jspec 4.3.2 → 4.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.md CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ 4.3.3 / 2010-07-13
3
+ ==================
4
+
5
+ * Fixed destubing stub overrides
6
+ * Fixed jQuery have_event_handlers to match "live" events
7
+ * Installables updated: MooTools to 1.2.4, Dojo to 1.4.0, jQuery to 1.4.0.
8
+ * Call rhino with "-opt -1" to avoid silent failure
9
+
2
10
  4.3.2 / 2010-05-30
3
11
  ==================
4
12
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{jspec}
5
- s.version = "4.3.2"
5
+ s.version = "4.3.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["TJ Holowaychuk"]
9
- s.date = %q{2010-05-30}
9
+ s.date = %q{2010-07-30}
10
10
  s.default_executable = %q{jspec}
11
11
  s.description = %q{JavaScript BDD Testing Framework}
12
12
  s.email = %q{tj@vision-media.ca}
@@ -17,14 +17,14 @@ Gem::Specification.new do |s|
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jspec", "--main", "README.md"]
18
18
  s.require_paths = ["lib"]
19
19
  s.rubyforge_project = %q{jspec}
20
- s.rubygems_version = %q{1.3.6}
20
+ s.rubygems_version = %q{1.3.7}
21
21
  s.summary = %q{JavaScript BDD Testing Framework}
22
22
 
23
23
  if s.respond_to? :specification_version then
24
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
25
  s.specification_version = 3
26
26
 
27
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
28
  s.add_runtime_dependency(%q<sinatra>, [">= 0"])
29
29
  s.add_runtime_dependency(%q<json_pure>, [">= 0"])
30
30
  s.add_runtime_dependency(%q<commander>, [">= 4.0.1"])
@@ -60,9 +60,18 @@ JSpec
60
60
  },
61
61
 
62
62
  have_event_handlers : function(actual, expected) {
63
- return jQuery(actual).data('events') ?
64
- jQuery(actual).data('events').hasOwnProperty(expected) :
65
- false
63
+ if (jQuery(actual).data('events') && jQuery(actual).data('events').hasOwnProperty(expected)) {
64
+ return true;
65
+ } else if (jQuery(actual.context).data('events') && jQuery(actual.context).data('events').hasOwnProperty(expected)) {
66
+ var events = jQuery(actual.context).data('events')[expected];
67
+
68
+ for (index in events) {
69
+ if (events[index].selector === actual.selector) {
70
+ return true;
71
+ }
72
+ }
73
+ }
74
+ return false;
66
75
  },
67
76
 
