1/*! 2 * jQuery JavaScript Library v1.7 3 * http://jquery.com/ 4 * 5 * Copyright 2011, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2011, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Thu Nov 3 16:18:21 2011 -0400 15 */ 16(function( window, undefined ) { 17 18// Use the correct document accordingly with window argument (sandbox) 19var document = window.document, 20 navigator = window.navigator, 21 location = window.location; 22var jQuery = (function() { 23 24// Define a local copy of jQuery 25var jQuery = function( selector, context ) { 26 // The jQuery object is actually just the init constructor 'enhanced' 27 return new jQuery.fn.init( selector, context, rootjQuery ); 28 }, 29 30 // Map over jQuery in case of overwrite 31 _jQuery = window.jQuery, 32 33 // Map over the $ in case of overwrite 34 _$ = window.$, 35 36 // A central reference to the root jQuery(document) 37 rootjQuery, 38 39 // A simple way to check for HTML strings or ID strings 40 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 41 quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, 42 43 // Check if a string has a non-whitespace character in it 44 rnotwhite = /\S/, 45 46 // Used for trimming whitespace 47 trimLeft = /^\s+/, 48 trimRight = /\s+$/, 49 50 // Check for digits 51 rdigit = /\d/, 52 53 // Match a standalone tag 54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 55 56 // JSON RegExp 57 rvalidchars = /^[\],:{}\s]*$/, 58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 61 62 // Useragent RegExp 63 rwebkit = /(webkit)[ \/]([\w.]+)/, 64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 65 rmsie = /(msie) ([\w.]+)/, 66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 67 68 // Matches dashed string for camelizing 69 rdashAlpha = /-([a-z]|[0-9])/ig, 70 rmsPrefix = /^-ms-/, 71 72 // Used by jQuery.camelCase as callback to replace() 73 fcamelCase = function( all, letter ) { 74 return ( letter + "" ).toUpperCase(); 75 }, 76 77 // Keep a UserAgent string for use with jQuery.browser 78 userAgent = navigator.userAgent, 79 80 // For matching the engine and version of the browser 81 browserMatch, 82 83 // The deferred used on DOM ready 84 readyList, 85 86 // The ready event handler 87 DOMContentLoaded, 88 89 // Save a reference to some core methods 90 toString = Object.prototype.toString, 91 hasOwn = Object.prototype.hasOwnProperty, 92 push = Array.prototype.push, 93 slice = Array.prototype.slice, 94 trim = String.prototype.trim, 95 indexOf = Array.prototype.indexOf, 96 97 // [[Class]] -> type pairs 98 class2type = {}; 99 100jQuery.fn = jQuery.prototype = { 101 constructor: jQuery, 102 init: function( selector, context, rootjQuery ) { 103 var match, elem, ret, doc; 104 105 // Handle $(""), $(null), or $(undefined) 106 if ( !selector ) { 107 return this; 108 } 109 110 // Handle $(DOMElement) 111 if ( selector.nodeType ) { 112 this.context = this[0] = selector; 113 this.length = 1; 114 return this; 115 } 116 117 // The body element only exists once, optimize finding it 118 if ( selector === "body" && !context && document.body ) { 119 this.context = document; 120 this[0] = document.body; 121 this.selector = selector; 122 this.length = 1; 123 return this; 124 } 125 126 // Handle HTML strings 127 if ( typeof selector === "string" ) { 128 // Are we dealing with HTML string or an ID? 129 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 130 // Assume that strings that start and end with <> are HTML and skip the regex check 131 match = [ null, selector, null ]; 132 133 } else { 134 match = quickExpr.exec( selector ); 135 } 136 137 // Verify a match, and that no context was specified for #id 138 if ( match && (match[1] || !context) ) { 139 140 // HANDLE: $(html) -> $(array) 141 if ( match[1] ) { 142 context = context instanceof jQuery ? context[0] : context; 143 doc = ( context ? context.ownerDocument || context : document ); 144 145 // If a single string is passed in and it's a single tag 146 // just do a createElement and skip the rest 147 ret = rsingleTag.exec( selector ); 148 149 if ( ret ) { 150 if ( jQuery.isPlainObject( context ) ) { 151 selector = [ document.createElement( ret[1] ) ]; 152 jQuery.fn.attr.call( selector, context, true ); 153 154 } else { 155 selector = [ doc.createElement( ret[1] ) ]; 156 } 157 158 } else { 159 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 160 selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; 161 } 162 163 return jQuery.merge( this, selector ); 164 165 // HANDLE: $("#id") 166 } else { 167 elem = document.getElementById( match[2] ); 168 169 // Check parentNode to catch when Blackberry 4.6 returns 170 // nodes that are no longer in the document #6963 171 if ( elem && elem.parentNode ) { 172 // Handle the case where IE and Opera return items 173 // by name instead of ID 174 if ( elem.id !== match[2] ) { 175 return rootjQuery.find( selector ); 176 } 177 178 // Otherwise, we inject the element directly into the jQuery object 179 this.length = 1; 180 this[0] = elem; 181 } 182 183 this.context = document; 184 this.selector = selector; 185 return this; 186 } 187 188 // HANDLE: $(expr, $(...)) 189 } else if ( !context || context.jquery ) { 190 return ( context || rootjQuery ).find( selector ); 191 192 // HANDLE: $(expr, context) 193 // (which is just equivalent to: $(context).find(expr) 194 } else { 195 return this.constructor( context ).find( selector ); 196 } 197 198 // HANDLE: $(function) 199 // Shortcut for document ready 200 } else if ( jQuery.isFunction( selector ) ) { 201 return rootjQuery.ready( selector ); 202 } 203 204 if ( selector.selector !== undefined ) { 205 this.selector = selector.selector; 206 this.context = selector.context; 207 } 208 209 return jQuery.makeArray( selector, this ); 210 }, 211 212 // Start with an empty selector 213 selector: "", 214 215 // The current version of jQuery being used 216 jquery: "1.7", 217 218 // The default length of a jQuery object is 0 219 length: 0, 220 221 // The number of elements contained in the matched element set 222 size: function() { 223 return this.length; 224 }, 225 226 toArray: function() { 227 return slice.call( this, 0 ); 228 }, 229 230 // Get the Nth element in the matched element set OR 231 // Get the whole matched element set as a clean array 232 get: function( num ) { 233 return num == null ? 234 235 // Return a 'clean' array 236 this.toArray() : 237 238 // Return just the object 239 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 240 }, 241 242 // Take an array of elements and push it onto the stack 243 // (returning the new matched element set) 244 pushStack: function( elems, name, selector ) { 245 // Build a new jQuery matched element set 246 var ret = this.constructor(); 247 248 if ( jQuery.isArray( elems ) ) { 249 push.apply( ret, elems ); 250 251 } else { 252 jQuery.merge( ret, elems ); 253 } 254 255 // Add the old object onto the stack (as a reference) 256 ret.prevObject = this; 257 258 ret.context = this.context; 259 260 if ( name === "find" ) { 261 ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; 262 } else if ( name ) { 263 ret.selector = this.selector + "." + name + "(" + selector + ")"; 264 } 265 266 // Return the newly-formed element set 267 return ret; 268 }, 269 270 // Execute a callback for every element in the matched set. 271 // (You can seed the arguments with an array of args, but this is 272 // only used internally.) 273 each: function( callback, args ) { 274 return jQuery.each( this, callback, args ); 275 }, 276 277 ready: function( fn ) { 278 // Attach the listeners 279 jQuery.bindReady(); 280 281 // Add the callback 282 readyList.add( fn ); 283 284 return this; 285 }, 286 287 eq: function( i ) { 288 return i === -1 ? 289 this.slice( i ) : 290 this.slice( i, +i + 1 ); 291 }, 292 293 first: function() { 294 return this.eq( 0 ); 295 }, 296 297 last: function() { 298 return this.eq( -1 ); 299 }, 300 301 slice: function() { 302 return this.pushStack( slice.apply( this, arguments ), 303 "slice", slice.call(arguments).join(",") ); 304 }, 305 306 map: function( callback ) { 307 return this.pushStack( jQuery.map(this, function( elem, i ) { 308 return callback.call( elem, i, elem ); 309 })); 310 }, 311 312 end: function() { 313 return this.prevObject || this.constructor(null); 314 }, 315 316 // For internal use only. 317 // Behaves like an Array's method, not like a jQuery method. 318 push: push, 319 sort: [].sort, 320 splice: [].splice 321}; 322 323// Give the init function the jQuery prototype for later instantiation 324jQuery.fn.init.prototype = jQuery.fn; 325 326jQuery.extend = jQuery.fn.extend = function() { 327 var options, name, src, copy, copyIsArray, clone, 328 target = arguments[0] || {}, 329 i = 1, 330 length = arguments.length, 331 deep = false; 332 333 // Handle a deep copy situation 334 if ( typeof target === "boolean" ) { 335 deep = target; 336 target = arguments[1] || {}; 337 // skip the boolean and the target 338 i = 2; 339 } 340 341 // Handle case when target is a string or something (possible in deep copy) 342 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 343 target = {}; 344 } 345 346 // extend jQuery itself if only one argument is passed 347 if ( length === i ) { 348 target = this; 349 --i; 350 } 351 352 for ( ; i < length; i++ ) { 353 // Only deal with non-null/undefined values 354 if ( (options = arguments[ i ]) != null ) { 355 // Extend the base object 356 for ( name in options ) { 357 src = target[ name ]; 358 copy = options[ name ]; 359 360 // Prevent never-ending loop 361 if ( target === copy ) { 362 continue; 363 } 364 365 // Recurse if we're merging plain objects or arrays 366 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 367 if ( copyIsArray ) { 368 copyIsArray = false; 369 clone = src && jQuery.isArray(src) ? src : []; 370 371 } else { 372 clone = src && jQuery.isPlainObject(src) ? src : {}; 373 } 374 375 // Never move original objects, clone them 376 target[ name ] = jQuery.extend( deep, clone, copy ); 377 378 // Don't bring in undefined values 379 } else if ( copy !== undefined ) { 380 target[ name ] = copy; 381 } 382 } 383 } 384 } 385 386 // Return the modified object 387 return target; 388}; 389 390jQuery.extend({ 391 noConflict: function( deep ) { 392 if ( window.$ === jQuery ) { 393 window.$ = _$; 394 } 395 396 if ( deep && window.jQuery === jQuery ) { 397 window.jQuery = _jQuery; 398 } 399 400 return jQuery; 401 }, 402 403 // Is the DOM ready to be used? Set to true once it occurs. 404 isReady: false, 405 406 // A counter to track how many items to wait for before 407 // the ready event fires. See #6781 408 readyWait: 1, 409 410 // Hold (or release) the ready event 411 holdReady: function( hold ) { 412 if ( hold ) { 413 jQuery.readyWait++; 414 } else { 415 jQuery.ready( true ); 416 } 417 }, 418 419 // Handle when the DOM is ready 420 ready: function( wait ) { 421 // Either a released hold or an DOMready/load event and not yet ready 422 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { 423 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 424 if ( !document.body ) { 425 return setTimeout( jQuery.ready, 1 ); 426 } 427 428 // Remember that the DOM is ready 429 jQuery.isReady = true; 430 431 // If a normal DOM Ready event fired, decrement, and wait if need be 432 if ( wait !== true && --jQuery.readyWait > 0 ) { 433 return; 434 } 435 436 // If there are functions bound, to execute 437 readyList.fireWith( document, [ jQuery ] ); 438 439 // Trigger any bound ready events 440 if ( jQuery.fn.trigger ) { 441 jQuery( document ).trigger( "ready" ).unbind( "ready" ); 442 } 443 } 444 }, 445 446 bindReady: function() { 447 if ( readyList ) { 448 return; 449 } 450 451 readyList = jQuery.Callbacks( "once memory" ); 452 453 // Catch cases where $(document).ready() is called after the 454 // browser event has already occurred. 455 if ( document.readyState === "complete" ) { 456 // Handle it asynchronously to allow scripts the opportunity to delay ready 457 return setTimeout( jQuery.ready, 1 ); 458 } 459 460 // Mozilla, Opera and webkit nightlies currently support this event 461 if ( document.addEventListener ) { 462 // Use the handy event callback 463 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 464 465 // A fallback to window.onload, that will always work 466 window.addEventListener( "load", jQuery.ready, false ); 467 468 // If IE event model is used 469 } else if ( document.attachEvent ) { 470 // ensure firing before onload, 471 // maybe late but safe also for iframes 472 document.attachEvent( "onreadystatechange", DOMContentLoaded ); 473 474 // A fallback to window.onload, that will always work 475 window.attachEvent( "onload", jQuery.ready ); 476 477 // If IE and not a frame 478 // continually check to see if the document is ready 479 var toplevel = false; 480 481 try { 482 toplevel = window.frameElement == null; 483 } catch(e) {} 484 485 if ( document.documentElement.doScroll && toplevel ) { 486 doScrollCheck(); 487 } 488 } 489 }, 490 491 // See test/unit/core.js for details concerning isFunction. 492 // Since version 1.3, DOM methods and functions like alert 493 // aren't supported. They return false on IE (#2968). 494 isFunction: function( obj ) { 495 return jQuery.type(obj) === "function"; 496 }, 497 498 isArray: Array.isArray || function( obj ) { 499 return jQuery.type(obj) === "array"; 500 }, 501 502 // A crude way of determining if an object is a window 503 isWindow: function( obj ) { 504 return obj && typeof obj === "object" && "setInterval" in obj; 505 }, 506 507 isNumeric: function( obj ) { 508 return obj != null && rdigit.test( obj ) && !isNaN( obj ); 509 }, 510 511 type: function( obj ) { 512 return obj == null ? 513 String( obj ) : 514 class2type[ toString.call(obj) ] || "object"; 515 }, 516 517 isPlainObject: function( obj ) { 518 // Must be an Object. 519 // Because of IE, we also have to check the presence of the constructor property. 520 // Make sure that DOM nodes and window objects don't pass through, as well 521 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 522 return false; 523 } 524 525 try { 526 // Not own constructor property must be Object 527 if ( obj.constructor && 528 !hasOwn.call(obj, "constructor") && 529 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 530 return false; 531 } 532 } catch ( e ) { 533 // IE8,9 Will throw exceptions on certain host objects #9897 534 return false; 535 } 536 537 // Own properties are enumerated firstly, so to speed up, 538 // if last one is own, then all properties are own. 539 540 var key; 541 for ( key in obj ) {} 542 543 return key === undefined || hasOwn.call( obj, key ); 544 }, 545 546 isEmptyObject: function( obj ) { 547 for ( var name in obj ) { 548 return false; 549 } 550 return true; 551 }, 552 553 error: function( msg ) { 554 throw msg; 555 }, 556 557 parseJSON: function( data ) { 558 if ( typeof data !== "string" || !data ) { 559 return null; 560 } 561 562 // Make sure leading/trailing whitespace is removed (IE can't handle it) 563 data = jQuery.trim( data ); 564 565 // Attempt to parse using the native JSON parser first 566 if ( window.JSON && window.JSON.parse ) { 567 return window.JSON.parse( data ); 568 } 569 570 // Make sure the incoming data is actual JSON 571 // Logic borrowed from http://json.org/json2.js 572 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 573 .replace( rvalidtokens, "]" ) 574 .replace( rvalidbraces, "")) ) { 575 576 return ( new Function( "return " + data ) )(); 577 578 } 579 jQuery.error( "Invalid JSON: " + data ); 580 }, 581 582 // Cross-browser xml parsing 583 parseXML: function( data ) { 584 var xml, tmp; 585 try { 586 if ( window.DOMParser ) { // Standard 587 tmp = new DOMParser(); 588 xml = tmp.parseFromString( data , "text/xml" ); 589 } else { // IE 590 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 591 xml.async = "false"; 592 xml.loadXML( data ); 593 } 594 } catch( e ) { 595 xml = undefined; 596 } 597 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { 598 jQuery.error( "Invalid XML: " + data ); 599 } 600 return xml; 601 }, 602 603 noop: function() {}, 604 605 // Evaluates a script in a global context 606 // Workarounds based on findings by Jim Driscoll 607 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 608 globalEval: function( data ) { 609 if ( data && rnotwhite.test( data ) ) { 610 // We use execScript on Internet Explorer 611 // We use an anonymous function so that context is window 612 // rather than jQuery in Firefox 613 ( window.execScript || function( data ) { 614 window[ "eval" ].call( window, data ); 615 } )( data ); 616 } 617 }, 618 619 // Convert dashed to camelCase; used by the css and data modules 620 // Microsoft forgot to hump their vendor prefix (#9572) 621 camelCase: function( string ) { 622 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 623 }, 624 625 nodeName: function( elem, name ) { 626 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 627 }, 628 629 // args is for internal usage only 630 each: function( object, callback, args ) { 631 var name, i = 0, 632 length = object.length, 633 isObj = length === undefined || jQuery.isFunction( object ); 634 635 if ( args ) { 636 if ( isObj ) { 637 for ( name in object ) { 638 if ( callback.apply( object[ name ], args ) === false ) { 639 break; 640 } 641 } 642 } else { 643 for ( ; i < length; ) { 644 if ( callback.apply( object[ i++ ], args ) === false ) { 645 break; 646 } 647 } 648 } 649 650 // A special, fast, case for the most common use of each 651 } else { 652 if ( isObj ) { 653 for ( name in object ) { 654 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 655 break; 656 } 657 } 658 } else { 659 for ( ; i < length; ) { 660 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 661 break; 662 } 663 } 664 } 665 } 666 667 return object; 668 }, 669 670 // Use native String.trim function wherever possible 671 trim: trim ? 672 function( text ) { 673 return text == null ? 674 "" : 675 trim.call( text ); 676 } : 677 678 // Otherwise use our own trimming functionality 679 function( text ) { 680 return text == null ? 681 "" : 682 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 683 }, 684 685 // results is for internal usage only 686 makeArray: function( array, results ) { 687 var ret = results || []; 688 689 if ( array != null ) { 690 // The window, strings (and functions) also have 'length' 691 // The extra typeof function check is to prevent crashes 692 // in Safari 2 (See: #3039) 693 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 694 var type = jQuery.type( array ); 695 696 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 697 push.call( ret, array ); 698 } else { 699 jQuery.merge( ret, array ); 700 } 701 } 702 703 return ret; 704 }, 705 706 inArray: function( elem, array, i ) { 707 var len; 708 709 if ( array ) { 710 if ( indexOf ) { 711 return indexOf.call( array, elem, i ); 712 } 713 714 len = array.length; 715 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; 716 717 for ( ; i < len; i++ ) { 718 // Skip accessing in sparse arrays 719 if ( i in array && array[ i ] === elem ) { 720 return i; 721 } 722 } 723 } 724 725 return -1; 726 }, 727 728 merge: function( first, second ) { 729 var i = first.length, 730 j = 0; 731 732 if ( typeof second.length === "number" ) { 733 for ( var l = second.length; j < l; j++ ) { 734 first[ i++ ] = second[ j ]; 735 } 736 737 } else { 738 while ( second[j] !== undefined ) { 739 first[ i++ ] = second[ j++ ]; 740 } 741 } 742 743 first.length = i; 744 745 return first; 746 }, 747 748 grep: function( elems, callback, inv ) { 749 var ret = [], retVal; 750 inv = !!inv; 751 752 // Go through the array, only saving the items 753 // that pass the validator function 754 for ( var i = 0, length = elems.length; i < length; i++ ) { 755 retVal = !!callback( elems[ i ], i ); 756 if ( inv !== retVal ) { 757 ret.push( elems[ i ] ); 758 } 759 } 760 761 return ret; 762 }, 763 764 // arg is for internal usage only 765 map: function( elems, callback, arg ) { 766 var value, key, ret = [], 767 i = 0, 768 length = elems.length, 769 // jquery objects are treated as arrays 770 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 771 772 // Go through the array, translating each of the items to their 773 if ( isArray ) { 774 for ( ; i < length; i++ ) { 775 value = callback( elems[ i ], i, arg ); 776 777 if ( value != null ) { 778 ret[ ret.length ] = value; 779 } 780 } 781 782 // Go through every key on the object, 783 } else { 784 for ( key in elems ) { 785 value = callback( elems[ key ], key, arg ); 786 787 if ( value != null ) { 788 ret[ ret.length ] = value; 789 } 790 } 791 } 792 793 // Flatten any nested arrays 794 return ret.concat.apply( [], ret ); 795 }, 796 797 // A global GUID counter for objects 798 guid: 1, 799 800 // Bind a function to a context, optionally partially applying any 801 // arguments. 802 proxy: function( fn, context ) { 803 if ( typeof context === "string" ) { 804 var tmp = fn[ context ]; 805 context = fn; 806 fn = tmp; 807 } 808 809 // Quick check to determine if target is callable, in the spec 810 // this throws a TypeError, but we will just return undefined. 811 if ( !jQuery.isFunction( fn ) ) { 812 return undefined; 813 } 814 815 // Simulated bind 816 var args = slice.call( arguments, 2 ), 817 proxy = function() { 818 return fn.apply( context, args.concat( slice.call( arguments ) ) ); 819 }; 820 821 // Set the guid of unique handler to the same of original handler, so it can be removed 822 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 823 824 return proxy; 825 }, 826 827 // Mutifunctional method to get and set values to a collection 828 // The value/s can optionally be executed if it's a function 829 access: function( elems, key, value, exec, fn, pass ) { 830 var length = elems.length; 831 832 // Setting many attributes 833 if ( typeof key === "object" ) { 834 for ( var k in key ) { 835 jQuery.access( elems, k, key[k], exec, fn, value ); 836 } 837 return elems; 838 } 839 840 // Setting one attribute 841 if ( value !== undefined ) { 842 // Optionally, function values get executed if exec is true 843 exec = !pass && exec && jQuery.isFunction(value); 844 845 for ( var i = 0; i < length; i++ ) { 846 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 847 } 848 849 return elems; 850 } 851 852 // Getting an attribute 853 return length ? fn( elems[0], key ) : undefined; 854 }, 855 856 now: function() { 857 return ( new Date() ).getTime(); 858 }, 859 860 // Use of jQuery.browser is frowned upon. 861 // More details: http://docs.jquery.com/Utilities/jQuery.browser 862 uaMatch: function( ua ) { 863 ua = ua.toLowerCase(); 864 865 var match = rwebkit.exec( ua ) || 866 ropera.exec( ua ) || 867 rmsie.exec( ua ) || 868 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 869 []; 870 871 return { browser: match[1] || "", version: match[2] || "0" }; 872 }, 873 874 sub: function() { 875 function jQuerySub( selector, context ) { 876 return new jQuerySub.fn.init( selector, context ); 877 } 878 jQuery.extend( true, jQuerySub, this ); 879 jQuerySub.superclass = this; 880 jQuerySub.fn = jQuerySub.prototype = this(); 881 jQuerySub.fn.constructor = jQuerySub; 882 jQuerySub.sub = this.sub; 883 jQuerySub.fn.init = function init( selector, context ) { 884 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 885 context = jQuerySub( context ); 886 } 887 888 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 889 }; 890 jQuerySub.fn.init.prototype = jQuerySub.fn; 891 var rootjQuerySub = jQuerySub(document); 892 return jQuerySub; 893 }, 894 895 browser: {} 896}); 897 898// Populate the class2type map 899jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 900 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 901}); 902 903browserMatch = jQuery.uaMatch( userAgent ); 904if ( browserMatch.browser ) { 905 jQuery.browser[ browserMatch.browser ] = true; 906 jQuery.browser.version = browserMatch.version; 907} 908 909// Deprecated, use jQuery.browser.webkit instead 910if ( jQuery.browser.webkit ) { 911 jQuery.browser.safari = true; 912} 913 914// IE doesn't match non-breaking spaces with \s 915if ( rnotwhite.test( "\xA0" ) ) { 916 trimLeft = /^[\s\xA0]+/; 917 trimRight = /[\s\xA0]+$/; 918} 919 920// All jQuery objects should point back to these 921rootjQuery = jQuery(document); 922 923// Cleanup functions for the document ready method 924if ( document.addEventListener ) { 925 DOMContentLoaded = function() { 926 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 927 jQuery.ready(); 928 }; 929 930} else if ( document.attachEvent ) { 931 DOMContentLoaded = function() { 932 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 933 if ( document.readyState === "complete" ) { 934 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 935 jQuery.ready(); 936 } 937 }; 938} 939 940// The DOM ready check for Internet Explorer 941function doScrollCheck() { 942 if ( jQuery.isReady ) { 943 return; 944 } 945 946 try { 947 // If IE is used, use the trick by Diego Perini 948 // http://javascript.nwbox.com/IEContentLoaded/ 949 document.documentElement.doScroll("left"); 950 } catch(e) { 951 setTimeout( doScrollCheck, 1 ); 952 return; 953 } 954 955 // and execute any waiting functions 956 jQuery.ready(); 957} 958 959// Expose jQuery as an AMD module, but only for AMD loaders that 960// understand the issues with loading multiple versions of jQuery 961// in a page that all might call define(). The loader will indicate 962// they have special allowances for multiple jQuery versions by 963// specifying define.amd.jQuery = true. Register as a named module, 964// since jQuery can be concatenated with other files that may use define, 965// but not use a proper concatenation script that understands anonymous 966// AMD modules. A named AMD is safest and most robust way to register. 967// Lowercase jquery is used because AMD module names are derived from 968// file names, and jQuery is normally delivered in a lowercase file name. 969if ( typeof define === "function" && define.amd && define.amd.jQuery ) { 970 define( "jquery", [], function () { return jQuery; } ); 971} 972 973return jQuery; 974 975})(); 976 977 978// String to Object flags format cache 979var flagsCache = {}; 980 981// Convert String-formatted flags into Object-formatted ones and store in cache 982function createFlags( flags ) { 983 var object = flagsCache[ flags ] = {}, 984 i, length; 985 flags = flags.split( /\s+/ ); 986 for ( i = 0, length = flags.length; i < length; i++ ) { 987 object[ flags[i] ] = true; 988 } 989 return object; 990} 991 992/* 993 * Create a callback list using the following parameters: 994 * 995 * flags: an optional list of space-separated flags that will change how 996 * the callback list behaves 997 * 998 * By default a callback list will act like an event callback list and can be 999 * "fired" multiple times. 1000 * 1001 * Possible flags: 1002 * 1003 * once: will ensure the callback list can only be fired once (like a Deferred) 1004 * 1005 * memory: will keep track of previous values and will call any callback added 1006 * after the list has been fired right away with the latest "memorized" 1007 * values (like a Deferred) 1008 * 1009 * unique: will ensure a callback can only be added once (no duplicate in the list) 1010 * 1011 * stopOnFalse: interrupt callings when a callback returns false 1012 * 1013 */ 1014jQuery.Callbacks = function( flags ) { 1015 1016 // Convert flags from String-formatted to Object-formatted 1017 // (we check in cache first) 1018 flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; 1019 1020 var // Actual callback list 1021 list = [], 1022 // Stack of fire calls for repeatable lists 1023 stack = [], 1024 // Last fire value (for non-forgettable lists) 1025 memory, 1026 // Flag to know if list is currently firing 1027 firing, 1028 // First callback to fire (used internally by add and fireWith) 1029 firingStart, 1030 // End of the loop when firing 1031 firingLength, 1032 // Index of currently firing callback (modified by remove if needed) 1033 firingIndex, 1034 // Add one or several callbacks to the list 1035 add = function( args ) { 1036 var i, 1037 length, 1038 elem, 1039 type, 1040 actual; 1041 for ( i = 0, length = args.length; i < length; i++ ) { 1042 elem = args[ i ]; 1043 type = jQuery.type( elem ); 1044 if ( type === "array" ) { 1045 // Inspect recursively 1046 add( elem ); 1047 } else if ( type === "function" ) { 1048 // Add if not in unique mode and callback is not in 1049 if ( !flags.unique || !self.has( elem ) ) { 1050 list.push( elem ); 1051 } 1052 } 1053 } 1054 }, 1055 // Fire callbacks 1056 fire = function( context, args ) { 1057 args = args || []; 1058 memory = !flags.memory || [ context, args ]; 1059 firing = true; 1060 firingIndex = firingStart || 0; 1061 firingStart = 0; 1062 firingLength = list.length; 1063 for ( ; list && firingIndex < firingLength; firingIndex++ ) { 1064 if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { 1065 memory = true; // Mark as halted 1066 break; 1067 } 1068 } 1069 firing = false; 1070 if ( list ) { 1071 if ( !flags.once ) { 1072 if ( stack && stack.length ) { 1073 memory = stack.shift(); 1074 self.fireWith( memory[ 0 ], memory[ 1 ] ); 1075 } 1076 } else if ( memory === true ) { 1077 self.disable(); 1078 } else { 1079 list = []; 1080 } 1081 } 1082 }, 1083 // Actual Callbacks object 1084 self = { 1085 // Add a callback or a collection of callbacks to the list 1086 add: function() { 1087 if ( list ) { 1088 var length = list.length; 1089 add( arguments ); 1090 // Do we need to add the callbacks to the 1091 // current firing batch? 1092 if ( firing ) { 1093 firingLength = list.length; 1094 // With memory, if we're not firing then 1095 // we should call right away, unless previous 1096 // firing was halted (stopOnFalse) 1097 } else if ( memory && memory !== true ) { 1098 firingStart = length; 1099 fire( memory[ 0 ], memory[ 1 ] ); 1100 } 1101 } 1102 return this; 1103 }, 1104 // Remove a callback from the list 1105 remove: function() { 1106 if ( list ) { 1107 var args = arguments, 1108 argIndex = 0, 1109 argLength = args.length; 1110 for ( ; argIndex < argLength ; argIndex++ ) { 1111 for ( var i = 0; i < list.length; i++ ) { 1112 if ( args[ argIndex ] === list[ i ] ) { 1113 // Handle firingIndex and firingLength 1114 if ( firing ) { 1115 if ( i <= firingLength ) { 1116 firingLength--; 1117 if ( i <= firingIndex ) { 1118 firingIndex--; 1119 } 1120 } 1121 } 1122 // Remove the element 1123 list.splice( i--, 1 ); 1124 // If we have some unicity property then 1125 // we only need to do this once 1126 if ( flags.unique ) { 1127 break; 1128 } 1129 } 1130 } 1131 } 1132 } 1133 return this; 1134 }, 1135 // Control if a given callback is in the list 1136 has: function( fn ) { 1137 if ( list ) { 1138 var i = 0, 1139 length = list.length; 1140 for ( ; i < length; i++ ) { 1141 if ( fn === list[ i ] ) { 1142 return true; 1143 } 1144 } 1145 } 1146 return false; 1147 }, 1148 // Remove all callbacks from the list 1149 empty: function() { 1150 list = []; 1151 return this; 1152 }, 1153 // Have the list do nothing anymore 1154 disable: function() { 1155 list = stack = memory = undefined; 1156 return this; 1157 }, 1158 // Is it disabled? 1159 disabled: function() { 1160 return !list; 1161 }, 1162 // Lock the list in its current state 1163 lock: function() { 1164 stack = undefined; 1165 if ( !memory || memory === true ) { 1166 self.disable(); 1167 } 1168 return this; 1169 }, 1170 // Is it locked? 1171 locked: function() { 1172 return !stack; 1173 }, 1174 // Call all callbacks with the given context and arguments 1175 fireWith: function( context, args ) { 1176 if ( stack ) { 1177 if ( firing ) { 1178 if ( !flags.once ) { 1179 stack.push( [ context, args ] ); 1180 } 1181 } else if ( !( flags.once && memory ) ) { 1182 fire( context, args ); 1183 } 1184 } 1185 return this; 1186 }, 1187 // Call all the callbacks with the given arguments 1188 fire: function() { 1189 self.fireWith( this, arguments ); 1190 return this; 1191 }, 1192 // To know if the callbacks have already been called at least once 1193 fired: function() { 1194 return !!memory; 1195 } 1196 }; 1197 1198 return self; 1199}; 1200 1201 1202 1203 1204var // Static reference to slice 1205 sliceDeferred = [].slice; 1206 1207jQuery.extend({ 1208 1209 Deferred: function( func ) { 1210 var doneList = jQuery.Callbacks( "once memory" ), 1211 failList = jQuery.Callbacks( "once memory" ), 1212 progressList = jQuery.Callbacks( "memory" ), 1213 state = "pending", 1214 lists = { 1215 resolve: doneList, 1216 reject: failList, 1217 notify: progressList 1218 }, 1219 promise = { 1220 done: doneList.add, 1221 fail: failList.add, 1222 progress: progressList.add, 1223 1224 state: function() { 1225 return state; 1226 }, 1227 1228 // Deprecated 1229 isResolved: doneList.fired, 1230 isRejected: failList.fired, 1231 1232 then: function( doneCallbacks, failCallbacks, progressCallbacks ) { 1233 deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); 1234 return this; 1235 }, 1236 always: function() { 1237 return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); 1238 }, 1239 pipe: function( fnDone, fnFail, fnProgress ) { 1240 return jQuery.Deferred(function( newDefer ) { 1241 jQuery.each( { 1242 done: [ fnDone, "resolve" ], 1243 fail: [ fnFail, "reject" ], 1244 progress: [ fnProgress, "notify" ] 1245 }, function( handler, data ) { 1246 var fn = data[ 0 ], 1247 action = data[ 1 ], 1248 returned; 1249 if ( jQuery.isFunction( fn ) ) { 1250 deferred[ handler ](function() { 1251 returned = fn.apply( this, arguments ); 1252 if ( returned && jQuery.isFunction( returned.promise ) ) { 1253 returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); 1254 } else { 1255 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); 1256 } 1257 }); 1258 } else { 1259 deferred[ handler ]( newDefer[ action ] ); 1260 } 1261 }); 1262 }).promise(); 1263 }, 1264 // Get a promise for this deferred 1265 // If obj is provided, the promise aspect is added to the object 1266 promise: function( obj ) { 1267 if ( obj == null ) { 1268 obj = promise; 1269 } else { 1270 for ( var key in promise ) { 1271 obj[ key ] = promise[ key ]; 1272 } 1273 } 1274 return obj; 1275 } 1276 }, 1277 deferred = promise.promise({}), 1278 key; 1279 1280 for ( key in lists ) { 1281 deferred[ key ] = lists[ key ].fire; 1282 deferred[ key + "With" ] = lists[ key ].fireWith; 1283 } 1284 1285 // Handle state 1286 deferred.done( function() { 1287 state = "resolved"; 1288 }, failList.disable, progressList.lock ).fail( function() { 1289 state = "rejected"; 1290 }, doneList.disable, progressList.lock ); 1291 1292 // Call given func if any 1293 if ( func ) { 1294 func.call( deferred, deferred ); 1295 } 1296 1297 // All done! 1298 return deferred; 1299 }, 1300 1301 // Deferred helper 1302 when: function( firstParam ) { 1303 var args = sliceDeferred.call( arguments, 0 ), 1304 i = 0, 1305 length = args.length, 1306 pValues = new Array( length ), 1307 count = length, 1308 pCount = length, 1309 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? 1310 firstParam : 1311 jQuery.Deferred(), 1312 promise = deferred.promise(); 1313 function resolveFunc( i ) { 1314 return function( value ) { 1315 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1316 if ( !( --count ) ) { 1317 deferred.resolveWith( deferred, args ); 1318 } 1319 }; 1320 } 1321 function progressFunc( i ) { 1322 return function( value ) { 1323 pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1324 deferred.notifyWith( promise, pValues ); 1325 }; 1326 } 1327 if ( length > 1 ) { 1328 for ( ; i < length; i++ ) { 1329 if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { 1330 args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); 1331 } else { 1332 --count; 1333 } 1334 } 1335 if ( !count ) { 1336 deferred.resolveWith( deferred, args ); 1337 } 1338 } else if ( deferred !== firstParam ) { 1339 deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); 1340 } 1341 return promise; 1342 } 1343}); 1344 1345 1346 1347 1348jQuery.support = (function() { 1349 1350 var div = document.createElement( "div" ), 1351 documentElement = document.documentElement, 1352 all, 1353 a, 1354 select, 1355 opt, 1356 input, 1357 marginDiv, 1358 support, 1359 fragment, 1360 body, 1361 testElementParent, 1362 testElement, 1363 testElementStyle, 1364 tds, 1365 events, 1366 eventName, 1367 i, 1368 isSupported; 1369 1370 // Preliminary tests 1371 div.setAttribute("className", "t"); 1372 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/><nav></nav>"; 1373 1374 1375 all = div.getElementsByTagName( "*" ); 1376 a = div.getElementsByTagName( "a" )[ 0 ]; 1377 1378 // Can't get basic test support 1379 if ( !all || !all.length || !a ) { 1380 return {}; 1381 } 1382 1383 // First batch of supports tests 1384 select = document.createElement( "select" ); 1385 opt = select.appendChild( document.createElement("option") ); 1386 input = div.getElementsByTagName( "input" )[ 0 ]; 1387 1388 support = { 1389 // IE strips leading whitespace when .innerHTML is used 1390 leadingWhitespace: ( div.firstChild.nodeType === 3 ), 1391 1392 // Make sure that tbody elements aren't automatically inserted 1393 // IE will insert them into empty tables 1394 tbody: !div.getElementsByTagName( "tbody" ).length, 1395 1396 // Make sure that link elements get serialized correctly by innerHTML 1397 // This requires a wrapper element in IE 1398 htmlSerialize: !!div.getElementsByTagName( "link" ).length, 1399 1400 // Get the style information from getAttribute 1401 // (IE uses .cssText instead) 1402 style: /top/.test( a.getAttribute("style") ), 1403 1404 // Make sure that URLs aren't manipulated 1405 // (IE normalizes it by default) 1406 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), 1407 1408 // Make sure that element opacity exists 1409 // (IE uses filter instead) 1410 // Use a regex to work around a WebKit issue. See #5145 1411 opacity: /^0.55/.test( a.style.opacity ), 1412 1413 // Verify style float existence 1414 // (IE uses styleFloat instead of cssFloat) 1415 cssFloat: !!a.style.cssFloat, 1416 1417 // Make sure unknown elements (like HTML5 elems) are handled appropriately 1418 unknownElems: !!div.getElementsByTagName( "nav" ).length, 1419 1420 // Make sure that if no value is specified for a checkbox 1421 // that it defaults to "on". 1422 // (WebKit defaults to "" instead) 1423 checkOn: ( input.value === "on" ), 1424 1425 // Make sure that a selected-by-default option has a working selected property. 1426 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1427 optSelected: opt.selected, 1428 1429 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) 1430 getSetAttribute: div.className !== "t", 1431 1432 // Tests for enctype support on a form(#6743) 1433 enctype: !!document.createElement("form").enctype, 1434 1435 // Will be defined later 1436 submitBubbles: true, 1437 changeBubbles: true, 1438 focusinBubbles: false, 1439 deleteExpando: true, 1440 noCloneEvent: true, 1441 inlineBlockNeedsLayout: false, 1442 shrinkWrapBlocks: false, 1443 reliableMarginRight: true 1444 }; 1445 1446 // Make sure checked status is properly cloned 1447 input.checked = true; 1448 support.noCloneChecked = input.cloneNode( true ).checked; 1449 1450 // Make sure that the options inside disabled selects aren't marked as disabled 1451 // (WebKit marks them as disabled) 1452 select.disabled = true; 1453 support.optDisabled = !opt.disabled; 1454 1455 // Test to see if it's possible to delete an expando from an element 1456 // Fails in Internet Explorer 1457 try { 1458 delete div.test; 1459 } catch( e ) { 1460 support.deleteExpando = false; 1461 } 1462 1463 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1464 div.attachEvent( "onclick", function() { 1465 // Cloning a node shouldn't copy over any 1466 // bound event handlers (IE does this) 1467 support.noCloneEvent = false; 1468 }); 1469 div.cloneNode( true ).fireEvent( "onclick" ); 1470 } 1471 1472 // Check if a radio maintains its value 1473 // after being appended to the DOM 1474 input = document.createElement("input"); 1475 input.value = "t"; 1476 input.setAttribute("type", "radio"); 1477 support.radioValue = input.value === "t"; 1478 1479 input.setAttribute("checked", "checked"); 1480 div.appendChild( input ); 1481 fragment = document.createDocumentFragment(); 1482 fragment.appendChild( div.lastChild ); 1483 1484 // WebKit doesn't clone checked state correctly in fragments 1485 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; 1486 1487 div.innerHTML = ""; 1488 1489 // Figure out if the W3C box model works as expected 1490 div.style.width = div.style.paddingLeft = "1px"; 1491 1492 // We don't want to do body-related feature tests on frameset 1493 // documents, which lack a body. So we use 1494 // document.getElementsByTagName("body")[0], which is undefined in 1495 // frameset documents, while document.body isn’t. (7398) 1496 body = document.getElementsByTagName("body")[ 0 ]; 1497 // We use our own, invisible, body unless the body is already present 1498 // in which case we use a div (#9239) 1499 testElement = document.createElement( body ? "div" : "body" ); 1500 testElementStyle = { 1501 visibility: "hidden", 1502 width: 0, 1503 height: 0, 1504 border: 0, 1505 margin: 0, 1506 background: "none" 1507 }; 1508 if ( body ) { 1509 jQuery.extend( testElementStyle, { 1510 position: "absolute", 1511 left: "-999px", 1512 top: "-999px" 1513 }); 1514 } 1515 for ( i in testElementStyle ) { 1516 testElement.style[ i ] = testElementStyle[ i ]; 1517 } 1518 testElement.appendChild( div ); 1519 testElementParent = body || documentElement; 1520 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1521 1522 // Check if a disconnected checkbox will retain its checked 1523 // value of true after appended to the DOM (IE6/7) 1524 support.appendChecked = input.checked; 1525 1526 support.boxModel = div.offsetWidth === 2; 1527 1528 if ( "zoom" in div.style ) { 1529 // Check if natively block-level elements act like inline-block 1530 // elements when setting their display to 'inline' and giving 1531 // them layout 1532 // (IE < 8 does this) 1533 div.style.display = "inline"; 1534 div.style.zoom = 1; 1535 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); 1536 1537 // Check if elements with layout shrink-wrap their children 1538 // (IE 6 does this) 1539 div.style.display = ""; 1540 div.innerHTML = "<div style='width:4px;'></div>"; 1541 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); 1542 } 1543 1544 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; 1545 tds = div.getElementsByTagName( "td" ); 1546 1547 // Check if table cells still have offsetWidth/Height when they are set 1548 // to display:none and there are still other visible table cells in a 1549 // table row; if so, offsetWidth/Height are not reliable for use when 1550 // determining if an element has been hidden directly using 1551 // display:none (it is still safe to use offsets if a parent element is 1552 // hidden; don safety goggles and see bug #4512 for more information). 1553 // (only IE 8 fails this test) 1554 isSupported = ( tds[ 0 ].offsetHeight === 0 ); 1555 1556 tds[ 0 ].style.display = ""; 1557 tds[ 1 ].style.display = "none"; 1558 1559 // Check if empty table cells still have offsetWidth/Height 1560 // (IE < 8 fail this test) 1561 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); 1562 div.innerHTML = ""; 1563 1564 // Check if div with explicit width and no margin-right incorrectly 1565 // gets computed margin-right based on width of container. For more 1566 // info see bug #3333 1567 // Fails in WebKit before Feb 2011 nightlies 1568 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 1569 if ( document.defaultView && document.defaultView.getComputedStyle ) { 1570 marginDiv = document.createElement( "div" ); 1571 marginDiv.style.width = "0"; 1572 marginDiv.style.marginRight = "0"; 1573 div.appendChild( marginDiv ); 1574 support.reliableMarginRight = 1575 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; 1576 } 1577 1578 // Technique from Juriy Zaytsev 1579 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 1580 // We only care about the case where non-standard event systems 1581 // are used, namely in IE. Short-circuiting here helps us to 1582 // avoid an eval call (in setAttribute) which can cause CSP 1583 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1584 if ( div.attachEvent ) { 1585 for( i in { 1586 submit: 1, 1587 change: 1, 1588 focusin: 1 1589 } ) { 1590 eventName = "on" + i; 1591 isSupported = ( eventName in div ); 1592 if ( !isSupported ) { 1593 div.setAttribute( eventName, "return;" ); 1594 isSupported = ( typeof div[ eventName ] === "function" ); 1595 } 1596 support[ i + "Bubbles" ] = isSupported; 1597 } 1598 } 1599 1600 // Run fixed position tests at doc ready to avoid a crash 1601 // related to the invisible body in IE8 1602 jQuery(function() { 1603 var container, outer, inner, table, td, offsetSupport, 1604 conMarginTop = 1, 1605 ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;", 1606 vb = "visibility:hidden;border:0;", 1607 style = "style='" + ptlm + "border:5px solid #000;padding:0;'", 1608 html = "<div " + style + "><div></div></div>" + 1609 "<table " + style + " cellpadding='0' cellspacing='0'>" + 1610 "<tr><td></td></tr></table>"; 1611 1612 // Reconstruct a container 1613 body = document.getElementsByTagName("body")[0]; 1614 if ( !body ) { 1615 // Return for frameset docs that don't have a body 1616 // These tests cannot be done 1617 return; 1618 } 1619 1620 container = document.createElement("div"); 1621 container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; 1622 body.insertBefore( container, body.firstChild ); 1623 1624 // Construct a test element 1625 testElement = document.createElement("div"); 1626 testElement.style.cssText = ptlm + vb; 1627 1628 testElement.innerHTML = html; 1629 container.appendChild( testElement ); 1630 outer = testElement.firstChild; 1631 inner = outer.firstChild; 1632 td = outer.nextSibling.firstChild.firstChild; 1633 1634 offsetSupport = { 1635 doesNotAddBorder: ( inner.offsetTop !== 5 ), 1636 doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) 1637 }; 1638 1639 inner.style.position = "fixed"; 1640 inner.style.top = "20px"; 1641 1642 // safari subtracts parent border width here which is 5px 1643 offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); 1644 inner.style.position = inner.style.top = ""; 1645 1646 outer.style.overflow = "hidden"; 1647 outer.style.position = "relative"; 1648 1649 offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); 1650 offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); 1651 1652 body.removeChild( container ); 1653 testElement = container = null; 1654 1655 jQuery.extend( support, offsetSupport ); 1656 }); 1657 1658 testElement.innerHTML = ""; 1659 testElementParent.removeChild( testElement ); 1660 1661 // Null connected elements to avoid leaks in IE 1662 testElement = fragment = select = opt = body = marginDiv = div = input = null; 1663 1664 return support; 1665})(); 1666 1667// Keep track of boxModel 1668jQuery.boxModel = jQuery.support.boxModel; 1669 1670 1671 1672 1673var rbrace = /^(?:\{.*\}|\[.*\])$/, 1674 rmultiDash = /([A-Z])/g; 1675 1676jQuery.extend({ 1677 cache: {}, 1678 1679 // Please use with caution 1680 uuid: 0, 1681 1682 // Unique for each copy of jQuery on the page 1683 // Non-digits removed to match rinlinejQuery 1684 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1685 1686 // The following elements throw uncatchable exceptions if you 1687 // attempt to add expando properties to them. 1688 noData: { 1689 "embed": true, 1690 // Ban all objects except for Flash (which handle expandos) 1691 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1692 "applet": true 1693 }, 1694 1695 hasData: function( elem ) { 1696 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1697 return !!elem && !isEmptyDataObject( elem ); 1698 }, 1699 1700 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1701 if ( !jQuery.acceptData( elem ) ) { 1702 return; 1703 } 1704 1705 var privateCache, thisCache, ret, 1706 internalKey = jQuery.expando, 1707 getByName = typeof name === "string", 1708 1709 // We have to handle DOM nodes and JS objects differently because IE6-7 1710 // can't GC object references properly across the DOM-JS boundary 1711 isNode = elem.nodeType, 1712 1713 // Only DOM nodes need the global jQuery cache; JS object data is 1714 // attached directly to the object so GC can occur automatically 1715 cache = isNode ? jQuery.cache : elem, 1716 1717 // Only defining an ID for JS objects if its cache already exists allows 1718 // the code to shortcut on the same path as a DOM node with no cache 1719 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando, 1720 isEvents = name === "events"; 1721 1722 // Avoid doing any more work than we need to when trying to get data on an 1723 // object that has no data at all 1724 if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { 1725 return; 1726 } 1727 1728 if ( !id ) { 1729 // Only DOM nodes need a new unique ID for each element since their data 1730 // ends up in the global cache 1731 if ( isNode ) { 1732 elem[ jQuery.expando ] = id = ++jQuery.uuid; 1733 } else { 1734 id = jQuery.expando; 1735 } 1736 } 1737 1738 if ( !cache[ id ] ) { 1739 cache[ id ] = {}; 1740 1741 // Avoids exposing jQuery metadata on plain JS objects when the object 1742 // is serialized using JSON.stringify 1743 if ( !isNode ) { 1744 cache[ id ].toJSON = jQuery.noop; 1745 } 1746 } 1747 1748 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1749 // shallow copied over onto the existing cache 1750 if ( typeof name === "object" || typeof name === "function" ) { 1751 if ( pvt ) { 1752 cache[ id ] = jQuery.extend( cache[ id ], name ); 1753 } else { 1754 cache[ id ].data = jQuery.extend( cache[ id ].data, name ); 1755 } 1756 } 1757 1758 privateCache = thisCache = cache[ id ]; 1759 1760 // jQuery data() is stored in a separate object inside the object's internal data 1761 // cache in order to avoid key collisions between internal data and user-defined 1762 // data. 1763 if ( !pvt ) { 1764 if ( !thisCache.data ) { 1765 thisCache.data = {}; 1766 } 1767 1768 thisCache = thisCache.data; 1769 } 1770 1771 if ( data !== undefined ) { 1772 thisCache[ jQuery.camelCase( name ) ] = data; 1773 } 1774 1775 // Users should not attempt to inspect the internal events object using jQuery.data, 1776 // it is undocumented and subject to change. But does anyone listen? No. 1777 if ( isEvents && !thisCache[ name ] ) { 1778 return privateCache.events; 1779 } 1780 1781 // Check for both converted-to-camel and non-converted data property names 1782 // If a data property was specified 1783 if ( getByName ) { 1784 1785 // First Try to find as-is property data 1786 ret = thisCache[ name ]; 1787 1788 // Test for null|undefined property data 1789 if ( ret == null ) { 1790 1791 // Try to find the camelCased property 1792 ret = thisCache[ jQuery.camelCase( name ) ]; 1793 } 1794 } else { 1795 ret = thisCache; 1796 } 1797 1798 return ret; 1799 }, 1800 1801 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1802 if ( !jQuery.acceptData( elem ) ) { 1803 return; 1804 } 1805 1806 var thisCache, i, l, 1807 1808 // Reference to internal data cache key 1809 internalKey = jQuery.expando, 1810 1811 isNode = elem.nodeType, 1812 1813 // See jQuery.data for more information 1814 cache = isNode ? jQuery.cache : elem, 1815 1816 // See jQuery.data for more information 1817 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 1818 1819 // If there is already no cache entry for this object, there is no 1820 // purpose in continuing 1821 if ( !cache[ id ] ) { 1822 return; 1823 } 1824 1825 if ( name ) { 1826 1827 thisCache = pvt ? cache[ id ] : cache[ id ].data; 1828 1829 if ( thisCache ) { 1830 1831 // Support space separated names 1832 if ( jQuery.isArray( name ) ) { 1833 name = name; 1834 } else if ( name in thisCache ) { 1835 name = [ name ]; 1836 } else { 1837 1838 // split the camel cased version by spaces 1839 name = jQuery.camelCase( name ); 1840 if ( name in thisCache ) { 1841 name = [ name ]; 1842 } else { 1843 name = name.split( " " ); 1844 } 1845 } 1846 1847 for ( i = 0, l = name.length; i < l; i++ ) { 1848 delete thisCache[ name[i] ]; 1849 } 1850 1851 // If there is no data left in the cache, we want to continue 1852 // and let the cache object itself get destroyed 1853 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { 1854 return; 1855 } 1856 } 1857 } 1858 1859 // See jQuery.data for more information 1860 if ( !pvt ) { 1861 delete cache[ id ].data; 1862 1863 // Don't destroy the parent cache unless the internal data object 1864 // had been the only thing left in it 1865 if ( !isEmptyDataObject(cache[ id ]) ) { 1866 return; 1867 } 1868 } 1869 1870 // Browsers that fail expando deletion also refuse to delete expandos on 1871 // the window, but it will allow it on all other JS objects; other browsers 1872 // don't care 1873 // Ensure that `cache` is not a window object #10080 1874 if ( jQuery.support.deleteExpando || !cache.setInterval ) { 1875 delete cache[ id ]; 1876 } else { 1877 cache[ id ] = null; 1878 } 1879 1880 // We destroyed the cache and need to eliminate the expando on the node to avoid 1881 // false lookups in the cache for entries that no longer exist 1882 if ( isNode ) { 1883 // IE does not allow us to delete expando properties from nodes, 1884 // nor does it have a removeAttribute function on Document nodes; 1885 // we must handle all of these cases 1886 if ( jQuery.support.deleteExpando ) { 1887 delete elem[ jQuery.expando ]; 1888 } else if ( elem.removeAttribute ) { 1889 elem.removeAttribute( jQuery.expando ); 1890 } else { 1891 elem[ jQuery.expando ] = null; 1892 } 1893 } 1894 }, 1895 1896 // For internal use only. 1897 _data: function( elem, name, data ) { 1898 return jQuery.data( elem, name, data, true ); 1899 }, 1900 1901 // A method for determining if a DOM node can handle the data expando 1902 acceptData: function( elem ) { 1903 if ( elem.nodeName ) { 1904 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1905 1906 if ( match ) { 1907 return !(match === true || elem.getAttribute("classid") !== match); 1908 } 1909 } 1910 1911 return true; 1912 } 1913}); 1914 1915jQuery.fn.extend({ 1916 data: function( key, value ) { 1917 var parts, attr, name, 1918 data = null; 1919 1920 if ( typeof key === "undefined" ) { 1921 if ( this.length ) { 1922 data = jQuery.data( this[0] ); 1923 1924 if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { 1925 attr = this[0].attributes; 1926 for ( var i = 0, l = attr.length; i < l; i++ ) { 1927 name = attr[i].name; 1928 1929 if ( name.indexOf( "data-" ) === 0 ) { 1930 name = jQuery.camelCase( name.substring(5) ); 1931 1932 dataAttr( this[0], name, data[ name ] ); 1933 } 1934 } 1935 jQuery._data( this[0], "parsedAttrs", true ); 1936 } 1937 } 1938 1939 return data; 1940 1941 } else if ( typeof key === "object" ) { 1942 return this.each(function() { 1943 jQuery.data( this, key ); 1944 }); 1945 } 1946 1947 parts = key.split("."); 1948 parts[1] = parts[1] ? "." + parts[1] : ""; 1949 1950 if ( value === undefined ) { 1951 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 1952 1953 // Try to fetch any internally stored data first 1954 if ( data === undefined && this.length ) { 1955 data = jQuery.data( this[0], key ); 1956 data = dataAttr( this[0], key, data ); 1957 } 1958 1959 return data === undefined && parts[1] ? 1960 this.data( parts[0] ) : 1961 data; 1962 1963 } else { 1964 return this.each(function() { 1965 var $this = jQuery( this ), 1966 args = [ parts[0], value ]; 1967 1968 $this.triggerHandler( "setData" + parts[1] + "!", args ); 1969 jQuery.data( this, key, value ); 1970 $this.triggerHandler( "changeData" + parts[1] + "!", args ); 1971 }); 1972 } 1973 }, 1974 1975 removeData: function( key ) { 1976 return this.each(function() { 1977 jQuery.removeData( this, key ); 1978 }); 1979 } 1980}); 1981 1982function dataAttr( elem, key, data ) { 1983 // If nothing was found internally, try to fetch any 1984 // data from the HTML5 data-* attribute 1985 if ( data === undefined && elem.nodeType === 1 ) { 1986 1987 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); 1988 1989 data = elem.getAttribute( name ); 1990 1991 if ( typeof data === "string" ) { 1992 try { 1993 data = data === "true" ? true : 1994 data === "false" ? false : 1995 data === "null" ? null : 1996 jQuery.isNumeric( data ) ? parseFloat( data ) : 1997 rbrace.test( data ) ? jQuery.parseJSON( data ) : 1998 data; 1999 } catch( e ) {} 2000 2001 // Make sure we set the data so it isn't changed later 2002 jQuery.data( elem, key, data ); 2003 2004 } else { 2005 data = undefined; 2006 } 2007 } 2008 2009 return data; 2010} 2011 2012// checks a cache object for emptiness 2013function isEmptyDataObject( obj ) { 2014 for ( var name in obj ) { 2015 2016 // if the public data object is empty, the private is still empty 2017 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { 2018 continue; 2019 } 2020 if ( name !== "toJSON" ) { 2021 return false; 2022 } 2023 } 2024 2025 return true; 2026} 2027 2028 2029 2030 2031function handleQueueMarkDefer( elem, type, src ) { 2032 var deferDataKey = type + "defer", 2033 queueDataKey = type + "queue", 2034 markDataKey = type + "mark", 2035 defer = jQuery._data( elem, deferDataKey ); 2036 if ( defer && 2037 ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && 2038 ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { 2039 // Give room for hard-coded callbacks to fire first 2040 // and eventually mark/queue something else on the element 2041 setTimeout( function() { 2042 if ( !jQuery._data( elem, queueDataKey ) && 2043 !jQuery._data( elem, markDataKey ) ) { 2044 jQuery.removeData( elem, deferDataKey, true ); 2045 defer.fire(); 2046 } 2047 }, 0 ); 2048 } 2049} 2050 2051jQuery.extend({ 2052 2053 _mark: function( elem, type ) { 2054 if ( elem ) { 2055 type = ( type || "fx" ) + "mark"; 2056 jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); 2057 } 2058 }, 2059 2060 _unmark: function( force, elem, type ) { 2061 if ( force !== true ) { 2062 type = elem; 2063 elem = force; 2064 force = false; 2065 } 2066 if ( elem ) { 2067 type = type || "fx"; 2068 var key = type + "mark", 2069 count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); 2070 if ( count ) { 2071 jQuery._data( elem, key, count ); 2072 } else { 2073 jQuery.removeData( elem, key, true ); 2074 handleQueueMarkDefer( elem, type, "mark" ); 2075 } 2076 } 2077 }, 2078 2079 queue: function( elem, type, data ) { 2080 var q; 2081 if ( elem ) { 2082 type = ( type || "fx" ) + "queue"; 2083 q = jQuery._data( elem, type ); 2084 2085 // Speed up dequeue by getting out quickly if this is just a lookup 2086 if ( data ) { 2087 if ( !q || jQuery.isArray(data) ) { 2088 q = jQuery._data( elem, type, jQuery.makeArray(data) ); 2089 } else { 2090 q.push( data ); 2091 } 2092 } 2093 return q || []; 2094 } 2095 }, 2096 2097 dequeue: function( elem, type ) { 2098 type = type || "fx"; 2099 2100 var queue = jQuery.queue( elem, type ), 2101 fn = queue.shift(), 2102 hooks = {}; 2103 2104 // If the fx queue is dequeued, always remove the progress sentinel 2105 if ( fn === "inprogress" ) { 2106 fn = queue.shift(); 2107 } 2108 2109 if ( fn ) { 2110 // Add a progress sentinel to prevent the fx queue from being 2111 // automatically dequeued 2112 if ( type === "fx" ) { 2113 queue.unshift( "inprogress" ); 2114 } 2115 2116 jQuery._data( elem, type + ".run", hooks ); 2117 fn.call( elem, function() { 2118 jQuery.dequeue( elem, type ); 2119 }, hooks ); 2120 } 2121 2122 if ( !queue.length ) { 2123 jQuery.removeData( elem, type + "queue " + type + ".run", true ); 2124 handleQueueMarkDefer( elem, type, "queue" ); 2125 } 2126 } 2127}); 2128 2129jQuery.fn.extend({ 2130 queue: function( type, data ) { 2131 if ( typeof type !== "string" ) { 2132 data = type; 2133 type = "fx"; 2134 } 2135 2136 if ( data === undefined ) { 2137 return jQuery.queue( this[0], type ); 2138 } 2139 return this.each(function() { 2140 var queue = jQuery.queue( this, type, data ); 2141 2142 if ( type === "fx" && queue[0] !== "inprogress" ) { 2143 jQuery.dequeue( this, type ); 2144 } 2145 }); 2146 }, 2147 dequeue: function( type ) { 2148 return this.each(function() { 2149 jQuery.dequeue( this, type ); 2150 }); 2151 }, 2152 // Based off of the plugin by Clint Helfers, with permission. 2153 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 2154 delay: function( time, type ) { 2155 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 2156 type = type || "fx"; 2157 2158 return this.queue( type, function( next, hooks ) { 2159 var timeout = setTimeout( next, time ); 2160 hooks.stop = function() { 2161 clearTimeout( timeout ); 2162 }; 2163 }); 2164 }, 2165 clearQueue: function( type ) { 2166 return this.queue( type || "fx", [] ); 2167 }, 2168 // Get a promise resolved when queues of a certain type 2169 // are emptied (fx is the type by default) 2170 promise: function( type, object ) { 2171 if ( typeof type !== "string" ) { 2172 object = type; 2173 type = undefined; 2174 } 2175 type = type || "fx"; 2176 var defer = jQuery.Deferred(), 2177 elements = this, 2178 i = elements.length, 2179 count = 1, 2180 deferDataKey = type + "defer", 2181 queueDataKey = type + "queue", 2182 markDataKey = type + "mark", 2183 tmp; 2184 function resolve() { 2185 if ( !( --count ) ) { 2186 defer.resolveWith( elements, [ elements ] ); 2187 } 2188 } 2189 while( i-- ) { 2190 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || 2191 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || 2192 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && 2193 jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { 2194 count++; 2195 tmp.add( resolve ); 2196 } 2197 } 2198 resolve(); 2199 return defer.promise(); 2200 } 2201}); 2202 2203 2204 2205 2206var rclass = /[\n\t\r]/g, 2207 rspace = /\s+/, 2208 rreturn = /\r/g, 2209 rtype = /^(?:button|input)$/i, 2210 rfocusable = /^(?:button|input|object|select|textarea)$/i, 2211 rclickable = /^a(?:rea)?$/i, 2212 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 2213 getSetAttribute = jQuery.support.getSetAttribute, 2214 nodeHook, boolHook, fixSpecified; 2215 2216jQuery.fn.extend({ 2217 attr: function( name, value ) { 2218 return jQuery.access( this, name, value, true, jQuery.attr ); 2219 }, 2220 2221 removeAttr: function( name ) { 2222 return this.each(function() { 2223 jQuery.removeAttr( this, name ); 2224 }); 2225 }, 2226 2227 prop: function( name, value ) { 2228 return jQuery.access( this, name, value, true, jQuery.prop ); 2229 }, 2230 2231 removeProp: function( name ) { 2232 name = jQuery.propFix[ name ] || name; 2233 return this.each(function() { 2234 // try/catch handles cases where IE balks (such as removing a property on window) 2235 try { 2236 this[ name ] = undefined; 2237 delete this[ name ]; 2238 } catch( e ) {} 2239 }); 2240 }, 2241 2242 addClass: function( value ) { 2243 var classNames, i, l, elem, 2244 setClass, c, cl; 2245 2246 if ( jQuery.isFunction( value ) ) { 2247 return this.each(function( j ) { 2248 jQuery( this ).addClass( value.call(this, j, this.className) ); 2249 }); 2250 } 2251 2252 if ( value && typeof value === "string" ) { 2253 classNames = value.split( rspace ); 2254 2255 for ( i = 0, l = this.length; i < l; i++ ) { 2256 elem = this[ i ]; 2257 2258 if ( elem.nodeType === 1 ) { 2259 if ( !elem.className && classNames.length === 1 ) { 2260 elem.className = value; 2261 2262 } else { 2263 setClass = " " + elem.className + " "; 2264 2265 for ( c = 0, cl = classNames.length; c < cl; c++ ) { 2266 if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { 2267 setClass += classNames[ c ] + " "; 2268 } 2269 } 2270 elem.className = jQuery.trim( setClass ); 2271 } 2272 } 2273 } 2274 } 2275 2276 return this; 2277 }, 2278 2279 removeClass: function( value ) { 2280 var classNames, i, l, elem, className, c, cl; 2281 2282 if ( jQuery.isFunction( value ) ) { 2283 return this.each(function( j ) { 2284 jQuery( this ).removeClass( value.call(this, j, this.className) ); 2285 }); 2286 } 2287 2288 if ( (value && typeof value === "string") || value === undefined ) { 2289 classNames = ( value || "" ).split( rspace ); 2290 2291 for ( i = 0, l = this.length; i < l; i++ ) { 2292 elem = this[ i ]; 2293 2294 if ( elem.nodeType === 1 && elem.className ) { 2295 if ( value ) { 2296 className = (" " + elem.className + " ").replace( rclass, " " ); 2297 for ( c = 0, cl = classNames.length; c < cl; c++ ) { 2298 className = className.replace(" " + classNames[ c ] + " ", " "); 2299 } 2300 elem.className = jQuery.trim( className ); 2301 2302 } else { 2303 elem.className = ""; 2304 } 2305 } 2306 } 2307 } 2308 2309 return this; 2310 }, 2311 2312 toggleClass: function( value, stateVal ) { 2313 var type = typeof value, 2314 isBool = typeof stateVal === "boolean"; 2315 2316 if ( jQuery.isFunction( value ) ) { 2317 return this.each(function( i ) { 2318 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); 2319 }); 2320 } 2321 2322 return this.each(function() { 2323 if ( type === "string" ) { 2324 // toggle individual class names 2325 var className, 2326 i = 0, 2327 self = jQuery( this ), 2328 state = stateVal, 2329 classNames = value.split( rspace ); 2330 2331 while ( (className = classNames[ i++ ]) ) { 2332 // check each className given, space seperated list 2333 state = isBool ? state : !self.hasClass( className ); 2334 self[ state ? "addClass" : "removeClass" ]( className ); 2335 } 2336 2337 } else if ( type === "undefined" || type === "boolean" ) { 2338 if ( this.className ) { 2339 // store className if set 2340 jQuery._data( this, "__className__", this.className ); 2341 } 2342 2343 // toggle whole className 2344 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 2345 } 2346 }); 2347 }, 2348 2349 hasClass: function( selector ) { 2350 var className = " " + selector + " ", 2351 i = 0, 2352 l = this.length; 2353 for ( ; i < l; i++ ) { 2354 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 2355 return true; 2356 } 2357 } 2358 2359 return false; 2360 }, 2361 2362 val: function( value ) { 2363 var hooks, ret, isFunction, 2364 elem = this[0]; 2365 2366 if ( !arguments.length ) { 2367 if ( elem ) { 2368 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; 2369 2370 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 2371 return ret; 2372 } 2373 2374 ret = elem.value; 2375 2376 return typeof ret === "string" ? 2377 // handle most common string cases 2378 ret.replace(rreturn, "") : 2379 // handle cases where value is null/undef or number 2380 ret == null ? "" : ret; 2381 } 2382 2383 return undefined; 2384 } 2385 2386 isFunction = jQuery.isFunction( value ); 2387 2388 return this.each(function( i ) { 2389 var self = jQuery(this), val; 2390 2391 if ( this.nodeType !== 1 ) { 2392 return; 2393 } 2394 2395 if ( isFunction ) { 2396 val = value.call( this, i, self.val() ); 2397 } else { 2398 val = value; 2399 } 2400 2401 // Treat null/undefined as ""; convert numbers to string 2402 if ( val == null ) { 2403 val = ""; 2404 } else if ( typeof val === "number" ) { 2405 val += ""; 2406 } else if ( jQuery.isArray( val ) ) { 2407 val = jQuery.map(val, function ( value ) { 2408 return value == null ? "" : value + ""; 2409 }); 2410 } 2411 2412 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; 2413 2414 // If set returns undefined, fall back to normal setting 2415 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 2416 this.value = val; 2417 } 2418 }); 2419 } 2420}); 2421 2422jQuery.extend({ 2423 valHooks: { 2424 option: { 2425 get: function( elem ) { 2426 // attributes.value is undefined in Blackberry 4.7 but 2427 // uses .value. See #6932 2428 var val = elem.attributes.value; 2429 return !val || val.specified ? elem.value : elem.text; 2430 } 2431 }, 2432 select: { 2433 get: function( elem ) { 2434 var value, i, max, option, 2435 index = elem.selectedIndex, 2436 values = [], 2437 options = elem.options, 2438 one = elem.type === "select-one"; 2439 2440 // Nothing was selected 2441 if ( index < 0 ) { 2442 return null; 2443 } 2444 2445 // Loop through all the selected options 2446 i = one ? index : 0; 2447 max = one ? index + 1 : options.length; 2448 for ( ; i < max; i++ ) { 2449 option = options[ i ]; 2450 2451 // Don't return options that are disabled or in a disabled optgroup 2452 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 2453 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 2454 2455 // Get the specific value for the option 2456 value = jQuery( option ).val(); 2457 2458 // We don't need an array for one selects 2459 if ( one ) { 2460 return value; 2461 } 2462 2463 // Multi-Selects return an array 2464 values.push( value ); 2465 } 2466 } 2467 2468 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() 2469 if ( one && !values.length && options.length ) { 2470 return jQuery( options[ index ] ).val(); 2471 } 2472 2473 return values; 2474 }, 2475 2476 set: function( elem, value ) { 2477 var values = jQuery.makeArray( value ); 2478 2479 jQuery(elem).find("option").each(function() { 2480 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 2481 }); 2482 2483 if ( !values.length ) { 2484 elem.selectedIndex = -1; 2485 } 2486 return values; 2487 } 2488 } 2489 }, 2490 2491 attrFn: { 2492 val: true, 2493 css: true, 2494 html: true, 2495 text: true, 2496 data: true, 2497 width: true, 2498 height: true, 2499 offset: true 2500 }, 2501 2502 attr: function( elem, name, value, pass ) { 2503 var ret, hooks, notxml, 2504 nType = elem.nodeType; 2505 2506 // don't get/set attributes on text, comment and attribute nodes 2507 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2508 return undefined; 2509 } 2510 2511 if ( pass && name in jQuery.attrFn ) { 2512 return jQuery( elem )[ name ]( value ); 2513 } 2514 2515 // Fallback to prop when attributes are not supported 2516 if ( !("getAttribute" in elem) ) { 2517 return jQuery.prop( elem, name, value ); 2518 } 2519 2520 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2521 2522 // All attributes are lowercase 2523 // Grab necessary hook if one is defined 2524 if ( notxml ) { 2525 name = name.toLowerCase(); 2526 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); 2527 } 2528 2529 if ( value !== undefined ) { 2530 2531 if ( value === null ) { 2532 jQuery.removeAttr( elem, name ); 2533 return undefined; 2534 2535 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 2536 return ret; 2537 2538 } else { 2539 elem.setAttribute( name, "" + value ); 2540 return value; 2541 } 2542 2543 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { 2544 return ret; 2545 2546 } else { 2547 2548 ret = elem.getAttribute( name ); 2549 2550 // Non-existent attributes return null, we normalize to undefined 2551 return ret === null ? 2552 undefined : 2553 ret; 2554 } 2555 }, 2556 2557 removeAttr: function( elem, value ) { 2558 var propName, attrNames, name, l, 2559 i = 0; 2560 2561 if ( elem.nodeType === 1 ) { 2562 attrNames = ( value || "" ).split( rspace ); 2563 l = attrNames.length; 2564 2565 for ( ; i < l; i++ ) { 2566 name = attrNames[ i ].toLowerCase(); 2567 propName = jQuery.propFix[ name ] || name; 2568 2569 // See #9699 for explanation of this approach (setting first, then removal) 2570 jQuery.attr( elem, name, "" ); 2571 elem.removeAttribute( getSetAttribute ? name : propName ); 2572 2573 // Set corresponding property to false for boolean attributes 2574 if ( rboolean.test( name ) && propName in elem ) { 2575 elem[ propName ] = false; 2576 } 2577 } 2578 } 2579 }, 2580 2581 attrHooks: { 2582 type: { 2583 set: function( elem, value ) { 2584 // We can't allow the type property to be changed (since it causes problems in IE) 2585 if ( rtype.test( elem.nodeName ) && elem.parentNode ) { 2586 jQuery.error( "type property can't be changed" ); 2587 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { 2588 // Setting the type on a radio button after the value resets the value in IE6-9 2589 // Reset value to it's default in case type is set after value 2590 // This is for element creation 2591 var val = elem.value; 2592 elem.setAttribute( "type", value ); 2593 if ( val ) { 2594 elem.value = val; 2595 } 2596 return value; 2597 } 2598 } 2599 }, 2600 // Use the value property for back compat 2601 // Use the nodeHook for button elements in IE6/7 (#1954) 2602 value: { 2603 get: function( elem, name ) { 2604 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2605 return nodeHook.get( elem, name ); 2606 } 2607 return name in elem ? 2608 elem.value : 2609 null; 2610 }, 2611 set: function( elem, value, name ) { 2612 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2613 return nodeHook.set( elem, value, name ); 2614 } 2615 // Does not return so that setAttribute is also used 2616 elem.value = value; 2617 } 2618 } 2619 }, 2620 2621 propFix: { 2622 tabindex: "tabIndex", 2623 readonly: "readOnly", 2624 "for": "htmlFor", 2625 "class": "className", 2626 maxlength: "maxLength", 2627 cellspacing: "cellSpacing", 2628 cellpadding: "cellPadding", 2629 rowspan: "rowSpan", 2630 colspan: "colSpan", 2631 usemap: "useMap", 2632 frameborder: "frameBorder", 2633 contenteditable: "contentEditable" 2634 }, 2635 2636 prop: function( elem, name, value ) { 2637 var ret, hooks, notxml, 2638 nType = elem.nodeType; 2639 2640 // don't get/set properties on text, comment and attribute nodes 2641 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2642 return undefined; 2643 } 2644 2645 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2646 2647 if ( notxml ) { 2648 // Fix name and attach hooks 2649 name = jQuery.propFix[ name ] || name; 2650 hooks = jQuery.propHooks[ name ]; 2651 } 2652 2653 if ( value !== undefined ) { 2654 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 2655 return ret; 2656 2657 } else { 2658 return ( elem[ name ] = value ); 2659 } 2660 2661 } else { 2662 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { 2663 return ret; 2664 2665 } else { 2666 return elem[ name ]; 2667 } 2668 } 2669 }, 2670 2671 propHooks: { 2672 tabIndex: { 2673 get: function( elem ) { 2674 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2675 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2676 var attributeNode = elem.getAttributeNode("tabindex"); 2677 2678 return attributeNode && attributeNode.specified ? 2679 parseInt( attributeNode.value, 10 ) : 2680 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2681 0 : 2682 undefined; 2683 } 2684 } 2685 } 2686}); 2687 2688// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) 2689jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; 2690 2691// Hook for boolean attributes 2692boolHook = { 2693 get: function( elem, name ) { 2694 // Align boolean attributes with corresponding properties 2695 // Fall back to attribute presence where some booleans are not supported 2696 var attrNode, 2697 property = jQuery.prop( elem, name ); 2698 return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? 2699 name.toLowerCase() : 2700 undefined; 2701 }, 2702 set: function( elem, value, name ) { 2703 var propName; 2704 if ( value === false ) { 2705 // Remove boolean attributes when set to false 2706 jQuery.removeAttr( elem, name ); 2707 } else { 2708 // value is true since we know at this point it's type boolean and not false 2709 // Set boolean attributes to the same name and set the DOM property 2710 propName = jQuery.propFix[ name ] || name; 2711 if ( propName in elem ) { 2712 // Only set the IDL specifically if it already exists on the element 2713 elem[ propName ] = true; 2714 } 2715 2716 elem.setAttribute( name, name.toLowerCase() ); 2717 } 2718 return name; 2719 } 2720}; 2721 2722// IE6/7 do not support getting/setting some attributes with get/setAttribute 2723if ( !getSetAttribute ) { 2724 2725 fixSpecified = { 2726 name: true, 2727 id: true 2728 }; 2729 2730 // Use this for any attribute in IE6/7 2731 // This fixes almost every IE6/7 issue 2732 nodeHook = jQuery.valHooks.button = { 2733 get: function( elem, name ) { 2734 var ret; 2735 ret = elem.getAttributeNode( name ); 2736 return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? 2737 ret.nodeValue : 2738 undefined; 2739 }, 2740 set: function( elem, value, name ) { 2741 // Set the existing or create a new attribute node 2742 var ret = elem.getAttributeNode( name ); 2743 if ( !ret ) { 2744 ret = document.createAttribute( name ); 2745 elem.setAttributeNode( ret ); 2746 } 2747 return ( ret.nodeValue = value + "" ); 2748 } 2749 }; 2750 2751 // Apply the nodeHook to tabindex 2752 jQuery.attrHooks.tabindex.set = nodeHook.set; 2753 2754 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 2755 // This is for removals 2756 jQuery.each([ "width", "height" ], function( i, name ) { 2757 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2758 set: function( elem, value ) { 2759 if ( value === "" ) { 2760 elem.setAttribute( name, "auto" ); 2761 return value; 2762 } 2763 } 2764 }); 2765 }); 2766 2767 // Set contenteditable to false on removals(#10429) 2768 // Setting to empty string throws an error as an invalid value 2769 jQuery.attrHooks.contenteditable = { 2770 get: nodeHook.get, 2771 set: function( elem, value, name ) { 2772 if ( value === "" ) { 2773 value = "false"; 2774 } 2775 nodeHook.set( elem, value, name ); 2776 } 2777 }; 2778} 2779 2780 2781// Some attributes require a special call on IE 2782if ( !jQuery.support.hrefNormalized ) { 2783 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { 2784 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2785 get: function( elem ) { 2786 var ret = elem.getAttribute( name, 2 ); 2787 return ret === null ? undefined : ret; 2788 } 2789 }); 2790 }); 2791} 2792 2793if ( !jQuery.support.style ) { 2794 jQuery.attrHooks.style = { 2795 get: function( elem ) { 2796 // Return undefined in the case of empty string 2797 // Normalize to lowercase since IE uppercases css property names 2798 return elem.style.cssText.toLowerCase() || undefined; 2799 }, 2800 set: function( elem, value ) { 2801 return ( elem.style.cssText = "" + value ); 2802 } 2803 }; 2804} 2805 2806// Safari mis-reports the default selected property of an option 2807// Accessing the parent's selectedIndex property fixes it 2808if ( !jQuery.support.optSelected ) { 2809 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { 2810 get: function( elem ) { 2811 var parent = elem.parentNode; 2812 2813 if ( parent ) { 2814 parent.selectedIndex; 2815 2816 // Make sure that it also works with optgroups, see #5701 2817 if ( parent.parentNode ) { 2818 parent.parentNode.selectedIndex; 2819 } 2820 } 2821 return null; 2822 } 2823 }); 2824} 2825 2826// IE6/7 call enctype encoding 2827if ( !jQuery.support.enctype ) { 2828 jQuery.propFix.enctype = "encoding"; 2829} 2830 2831// Radios and checkboxes getter/setter 2832if ( !jQuery.support.checkOn ) { 2833 jQuery.each([ "radio", "checkbox" ], function() { 2834 jQuery.valHooks[ this ] = { 2835 get: function( elem ) { 2836 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 2837 return elem.getAttribute("value") === null ? "on" : elem.value; 2838 } 2839 }; 2840 }); 2841} 2842jQuery.each([ "radio", "checkbox" ], function() { 2843 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { 2844 set: function( elem, value ) { 2845 if ( jQuery.isArray( value ) ) { 2846 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); 2847 } 2848 } 2849 }); 2850}); 2851 2852 2853 2854 2855var rnamespaces = /\.(.*)$/, 2856 rformElems = /^(?:textarea|input|select)$/i, 2857 rperiod = /\./g, 2858 rspaces = / /g, 2859 rescape = /[^\w\s.|`]/g, 2860 rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, 2861 rhoverHack = /\bhover(\.\S+)?/, 2862 rkeyEvent = /^key/, 2863 rmouseEvent = /^(?:mouse|contextmenu)|click/, 2864 rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, 2865 quickParse = function( selector ) { 2866 var quick = rquickIs.exec( selector ); 2867 if ( quick ) { 2868 // 0 1 2 3 2869 // [ _, tag, id, class ] 2870 quick[1] = ( quick[1] || "" ).toLowerCase(); 2871 quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); 2872 } 2873 return quick; 2874 }, 2875 quickIs = function( elem, m ) { 2876 return ( 2877 (!m[1] || elem.nodeName.toLowerCase() === m[1]) && 2878 (!m[2] || elem.id === m[2]) && 2879 (!m[3] || m[3].test( elem.className )) 2880 ); 2881 }, 2882 hoverHack = function( events ) { 2883 return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); 2884 }; 2885 2886/* 2887 * Helper functions for managing events -- not part of the public interface. 2888 * Props to Dean Edwards' addEvent library for many of the ideas. 2889 */ 2890jQuery.event = { 2891 2892 add: function( elem, types, handler, data, selector ) { 2893 2894 var elemData, eventHandle, events, 2895 t, tns, type, namespaces, handleObj, 2896 handleObjIn, quick, handlers, special; 2897 2898 // Don't attach events to noData or text/comment nodes (allow plain objects tho) 2899 if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { 2900 return; 2901 } 2902 2903 // Caller can pass in an object of custom data in lieu of the handler 2904 if ( handler.handler ) { 2905 handleObjIn = handler; 2906 handler = handleObjIn.handler; 2907 } 2908 2909 // Make sure that the handler has a unique ID, used to find/remove it later 2910 if ( !handler.guid ) { 2911 handler.guid = jQuery.guid++; 2912 } 2913 2914 // Init the element's event structure and main handler, if this is the first 2915 events = elemData.events; 2916 if ( !events ) { 2917 elemData.events = events = {}; 2918 } 2919 eventHandle = elemData.handle; 2920 if ( !eventHandle ) { 2921 elemData.handle = eventHandle = function( e ) { 2922 // Discard the second event of a jQuery.event.trigger() and 2923 // when an event is called after a page has unloaded 2924 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? 2925 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : 2926 undefined; 2927 }; 2928 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events 2929 eventHandle.elem = elem; 2930 } 2931 2932 // Handle multiple events separated by a space 2933 // jQuery(...).bind("mouseover mouseout", fn); 2934 types = hoverHack(types).split( " " ); 2935 for ( t = 0; t < types.length; t++ ) { 2936 2937 tns = rtypenamespace.exec( types[t] ) || []; 2938 type = tns[1]; 2939 namespaces = ( tns[2] || "" ).split( "." ).sort(); 2940 2941 // If event changes its type, use the special event handlers for the changed type 2942 special = jQuery.event.special[ type ] || {}; 2943 2944 // If selector defined, determine special event api type, otherwise given type 2945 type = ( selector ? special.delegateType : special.bindType ) || type; 2946 2947 // Update special based on newly reset type 2948 special = jQuery.event.special[ type ] || {}; 2949 2950 // handleObj is passed to all event handlers 2951 handleObj = jQuery.extend({ 2952 type: type, 2953 origType: tns[1], 2954 data: data, 2955 handler: handler, 2956 guid: handler.guid, 2957 selector: selector, 2958 namespace: namespaces.join(".") 2959 }, handleObjIn ); 2960 2961 // Delegated event; pre-analyze selector so it's processed quickly on event dispatch 2962 if ( selector ) { 2963 handleObj.quick = quickParse( selector ); 2964 if ( !handleObj.quick && jQuery.expr.match.POS.test( selector ) ) { 2965 handleObj.isPositional = true; 2966 } 2967 } 2968 2969 // Init the event handler queue if we're the first 2970 handlers = events[ type ]; 2971 if ( !handlers ) { 2972 handlers = events[ type ] = []; 2973 handlers.delegateCount = 0; 2974 2975 // Only use addEventListener/attachEvent if the special events handler returns false 2976 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2977 // Bind the global event handler to the element 2978 if ( elem.addEventListener ) { 2979 elem.addEventListener( type, eventHandle, false ); 2980 2981 } else if ( elem.attachEvent ) { 2982 elem.attachEvent( "on" + type, eventHandle ); 2983 } 2984 } 2985 } 2986 2987 if ( special.add ) { 2988 special.add.call( elem, handleObj ); 2989 2990 if ( !handleObj.handler.guid ) { 2991 handleObj.handler.guid = handler.guid; 2992 } 2993 } 2994 2995 // Add to the element's handler list, delegates in front 2996 if ( selector ) { 2997 handlers.splice( handlers.delegateCount++, 0, handleObj ); 2998 } else { 2999 handlers.push( handleObj ); 3000 } 3001 3002 // Keep track of which events have ever been used, for event optimization 3003 jQuery.event.global[ type ] = true; 3004 } 3005 3006 // Nullify elem to prevent memory leaks in IE 3007 elem = null; 3008 }, 3009 3010 global: {}, 3011 3012 // Detach an event or set of events from an element 3013 remove: function( elem, types, handler, selector ) { 3014 3015 var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), 3016 t, tns, type, namespaces, origCount, 3017 j, events, special, handle, eventType, handleObj; 3018 3019 if ( !elemData || !(events = elemData.events) ) { 3020 return; 3021 } 3022 3023 // Once for each type.namespace in types; type may be omitted 3024 types = hoverHack( types || "" ).split(" "); 3025 for ( t = 0; t < types.length; t++ ) { 3026 tns = rtypenamespace.exec( types[t] ) || []; 3027 type = tns[1]; 3028 namespaces = tns[2]; 3029 3030 // Unbind all events (on this namespace, if provided) for the element 3031 if ( !type ) { 3032 namespaces = namespaces? "." + namespaces : ""; 3033 for ( j in events ) { 3034 jQuery.event.remove( elem, j + namespaces, handler, selector ); 3035 } 3036 return; 3037 } 3038 3039 special = jQuery.event.special[ type ] || {}; 3040 type = ( selector? special.delegateType : special.bindType ) || type; 3041 eventType = events[ type ] || []; 3042 origCount = eventType.length; 3043 namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; 3044 3045 // Only need to loop for special events or selective removal 3046 if ( handler || namespaces || selector || special.remove ) { 3047 for ( j = 0; j < eventType.length; j++ ) { 3048 handleObj = eventType[ j ]; 3049 3050 if ( !handler || handler.guid === handleObj.guid ) { 3051 if ( !namespaces || namespaces.test( handleObj.namespace ) ) { 3052 if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) { 3053 eventType.splice( j--, 1 ); 3054 3055 if ( handleObj.selector ) { 3056 eventType.delegateCount--; 3057 } 3058 if ( special.remove ) { 3059 special.remove.call( elem, handleObj ); 3060 } 3061 } 3062 } 3063 } 3064 } 3065 } else { 3066 // Removing all events 3067 eventType.length = 0; 3068 } 3069 3070 // Remove generic event handler if we removed something and no more handlers exist 3071 // (avoids potential for endless recursion during removal of special event handlers) 3072 if ( eventType.length === 0 && origCount !== eventType.length ) { 3073 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 3074 jQuery.removeEvent( elem, type, elemData.handle ); 3075 } 3076 3077 delete events[ type ]; 3078 } 3079 } 3080 3081 // Remove the expando if it's no longer used 3082 if ( jQuery.isEmptyObject( events ) ) { 3083 handle = elemData.handle; 3084 if ( handle ) { 3085 handle.elem = null; 3086 } 3087 3088 // removeData also checks for emptiness and clears the expando if empty 3089 // so use it instead of delete 3090 jQuery.removeData( elem, [ "events", "handle" ], true ); 3091 } 3092 }, 3093 3094 // Events that are safe to short-circuit if no handlers are attached. 3095 // Native DOM events should not be added, they may have inline handlers. 3096 customEvent: { 3097 "getData": true, 3098 "setData": true, 3099 "changeData": true 3100 }, 3101 3102 trigger: function( event, data, elem, onlyHandlers ) { 3103 // Don't do events on text and comment nodes 3104 if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { 3105 return; 3106 } 3107 3108 // Event object or event type 3109 var type = event.type || event, 3110 namespaces = [], 3111 cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; 3112 3113 if ( type.indexOf( "!" ) >= 0 ) { 3114 // Exclusive events trigger only for the exact event (no namespaces) 3115 type = type.slice(0, -1); 3116 exclusive = true; 3117 } 3118 3119 if ( type.indexOf( "." ) >= 0 ) { 3120 // Namespaced trigger; create a regexp to match event type in handle() 3121 namespaces = type.split("."); 3122 type = namespaces.shift(); 3123 namespaces.sort(); 3124 } 3125 3126 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { 3127 // No jQuery handlers for this event type, and it can't have inline handlers 3128 return; 3129 } 3130 3131 // Caller can pass in an Event, Object, or just an event type string 3132 event = typeof event === "object" ? 3133 // jQuery.Event object 3134 event[ jQuery.expando ] ? event : 3135 // Object literal 3136 new jQuery.Event( type, event ) : 3137 // Just the event type (string) 3138 new jQuery.Event( type ); 3139 3140 event.type = type; 3141 event.isTrigger = true; 3142 event.exclusive = exclusive; 3143 event.namespace = namespaces.join( "." ); 3144 event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; 3145 ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; 3146 3147 // triggerHandler() and global events don't bubble or run the default action 3148 if ( onlyHandlers || !elem ) { 3149 event.preventDefault(); 3150 } 3151 3152 // Handle a global trigger 3153 if ( !elem ) { 3154 3155 // TODO: Stop taunting the data cache; remove global events and always attach to document 3156 cache = jQuery.cache; 3157 for ( i in cache ) { 3158 if ( cache[ i ].events && cache[ i ].events[ type ] ) { 3159 jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); 3160 } 3161 } 3162 return; 3163 } 3164 3165 // Clean up the event in case it is being reused 3166 event.result = undefined; 3167 if ( !event.target ) { 3168 event.target = elem; 3169 } 3170 3171 // Clone any incoming data and prepend the event, creating the handler arg list 3172 data = data != null ? jQuery.makeArray( data ) : []; 3173 data.unshift( event ); 3174 3175 // Allow special events to draw outside the lines 3176 special = jQuery.event.special[ type ] || {}; 3177 if ( special.trigger && special.trigger.apply( elem, data ) === false ) { 3178 return; 3179 } 3180 3181 // Determine event propagation path in advance, per W3C events spec (#9951) 3182 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 3183 eventPath = [[ elem, special.bindType || type ]]; 3184 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 3185 3186 bubbleType = special.delegateType || type; 3187 old = null; 3188 for ( cur = elem.parentNode; cur; cur = cur.parentNode ) { 3189 eventPath.push([ cur, bubbleType ]); 3190 old = cur; 3191 } 3192 3193 // Only add window if we got to document (e.g., not plain obj or detached DOM) 3194 if ( old && old === elem.ownerDocument ) { 3195 eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); 3196 } 3197 } 3198 3199 // Fire handlers on the event path 3200 for ( i = 0; i < eventPath.length; i++ ) { 3201 3202 cur = eventPath[i][0]; 3203 event.type = eventPath[i][1]; 3204 3205 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); 3206 if ( handle ) { 3207 handle.apply( cur, data ); 3208 } 3209 handle = ontype && cur[ ontype ]; 3210 if ( handle && jQuery.acceptData( cur ) ) { 3211 handle.apply( cur, data ); 3212 } 3213 3214 if ( event.isPropagationStopped() ) { 3215 break; 3216 } 3217 } 3218 event.type = type; 3219 3220 // If nobody prevented the default action, do it now 3221 if ( !event.isDefaultPrevented() ) { 3222 3223 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && 3224 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { 3225 3226 // Call a native DOM method on the target with the same name name as the event. 3227 // Can't use an .isFunction() check here because IE6/7 fails that test. 3228 // Don't do default actions on window, that's where global variables be (#6170) 3229 // IE<9 dies on focus/blur to hidden element (#1486) 3230 if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { 3231 3232 // Don't re-trigger an onFOO event when we call its FOO() method 3233 old = elem[ ontype ]; 3234 3235 if ( old ) { 3236 elem[ ontype ] = null; 3237 } 3238 3239 // Prevent re-triggering of the same event, since we already bubbled it above 3240 jQuery.event.triggered = type; 3241 elem[ type ](); 3242 jQuery.event.triggered = undefined; 3243 3244 if ( old ) { 3245 elem[ ontype ] = old; 3246 } 3247 } 3248 } 3249 } 3250 3251 return event.result; 3252 }, 3253 3254 dispatch: function( event ) { 3255 3256 // Make a writable jQuery.Event from the native event object 3257 event = jQuery.event.fix( event || window.event ); 3258 3259 var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), 3260 delegateCount = handlers.delegateCount, 3261 args = [].slice.call( arguments, 0 ), 3262 run_all = !event.exclusive && !event.namespace, 3263 specialHandle = ( jQuery.event.special[ event.type ] || {} ).handle, 3264 handlerQueue = [], 3265 i, j, cur, ret, selMatch, matched, matches, handleObj, sel, hit, related; 3266 3267 // Use the fix-ed jQuery.Event rather than the (read-only) native event 3268 args[0] = event; 3269 event.delegateTarget = this; 3270 3271 // Determine handlers that should run if there are delegated events 3272 // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) 3273 if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { 3274 3275 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { 3276 selMatch = {}; 3277 matches = []; 3278 for ( i = 0; i < delegateCount; i++ ) { 3279 handleObj = handlers[ i ]; 3280 sel = handleObj.selector; 3281 hit = selMatch[ sel ]; 3282 3283 if ( handleObj.isPositional ) { 3284 // Since .is() does not work for positionals; see http://jsfiddle.net/eJ4yd/3/ 3285 hit = ( hit || (selMatch[ sel ] = jQuery( sel )) ).index( cur ) >= 0; 3286 } else if ( hit === undefined ) { 3287 hit = selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jQuery( cur ).is( sel ) ); 3288 } 3289 if ( hit ) { 3290 matches.push( handleObj ); 3291 } 3292 } 3293 if ( matches.length ) { 3294 handlerQueue.push({ elem: cur, matches: matches }); 3295 } 3296 } 3297 } 3298 3299 // Add the remaining (directly-bound) handlers 3300 if ( handlers.length > delegateCount ) { 3301 handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); 3302 } 3303 3304 // Run delegates first; they may want to stop propagation beneath us 3305 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { 3306 matched = handlerQueue[ i ]; 3307 event.currentTarget = matched.elem; 3308 3309 for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { 3310 handleObj = matched.matches[ j ]; 3311 3312 // Triggered event must either 1) be non-exclusive and have no namespace, or 3313 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). 3314 if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { 3315 3316 event.data = handleObj.data; 3317 event.handleObj = handleObj; 3318 3319 ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args ); 3320 3321 if ( ret !== undefined ) { 3322 event.result = ret; 3323 if ( ret === false ) { 3324 event.preventDefault(); 3325 event.stopPropagation(); 3326 } 3327 } 3328 } 3329 } 3330 } 3331 3332 return event.result; 3333 }, 3334 3335 // Includes some event props shared by KeyEvent and MouseEvent 3336 // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** 3337 props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), 3338 3339 fixHooks: {}, 3340 3341 keyHooks: { 3342 props: "char charCode key keyCode".split(" "), 3343 filter: function( event, original ) { 3344 3345 // Add which for key events 3346 if ( event.which == null ) { 3347 event.which = original.charCode != null ? original.charCode : original.keyCode; 3348 } 3349 3350 return event; 3351 } 3352 }, 3353 3354 mouseHooks: { 3355 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "), 3356 filter: function( event, original ) { 3357 var eventDoc, doc, body, 3358 button = original.button, 3359 fromElement = original.fromElement; 3360 3361 // Calculate pageX/Y if missing and clientX/Y available 3362 if ( event.pageX == null && original.clientX != null ) { 3363 eventDoc = event.target.ownerDocument || document; 3364 doc = eventDoc.documentElement; 3365 body = eventDoc.body; 3366 3367 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 3368 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); 3369 } 3370 3371 // Add relatedTarget, if necessary 3372 if ( !event.relatedTarget && fromElement ) { 3373 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; 3374 } 3375 3376 // Add which for click: 1 === left; 2 === middle; 3 === right 3377 // Note: button is not normalized, so don't use it 3378 if ( !event.which && button !== undefined ) { 3379 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 3380 } 3381 3382 return event; 3383 } 3384 }, 3385 3386 fix: function( event ) { 3387 if ( event[ jQuery.expando ] ) { 3388 return event; 3389 } 3390 3391 // Create a writable copy of the event object and normalize some properties 3392 var i, prop, 3393 originalEvent = event, 3394 fixHook = jQuery.event.fixHooks[ event.type ] || {}, 3395 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 3396 3397 event = jQuery.Event( originalEvent ); 3398 3399 for ( i = copy.length; i; ) { 3400 prop = copy[ --i ]; 3401 event[ prop ] = originalEvent[ prop ]; 3402 } 3403 3404 // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) 3405 if ( !event.target ) { 3406 event.target = originalEvent.srcElement || document; 3407 } 3408 3409 // Target should not be a text node (#504, Safari) 3410 if ( event.target.nodeType === 3 ) { 3411 event.target = event.target.parentNode; 3412 } 3413 3414 // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) 3415 if ( event.metaKey === undefined ) { 3416 event.metaKey = event.ctrlKey; 3417 } 3418 3419 return fixHook.filter? fixHook.filter( event, originalEvent ) : event; 3420 }, 3421 3422 special: { 3423 ready: { 3424 // Make sure the ready event is setup 3425 setup: jQuery.bindReady 3426 }, 3427 3428 focus: { 3429 delegateType: "focusin", 3430 noBubble: true 3431 }, 3432 blur: { 3433 delegateType: "focusout", 3434 noBubble: true 3435 }, 3436 3437 beforeunload: { 3438 setup: function( data, namespaces, eventHandle ) { 3439 // We only want to do this special case on windows 3440 if ( jQuery.isWindow( this ) ) { 3441 this.onbeforeunload = eventHandle; 3442 } 3443 }, 3444 3445 teardown: function( namespaces, eventHandle ) { 3446 if ( this.onbeforeunload === eventHandle ) { 3447 this.onbeforeunload = null; 3448 } 3449 } 3450 } 3451 }, 3452 3453 simulate: function( type, elem, event, bubble ) { 3454 // Piggyback on a donor event to simulate a different one. 3455 // Fake originalEvent to avoid donor's stopPropagation, but if the 3456 // simulated event prevents default then we do the same on the donor. 3457 var e = jQuery.extend( 3458 new jQuery.Event(), 3459 event, 3460 { type: type, 3461 isSimulated: true, 3462 originalEvent: {} 3463 } 3464 ); 3465 if ( bubble ) { 3466 jQuery.event.trigger( e, null, elem ); 3467 } else { 3468 jQuery.event.dispatch.call( elem, e ); 3469 } 3470 if ( e.isDefaultPrevented() ) { 3471 event.preventDefault(); 3472 } 3473 } 3474}; 3475 3476// Some plugins are using, but it's undocumented/deprecated and will be removed. 3477// The 1.7 special event interface should provide all the hooks needed now. 3478jQuery.event.handle = jQuery.event.dispatch; 3479 3480jQuery.removeEvent = document.removeEventListener ? 3481 function( elem, type, handle ) { 3482 if ( elem.removeEventListener ) { 3483 elem.removeEventListener( type, handle, false ); 3484 } 3485 } : 3486 function( elem, type, handle ) { 3487 if ( elem.detachEvent ) { 3488 elem.detachEvent( "on" + type, handle ); 3489 } 3490 }; 3491 3492jQuery.Event = function( src, props ) { 3493 // Allow instantiation without the 'new' keyword 3494 if ( !(this instanceof jQuery.Event) ) { 3495 return new jQuery.Event( src, props ); 3496 } 3497 3498 // Event object 3499 if ( src && src.type ) { 3500 this.originalEvent = src; 3501 this.type = src.type; 3502 3503 // Events bubbling up the document may have been marked as prevented 3504 // by a handler lower down the tree; reflect the correct value. 3505 this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || 3506 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; 3507 3508 // Event type 3509 } else { 3510 this.type = src; 3511 } 3512 3513 // Put explicitly provided properties onto the event object 3514 if ( props ) { 3515 jQuery.extend( this, props ); 3516 } 3517 3518 // Create a timestamp if incoming event doesn't have one 3519 this.timeStamp = src && src.timeStamp || jQuery.now(); 3520 3521 // Mark it as fixed 3522 this[ jQuery.expando ] = true; 3523}; 3524 3525function returnFalse() { 3526 return false; 3527} 3528function returnTrue() { 3529 return true; 3530} 3531 3532// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 3533// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 3534jQuery.Event.prototype = { 3535 preventDefault: function() { 3536 this.isDefaultPrevented = returnTrue; 3537 3538 var e = this.originalEvent; 3539 if ( !e ) { 3540 return; 3541 } 3542 3543 // if preventDefault exists run it on the original event 3544 if ( e.preventDefault ) { 3545 e.preventDefault(); 3546 3547 // otherwise set the returnValue property of the original event to false (IE) 3548 } else { 3549 e.returnValue = false; 3550 } 3551 }, 3552 stopPropagation: function() { 3553 this.isPropagationStopped = returnTrue; 3554 3555 var e = this.originalEvent; 3556 if ( !e ) { 3557 return; 3558 } 3559 // if stopPropagation exists run it on the original event 3560 if ( e.stopPropagation ) { 3561 e.stopPropagation(); 3562 } 3563 // otherwise set the cancelBubble property of the original event to true (IE) 3564 e.cancelBubble = true; 3565 }, 3566 stopImmediatePropagation: function() { 3567 this.isImmediatePropagationStopped = returnTrue; 3568 this.stopPropagation(); 3569 }, 3570 isDefaultPrevented: returnFalse, 3571 isPropagationStopped: returnFalse, 3572 isImmediatePropagationStopped: returnFalse 3573}; 3574 3575// Create mouseenter/leave events using mouseover/out and event-time checks 3576jQuery.each({ 3577 mouseenter: "mouseover", 3578 mouseleave: "mouseout" 3579}, function( orig, fix ) { 3580 jQuery.event.special[ orig ] = jQuery.event.special[ fix ] = { 3581 delegateType: fix, 3582 bindType: fix, 3583 3584 handle: function( event ) { 3585 var target = this, 3586 related = event.relatedTarget, 3587 handleObj = event.handleObj, 3588 selector = handleObj.selector, 3589 oldType, ret; 3590 3591 // For a real mouseover/out, always call the handler; for 3592 // mousenter/leave call the handler if related is outside the target. 3593 // NB: No relatedTarget if the mouse left/entered the browser window 3594 if ( !related || handleObj.origType === event.type || (related !== target && !jQuery.contains( target, related )) ) { 3595 oldType = event.type; 3596 event.type = handleObj.origType; 3597 ret = handleObj.handler.apply( this, arguments ); 3598 event.type = oldType; 3599 } 3600 return ret; 3601 } 3602 }; 3603}); 3604 3605// IE submit delegation 3606if ( !jQuery.support.submitBubbles ) { 3607 3608 jQuery.event.special.submit = { 3609 setup: function() { 3610 // Only need this for delegated form submit events 3611 if ( jQuery.nodeName( this, "form" ) ) { 3612 return false; 3613 } 3614 3615 // Lazy-add a submit handler when a descendant form may potentially be submitted 3616 jQuery.event.add( this, "click._submit keypress._submit", function( e ) { 3617 // Node name check avoids a VML-related crash in IE (#9807) 3618 var elem = e.target, 3619 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; 3620 if ( form && !form._submit_attached ) { 3621 jQuery.event.add( form, "submit._submit", function( event ) { 3622 // Form was submitted, bubble the event up the tree 3623 if ( this.parentNode ) { 3624 jQuery.event.simulate( "submit", this.parentNode, event, true ); 3625 } 3626 }); 3627 form._submit_attached = true; 3628 } 3629 }); 3630 // return undefined since we don't need an event listener 3631 }, 3632 3633 teardown: function() { 3634 // Only need this for delegated form submit events 3635 if ( jQuery.nodeName( this, "form" ) ) { 3636 return false; 3637 } 3638 3639 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above 3640 jQuery.event.remove( this, "._submit" ); 3641 } 3642 }; 3643} 3644 3645// IE change delegation and checkbox/radio fix 3646if ( !jQuery.support.changeBubbles ) { 3647 3648 jQuery.event.special.change = { 3649 3650 setup: function() { 3651 3652 if ( rformElems.test( this.nodeName ) ) { 3653 // IE doesn't fire change on a check/radio until blur; trigger it on click 3654 // after a propertychange. Eat the blur-change in special.change.handle. 3655 // This still fires onchange a second time for check/radio after blur. 3656 if ( this.type === "checkbox" || this.type === "radio" ) { 3657 jQuery.event.add( this, "propertychange._change", function( event ) { 3658 if ( event.originalEvent.propertyName === "checked" ) { 3659 this._just_changed = true; 3660 } 3661 }); 3662 jQuery.event.add( this, "click._change", function( event ) { 3663 if ( this._just_changed ) { 3664 this._just_changed = false; 3665 jQuery.event.simulate( "change", this, event, true ); 3666 } 3667 }); 3668 } 3669 return false; 3670 } 3671 // Delegated event; lazy-add a change handler on descendant inputs 3672 jQuery.event.add( this, "beforeactivate._change", function( e ) { 3673 var elem = e.target; 3674 3675 if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { 3676 jQuery.event.add( elem, "change._change", function( event ) { 3677 if ( this.parentNode && !event.isSimulated ) { 3678 jQuery.event.simulate( "change", this.parentNode, event, true ); 3679 } 3680 }); 3681 elem._change_attached = true; 3682 } 3683 }); 3684 }, 3685 3686 handle: function( event ) { 3687 var elem = event.target; 3688 3689 // Swallow native change events from checkbox/radio, we already triggered them above 3690 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { 3691 return event.handleObj.handler.apply( this, arguments ); 3692 } 3693 }, 3694 3695 teardown: function() { 3696 jQuery.event.remove( this, "._change" ); 3697 3698 return rformElems.test( this.nodeName ); 3699 } 3700 }; 3701} 3702 3703// Create "bubbling" focus and blur events 3704if ( !jQuery.support.focusinBubbles ) { 3705 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 3706 3707 // Attach a single capturing handler while someone wants focusin/focusout 3708 var attaches = 0, 3709 handler = function( event ) { 3710 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); 3711 }; 3712 3713 jQuery.event.special[ fix ] = { 3714 setup: function() { 3715 if ( attaches++ === 0 ) { 3716 document.addEventListener( orig, handler, true ); 3717 } 3718 }, 3719 teardown: function() { 3720 if ( --attaches === 0 ) { 3721 document.removeEventListener( orig, handler, true ); 3722 } 3723 } 3724 }; 3725 }); 3726} 3727 3728jQuery.fn.extend({ 3729 3730 on: function( types, selector, data, fn, /*INTERNAL*/ one ) { 3731 var origFn, type; 3732 3733 // Types can be a map of types/handlers 3734 if ( typeof types === "object" ) { 3735 // ( types-Object, selector, data ) 3736 if ( typeof selector !== "string" ) { 3737 // ( types-Object, data ) 3738 data = selector; 3739 selector = undefined; 3740 } 3741 for ( type in types ) { 3742 this.on( type, selector, data, types[ type ], one ); 3743 } 3744 return this; 3745 } 3746 3747 if ( data == null && fn == null ) { 3748 // ( types, fn ) 3749 fn = selector; 3750 data = selector = undefined; 3751 } else if ( fn == null ) { 3752 if ( typeof selector === "string" ) { 3753 // ( types, selector, fn ) 3754 fn = data; 3755 data = undefined; 3756 } else { 3757 // ( types, data, fn ) 3758 fn = data; 3759 data = selector; 3760 selector = undefined; 3761 } 3762 } 3763 if ( fn === false ) { 3764 fn = returnFalse; 3765 } else if ( !fn ) { 3766 return this; 3767 } 3768 3769 if ( one === 1 ) { 3770 origFn = fn; 3771 fn = function( event ) { 3772 // Can use an empty set, since event contains the info 3773 jQuery().off( event ); 3774 return origFn.apply( this, arguments ); 3775 }; 3776 // Use same guid so caller can remove using origFn 3777 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 3778 } 3779 return this.each( function() { 3780 jQuery.event.add( this, types, fn, data, selector ); 3781 }); 3782 }, 3783 one: function( types, selector, data, fn ) { 3784 return this.on.call( this, types, selector, data, fn, 1 ); 3785 }, 3786 off: function( types, selector, fn ) { 3787 if ( types && types.preventDefault && types.handleObj ) { 3788 // ( event ) dispatched jQuery.Event 3789 var handleObj = types.handleObj; 3790 jQuery( types.delegateTarget ).off( 3791 handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, 3792 handleObj.selector, 3793 handleObj.handler 3794 ); 3795 return this; 3796 } 3797 if ( typeof types === "object" ) { 3798 // ( types-object [, selector] ) 3799 for ( var type in types ) { 3800 this.off( type, selector, types[ type ] ); 3801 } 3802 return this; 3803 } 3804 if ( selector === false || typeof selector === "function" ) { 3805 // ( types [, fn] ) 3806 fn = selector; 3807 selector = undefined; 3808 } 3809 if ( fn === false ) { 3810 fn = returnFalse; 3811 } 3812 return this.each(function() { 3813 jQuery.event.remove( this, types, fn, selector ); 3814 }); 3815 }, 3816 3817 bind: function( types, data, fn ) { 3818 return this.on( types, null, data, fn ); 3819 }, 3820 unbind: function( types, fn ) { 3821 return this.off( types, null, fn ); 3822 }, 3823 3824 live: function( types, data, fn ) { 3825 jQuery( this.context ).on( types, this.selector, data, fn ); 3826 return this; 3827 }, 3828 die: function( types, fn ) { 3829 jQuery( this.context ).off( types, this.selector || "**", fn ); 3830 return this; 3831 }, 3832 3833 delegate: function( selector, types, data, fn ) { 3834 return this.on( types, selector, data, fn ); 3835 }, 3836 undelegate: function( selector, types, fn ) { 3837 // ( namespace ) or ( selector, types [, fn] ) 3838 return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); 3839 }, 3840 3841 trigger: function( type, data ) { 3842 return this.each(function() { 3843 jQuery.event.trigger( type, data, this ); 3844 }); 3845 }, 3846 triggerHandler: function( type, data ) { 3847 if ( this[0] ) { 3848 return jQuery.event.trigger( type, data, this[0], true ); 3849 } 3850 }, 3851 3852 toggle: function( fn ) { 3853 // Save reference to arguments for access in closure 3854 var args = arguments, 3855 guid = fn.guid || jQuery.guid++, 3856 i = 0, 3857 toggler = function( event ) { 3858 // Figure out which function to execute 3859 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; 3860 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 3861 3862 // Make sure that clicks stop 3863 event.preventDefault(); 3864 3865 // and execute the function 3866 return args[ lastToggle ].apply( this, arguments ) || false; 3867 }; 3868 3869 // link all the functions, so any of them can unbind this click handler 3870 toggler.guid = guid; 3871 while ( i < args.length ) { 3872 args[ i++ ].guid = guid; 3873 } 3874 3875 return this.click( toggler ); 3876 }, 3877 3878 hover: function( fnOver, fnOut ) { 3879 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 3880 } 3881}); 3882 3883jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 3884 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 3885 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { 3886 3887 // Handle event binding 3888 jQuery.fn[ name ] = function( data, fn ) { 3889 if ( fn == null ) { 3890 fn = data; 3891 data = null; 3892 } 3893 3894 return arguments.length > 0 ? 3895 this.bind( name, data, fn ) : 3896 this.trigger( name ); 3897 }; 3898 3899 if ( jQuery.attrFn ) { 3900 jQuery.attrFn[ name ] = true; 3901 } 3902 3903 if ( rkeyEvent.test( name ) ) { 3904 jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; 3905 } 3906 3907 if ( rmouseEvent.test( name ) ) { 3908 jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; 3909 } 3910}); 3911 3912 3913 3914/*! 3915 * Sizzle CSS Selector Engine 3916 * Copyright 2011, The Dojo Foundation 3917 * Released under the MIT, BSD, and GPL Licenses. 3918 * More information: http://sizzlejs.com/ 3919 */ 3920(function(){ 3921 3922var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3923 expando = "sizcache" + (Math.random() + '').replace('.', ''), 3924 done = 0, 3925 toString = Object.prototype.toString, 3926 hasDuplicate = false, 3927 baseHasDuplicate = true, 3928 rBackslash = /\\/g, 3929 rReturn = /\r\n/g, 3930 rNonWord = /\W/; 3931 3932// Here we check if the JavaScript engine is using some sort of 3933// optimization where it does not always call our comparision 3934// function. If that is the case, discard the hasDuplicate value. 3935// Thus far that includes Google Chrome. 3936[0, 0].sort(function() { 3937 baseHasDuplicate = false; 3938 return 0; 3939}); 3940 3941var Sizzle = function( selector, context, results, seed ) { 3942 results = results || []; 3943 context = context || document; 3944 3945 var origContext = context; 3946 3947 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3948 return []; 3949 } 3950 3951 if ( !selector || typeof selector !== "string" ) { 3952 return results; 3953 } 3954 3955 var m, set, checkSet, extra, ret, cur, pop, i, 3956 prune = true, 3957 contextXML = Sizzle.isXML( context ), 3958 parts = [], 3959 soFar = selector; 3960 3961 // Reset the position of the chunker regexp (start from head) 3962 do { 3963 chunker.exec( "" ); 3964 m = chunker.exec( soFar ); 3965 3966 if ( m ) { 3967 soFar = m[3]; 3968 3969 parts.push( m[1] ); 3970 3971 if ( m[2] ) { 3972 extra = m[3]; 3973 break; 3974 } 3975 } 3976 } while ( m ); 3977 3978 if ( parts.length > 1 && origPOS.exec( selector ) ) { 3979 3980 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 3981 set = posProcess( parts[0] + parts[1], context, seed ); 3982 3983 } else { 3984 set = Expr.relative[ parts[0] ] ? 3985 [ context ] : 3986 Sizzle( parts.shift(), context ); 3987 3988 while ( parts.length ) { 3989 selector = parts.shift(); 3990 3991 if ( Expr.relative[ selector ] ) { 3992 selector += parts.shift(); 3993 } 3994 3995 set = posProcess( selector, set, seed ); 3996 } 3997 } 3998 3999 } else { 4000 // Take a shortcut and set the context if the root selector is an ID 4001 // (but not if it'll be faster if the inner selector is an ID) 4002 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 4003 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 4004 4005 ret = Sizzle.find( parts.shift(), context, contextXML ); 4006 context = ret.expr ? 4007 Sizzle.filter( ret.expr, ret.set )[0] : 4008 ret.set[0]; 4009 } 4010 4011 if ( context ) { 4012 ret = seed ? 4013 { expr: parts.pop(), set: makeArray(seed) } : 4014 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 4015 4016 set = ret.expr ? 4017 Sizzle.filter( ret.expr, ret.set ) : 4018 ret.set; 4019 4020 if ( parts.length > 0 ) { 4021 checkSet = makeArray( set ); 4022 4023 } else { 4024 prune = false; 4025 } 4026 4027 while ( parts.length ) { 4028 cur = parts.pop(); 4029 pop = cur; 4030 4031 if ( !Expr.relative[ cur ] ) { 4032 cur = ""; 4033 } else { 4034 pop = parts.pop(); 4035 } 4036 4037 if ( pop == null ) { 4038 pop = context; 4039 } 4040 4041 Expr.relative[ cur ]( checkSet, pop, contextXML ); 4042 } 4043 4044 } else { 4045 checkSet = parts = []; 4046 } 4047 } 4048 4049 if ( !checkSet ) { 4050 checkSet = set; 4051 } 4052 4053 if ( !checkSet ) { 4054 Sizzle.error( cur || selector ); 4055 } 4056 4057 if ( toString.call(checkSet) === "[object Array]" ) { 4058 if ( !prune ) { 4059 results.push.apply( results, checkSet ); 4060 4061 } else if ( context && context.nodeType === 1 ) { 4062 for ( i = 0; checkSet[i] != null; i++ ) { 4063 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { 4064 results.push( set[i] ); 4065 } 4066 } 4067 4068 } else { 4069 for ( i = 0; checkSet[i] != null; i++ ) { 4070 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 4071 results.push( set[i] ); 4072 } 4073 } 4074 } 4075 4076 } else { 4077 makeArray( checkSet, results ); 4078 } 4079 4080 if ( extra ) { 4081 Sizzle( extra, origContext, results, seed ); 4082 Sizzle.uniqueSort( results ); 4083 } 4084 4085 return results; 4086}; 4087 4088Sizzle.uniqueSort = function( results ) { 4089 if ( sortOrder ) { 4090 hasDuplicate = baseHasDuplicate; 4091 results.sort( sortOrder ); 4092 4093 if ( hasDuplicate ) { 4094 for ( var i = 1; i < results.length; i++ ) { 4095 if ( results[i] === results[ i - 1 ] ) { 4096 results.splice( i--, 1 ); 4097 } 4098 } 4099 } 4100 } 4101 4102 return results; 4103}; 4104 4105Sizzle.matches = function( expr, set ) { 4106 return Sizzle( expr, null, null, set ); 4107}; 4108 4109Sizzle.matchesSelector = function( node, expr ) { 4110 return Sizzle( expr, null, null, [node] ).length > 0; 4111}; 4112 4113Sizzle.find = function( expr, context, isXML ) { 4114 var set, i, len, match, type, left; 4115 4116 if ( !expr ) { 4117 return []; 4118 } 4119 4120 for ( i = 0, len = Expr.order.length; i < len; i++ ) { 4121 type = Expr.order[i]; 4122 4123 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 4124 left = match[1]; 4125 match.splice( 1, 1 ); 4126 4127 if ( left.substr( left.length - 1 ) !== "\\" ) { 4128 match[1] = (match[1] || "").replace( rBackslash, "" ); 4129 set = Expr.find[ type ]( match, context, isXML ); 4130 4131 if ( set != null ) { 4132 expr = expr.replace( Expr.match[ type ], "" ); 4133 break; 4134 } 4135 } 4136 } 4137 } 4138 4139 if ( !set ) { 4140 set = typeof context.getElementsByTagName !== "undefined" ? 4141 context.getElementsByTagName( "*" ) : 4142 []; 4143 } 4144 4145 return { set: set, expr: expr }; 4146}; 4147 4148Sizzle.filter = function( expr, set, inplace, not ) { 4149 var match, anyFound, 4150 type, found, item, filter, left, 4151 i, pass, 4152 old = expr, 4153 result = [], 4154 curLoop = set, 4155 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); 4156 4157 while ( expr && set.length ) { 4158 for ( type in Expr.filter ) { 4159 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 4160 filter = Expr.filter[ type ]; 4161 left = match[1]; 4162 4163 anyFound = false; 4164 4165 match.splice(1,1); 4166 4167 if ( left.substr( left.length - 1 ) === "\\" ) { 4168 continue; 4169 } 4170 4171 if ( curLoop === result ) { 4172 result = []; 4173 } 4174 4175 if ( Expr.preFilter[ type ] ) { 4176 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 4177 4178 if ( !match ) { 4179 anyFound = found = true; 4180 4181 } else if ( match === true ) { 4182 continue; 4183 } 4184 } 4185 4186 if ( match ) { 4187 for ( i = 0; (item = curLoop[i]) != null; i++ ) { 4188 if ( item ) { 4189 found = filter( item, match, i, curLoop ); 4190 pass = not ^ found; 4191 4192 if ( inplace && found != null ) { 4193 if ( pass ) { 4194 anyFound = true; 4195 4196 } else { 4197 curLoop[i] = false; 4198 } 4199 4200 } else if ( pass ) { 4201 result.push( item ); 4202 anyFound = true; 4203 } 4204 } 4205 } 4206 } 4207 4208 if ( found !== undefined ) { 4209 if ( !inplace ) { 4210 curLoop = result; 4211 } 4212 4213 expr = expr.replace( Expr.match[ type ], "" ); 4214 4215 if ( !anyFound ) { 4216 return []; 4217 } 4218 4219 break; 4220 } 4221 } 4222 } 4223 4224 // Improper expression 4225 if ( expr === old ) { 4226 if ( anyFound == null ) { 4227 Sizzle.error( expr ); 4228 4229 } else { 4230 break; 4231 } 4232 } 4233 4234 old = expr; 4235 } 4236 4237 return curLoop; 4238}; 4239 4240Sizzle.error = function( msg ) { 4241 throw "Syntax error, unrecognized expression: " + msg; 4242}; 4243 4244/** 4245 * Utility function for retreiving the text value of an array of DOM nodes 4246 * @param {Array|Element} elem 4247 */ 4248var getText = Sizzle.getText = function( elem ) { 4249 var i, node, 4250 nodeType = elem.nodeType, 4251 ret = ""; 4252 4253 if ( nodeType ) { 4254 if ( nodeType === 1 ) { 4255 // Use textContent || innerText for elements 4256 if ( typeof elem.textContent === 'string' ) { 4257 return elem.textContent; 4258 } else if ( typeof elem.innerText === 'string' ) { 4259 // Replace IE's carriage returns 4260 return elem.innerText.replace( rReturn, '' ); 4261 } else { 4262 // Traverse it's children 4263 for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { 4264 ret += getText( elem ); 4265 } 4266 } 4267 } else if ( nodeType === 3 || nodeType === 4 ) { 4268 return elem.nodeValue; 4269 } 4270 } else { 4271 4272 // If no nodeType, this is expected to be an array 4273 for ( i = 0; (node = elem[i]); i++ ) { 4274 // Do not traverse comment nodes 4275 if ( node.nodeType !== 8 ) { 4276 ret += getText( node ); 4277 } 4278 } 4279 } 4280 return ret; 4281}; 4282 4283var Expr = Sizzle.selectors = { 4284 order: [ "ID", "NAME", "TAG" ], 4285 4286 match: { 4287 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4288 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4289 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, 4290 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, 4291 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, 4292 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, 4293 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, 4294 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 4295 }, 4296 4297 leftMatch: {}, 4298 4299 attrMap: { 4300 "class": "className", 4301 "for": "htmlFor" 4302 }, 4303 4304 attrHandle: { 4305 href: function( elem ) { 4306 return elem.getAttribute( "href" ); 4307 }, 4308 type: function( elem ) { 4309 return elem.getAttribute( "type" ); 4310 } 4311 }, 4312 4313 relative: { 4314 "+": function(checkSet, part){ 4315 var isPartStr = typeof part === "string", 4316 isTag = isPartStr && !rNonWord.test( part ), 4317 isPartStrNotTag = isPartStr && !isTag; 4318 4319 if ( isTag ) { 4320 part = part.toLowerCase(); 4321 } 4322 4323 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 4324 if ( (elem = checkSet[i]) ) { 4325 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 4326 4327 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 4328 elem || false : 4329 elem === part; 4330 } 4331 } 4332 4333 if ( isPartStrNotTag ) { 4334 Sizzle.filter( part, checkSet, true ); 4335 } 4336 }, 4337 4338 ">": function( checkSet, part ) { 4339 var elem, 4340 isPartStr = typeof part === "string", 4341 i = 0, 4342 l = checkSet.length; 4343 4344 if ( isPartStr && !rNonWord.test( part ) ) { 4345 part = part.toLowerCase(); 4346 4347 for ( ; i < l; i++ ) { 4348 elem = checkSet[i]; 4349 4350 if ( elem ) { 4351 var parent = elem.parentNode; 4352 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 4353 } 4354 } 4355 4356 } else { 4357 for ( ; i < l; i++ ) { 4358 elem = checkSet[i]; 4359 4360 if ( elem ) { 4361 checkSet[i] = isPartStr ? 4362 elem.parentNode : 4363 elem.parentNode === part; 4364 } 4365 } 4366 4367 if ( isPartStr ) { 4368 Sizzle.filter( part, checkSet, true ); 4369 } 4370 } 4371 }, 4372 4373 "": function(checkSet, part, isXML){ 4374 var nodeCheck, 4375 doneName = done++, 4376 checkFn = dirCheck; 4377 4378 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4379 part = part.toLowerCase(); 4380 nodeCheck = part; 4381 checkFn = dirNodeCheck; 4382 } 4383 4384 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); 4385 }, 4386 4387 "~": function( checkSet, part, isXML ) { 4388 var nodeCheck, 4389 doneName = done++, 4390 checkFn = dirCheck; 4391 4392 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4393 part = part.toLowerCase(); 4394 nodeCheck = part; 4395 checkFn = dirNodeCheck; 4396 } 4397 4398 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); 4399 } 4400 }, 4401 4402 find: { 4403 ID: function( match, context, isXML ) { 4404 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4405 var m = context.getElementById(match[1]); 4406 // Check parentNode to catch when Blackberry 4.6 returns 4407 // nodes that are no longer in the document #6963 4408 return m && m.parentNode ? [m] : []; 4409 } 4410 }, 4411 4412 NAME: function( match, context ) { 4413 if ( typeof context.getElementsByName !== "undefined" ) { 4414 var ret = [], 4415 results = context.getElementsByName( match[1] ); 4416 4417 for ( var i = 0, l = results.length; i < l; i++ ) { 4418 if ( results[i].getAttribute("name") === match[1] ) { 4419 ret.push( results[i] ); 4420 } 4421 } 4422 4423 return ret.length === 0 ? null : ret; 4424 } 4425 }, 4426 4427 TAG: function( match, context ) { 4428 if ( typeof context.getElementsByTagName !== "undefined" ) { 4429 return context.getElementsByTagName( match[1] ); 4430 } 4431 } 4432 }, 4433 preFilter: { 4434 CLASS: function( match, curLoop, inplace, result, not, isXML ) { 4435 match = " " + match[1].replace( rBackslash, "" ) + " "; 4436 4437 if ( isXML ) { 4438 return match; 4439 } 4440 4441 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 4442 if ( elem ) { 4443 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { 4444 if ( !inplace ) { 4445 result.push( elem ); 4446 } 4447 4448 } else if ( inplace ) { 4449 curLoop[i] = false; 4450 } 4451 } 4452 } 4453 4454 return false; 4455 }, 4456 4457 ID: function( match ) { 4458 return match[1].replace( rBackslash, "" ); 4459 }, 4460 4461 TAG: function( match, curLoop ) { 4462 return match[1].replace( rBackslash, "" ).toLowerCase(); 4463 }, 4464 4465 CHILD: function( match ) { 4466 if ( match[1] === "nth" ) { 4467 if ( !match[2] ) { 4468 Sizzle.error( match[0] ); 4469 } 4470 4471 match[2] = match[2].replace(/^\+|\s*/g, ''); 4472 4473 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 4474 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( 4475 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 4476 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 4477 4478 // calculate the numbers (first)n+(last) including if they are negative 4479 match[2] = (test[1] + (test[2] || 1)) - 0; 4480 match[3] = test[3] - 0; 4481 } 4482 else if ( match[2] ) { 4483 Sizzle.error( match[0] ); 4484 } 4485 4486 // TODO: Move to normal caching system 4487 match[0] = done++; 4488 4489 return match; 4490 }, 4491 4492 ATTR: function( match, curLoop, inplace, result, not, isXML ) { 4493 var name = match[1] = match[1].replace( rBackslash, "" ); 4494 4495 if ( !isXML && Expr.attrMap[name] ) { 4496 match[1] = Expr.attrMap[name]; 4497 } 4498 4499 // Handle if an un-quoted value was used 4500 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); 4501 4502 if ( match[2] === "~=" ) { 4503 match[4] = " " + match[4] + " "; 4504 } 4505 4506 return match; 4507 }, 4508 4509 PSEUDO: function( match, curLoop, inplace, result, not ) { 4510 if ( match[1] === "not" ) { 4511 // If we're dealing with a complex expression, or a simple one 4512 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 4513 match[3] = Sizzle(match[3], null, null, curLoop); 4514 4515 } else { 4516 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 4517 4518 if ( !inplace ) { 4519 result.push.apply( result, ret ); 4520 } 4521 4522 return false; 4523 } 4524 4525 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 4526 return true; 4527 } 4528 4529 return match; 4530 }, 4531 4532 POS: function( match ) { 4533 match.unshift( true ); 4534 4535 return match; 4536 } 4537 }, 4538 4539 filters: { 4540 enabled: function( elem ) { 4541 return elem.disabled === false && elem.type !== "hidden"; 4542 }, 4543 4544 disabled: function( elem ) { 4545 return elem.disabled === true; 4546 }, 4547 4548 checked: function( elem ) { 4549 return elem.checked === true; 4550 }, 4551 4552 selected: function( elem ) { 4553 // Accessing this property makes selected-by-default 4554 // options in Safari work properly 4555 if ( elem.parentNode ) { 4556 elem.parentNode.selectedIndex; 4557 } 4558 4559 return elem.selected === true; 4560 }, 4561 4562 parent: function( elem ) { 4563 return !!elem.firstChild; 4564 }, 4565 4566 empty: function( elem ) { 4567 return !elem.firstChild; 4568 }, 4569 4570 has: function( elem, i, match ) { 4571 return !!Sizzle( match[3], elem ).length; 4572 }, 4573 4574 header: function( elem ) { 4575 return (/h\d/i).test( elem.nodeName ); 4576 }, 4577 4578 text: function( elem ) { 4579 var attr = elem.getAttribute( "type" ), type = elem.type; 4580 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 4581 // use getAttribute instead to test this case 4582 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); 4583 }, 4584 4585 radio: function( elem ) { 4586 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; 4587 }, 4588 4589 checkbox: function( elem ) { 4590 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; 4591 }, 4592 4593 file: function( elem ) { 4594 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; 4595 }, 4596 4597 password: function( elem ) { 4598 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; 4599 }, 4600 4601 submit: function( elem ) { 4602 var name = elem.nodeName.toLowerCase(); 4603 return (name === "input" || name === "button") && "submit" === elem.type; 4604 }, 4605 4606 image: function( elem ) { 4607 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; 4608 }, 4609 4610 reset: function( elem ) { 4611 var name = elem.nodeName.toLowerCase(); 4612 return (name === "input" || name === "button") && "reset" === elem.type; 4613 }, 4614 4615 button: function( elem ) { 4616 var name = elem.nodeName.toLowerCase(); 4617 return name === "input" && "button" === elem.type || name === "button"; 4618 }, 4619 4620 input: function( elem ) { 4621 return (/input|select|textarea|button/i).test( elem.nodeName ); 4622 }, 4623 4624 focus: function( elem ) { 4625 return elem === elem.ownerDocument.activeElement; 4626 } 4627 }, 4628 setFilters: { 4629 first: function( elem, i ) { 4630 return i === 0; 4631 }, 4632 4633 last: function( elem, i, match, array ) { 4634 return i === array.length - 1; 4635 }, 4636 4637 even: function( elem, i ) { 4638 return i % 2 === 0; 4639 }, 4640 4641 odd: function( elem, i ) { 4642 return i % 2 === 1; 4643 }, 4644 4645 lt: function( elem, i, match ) { 4646 return i < match[3] - 0; 4647 }, 4648 4649 gt: function( elem, i, match ) { 4650 return i > match[3] - 0; 4651 }, 4652 4653 nth: function( elem, i, match ) { 4654 return match[3] - 0 === i; 4655 }, 4656 4657 eq: function( elem, i, match ) { 4658 return match[3] - 0 === i; 4659 } 4660 }, 4661 filter: { 4662 PSEUDO: function( elem, match, i, array ) { 4663 var name = match[1], 4664 filter = Expr.filters[ name ]; 4665 4666 if ( filter ) { 4667 return filter( elem, i, match, array ); 4668 4669 } else if ( name === "contains" ) { 4670 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; 4671 4672 } else if ( name === "not" ) { 4673 var not = match[3]; 4674 4675 for ( var j = 0, l = not.length; j < l; j++ ) { 4676 if ( not[j] === elem ) { 4677 return false; 4678 } 4679 } 4680 4681 return true; 4682 4683 } else { 4684 Sizzle.error( name ); 4685 } 4686 }, 4687 4688 CHILD: function( elem, match ) { 4689 var first, last, 4690 doneName, parent, cache, 4691 count, diff, 4692 type = match[1], 4693 node = elem; 4694 4695 switch ( type ) { 4696 case "only": 4697 case "first": 4698 while ( (node = node.previousSibling) ) { 4699 if ( node.nodeType === 1 ) { 4700 return false; 4701 } 4702 } 4703 4704 if ( type === "first" ) { 4705 return true; 4706 } 4707 4708 node = elem; 4709 4710 case "last": 4711 while ( (node = node.nextSibling) ) { 4712 if ( node.nodeType === 1 ) { 4713 return false; 4714 } 4715 } 4716 4717 return true; 4718 4719 case "nth": 4720 first = match[2]; 4721 last = match[3]; 4722 4723 if ( first === 1 && last === 0 ) { 4724 return true; 4725 } 4726 4727 doneName = match[0]; 4728 parent = elem.parentNode; 4729 4730 if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { 4731 count = 0; 4732 4733 for ( node = parent.firstChild; node; node = node.nextSibling ) { 4734 if ( node.nodeType === 1 ) { 4735 node.nodeIndex = ++count; 4736 } 4737 } 4738 4739 parent[ expando ] = doneName; 4740 } 4741 4742 diff = elem.nodeIndex - last; 4743 4744 if ( first === 0 ) { 4745 return diff === 0; 4746 4747 } else { 4748 return ( diff % first === 0 && diff / first >= 0 ); 4749 } 4750 } 4751 }, 4752 4753 ID: function( elem, match ) { 4754 return elem.nodeType === 1 && elem.getAttribute("id") === match; 4755 }, 4756 4757 TAG: function( elem, match ) { 4758 return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; 4759 }, 4760 4761 CLASS: function( elem, match ) { 4762 return (" " + (elem.className || elem.getAttribute("class")) + " ") 4763 .indexOf( match ) > -1; 4764 }, 4765 4766 ATTR: function( elem, match ) { 4767 var name = match[1], 4768 result = Sizzle.attr ? 4769 Sizzle.attr( elem, name ) : 4770 Expr.attrHandle[ name ] ? 4771 Expr.attrHandle[ name ]( elem ) : 4772 elem[ name ] != null ? 4773 elem[ name ] : 4774 elem.getAttribute( name ), 4775 value = result + "", 4776 type = match[2], 4777 check = match[4]; 4778 4779 return result == null ? 4780 type === "!=" : 4781 !type && Sizzle.attr ? 4782 result != null : 4783 type === "=" ? 4784 value === check : 4785 type === "*=" ? 4786 value.indexOf(check) >= 0 : 4787 type === "~=" ? 4788 (" " + value + " ").indexOf(check) >= 0 : 4789 !check ? 4790 value && result !== false : 4791 type === "!=" ? 4792 value !== check : 4793 type === "^=" ? 4794 value.indexOf(check) === 0 : 4795 type === "$=" ? 4796 value.substr(value.length - check.length) === check : 4797 type === "|=" ? 4798 value === check || value.substr(0, check.length + 1) === check + "-" : 4799 false; 4800 }, 4801 4802 POS: function( elem, match, i, array ) { 4803 var name = match[2], 4804 filter = Expr.setFilters[ name ]; 4805 4806 if ( filter ) { 4807 return filter( elem, i, match, array ); 4808 } 4809 } 4810 } 4811}; 4812 4813var origPOS = Expr.match.POS, 4814 fescape = function(all, num){ 4815 return "\\" + (num - 0 + 1); 4816 }; 4817 4818for ( var type in Expr.match ) { 4819 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); 4820 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); 4821} 4822 4823var makeArray = function( array, results ) { 4824 array = Array.prototype.slice.call( array, 0 ); 4825 4826 if ( results ) { 4827 results.push.apply( results, array ); 4828 return results; 4829 } 4830 4831 return array; 4832}; 4833 4834// Perform a simple check to determine if the browser is capable of 4835// converting a NodeList to an array using builtin methods. 4836// Also verifies that the returned array holds DOM nodes 4837// (which is not the case in the Blackberry browser) 4838try { 4839 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; 4840 4841// Provide a fallback method if it does not work 4842} catch( e ) { 4843 makeArray = function( array, results ) { 4844 var i = 0, 4845 ret = results || []; 4846 4847 if ( toString.call(array) === "[object Array]" ) { 4848 Array.prototype.push.apply( ret, array ); 4849 4850 } else { 4851 if ( typeof array.length === "number" ) { 4852 for ( var l = array.length; i < l; i++ ) { 4853 ret.push( array[i] ); 4854 } 4855 4856 } else { 4857 for ( ; array[i]; i++ ) { 4858 ret.push( array[i] ); 4859 } 4860 } 4861 } 4862 4863 return ret; 4864 }; 4865} 4866 4867var sortOrder, siblingCheck; 4868 4869if ( document.documentElement.compareDocumentPosition ) { 4870 sortOrder = function( a, b ) { 4871 if ( a === b ) { 4872 hasDuplicate = true; 4873 return 0; 4874 } 4875 4876 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 4877 return a.compareDocumentPosition ? -1 : 1; 4878 } 4879 4880 return a.compareDocumentPosition(b) & 4 ? -1 : 1; 4881 }; 4882 4883} else { 4884 sortOrder = function( a, b ) { 4885 // The nodes are identical, we can exit early 4886 if ( a === b ) { 4887 hasDuplicate = true; 4888 return 0; 4889 4890 // Fallback to using sourceIndex (in IE) if it's available on both nodes 4891 } else if ( a.sourceIndex && b.sourceIndex ) { 4892 return a.sourceIndex - b.sourceIndex; 4893 } 4894 4895 var al, bl, 4896 ap = [], 4897 bp = [], 4898 aup = a.parentNode, 4899 bup = b.parentNode, 4900 cur = aup; 4901 4902 // If the nodes are siblings (or identical) we can do a quick check 4903 if ( aup === bup ) { 4904 return siblingCheck( a, b ); 4905 4906 // If no parents were found then the nodes are disconnected 4907 } else if ( !aup ) { 4908 return -1; 4909 4910 } else if ( !bup ) { 4911 return 1; 4912 } 4913 4914 // Otherwise they're somewhere else in the tree so we need 4915 // to build up a full list of the parentNodes for comparison 4916 while ( cur ) { 4917 ap.unshift( cur ); 4918 cur = cur.parentNode; 4919 } 4920 4921 cur = bup; 4922 4923 while ( cur ) { 4924 bp.unshift( cur ); 4925 cur = cur.parentNode; 4926 } 4927 4928 al = ap.length; 4929 bl = bp.length; 4930 4931 // Start walking down the tree looking for a discrepancy 4932 for ( var i = 0; i < al && i < bl; i++ ) { 4933 if ( ap[i] !== bp[i] ) { 4934 return siblingCheck( ap[i], bp[i] ); 4935 } 4936 } 4937 4938 // We ended someplace up the tree so do a sibling check 4939 return i === al ? 4940 siblingCheck( a, bp[i], -1 ) : 4941 siblingCheck( ap[i], b, 1 ); 4942 }; 4943 4944 siblingCheck = function( a, b, ret ) { 4945 if ( a === b ) { 4946 return ret; 4947 } 4948 4949 var cur = a.nextSibling; 4950 4951 while ( cur ) { 4952 if ( cur === b ) { 4953 return -1; 4954 } 4955 4956 cur = cur.nextSibling; 4957 } 4958 4959 return 1; 4960 }; 4961} 4962 4963// Check to see if the browser returns elements by name when 4964// querying by getElementById (and provide a workaround) 4965(function(){ 4966 // We're going to inject a fake input element with a specified name 4967 var form = document.createElement("div"), 4968 id = "script" + (new Date()).getTime(), 4969 root = document.documentElement; 4970 4971 form.innerHTML = "<a name='" + id + "'/>"; 4972 4973 // Inject it into the root element, check its status, and remove it quickly 4974 root.insertBefore( form, root.firstChild ); 4975 4976 // The workaround has to do additional checks after a getElementById 4977 // Which slows things down for other browsers (hence the branching) 4978 if ( document.getElementById( id ) ) { 4979 Expr.find.ID = function( match, context, isXML ) { 4980 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4981 var m = context.getElementById(match[1]); 4982 4983 return m ? 4984 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? 4985 [m] : 4986 undefined : 4987 []; 4988 } 4989 }; 4990 4991 Expr.filter.ID = function( elem, match ) { 4992 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 4993 4994 return elem.nodeType === 1 && node && node.nodeValue === match; 4995 }; 4996 } 4997 4998 root.removeChild( form ); 4999 5000 // release memory in IE 5001 root = form = null; 5002})(); 5003 5004(function(){ 5005 // Check to see if the browser returns only elements 5006 // when doing getElementsByTagName("*") 5007 5008 // Create a fake element 5009 var div = document.createElement("div"); 5010 div.appendChild( document.createComment("") ); 5011 5012 // Make sure no comments are found 5013 if ( div.getElementsByTagName("*").length > 0 ) { 5014 Expr.find.TAG = function( match, context ) { 5015 var results = context.getElementsByTagName( match[1] ); 5016 5017 // Filter out possible comments 5018 if ( match[1] === "*" ) { 5019 var tmp = []; 5020 5021 for ( var i = 0; results[i]; i++ ) { 5022 if ( results[i].nodeType === 1 ) { 5023 tmp.push( results[i] ); 5024 } 5025 } 5026 5027 results = tmp; 5028 } 5029 5030 return results; 5031 }; 5032 } 5033 5034 // Check to see if an attribute returns normalized href attributes 5035 div.innerHTML = "<a href='#'></a>"; 5036 5037 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 5038 div.firstChild.getAttribute("href") !== "#" ) { 5039 5040 Expr.attrHandle.href = function( elem ) { 5041 return elem.getAttribute( "href", 2 ); 5042 }; 5043 } 5044 5045 // release memory in IE 5046 div = null; 5047})(); 5048 5049if ( document.querySelectorAll ) { 5050 (function(){ 5051 var oldSizzle = Sizzle, 5052 div = document.createElement("div"), 5053 id = "__sizzle__"; 5054 5055 div.innerHTML = "<p class='TEST'></p>"; 5056 5057 // Safari can't handle uppercase or unicode characters when 5058 // in quirks mode. 5059 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 5060 return; 5061 } 5062 5063 Sizzle = function( query, context, extra, seed ) { 5064 context = context || document; 5065 5066 // Only use querySelectorAll on non-XML documents 5067 // (ID selectors don't work in non-HTML documents) 5068 if ( !seed && !Sizzle.isXML(context) ) { 5069 // See if we find a selector to speed up 5070 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); 5071 5072 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { 5073 // Speed-up: Sizzle("TAG") 5074 if ( match[1] ) { 5075 return makeArray( context.getElementsByTagName( query ), extra ); 5076 5077 // Speed-up: Sizzle(".CLASS") 5078 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { 5079 return makeArray( context.getElementsByClassName( match[2] ), extra ); 5080 } 5081 } 5082 5083 if ( context.nodeType === 9 ) { 5084 // Speed-up: Sizzle("body") 5085 // The body element only exists once, optimize finding it 5086 if ( query === "body" && context.body ) { 5087 return makeArray( [ context.body ], extra ); 5088 5089 // Speed-up: Sizzle("#ID") 5090 } else if ( match && match[3] ) { 5091 var elem = context.getElementById( match[3] ); 5092 5093 // Check parentNode to catch when Blackberry 4.6 returns 5094 // nodes that are no longer in the document #6963 5095 if ( elem && elem.parentNode ) { 5096 // Handle the case where IE and Opera return items 5097 // by name instead of ID 5098 if ( elem.id === match[3] ) { 5099 return makeArray( [ elem ], extra ); 5100 } 5101 5102 } else { 5103 return makeArray( [], extra ); 5104 } 5105 } 5106 5107 try { 5108 return makeArray( context.querySelectorAll(query), extra ); 5109 } catch(qsaError) {} 5110 5111 // qSA works strangely on Element-rooted queries 5112 // We can work around this by specifying an extra ID on the root 5113 // and working up from there (Thanks to Andrew Dupont for the technique) 5114 // IE 8 doesn't work on object elements 5115 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 5116 var oldContext = context, 5117 old = context.getAttribute( "id" ), 5118 nid = old || id, 5119 hasParent = context.parentNode, 5120 relativeHierarchySelector = /^\s*[+~]/.test( query ); 5121 5122 if ( !old ) { 5123 context.setAttribute( "id", nid ); 5124 } else { 5125 nid = nid.replace( /'/g, "\\$&" ); 5126 } 5127 if ( relativeHierarchySelector && hasParent ) { 5128 context = context.parentNode; 5129 } 5130 5131 try { 5132 if ( !relativeHierarchySelector || hasParent ) { 5133 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); 5134 } 5135 5136 } catch(pseudoError) { 5137 } finally { 5138 if ( !old ) { 5139 oldContext.removeAttribute( "id" ); 5140 } 5141 } 5142 } 5143 } 5144 5145 return oldSizzle(query, context, extra, seed); 5146 }; 5147 5148 for ( var prop in oldSizzle ) { 5149 Sizzle[ prop ] = oldSizzle[ prop ]; 5150 } 5151 5152 // release memory in IE 5153 div = null; 5154 })(); 5155} 5156 5157(function(){ 5158 var html = document.documentElement, 5159 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; 5160 5161 if ( matches ) { 5162 // Check to see if it's possible to do matchesSelector 5163 // on a disconnected node (IE 9 fails this) 5164 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), 5165 pseudoWorks = false; 5166 5167 try { 5168 // This should fail with an exception 5169 // Gecko does not error, returns false instead 5170 matches.call( document.documentElement, "[test!='']:sizzle" ); 5171 5172 } catch( pseudoError ) { 5173 pseudoWorks = true; 5174 } 5175 5176 Sizzle.matchesSelector = function( node, expr ) { 5177 // Make sure that attribute selectors are quoted 5178 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); 5179 5180 if ( !Sizzle.isXML( node ) ) { 5181 try { 5182 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { 5183 var ret = matches.call( node, expr ); 5184 5185 // IE 9's matchesSelector returns false on disconnected nodes 5186 if ( ret || !disconnectedMatch || 5187 // As well, disconnected nodes are said to be in a document 5188 // fragment in IE 9, so check for that 5189 node.document && node.document.nodeType !== 11 ) { 5190 return ret; 5191 } 5192 } 5193 } catch(e) {} 5194 } 5195 5196 return Sizzle(expr, null, null, [node]).length > 0; 5197 }; 5198 } 5199})(); 5200 5201(function(){ 5202 var div = document.createElement("div"); 5203 5204 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 5205 5206 // Opera can't find a second classname (in 9.6) 5207 // Also, make sure that getElementsByClassName actually exists 5208 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 5209 return; 5210 } 5211 5212 // Safari caches class attributes, doesn't catch changes (in 3.2) 5213 div.lastChild.className = "e"; 5214 5215 if ( div.getElementsByClassName("e").length === 1 ) { 5216 return; 5217 } 5218 5219 Expr.order.splice(1, 0, "CLASS"); 5220 Expr.find.CLASS = function( match, context, isXML ) { 5221 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 5222 return context.getElementsByClassName(match[1]); 5223 } 5224 }; 5225 5226 // release memory in IE 5227 div = null; 5228})(); 5229 5230function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 5231 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 5232 var elem = checkSet[i]; 5233 5234 if ( elem ) { 5235 var match = false; 5236 5237 elem = elem[dir]; 5238 5239 while ( elem ) { 5240 if ( elem[ expando ] === doneName ) { 5241 match = checkSet[elem.sizset]; 5242 break; 5243 } 5244 5245 if ( elem.nodeType === 1 && !isXML ){ 5246 elem[ expando ] = doneName; 5247 elem.sizset = i; 5248 } 5249 5250 if ( elem.nodeName.toLowerCase() === cur ) { 5251 match = elem; 5252 break; 5253 } 5254 5255 elem = elem[dir]; 5256 } 5257 5258 checkSet[i] = match; 5259 } 5260 } 5261} 5262 5263function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 5264 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 5265 var elem = checkSet[i]; 5266 5267 if ( elem ) { 5268 var match = false; 5269 5270 elem = elem[dir]; 5271 5272 while ( elem ) { 5273 if ( elem[ expando ] === doneName ) { 5274 match = checkSet[elem.sizset]; 5275 break; 5276 } 5277 5278 if ( elem.nodeType === 1 ) { 5279 if ( !isXML ) { 5280 elem[ expando ] = doneName; 5281 elem.sizset = i; 5282 } 5283 5284 if ( typeof cur !== "string" ) { 5285 if ( elem === cur ) { 5286 match = true; 5287 break; 5288 } 5289 5290 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 5291 match = elem; 5292 break; 5293 } 5294 } 5295 5296 elem = elem[dir]; 5297 } 5298 5299 checkSet[i] = match; 5300 } 5301 } 5302} 5303 5304if ( document.documentElement.contains ) { 5305 Sizzle.contains = function( a, b ) { 5306 return a !== b && (a.contains ? a.contains(b) : true); 5307 }; 5308 5309} else if ( document.documentElement.compareDocumentPosition ) { 5310 Sizzle.contains = function( a, b ) { 5311 return !!(a.compareDocumentPosition(b) & 16); 5312 }; 5313 5314} else { 5315 Sizzle.contains = function() { 5316 return false; 5317 }; 5318} 5319 5320Sizzle.isXML = function( elem ) { 5321 // documentElement is verified for cases where it doesn't yet exist 5322 // (such as loading iframes in IE - #4833) 5323 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 5324 5325 return documentElement ? documentElement.nodeName !== "HTML" : false; 5326}; 5327 5328var posProcess = function( selector, context, seed ) { 5329 var match, 5330 tmpSet = [], 5331 later = "", 5332 root = context.nodeType ? [context] : context; 5333 5334 // Position selectors must be done after the filter 5335 // And so must :not(positional) so we move all PSEUDOs to the end 5336 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 5337 later += match[0]; 5338 selector = selector.replace( Expr.match.PSEUDO, "" ); 5339 } 5340 5341 selector = Expr.relative[selector] ? selector + "*" : selector; 5342 5343 for ( var i = 0, l = root.length; i < l; i++ ) { 5344 Sizzle( selector, root[i], tmpSet, seed ); 5345 } 5346 5347 return Sizzle.filter( later, tmpSet ); 5348}; 5349 5350// EXPOSE 5351// Override sizzle attribute retrieval 5352Sizzle.attr = jQuery.attr; 5353Sizzle.selectors.attrMap = {}; 5354jQuery.find = Sizzle; 5355jQuery.expr = Sizzle.selectors; 5356jQuery.expr[":"] = jQuery.expr.filters; 5357jQuery.unique = Sizzle.uniqueSort; 5358jQuery.text = Sizzle.getText; 5359jQuery.isXMLDoc = Sizzle.isXML; 5360jQuery.contains = Sizzle.contains; 5361 5362 5363})(); 5364 5365 5366var runtil = /Until$/, 5367 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 5368 // Note: This RegExp should be improved, or likely pulled from Sizzle 5369 rmultiselector = /,/, 5370 isSimple = /^.[^:#\[\.,]*$/, 5371 slice = Array.prototype.slice, 5372 POS = jQuery.expr.match.POS, 5373 // methods guaranteed to produce a unique set when starting from a unique set 5374 guaranteedUnique = { 5375 children: true, 5376 contents: true, 5377 next: true, 5378 prev: true 5379 }; 5380 5381jQuery.fn.extend({ 5382 find: function( selector ) { 5383 var self = this, 5384 i, l; 5385 5386 if ( typeof selector !== "string" ) { 5387 return jQuery( selector ).filter(function() { 5388 for ( i = 0, l = self.length; i < l; i++ ) { 5389 if ( jQuery.contains( self[ i ], this ) ) { 5390 return true; 5391 } 5392 } 5393 }); 5394 } 5395 5396 var ret = this.pushStack( "", "find", selector ), 5397 length, n, r; 5398 5399 for ( i = 0, l = this.length; i < l; i++ ) { 5400 length = ret.length; 5401 jQuery.find( selector, this[i], ret ); 5402 5403 if ( i > 0 ) { 5404 // Make sure that the results are unique 5405 for ( n = length; n < ret.length; n++ ) { 5406 for ( r = 0; r < length; r++ ) { 5407 if ( ret[r] === ret[n] ) { 5408 ret.splice(n--, 1); 5409 break; 5410 } 5411 } 5412 } 5413 } 5414 } 5415 5416 return ret; 5417 }, 5418 5419 has: function( target ) { 5420 var targets = jQuery( target ); 5421 return this.filter(function() { 5422 for ( var i = 0, l = targets.length; i < l; i++ ) { 5423 if ( jQuery.contains( this, targets[i] ) ) { 5424 return true; 5425 } 5426 } 5427 }); 5428 }, 5429 5430 not: function( selector ) { 5431 return this.pushStack( winnow(this, selector, false), "not", selector); 5432 }, 5433 5434 filter: function( selector ) { 5435 return this.pushStack( winnow(this, selector, true), "filter", selector ); 5436 }, 5437 5438 is: function( selector ) { 5439 return !!selector && ( 5440 typeof selector === "string" ? 5441 // If this is a positional selector, check membership in the returned set 5442 // so $("p:first").is("p:last") won't return true for a doc with two "p". 5443 POS.test( selector ) ? 5444 jQuery( selector, this.context ).index( this[0] ) >= 0 : 5445 jQuery.filter( selector, this ).length > 0 : 5446 this.filter( selector ).length > 0 ); 5447 }, 5448 5449 closest: function( selectors, context ) { 5450 var ret = [], i, l, cur = this[0]; 5451 5452 // Array (deprecated as of jQuery 1.7) 5453 if ( jQuery.isArray( selectors ) ) { 5454 var level = 1; 5455 5456 while ( cur && cur.ownerDocument && cur !== context ) { 5457 for ( i = 0; i < selectors.length; i++ ) { 5458 5459 if ( jQuery( cur ).is( selectors[ i ] ) ) { 5460 ret.push({ selector: selectors[ i ], elem: cur, level: level }); 5461 } 5462 } 5463 5464 cur = cur.parentNode; 5465 level++; 5466 } 5467 5468 return ret; 5469 } 5470 5471 // String 5472 var pos = POS.test( selectors ) || typeof selectors !== "string" ? 5473 jQuery( selectors, context || this.context ) : 5474 0; 5475 5476 for ( i = 0, l = this.length; i < l; i++ ) { 5477 cur = this[i]; 5478 5479 while ( cur ) { 5480 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { 5481 ret.push( cur ); 5482 break; 5483 5484 } else { 5485 cur = cur.parentNode; 5486 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { 5487 break; 5488 } 5489 } 5490 } 5491 } 5492 5493 ret = ret.length > 1 ? jQuery.unique( ret ) : ret; 5494 5495 return this.pushStack( ret, "closest", selectors ); 5496 }, 5497 5498 // Determine the position of an element within 5499 // the matched set of elements 5500 index: function( elem ) { 5501 5502 // No argument, return index in parent 5503 if ( !elem ) { 5504 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; 5505 } 5506 5507 // index in selector 5508 if ( typeof elem === "string" ) { 5509 return jQuery.inArray( this[0], jQuery( elem ) ); 5510 } 5511 5512 // Locate the position of the desired element 5513 return jQuery.inArray( 5514 // If it receives a jQuery object, the first element is used 5515 elem.jquery ? elem[0] : elem, this ); 5516 }, 5517 5518 add: function( selector, context ) { 5519 var set = typeof selector === "string" ? 5520 jQuery( selector, context ) : 5521 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), 5522 all = jQuery.merge( this.get(), set ); 5523 5524 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 5525 all : 5526 jQuery.unique( all ) ); 5527 }, 5528 5529 andSelf: function() { 5530 return this.add( this.prevObject ); 5531 } 5532}); 5533 5534// A painfully simple check to see if an element is disconnected 5535// from a document (should be improved, where feasible). 5536function isDisconnected( node ) { 5537 return !node || !node.parentNode || node.parentNode.nodeType === 11; 5538} 5539 5540jQuery.each({ 5541 parent: function( elem ) { 5542 var parent = elem.parentNode; 5543 return parent && parent.nodeType !== 11 ? parent : null; 5544 }, 5545 parents: function( elem ) { 5546 return jQuery.dir( elem, "parentNode" ); 5547 }, 5548 parentsUntil: function( elem, i, until ) { 5549 return jQuery.dir( elem, "parentNode", until ); 5550 }, 5551 next: function( elem ) { 5552 return jQuery.nth( elem, 2, "nextSibling" ); 5553 }, 5554 prev: function( elem ) { 5555 return jQuery.nth( elem, 2, "previousSibling" ); 5556 }, 5557 nextAll: function( elem ) { 5558 return jQuery.dir( elem, "nextSibling" ); 5559 }, 5560 prevAll: function( elem ) { 5561 return jQuery.dir( elem, "previousSibling" ); 5562 }, 5563 nextUntil: function( elem, i, until ) { 5564 return jQuery.dir( elem, "nextSibling", until ); 5565 }, 5566 prevUntil: function( elem, i, until ) { 5567 return jQuery.dir( elem, "previousSibling", until ); 5568 }, 5569 siblings: function( elem ) { 5570 return jQuery.sibling( elem.parentNode.firstChild, elem ); 5571 }, 5572 children: function( elem ) { 5573 return jQuery.sibling( elem.firstChild ); 5574 }, 5575 contents: function( elem ) { 5576 return jQuery.nodeName( elem, "iframe" ) ? 5577 elem.contentDocument || elem.contentWindow.document : 5578 jQuery.makeArray( elem.childNodes ); 5579 } 5580}, function( name, fn ) { 5581 jQuery.fn[ name ] = function( until, selector ) { 5582 var ret = jQuery.map( this, fn, until ), 5583 // The variable 'args' was introduced in 5584 // https://github.com/jquery/jquery/commit/52a0238 5585 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. 5586 // http://code.google.com/p/v8/issues/detail?id=1050 5587 args = slice.call(arguments); 5588 5589 if ( !runtil.test( name ) ) { 5590 selector = until; 5591 } 5592 5593 if ( selector && typeof selector === "string" ) { 5594 ret = jQuery.filter( selector, ret ); 5595 } 5596 5597 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; 5598 5599 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 5600 ret = ret.reverse(); 5601 } 5602 5603 return this.pushStack( ret, name, args.join(",") ); 5604 }; 5605}); 5606 5607jQuery.extend({ 5608 filter: function( expr, elems, not ) { 5609 if ( not ) { 5610 expr = ":not(" + expr + ")"; 5611 } 5612 5613 return elems.length === 1 ? 5614 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : 5615 jQuery.find.matches(expr, elems); 5616 }, 5617 5618 dir: function( elem, dir, until ) { 5619 var matched = [], 5620 cur = elem[ dir ]; 5621 5622 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 5623 if ( cur.nodeType === 1 ) { 5624 matched.push( cur ); 5625 } 5626 cur = cur[dir]; 5627 } 5628 return matched; 5629 }, 5630 5631 nth: function( cur, result, dir, elem ) { 5632 result = result || 1; 5633 var num = 0; 5634 5635 for ( ; cur; cur = cur[dir] ) { 5636 if ( cur.nodeType === 1 && ++num === result ) { 5637 break; 5638 } 5639 } 5640 5641 return cur; 5642 }, 5643 5644 sibling: function( n, elem ) { 5645 var r = []; 5646 5647 for ( ; n; n = n.nextSibling ) { 5648 if ( n.nodeType === 1 && n !== elem ) { 5649 r.push( n ); 5650 } 5651 } 5652 5653 return r; 5654 } 5655}); 5656 5657// Implement the identical functionality for filter and not 5658function winnow( elements, qualifier, keep ) { 5659 5660 // Can't pass null or undefined to indexOf in Firefox 4 5661 // Set to 0 to skip string check 5662 qualifier = qualifier || 0; 5663 5664 if ( jQuery.isFunction( qualifier ) ) { 5665 return jQuery.grep(elements, function( elem, i ) { 5666 var retVal = !!qualifier.call( elem, i, elem ); 5667 return retVal === keep; 5668 }); 5669 5670 } else if ( qualifier.nodeType ) { 5671 return jQuery.grep(elements, function( elem, i ) { 5672 return ( elem === qualifier ) === keep; 5673 }); 5674 5675 } else if ( typeof qualifier === "string" ) { 5676 var filtered = jQuery.grep(elements, function( elem ) { 5677 return elem.nodeType === 1; 5678 }); 5679 5680 if ( isSimple.test( qualifier ) ) { 5681 return jQuery.filter(qualifier, filtered, !keep); 5682 } else { 5683 qualifier = jQuery.filter( qualifier, filtered ); 5684 } 5685 } 5686 5687 return jQuery.grep(elements, function( elem, i ) { 5688 return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; 5689 }); 5690} 5691 5692 5693 5694 5695function createSafeFragment( document ) { 5696 var list = nodeNames.split( " " ), 5697 safeFrag = document.createDocumentFragment(); 5698 5699 if ( safeFrag.createElement ) { 5700 while ( list.length ) { 5701 safeFrag.createElement( 5702 list.pop() 5703 ); 5704 } 5705 } 5706 return safeFrag; 5707} 5708 5709var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " + 5710 "header hgroup mark meter nav output progress section summary time video", 5711 rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 5712 rleadingWhitespace = /^\s+/, 5713 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 5714 rtagName = /<([\w:]+)/, 5715 rtbody = /<tbody/i, 5716 rhtml = /<|&#?\w+;/, 5717 rnoInnerhtml = /<(?:script|style)/i, 5718 rnocache = /<(?:script|object|embed|option|style)/i, 5719 rnoshimcache = new RegExp("<(?:" + nodeNames.replace(" ", "|") + ")", "i"), 5720 // checked="checked" or checked 5721 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5722 rscriptType = /\/(java|ecma)script/i, 5723 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, 5724 wrapMap = { 5725 option: [ 1, "<select multiple='multiple'>", "</select>" ], 5726 legend: [ 1, "<fieldset>", "</fieldset>" ], 5727 thead: [ 1, "<table>", "</table>" ], 5728 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5729 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5730 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 5731 area: [ 1, "<map>", "</map>" ], 5732 _default: [ 0, "", "" ] 5733 }, 5734 safeFragment = createSafeFragment( document ); 5735 5736wrapMap.optgroup = wrapMap.option; 5737wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5738wrapMap.th = wrapMap.td; 5739 5740// IE can't serialize <link> and <script> tags normally 5741if ( !jQuery.support.htmlSerialize ) { 5742 wrapMap._default = [ 1, "div<div>", "</div>" ]; 5743} 5744 5745jQuery.fn.extend({ 5746 text: function( text ) { 5747 if ( jQuery.isFunction(text) ) { 5748 return this.each(function(i) { 5749 var self = jQuery( this ); 5750 5751 self.text( text.call(this, i, self.text()) ); 5752 }); 5753 } 5754 5755 if ( typeof text !== "object" && text !== undefined ) { 5756 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 5757 } 5758 5759 return jQuery.text( this ); 5760 }, 5761 5762 wrapAll: function( html ) { 5763 if ( jQuery.isFunction( html ) ) { 5764 return this.each(function(i) { 5765 jQuery(this).wrapAll( html.call(this, i) ); 5766 }); 5767 } 5768 5769 if ( this[0] ) { 5770 // The elements to wrap the target around 5771 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 5772 5773 if ( this[0].parentNode ) { 5774 wrap.insertBefore( this[0] ); 5775 } 5776 5777 wrap.map(function() { 5778 var elem = this; 5779 5780 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 5781 elem = elem.firstChild; 5782 } 5783 5784 return elem; 5785 }).append( this ); 5786 } 5787 5788 return this; 5789 }, 5790 5791 wrapInner: function( html ) { 5792 if ( jQuery.isFunction( html ) ) { 5793 return this.each(function(i) { 5794 jQuery(this).wrapInner( html.call(this, i) ); 5795 }); 5796 } 5797 5798 return this.each(function() { 5799 var self = jQuery( this ), 5800 contents = self.contents(); 5801 5802 if ( contents.length ) { 5803 contents.wrapAll( html ); 5804 5805 } else { 5806 self.append( html ); 5807 } 5808 }); 5809 }, 5810 5811 wrap: function( html ) { 5812 return this.each(function() { 5813 jQuery( this ).wrapAll( html ); 5814 }); 5815 }, 5816 5817 unwrap: function() { 5818 return this.parent().each(function() { 5819 if ( !jQuery.nodeName( this, "body" ) ) { 5820 jQuery( this ).replaceWith( this.childNodes ); 5821 } 5822 }).end(); 5823 }, 5824 5825 append: function() { 5826 return this.domManip(arguments, true, function( elem ) { 5827 if ( this.nodeType === 1 ) { 5828 this.appendChild( elem ); 5829 } 5830 }); 5831 }, 5832 5833 prepend: function() { 5834 return this.domManip(arguments, true, function( elem ) { 5835 if ( this.nodeType === 1 ) { 5836 this.insertBefore( elem, this.firstChild ); 5837 } 5838 }); 5839 }, 5840 5841 before: function() { 5842 if ( this[0] && this[0].parentNode ) { 5843 return this.domManip(arguments, false, function( elem ) { 5844 this.parentNode.insertBefore( elem, this ); 5845 }); 5846 } else if ( arguments.length ) { 5847 var set = jQuery(arguments[0]); 5848 set.push.apply( set, this.toArray() ); 5849 return this.pushStack( set, "before", arguments ); 5850 } 5851 }, 5852 5853 after: function() { 5854 if ( this[0] && this[0].parentNode ) { 5855 return this.domManip(arguments, false, function( elem ) { 5856 this.parentNode.insertBefore( elem, this.nextSibling ); 5857 }); 5858 } else if ( arguments.length ) { 5859 var set = this.pushStack( this, "after", arguments ); 5860 set.push.apply( set, jQuery(arguments[0]).toArray() ); 5861 return set; 5862 } 5863 }, 5864 5865 // keepData is for internal use only--do not document 5866 remove: function( selector, keepData ) { 5867 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5868 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 5869 if ( !keepData && elem.nodeType === 1 ) { 5870 jQuery.cleanData( elem.getElementsByTagName("*") ); 5871 jQuery.cleanData( [ elem ] ); 5872 } 5873 5874 if ( elem.parentNode ) { 5875 elem.parentNode.removeChild( elem ); 5876 } 5877 } 5878 } 5879 5880 return this; 5881 }, 5882 5883 empty: function() { 5884 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5885 // Remove element nodes and prevent memory leaks 5886 if ( elem.nodeType === 1 ) { 5887 jQuery.cleanData( elem.getElementsByTagName("*") ); 5888 } 5889 5890 // Remove any remaining nodes 5891 while ( elem.firstChild ) { 5892 elem.removeChild( elem.firstChild ); 5893 } 5894 } 5895 5896 return this; 5897 }, 5898 5899 clone: function( dataAndEvents, deepDataAndEvents ) { 5900 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5901 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5902 5903 return this.map( function () { 5904 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5905 }); 5906 }, 5907 5908 html: function( value ) { 5909 if ( value === undefined ) { 5910 return this[0] && this[0].nodeType === 1 ? 5911 this[0].innerHTML.replace(rinlinejQuery, "") : 5912 null; 5913 5914 // See if we can take a shortcut and just use innerHTML 5915 } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 5916 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && 5917 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { 5918 5919 value = value.replace(rxhtmlTag, "<$1></$2>"); 5920 5921 try { 5922 for ( var i = 0, l = this.length; i < l; i++ ) { 5923 // Remove element nodes and prevent memory leaks 5924 if ( this[i].nodeType === 1 ) { 5925 jQuery.cleanData( this[i].getElementsByTagName("*") ); 5926 this[i].innerHTML = value; 5927 } 5928 } 5929 5930 // If using innerHTML throws an exception, use the fallback method 5931 } catch(e) { 5932 this.empty().append( value ); 5933 } 5934 5935 } else if ( jQuery.isFunction( value ) ) { 5936 this.each(function(i){ 5937 var self = jQuery( this ); 5938 5939 self.html( value.call(this, i, self.html()) ); 5940 }); 5941 5942 } else { 5943 this.empty().append( value ); 5944 } 5945 5946 return this; 5947 }, 5948 5949 replaceWith: function( value ) { 5950 if ( this[0] && this[0].parentNode ) { 5951 // Make sure that the elements are removed from the DOM before they are inserted 5952 // this can help fix replacing a parent with child elements 5953 if ( jQuery.isFunction( value ) ) { 5954 return this.each(function(i) { 5955 var self = jQuery(this), old = self.html(); 5956 self.replaceWith( value.call( this, i, old ) ); 5957 }); 5958 } 5959 5960 if ( typeof value !== "string" ) { 5961 value = jQuery( value ).detach(); 5962 } 5963 5964 return this.each(function() { 5965 var next = this.nextSibling, 5966 parent = this.parentNode; 5967 5968 jQuery( this ).remove(); 5969 5970 if ( next ) { 5971 jQuery(next).before( value ); 5972 } else { 5973 jQuery(parent).append( value ); 5974 } 5975 }); 5976 } else { 5977 return this.length ? 5978 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : 5979 this; 5980 } 5981 }, 5982 5983 detach: function( selector ) { 5984 return this.remove( selector, true ); 5985 }, 5986 5987 domManip: function( args, table, callback ) { 5988 var results, first, fragment, parent, 5989 value = args[0], 5990 scripts = []; 5991 5992 // We can't cloneNode fragments that contain checked, in WebKit 5993 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 5994 return this.each(function() { 5995 jQuery(this).domManip( args, table, callback, true ); 5996 }); 5997 } 5998 5999 if ( jQuery.isFunction(value) ) { 6000 return this.each(function(i) { 6001 var self = jQuery(this); 6002 args[0] = value.call(this, i, table ? self.html() : undefined); 6003 self.domManip( args, table, callback ); 6004 }); 6005 } 6006 6007 if ( this[0] ) { 6008 parent = value && value.parentNode; 6009 6010 // If we're in a fragment, just use that instead of building a new one 6011 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { 6012 results = { fragment: parent }; 6013 6014 } else { 6015 results = jQuery.buildFragment( args, this, scripts ); 6016 } 6017 6018 fragment = results.fragment; 6019 6020 if ( fragment.childNodes.length === 1 ) { 6021 first = fragment = fragment.firstChild; 6022 } else { 6023 first = fragment.firstChild; 6024 } 6025 6026 if ( first ) { 6027 table = table && jQuery.nodeName( first, "tr" ); 6028 6029 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { 6030 callback.call( 6031 table ? 6032 root(this[i], first) : 6033 this[i], 6034 // Make sure that we do not leak memory by inadvertently discarding 6035 // the original fragment (which might have attached data) instead of 6036 // using it; in addition, use the original fragment object for the last 6037 // item instead of first because it can end up being emptied incorrectly 6038 // in certain situations (Bug #8070). 6039 // Fragments from the fragment cache must always be cloned and never used 6040 // in place. 6041 results.cacheable || ( l > 1 && i < lastIndex ) ? 6042 jQuery.clone( fragment, true, true ) : 6043 fragment 6044 ); 6045 } 6046 } 6047 6048 if ( scripts.length ) { 6049 jQuery.each( scripts, evalScript ); 6050 } 6051 } 6052 6053 return this; 6054 } 6055}); 6056 6057function root( elem, cur ) { 6058 return jQuery.nodeName(elem, "table") ? 6059 (elem.getElementsByTagName("tbody")[0] || 6060 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 6061 elem; 6062} 6063 6064function cloneCopyEvent( src, dest ) { 6065 6066 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { 6067 return; 6068 } 6069 6070 var type, i, l, 6071 oldData = jQuery._data( src ), 6072 curData = jQuery._data( dest, oldData ), 6073 events = oldData.events; 6074 6075 if ( events ) { 6076 delete curData.handle; 6077 curData.events = {}; 6078 6079 for ( type in events ) { 6080 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 6081 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); 6082 } 6083 } 6084 } 6085 6086 // make the cloned public data object a copy from the original 6087 if ( curData.data ) { 6088 curData.data = jQuery.extend( {}, curData.data ); 6089 } 6090} 6091 6092function cloneFixAttributes( src, dest ) { 6093 var nodeName; 6094 6095 // We do not need to do anything for non-Elements 6096 if ( dest.nodeType !== 1 ) { 6097 return; 6098 } 6099 6100 // clearAttributes removes the attributes, which we don't want, 6101 // but also removes the attachEvent events, which we *do* want 6102 if ( dest.clearAttributes ) { 6103 dest.clearAttributes(); 6104 } 6105 6106 // mergeAttributes, in contrast, only merges back on the 6107 // original attributes, not the events 6108 if ( dest.mergeAttributes ) { 6109 dest.mergeAttributes( src ); 6110 } 6111 6112 nodeName = dest.nodeName.toLowerCase(); 6113 6114 // IE6-8 fail to clone children inside object elements that use 6115 // the proprietary classid attribute value (rather than the type 6116 // attribute) to identify the type of content to display 6117 if ( nodeName === "object" ) { 6118 dest.outerHTML = src.outerHTML; 6119 6120 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { 6121 // IE6-8 fails to persist the checked state of a cloned checkbox 6122 // or radio button. Worse, IE6-7 fail to give the cloned element 6123 // a checked appearance if the defaultChecked value isn't also set 6124 if ( src.checked ) { 6125 dest.defaultChecked = dest.checked = src.checked; 6126 } 6127 6128 // IE6-7 get confused and end up setting the value of a cloned 6129 // checkbox/radio button to an empty string instead of "on" 6130 if ( dest.value !== src.value ) { 6131 dest.value = src.value; 6132 } 6133 6134 // IE6-8 fails to return the selected option to the default selected 6135 // state when cloning options 6136 } else if ( nodeName === "option" ) { 6137 dest.selected = src.defaultSelected; 6138 6139 // IE6-8 fails to set the defaultValue to the correct value when 6140 // cloning other types of input fields 6141 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6142 dest.defaultValue = src.defaultValue; 6143 } 6144 6145 // Event data gets referenced instead of copied if the expando 6146 // gets copied too 6147 dest.removeAttribute( jQuery.expando ); 6148} 6149 6150jQuery.buildFragment = function( args, nodes, scripts ) { 6151 var fragment, cacheable, cacheresults, doc, 6152 first = args[ 0 ]; 6153 6154 // nodes may contain either an explicit document object, 6155 // a jQuery collection or context object. 6156 // If nodes[0] contains a valid object to assign to doc 6157 if ( nodes && nodes[0] ) { 6158 doc = nodes[0].ownerDocument || nodes[0]; 6159 } 6160 6161 // Ensure that an attr object doesn't incorrectly stand in as a document object 6162 // Chrome and Firefox seem to allow this to occur and will throw exception 6163 // Fixes #8950 6164 if ( !doc.createDocumentFragment ) { 6165 doc = document; 6166 } 6167 6168 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document 6169 // Cloning options loses the selected state, so don't cache them 6170 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 6171 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 6172 // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 6173 if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && 6174 first.charAt(0) === "<" && !rnocache.test( first ) && 6175 (jQuery.support.checkClone || !rchecked.test( first )) && 6176 (!jQuery.support.unknownElems && rnoshimcache.test( first )) ) { 6177 6178 cacheable = true; 6179 6180 cacheresults = jQuery.fragments[ first ]; 6181 if ( cacheresults && cacheresults !== 1 ) { 6182 fragment = cacheresults; 6183 } 6184 } 6185 6186 if ( !fragment ) { 6187 fragment = doc.createDocumentFragment(); 6188 jQuery.clean( args, doc, fragment, scripts ); 6189 } 6190 6191 if ( cacheable ) { 6192 jQuery.fragments[ first ] = cacheresults ? fragment : 1; 6193 } 6194 6195 return { fragment: fragment, cacheable: cacheable }; 6196}; 6197 6198jQuery.fragments = {}; 6199 6200jQuery.each({ 6201 appendTo: "append", 6202 prependTo: "prepend", 6203 insertBefore: "before", 6204 insertAfter: "after", 6205 replaceAll: "replaceWith" 6206}, function( name, original ) { 6207 jQuery.fn[ name ] = function( selector ) { 6208 var ret = [], 6209 insert = jQuery( selector ), 6210 parent = this.length === 1 && this[0].parentNode; 6211 6212 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 6213 insert[ original ]( this[0] ); 6214 return this; 6215 6216 } else { 6217 for ( var i = 0, l = insert.length; i < l; i++ ) { 6218 var elems = ( i > 0 ? this.clone(true) : this ).get(); 6219 jQuery( insert[i] )[ original ]( elems ); 6220 ret = ret.concat( elems ); 6221 } 6222 6223 return this.pushStack( ret, name, insert.selector ); 6224 } 6225 }; 6226}); 6227 6228function getAll( elem ) { 6229 if ( typeof elem.getElementsByTagName !== "undefined" ) { 6230 return elem.getElementsByTagName( "*" ); 6231 6232 } else if ( typeof elem.querySelectorAll !== "undefined" ) { 6233 return elem.querySelectorAll( "*" ); 6234 6235 } else { 6236 return []; 6237 } 6238} 6239 6240// Used in clean, fixes the defaultChecked property 6241function fixDefaultChecked( elem ) { 6242 if ( elem.type === "checkbox" || elem.type === "radio" ) { 6243 elem.defaultChecked = elem.checked; 6244 } 6245} 6246// Finds all inputs and passes them to fixDefaultChecked 6247function findInputs( elem ) { 6248 var nodeName = ( elem.nodeName || "" ).toLowerCase(); 6249 if ( nodeName === "input" ) { 6250 fixDefaultChecked( elem ); 6251 // Skip scripts, get other children 6252 } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) { 6253 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); 6254 } 6255} 6256 6257jQuery.extend({ 6258 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6259 var clone = elem.cloneNode(true), 6260 srcElements, 6261 destElements, 6262 i; 6263 6264 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && 6265 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { 6266 // IE copies events bound via attachEvent when using cloneNode. 6267 // Calling detachEvent on the clone will also remove the events 6268 // from the original. In order to get around this, we use some 6269 // proprietary methods to clear the events. Thanks to MooTools 6270 // guys for this hotness. 6271 6272 cloneFixAttributes( elem, clone ); 6273 6274 // Using Sizzle here is crazy slow, so we use getElementsByTagName 6275 // instead 6276 srcElements = getAll( elem ); 6277 destElements = getAll( clone ); 6278 6279 // Weird iteration because IE will replace the length property 6280 // with an element if you are cloning the body and one of the 6281 // elements on the page has a name or id of "length" 6282 for ( i = 0; srcElements[i]; ++i ) { 6283 // Ensure that the destination node is not null; Fixes #9587 6284 if ( destElements[i] ) { 6285 cloneFixAttributes( srcElements[i], destElements[i] ); 6286 } 6287 } 6288 } 6289 6290 // Copy the events from the original to the clone 6291 if ( dataAndEvents ) { 6292 cloneCopyEvent( elem, clone ); 6293 6294 if ( deepDataAndEvents ) { 6295 srcElements = getAll( elem ); 6296 destElements = getAll( clone ); 6297 6298 for ( i = 0; srcElements[i]; ++i ) { 6299 cloneCopyEvent( srcElements[i], destElements[i] ); 6300 } 6301 } 6302 } 6303 6304 srcElements = destElements = null; 6305 6306 // Return the cloned set 6307 return clone; 6308 }, 6309 6310 clean: function( elems, context, fragment, scripts ) { 6311 var checkScriptType; 6312 6313 context = context || document; 6314 6315 // !context.createElement fails in IE with an error but returns typeof 'object' 6316 if ( typeof context.createElement === "undefined" ) { 6317 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 6318 } 6319 6320 var ret = [], j; 6321 6322 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6323 if ( typeof elem === "number" ) { 6324 elem += ""; 6325 } 6326 6327 if ( !elem ) { 6328 continue; 6329 } 6330 6331 // Convert html string into DOM nodes 6332 if ( typeof elem === "string" ) { 6333 if ( !rhtml.test( elem ) ) { 6334 elem = context.createTextNode( elem ); 6335 } else { 6336 // Fix "XHTML"-style tags in all browsers 6337 elem = elem.replace(rxhtmlTag, "<$1></$2>"); 6338 6339 // Trim whitespace, otherwise indexOf won't work as expected 6340 var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(), 6341 wrap = wrapMap[ tag ] || wrapMap._default, 6342 depth = wrap[0], 6343 div = context.createElement("div"); 6344 6345 // Append wrapper element to unknown element safe doc fragment 6346 if ( context === document ) { 6347 // Use the fragment we've already created for this document 6348 safeFragment.appendChild( div ); 6349 } else { 6350 // Use a fragment created with the owner document 6351 createSafeFragment( context ).appendChild( div ); 6352 } 6353 6354 // Go to html and back, then peel off extra wrappers 6355 div.innerHTML = wrap[1] + elem + wrap[2]; 6356 6357 // Move to the right depth 6358 while ( depth-- ) { 6359 div = div.lastChild; 6360 } 6361 6362 // Remove IE's autoinserted <tbody> from table fragments 6363 if ( !jQuery.support.tbody ) { 6364 6365 // String was a <table>, *may* have spurious <tbody> 6366 var hasBody = rtbody.test(elem), 6367 tbody = tag === "table" && !hasBody ? 6368 div.firstChild && div.firstChild.childNodes : 6369 6370 // String was a bare <thead> or <tfoot> 6371 wrap[1] === "<table>" && !hasBody ? 6372 div.childNodes : 6373 []; 6374 6375 for ( j = tbody.length - 1; j >= 0 ; --j ) { 6376 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 6377 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 6378 } 6379 } 6380 } 6381 6382 // IE completely kills leading whitespace when innerHTML is used 6383 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 6384 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 6385 } 6386 6387 elem = div.childNodes; 6388 } 6389 } 6390 6391 // Resets defaultChecked for any radios and checkboxes 6392 // about to be appended to the DOM in IE 6/7 (#8060) 6393 var len; 6394 if ( !jQuery.support.appendChecked ) { 6395 if ( elem[0] && typeof (len = elem.length) === "number" ) { 6396 for ( j = 0; j < len; j++ ) { 6397 findInputs( elem[j] ); 6398 } 6399 } else { 6400 findInputs( elem ); 6401 } 6402 } 6403 6404 if ( elem.nodeType ) { 6405 ret.push( elem ); 6406 } else { 6407 ret = jQuery.merge( ret, elem ); 6408 } 6409 } 6410 6411 if ( fragment ) { 6412 checkScriptType = function( elem ) { 6413 return !elem.type || rscriptType.test( elem.type ); 6414 }; 6415 for ( i = 0; ret[i]; i++ ) { 6416 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { 6417 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); 6418 6419 } else { 6420 if ( ret[i].nodeType === 1 ) { 6421 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); 6422 6423 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); 6424 } 6425 fragment.appendChild( ret[i] ); 6426 } 6427 } 6428 } 6429 6430 return ret; 6431 }, 6432 6433 cleanData: function( elems ) { 6434 var data, id, 6435 cache = jQuery.cache, 6436 special = jQuery.event.special, 6437 deleteExpando = jQuery.support.deleteExpando; 6438 6439 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6440 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 6441 continue; 6442 } 6443 6444 id = elem[ jQuery.expando ]; 6445 6446 if ( id ) { 6447 data = cache[ id ]; 6448 6449 if ( data && data.events ) { 6450 for ( var type in data.events ) { 6451 if ( special[ type ] ) { 6452 jQuery.event.remove( elem, type ); 6453 6454 // This is a shortcut to avoid jQuery.event.remove's overhead 6455 } else { 6456 jQuery.removeEvent( elem, type, data.handle ); 6457 } 6458 } 6459 6460 // Null the DOM reference to avoid IE6/7/8 leak (#7054) 6461 if ( data.handle ) { 6462 data.handle.elem = null; 6463 } 6464 } 6465 6466 if ( deleteExpando ) { 6467 delete elem[ jQuery.expando ]; 6468 6469 } else if ( elem.removeAttribute ) { 6470 elem.removeAttribute( jQuery.expando ); 6471 } 6472 6473 delete cache[ id ]; 6474 } 6475 } 6476 } 6477}); 6478 6479function evalScript( i, elem ) { 6480 if ( elem.src ) { 6481 jQuery.ajax({ 6482 url: elem.src, 6483 async: false, 6484 dataType: "script" 6485 }); 6486 } else { 6487 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); 6488 } 6489 6490 if ( elem.parentNode ) { 6491 elem.parentNode.removeChild( elem ); 6492 } 6493} 6494 6495 6496 6497 6498var ralpha = /alpha\([^)]*\)/i, 6499 ropacity = /opacity=([^)]*)/, 6500 // fixed for IE9, see #8346 6501 rupper = /([A-Z]|^ms)/g, 6502 rnumpx = /^-?\d+(?:px)?$/i, 6503 rnum = /^-?\d/, 6504 rrelNum = /^([\-+])=([\-+.\de]+)/, 6505 6506 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6507 cssWidth = [ "Left", "Right" ], 6508 cssHeight = [ "Top", "Bottom" ], 6509 curCSS, 6510 6511 getComputedStyle, 6512 currentStyle; 6513 6514jQuery.fn.css = function( name, value ) { 6515 // Setting 'undefined' is a no-op 6516 if ( arguments.length === 2 && value === undefined ) { 6517 return this; 6518 } 6519 6520 return jQuery.access( this, name, value, true, function( elem, name, value ) { 6521 return value !== undefined ? 6522 jQuery.style( elem, name, value ) : 6523 jQuery.css( elem, name ); 6524 }); 6525}; 6526 6527jQuery.extend({ 6528 // Add in style property hooks for overriding the default 6529 // behavior of getting and setting a style property 6530 cssHooks: { 6531 opacity: { 6532 get: function( elem, computed ) { 6533 if ( computed ) { 6534 // We should always get a number back from opacity 6535 var ret = curCSS( elem, "opacity", "opacity" ); 6536 return ret === "" ? "1" : ret; 6537 6538 } else { 6539 return elem.style.opacity; 6540 } 6541 } 6542 } 6543 }, 6544 6545 // Exclude the following css properties to add px 6546 cssNumber: { 6547 "fillOpacity": true, 6548 "fontWeight": true, 6549 "lineHeight": true, 6550 "opacity": true, 6551 "orphans": true, 6552 "widows": true, 6553 "zIndex": true, 6554 "zoom": true 6555 }, 6556 6557 // Add in properties whose names you wish to fix before 6558 // setting or getting the value 6559 cssProps: { 6560 // normalize float css property 6561 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" 6562 }, 6563 6564 // Get and set the style property on a DOM Node 6565 style: function( elem, name, value, extra ) { 6566 // Don't set styles on text and comment nodes 6567 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6568 return; 6569 } 6570 6571 // Make sure that we're working with the right name 6572 var ret, type, origName = jQuery.camelCase( name ), 6573 style = elem.style, hooks = jQuery.cssHooks[ origName ]; 6574 6575 name = jQuery.cssProps[ origName ] || origName; 6576 6577 // Check if we're setting a value 6578 if ( value !== undefined ) { 6579 type = typeof value; 6580 6581 // convert relative number strings (+= or -=) to relative numbers. #7345 6582 if ( type === "string" && (ret = rrelNum.exec( value )) ) { 6583 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) ); 6584 // Fixes bug #9237 6585 type = "number"; 6586 } 6587 6588 // Make sure that NaN and null values aren't set. See: #7116 6589 if ( value == null || type === "number" && isNaN( value ) ) { 6590 return; 6591 } 6592 6593 // If a number was passed in, add 'px' to the (except for certain CSS properties) 6594 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { 6595 value += "px"; 6596 } 6597 6598 // If a hook was provided, use that value, otherwise just set the specified value 6599 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { 6600 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided 6601 // Fixes bug #5509 6602 try { 6603 style[ name ] = value; 6604 } catch(e) {} 6605 } 6606 6607 } else { 6608 // If a hook was provided get the non-computed value from there 6609 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 6610 return ret; 6611 } 6612 6613 // Otherwise just get the value from the style object 6614 return style[ name ]; 6615 } 6616 }, 6617 6618 css: function( elem, name, extra ) { 6619 var ret, hooks; 6620 6621 // Make sure that we're working with the right name 6622 name = jQuery.camelCase( name ); 6623 hooks = jQuery.cssHooks[ name ]; 6624 name = jQuery.cssProps[ name ] || name; 6625 6626 // cssFloat needs a special treatment 6627 if ( name === "cssFloat" ) { 6628 name = "float"; 6629 } 6630 6631 // If a hook was provided get the computed value from there 6632 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { 6633 return ret; 6634 6635 // Otherwise, if a way to get the computed value exists, use that 6636 } else if ( curCSS ) { 6637 return curCSS( elem, name ); 6638 } 6639 }, 6640 6641 // A method for quickly swapping in/out CSS properties to get correct calculations 6642 swap: function( elem, options, callback ) { 6643 var old = {}; 6644 6645 // Remember the old values, and insert the new ones 6646 for ( var name in options ) { 6647 old[ name ] = elem.style[ name ]; 6648 elem.style[ name ] = options[ name ]; 6649 } 6650 6651 callback.call( elem ); 6652 6653 // Revert the old values 6654 for ( name in options ) { 6655 elem.style[ name ] = old[ name ]; 6656 } 6657 } 6658}); 6659 6660// DEPRECATED, Use jQuery.css() instead 6661jQuery.curCSS = jQuery.css; 6662 6663jQuery.each(["height", "width"], function( i, name ) { 6664 jQuery.cssHooks[ name ] = { 6665 get: function( elem, computed, extra ) { 6666 var val; 6667 6668 if ( computed ) { 6669 if ( elem.offsetWidth !== 0 ) { 6670 return getWH( elem, name, extra ); 6671 } else { 6672 jQuery.swap( elem, cssShow, function() { 6673 val = getWH( elem, name, extra ); 6674 }); 6675 } 6676 6677 return val; 6678 } 6679 }, 6680 6681 set: function( elem, value ) { 6682 if ( rnumpx.test( value ) ) { 6683 // ignore negative width and height values #1599 6684 value = parseFloat( value ); 6685 6686 if ( value >= 0 ) { 6687 return value + "px"; 6688 } 6689 6690 } else { 6691 return value; 6692 } 6693 } 6694 }; 6695}); 6696 6697if ( !jQuery.support.opacity ) { 6698 jQuery.cssHooks.opacity = { 6699 get: function( elem, computed ) { 6700 // IE uses filters for opacity 6701 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? 6702 ( parseFloat( RegExp.$1 ) / 100 ) + "" : 6703 computed ? "1" : ""; 6704 }, 6705 6706 set: function( elem, value ) { 6707 var style = elem.style, 6708 currentStyle = elem.currentStyle, 6709 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", 6710 filter = currentStyle && currentStyle.filter || style.filter || ""; 6711 6712 // IE has trouble with opacity if it does not have layout 6713 // Force it by setting the zoom level 6714 style.zoom = 1; 6715 6716 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 6717 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) { 6718 6719 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText 6720 // if "filter:" is present at all, clearType is disabled, we want to avoid this 6721 // style.removeAttribute is IE Only, but so apparently is this code path... 6722 style.removeAttribute( "filter" ); 6723 6724 // if there there is no filter style applied in a css rule, we are done 6725 if ( currentStyle && !currentStyle.filter ) { 6726 return; 6727 } 6728 } 6729 6730 // otherwise, set new filter values 6731 style.filter = ralpha.test( filter ) ? 6732 filter.replace( ralpha, opacity ) : 6733 filter + " " + opacity; 6734 } 6735 }; 6736} 6737 6738jQuery(function() { 6739 // This hook cannot be added until DOM ready because the support test 6740 // for it is not run until after DOM ready 6741 if ( !jQuery.support.reliableMarginRight ) { 6742 jQuery.cssHooks.marginRight = { 6743 get: function( elem, computed ) { 6744 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 6745 // Work around by temporarily setting element display to inline-block 6746 var ret; 6747 jQuery.swap( elem, { "display": "inline-block" }, function() { 6748 if ( computed ) { 6749 ret = curCSS( elem, "margin-right", "marginRight" ); 6750 } else { 6751 ret = elem.style.marginRight; 6752 } 6753 }); 6754 return ret; 6755 } 6756 }; 6757 } 6758}); 6759 6760if ( document.defaultView && document.defaultView.getComputedStyle ) { 6761 getComputedStyle = function( elem, name ) { 6762 var ret, defaultView, computedStyle; 6763 6764 name = name.replace( rupper, "-$1" ).toLowerCase(); 6765 6766 if ( !(defaultView = elem.ownerDocument.defaultView) ) { 6767 return undefined; 6768 } 6769 6770 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { 6771 ret = computedStyle.getPropertyValue( name ); 6772 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { 6773 ret = jQuery.style( elem, name ); 6774 } 6775 } 6776 6777 return ret; 6778 }; 6779} 6780 6781if ( document.documentElement.currentStyle ) { 6782 currentStyle = function( elem, name ) { 6783 var left, rsLeft, uncomputed, 6784 ret = elem.currentStyle && elem.currentStyle[ name ], 6785 style = elem.style; 6786 6787 // Avoid setting ret to empty string here 6788 // so we don't default to auto 6789 if ( ret === null && style && (uncomputed = style[ name ]) ) { 6790 ret = uncomputed; 6791 } 6792 6793 // From the awesome hack by Dean Edwards 6794 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6795 6796 // If we're not dealing with a regular pixel number 6797 // but a number that has a weird ending, we need to convert it to pixels 6798 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { 6799 6800 // Remember the original values 6801 left = style.left; 6802 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; 6803 6804 // Put in the new values to get a computed value out 6805 if ( rsLeft ) { 6806 elem.runtimeStyle.left = elem.currentStyle.left; 6807 } 6808 style.left = name === "fontSize" ? "1em" : ( ret || 0 ); 6809 ret = style.pixelLeft + "px"; 6810 6811 // Revert the changed values 6812 style.left = left; 6813 if ( rsLeft ) { 6814 elem.runtimeStyle.left = rsLeft; 6815 } 6816 } 6817 6818 return ret === "" ? "auto" : ret; 6819 }; 6820} 6821 6822curCSS = getComputedStyle || currentStyle; 6823 6824function getWH( elem, name, extra ) { 6825 6826 // Start with offset property 6827 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 6828 which = name === "width" ? cssWidth : cssHeight; 6829 6830 if ( val > 0 ) { 6831 if ( extra !== "border" ) { 6832 jQuery.each( which, function() { 6833 if ( !extra ) { 6834 val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; 6835 } 6836 if ( extra === "margin" ) { 6837 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; 6838 } else { 6839 val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; 6840 } 6841 }); 6842 } 6843 6844 return val + "px"; 6845 } 6846 6847 // Fall back to computed then uncomputed css if necessary 6848 val = curCSS( elem, name, name ); 6849 if ( val < 0 || val == null ) { 6850 val = elem.style[ name ] || 0; 6851 } 6852 // Normalize "", auto, and prepare for extra 6853 val = parseFloat( val ) || 0; 6854 6855 // Add padding, border, margin 6856 if ( extra ) { 6857 jQuery.each( which, function() { 6858 val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; 6859 if ( extra !== "padding" ) { 6860 val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; 6861 } 6862 if ( extra === "margin" ) { 6863 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; 6864 } 6865 }); 6866 } 6867 6868 return val + "px"; 6869} 6870 6871if ( jQuery.expr && jQuery.expr.filters ) { 6872 jQuery.expr.filters.hidden = function( elem ) { 6873 var width = elem.offsetWidth, 6874 height = elem.offsetHeight; 6875 6876 return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); 6877 }; 6878 6879 jQuery.expr.filters.visible = function( elem ) { 6880 return !jQuery.expr.filters.hidden( elem ); 6881 }; 6882} 6883 6884 6885 6886 6887var r20 = /%20/g, 6888 rbracket = /\[\]$/, 6889 rCRLF = /\r?\n/g, 6890 rhash = /#.*$/, 6891 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL 6892 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, 6893 // #7653, #8125, #8152: local protocol detection 6894 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, 6895 rnoContent = /^(?:GET|HEAD)$/, 6896 rprotocol = /^\/\//, 6897 rquery = /\?/, 6898 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 6899 rselectTextarea = /^(?:select|textarea)/i, 6900 rspacesAjax = /\s+/, 6901 rts = /([?&])_=[^&]*/, 6902 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, 6903 6904 // Keep a copy of the old load method 6905 _load = jQuery.fn.load, 6906 6907 /* Prefilters 6908 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 6909 * 2) These are called: 6910 * - BEFORE asking for a transport 6911 * - AFTER param serialization (s.data is a string if s.processData is true) 6912 * 3) key is the dataType 6913 * 4) the catchall symbol "*" can be used 6914 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 6915 */ 6916 prefilters = {}, 6917 6918 /* Transports bindings 6919 * 1) key is the dataType 6920 * 2) the catchall symbol "*" can be used 6921 * 3) selection will start with transport dataType and THEN go to "*" if needed 6922 */ 6923 transports = {}, 6924 6925 // Document location 6926 ajaxLocation, 6927 6928 // Document location segments 6929 ajaxLocParts, 6930 6931 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 6932 allTypes = ["*/"] + ["*"]; 6933 6934// #8138, IE may throw an exception when accessing 6935// a field from window.location if document.domain has been set 6936try { 6937 ajaxLocation = location.href; 6938} catch( e ) { 6939 // Use the href attribute of an A element 6940 // since IE will modify it given document.location 6941 ajaxLocation = document.createElement( "a" ); 6942 ajaxLocation.href = ""; 6943 ajaxLocation = ajaxLocation.href; 6944} 6945 6946// Segment location into parts 6947ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 6948 6949// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 6950function addToPrefiltersOrTransports( structure ) { 6951 6952 // dataTypeExpression is optional and defaults to "*" 6953 return function( dataTypeExpression, func ) { 6954 6955 if ( typeof dataTypeExpression !== "string" ) { 6956 func = dataTypeExpression; 6957 dataTypeExpression = "*"; 6958 } 6959 6960 if ( jQuery.isFunction( func ) ) { 6961 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), 6962 i = 0, 6963 length = dataTypes.length, 6964 dataType, 6965 list, 6966 placeBefore; 6967 6968 // For each dataType in the dataTypeExpression 6969 for ( ; i < length; i++ ) { 6970 dataType = dataTypes[ i ]; 6971 // We control if we're asked to add before 6972 // any existing element 6973 placeBefore = /^\+/.test( dataType ); 6974 if ( placeBefore ) { 6975 dataType = dataType.substr( 1 ) || "*"; 6976 } 6977 list = structure[ dataType ] = structure[ dataType ] || []; 6978 // then we add to the structure accordingly 6979 list[ placeBefore ? "unshift" : "push" ]( func ); 6980 } 6981 } 6982 }; 6983} 6984 6985// Base inspection function for prefilters and transports 6986function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, 6987 dataType /* internal */, inspected /* internal */ ) { 6988 6989 dataType = dataType || options.dataTypes[ 0 ]; 6990 inspected = inspected || {}; 6991 6992 inspected[ dataType ] = true; 6993 6994 var list = structure[ dataType ], 6995 i = 0, 6996 length = list ? list.length : 0, 6997 executeOnly = ( structure === prefilters ), 6998 selection; 6999 7000 for ( ; i < length && ( executeOnly || !selection ); i++ ) { 7001 selection = list[ i ]( options, originalOptions, jqXHR ); 7002 // If we got redirected to another dataType 7003 // we try there if executing only and not done already 7004 if ( typeof selection === "string" ) { 7005 if ( !executeOnly || inspected[ selection ] ) { 7006 selection = undefined; 7007 } else { 7008 options.dataTypes.unshift( selection ); 7009 selection = inspectPrefiltersOrTransports( 7010 structure, options, originalOptions, jqXHR, selection, inspected ); 7011 } 7012 } 7013 } 7014 // If we're only executing or nothing was selected 7015 // we try the catchall dataType if not done already 7016 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { 7017 selection = inspectPrefiltersOrTransports( 7018 structure, options, originalOptions, jqXHR, "*", inspected ); 7019 } 7020 // unnecessary when only executing (prefilters) 7021 // but it'll be ignored by the caller in that case 7022 return selection; 7023} 7024 7025// A special extend for ajax options 7026// that takes "flat" options (not to be deep extended) 7027// Fixes #9887 7028function ajaxExtend( target, src ) { 7029 var key, deep, 7030 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 7031 for ( key in src ) { 7032 if ( src[ key ] !== undefined ) { 7033 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 7034 } 7035 } 7036 if ( deep ) { 7037 jQuery.extend( true, target, deep ); 7038 } 7039} 7040 7041jQuery.fn.extend({ 7042 load: function( url, params, callback ) { 7043 if ( typeof url !== "string" && _load ) { 7044 return _load.apply( this, arguments ); 7045 7046 // Don't do a request if no elements are being requested 7047 } else if ( !this.length ) { 7048 return this; 7049 } 7050 7051 var off = url.indexOf( " " ); 7052 if ( off >= 0 ) { 7053 var selector = url.slice( off, url.length ); 7054 url = url.slice( 0, off ); 7055 } 7056 7057 // Default to a GET request 7058 var type = "GET"; 7059 7060 // If the second parameter was provided 7061 if ( params ) { 7062 // If it's a function 7063 if ( jQuery.isFunction( params ) ) { 7064 // We assume that it's the callback 7065 callback = params; 7066 params = undefined; 7067 7068 // Otherwise, build a param string 7069 } else if ( typeof params === "object" ) { 7070 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 7071 type = "POST"; 7072 } 7073 } 7074 7075 var self = this; 7076 7077 // Request the remote document 7078 jQuery.ajax({ 7079 url: url, 7080 type: type, 7081 dataType: "html", 7082 data: params, 7083 // Complete callback (responseText is used internally) 7084 complete: function( jqXHR, status, responseText ) { 7085 // Store the response as specified by the jqXHR object 7086 responseText = jqXHR.responseText; 7087 // If successful, inject the HTML into all the matched elements 7088 if ( jqXHR.isResolved() ) { 7089 // #4825: Get the actual response in case 7090 // a dataFilter is present in ajaxSettings 7091 jqXHR.done(function( r ) { 7092 responseText = r; 7093 }); 7094 // See if a selector was specified 7095 self.html( selector ? 7096 // Create a dummy div to hold the results 7097 jQuery("<div>") 7098 // inject the contents of the document in, removing the scripts 7099 // to avoid any 'Permission Denied' errors in IE 7100 .append(responseText.replace(rscript, "")) 7101 7102 // Locate the specified elements 7103 .find(selector) : 7104 7105 // If not, just inject the full result 7106 responseText ); 7107 } 7108 7109 if ( callback ) { 7110 self.each( callback, [ responseText, status, jqXHR ] ); 7111 } 7112 } 7113 }); 7114 7115 return this; 7116 }, 7117 7118 serialize: function() { 7119 return jQuery.param( this.serializeArray() ); 7120 }, 7121 7122 serializeArray: function() { 7123 return this.map(function(){ 7124 return this.elements ? jQuery.makeArray( this.elements ) : this; 7125 }) 7126 .filter(function(){ 7127 return this.name && !this.disabled && 7128 ( this.checked || rselectTextarea.test( this.nodeName ) || 7129 rinput.test( this.type ) ); 7130 }) 7131 .map(function( i, elem ){ 7132 var val = jQuery( this ).val(); 7133 7134 return val == null ? 7135 null : 7136 jQuery.isArray( val ) ? 7137 jQuery.map( val, function( val, i ){ 7138 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7139 }) : 7140 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7141 }).get(); 7142 } 7143}); 7144 7145// Attach a bunch of functions for handling common AJAX events 7146jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ 7147 jQuery.fn[ o ] = function( f ){ 7148 return this.bind( o, f ); 7149 }; 7150}); 7151 7152jQuery.each( [ "get", "post" ], function( i, method ) { 7153 jQuery[ method ] = function( url, data, callback, type ) { 7154 // shift arguments if data argument was omitted 7155 if ( jQuery.isFunction( data ) ) { 7156 type = type || callback; 7157 callback = data; 7158 data = undefined; 7159 } 7160 7161 return jQuery.ajax({ 7162 type: method, 7163 url: url, 7164 data: data, 7165 success: callback, 7166 dataType: type 7167 }); 7168 }; 7169}); 7170 7171jQuery.extend({ 7172 7173 getScript: function( url, callback ) { 7174 return jQuery.get( url, undefined, callback, "script" ); 7175 }, 7176 7177 getJSON: function( url, data, callback ) { 7178 return jQuery.get( url, data, callback, "json" ); 7179 }, 7180 7181 // Creates a full fledged settings object into target 7182 // with both ajaxSettings and settings fields. 7183 // If target is omitted, writes into ajaxSettings. 7184 ajaxSetup: function( target, settings ) { 7185 if ( settings ) { 7186 // Building a settings object 7187 ajaxExtend( target, jQuery.ajaxSettings ); 7188 } else { 7189 // Extending ajaxSettings 7190 settings = target; 7191 target = jQuery.ajaxSettings; 7192 } 7193 ajaxExtend( target, settings ); 7194 return target; 7195 }, 7196 7197 ajaxSettings: { 7198 url: ajaxLocation, 7199 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 7200 global: true, 7201 type: "GET", 7202 contentType: "application/x-www-form-urlencoded", 7203 processData: true, 7204 async: true, 7205 /* 7206 timeout: 0, 7207 data: null, 7208 dataType: null, 7209 username: null, 7210 password: null, 7211 cache: null, 7212 traditional: false, 7213 headers: {}, 7214 */ 7215 7216 accepts: { 7217 xml: "application/xml, text/xml", 7218 html: "text/html", 7219 text: "text/plain", 7220 json: "application/json, text/javascript", 7221 "*": allTypes 7222 }, 7223 7224 contents: { 7225 xml: /xml/, 7226 html: /html/, 7227 json: /json/ 7228 }, 7229 7230 responseFields: { 7231 xml: "responseXML", 7232 text: "responseText" 7233 }, 7234 7235 // List of data converters 7236 // 1) key format is "source_type destination_type" (a single space in-between) 7237 // 2) the catchall symbol "*" can be used for source_type 7238 converters: { 7239 7240 // Convert anything to text 7241 "* text": window.String, 7242 7243 // Text to html (true = no transformation) 7244 "text html": true, 7245 7246 // Evaluate text as a json expression 7247 "text json": jQuery.parseJSON, 7248 7249 // Parse text as xml 7250 "text xml": jQuery.parseXML 7251 }, 7252 7253 // For options that shouldn't be deep extended: 7254 // you can add your own custom options here if 7255 // and when you create one that shouldn't be 7256 // deep extended (see ajaxExtend) 7257 flatOptions: { 7258 context: true, 7259 url: true 7260 } 7261 }, 7262 7263 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 7264 ajaxTransport: addToPrefiltersOrTransports( transports ), 7265 7266 // Main method 7267 ajax: function( url, options ) { 7268 7269 // If url is an object, simulate pre-1.5 signature 7270 if ( typeof url === "object" ) { 7271 options = url; 7272 url = undefined; 7273 } 7274 7275 // Force options to be an object 7276 options = options || {}; 7277 7278 var // Create the final options object 7279 s = jQuery.ajaxSetup( {}, options ), 7280 // Callbacks context 7281 callbackContext = s.context || s, 7282 // Context for global events 7283 // It's the callbackContext if one was provided in the options 7284 // and if it's a DOM node or a jQuery collection 7285 globalEventContext = callbackContext !== s && 7286 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? 7287 jQuery( callbackContext ) : jQuery.event, 7288 // Deferreds 7289 deferred = jQuery.Deferred(), 7290 completeDeferred = jQuery.Callbacks( "once memory" ), 7291 // Status-dependent callbacks 7292 statusCode = s.statusCode || {}, 7293 // ifModified key 7294 ifModifiedKey, 7295 // Headers (they are sent all at once) 7296 requestHeaders = {}, 7297 requestHeadersNames = {}, 7298 // Response headers 7299 responseHeadersString, 7300 responseHeaders, 7301 // transport 7302 transport, 7303 // timeout handle 7304 timeoutTimer, 7305 // Cross-domain detection vars 7306 parts, 7307 // The jqXHR state 7308 state = 0, 7309 // To know if global events are to be dispatched 7310 fireGlobals, 7311 // Loop variable 7312 i, 7313 // Fake xhr 7314 jqXHR = { 7315 7316 readyState: 0, 7317 7318 // Caches the header 7319 setRequestHeader: function( name, value ) { 7320 if ( !state ) { 7321 var lname = name.toLowerCase(); 7322 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 7323 requestHeaders[ name ] = value; 7324 } 7325 return this; 7326 }, 7327 7328 // Raw string 7329 getAllResponseHeaders: function() { 7330 return state === 2 ? responseHeadersString : null; 7331 }, 7332 7333 // Builds headers hashtable if needed 7334 getResponseHeader: function( key ) { 7335 var match; 7336 if ( state === 2 ) { 7337 if ( !responseHeaders ) { 7338 responseHeaders = {}; 7339 while( ( match = rheaders.exec( responseHeadersString ) ) ) { 7340 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; 7341 } 7342 } 7343 match = responseHeaders[ key.toLowerCase() ]; 7344 } 7345 return match === undefined ? null : match; 7346 }, 7347 7348 // Overrides response content-type header 7349 overrideMimeType: function( type ) { 7350 if ( !state ) { 7351 s.mimeType = type; 7352 } 7353 return this; 7354 }, 7355 7356 // Cancel the request 7357 abort: function( statusText ) { 7358 statusText = statusText || "abort"; 7359 if ( transport ) { 7360 transport.abort( statusText ); 7361 } 7362 done( 0, statusText ); 7363 return this; 7364 } 7365 }; 7366 7367 // Callback for when everything is done 7368 // It is defined here because jslint complains if it is declared 7369 // at the end of the function (which would be more logical and readable) 7370 function done( status, nativeStatusText, responses, headers ) { 7371 7372 // Called once 7373 if ( state === 2 ) { 7374 return; 7375 } 7376 7377 // State is "done" now 7378 state = 2; 7379 7380 // Clear timeout if it exists 7381 if ( timeoutTimer ) { 7382 clearTimeout( timeoutTimer ); 7383 } 7384 7385 // Dereference transport for early garbage collection 7386 // (no matter how long the jqXHR object will be used) 7387 transport = undefined; 7388 7389 // Cache response headers 7390 responseHeadersString = headers || ""; 7391 7392 // Set readyState 7393 jqXHR.readyState = status > 0 ? 4 : 0; 7394 7395 var isSuccess, 7396 success, 7397 error, 7398 statusText = nativeStatusText, 7399 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, 7400 lastModified, 7401 etag; 7402 7403 // If successful, handle type chaining 7404 if ( status >= 200 && status < 300 || status === 304 ) { 7405 7406 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7407 if ( s.ifModified ) { 7408 7409 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { 7410 jQuery.lastModified[ ifModifiedKey ] = lastModified; 7411 } 7412 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { 7413 jQuery.etag[ ifModifiedKey ] = etag; 7414 } 7415 } 7416 7417 // If not modified 7418 if ( status === 304 ) { 7419 7420 statusText = "notmodified"; 7421 isSuccess = true; 7422 7423 // If we have data 7424 } else { 7425 7426 try { 7427 success = ajaxConvert( s, response ); 7428 statusText = "success"; 7429 isSuccess = true; 7430 } catch(e) { 7431 // We have a parsererror 7432 statusText = "parsererror"; 7433 error = e; 7434 } 7435 } 7436 } else { 7437 // We extract error from statusText 7438 // then normalize statusText and status for non-aborts 7439 error = statusText; 7440 if ( !statusText || status ) { 7441 statusText = "error"; 7442 if ( status < 0 ) { 7443 status = 0; 7444 } 7445 } 7446 } 7447 7448 // Set data for the fake xhr object 7449 jqXHR.status = status; 7450 jqXHR.statusText = "" + ( nativeStatusText || statusText ); 7451 7452 // Success/Error 7453 if ( isSuccess ) { 7454 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 7455 } else { 7456 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 7457 } 7458 7459 // Status-dependent callbacks 7460 jqXHR.statusCode( statusCode ); 7461 statusCode = undefined; 7462 7463 if ( fireGlobals ) { 7464 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), 7465 [ jqXHR, s, isSuccess ? success : error ] ); 7466 } 7467 7468 // Complete 7469 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 7470 7471 if ( fireGlobals ) { 7472 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 7473 // Handle the global AJAX counter 7474 if ( !( --jQuery.active ) ) { 7475 jQuery.event.trigger( "ajaxStop" ); 7476 } 7477 } 7478 } 7479 7480 // Attach deferreds 7481 deferred.promise( jqXHR ); 7482 jqXHR.success = jqXHR.done; 7483 jqXHR.error = jqXHR.fail; 7484 jqXHR.complete = completeDeferred.add; 7485 7486 // Status-dependent callbacks 7487 jqXHR.statusCode = function( map ) { 7488 if ( map ) { 7489 var tmp; 7490 if ( state < 2 ) { 7491 for ( tmp in map ) { 7492 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; 7493 } 7494 } else { 7495 tmp = map[ jqXHR.status ]; 7496 jqXHR.then( tmp, tmp ); 7497 } 7498 } 7499 return this; 7500 }; 7501 7502 // Remove hash character (#7531: and string promotion) 7503 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 7504 // We also use the url parameter if available 7505 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 7506 7507 // Extract dataTypes list 7508 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); 7509 7510 // Determine if a cross-domain request is in order 7511 if ( s.crossDomain == null ) { 7512 parts = rurl.exec( s.url.toLowerCase() ); 7513 s.crossDomain = !!( parts && 7514 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || 7515 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != 7516 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) 7517 ); 7518 } 7519 7520 // Convert data if not already a string 7521 if ( s.data && s.processData && typeof s.data !== "string" ) { 7522 s.data = jQuery.param( s.data, s.traditional ); 7523 } 7524 7525 // Apply prefilters 7526 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 7527 7528 // If request was aborted inside a prefiler, stop there 7529 if ( state === 2 ) { 7530 return false; 7531 } 7532 7533 // We can fire global events as of now if asked to 7534 fireGlobals = s.global; 7535 7536 // Uppercase the type 7537 s.type = s.type.toUpperCase(); 7538 7539 // Determine if request has content 7540 s.hasContent = !rnoContent.test( s.type ); 7541 7542 // Watch for a new set of requests 7543 if ( fireGlobals && jQuery.active++ === 0 ) { 7544 jQuery.event.trigger( "ajaxStart" ); 7545 } 7546 7547 // More options handling for requests with no content 7548 if ( !s.hasContent ) { 7549 7550 // If data is available, append data to url 7551 if ( s.data ) { 7552 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; 7553 // #9682: remove data so that it's not used in an eventual retry 7554 delete s.data; 7555 } 7556 7557 // Get ifModifiedKey before adding the anti-cache parameter 7558 ifModifiedKey = s.url; 7559 7560 // Add anti-cache in url if needed 7561 if ( s.cache === false ) { 7562 7563 var ts = jQuery.now(), 7564 // try replacing _= if it is there 7565 ret = s.url.replace( rts, "$1_=" + ts ); 7566 7567 // if nothing was replaced, add timestamp to the end 7568 s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); 7569 } 7570 } 7571 7572 // Set the correct header, if data is being sent 7573 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 7574 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 7575 } 7576 7577 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7578 if ( s.ifModified ) { 7579 ifModifiedKey = ifModifiedKey || s.url; 7580 if ( jQuery.lastModified[ ifModifiedKey ] ) { 7581 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); 7582 } 7583 if ( jQuery.etag[ ifModifiedKey ] ) { 7584 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); 7585 } 7586 } 7587 7588 // Set the Accepts header for the server, depending on the dataType 7589 jqXHR.setRequestHeader( 7590 "Accept", 7591 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? 7592 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 7593 s.accepts[ "*" ] 7594 ); 7595 7596 // Check for headers option 7597 for ( i in s.headers ) { 7598 jqXHR.setRequestHeader( i, s.headers[ i ] ); 7599 } 7600 7601 // Allow custom headers/mimetypes and early abort 7602 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 7603 // Abort if not done already 7604 jqXHR.abort(); 7605 return false; 7606 7607 } 7608 7609 // Install callbacks on deferreds 7610 for ( i in { success: 1, error: 1, complete: 1 } ) { 7611 jqXHR[ i ]( s[ i ] ); 7612 } 7613 7614 // Get transport 7615 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 7616 7617 // If no transport, we auto-abort 7618 if ( !transport ) { 7619 done( -1, "No Transport" ); 7620 } else { 7621 jqXHR.readyState = 1; 7622 // Send global event 7623 if ( fireGlobals ) { 7624 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 7625 } 7626 // Timeout 7627 if ( s.async && s.timeout > 0 ) { 7628 timeoutTimer = setTimeout( function(){ 7629 jqXHR.abort( "timeout" ); 7630 }, s.timeout ); 7631 } 7632 7633 try { 7634 state = 1; 7635 transport.send( requestHeaders, done ); 7636 } catch (e) { 7637 // Propagate exception as error if not done 7638 if ( state < 2 ) { 7639 done( -1, e ); 7640 // Simply rethrow otherwise 7641 } else { 7642 jQuery.error( e ); 7643 } 7644 } 7645 } 7646 7647 return jqXHR; 7648 }, 7649 7650 // Serialize an array of form elements or a set of 7651 // key/values into a query string 7652 param: function( a, traditional ) { 7653 var s = [], 7654 add = function( key, value ) { 7655 // If value is a function, invoke it and return its value 7656 value = jQuery.isFunction( value ) ? value() : value; 7657 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 7658 }; 7659 7660 // Set traditional to true for jQuery <= 1.3.2 behavior. 7661 if ( traditional === undefined ) { 7662 traditional = jQuery.ajaxSettings.traditional; 7663 } 7664 7665 // If an array was passed in, assume that it is an array of form elements. 7666 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 7667 // Serialize the form elements 7668 jQuery.each( a, function() { 7669 add( this.name, this.value ); 7670 }); 7671 7672 } else { 7673 // If traditional, encode the "old" way (the way 1.3.2 or older 7674 // did it), otherwise encode params recursively. 7675 for ( var prefix in a ) { 7676 buildParams( prefix, a[ prefix ], traditional, add ); 7677 } 7678 } 7679 7680 // Return the resulting serialization 7681 return s.join( "&" ).replace( r20, "+" ); 7682 } 7683}); 7684 7685function buildParams( prefix, obj, traditional, add ) { 7686 if ( jQuery.isArray( obj ) ) { 7687 // Serialize array item. 7688 jQuery.each( obj, function( i, v ) { 7689 if ( traditional || rbracket.test( prefix ) ) { 7690 // Treat each array item as a scalar. 7691 add( prefix, v ); 7692 7693 } else { 7694 // If array item is non-scalar (array or object), encode its 7695 // numeric index to resolve deserialization ambiguity issues. 7696 // Note that rack (as of 1.0.0) can't currently deserialize 7697 // nested arrays properly, and attempting to do so may cause 7698 // a server error. Possible fixes are to modify rack's 7699 // deserialization algorithm or to provide an option or flag 7700 // to force array serialization to be shallow. 7701 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); 7702 } 7703 }); 7704 7705 } else if ( !traditional && obj != null && typeof obj === "object" ) { 7706 // Serialize object item. 7707 for ( var name in obj ) { 7708 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 7709 } 7710 7711 } else { 7712 // Serialize scalar item. 7713 add( prefix, obj ); 7714 } 7715} 7716 7717// This is still on the jQuery object... for now 7718// Want to move this to jQuery.ajax some day 7719jQuery.extend({ 7720 7721 // Counter for holding the number of active queries 7722 active: 0, 7723 7724 // Last-Modified header cache for next request 7725 lastModified: {}, 7726 etag: {} 7727 7728}); 7729 7730/* Handles responses to an ajax request: 7731 * - sets all responseXXX fields accordingly 7732 * - finds the right dataType (mediates between content-type and expected dataType) 7733 * - returns the corresponding response 7734 */ 7735function ajaxHandleResponses( s, jqXHR, responses ) { 7736 7737 var contents = s.contents, 7738 dataTypes = s.dataTypes, 7739 responseFields = s.responseFields, 7740 ct, 7741 type, 7742 finalDataType, 7743 firstDataType; 7744 7745 // Fill responseXXX fields 7746 for ( type in responseFields ) { 7747 if ( type in responses ) { 7748 jqXHR[ responseFields[type] ] = responses[ type ]; 7749 } 7750 } 7751 7752 // Remove auto dataType and get content-type in the process 7753 while( dataTypes[ 0 ] === "*" ) { 7754 dataTypes.shift(); 7755 if ( ct === undefined ) { 7756 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); 7757 } 7758 } 7759 7760 // Check if we're dealing with a known content-type 7761 if ( ct ) { 7762 for ( type in contents ) { 7763 if ( contents[ type ] && contents[ type ].test( ct ) ) { 7764 dataTypes.unshift( type ); 7765 break; 7766 } 7767 } 7768 } 7769 7770 // Check to see if we have a response for the expected dataType 7771 if ( dataTypes[ 0 ] in responses ) { 7772 finalDataType = dataTypes[ 0 ]; 7773 } else { 7774 // Try convertible dataTypes 7775 for ( type in responses ) { 7776 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { 7777 finalDataType = type; 7778 break; 7779 } 7780 if ( !firstDataType ) { 7781 firstDataType = type; 7782 } 7783 } 7784 // Or just use first one 7785 finalDataType = finalDataType || firstDataType; 7786 } 7787 7788 // If we found a dataType 7789 // We add the dataType to the list if needed 7790 // and return the corresponding response 7791 if ( finalDataType ) { 7792 if ( finalDataType !== dataTypes[ 0 ] ) { 7793 dataTypes.unshift( finalDataType ); 7794 } 7795 return responses[ finalDataType ]; 7796 } 7797} 7798 7799// Chain conversions given the request and the original response 7800function ajaxConvert( s, response ) { 7801 7802 // Apply the dataFilter if provided 7803 if ( s.dataFilter ) { 7804 response = s.dataFilter( response, s.dataType ); 7805 } 7806 7807 var dataTypes = s.dataTypes, 7808 converters = {}, 7809 i, 7810 key, 7811 length = dataTypes.length, 7812 tmp, 7813 // Current and previous dataTypes 7814 current = dataTypes[ 0 ], 7815 prev, 7816 // Conversion expression 7817 conversion, 7818 // Conversion function 7819 conv, 7820 // Conversion functions (transitive conversion) 7821 conv1, 7822 conv2; 7823 7824 // For each dataType in the chain 7825 for ( i = 1; i < length; i++ ) { 7826 7827 // Create converters map 7828 // with lowercased keys 7829 if ( i === 1 ) { 7830 for ( key in s.converters ) { 7831 if ( typeof key === "string" ) { 7832 converters[ key.toLowerCase() ] = s.converters[ key ]; 7833 } 7834 } 7835 } 7836 7837 // Get the dataTypes 7838 prev = current; 7839 current = dataTypes[ i ]; 7840 7841 // If current is auto dataType, update it to prev 7842 if ( current === "*" ) { 7843 current = prev; 7844 // If no auto and dataTypes are actually different 7845 } else if ( prev !== "*" && prev !== current ) { 7846 7847 // Get the converter 7848 conversion = prev + " " + current; 7849 conv = converters[ conversion ] || converters[ "* " + current ]; 7850 7851 // If there is no direct converter, search transitively 7852 if ( !conv ) { 7853 conv2 = undefined; 7854 for ( conv1 in converters ) { 7855 tmp = conv1.split( " " ); 7856 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { 7857 conv2 = converters[ tmp[1] + " " + current ]; 7858 if ( conv2 ) { 7859 conv1 = converters[ conv1 ]; 7860 if ( conv1 === true ) { 7861 conv = conv2; 7862 } else if ( conv2 === true ) { 7863 conv = conv1; 7864 } 7865 break; 7866 } 7867 } 7868 } 7869 } 7870 // If we found no converter, dispatch an error 7871 if ( !( conv || conv2 ) ) { 7872 jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); 7873 } 7874 // If found converter is not an equivalence 7875 if ( conv !== true ) { 7876 // Convert with 1 or 2 converters accordingly 7877 response = conv ? conv( response ) : conv2( conv1(response) ); 7878 } 7879 } 7880 } 7881 return response; 7882} 7883 7884 7885 7886 7887var jsc = jQuery.now(), 7888 jsre = /(\=)\?(&|$)|\?\?/i; 7889 7890// Default jsonp settings 7891jQuery.ajaxSetup({ 7892 jsonp: "callback", 7893 jsonpCallback: function() { 7894 return jQuery.expando + "_" + ( jsc++ ); 7895 } 7896}); 7897 7898// Detect, normalize options and install callbacks for jsonp requests 7899jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 7900 7901 var inspectData = s.contentType === "application/x-www-form-urlencoded" && 7902 ( typeof s.data === "string" ); 7903 7904 if ( s.dataTypes[ 0 ] === "jsonp" || 7905 s.jsonp !== false && ( jsre.test( s.url ) || 7906 inspectData && jsre.test( s.data ) ) ) { 7907 7908 var responseContainer, 7909 jsonpCallback = s.jsonpCallback = 7910 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, 7911 previous = window[ jsonpCallback ], 7912 url = s.url, 7913 data = s.data, 7914 replace = "$1" + jsonpCallback + "$2"; 7915 7916 if ( s.jsonp !== false ) { 7917 url = url.replace( jsre, replace ); 7918 if ( s.url === url ) { 7919 if ( inspectData ) { 7920 data = data.replace( jsre, replace ); 7921 } 7922 if ( s.data === data ) { 7923 // Add callback manually 7924 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; 7925 } 7926 } 7927 } 7928 7929 s.url = url; 7930 s.data = data; 7931 7932 // Install callback 7933 window[ jsonpCallback ] = function( response ) { 7934 responseContainer = [ response ]; 7935 }; 7936 7937 // Clean-up function 7938 jqXHR.always(function() { 7939 // Set callback back to previous value 7940 window[ jsonpCallback ] = previous; 7941 // Call if it was a function and we have a response 7942 if ( responseContainer && jQuery.isFunction( previous ) ) { 7943 window[ jsonpCallback ]( responseContainer[ 0 ] ); 7944 } 7945 }); 7946 7947 // Use data converter to retrieve json after script execution 7948 s.converters["script json"] = function() { 7949 if ( !responseContainer ) { 7950 jQuery.error( jsonpCallback + " was not called" ); 7951 } 7952 return responseContainer[ 0 ]; 7953 }; 7954 7955 // force json dataType 7956 s.dataTypes[ 0 ] = "json"; 7957 7958 // Delegate to script 7959 return "script"; 7960 } 7961}); 7962 7963 7964 7965 7966// Install script dataType 7967jQuery.ajaxSetup({ 7968 accepts: { 7969 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 7970 }, 7971 contents: { 7972 script: /javascript|ecmascript/ 7973 }, 7974 converters: { 7975 "text script": function( text ) { 7976 jQuery.globalEval( text ); 7977 return text; 7978 } 7979 } 7980}); 7981 7982// Handle cache's special case and global 7983jQuery.ajaxPrefilter( "script", function( s ) { 7984 if ( s.cache === undefined ) { 7985 s.cache = false; 7986 } 7987 if ( s.crossDomain ) { 7988 s.type = "GET"; 7989 s.global = false; 7990 } 7991}); 7992 7993// Bind script tag hack transport 7994jQuery.ajaxTransport( "script", function(s) { 7995 7996 // This transport only deals with cross domain requests 7997 if ( s.crossDomain ) { 7998 7999 var script, 8000 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; 8001 8002 return { 8003 8004 send: function( _, callback ) { 8005 8006 script = document.createElement( "script" ); 8007 8008 script.async = "async"; 8009 8010 if ( s.scriptCharset ) { 8011 script.charset = s.scriptCharset; 8012 } 8013 8014 script.src = s.url; 8015 8016 // Attach handlers for all browsers 8017 script.onload = script.onreadystatechange = function( _, isAbort ) { 8018 8019 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { 8020 8021 // Handle memory leak in IE 8022 script.onload = script.onreadystatechange = null; 8023 8024 // Remove the script 8025 if ( head && script.parentNode ) { 8026 head.removeChild( script ); 8027 } 8028 8029 // Dereference the script 8030 script = undefined; 8031 8032 // Callback if not abort 8033 if ( !isAbort ) { 8034 callback( 200, "success" ); 8035 } 8036 } 8037 }; 8038 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 8039 // This arises when a base node is used (#2709 and #4378). 8040 head.insertBefore( script, head.firstChild ); 8041 }, 8042 8043 abort: function() { 8044 if ( script ) { 8045 script.onload( 0, 1 ); 8046 } 8047 } 8048 }; 8049 } 8050}); 8051 8052 8053 8054 8055var // #5280: Internet Explorer will keep connections alive if we don't abort on unload 8056 xhrOnUnloadAbort = window.ActiveXObject ? function() { 8057 // Abort all pending requests 8058 for ( var key in xhrCallbacks ) { 8059 xhrCallbacks[ key ]( 0, 1 ); 8060 } 8061 } : false, 8062 xhrId = 0, 8063 xhrCallbacks; 8064 8065// Functions to create xhrs 8066function createStandardXHR() { 8067 try { 8068 return new window.XMLHttpRequest(); 8069 } catch( e ) {} 8070} 8071 8072function createActiveXHR() { 8073 try { 8074 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); 8075 } catch( e ) {} 8076} 8077 8078// Create the request object 8079// (This is still attached to ajaxSettings for backward compatibility) 8080jQuery.ajaxSettings.xhr = window.ActiveXObject ? 8081 /* Microsoft failed to properly 8082 * implement the XMLHttpRequest in IE7 (can't request local files), 8083 * so we use the ActiveXObject when it is available 8084 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so 8085 * we need a fallback. 8086 */ 8087 function() { 8088 return !this.isLocal && createStandardXHR() || createActiveXHR(); 8089 } : 8090 // For all other browsers, use the standard XMLHttpRequest object 8091 createStandardXHR; 8092 8093// Determine support properties 8094(function( xhr ) { 8095 jQuery.extend( jQuery.support, { 8096 ajax: !!xhr, 8097 cors: !!xhr && ( "withCredentials" in xhr ) 8098 }); 8099})( jQuery.ajaxSettings.xhr() ); 8100 8101// Create transport if the browser can provide an xhr 8102if ( jQuery.support.ajax ) { 8103 8104 jQuery.ajaxTransport(function( s ) { 8105 // Cross domain only allowed if supported through XMLHttpRequest 8106 if ( !s.crossDomain || jQuery.support.cors ) { 8107 8108 var callback; 8109 8110 return { 8111 send: function( headers, complete ) { 8112 8113 // Get a new xhr 8114 var xhr = s.xhr(), 8115 handle, 8116 i; 8117 8118 // Open the socket 8119 // Passing null username, generates a login popup on Opera (#2865) 8120 if ( s.username ) { 8121 xhr.open( s.type, s.url, s.async, s.username, s.password ); 8122 } else { 8123 xhr.open( s.type, s.url, s.async ); 8124 } 8125 8126 // Apply custom fields if provided 8127 if ( s.xhrFields ) { 8128 for ( i in s.xhrFields ) { 8129 xhr[ i ] = s.xhrFields[ i ]; 8130 } 8131 } 8132 8133 // Override mime type if needed 8134 if ( s.mimeType && xhr.overrideMimeType ) { 8135 xhr.overrideMimeType( s.mimeType ); 8136 } 8137 8138 // X-Requested-With header 8139 // For cross-domain requests, seeing as conditions for a preflight are 8140 // akin to a jigsaw puzzle, we simply never set it to be sure. 8141 // (it can always be set on a per-request basis or even using ajaxSetup) 8142 // For same-domain requests, won't change header if already provided. 8143 if ( !s.crossDomain && !headers["X-Requested-With"] ) { 8144 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 8145 } 8146 8147 // Need an extra try/catch for cross domain requests in Firefox 3 8148 try { 8149 for ( i in headers ) { 8150 xhr.setRequestHeader( i, headers[ i ] ); 8151 } 8152 } catch( _ ) {} 8153 8154 // Do send the request 8155 // This may raise an exception which is actually 8156 // handled in jQuery.ajax (so no try/catch here) 8157 xhr.send( ( s.hasContent && s.data ) || null ); 8158 8159 // Listener 8160 callback = function( _, isAbort ) { 8161 8162 var status, 8163 statusText, 8164 responseHeaders, 8165 responses, 8166 xml; 8167 8168 // Firefox throws exceptions when accessing properties 8169 // of an xhr when a network error occured 8170 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) 8171 try { 8172 8173 // Was never called and is aborted or complete 8174 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { 8175 8176 // Only called once 8177 callback = undefined; 8178 8179 // Do not keep as active anymore 8180 if ( handle ) { 8181 xhr.onreadystatechange = jQuery.noop; 8182 if ( xhrOnUnloadAbort ) { 8183 delete xhrCallbacks[ handle ]; 8184 } 8185 } 8186 8187 // If it's an abort 8188 if ( isAbort ) { 8189 // Abort it manually if needed 8190 if ( xhr.readyState !== 4 ) { 8191 xhr.abort(); 8192 } 8193 } else { 8194 status = xhr.status; 8195 responseHeaders = xhr.getAllResponseHeaders(); 8196 responses = {}; 8197 xml = xhr.responseXML; 8198 8199 // Construct response list 8200 if ( xml && xml.documentElement /* #4958 */ ) { 8201 responses.xml = xml; 8202 } 8203 responses.text = xhr.responseText; 8204 8205 // Firefox throws an exception when accessing 8206 // statusText for faulty cross-domain requests 8207 try { 8208 statusText = xhr.statusText; 8209 } catch( e ) { 8210 // We normalize with Webkit giving an empty statusText 8211 statusText = ""; 8212 } 8213 8214 // Filter status for non standard behaviors 8215 8216 // If the request is local and we have data: assume a success 8217 // (success with no data won't get notified, that's the best we 8218 // can do given current implementations) 8219 if ( !status && s.isLocal && !s.crossDomain ) { 8220 status = responses.text ? 200 : 404; 8221 // IE - #1450: sometimes returns 1223 when it should be 204 8222 } else if ( status === 1223 ) { 8223 status = 204; 8224 } 8225 } 8226 } 8227 } catch( firefoxAccessException ) { 8228 if ( !isAbort ) { 8229 complete( -1, firefoxAccessException ); 8230 } 8231 } 8232 8233 // Call complete if needed 8234 if ( responses ) { 8235 complete( status, statusText, responses, responseHeaders ); 8236 } 8237 }; 8238 8239 // if we're in sync mode or it's in cache 8240 // and has been retrieved directly (IE6 & IE7) 8241 // we need to manually fire the callback 8242 if ( !s.async || xhr.readyState === 4 ) { 8243 callback(); 8244 } else { 8245 handle = ++xhrId; 8246 if ( xhrOnUnloadAbort ) { 8247 // Create the active xhrs callbacks list if needed 8248 // and attach the unload handler 8249 if ( !xhrCallbacks ) { 8250 xhrCallbacks = {}; 8251 jQuery( window ).unload( xhrOnUnloadAbort ); 8252 } 8253 // Add to list of active xhrs callbacks 8254 xhrCallbacks[ handle ] = callback; 8255 } 8256 xhr.onreadystatechange = callback; 8257 } 8258 }, 8259 8260 abort: function() { 8261 if ( callback ) { 8262 callback(0,1); 8263 } 8264 } 8265 }; 8266 } 8267 }); 8268} 8269 8270 8271 8272 8273var elemdisplay = {}, 8274 iframe, iframeDoc, 8275 rfxtypes = /^(?:toggle|show|hide)$/, 8276 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, 8277 timerId, 8278 fxAttrs = [ 8279 // height animations 8280 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 8281 // width animations 8282 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 8283 // opacity animations 8284 [ "opacity" ] 8285 ], 8286 fxNow; 8287 8288jQuery.fn.extend({ 8289 show: function( speed, easing, callback ) { 8290 var elem, display; 8291 8292 if ( speed || speed === 0 ) { 8293 return this.animate( genFx("show", 3), speed, easing, callback ); 8294 8295 } else { 8296 for ( var i = 0, j = this.length; i < j; i++ ) { 8297 elem = this[ i ]; 8298 8299 if ( elem.style ) { 8300 display = elem.style.display; 8301 8302 // Reset the inline display of this element to learn if it is 8303 // being hidden by cascaded rules or not 8304 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { 8305 display = elem.style.display = ""; 8306 } 8307 8308 // Set elements which have been overridden with display: none 8309 // in a stylesheet to whatever the default browser style is 8310 // for such an element 8311 if ( display === "" && jQuery.css(elem, "display") === "none" ) { 8312 jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); 8313 } 8314 } 8315 } 8316 8317 // Set the display of most of the elements in a second loop 8318 // to avoid the constant reflow 8319 for ( i = 0; i < j; i++ ) { 8320 elem = this[ i ]; 8321 8322 if ( elem.style ) { 8323 display = elem.style.display; 8324 8325 if ( display === "" || display === "none" ) { 8326 elem.style.display = jQuery._data( elem, "olddisplay" ) || ""; 8327 } 8328 } 8329 } 8330 8331 return this; 8332 } 8333 }, 8334 8335 hide: function( speed, easing, callback ) { 8336 if ( speed || speed === 0 ) { 8337 return this.animate( genFx("hide", 3), speed, easing, callback); 8338 8339 } else { 8340 var elem, display, 8341 i = 0, 8342 j = this.length; 8343 8344 for ( ; i < j; i++ ) { 8345 elem = this[i]; 8346 if ( elem.style ) { 8347 display = jQuery.css( elem, "display" ); 8348 8349 if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) { 8350 jQuery._data( elem, "olddisplay", display ); 8351 } 8352 } 8353 } 8354 8355 // Set the display of the elements in a second loop 8356 // to avoid the constant reflow 8357 for ( i = 0; i < j; i++ ) { 8358 if ( this[i].style ) { 8359 this[i].style.display = "none"; 8360 } 8361 } 8362 8363 return this; 8364 } 8365 }, 8366 8367 // Save the old toggle function 8368 _toggle: jQuery.fn.toggle, 8369 8370 toggle: function( fn, fn2, callback ) { 8371 var bool = typeof fn === "boolean"; 8372 8373 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 8374 this._toggle.apply( this, arguments ); 8375 8376 } else if ( fn == null || bool ) { 8377 this.each(function() { 8378 var state = bool ? fn : jQuery(this).is(":hidden"); 8379 jQuery(this)[ state ? "show" : "hide" ](); 8380 }); 8381 8382 } else { 8383 this.animate(genFx("toggle", 3), fn, fn2, callback); 8384 } 8385 8386 return this; 8387 }, 8388 8389 fadeTo: function( speed, to, easing, callback ) { 8390 return this.filter(":hidden").css("opacity", 0).show().end() 8391 .animate({opacity: to}, speed, easing, callback); 8392 }, 8393 8394 animate: function( prop, speed, easing, callback ) { 8395 var optall = jQuery.speed( speed, easing, callback ); 8396 8397 if ( jQuery.isEmptyObject( prop ) ) { 8398 return this.each( optall.complete, [ false ] ); 8399 } 8400 8401 // Do not change referenced properties as per-property easing will be lost 8402 prop = jQuery.extend( {}, prop ); 8403 8404 function doAnimation() { 8405 // XXX 'this' does not always have a nodeName when running the 8406 // test suite 8407 8408 if ( optall.queue === false ) { 8409 jQuery._mark( this ); 8410 } 8411 8412 var opt = jQuery.extend( {}, optall ), 8413 isElement = this.nodeType === 1, 8414 hidden = isElement && jQuery(this).is(":hidden"), 8415 name, val, p, e, 8416 parts, start, end, unit, 8417 method; 8418 8419 // will store per property easing and be used to determine when an animation is complete 8420 opt.animatedProperties = {}; 8421 8422 for ( p in prop ) { 8423 8424 // property name normalization 8425 name = jQuery.camelCase( p ); 8426 if ( p !== name ) { 8427 prop[ name ] = prop[ p ]; 8428 delete prop[ p ]; 8429 } 8430 8431 val = prop[ name ]; 8432 8433 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) 8434 if ( jQuery.isArray( val ) ) { 8435 opt.animatedProperties[ name ] = val[ 1 ]; 8436 val = prop[ name ] = val[ 0 ]; 8437 } else { 8438 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; 8439 } 8440 8441 if ( val === "hide" && hidden || val === "show" && !hidden ) { 8442 return opt.complete.call( this ); 8443 } 8444 8445 if ( isElement && ( name === "height" || name === "width" ) ) { 8446 // Make sure that nothing sneaks out 8447 // Record all 3 overflow attributes because IE does not 8448 // change the overflow attribute when overflowX and 8449 // overflowY are set to the same value 8450 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; 8451 8452 // Set display property to inline-block for height/width 8453 // animations on inline elements that are having width/height animated 8454 if ( jQuery.css( this, "display" ) === "inline" && 8455 jQuery.css( this, "float" ) === "none" ) { 8456 8457 // inline-level elements accept inline-block; 8458 // block-level elements need to be inline with layout 8459 if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { 8460 this.style.display = "inline-block"; 8461 8462 } else { 8463 this.style.zoom = 1; 8464 } 8465 } 8466 } 8467 } 8468 8469 if ( opt.overflow != null ) { 8470 this.style.overflow = "hidden"; 8471 } 8472 8473 for ( p in prop ) { 8474 e = new jQuery.fx( this, opt, p ); 8475 val = prop[ p ]; 8476 8477 if ( rfxtypes.test( val ) ) { 8478 8479 // Tracks whether to show or hide based on private 8480 // data attached to the element 8481 method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 ); 8482 if ( method ) { 8483 jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" ); 8484 e[ method ](); 8485 } else { 8486 e[ val ](); 8487 } 8488 8489 } else { 8490 parts = rfxnum.exec( val ); 8491 start = e.cur(); 8492 8493 if ( parts ) { 8494 end = parseFloat( parts[2] ); 8495 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); 8496 8497 // We need to compute starting value 8498 if ( unit !== "px" ) { 8499 jQuery.style( this, p, (end || 1) + unit); 8500 start = ( (end || 1) / e.cur() ) * start; 8501 jQuery.style( this, p, start + unit); 8502 } 8503 8504 // If a +=/-= token was provided, we're doing a relative animation 8505 if ( parts[1] ) { 8506 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; 8507 } 8508 8509 e.custom( start, end, unit ); 8510 8511 } else { 8512 e.custom( start, val, "" ); 8513 } 8514 } 8515 } 8516 8517 // For JS strict compliance 8518 return true; 8519 } 8520 8521 return optall.queue === false ? 8522 this.each( doAnimation ) : 8523 this.queue( optall.queue, doAnimation ); 8524 }, 8525 8526 stop: function( type, clearQueue, gotoEnd ) { 8527 if ( typeof type !== "string" ) { 8528 gotoEnd = clearQueue; 8529 clearQueue = type; 8530 type = undefined; 8531 } 8532 if ( clearQueue && type !== false ) { 8533 this.queue( type || "fx", [] ); 8534 } 8535 8536 return this.each(function() { 8537 var i, 8538 hadTimers = false, 8539 timers = jQuery.timers, 8540 data = jQuery._data( this ); 8541 8542 // clear marker counters if we know they won't be 8543 if ( !gotoEnd ) { 8544 jQuery._unmark( true, this ); 8545 } 8546 8547 function stopQueue( elem, data, i ) { 8548 var hooks = data[ i ]; 8549 jQuery.removeData( elem, i, true ); 8550 hooks.stop( gotoEnd ); 8551 } 8552 8553 if ( type == null ) { 8554 for ( i in data ) { 8555 if ( data[ i ].stop && i.indexOf(".run") === i.length - 4 ) { 8556 stopQueue( this, data, i ); 8557 } 8558 } 8559 } else if ( data[ i = type + ".run" ] && data[ i ].stop ){ 8560 stopQueue( this, data, i ); 8561 } 8562 8563 for ( i = timers.length; i--; ) { 8564 if ( timers[ i ].elem === this && (type == null || timers[ i ].queue === type) ) { 8565 if ( gotoEnd ) { 8566 8567 // force the next step to be the last 8568 timers[ i ]( true ); 8569 } else { 8570 timers[ i ].saveState(); 8571 } 8572 hadTimers = true; 8573 timers.splice( i, 1 ); 8574 } 8575 } 8576 8577 // start the next in the queue if the last step wasn't forced 8578 // timers currently will call their complete callbacks, which will dequeue 8579 // but only if they were gotoEnd 8580 if ( !( gotoEnd && hadTimers ) ) { 8581 jQuery.dequeue( this, type ); 8582 } 8583 }); 8584 } 8585 8586}); 8587 8588// Animations created synchronously will run synchronously 8589function createFxNow() { 8590 setTimeout( clearFxNow, 0 ); 8591 return ( fxNow = jQuery.now() ); 8592} 8593 8594function clearFxNow() { 8595 fxNow = undefined; 8596} 8597 8598// Generate parameters to create a standard animation 8599function genFx( type, num ) { 8600 var obj = {}; 8601 8602 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() { 8603 obj[ this ] = type; 8604 }); 8605 8606 return obj; 8607} 8608 8609// Generate shortcuts for custom animations 8610jQuery.each({ 8611 slideDown: genFx( "show", 1 ), 8612 slideUp: genFx( "hide", 1 ), 8613 slideToggle: genFx( "toggle", 1 ), 8614 fadeIn: { opacity: "show" }, 8615 fadeOut: { opacity: "hide" }, 8616 fadeToggle: { opacity: "toggle" } 8617}, function( name, props ) { 8618 jQuery.fn[ name ] = function( speed, easing, callback ) { 8619 return this.animate( props, speed, easing, callback ); 8620 }; 8621}); 8622 8623jQuery.extend({ 8624 speed: function( speed, easing, fn ) { 8625 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 8626 complete: fn || !fn && easing || 8627 jQuery.isFunction( speed ) && speed, 8628 duration: speed, 8629 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 8630 }; 8631 8632 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 8633 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 8634 8635 // normalize opt.queue - true/undefined/null -> "fx" 8636 if ( opt.queue == null || opt.queue === true ) { 8637 opt.queue = "fx"; 8638 } 8639 8640 // Queueing 8641 opt.old = opt.complete; 8642 8643 opt.complete = function( noUnmark ) { 8644 if ( jQuery.isFunction( opt.old ) ) { 8645 opt.old.call( this ); 8646 } 8647 8648 if ( opt.queue ) { 8649 jQuery.dequeue( this, opt.queue ); 8650 } else if ( noUnmark !== false ) { 8651 jQuery._unmark( this ); 8652 } 8653 }; 8654 8655 return opt; 8656 }, 8657 8658 easing: { 8659 linear: function( p, n, firstNum, diff ) { 8660 return firstNum + diff * p; 8661 }, 8662 swing: function( p, n, firstNum, diff ) { 8663 return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum; 8664 } 8665 }, 8666 8667 timers: [], 8668 8669 fx: function( elem, options, prop ) { 8670 this.options = options; 8671 this.elem = elem; 8672 this.prop = prop; 8673 8674 options.orig = options.orig || {}; 8675 } 8676 8677}); 8678 8679jQuery.fx.prototype = { 8680 // Simple function for setting a style value 8681 update: function() { 8682 if ( this.options.step ) { 8683 this.options.step.call( this.elem, this.now, this ); 8684 } 8685 8686 ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this ); 8687 }, 8688 8689 // Get the current size 8690 cur: function() { 8691 if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) { 8692 return this.elem[ this.prop ]; 8693 } 8694 8695 var parsed, 8696 r = jQuery.css( this.elem, this.prop ); 8697 // Empty strings, null, undefined and "auto" are converted to 0, 8698 // complex values such as "rotate(1rad)" are returned as is, 8699 // simple values such as "10px" are parsed to Float. 8700 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; 8701 }, 8702 8703 // Start an animation from one number to another 8704 custom: function( from, to, unit ) { 8705 var self = this, 8706 fx = jQuery.fx; 8707 8708 this.startTime = fxNow || createFxNow(); 8709 this.end = to; 8710 this.now = this.start = from; 8711 this.pos = this.state = 0; 8712 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); 8713 8714 function t( gotoEnd ) { 8715 return self.step( gotoEnd ); 8716 } 8717 8718 t.queue = this.options.queue; 8719 t.elem = this.elem; 8720 t.saveState = function() { 8721 if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) { 8722 jQuery._data( self.elem, "fxshow" + self.prop, self.start ); 8723 } 8724 }; 8725 8726 if ( t() && jQuery.timers.push(t) && !timerId ) { 8727 timerId = setInterval( fx.tick, fx.interval ); 8728 } 8729 }, 8730 8731 // Simple 'show' function 8732 show: function() { 8733 var dataShow = jQuery._data( this.elem, "fxshow" + this.prop ); 8734 8735 // Remember where we started, so that we can go back to it later 8736 this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop ); 8737 this.options.show = true; 8738 8739 // Begin the animation 8740 // Make sure that we start at a small width/height to avoid any flash of content 8741 if ( dataShow !== undefined ) { 8742 // This show is picking up where a previous hide or show left off 8743 this.custom( this.cur(), dataShow ); 8744 } else { 8745 this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() ); 8746 } 8747 8748 // Start by showing the element 8749 jQuery( this.elem ).show(); 8750 }, 8751 8752 // Simple 'hide' function 8753 hide: function() { 8754 // Remember where we started, so that we can go back to it later 8755 this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop ); 8756 this.options.hide = true; 8757 8758 // Begin the animation 8759 this.custom( this.cur(), 0 ); 8760 }, 8761 8762 // Each step of an animation 8763 step: function( gotoEnd ) { 8764 var p, n, complete, 8765 t = fxNow || createFxNow(), 8766 done = true, 8767 elem = this.elem, 8768 options = this.options; 8769 8770 if ( gotoEnd || t >= options.duration + this.startTime ) { 8771 this.now = this.end; 8772 this.pos = this.state = 1; 8773 this.update(); 8774 8775 options.animatedProperties[ this.prop ] = true; 8776 8777 for ( p in options.animatedProperties ) { 8778 if ( options.animatedProperties[ p ] !== true ) { 8779 done = false; 8780 } 8781 } 8782 8783 if ( done ) { 8784 // Reset the overflow 8785 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { 8786 8787 jQuery.each( [ "", "X", "Y" ], function( index, value ) { 8788 elem.style[ "overflow" + value ] = options.overflow[ index ]; 8789 }); 8790 } 8791 8792 // Hide the element if the "hide" operation was done 8793 if ( options.hide ) { 8794 jQuery( elem ).hide(); 8795 } 8796 8797 // Reset the properties, if the item has been hidden or shown 8798 if ( options.hide || options.show ) { 8799 for ( p in options.animatedProperties ) { 8800 jQuery.style( elem, p, options.orig[ p ] ); 8801 jQuery.removeData( elem, "fxshow" + p, true ); 8802 // Toggle data is no longer needed 8803 jQuery.removeData( elem, "toggle" + p, true ); 8804 } 8805 } 8806 8807 // Execute the complete function 8808 // in the event that the complete function throws an exception 8809 // we must ensure it won't be called twice. #5684 8810 8811 complete = options.complete; 8812 if ( complete ) { 8813 8814 options.complete = false; 8815 complete.call( elem ); 8816 } 8817 } 8818 8819 return false; 8820 8821 } else { 8822 // classical easing cannot be used with an Infinity duration 8823 if ( options.duration == Infinity ) { 8824 this.now = t; 8825 } else { 8826 n = t - this.startTime; 8827 this.state = n / options.duration; 8828 8829 // Perform the easing function, defaults to swing 8830 this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration ); 8831 this.now = this.start + ( (this.end - this.start) * this.pos ); 8832 } 8833 // Perform the next step of the animation 8834 this.update(); 8835 } 8836 8837 return true; 8838 } 8839}; 8840 8841jQuery.extend( jQuery.fx, { 8842 tick: function() { 8843 var timer, 8844 timers = jQuery.timers, 8845 i = 0; 8846 8847 for ( ; i < timers.length; i++ ) { 8848 timer = timers[ i ]; 8849 // Checks the timer has not already been removed 8850 if ( !timer() && timers[ i ] === timer ) { 8851 timers.splice( i--, 1 ); 8852 } 8853 } 8854 8855 if ( !timers.length ) { 8856 jQuery.fx.stop(); 8857 } 8858 }, 8859 8860 interval: 13, 8861 8862 stop: function() { 8863 clearInterval( timerId ); 8864 timerId = null; 8865 }, 8866 8867 speeds: { 8868 slow: 600, 8869 fast: 200, 8870 // Default speed 8871 _default: 400 8872 }, 8873 8874 step: { 8875 opacity: function( fx ) { 8876 jQuery.style( fx.elem, "opacity", fx.now ); 8877 }, 8878 8879 _default: function( fx ) { 8880 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 8881 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 8882 } else { 8883 fx.elem[ fx.prop ] = fx.now; 8884 } 8885 } 8886 } 8887}); 8888 8889// Adds width/height step functions 8890// Do not set anything below 0 8891jQuery.each([ "width", "height" ], function( i, prop ) { 8892 jQuery.fx.step[ prop ] = function( fx ) { 8893 jQuery.style( fx.elem, prop, Math.max(0, fx.now) ); 8894 }; 8895}); 8896 8897if ( jQuery.expr && jQuery.expr.filters ) { 8898 jQuery.expr.filters.animated = function( elem ) { 8899 return jQuery.grep(jQuery.timers, function( fn ) { 8900 return elem === fn.elem; 8901 }).length; 8902 }; 8903} 8904 8905// Try to restore the default display value of an element 8906function defaultDisplay( nodeName ) { 8907 8908 if ( !elemdisplay[ nodeName ] ) { 8909 8910 var body = document.body, 8911 elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), 8912 display = elem.css( "display" ); 8913 elem.remove(); 8914 8915 // If the simple way fails, 8916 // get element's real default display by attaching it to a temp iframe 8917 if ( display === "none" || display === "" ) { 8918 // No iframe to use yet, so create it 8919 if ( !iframe ) { 8920 iframe = document.createElement( "iframe" ); 8921 iframe.frameBorder = iframe.width = iframe.height = 0; 8922 } 8923 8924 body.appendChild( iframe ); 8925 8926 // Create a cacheable copy of the iframe document on first call. 8927 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML 8928 // document to it; WebKit & Firefox won't allow reusing the iframe document. 8929 if ( !iframeDoc || !iframe.createElement ) { 8930 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; 8931 iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" ); 8932 iframeDoc.close(); 8933 } 8934 8935 elem = iframeDoc.createElement( nodeName ); 8936 8937 iframeDoc.body.appendChild( elem ); 8938 8939 display = jQuery.css( elem, "display" ); 8940 body.removeChild( iframe ); 8941 } 8942 8943 // Store the correct default display 8944 elemdisplay[ nodeName ] = display; 8945 } 8946 8947 return elemdisplay[ nodeName ]; 8948} 8949 8950 8951 8952 8953var rtable = /^t(?:able|d|h)$/i, 8954 rroot = /^(?:body|html)$/i; 8955 8956if ( "getBoundingClientRect" in document.documentElement ) { 8957 jQuery.fn.offset = function( options ) { 8958 var elem = this[0], box; 8959 8960 if ( options ) { 8961 return this.each(function( i ) { 8962 jQuery.offset.setOffset( this, options, i ); 8963 }); 8964 } 8965 8966 if ( !elem || !elem.ownerDocument ) { 8967 return null; 8968 } 8969 8970 if ( elem === elem.ownerDocument.body ) { 8971 return jQuery.offset.bodyOffset( elem ); 8972 } 8973 8974 try { 8975 box = elem.getBoundingClientRect(); 8976 } catch(e) {} 8977 8978 var doc = elem.ownerDocument, 8979 docElem = doc.documentElement; 8980 8981 // Make sure we're not dealing with a disconnected DOM node 8982 if ( !box || !jQuery.contains( docElem, elem ) ) { 8983 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; 8984 } 8985 8986 var body = doc.body, 8987 win = getWindow(doc), 8988 clientTop = docElem.clientTop || body.clientTop || 0, 8989 clientLeft = docElem.clientLeft || body.clientLeft || 0, 8990 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, 8991 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, 8992 top = box.top + scrollTop - clientTop, 8993 left = box.left + scrollLeft - clientLeft; 8994 8995 return { top: top, left: left }; 8996 }; 8997 8998} else { 8999 jQuery.fn.offset = function( options ) { 9000 var elem = this[0]; 9001 9002 if ( options ) { 9003 return this.each(function( i ) { 9004 jQuery.offset.setOffset( this, options, i ); 9005 }); 9006 } 9007 9008 if ( !elem || !elem.ownerDocument ) { 9009 return null; 9010 } 9011 9012 if ( elem === elem.ownerDocument.body ) { 9013 return jQuery.offset.bodyOffset( elem ); 9014 } 9015 9016 var computedStyle, 9017 offsetParent = elem.offsetParent, 9018 prevOffsetParent = elem, 9019 doc = elem.ownerDocument, 9020 docElem = doc.documentElement, 9021 body = doc.body, 9022 defaultView = doc.defaultView, 9023 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 9024 top = elem.offsetTop, 9025 left = elem.offsetLeft; 9026 9027 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 9028 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { 9029 break; 9030 } 9031 9032 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 9033 top -= elem.scrollTop; 9034 left -= elem.scrollLeft; 9035 9036 if ( elem === offsetParent ) { 9037 top += elem.offsetTop; 9038 left += elem.offsetLeft; 9039 9040 if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { 9041 top += parseFloat( computedStyle.borderTopWidth ) || 0; 9042 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 9043 } 9044 9045 prevOffsetParent = offsetParent; 9046 offsetParent = elem.offsetParent; 9047 } 9048 9049 if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 9050 top += parseFloat( computedStyle.borderTopWidth ) || 0; 9051 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 9052 } 9053 9054 prevComputedStyle = computedStyle; 9055 } 9056 9057 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 9058 top += body.offsetTop; 9059 left += body.offsetLeft; 9060 } 9061 9062 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { 9063 top += Math.max( docElem.scrollTop, body.scrollTop ); 9064 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 9065 } 9066 9067 return { top: top, left: left }; 9068 }; 9069} 9070 9071jQuery.offset = { 9072 9073 bodyOffset: function( body ) { 9074 var top = body.offsetTop, 9075 left = body.offsetLeft; 9076 9077 if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { 9078 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; 9079 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; 9080 } 9081 9082 return { top: top, left: left }; 9083 }, 9084 9085 setOffset: function( elem, options, i ) { 9086 var position = jQuery.css( elem, "position" ); 9087 9088 // set position first, in-case top/left are set even on static elem 9089 if ( position === "static" ) { 9090 elem.style.position = "relative"; 9091 } 9092 9093 var curElem = jQuery( elem ), 9094 curOffset = curElem.offset(), 9095 curCSSTop = jQuery.css( elem, "top" ), 9096 curCSSLeft = jQuery.css( elem, "left" ), 9097 calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, 9098 props = {}, curPosition = {}, curTop, curLeft; 9099 9100 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed 9101 if ( calculatePosition ) { 9102 curPosition = curElem.position(); 9103 curTop = curPosition.top; 9104 curLeft = curPosition.left; 9105 } else { 9106 curTop = parseFloat( curCSSTop ) || 0; 9107 curLeft = parseFloat( curCSSLeft ) || 0; 9108 } 9109 9110 if ( jQuery.isFunction( options ) ) { 9111 options = options.call( elem, i, curOffset ); 9112 } 9113 9114 if ( options.top != null ) { 9115 props.top = ( options.top - curOffset.top ) + curTop; 9116 } 9117 if ( options.left != null ) { 9118 props.left = ( options.left - curOffset.left ) + curLeft; 9119 } 9120 9121 if ( "using" in options ) { 9122 options.using.call( elem, props ); 9123 } else { 9124 curElem.css( props ); 9125 } 9126 } 9127}; 9128 9129 9130jQuery.fn.extend({ 9131 9132 position: function() { 9133 if ( !this[0] ) { 9134 return null; 9135 } 9136 9137 var elem = this[0], 9138 9139 // Get *real* offsetParent 9140 offsetParent = this.offsetParent(), 9141 9142 // Get correct offsets 9143 offset = this.offset(), 9144 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 9145 9146 // Subtract element margins 9147 // note: when an element has margin: auto the offsetLeft and marginLeft 9148 // are the same in Safari causing offset.left to incorrectly be 0 9149 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; 9150 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; 9151 9152 // Add offsetParent borders 9153 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; 9154 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; 9155 9156 // Subtract the two offsets 9157 return { 9158 top: offset.top - parentOffset.top, 9159 left: offset.left - parentOffset.left 9160 }; 9161 }, 9162 9163 offsetParent: function() { 9164 return this.map(function() { 9165 var offsetParent = this.offsetParent || document.body; 9166 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 9167 offsetParent = offsetParent.offsetParent; 9168 } 9169 return offsetParent; 9170 }); 9171 } 9172}); 9173 9174 9175// Create scrollLeft and scrollTop methods 9176jQuery.each( ["Left", "Top"], function( i, name ) { 9177 var method = "scroll" + name; 9178 9179 jQuery.fn[ method ] = function( val ) { 9180 var elem, win; 9181 9182 if ( val === undefined ) { 9183 elem = this[ 0 ]; 9184 9185 if ( !elem ) { 9186 return null; 9187 } 9188 9189 win = getWindow( elem ); 9190 9191 // Return the scroll offset 9192 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : 9193 jQuery.support.boxModel && win.document.documentElement[ method ] || 9194 win.document.body[ method ] : 9195 elem[ method ]; 9196 } 9197 9198 // Set the scroll offset 9199 return this.each(function() { 9200 win = getWindow( this ); 9201 9202 if ( win ) { 9203 win.scrollTo( 9204 !i ? val : jQuery( win ).scrollLeft(), 9205 i ? val : jQuery( win ).scrollTop() 9206 ); 9207 9208 } else { 9209 this[ method ] = val; 9210 } 9211 }); 9212 }; 9213}); 9214 9215function getWindow( elem ) { 9216 return jQuery.isWindow( elem ) ? 9217 elem : 9218 elem.nodeType === 9 ? 9219 elem.defaultView || elem.parentWindow : 9220 false; 9221} 9222 9223 9224 9225 9226// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods 9227jQuery.each([ "Height", "Width" ], function( i, name ) { 9228 9229 var type = name.toLowerCase(); 9230 9231 // innerHeight and innerWidth 9232 jQuery.fn[ "inner" + name ] = function() { 9233 var elem = this[0]; 9234 return elem ? 9235 elem.style ? 9236 parseFloat( jQuery.css( elem, type, "padding" ) ) : 9237 this[ type ]() : 9238 null; 9239 }; 9240 9241 // outerHeight and outerWidth 9242 jQuery.fn[ "outer" + name ] = function( margin ) { 9243 var elem = this[0]; 9244 return elem ? 9245 elem.style ? 9246 parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : 9247 this[ type ]() : 9248 null; 9249 }; 9250 9251 jQuery.fn[ type ] = function( size ) { 9252 // Get window width or height 9253 var elem = this[0]; 9254 if ( !elem ) { 9255 return size == null ? null : this; 9256 } 9257 9258 if ( jQuery.isFunction( size ) ) { 9259 return this.each(function( i ) { 9260 var self = jQuery( this ); 9261 self[ type ]( size.call( this, i, self[ type ]() ) ); 9262 }); 9263 } 9264 9265 if ( jQuery.isWindow( elem ) ) { 9266 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 9267 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat 9268 var docElemProp = elem.document.documentElement[ "client" + name ], 9269 body = elem.document.body; 9270 return elem.document.compatMode === "CSS1Compat" && docElemProp || 9271 body && body[ "client" + name ] || docElemProp; 9272 9273 // Get document width or height 9274 } else if ( elem.nodeType === 9 ) { 9275 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 9276 return Math.max( 9277 elem.documentElement["client" + name], 9278 elem.body["scroll" + name], elem.documentElement["scroll" + name], 9279 elem.body["offset" + name], elem.documentElement["offset" + name] 9280 ); 9281 9282 // Get or set width or height on the element 9283 } else if ( size === undefined ) { 9284 var orig = jQuery.css( elem, type ), 9285 ret = parseFloat( orig ); 9286 9287 return jQuery.isNumeric( ret ) ? ret : orig; 9288 9289 // Set the width or height on the element (default to pixels if value is unitless) 9290 } else { 9291 return this.css( type, typeof size === "string" ? size : size + "px" ); 9292 } 9293 }; 9294 9295}); 9296 9297 9298// Expose jQuery to the global object 9299window.jQuery = window.$ = jQuery; 9300})( window ); 9301