68
77
  'be disabled selected checked' : function(attr) {
@@ -4,7 +4,7 @@
4
4
  ;(function(){
5
5
 
6
6
  JSpec = {
7
- version : '4.3.2',
7
+ version : '4.3.3',
8
8
  assert : true,
9
9
  cache : {},
10
10
  suites : [],
@@ -1050,8 +1050,12 @@
1050
1050
  if (object === false) return 'false'
1051
1051
  if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name
1052
1052
  if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector)
1053
- if (object.jquery) return object.get(0).outerHTML
1054
- if (object.nodeName) return object.outerHTML
1053
+ if (object.jquery && object.get(0) && object.get(0).outerHTML) return object.get(0).outerHTML
1054
+ if (object.jquery && object.get(0) && object.get(0).nodeType == 9) return 'jQuery(document)'
1055
+ if (object.jquery && object.get(0)) return document.createElement('div').appendChild(object.get(0)).parentNode.innerHTML
1056
+ if (object.jquery && object.length == 0) return 'jQuery()'
1057
+ if (object.nodeName && object.outerHTML) return object.outerHTML
1058
+ if (object.nodeName) return document.createElement('div').appendChild(object).parentNode.innerHTML
1055
1059
  switch (object.constructor) {
1056
1060
  case Function: return object.name || object
1057
1061
  case String:
@@ -1272,12 +1276,13 @@
1272
1276
  destub : function(object, method) {
1273
1277
  var captures
1274
1278
  if (method) {
1275
- if (object['__prototype__' + method])
1279
+ if (object.hasOwnProperty('__prototype__' + method))
1276
1280
  delete object[method]
1277
- else
1281
+ else if (object.hasOwnProperty('__original__' + method))
1278
1282
  object[method] = object['__original__' + method]
1283
+
1279
1284
  delete object['__prototype__' + method]
1280
- delete object['__original____' + method]
1285
+ delete object['__original__' + method]
1281
1286
  }
1282
1287
  else if (object) {
1283
1288
  for (var key in object)
@@ -1302,9 +1307,13 @@
1302
1307
 
1303
1308
  stub : function(object, method) {
1304
1309
  hook('stubbing', object, method)
1310
+
1311
+ //unbind any stub already present on this method
1312
+ JSpec.destub(object, method);
1305
1313
  JSpec.stubbed.push(object)
1306
1314
  var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
1307
1315
  object[type + method] = object[method]
1316
+
1308
1317
  object[method] = function(){}
1309
1318
  return {
1310
1319
  and_return : function(value) {
@@ -1757,6 +1766,12 @@
1757
1766
  return fs.readFileSync(file).toString('utf8')
1758
1767
  }
1759
1768
  }
1769
+
1770
+ // --- envjsrb / johnson support
1771
+
1772
+ if (typeof Johnson === 'object') {
1773
+ quit = function () {}
1774
+ }
1760
1775
 
1761
1776
  // --- Utility functions
1762
1777
 
@@ -1,73 +1,122 @@
1
1
 
2
- // JSpec - Mock Timers - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
2
+ // Mock Timers - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
3
3
 
4
4
  ;(function(){
5
5
 
6
- /**
7
- * Version.
8
- */
9
-
10
- mockTimersVersion = '1.0.2'
11
-
12
6
  /**
13
7
  * Localized timer stack.
14
8
  */
9
+ var timers = [];
15
10
 
16
- var timers = []
11
+ // nodejs, rhino don't have a window object
12
+ var global = this;
17
13
 
18
- /**
19
- * Set mock timeout with _callback_ and timeout of _ms_.
20
- *
21
- * @param {function} callback
22
- * @param {int} ms
23
- * @return {int}
24
- * @api public
25
- */
14
+ // if they where mocked before this library is loaded - bad luck
15
+ var savedGlobals = {
16
+ setTimeout: global.setTimeout,
17
+ setInterval: global.setInterval,
18
+ clearInterval: global.clearInterval,
19
+ clearTimeout: global.clearTimeout,
20
+
21
+ // those should not be globals, but are mocked none the less, so we save them
22
+ resetTimers: global.resetTimers,
23
+ tick: global.tick
24
+ };
25
+ var hadResetTimers = 'resetTimers' in global;
26
+ var hadTick = 'tick' in global;
26
27
 
27
- setTimeout = function(callback, ms) {
28
- var id
29
- return id = setInterval(function(){
30
- callback()
31
- clearInterval(id)
32
- }, ms)
28
+ function forEachProperty(anObject, aClosure) {
29
+ for (var key in anObject) {
30
+ if ( ! anObject.hasOwnProperty(key))
31
+ continue;
32
+
33
+ aClosure(key, anObject[key]);
34
+ }
33
35
  }
34
36
 
35
- /**
36
- * Set mock interval with _callback_ and interval of _ms_.
37
- *
38
- * @param {function} callback
39
- * @param {int} ms
40
- * @return {int}
41
- * @api public
42
- */
43
-
44
- setInterval = function(callback, ms) {
45
- callback.step = ms, callback.current = callback.last = 0
46
- return timers[timers.length] = callback, timers.length
37
+ global.MockTimers = {
38
+
39
+ mockTimersVersion: '2.0.0',
40
+
41
+ mockGlobalTimerFunctions: function() {
42
+ forEachProperty(this.mocks, function(aName, aFunction) {
43
+ global[aName] = aFunction;
44
+ });
45
+ },
46
+
47
+ unmockGlobalTimerFunctions: function() {
48
+ forEachProperty(this.savedGlobals, function(aName, aFunction) {
49
+ global[aName] = aFunction;
50
+ });
51
+
52
+ if ( ! hadResetTimers)
53
+ delete global['resetTimers'];
54
+ if ( ! hadTick)
55
+ delete global['tick'];
56
+
57
+ }
58
+ };
59
+
60
+ function clearTimer(id) {
61
+ return delete timers[--id];
47
62
  }
48
63
 
49
- /**
50
- * Destroy timer with _id_.
51
- *
52
- * @param {int} id
53
- * @return {bool}
54
- * @api public
55
- */
64
+ var mocks = {
65
+
66
+ /**
67
+ * Set mock timeout with _callback_ and timeout of _ms_.
68
+ *
69
+ * @param {function} callback
70
+ * @param {int} ms
71
+ * @return {int}
72
+ * @api public
73
+ */
74
+ setTimeout: function(callback, ms) {
75
+ var id;
76
+ return id = setInterval(function(){
77
+ callback();
78
+ clearInterval(id);
79
+ }, ms);
80
+ },
56
81
 
57
- clearInterval = clearTimeout = function(id) {
58
- return delete timers[--id]
59
- }
82
+
83
+ /**
84
+ * Set mock interval with _callback_ and interval of _ms_.
85
+ *
86
+ * @param {function} callback
87
+ * @param {int} ms
88
+ * @return {int}
89
+ * @api public
90
+ */
91
+ setInterval: function(callback, ms) {
92
+ // REFACT: use wrapper object so callback is not changed -> state leak
93
+ callback.step = ms;
94
+ callback.current = callback.last = 0;
95
+ timers[timers.length] = callback;
96
+ return timers.length;
97
+ },
98
+
99
+ /**
100
+ * Destroy timer with _id_.
101
+ *
102
+ * @param {int} id
103
+ * @return {bool}
104
+ * @api public
105
+ */
106
+ clearInterval: clearTimer,
107
+ clearTimeout: clearTimer
108
+ };
60
109
 
110
+ // additional functions that are not originally in the global namespace
61
111
  /**
62
112
  * Reset timers.
63
113
  *
64
114
  * @return {array}
65
115
  * @api public
66
116
  */
67
-
68
- resetTimers = function() {
69
- return timers = []
70
- }
117
+ mocks.resetTimers = function() {
118
+ return timers = [];
119
+ };
71
120
 
72
121
  /**
73
122
  * Increment each timers internal clock by _ms_.
@@ -75,16 +124,31 @@
75
124
  * @param {int} ms
76
125
  * @api public
77
126
  */
127
+ mocks.tick = function(ms) {
128
+ for (var i = 0, len = timers.length; i < len; ++i) {
129
+ if ( ! timers[i] || ! (timers[i].current += ms))
130
+ continue;
131
+
132
+ if (timers[i].current - timers[i].last < timers[i].step)
133
+ continue;
134
+
135
+ var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step);
136
+ var remainder = (timers[i].current - timers[i].last) % timers[i].step;
137
+ timers[i].last = timers[i].current - remainder;
138
+ while (times-- && timers[i])
139
+ timers[i]();
140
+ }
141
+ };
78
142
 
79
- tick = function(ms) {
80
- for (var i = 0, len = timers.length; i < len; ++i)
81
- if (timers[i] && (timers[i].current += ms))
82
- if (timers[i].current - timers[i].last >= timers[i].step) {
83
- var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step)
84
- var remainder = (timers[i].current - timers[i].last) % timers[i].step
85
- timers[i].last = timers[i].current - remainder
86
- while (times-- && timers[i]) timers[i]()
87
- }
88
- }
143
+ // make them available publicly
144
+ MockTimers.mocks = mocks;
89
145
 
90
- })()
146
+ JSpec.include({
147
+ beforeSpec: function(){
148
+ MockTimers.mockGlobalTimerFunctions();
149
+ },
150
+ afterSpec : function() {
151
+ MockTimers.unmockGlobalTimerFunctions();
152
+ }
153
+ });
154
+ })();
@@ -1,662 +1,541 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.3.2
2
+ * jQuery JavaScript Library v1.4.2
3
3
  * http://jquery.com/
4
4
  *
5
- * Copyright (c) 2009 John Resig
6
- * Dual licensed under the MIT and GPL licenses.
7
- * http://docs.jquery.com/License
5
+ * Copyright 2010, John Resig
6
+ * Dual licensed under the MIT or GPL Version 2 licenses.
7
+ * http://jquery.org/license
8
8
  *
9
- * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10
- * Revision: 6246
9
+ * Includes Sizzle.js
10
+ * http://sizzlejs.com/
11
+ * Copyright 2010, The Dojo Foundation
12
+ * Released under the MIT, BSD, and GPL Licenses.
13
+ *
14
+ * Date: Sat Feb 13 22:33:48 2010 -0500
11
15
  */
12
- (function(){
16
+ (function( window, undefined ) {
17
+
18
+ // Define a local copy of jQuery
19
+ var jQuery = function( selector, context ) {
20
+ // The jQuery object is actually just the init constructor 'enhanced'
21
+ return new jQuery.fn.init( selector, context );
22
+ },
13
23
 
14
- var
15
- // Will speed up references to window, and allows munging its name.
16
- window = this,
17
- // Will speed up references to undefined, and allows munging its name.
18
- undefined,
19
24
  // Map over jQuery in case of overwrite
20
25
  _jQuery = window.jQuery,
26
+
21
27
  // Map over the $ in case of overwrite
22
28
  _$ = window.$,
23
29
 
24
- jQuery = window.jQuery = window.$ = function( selector, context ) {
25
- // The jQuery object is actually just the init constructor 'enhanced'
26
- return new jQuery.fn.init( selector, context );
27
- },
30
+ // Use the correct document accordingly with window argument (sandbox)
31
+ document = window.document,
32
+
33
+ // A central reference to the root jQuery(document)
34
+ rootjQuery,
28
35
 
29
36
  // A simple way to check for HTML strings or ID strings
30
37
  // (both of which we optimize for)
31
- quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
38
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
39
+
32
40
  // Is it a simple selector
33
- isSimple = /^.[^:#\[\.,]*$/;
41
+ isSimple = /^.[^:#\[\.,]*$/,
42
+
43
+ // Check if a string has a non-whitespace character in it
44
+ rnotwhite = /\S/,
45
+
46
+ // Used for trimming whitespace
47
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
48
+
49
+ // Match a standalone tag
50
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
51
+
52
+ // Keep a UserAgent string for use with jQuery.browser
53
+ userAgent = navigator.userAgent,
54
+
55
+ // For matching the engine and version of the browser
56
+ browserMatch,
57
+
58
+ // Has the ready events already been bound?
59
+ readyBound = false,
60
+
61
+ // The functions to execute on DOM ready
62
+ readyList = [],
63
+
64
+ // The ready event handler
65
+ DOMContentLoaded,
66
+
67
+ // Save a reference to some core methods
68
+ toString = Object.prototype.toString,
69
+ hasOwnProperty = Object.prototype.hasOwnProperty,
70
+ push = Array.prototype.push,
71
+ slice = Array.prototype.slice,
72
+ indexOf = Array.prototype.indexOf;
34
73
 
35
74
  jQuery.fn = jQuery.prototype = {
36
75
  init: function( selector, context ) {
37
- // Make sure that a selection was provided
38
- selector = selector || document;
76
+ var match, elem, ret, doc;
77
+
78
+ // Handle $(""), $(null), or $(undefined)
79
+ if ( !selector ) {
80
+ return this;
81
+ }
39
82
 
40
83
  // Handle $(DOMElement)
41
84
  if ( selector.nodeType ) {
42
- this[0] = selector;
85
+ this.context = this[0] = selector;
43
86
  this.length = 1;
44
- this.context = selector;
45
87
  return this;
46
88
  }
89
+
90
+ // The body element only exists once, optimize finding it
91
+ if ( selector === "body" && !context ) {
92
+ this.context = document;
93
+ this[0] = document.body;
94
+ this.selector = "body";
95
+ this.length = 1;
96
+ return this;
97
+ }
98
+
47
99
  // Handle HTML strings
48
100
  if ( typeof selector === "string" ) {
49
101
  // Are we dealing with HTML string or an ID?
50
- var match = quickExpr.exec( selector );
102
+ match = quickExpr.exec( selector );
51
103
 
52
104
  // Verify a match, and that no context was specified for #id
53
105
  if ( match && (match[1] || !context) ) {
54
106
 
55
107
  // HANDLE: $(html) -> $(array)
56
- if ( match[1] )
57
- selector = jQuery.clean( [ match[1] ], context );
108
+ if ( match[1] ) {
109
+ doc = (context ? context.ownerDocument || context : document);
110
+
111
+ // If a single string is passed in and it's a single tag
112
+ // just do a createElement and skip the rest
113
+ ret = rsingleTag.exec( selector );
114
+
115
+ if ( ret ) {
116
+ if ( jQuery.isPlainObject( context ) ) {
117
+ selector = [ document.createElement( ret[1] ) ];
118
+ jQuery.fn.attr.call( selector, context, true );
119
+
120
+ } else {
121
+ selector = [ doc.createElement( ret[1] ) ];
122
+ }
58
123
 
124
+ } else {
125
+ ret = buildFragment( [ match[1] ], [ doc ] );
126
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
127
+ }
128
+
129
+ return jQuery.merge( this, selector );
130
+
59
131
  // HANDLE: $("#id")
60
- else {
61
- var elem = document.getElementById( match[3] );
62
-
63
- // Handle the case where IE and Opera return items
64
- // by name instead of ID
65
- if ( elem && elem.id != match[3] )
66
- return jQuery().find( selector );
67
-
68
- // Otherwise, we inject the element directly into the jQuery object
69
- var ret = jQuery( elem || [] );
70
- ret.context = document;
71
- ret.selector = selector;
72
- return ret;
132
+ } else {
133
+ elem = document.getElementById( match[2] );
134
+
135
+ if ( elem ) {
136
+ // Handle the case where IE and Opera return items
137
+ // by name instead of ID
138
+ if ( elem.id !== match[2] ) {
139
+ return rootjQuery.find( selector );
140
+ }
141
+
142
+ // Otherwise, we inject the element directly into the jQuery object
143
+ this.length = 1;
144
+ this[0] = elem;
145
+ }
146
+
147
+ this.context = document;
148
+ this.selector = selector;
149
+ return this;
73
150
  }
74
151
 
75
- // HANDLE: $(expr, [context])
76
- // (which is just equivalent to: $(content).find(expr)
77
- } else
152
+ // HANDLE: $("TAG")
153
+ } else if ( !context && /^\w+$/.test( selector ) ) {
154
+ this.selector = selector;
155
+ this.context = document;
156
+ selector = document.getElementsByTagName( selector );
157
+ return jQuery.merge( this, selector );
158
+
159
+ // HANDLE: $(expr, $(...))
160
+ } else if ( !context || context.jquery ) {
161
+ return (context || rootjQuery).find( selector );
162
+
163
+ // HANDLE: $(expr, context)
164
+ // (which is just equivalent to: $(context).find(expr)
165
+ } else {
78
166
  return jQuery( context ).find( selector );
167
+ }
79
168
 
80
169
  // HANDLE: $(function)
81
170
  // Shortcut for document ready
82
- } else if ( jQuery.isFunction( selector ) )
83
- return jQuery( document ).ready( selector );
171
+ } else if ( jQuery.isFunction( selector ) ) {
172
+ return rootjQuery.ready( selector );
173
+ }
84
174
 
85
- // Make sure that old selector state is passed along
86
- if ( selector.selector && selector.context ) {
175
+ if (selector.selector !== undefined) {
87
176
  this.selector = selector.selector;
88
177
  this.context = selector.context;
89
178
  }
90
179
 
91
- return this.setArray(jQuery.isArray( selector ) ?
92
- selector :
93
- jQuery.makeArray(selector));
180
+ return jQuery.makeArray( selector, this );
94
181
  },
95
182
 
96
183
  // Start with an empty selector
97
184
  selector: "",
98
185
 
99
186
  // The current version of jQuery being used
100
- jquery: "1.3.2",
187
+ jquery: "1.4.2",
188
+
189
+ // The default length of a jQuery object is 0
190
+ length: 0,
101
191
 
102
192
  // The number of elements contained in the matched element set
103
193
  size: function() {
104
194
  return this.length;
105
195
  },
106
196
 
197
+ toArray: function() {
198
+ return slice.call( this, 0 );
199
+ },
200
+
107
201
  // Get the Nth element in the matched element set OR
108
202
  // Get the whole matched element set as a clean array
109
203
  get: function( num ) {
110
- return num === undefined ?
204
+ return num == null ?
111
205
 
112
206
  // Return a 'clean' array
113
- Array.prototype.slice.call( this ) :
207
+ this.toArray() :
114
208
 
115
209
  // Return just the object
116
- this[ num ];
210
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
117
211
  },
118
212
 
119
213
  // Take an array of elements and push it onto the stack
120
214
  // (returning the new matched element set)
121
215
  pushStack: function( elems, name, selector ) {
122
216
  // Build a new jQuery matched element set
123
- var ret = jQuery( elems );
217
+ var ret = jQuery();
218
+
219
+ if ( jQuery.isArray( elems ) ) {
220
+ push.apply( ret, elems );
221
+
222
+ } else {
223
+ jQuery.merge( ret, elems );
224
+ }
124
225
 
125
226
  // Add the old object onto the stack (as a reference)
126
227
  ret.prevObject = this;
127
228
 
128
229
  ret.context = this.context;
129
230
 
130
- if ( name === "find" )
231
+ if ( name === "find" ) {
131
232
  ret.selector = this.selector + (this.selector ? " " : "") + selector;
132
- else if ( name )
233
+ } else if ( name ) {
133
234
  ret.selector = this.selector + "." + name + "(" + selector + ")";
235
+ }
134
236
 
135
237
  // Return the newly-formed element set
136
238
  return ret;
137
239
  },
138
240
 
139
- // Force the current matched set of elements to become
140
- // the specified array of elements (destroying the stack in the process)
141
- // You should use pushStack() in order to do this, but maintain the stack
142
- setArray: function( elems ) {
143
- // Resetting the length to 0, then using the native Array push
144
- // is a super-fast way to populate an object with array-like properties
145
- this.length = 0;
146
- Array.prototype.push.apply( this, elems );
147
-
148
- return this;
149
- },
150
-
151
241
  // Execute a callback for every element in the matched set.
152
242
  // (You can seed the arguments with an array of args, but this is
153
243
  // only used internally.)
154
244
  each: function( callback, args ) {
155
245
  return jQuery.each( this, callback, args );
156
246
  },
247
+
248
+ ready: function( fn ) {
249
+ // Attach the listeners
250
+ jQuery.bindReady();
157
251
 
158
- // Determine the position of an element within
159
- // the matched set of elements
160
- index: function( elem ) {
161
- // Locate the position of the desired element
162
- return jQuery.inArray(
163
- // If it receives a jQuery object, the first element is used
164
- elem && elem.jquery ? elem[0] : elem
165
- , this );
166
- },
167
-
168
- attr: function( name, value, type ) {
169
- var options = name;
170
-
171
- // Look for the case where we're accessing a style value
172
- if ( typeof name === "string" )
173
- if ( value === undefined )
174
- return this[0] && jQuery[ type || "attr" ]( this[0], name );
175
-
176
- else {
177
- options = {};
178
- options[ name ] = value;
179
- }
180
-
181
- // Check to see if we're setting style values
182
- return this.each(function(i){
183
- // Set all the styles
184
- for ( name in options )
185
- jQuery.attr(
186
- type ?
187
- this.style :
188
- this,
189
- name, jQuery.prop( this, options[ name ], type, i, name )
190
- );
191
- });
192
- },
193
-
194
- css: function( key, value ) {
195
- // ignore negative width and height values
196
- if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
197
- value = undefined;
198
- return this.attr( key, value, "curCSS" );
199
- },
200
-
201
- text: function( text ) {
202
- if ( typeof text !== "object" && text != null )
203
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
204
-
205
- var ret = "";
206
-
207
- jQuery.each( text || this, function(){
208
- jQuery.each( this.childNodes, function(){
209
- if ( this.nodeType != 8 )
210
- ret += this.nodeType != 1 ?
211
- this.nodeValue :
212
- jQuery.fn.text( [ this ] );
213
- });
214
- });
215
-
216
- return ret;
217
- },
218
-
219
- wrapAll: function( html ) {
220
- if ( this[0] ) {
221
- // The elements to wrap the target around
222
- var wrap = jQuery( html, this[0].ownerDocument ).clone();
223
-
224
- if ( this[0].parentNode )
225
- wrap.insertBefore( this[0] );
226
-
227
- wrap.map(function(){
228
- var elem = this;
229
-
230
- while ( elem.firstChild )
231
- elem = elem.firstChild;
252
+ // If the DOM is already ready
253
+ if ( jQuery.isReady ) {
254
+ // Execute the function immediately
255
+ fn.call( document, jQuery );
232
256
 
233
- return elem;
234
- }).append(this);
257
+ // Otherwise, remember the function for later
258
+ } else if ( readyList ) {
259
+ // Add the function to the wait list
260
+ readyList.push( fn );
235
261
  }
236
262
 
237
263
  return this;
238
264
  },
239
-
240
- wrapInner: function( html ) {
241
- return this.each(function(){
242
- jQuery( this ).contents().wrapAll( html );
243
- });
244
- },
245
-
246
- wrap: function( html ) {
247
- return this.each(function(){
248
- jQuery( this ).wrapAll( html );
249
- });
265
+
266
+ eq: function( i ) {
267
+ return i === -1 ?
268
+ this.slice( i ) :
269
+ this.slice( i, +i + 1 );
250
270
  },
251
271
 
252
- append: function() {
253
- return this.domManip(arguments, true, function(elem){
254
- if (this.nodeType == 1)
255
- this.appendChild( elem );
256
- });
272
+ first: function() {
273
+ return this.eq( 0 );
257
274
  },
258
275
 
259
- prepend: function() {
260
- return this.domManip(arguments, true, function(elem){
261
- if (this.nodeType == 1)
262
- this.insertBefore( elem, this.firstChild );
263
- });
276
+ last: function() {
277
+ return this.eq( -1 );
264
278
  },
265
279
 
266
- before: function() {
267
- return this.domManip(arguments, false, function(elem){
268
- this.parentNode.insertBefore( elem, this );
269
- });
280
+ slice: function() {
281
+ return this.pushStack( slice.apply( this, arguments ),
282
+ "slice", slice.call(arguments).join(",") );
270
283
  },
271
284
 
272
- after: function() {
273
- return this.domManip(arguments, false, function(elem){
274
- this.parentNode.insertBefore( elem, this.nextSibling );
275
- });
285
+ map: function( callback ) {
286
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
287
+ return callback.call( elem, i, elem );
288
+ }));
276
289
  },
277
-
290
+
278
291
  end: function() {
279
- return this.prevObject || jQuery( [] );
292
+ return this.prevObject || jQuery(null);
280
293
  },
281
294
 
282
295
  // For internal use only.
283
296
  // Behaves like an Array's method, not like a jQuery method.
284
- push: [].push,
297
+ push: push,
285
298
  sort: [].sort,
286
- splice: [].splice,
299
+ splice: [].splice
300
+ };
287
301
 
288
- find: function( selector ) {
289
- if ( this.length === 1 ) {
290
- var ret = this.pushStack( [], "find", selector );
291
- ret.length = 0;
292
- jQuery.find( selector, this[0], ret );
293
- return ret;
294
- } else {
295
- return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296
- return jQuery.find( selector, elem );
297
- })), "find", selector );
298
- }
299
- },
302
+ // Give the init function the jQuery prototype for later instantiation
303
+ jQuery.fn.init.prototype = jQuery.fn;
300
304
 
301
- clone: function( events ) {
302
- // Do the clone
303
- var ret = this.map(function(){
304
- if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
305
- // IE copies events bound via attachEvent when
306
- // using cloneNode. Calling detachEvent on the
307
- // clone will also remove the events from the orignal
308
- // In order to get around this, we use innerHTML.
309
- // Unfortunately, this means some modifications to
310
- // attributes in IE that are actually only stored
311
- // as properties will not be copied (such as the
312
- // the name attribute on an input).
313
- var html = this.outerHTML;
314
- if ( !html ) {
315
- var div = this.ownerDocument.createElement("div");
316
- div.appendChild( this.cloneNode(true) );
317
- html = div.innerHTML;
318
- }
305
+ jQuery.extend = jQuery.fn.extend = function() {
306
+ // copy reference to target object
307
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
319
308
 
320
- return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
321
- } else
322
- return this.cloneNode(true);
323
- });
309
+ // Handle a deep copy situation
310
+ if ( typeof target === "boolean" ) {
311
+ deep = target;
312
+ target = arguments[1] || {};
313
+ // skip the boolean and the target
314
+ i = 2;
315
+ }
324
316
 
325
- // Copy the events from the original to the clone
326
- if ( events === true ) {
327
- var orig = this.find("*").andSelf(), i = 0;
317
+ // Handle case when target is a string or something (possible in deep copy)
318
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
319
+ target = {};
320
+ }
328
321
 
329
- ret.find("*").andSelf().each(function(){
330
- if ( this.nodeName !== orig[i].nodeName )
331
- return;
322
+ // extend jQuery itself if only one argument is passed
323
+ if ( length === i ) {
324
+ target = this;
325
+ --i;
326
+ }
332
327
 
333
- var events = jQuery.data( orig[i], "events" );
328
+ for ( ; i < length; i++ ) {
329
+ // Only deal with non-null/undefined values
330
+ if ( (options = arguments[ i ]) != null ) {
331
+ // Extend the base object
332
+ for ( name in options ) {
333
+ src = target[ name ];
334
+ copy = options[ name ];
334
335
 
335
- for ( var type in events ) {
336
- for ( var handler in events[ type ] ) {
337
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
338
- }
336
+ // Prevent never-ending loop
337
+ if ( target === copy ) {
338
+ continue;
339
339
  }
340
340
 
341
- i++;
342
- });
343
- }
341
+ // Recurse if we're merging object literal values or arrays
342
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
343
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
344
+ : jQuery.isArray(copy) ? [] : {};
344
345
 
345
- // Return the cloned set
346
- return ret;
347
- },
346
+ // Never move original objects, clone them
347
+ target[ name ] = jQuery.extend( deep, clone, copy );
348
348
 
349
- filter: function( selector ) {
350
- return this.pushStack(
351
- jQuery.isFunction( selector ) &&
352
- jQuery.grep(this, function(elem, i){
353
- return selector.call( elem, i );
354
- }) ||
355
-
356
- jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357
- return elem.nodeType === 1;
358
- }) ), "filter", selector );
359
- },
360
-
361
- closest: function( selector ) {
362
- var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
363
- closer = 0;
364
-
365
- return this.map(function(){
366
- var cur = this;
367
- while ( cur && cur.ownerDocument ) {
368
- if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369
- jQuery.data(cur, "closest", closer);
370
- return cur;
349
+ // Don't bring in undefined values
350
+ } else if ( copy !== undefined ) {
351
+ target[ name ] = copy;
371
352
  }
372
- cur = cur.parentNode;
373
- closer++;
374
353
  }
375
- });
376
- },
354
+ }
355
+ }
377
356
 
378
- not: function( selector ) {
379
- if ( typeof selector === "string" )
380
- // test special case where just one selector is passed in
381
- if ( isSimple.test( selector ) )
382
- return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
383
- else
384
- selector = jQuery.multiFilter( selector, this );
385
-
386
- var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
387
- return this.filter(function() {
388
- return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
389
- });
390
- },
357
+ // Return the modified object
358
+ return target;
359
+ };
391
360
 
392
- add: function( selector ) {
393
- return this.pushStack( jQuery.unique( jQuery.merge(
394
- this.get(),
395
- typeof selector === "string" ?
396
- jQuery( selector ) :
397
- jQuery.makeArray( selector )
398
- )));
399
- },
361
+ jQuery.extend({
362
+ noConflict: function( deep ) {
363
+ window.$ = _$;
400
364
 
401
- is: function( selector ) {
402
- return !!selector && jQuery.multiFilter( selector, this ).length > 0;
403
- },
365
+ if ( deep ) {
366
+ window.jQuery = _jQuery;
367
+ }
404
368
 
405
- hasClass: function( selector ) {
406
- return !!selector && this.is( "." + selector );
369
+ return jQuery;
407
370
  },
371
+
372
+ // Is the DOM ready to be used? Set to true once it occurs.
373
+ isReady: false,
374
+
375
+ // Handle when the DOM is ready
376
+ ready: function() {
377
+ // Make sure that the DOM is not already loaded
378
+ if ( !jQuery.isReady ) {
379
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
380
+ if ( !document.body ) {
381
+ return setTimeout( jQuery.ready, 13 );
382
+ }
408
383
 
409
- val: function( value ) {
410
- if ( value === undefined ) {
411
- var elem = this[0];
384
+ // Remember that the DOM is ready
385
+ jQuery.isReady = true;
412
386
 
413
- if ( elem ) {
414
- if( jQuery.nodeName( elem, 'option' ) )
415
- return (elem.attributes.value || {}).specified ? elem.value : elem.text;
416
-
417
- // We need to handle select boxes special
418
- if ( jQuery.nodeName( elem, "select" ) ) {
419
- var index = elem.selectedIndex,
420
- values = [],
421
- options = elem.options,
422
- one = elem.type == "select-one";
387
+ // If there are functions bound, to execute
388
+ if ( readyList ) {
389
+ // Execute all of them
390
+ var fn, i = 0;
391
+ while ( (fn = readyList[ i++ ]) ) {
392
+ fn.call( document, jQuery );
393
+ }
423
394
 
424
- // Nothing was selected
425
- if ( index < 0 )
426
- return null;
395
+ // Reset the list of functions
396
+ readyList = null;
397
+ }
427
398
 
428
- // Loop through all the selected options
429
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
430
- var option = options[ i ];
399
+ // Trigger any bound ready events
400
+ if ( jQuery.fn.triggerHandler ) {
401
+ jQuery( document ).triggerHandler( "ready" );
402
+ }
403
+ }
404
+ },
405
+
406
+ bindReady: function() {
407
+ if ( readyBound ) {
408
+ return;
409
+ }
431
410
 
432
- if ( option.selected ) {
433
- // Get the specifc value for the option
434
- value = jQuery(option).val();
411
+ readyBound = true;
435
412
 
436
- // We don't need an array for one selects
437
- if ( one )
438
- return value;
413
+ // Catch cases where $(document).ready() is called after the
414
+ // browser event has already occurred.
415
+ if ( document.readyState === "complete" ) {
416
+ return jQuery.ready();
417
+ }
439
418
 
440
- // Multi-Selects return an array
441
- values.push( value );
442
- }
443
- }
419
+ // Mozilla, Opera and webkit nightlies currently support this event
420
+ if ( document.addEventListener ) {
421
+ // Use the handy event callback
422
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
423
+
424
+ // A fallback to window.onload, that will always work
425
+ window.addEventListener( "load", jQuery.ready, false );
426
+
427
+ // If IE event model is used
428
+ } else if ( document.attachEvent ) {
429
+ // ensure firing before onload,
430
+ // maybe late but safe also for iframes
431
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
432
+
433
+ // A fallback to window.onload, that will always work
434
+ window.attachEvent( "onload", jQuery.ready );
444
435
 
445
- return values;
446
- }
436
+ // If IE and not a frame
437
+ // continually check to see if the document is ready
438
+ var toplevel = false;
447
439
 
448
- // Everything else, we just grab the value
449
- return (elem.value || "").replace(/\r/g, "");
440
+ try {
441
+ toplevel = window.frameElement == null;
442
+ } catch(e) {}
450
443
 
444
+ if ( document.documentElement.doScroll && toplevel ) {
445
+ doScrollCheck();
451
446
  }
452
-
453
- return undefined;
454
447
  }
455
-
456
- if ( typeof value === "number" )
457
- value += '';
458
-
459
- return this.each(function(){
460
- if ( this.nodeType != 1 )
461
- return;
462
-
463
- if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
464
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||
465
- jQuery.inArray(this.name, value) >= 0);
466
-
467
- else if ( jQuery.nodeName( this, "select" ) ) {
468
- var values = jQuery.makeArray(value);
469
-
470
- jQuery( "option", this ).each(function(){
471
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
472
- jQuery.inArray( this.text, values ) >= 0);
473
- });
474
-
475
- if ( !values.length )
476
- this.selectedIndex = -1;
477
-
478
- } else
479
- this.value = value;
480
- });
481
- },
482
-
483
- html: function( value ) {
484
- return value === undefined ?
485
- (this[0] ?
486
- this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
487
- null) :
488
- this.empty().append( value );
489
448
  },
490
449
 
491
- replaceWith: function( value ) {
492
- return this.after( value ).remove();
450
+ // See test/unit/core.js for details concerning isFunction.
451
+ // Since version 1.3, DOM methods and functions like alert
452
+ // aren't supported. They return false on IE (#2968).
453
+ isFunction: function( obj ) {
454
+ return toString.call(obj) === "[object Function]";
493
455
  },
494
456
 
495
- eq: function( i ) {
496
- return this.slice( i, +i + 1 );
457
+ isArray: function( obj ) {
458
+ return toString.call(obj) === "[object Array]";
497
459
  },
498
460
 
499
- slice: function() {
500
- return this.pushStack( Array.prototype.slice.apply( this, arguments ),
501
- "slice", Array.prototype.slice.call(arguments).join(",") );
461
+ isPlainObject: function( obj ) {
462
+ // Must be an Object.
463
+ // Because of IE, we also have to check the presence of the constructor property.
464
+ // Make sure that DOM nodes and window objects don't pass through, as well
465
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
466
+ return false;
467
+ }
468
+
469
+ // Not own constructor property must be Object
470
+ if ( obj.constructor
471
+ && !hasOwnProperty.call(obj, "constructor")
472
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
473
+ return false;
474
+ }
475
+
476
+ // Own properties are enumerated firstly, so to speed up,
477
+ // if last one is own, then all properties are own.
478
+
479
+ var key;
480
+ for ( key in obj ) {}
481
+
482
+ return key === undefined || hasOwnProperty.call( obj, key );
502
483
  },
503
484
 
504
- map: function( callback ) {
505
- return this.pushStack( jQuery.map(this, function(elem, i){
506
- return callback.call( elem, i, elem );
507
- }));
485
+ isEmptyObject: function( obj ) {
486
+ for ( var name in obj ) {
487
+ return false;
488
+ }
489
+ return true;
508
490
  },
509
-
510
- andSelf: function() {
511
- return this.add( this.prevObject );
491
+
492
+ error: function( msg ) {
493
+ throw msg;
512
494
  },
513
-
514
- domManip: function( args, table, callback ) {
515
- if ( this[0] ) {
516
- var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
517
- scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
518
- first = fragment.firstChild;
519
-
520
- if ( first )
521
- for ( var i = 0, l = this.length; i < l; i++ )
522
- callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523
- fragment.cloneNode(true) : fragment );
524
-
525
- if ( scripts )
526
- jQuery.each( scripts, evalScript );
495
+
496
+ parseJSON: function( data ) {
497
+ if ( typeof data !== "string" || !data ) {
498
+ return null;
527
499
  }
528
500
 
529
- return this;
501
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
502
+ data = jQuery.trim( data );
530
503
 
531
- function root( elem, cur ) {
532
- return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533
- (elem.getElementsByTagName("tbody")[0] ||
534
- elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
535
- elem;
536
- }
537
- }
538
- };
539
-
540
- // Give the init function the jQuery prototype for later instantiation
541
- jQuery.fn.init.prototype = jQuery.fn;
542
-
543
- function evalScript( i, elem ) {
544
- if ( elem.src )
545
- jQuery.ajax({
546
- url: elem.src,
547
- async: false,
548
- dataType: "script"
549
- });
550
-
551
- else
552
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
553
-
554
- if ( elem.parentNode )
555
- elem.parentNode.removeChild( elem );
556
- }
557
-
558
- function now(){
559
- return +new Date;
560
- }
561
-
562
- jQuery.extend = jQuery.fn.extend = function() {
563
- // copy reference to target object
564
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
565
-
566
- // Handle a deep copy situation
567
- if ( typeof target === "boolean" ) {
568
- deep = target;
569
- target = arguments[1] || {};
570
- // skip the boolean and the target
571
- i = 2;
572
- }
573
-
574
- // Handle case when target is a string or something (possible in deep copy)
575
- if ( typeof target !== "object" && !jQuery.isFunction(target) )
576
- target = {};
577
-
578
- // extend jQuery itself if only one argument is passed
579
- if ( length == i ) {
580
- target = this;
581
- --i;
582
- }
583
-
584
- for ( ; i < length; i++ )
585
- // Only deal with non-null/undefined values
586
- if ( (options = arguments[ i ]) != null )
587
- // Extend the base object
588
- for ( var name in options ) {
589
- var src = target[ name ], copy = options[ name ];
590
-
591
- // Prevent never-ending loop
592
- if ( target === copy )
593
- continue;
594
-
595
- // Recurse if we're merging object values
596
- if ( deep && copy && typeof copy === "object" && !copy.nodeType )
597
- target[ name ] = jQuery.extend( deep,
598
- // Never move original objects, clone them
599
- src || ( copy.length != null ? [ ] : { } )
600
- , copy );
601
-
602
- // Don't bring in undefined values
603
- else if ( copy !== undefined )
604
- target[ name ] = copy;
605
-
606
- }
607
-
608
- // Return the modified object
609
- return target;
610
- };
611
-
612
- // exclude the following css properties to add px
613
- var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
614
- // cache defaultView
615
- defaultView = document.defaultView || {},
616
- toString = Object.prototype.toString;
617
-
618
- jQuery.extend({
619
- noConflict: function( deep ) {
620
- window.$ = _$;
621
-
622
- if ( deep )
623
- window.jQuery = _jQuery;
624
-
625
- return jQuery;
626
- },
504
+ // Make sure the incoming data is actual JSON
505
+ // Logic borrowed from http://json.org/json2.js
506
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
507
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
508
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
627
509
 
628
- // See test/unit/core.js for details concerning isFunction.
629
- // Since version 1.3, DOM methods and functions like alert
630
- // aren't supported. They return false on IE (#2968).
631
- isFunction: function( obj ) {
632
- return toString.call(obj) === "[object Function]";
633
- },
510
+ // Try to use the native JSON parser first
511
+ return window.JSON && window.JSON.parse ?
512
+ window.JSON.parse( data ) :
513
+ (new Function("return " + data))();
634
514
 
635
- isArray: function( obj ) {
636
- return toString.call(obj) === "[object Array]";
515
+ } else {
516
+ jQuery.error( "Invalid JSON: " + data );
517
+ }
637
518
  },
638
519
 
639
- // check if an element is in a (or is an) XML document
640
- isXMLDoc: function( elem ) {
641
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
642
- !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
643
- },
520
+ noop: function() {},
644
521
 
645
522
  // Evalulates a script in a global context
646
523
  globalEval: function( data ) {
647
- if ( data && /\S/.test(data) ) {
524
+ if ( data && rnotwhite.test(data) ) {
648
525
  // Inspired by code by Andrea Giammarchi
649
526
  // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
650
527
  var head = document.getElementsByTagName("head")[0] || document.documentElement,
651
528
  script = document.createElement("script");
652
529
 
653
530
  script.type = "text/javascript";
654
- if ( jQuery.support.scriptEval )
531
+
532
+ if ( jQuery.support.scriptEval ) {
655
533
  script.appendChild( document.createTextNode( data ) );
656
- else
534
+ } else {
657
535
  script.text = data;
536
+ }
658
537
 
659
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
538
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
660
539
  // This arises when a base node is used (#2709).
661
540
  head.insertBefore( script, head.firstChild );
662
541
  head.removeChild( script );
@@ -664,1049 +543,2424 @@ jQuery.extend({
664
543
  },
665
544
 
666
545
  nodeName: function( elem, name ) {
667
- return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
546
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
668
547
  },
669
548
 
670
549
  // args is for internal usage only
671
550
  each: function( object, callback, args ) {
672
- var name, i = 0, length = object.length;
551
+ var name, i = 0,
552
+ length = object.length,
553
+ isObj = length === undefined || jQuery.isFunction(object);
673
554
 
674
555
  if ( args ) {
675
- if ( length === undefined ) {
676
- for ( name in object )
677
- if ( callback.apply( object[ name ], args ) === false )
556
+ if ( isObj ) {
557
+ for ( name in object ) {
558
+ if ( callback.apply( object[ name ], args ) === false ) {
678
559
  break;
679
- } else
680
- for ( ; i < length; )
681
- if ( callback.apply( object[ i++ ], args ) === false )
560
+ }
561
+ }
562
+ } else {
563
+ for ( ; i < length; ) {
564
+ if ( callback.apply( object[ i++ ], args ) === false ) {
682
565
  break;
566
+ }
567
+ }
568
+ }
683
569
 
684
570
  // A special, fast, case for the most common use of each
685
571
  } else {
686
- if ( length === undefined ) {
687
- for ( name in object )
688
- if ( callback.call( object[ name ], name, object[ name ] ) === false )
572
+ if ( isObj ) {
573
+ for ( name in object ) {
574
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
689
575
  break;
690
- } else
576
+ }
577
+ }
578
+ } else {
691
579
  for ( var value = object[0];
692
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
580
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
581
+ }
693
582
  }
694
583
 
695
584
  return object;
696
585
  },
697
586
 
698
- prop: function( elem, value, type, i, name ) {
699
- // Handle executable functions
700
- if ( jQuery.isFunction( value ) )
701
- value = value.call( elem, i );
702
-
703
- // Handle passing in a number to a CSS property
704
- return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
705
- value + "px" :
706
- value;
587
+ trim: function( text ) {
588
+ return (text || "").replace( rtrim, "" );
707
589
  },
708
590
 
709
- className: {
710
- // internal only, use addClass("class")
711
- add: function( elem, classNames ) {
712
- jQuery.each((classNames || "").split(/\s+/), function(i, className){
713
- if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
714
- elem.className += (elem.className ? " " : "") + className;
715
- });
716
- },
717
-
718
- // internal only, use removeClass("class")
719
- remove: function( elem, classNames ) {
720
- if (elem.nodeType == 1)
721
- elem.className = classNames !== undefined ?
722
- jQuery.grep(elem.className.split(/\s+/), function(className){
723
- return !jQuery.className.has( classNames, className );
724
- }).join(" ") :
725
- "";
726
- },
591
+ // results is for internal usage only
592
+ makeArray: function( array, results ) {
593
+ var ret = results || [];
727
594
 
728
- // internal only, use hasClass("class")
729
- has: function( elem, className ) {
730
- return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
595
+ if ( array != null ) {
596
+ // The window, strings (and functions) also have 'length'
597
+ // The extra typeof function check is to prevent crashes
598
+ // in Safari 2 (See: #3039)
599
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
600
+ push.call( ret, array );
601
+ } else {
602
+ jQuery.merge( ret, array );
603
+ }
731
604
  }
605
+
606
+ return ret;
732
607
  },
733
608
 
734
- // A method for quickly swapping in/out CSS properties to get correct calculations
735
- swap: function( elem, options, callback ) {
736
- var old = {};
737
- // Remember the old values, and insert the new ones
738
- for ( var name in options ) {
739
- old[ name ] = elem.style[ name ];
740
- elem.style[ name ] = options[ name ];
609
+ inArray: function( elem, array ) {
610
+ if ( array.indexOf ) {
611
+ return array.indexOf( elem );
741
612
  }
742
613
 
743
- callback.call( elem );
614
+ for ( var i = 0, length = array.length; i < length; i++ ) {
615
+ if ( array[ i ] === elem ) {
616
+ return i;
617
+ }
618
+ }
744
619
 
745
- // Revert the old values
746
- for ( var name in options )
747
- elem.style[ name ] = old[ name ];
620
+ return -1;
748
621
  },
749
622
 
750
- css: function( elem, name, force, extra ) {
751
- if ( name == "width" || name == "height" ) {
752
- var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
623
+ merge: function( first, second ) {
624
+ var i = first.length, j = 0;
753
625
 
754
- function getWH() {
755
- val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
626
+ if ( typeof second.length === "number" ) {
627
+ for ( var l = second.length; j < l; j++ ) {
628
+ first[ i++ ] = second[ j ];
629
+ }
630
+
631
+ } else {
632
+ while ( second[j] !== undefined ) {
633
+ first[ i++ ] = second[ j++ ];
634
+ }
635
+ }
756
636
 
757
- if ( extra === "border" )
758
- return;
637
+ first.length = i;
759
638
 
760
- jQuery.each( which, function() {
761
- if ( !extra )
762
- val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763
- if ( extra === "margin" )
764
- val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
765
- else
766
- val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
767
- });
768
- }
639
+ return first;
640
+ },
769
641
 
770
- if ( elem.offsetWidth !== 0 )
771
- getWH();
772
- else
773
- jQuery.swap( elem, props, getWH );
642
+ grep: function( elems, callback, inv ) {
643
+ var ret = [];
774
644
 
775
- return Math.max(0, Math.round(val));
645
+ // Go through the array, only saving the items
646
+ // that pass the validator function
647
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
648
+ if ( !inv !== !callback( elems[ i ], i ) ) {
649
+ ret.push( elems[ i ] );
650
+ }
776
651
  }
777
652
 
778
- return jQuery.curCSS( elem, name, force );
653
+ return ret;
779
654
  },
780
655
 
781
- curCSS: function( elem, name, force ) {
782
- var ret, style = elem.style;
656
+ // arg is for internal usage only
657
+ map: function( elems, callback, arg ) {
658
+ var ret = [], value;
783
659
 
784
- // We need to handle opacity special in IE
785
- if ( name == "opacity" && !jQuery.support.opacity ) {
786
- ret = jQuery.attr( style, "opacity" );
660
+ // Go through the array, translating each of the items to their
661
+ // new value (or values).
662
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
663
+ value = callback( elems[ i ], i, arg );
787
664
 
788
- return ret == "" ?
789
- "1" :
790
- ret;
665
+ if ( value != null ) {
666
+ ret[ ret.length ] = value;
667
+ }
791
668
  }
792
669
 
793
- // Make sure we're using the right name for getting the float value
794
- if ( name.match( /float/i ) )
795
- name = styleFloat;
670
+ return ret.concat.apply( [], ret );
671
+ },
796
672
 
797
- if ( !force && style && style[ name ] )
798
- ret = style[ name ];
673
+ // A global GUID counter for objects
674
+ guid: 1,
799
675
 
800
- else if ( defaultView.getComputedStyle ) {
676
+ proxy: function( fn, proxy, thisObject ) {
677
+ if ( arguments.length === 2 ) {
678
+ if ( typeof proxy === "string" ) {
679
+ thisObject = fn;
680
+ fn = thisObject[ proxy ];
681
+ proxy = undefined;
801
682
 
802
- // Only "float" is needed here
803
- if ( name.match( /float/i ) )
804
- name = "float";
683
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
684
+ thisObject = proxy;
685
+ proxy = undefined;
686
+ }
687
+ }
805
688
 
806
- name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
689
+ if ( !proxy && fn ) {
690
+ proxy = function() {
691
+ return fn.apply( thisObject || this, arguments );
692
+ };
693
+ }
807
694
 
808
- var computedStyle = defaultView.getComputedStyle( elem, null );
695
+ // Set the guid of unique handler to the same of original handler, so it can be removed
696
+ if ( fn ) {
697
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
698
+ }
809
699
 
810
- if ( computedStyle )
811
- ret = computedStyle.getPropertyValue( name );
700
+ // So proxy can be declared as an argument
701
+ return proxy;
702
+ },
812
703
 
813
- // We should always get a number back from opacity
814
- if ( name == "opacity" && ret == "" )
815
- ret = "1";
704
+ // Use of jQuery.browser is frowned upon.
705
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
706
+ uaMatch: function( ua ) {
707
+ ua = ua.toLowerCase();
816
708
 
817
- } else if ( elem.currentStyle ) {
818
- var camelCase = name.replace(/\-(\w)/g, function(all, letter){
819
- return letter.toUpperCase();
820
- });
709
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
710
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
711
+ /(msie) ([\w.]+)/.exec( ua ) ||
712
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
713
+ [];
821
714
 
822
- ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
715
+ return { browser: match[1] || "", version: match[2] || "0" };
716
+ },
823
717
 
824
- // From the awesome hack by Dean Edwards
825
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
718
+ browser: {}
719
+ });
826
720
 
827
- // If we're not dealing with a regular pixel number
828
- // but a number that has a weird ending, we need to convert it to pixels
829
- if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
830
- // Remember the original values
831
- var left = style.left, rsLeft = elem.runtimeStyle.left;
832
-
833
- // Put in the new values to get a computed value out
834
- elem.runtimeStyle.left = elem.currentStyle.left;
835
- style.left = ret || 0;
836
- ret = style.pixelLeft + "px";
721
+ browserMatch = jQuery.uaMatch( userAgent );
722
+ if ( browserMatch.browser ) {
723
+ jQuery.browser[ browserMatch.browser ] = true;
724
+ jQuery.browser.version = browserMatch.version;
725
+ }
837
726
 
838
- // Revert the changed values
839
- style.left = left;
840
- elem.runtimeStyle.left = rsLeft;
841
- }
842
- }
727
+ // Deprecated, use jQuery.browser.webkit instead
728
+ if ( jQuery.browser.webkit ) {
729
+ jQuery.browser.safari = true;
730
+ }
843
731
 
844
- return ret;
845
- },
732
+ if ( indexOf ) {
733
+ jQuery.inArray = function( elem, array ) {
734
+ return indexOf.call( array, elem );
735
+ };
736
+ }
846
737
 
847
- clean: function( elems, context, fragment ) {
848
- context = context || document;
738
+ // All jQuery objects should point back to these
739
+ rootjQuery = jQuery(document);
849
740
 
850
- // !context.createElement fails in IE with an error but returns typeof 'object'
851
- if ( typeof context.createElement === "undefined" )
852
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
741
+ // Cleanup functions for the document ready method
742
+ if ( document.addEventListener ) {
743
+ DOMContentLoaded = function() {
744
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
745
+ jQuery.ready();
746
+ };
853
747
 
854
- // If a single string is passed in and it's a single tag
855
- // just do a createElement and skip the rest
856
- if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857
- var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
858
- if ( match )
859
- return [ context.createElement( match[1] ) ];
748
+ } else if ( document.attachEvent ) {
749
+ DOMContentLoaded = function() {
750
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
751
+ if ( document.readyState === "complete" ) {
752
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
753
+ jQuery.ready();
860
754
  }
755
+ };
756
+ }
861
757
 
862
- var ret = [], scripts = [], div = context.createElement("div");
863
-
864
- jQuery.each(elems, function(i, elem){
865
- if ( typeof elem === "number" )
866
- elem += '';
867
-
868
- if ( !elem )
869
- return;
758
+ // The DOM ready check for Internet Explorer
759
+ function doScrollCheck() {
760
+ if ( jQuery.isReady ) {
761
+ return;
762
+ }
870
763
 
871
- // Convert html string into DOM nodes
872
- if ( typeof elem === "string" ) {
873
- // Fix "XHTML"-style tags in all browsers
874
- elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
875
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
876
- all :
877
- front + "></" + tag + ">";
878
- });
764
+ try {
765
+ // If IE is used, use the trick by Diego Perini
766
+ // http://javascript.nwbox.com/IEContentLoaded/
767
+ document.documentElement.doScroll("left");
768
+ } catch( error ) {
769
+ setTimeout( doScrollCheck, 1 );
770
+ return;
771
+ }
879
772
 
880
- // Trim whitespace, otherwise indexOf won't work as expected
881
- var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
773
+ // and execute any waiting functions
774
+ jQuery.ready();
775
+ }
882
776
 
883
- var wrap =
884
- // option or optgroup
885
- !tags.indexOf("<opt") &&
886
- [ 1, "<select multiple='multiple'>", "</select>" ] ||
777
+ function evalScript( i, elem ) {
778
+ if ( elem.src ) {
779
+ jQuery.ajax({
780
+ url: elem.src,
781
+ async: false,
782
+ dataType: "script"
783
+ });
784
+ } else {
785
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
786
+ }
887
787
 
888
- !tags.indexOf("<leg") &&
889
- [ 1, "<fieldset>", "</fieldset>" ] ||
788
+ if ( elem.parentNode ) {
789
+ elem.parentNode.removeChild( elem );
790
+ }
791
+ }
890
792
 
891
- tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
892
- [ 1, "<table>", "</table>" ] ||
793
+ // Mutifunctional method to get and set values to a collection
794
+ // The value/s can be optionally by executed if its a function
795
+ function access( elems, key, value, exec, fn, pass ) {
796
+ var length = elems.length;
797
+
798
+ // Setting many attributes
799
+ if ( typeof key === "object" ) {
800
+ for ( var k in key ) {
801
+ access( elems, k, key[k], exec, fn, value );
802
+ }
803
+ return elems;
804
+ }
805
+
806
+ // Setting one attribute
807
+ if ( value !== undefined ) {
808
+ // Optionally, function values get executed if exec is true
809
+ exec = !pass && exec && jQuery.isFunction(value);
810
+
811
+ for ( var i = 0; i < length; i++ ) {
812
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
813
+ }
814
+
815
+ return elems;
816
+ }
817
+
818
+ // Getting an attribute
819
+ return length ? fn( elems[0], key ) : undefined;
820
+ }
893
821
 
894
- !tags.indexOf("<tr") &&
895
- [ 2, "<table><tbody>", "</tbody></table>" ] ||
822
+ function now() {
823
+ return (new Date).getTime();
824
+ }
825
+ (function() {
896
826
 
897
- // <thead> matched above
898
- (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
899
- [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
827
+ jQuery.support = {};
900
828
 
901
- !tags.indexOf("<col") &&
902
- [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
829
+ var root = document.documentElement,
830
+ script = document.createElement("script"),
831
+ div = document.createElement("div"),
832
+ id = "script" + now();
903
833
 
904
- // IE can't serialize <link> and <script> tags normally
905
- !jQuery.support.htmlSerialize &&
906
- [ 1, "div<div>", "</div>" ] ||
834
+ div.style.display = "none";
835
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
907
836
 
908
- [ 0, "", "" ];
837
+ var all = div.getElementsByTagName("*"),
838
+ a = div.getElementsByTagName("a")[0];
909
839
 
910
- // Go to html and back, then peel off extra wrappers
911
- div.innerHTML = wrap[1] + elem + wrap[2];
840
+ // Can't get basic test support
841
+ if ( !all || !all.length || !a ) {
842
+ return;
843
+ }
912
844
 
913
- // Move to the right depth
914
- while ( wrap[0]-- )
915
- div = div.lastChild;
845
+ jQuery.support = {
846
+ // IE strips leading whitespace when .innerHTML is used
847
+ leadingWhitespace: div.firstChild.nodeType === 3,
916
848
 
917
- // Remove IE's autoinserted <tbody> from table fragments
918
- if ( !jQuery.support.tbody ) {
849
+ // Make sure that tbody elements aren't automatically inserted
850
+ // IE will insert them into empty tables
851
+ tbody: !div.getElementsByTagName("tbody").length,
919
852
 
920
- // String was a <table>, *may* have spurious <tbody>
921
- var hasBody = /<tbody/i.test(elem),
922
- tbody = !tags.indexOf("<table") && !hasBody ?
923
- div.firstChild && div.firstChild.childNodes :
853
+ // Make sure that link elements get serialized correctly by innerHTML
854
+ // This requires a wrapper element in IE
855
+ htmlSerialize: !!div.getElementsByTagName("link").length,
924
856
 
925
- // String was a bare <thead> or <tfoot>
926
- wrap[1] == "<table>" && !hasBody ?
927
- div.childNodes :
928
- [];
857
+ // Get the style information from getAttribute
858
+ // (IE uses .cssText insted)
859
+ style: /red/.test( a.getAttribute("style") ),
929
860
 
930
- for ( var j = tbody.length - 1; j >= 0 ; --j )
931
- if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
932
- tbody[ j ].parentNode.removeChild( tbody[ j ] );
861
+ // Make sure that URLs aren't manipulated
862
+ // (IE normalizes it by default)
863
+ hrefNormalized: a.getAttribute("href") === "/a",
933
864
 
934
- }
865
+ // Make sure that element opacity exists
866
+ // (IE uses filter instead)
867
+ // Use a regex to work around a WebKit issue. See #5145
868
+ opacity: /^0.55$/.test( a.style.opacity ),
935
869
 
936
- // IE completely kills leading whitespace when innerHTML is used
937
- if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938
- div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
939
-
940
- elem = jQuery.makeArray( div.childNodes );
941
- }
870
+ // Verify style float existence
871
+ // (IE uses styleFloat instead of cssFloat)
872
+ cssFloat: !!a.style.cssFloat,
942
873
 
943
- if ( elem.nodeType )
944
- ret.push( elem );
945
- else
946
- ret = jQuery.merge( ret, elem );
874
+ // Make sure that if no value is specified for a checkbox
875
+ // that it defaults to "on".
876
+ // (WebKit defaults to "" instead)
877
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
947
878
 
948
- });
879
+ // Make sure that a selected-by-default option has a working selected property.
880
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
881
+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
949
882
 
950
- if ( fragment ) {
951
- for ( var i = 0; ret[i]; i++ ) {
952
- if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953
- scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
954
- } else {
955
- if ( ret[i].nodeType === 1 )
956
- ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957
- fragment.appendChild( ret[i] );
958
- }
959
- }
960
-
961
- return scripts;
962
- }
883
+ parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
963
884
 
964
- return ret;
965
- },
885
+ // Will be defined later
886
+ deleteExpando: true,
887
+ checkClone: false,
888
+ scriptEval: false,
889
+ noCloneEvent: true,
890
+ boxModel: null
891
+ };
966
892
 
967
- attr: function( elem, name, value ) {
968
- // don't set attributes on text and comment nodes
969
- if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
970
- return undefined;
893
+ script.type = "text/javascript";
894
+ try {
895
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
896
+ } catch(e) {}
971
897
 
972
- var notxml = !jQuery.isXMLDoc( elem ),
973
- // Whether we are setting (or getting)
974
- set = value !== undefined;
898
+ root.insertBefore( script, root.firstChild );
975
899
 
976
- // Try to normalize/fix the name
977
- name = notxml && jQuery.props[ name ] || name;
900
+ // Make sure that the execution of code works by injecting a script
901
+ // tag with appendChild/createTextNode
902
+ // (IE doesn't support this, fails, and uses .text instead)
903
+ if ( window[ id ] ) {
904
+ jQuery.support.scriptEval = true;
905
+ delete window[ id ];
906
+ }
978
907
 
979
- // Only do all the following if this is a node (faster for style)
980
- // IE elem.getAttribute passes even for style
981
- if ( elem.tagName ) {
908
+ // Test to see if it's possible to delete an expando from an element
909
+ // Fails in Internet Explorer
910
+ try {
911
+ delete script.test;
912
+
913
+ } catch(e) {
914
+ jQuery.support.deleteExpando = false;
915
+ }
982
916
 
983
- // These attributes require special treatment
984
- var special = /href|src|style/.test( name );
917
+ root.removeChild( script );
985
918
 
986
- // Safari mis-reports the default selected property of a hidden option
987
- // Accessing the parent's selectedIndex property fixes it
988
- if ( name == "selected" && elem.parentNode )
989
- elem.parentNode.selectedIndex;
919
+ if ( div.attachEvent && div.fireEvent ) {
920
+ div.attachEvent("onclick", function click() {
921
+ // Cloning a node shouldn't copy over any
922
+ // bound event handlers (IE does this)
923
+ jQuery.support.noCloneEvent = false;
924
+ div.detachEvent("onclick", click);
925
+ });
926
+ div.cloneNode(true).fireEvent("onclick");
927
+ }
990
928
 
991
- // If applicable, access the attribute via the DOM 0 way
992
- if ( name in elem && notxml && !special ) {
993
- if ( set ){
994
- // We can't allow the type property to be changed (since it causes problems in IE)
995
- if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
996
- throw "type property can't be changed";
929
+ div = document.createElement("div");
930
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
997
931
 
998
- elem[ name ] = value;
999
- }
932
+ var fragment = document.createDocumentFragment();
933
+ fragment.appendChild( div.firstChild );
1000
934
 
1001
- // browsers index elements by id/name on forms, give priority to attributes.
1002
- if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003
- return elem.getAttributeNode( name ).nodeValue;
935
+ // WebKit doesn't clone checked state correctly in fragments
936
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1004
937
 
1005
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007
- if ( name == "tabIndex" ) {
1008
- var attributeNode = elem.getAttributeNode( "tabIndex" );
1009
- return attributeNode && attributeNode.specified
1010
- ? attributeNode.value
1011
- : elem.nodeName.match(/(button|input|object|select|textarea)/i)
1012
- ? 0
1013
- : elem.nodeName.match(/^(a|area)$/i) && elem.href
1014
- ? 0
1015
- : undefined;
1016
- }
938
+ // Figure out if the W3C box model works as expected
939
+ // document.body must exist before we can do this
940
+ jQuery(function() {
941
+ var div = document.createElement("div");
942
+ div.style.width = div.style.paddingLeft = "1px";
1017
943
 
1018
- return elem[ name ];
1019
- }
944
+ document.body.appendChild( div );
945
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
946
+ document.body.removeChild( div ).style.display = 'none';
1020
947
 
1021
- if ( !jQuery.support.style && notxml && name == "style" )
1022
- return jQuery.attr( elem.style, "cssText", value );
948
+ div = null;
949
+ });
1023
950
 
1024
- if ( set )
1025
- // convert the value to a string (all browsers do this but IE) see #1070
1026
- elem.setAttribute( name, "" + value );
951
+ // Technique from Juriy Zaytsev
952
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
953
+ var eventSupported = function( eventName ) {
954
+ var el = document.createElement("div");
955
+ eventName = "on" + eventName;
1027
956
 
1028
- var attr = !jQuery.support.hrefNormalized && notxml && special
1029
- // Some attributes require a special call on IE
1030
- ? elem.getAttribute( name, 2 )
1031
- : elem.getAttribute( name );
957
+ var isSupported = (eventName in el);
958
+ if ( !isSupported ) {
959
+ el.setAttribute(eventName, "return;");
960
+ isSupported = typeof el[eventName] === "function";
961
+ }
962
+ el = null;
1032
963
 
1033
- // Non-existent attributes return null, we normalize to undefined
1034
- return attr === null ? undefined : attr;
1035
- }
964
+ return isSupported;
965
+ };
966
+
967
+ jQuery.support.submitBubbles = eventSupported("submit");
968
+ jQuery.support.changeBubbles = eventSupported("change");
1036
969
 
1037
- // elem is actually elem.style ... set the style
970
+ // release memory in IE
971
+ root = script = div = all = a = null;
972
+ })();
1038
973
 
1039
- // IE uses filters for opacity
1040
- if ( !jQuery.support.opacity && name == "opacity" ) {
1041
- if ( set ) {
1042
- // IE has trouble with opacity if it does not have layout
1043
- // Force it by setting the zoom level
1044
- elem.zoom = 1;
974
+ jQuery.props = {
975
+ "for": "htmlFor",
976
+ "class": "className",
977
+ readonly: "readOnly",
978
+ maxlength: "maxLength",
979
+ cellspacing: "cellSpacing",
980
+ rowspan: "rowSpan",
981
+ colspan: "colSpan",
982
+ tabindex: "tabIndex",
983
+ usemap: "useMap",
984
+ frameborder: "frameBorder"
985
+ };
986
+ var expando = "jQuery" + now(), uuid = 0, windowData = {};
1045
987
 
1046
- // Set the alpha filter to set the opacity
1047
- elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048
- (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1049
- }
988
+ jQuery.extend({
989
+ cache: {},
990
+
991
+ expando:expando,
992
+
993
+ // The following elements throw uncatchable exceptions if you
994
+ // attempt to add expando properties to them.
995
+ noData: {
996
+ "embed": true,
997
+ "object": true,
998
+ "applet": true
999
+ },
1050
1000
 
1051
- return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052
- (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1053
- "";
1001
+ data: function( elem, name, data ) {
1002
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1003
+ return;
1054
1004
  }
1055
1005
 
1056
- name = name.replace(/-([a-z])/ig, function(all, letter){
1057
- return letter.toUpperCase();
1058
- });
1006
+ elem = elem == window ?
1007
+ windowData :
1008
+ elem;
1059
1009
 
1060
- if ( set )
1061
- elem[ name ] = value;
1010
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
1062
1011
 
1063
- return elem[ name ];
1064
- },
1012
+ if ( !id && typeof name === "string" && data === undefined ) {
1013
+ return null;
1014
+ }
1065
1015
 
1066
- trim: function( text ) {
1067
- return (text || "").replace( /^\s+|\s+$/g, "" );
1068
- },
1016
+ // Compute a unique ID for the element
1017
+ if ( !id ) {
1018
+ id = ++uuid;
1019
+ }
1069
1020
 
1070
- makeArray: function( array ) {
1071
- var ret = [];
1021
+ // Avoid generating a new cache unless none exists and we
1022
+ // want to manipulate it.
1023
+ if ( typeof name === "object" ) {
1024
+ elem[ expando ] = id;
1025
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
1072
1026
 
1073
- if( array != null ){
1074
- var i = array.length;
1075
- // The window, strings (and functions) also have 'length'
1076
- if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1077
- ret[0] = array;
1078
- else
1079
- while( i )
1080
- ret[--i] = array[i];
1027
+ } else if ( !cache[ id ] ) {
1028
+ elem[ expando ] = id;
1029
+ cache[ id ] = {};
1081
1030
  }
1082
1031
 
1083
- return ret;
1084
- },
1032
+ thisCache = cache[ id ];
1085
1033
 
1086
- inArray: function( elem, array ) {
1087
- for ( var i = 0, length = array.length; i < length; i++ )
1088
- // Use === because on IE, window == document
1089
- if ( array[ i ] === elem )
1090
- return i;
1034
+ // Prevent overriding the named cache with undefined values
1035
+ if ( data !== undefined ) {
1036
+ thisCache[ name ] = data;
1037
+ }
1091
1038
 
1092
- return -1;
1039
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
1093
1040
  },
1094
1041
 
1095
- merge: function( first, second ) {
1096
- // We have to loop this way because IE & Opera overwrite the length
1097
- // expando of getElementsByTagName
1098
- var i = 0, elem, pos = first.length;
1099
- // Also, we need to make sure that the correct elements are being returned
1100
- // (IE returns comment nodes in a '*' query)
1101
- if ( !jQuery.support.getAll ) {
1102
- while ( (elem = second[ i++ ]) != null )
1103
- if ( elem.nodeType != 8 )
1104
- first[ pos++ ] = elem;
1105
-
1106
- } else
1107
- while ( (elem = second[ i++ ]) != null )
1108
- first[ pos++ ] = elem;
1109
-
1110
- return first;
1111
- },
1042
+ removeData: function( elem, name ) {
1043
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1044
+ return;
1045
+ }
1112
1046
 
1113
- unique: function( array ) {
1114
- var ret = [], done = {};
1047
+ elem = elem == window ?
1048
+ windowData :
1049
+ elem;
1115
1050
 
1116
- try {
1051
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
1117
1052
 
1118
- for ( var i = 0, length = array.length; i < length; i++ ) {
1119
- var id = jQuery.data( array[ i ] );
1053
+ // If we want to remove a specific section of the element's data
1054
+ if ( name ) {
1055
+ if ( thisCache ) {
1056
+ // Remove the section of cache data
1057
+ delete thisCache[ name ];
1120
1058
 
1121
- if ( !done[ id ] ) {
1122
- done[ id ] = true;
1123
- ret.push( array[ i ] );
1059
+ // If we've removed all the data, remove the element's cache
1060
+ if ( jQuery.isEmptyObject(thisCache) ) {
1061
+ jQuery.removeData( elem );
1124
1062
  }
1125
1063
  }
1126
1064
 
1127
- } catch( e ) {
1128
- ret = array;
1129
- }
1065
+ // Otherwise, we want to remove all of the element's data
1066
+ } else {
1067
+ if ( jQuery.support.deleteExpando ) {
1068
+ delete elem[ jQuery.expando ];
1130
1069
 
1131
- return ret;
1132
- },
1070
+ } else if ( elem.removeAttribute ) {
1071
+ elem.removeAttribute( jQuery.expando );
1072
+ }
1133
1073
 
1134
- grep: function( elems, callback, inv ) {
1135
- var ret = [];
1074
+ // Completely remove the data cache
1075
+ delete cache[ id ];
1076
+ }
1077
+ }
1078
+ });
1136
1079
 
1137
- // Go through the array, only saving the items
1138
- // that pass the validator function
1139
- for ( var i = 0, length = elems.length; i < length; i++ )
1140
- if ( !inv != !callback( elems[ i ], i ) )
1141
- ret.push( elems[ i ] );
1080
+ jQuery.fn.extend({
1081
+ data: function( key, value ) {
1082
+ if ( typeof key === "undefined" && this.length ) {
1083
+ return jQuery.data( this[0] );
1142
1084
 
1143
- return ret;
1144
- },
1085
+ } else if ( typeof key === "object" ) {
1086
+ return this.each(function() {
1087
+ jQuery.data( this, key );
1088
+ });
1089
+ }
1145
1090
 
1146
- map: function( elems, callback ) {
1147
- var ret = [];
1091
+ var parts = key.split(".");
1092
+ parts[1] = parts[1] ? "." + parts[1] : "";
1148
1093
 
1149
- // Go through the array, translating each of the items to their
1150
- // new value (or values).
1151
- for ( var i = 0, length = elems.length; i < length; i++ ) {
1152
- var value = callback( elems[ i ], i );
1094
+ if ( value === undefined ) {
1095
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1153
1096
 
1154
- if ( value != null )
1155
- ret[ ret.length ] = value;
1097
+ if ( data === undefined && this.length ) {
1098
+ data = jQuery.data( this[0], key );
1099
+ }
1100
+ return data === undefined && parts[1] ?
1101
+ this.data( parts[0] ) :
1102
+ data;
1103
+ } else {
1104
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
1105
+ jQuery.data( this, key, value );
1106
+ });
1156
1107
  }
1108
+ },
1157
1109
 
1158
- return ret.concat.apply( [], ret );
1110
+ removeData: function( key ) {
1111
+ return this.each(function() {
1112
+ jQuery.removeData( this, key );
1113
+ });
1159
1114
  }
1160
1115
  });
1116
+ jQuery.extend({
1117
+ queue: function( elem, type, data ) {
1118
+ if ( !elem ) {
1119
+ return;
1120
+ }
1161
1121
 
1162
- // Use of jQuery.browser is deprecated.
1163
- // It's included for backwards compatibility and plugins,
1164
- // although they should work to migrate away.
1122
+ type = (type || "fx") + "queue";
1123
+ var q = jQuery.data( elem, type );
1165
1124
 
1166
- var userAgent = navigator.userAgent.toLowerCase();
1125
+ // Speed up dequeue by getting out quickly if this is just a lookup
1126
+ if ( !data ) {
1127
+ return q || [];
1128
+ }
1167
1129
 
1168
- // Figure out what browser is being used
1169
- jQuery.browser = {
1170
- version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1171
- safari: /webkit/.test( userAgent ),
1172
- opera: /opera/.test( userAgent ),
1173
- msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1174
- mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1175
- };
1130
+ if ( !q || jQuery.isArray(data) ) {
1131
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
1176
1132
 
1177
- jQuery.each({
1178
- parent: function(elem){return elem.parentNode;},
1179
- parents: function(elem){return jQuery.dir(elem,"parentNode");},
1180
- next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1181
- prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1182
- nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1183
- prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1184
- siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1185
- children: function(elem){return jQuery.sibling(elem.firstChild);},
1186
- contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1187
- }, function(name, fn){
1188
- jQuery.fn[ name ] = function( selector ) {
1189
- var ret = jQuery.map( this, fn );
1133
+ } else {
1134
+ q.push( data );
1135
+ }
1190
1136
 
1191
- if ( selector && typeof selector == "string" )
1192
- ret = jQuery.multiFilter( selector, ret );
1137
+ return q;
1138
+ },
1193
1139
 
1194
- return this.pushStack( jQuery.unique( ret ), name, selector );
1195
- };
1196
- });
1140
+ dequeue: function( elem, type ) {
1141
+ type = type || "fx";
1197
1142
 
1198
- jQuery.each({
1199
- appendTo: "append",
1200
- prependTo: "prepend",
1201
- insertBefore: "before",
1202
- insertAfter: "after",
1203
- replaceAll: "replaceWith"
1204
- }, function(name, original){
1205
- jQuery.fn[ name ] = function( selector ) {
1206
- var ret = [], insert = jQuery( selector );
1143
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
1207
1144
 
1208
- for ( var i = 0, l = insert.length; i < l; i++ ) {
1209
- var elems = (i > 0 ? this.clone(true) : this).get();
1210
- jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211
- ret = ret.concat( elems );
1145
+ // If the fx queue is dequeued, always remove the progress sentinel
1146
+ if ( fn === "inprogress" ) {
1147
+ fn = queue.shift();