├── GPL-LICENSE.txt
├── MIT-LICENSE.txt
├── external
├── jquery-1.0.1.js
├── jquery-1.0.2.js
├── jquery-1.0.3.js
├── jquery-1.0.4.js
├── jquery-1.0.js
├── jquery-1.1.1.js
├── jquery-1.1.2.js
├── jquery-1.1.3.js
├── jquery-1.1.4.js
├── jquery-1.1.js
├── jquery-1.2.1.js
├── jquery-1.2.2.js
├── jquery-1.2.3.js
├── jquery-1.2.4.js
├── jquery-1.2.5.js
├── jquery-1.2.6.js
├── jquery-1.2.js
├── jquery-1.3.1.js
├── jquery-1.3.2.js
├── jquery-1.3.js
├── jquery-1.4.1.js
├── jquery-1.4.2.js
├── jquery-1.4.3.js
├── jquery-1.4.4.js
├── jquery-1.4.js
├── jquery-1.5.1.js
├── jquery-1.5.2.js
├── jquery-1.5.js
├── jquery-1.6.1.js
├── jquery-1.6.js
├── json2.js
├── qunit.css
└── qunit.js
├── jquery.jsoncookie.js
├── readme.md
└── test
├── jquery.js
├── test.html
└── unit.js
/GPL-LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
--------------------------------------------------------------------------------
/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2011 appendTo LLC. (http://appendto.com/team)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/external/jquery-1.0.1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery - New Wave Javascript
3 | *
4 | * Copyright (c) 2006 John Resig (jquery.com)
5 | * Dual licensed under the MIT (MIT-LICENSE.txt)
6 | * and GPL (GPL-LICENSE.txt) licenses.
7 | *
8 | * $Date: 2006-10-27 23:14:48 -0400 (Fri, 27 Oct 2006) $
9 | * $Rev: 509 $
10 | */
11 |
12 | // Global undefined variable
13 | window.undefined = window.undefined;
14 | function jQuery(a,c) {
15 |
16 | // Shortcut for document ready (because $(document).each() is silly)
17 | if ( a && a.constructor == Function && jQuery.fn.ready )
18 | return jQuery(document).ready(a);
19 |
20 | // Make sure that a selection was provided
21 | a = a || jQuery.context || document;
22 |
23 | // Watch for when a jQuery object is passed as the selector
24 | if ( a.jquery )
25 | return $( jQuery.merge( a, [] ) );
26 |
27 | // Watch for when a jQuery object is passed at the context
28 | if ( c && c.jquery )
29 | return $( c ).find(a);
30 |
31 | // If the context is global, return a new object
32 | if ( window == this )
33 | return new jQuery(a,c);
34 |
35 | // Handle HTML strings
36 | var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
37 | if ( m ) a = jQuery.clean( [ m[1] ] );
38 |
39 | // Watch for when an array is passed in
40 | this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
41 | // Assume that it is an array of DOM Elements
42 | jQuery.merge( a, [] ) :
43 |
44 | // Find the matching elements and save them for later
45 | jQuery.find( a, c ) );
46 |
47 | // See if an extra function was provided
48 | var fn = arguments[ arguments.length - 1 ];
49 |
50 | // If so, execute it in context
51 | if ( fn && fn.constructor == Function )
52 | this.each(fn);
53 | }
54 |
55 | // Map over the $ in case of overwrite
56 | if ( typeof $ != "undefined" )
57 | jQuery._$ = $;
58 |
59 | // Map the jQuery namespace to the '$' one
60 | var $ = jQuery;
61 |
62 | jQuery.fn = jQuery.prototype = {
63 | jquery: "$Rev: 509 $",
64 |
65 | size: function() {
66 | return this.length;
67 | },
68 |
69 | get: function( num ) {
70 | // Watch for when an array (of elements) is passed in
71 | if ( num && num.constructor == Array ) {
72 |
73 | // Use a tricky hack to make the jQuery object
74 | // look and feel like an array
75 | this.length = 0;
76 | [].push.apply( this, num );
77 |
78 | return this;
79 | } else
80 | return num == undefined ?
81 |
82 | // Return a 'clean' array
83 | jQuery.map( this, function(a){ return a } ) :
84 |
85 | // Return just the object
86 | this[num];
87 | },
88 | each: function( fn, args ) {
89 | return jQuery.each( this, fn, args );
90 | },
91 |
92 | index: function( obj ) {
93 | var pos = -1;
94 | this.each(function(i){
95 | if ( this == obj ) pos = i;
96 | });
97 | return pos;
98 | },
99 |
100 | attr: function( key, value, type ) {
101 | // Check to see if we're setting style values
102 | return key.constructor != String || value != undefined ?
103 | this.each(function(){
104 | // See if we're setting a hash of styles
105 | if ( value == undefined )
106 | // Set all the styles
107 | for ( var prop in key )
108 | jQuery.attr(
109 | type ? this.style : this,
110 | prop, key[prop]
111 | );
112 |
113 | // See if we're setting a single key/value style
114 | else
115 | jQuery.attr(
116 | type ? this.style : this,
117 | key, value
118 | );
119 | }) :
120 |
121 | // Look for the case where we're accessing a style value
122 | jQuery[ type || "attr" ]( this[0], key );
123 | },
124 |
125 | css: function( key, value ) {
126 | return this.attr( key, value, "curCSS" );
127 | },
128 | text: function(e) {
129 | e = e || this;
130 | var t = "";
131 | for ( var j = 0; j < e.length; j++ ) {
132 | var r = e[j].childNodes;
133 | for ( var i = 0; i < r.length; i++ )
134 | if ( r[i].nodeType != 8 )
135 | t += r[i].nodeType != 1 ?
136 | r[i].nodeValue : jQuery.fn.text([ r[i] ]);
137 | }
138 | return t;
139 | },
140 | wrap: function() {
141 | // The elements to wrap the target around
142 | var a = jQuery.clean(arguments);
143 |
144 | // Wrap each of the matched elements individually
145 | return this.each(function(){
146 | // Clone the structure that we're using to wrap
147 | var b = a[0].cloneNode(true);
148 |
149 | // Insert it before the element to be wrapped
150 | this.parentNode.insertBefore( b, this );
151 |
152 | // Find he deepest point in the wrap structure
153 | while ( b.firstChild )
154 | b = b.firstChild;
155 |
156 | // Move the matched element to within the wrap structure
157 | b.appendChild( this );
158 | });
159 | },
160 | append: function() {
161 | return this.domManip(arguments, true, 1, function(a){
162 | this.appendChild( a );
163 | });
164 | },
165 | prepend: function() {
166 | return this.domManip(arguments, true, -1, function(a){
167 | this.insertBefore( a, this.firstChild );
168 | });
169 | },
170 | before: function() {
171 | return this.domManip(arguments, false, 1, function(a){
172 | this.parentNode.insertBefore( a, this );
173 | });
174 | },
175 | after: function() {
176 | return this.domManip(arguments, false, -1, function(a){
177 | this.parentNode.insertBefore( a, this.nextSibling );
178 | });
179 | },
180 | end: function() {
181 | return this.get( this.stack.pop() );
182 | },
183 | find: function(t) {
184 | return this.pushStack( jQuery.map( this, function(a){
185 | return jQuery.find(t,a);
186 | }), arguments );
187 | },
188 |
189 | clone: function(deep) {
190 | return this.pushStack( jQuery.map( this, function(a){
191 | return a.cloneNode( deep != undefined ? deep : true );
192 | }), arguments );
193 | },
194 |
195 | filter: function(t) {
196 | return this.pushStack(
197 | t.constructor == Array &&
198 | jQuery.map(this,function(a){
199 | for ( var i = 0; i < t.length; i++ )
200 | if ( jQuery.filter(t[i],[a]).r.length )
201 | return a;
202 | }) ||
203 |
204 | t.constructor == Boolean &&
205 | ( t ? this.get() : [] ) ||
206 |
207 | t.constructor == Function &&
208 | jQuery.grep( this, t ) ||
209 |
210 | jQuery.filter(t,this).r, arguments );
211 | },
212 |
213 | not: function(t) {
214 | return this.pushStack( t.constructor == String ?
215 | jQuery.filter(t,this,false).r :
216 | jQuery.grep(this,function(a){ return a != t; }), arguments );
217 | },
218 |
219 | add: function(t) {
220 | return this.pushStack( jQuery.merge( this, t.constructor == String ?
221 | jQuery.find(t) : t.constructor == Array ? t : [t] ), arguments );
222 | },
223 | is: function(expr) {
224 | return expr ? jQuery.filter(expr,this).r.length > 0 : this.length > 0;
225 | },
226 | domManip: function(args, table, dir, fn){
227 | var clone = this.size() > 1;
228 | var a = jQuery.clean(args);
229 |
230 | return this.each(function(){
231 | var obj = this;
232 |
233 | if ( table && this.nodeName == "TABLE" && a[0].nodeName != "THEAD" ) {
234 | var tbody = this.getElementsByTagName("tbody");
235 |
236 | if ( !tbody.length ) {
237 | obj = document.createElement("tbody");
238 | this.appendChild( obj );
239 | } else
240 | obj = tbody[0];
241 | }
242 |
243 | for ( var i = ( dir < 0 ? a.length - 1 : 0 );
244 | i != ( dir < 0 ? dir : a.length ); i += dir ) {
245 | fn.apply( obj, [ clone ? a[i].cloneNode(true) : a[i] ] );
246 | }
247 | });
248 | },
249 | pushStack: function(a,args) {
250 | var fn = args && args[args.length-1];
251 |
252 | if ( !fn || fn.constructor != Function ) {
253 | if ( !this.stack ) this.stack = [];
254 | this.stack.push( this.get() );
255 | this.get( a );
256 | } else {
257 | var old = this.get();
258 | this.get( a );
259 | if ( fn.constructor == Function )
260 | return this.each( fn );
261 | this.get( old );
262 | }
263 |
264 | return this;
265 | }
266 | };
267 |
268 | jQuery.extend = jQuery.fn.extend = function(obj,prop) {
269 | if ( !prop ) { prop = obj; obj = this; }
270 | for ( var i in prop ) obj[i] = prop[i];
271 | return obj;
272 | };
273 |
274 | jQuery.extend({
275 | init: function(){
276 | jQuery.initDone = true;
277 |
278 | jQuery.each( jQuery.macros.axis, function(i,n){
279 | jQuery.fn[ i ] = function(a) {
280 | var ret = jQuery.map(this,n);
281 | if ( a && a.constructor == String )
282 | ret = jQuery.filter(a,ret).r;
283 | return this.pushStack( ret, arguments );
284 | };
285 | });
286 |
287 | jQuery.each( jQuery.macros.to, function(i,n){
288 | jQuery.fn[ i ] = function(){
289 | var a = arguments;
290 | return this.each(function(){
291 | for ( var j = 0; j < a.length; j++ )
292 | $(a[j])[n]( this );
293 | });
294 | };
295 | });
296 |
297 | jQuery.each( jQuery.macros.each, function(i,n){
298 | jQuery.fn[ i ] = function() {
299 | return this.each( n, arguments );
300 | };
301 | });
302 |
303 | jQuery.each( jQuery.macros.filter, function(i,n){
304 | jQuery.fn[ n ] = function(num,fn) {
305 | return this.filter( ":" + n + "(" + num + ")", fn );
306 | };
307 | });
308 |
309 | jQuery.each( jQuery.macros.attr, function(i,n){
310 | n = n || i;
311 | jQuery.fn[ i ] = function(h) {
312 | return h == undefined ?
313 | this.length ? this[0][n] : null :
314 | this.attr( n, h );
315 | };
316 | });
317 |
318 | jQuery.each( jQuery.macros.css, function(i,n){
319 | jQuery.fn[ n ] = function(h) {
320 | return h == undefined ?
321 | ( this.length ? jQuery.css( this[0], n ) : null ) :
322 | this.css( n, h );
323 | };
324 | });
325 |
326 | },
327 | each: function( obj, fn, args ) {
328 | if ( obj.length == undefined )
329 | for ( var i in obj )
330 | fn.apply( obj[i], args || [i, obj[i]] );
331 | else
332 | for ( var i = 0; i < obj.length; i++ )
333 | fn.apply( obj[i], args || [i, obj[i]] );
334 | return obj;
335 | },
336 |
337 | className: {
338 | add: function(o,c){
339 | if (jQuery.className.has(o,c)) return;
340 | o.className += ( o.className ? " " : "" ) + c;
341 | },
342 | remove: function(o,c){
343 | o.className = !c ? "" :
344 | o.className.replace(
345 | new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), "");
346 | },
347 | has: function(e,a) {
348 | if ( e.className != undefined )
349 | e = e.className;
350 | return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e);
351 | }
352 | },
353 | swap: function(e,o,f) {
354 | for ( var i in o ) {
355 | e.style["old"+i] = e.style[i];
356 | e.style[i] = o[i];
357 | }
358 | f.apply( e, [] );
359 | for ( var i in o )
360 | e.style[i] = e.style["old"+i];
361 | },
362 |
363 | css: function(e,p) {
364 | if ( p == "height" || p == "width" ) {
365 | var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
366 |
367 | for ( var i in d ) {
368 | old["padding" + d[i]] = 0;
369 | old["border" + d[i] + "Width"] = 0;
370 | }
371 |
372 | jQuery.swap( e, old, function() {
373 | if (jQuery.css(e,"display") != "none") {
374 | oHeight = e.offsetHeight;
375 | oWidth = e.offsetWidth;
376 | } else {
377 | e = $(e.cloneNode(true)).css({
378 | visibility: "hidden", position: "absolute", display: "block"
379 | }).prependTo("body")[0];
380 |
381 | oHeight = e.clientHeight;
382 | oWidth = e.clientWidth;
383 |
384 | e.parentNode.removeChild(e);
385 | }
386 | });
387 |
388 | return p == "height" ? oHeight : oWidth;
389 | } else if ( p == "opacity" && jQuery.browser.msie )
390 | return parseFloat( jQuery.curCSS(e,"filter").replace(/[^0-9.]/,"") ) || 1;
391 |
392 | return jQuery.curCSS( e, p );
393 | },
394 |
395 | curCSS: function(elem, prop, force) {
396 | var ret;
397 |
398 | if (!force && elem.style[prop]) {
399 |
400 | ret = elem.style[prop];
401 |
402 | } else if (elem.currentStyle) {
403 |
404 | var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()});
405 | ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
406 |
407 | } else if (document.defaultView && document.defaultView.getComputedStyle) {
408 |
409 | prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
410 | var cur = document.defaultView.getComputedStyle(elem, null);
411 |
412 | if ( cur )
413 | ret = cur.getPropertyValue(prop);
414 | else if ( prop == 'display' )
415 | ret = 'none';
416 | else
417 | jQuery.swap(elem, { display: 'block' }, function() {
418 | ret = document.defaultView.getComputedStyle(this,null).getPropertyValue(prop);
419 | });
420 |
421 | }
422 |
423 | return ret;
424 | },
425 |
426 | clean: function(a) {
427 | var r = [];
428 | for ( var i = 0; i < a.length; i++ ) {
429 | if ( a[i].constructor == String ) {
430 |
431 | var table = "";
432 |
433 | if ( !a[i].indexOf("" + a[i] + "";
436 | } else if ( !a[i].indexOf("
" + a[i] + "";
439 | } else if ( !a[i].indexOf("
" + a[i] + "
";
442 | }
443 |
444 | var div = document.createElement("div");
445 | div.innerHTML = a[i];
446 |
447 | if ( table ) {
448 | div = div.firstChild;
449 | if ( table != "thead" ) div = div.firstChild;
450 | if ( table == "td" ) div = div.firstChild;
451 | }
452 |
453 | for ( var j = 0; j < div.childNodes.length; j++ )
454 | r.push( div.childNodes[j] );
455 | } else if ( a[i].jquery || a[i].length && !a[i].nodeType )
456 | for ( var k = 0; k < a[i].length; k++ )
457 | r.push( a[i][k] );
458 | else if ( a[i] !== null )
459 | r.push( a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) );
460 | }
461 | return r;
462 | },
463 |
464 | expr: {
465 | "": "m[2]== '*'||a.nodeName.toUpperCase()==m[2].toUpperCase()",
466 | "#": "a.getAttribute('id')&&a.getAttribute('id')==m[2]",
467 | ":": {
468 | // Position Checks
469 | lt: "im[3]-0",
471 | nth: "m[3]-0==i",
472 | eq: "m[3]-0==i",
473 | first: "i==0",
474 | last: "i==r.length-1",
475 | even: "i%2==0",
476 | odd: "i%2",
477 |
478 | // Child Checks
479 | "nth-child": "jQuery.sibling(a,m[3]).cur",
480 | "first-child": "jQuery.sibling(a,0).cur",
481 | "last-child": "jQuery.sibling(a,0).last",
482 | "only-child": "jQuery.sibling(a).length==1",
483 |
484 | // Parent Checks
485 | parent: "a.childNodes.length",
486 | empty: "!a.childNodes.length",
487 |
488 | // Text Check
489 | contains: "(a.innerText||a.innerHTML).indexOf(m[3])>=0",
490 |
491 | // Visibility
492 | visible: "a.type!='hidden'&&jQuery.css(a,'display')!='none'&&jQuery.css(a,'visibility')!='hidden'",
493 | hidden: "a.type=='hidden'||jQuery.css(a,'display')=='none'||jQuery.css(a,'visibility')=='hidden'",
494 |
495 | // Form elements
496 | enabled: "!a.disabled",
497 | disabled: "a.disabled",
498 | checked: "a.checked",
499 | selected: "a.selected"
500 | },
501 | ".": "jQuery.className.has(a,m[2])",
502 | "@": {
503 | "=": "z==m[4]",
504 | "!=": "z!=m[4]",
505 | "^=": "!z.indexOf(m[4])",
506 | "$=": "z.substr(z.length - m[4].length,m[4].length)==m[4]",
507 | "*=": "z.indexOf(m[4])>=0",
508 | "": "z"
509 | },
510 | "[": "jQuery.find(m[2],a).length"
511 | },
512 |
513 | token: [
514 | "\\.\\.|/\\.\\.", "a.parentNode",
515 | ">|/", "jQuery.sibling(a.firstChild)",
516 | "\\+", "jQuery.sibling(a).next",
517 | "~", function(a){
518 | var r = [];
519 | var s = jQuery.sibling(a);
520 | if ( s.n > 0 )
521 | for ( var i = s.n; i < s.length; i++ )
522 | r.push( s[i] );
523 | return r;
524 | }
525 | ],
526 | find: function( t, context ) {
527 | // Make sure that the context is a DOM Element
528 | if ( context && context.nodeType == undefined )
529 | context = null;
530 |
531 | // Set the correct context (if none is provided)
532 | context = context || jQuery.context || document;
533 |
534 | if ( t.constructor != String ) return [t];
535 |
536 | if ( !t.indexOf("//") ) {
537 | context = context.documentElement;
538 | t = t.substr(2,t.length);
539 | } else if ( !t.indexOf("/") ) {
540 | context = context.documentElement;
541 | t = t.substr(1,t.length);
542 | // FIX Assume the root element is right :(
543 | if ( t.indexOf("/") >= 1 )
544 | t = t.substr(t.indexOf("/"),t.length);
545 | }
546 |
547 | var ret = [context];
548 | var done = [];
549 | var last = null;
550 |
551 | while ( t.length > 0 && last != t ) {
552 | var r = [];
553 | last = t;
554 |
555 | t = jQuery.trim(t).replace( /^\/\//i, "" );
556 |
557 | var foundToken = false;
558 |
559 | for ( var i = 0; i < jQuery.token.length; i += 2 ) {
560 | if ( foundToken ) continue;
561 |
562 | var re = new RegExp("^(" + jQuery.token[i] + ")");
563 | var m = re.exec(t);
564 |
565 | if ( m ) {
566 | r = ret = jQuery.map( ret, jQuery.token[i+1] );
567 | t = jQuery.trim( t.replace( re, "" ) );
568 | foundToken = true;
569 | }
570 | }
571 |
572 | if ( !foundToken ) {
573 | if ( !t.indexOf(",") || !t.indexOf("|") ) {
574 | if ( ret[0] == context ) ret.shift();
575 | done = jQuery.merge( done, ret );
576 | r = ret = [context];
577 | t = " " + t.substr(1,t.length);
578 | } else {
579 | var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
580 | var m = re2.exec(t);
581 |
582 | if ( m[1] == "#" ) {
583 | // Ummm, should make this work in all XML docs
584 | var oid = document.getElementById(m[2]);
585 | r = ret = oid ? [oid] : [];
586 | t = t.replace( re2, "" );
587 | } else {
588 | if ( !m[2] || m[1] == "." ) m[2] = "*";
589 |
590 | for ( var i = 0; i < ret.length; i++ )
591 | r = jQuery.merge( r,
592 | m[2] == "*" ?
593 | jQuery.getAll(ret[i]) :
594 | ret[i].getElementsByTagName(m[2])
595 | );
596 | }
597 | }
598 |
599 | }
600 |
601 | if ( t ) {
602 | var val = jQuery.filter(t,r);
603 | ret = r = val.r;
604 | t = jQuery.trim(val.t);
605 | }
606 | }
607 |
608 | if ( ret && ret[0] == context ) ret.shift();
609 | done = jQuery.merge( done, ret );
610 |
611 | return done;
612 | },
613 |
614 | getAll: function(o,r) {
615 | r = r || [];
616 | var s = o.childNodes;
617 | for ( var i = 0; i < s.length; i++ )
618 | if ( s[i].nodeType == 1 ) {
619 | r.push( s[i] );
620 | jQuery.getAll( s[i], r );
621 | }
622 | return r;
623 | },
624 |
625 | attr: function(elem, name, value){
626 | var fix = {
627 | "for": "htmlFor",
628 | "class": "className",
629 | "float": "cssFloat",
630 | innerHTML: "innerHTML",
631 | className: "className",
632 | value: "value",
633 | disabled: "disabled"
634 | };
635 |
636 | if ( fix[name] ) {
637 | if ( value != undefined ) elem[fix[name]] = value;
638 | return elem[fix[name]];
639 | } else if ( elem.getAttribute ) {
640 | if ( value != undefined ) elem.setAttribute( name, value );
641 | return elem.getAttribute( name, 2 );
642 | } else {
643 | name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
644 | if ( value != undefined ) elem[name] = value;
645 | return elem[name];
646 | }
647 | },
648 |
649 | // The regular expressions that power the parsing engine
650 | parse: [
651 | // Match: [@value='test'], [@foo]
652 | [ "\\[ *(@)S *([!*$^=]*) *Q\\]", 1 ],
653 |
654 | // Match: [div], [div p]
655 | [ "(\\[)Q\\]", 0 ],
656 |
657 | // Match: :contains('foo')
658 | [ "(:)S\\(Q\\)", 0 ],
659 |
660 | // Match: :even, :last-chlid
661 | [ "([:.#]*)S", 0 ]
662 | ],
663 |
664 | filter: function(t,r,not) {
665 | // Figure out if we're doing regular, or inverse, filtering
666 | var g = not !== false ? jQuery.grep :
667 | function(a,f) {return jQuery.grep(a,f,true);};
668 |
669 | while ( t && /^[a-z[({<*:.#]/i.test(t) ) {
670 |
671 | var p = jQuery.parse;
672 |
673 | for ( var i = 0; i < p.length; i++ ) {
674 | var re = new RegExp( "^" + p[i][0]
675 |
676 | // Look for a string-like sequence
677 | .replace( 'S', "([a-z*_-][a-z0-9_-]*)" )
678 |
679 | // Look for something (optionally) enclosed with quotes
680 | .replace( 'Q', " *'?\"?([^'\"]*?)'?\"? *" ), "i" );
681 |
682 | var m = re.exec( t );
683 |
684 | if ( m ) {
685 | // Re-organize the match
686 | if ( p[i][1] )
687 | m = ["", m[1], m[3], m[2], m[4]];
688 |
689 | // Remove what we just matched
690 | t = t.replace( re, "" );
691 |
692 | break;
693 | }
694 | }
695 |
696 | // :not() is a special case that can be optomized by
697 | // keeping it out of the expression list
698 | if ( m[1] == ":" && m[2] == "not" )
699 | r = jQuery.filter(m[3],r,false).r;
700 |
701 | // Otherwise, find the expression to execute
702 | else {
703 | var f = jQuery.expr[m[1]];
704 | if ( f.constructor != String )
705 | f = jQuery.expr[m[1]][m[2]];
706 |
707 | // Build a custom macro to enclose it
708 | eval("f = function(a,i){" +
709 | ( m[1] == "@" ? "z=jQuery.attr(a,m[3]);" : "" ) +
710 | "return " + f + "}");
711 |
712 | // Execute it against the current filter
713 | r = g( r, f );
714 | }
715 | }
716 |
717 | // Return an array of filtered elements (r)
718 | // and the modified expression string (t)
719 | return { r: r, t: t };
720 | },
721 | trim: function(t){
722 | return t.replace(/^\s+|\s+$/g, "");
723 | },
724 | parents: function( elem ){
725 | var matched = [];
726 | var cur = elem.parentNode;
727 | while ( cur && cur != document ) {
728 | matched.push( cur );
729 | cur = cur.parentNode;
730 | }
731 | return matched;
732 | },
733 | sibling: function(elem, pos, not) {
734 | var elems = [];
735 |
736 | var siblings = elem.parentNode.childNodes;
737 | for ( var i = 0; i < siblings.length; i++ ) {
738 | if ( not === true && siblings[i] == elem ) continue;
739 |
740 | if ( siblings[i].nodeType == 1 )
741 | elems.push( siblings[i] );
742 | if ( siblings[i] == elem )
743 | elems.n = elems.length - 1;
744 | }
745 |
746 | return jQuery.extend( elems, {
747 | last: elems.n == elems.length - 1,
748 | cur: pos == "even" && elems.n % 2 == 0 || pos == "odd" && elems.n % 2 || elems[pos] == elem,
749 | prev: elems[elems.n - 1],
750 | next: elems[elems.n + 1]
751 | });
752 | },
753 | merge: function(first, second) {
754 | var result = [];
755 |
756 | // Move b over to the new array (this helps to avoid
757 | // StaticNodeList instances)
758 | for ( var k = 0; k < first.length; k++ )
759 | result[k] = first[k];
760 |
761 | // Now check for duplicates between a and b and only
762 | // add the unique items
763 | for ( var i = 0; i < second.length; i++ ) {
764 | var noCollision = true;
765 |
766 | // The collision-checking process
767 | for ( var j = 0; j < first.length; j++ )
768 | if ( second[i] == first[j] )
769 | noCollision = false;
770 |
771 | // If the item is unique, add it
772 | if ( noCollision )
773 | result.push( second[i] );
774 | }
775 |
776 | return result;
777 | },
778 | grep: function(elems, fn, inv) {
779 | // If a string is passed in for the function, make a function
780 | // for it (a handy shortcut)
781 | if ( fn.constructor == String )
782 | fn = new Function("a","i","return " + fn);
783 |
784 | var result = [];
785 |
786 | // Go through the array, only saving the items
787 | // that pass the validator function
788 | for ( var i = 0; i < elems.length; i++ )
789 | if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
790 | result.push( elems[i] );
791 |
792 | return result;
793 | },
794 | map: function(elems, fn) {
795 | // If a string is passed in for the function, make a function
796 | // for it (a handy shortcut)
797 | if ( fn.constructor == String )
798 | fn = new Function("a","return " + fn);
799 |
800 | var result = [];
801 |
802 | // Go through the array, translating each of the items to their
803 | // new value (or values).
804 | for ( var i = 0; i < elems.length; i++ ) {
805 | var val = fn(elems[i],i);
806 |
807 | if ( val !== null && val != undefined ) {
808 | if ( val.constructor != Array ) val = [val];
809 | result = jQuery.merge( result, val );
810 | }
811 | }
812 |
813 | return result;
814 | },
815 |
816 | /*
817 | * A number of helper functions used for managing events.
818 | * Many of the ideas behind this code orignated from Dean Edwards' addEvent library.
819 | */
820 | event: {
821 |
822 | // Bind an event to an element
823 | // Original by Dean Edwards
824 | add: function(element, type, handler) {
825 | // For whatever reason, IE has trouble passing the window object
826 | // around, causing it to be cloned in the process
827 | if ( jQuery.browser.msie && element.setInterval != undefined )
828 | element = window;
829 |
830 | // Make sure that the function being executed has a unique ID
831 | if ( !handler.guid )
832 | handler.guid = this.guid++;
833 |
834 | // Init the element's event structure
835 | if (!element.events)
836 | element.events = {};
837 |
838 | // Get the current list of functions bound to this event
839 | var handlers = element.events[type];
840 |
841 | // If it hasn't been initialized yet
842 | if (!handlers) {
843 | // Init the event handler queue
844 | handlers = element.events[type] = {};
845 |
846 | // Remember an existing handler, if it's already there
847 | if (element["on" + type])
848 | handlers[0] = element["on" + type];
849 | }
850 |
851 | // Add the function to the element's handler list
852 | handlers[handler.guid] = handler;
853 |
854 | // And bind the global event handler to the element
855 | element["on" + type] = this.handle;
856 |
857 | // Remember the function in a global list (for triggering)
858 | if (!this.global[type])
859 | this.global[type] = [];
860 | this.global[type].push( element );
861 | },
862 |
863 | guid: 1,
864 | global: {},
865 |
866 | // Detach an event or set of events from an element
867 | remove: function(element, type, handler) {
868 | if (element.events)
869 | if (type && element.events[type])
870 | if ( handler )
871 | delete element.events[type][handler.guid];
872 | else
873 | for ( var i in element.events[type] )
874 | delete element.events[type][i];
875 | else
876 | for ( var j in element.events )
877 | this.remove( element, j );
878 | },
879 |
880 | trigger: function(type,data,element) {
881 | // Touch up the incoming data
882 | data = data || [];
883 |
884 | // Handle a global trigger
885 | if ( !element ) {
886 | var g = this.global[type];
887 | if ( g )
888 | for ( var i = 0; i < g.length; i++ )
889 | this.trigger( type, data, g[i] );
890 |
891 | // Handle triggering a single element
892 | } else if ( element["on" + type] ) {
893 | // Pass along a fake event
894 | data.unshift( this.fix({ type: type, target: element }) );
895 |
896 | // Trigger the event
897 | element["on" + type].apply( element, data );
898 | }
899 | },
900 |
901 | handle: function(event) {
902 | if ( typeof jQuery == "undefined" ) return;
903 |
904 | event = event || jQuery.event.fix( window.event );
905 |
906 | // If no correct event was found, fail
907 | if ( !event ) return;
908 |
909 | var returnValue = true;
910 |
911 | var c = this.events[event.type];
912 |
913 | for ( var j in c ) {
914 | if ( c[j].apply( this, [event] ) === false ) {
915 | event.preventDefault();
916 | event.stopPropagation();
917 | returnValue = false;
918 | }
919 | }
920 |
921 | return returnValue;
922 | },
923 |
924 | fix: function(event) {
925 | if ( event ) {
926 | event.preventDefault = function() {
927 | this.returnValue = false;
928 | };
929 |
930 | event.stopPropagation = function() {
931 | this.cancelBubble = true;
932 | };
933 | }
934 |
935 | return event;
936 | }
937 |
938 | }
939 | });
940 |
941 | new function() {
942 | var b = navigator.userAgent.toLowerCase();
943 |
944 | // Figure out what browser is being used
945 | jQuery.browser = {
946 | safari: /webkit/.test(b),
947 | opera: /opera/.test(b),
948 | msie: /msie/.test(b) && !/opera/.test(b),
949 | mozilla: /mozilla/.test(b) && !/compatible/.test(b)
950 | };
951 |
952 | // Check to see if the W3C box model is being used
953 | jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
954 | };
955 |
956 | jQuery.macros = {
957 | to: {
958 | appendTo: "append",
959 | prependTo: "prepend",
960 | insertBefore: "before",
961 | insertAfter: "after"
962 | },
963 |
964 |
965 | css: "width,height,top,left,position,float,overflow,color,background".split(","),
966 |
967 | filter: [ "eq", "lt", "gt", "contains" ],
968 |
969 | attr: {
970 |
971 | val: "value",
972 |
973 | html: "innerHTML",
974 |
975 | id: null,
976 |
977 | title: null,
978 |
979 | name: null,
980 |
981 | href: null,
982 |
983 | src: null,
984 |
985 | rel: null
986 | },
987 |
988 | axis: {
989 |
990 | parent: "a.parentNode",
991 |
992 | ancestors: jQuery.parents,
993 |
994 | parents: jQuery.parents,
995 |
996 | next: "jQuery.sibling(a).next",
997 |
998 | prev: "jQuery.sibling(a).prev",
999 |
1000 | siblings: jQuery.sibling,
1001 |
1002 | children: "jQuery.sibling(a.firstChild)"
1003 | },
1004 |
1005 | each: {
1006 |
1007 | removeAttr: function( key ) {
1008 | this.removeAttribute( key );
1009 | },
1010 | show: function(){
1011 | this.style.display = this.oldblock ? this.oldblock : "";
1012 | if ( jQuery.css(this,"display") == "none" )
1013 | this.style.display = "block";
1014 | },
1015 | hide: function(){
1016 | this.oldblock = this.oldblock || jQuery.css(this,"display");
1017 | if ( this.oldblock == "none" )
1018 | this.oldblock = "block";
1019 | this.style.display = "none";
1020 | },
1021 | toggle: function(){
1022 | $(this)[ $(this).is(":hidden") ? "show" : "hide" ].apply( $(this), arguments );
1023 | },
1024 | addClass: function(c){
1025 | jQuery.className.add(this,c);
1026 | },
1027 | removeClass: function(c){
1028 | jQuery.className.remove(this,c);
1029 | },
1030 | toggleClass: function( c ){
1031 | jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this,c);
1032 | },
1033 |
1034 | remove: function(a){
1035 | if ( !a || jQuery.filter( a, [this] ).r )
1036 | this.parentNode.removeChild( this );
1037 | },
1038 | empty: function(){
1039 | while ( this.firstChild )
1040 | this.removeChild( this.firstChild );
1041 | },
1042 | bind: function( type, fn ) {
1043 | if ( fn.constructor == String )
1044 | fn = new Function("e", ( !fn.indexOf(".") ? "$(this)" : "return " ) + fn);
1045 | jQuery.event.add( this, type, fn );
1046 | },
1047 |
1048 | unbind: function( type, fn ) {
1049 | jQuery.event.remove( this, type, fn );
1050 | },
1051 | trigger: function( type, data ) {
1052 | jQuery.event.trigger( type, data, this );
1053 | }
1054 | }
1055 | };
1056 |
1057 | jQuery.init();
1058 | jQuery.fn.extend({
1059 |
1060 | // We're overriding the old toggle function, so
1061 | // remember it for later
1062 | _toggle: jQuery.fn.toggle,
1063 | toggle: function(a,b) {
1064 | // If two functions are passed in, we're
1065 | // toggling on a click
1066 | return a && b && a.constructor == Function && b.constructor == Function ? this.click(function(e){
1067 | // Figure out which function to execute
1068 | this.last = this.last == a ? b : a;
1069 |
1070 | // Make sure that clicks stop
1071 | e.preventDefault();
1072 |
1073 | // and execute the function
1074 | return this.last.apply( this, [e] ) || false;
1075 | }) :
1076 |
1077 | // Otherwise, execute the old toggle function
1078 | this._toggle.apply( this, arguments );
1079 | },
1080 |
1081 | hover: function(f,g) {
1082 |
1083 | // A private function for haandling mouse 'hovering'
1084 | function handleHover(e) {
1085 | // Check if mouse(over|out) are still within the same parent element
1086 | var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
1087 |
1088 | // Traverse up the tree
1089 | while ( p && p != this ) p = p.parentNode;
1090 |
1091 | // If we actually just moused on to a sub-element, ignore it
1092 | if ( p == this ) return false;
1093 |
1094 | // Execute the right function
1095 | return (e.type == "mouseover" ? f : g).apply(this, [e]);
1096 | }
1097 |
1098 | // Bind the function to the two event listeners
1099 | return this.mouseover(handleHover).mouseout(handleHover);
1100 | },
1101 | ready: function(f) {
1102 | // If the DOM is already ready
1103 | if ( jQuery.isReady )
1104 | // Execute the function immediately
1105 | f.apply( document );
1106 |
1107 | // Otherwise, remember the function for later
1108 | else {
1109 | // Add the function to the wait list
1110 | jQuery.readyList.push( f );
1111 | }
1112 |
1113 | return this;
1114 | }
1115 | });
1116 |
1117 | jQuery.extend({
1118 | /*
1119 | * All the code that makes DOM Ready work nicely.
1120 | */
1121 | isReady: false,
1122 | readyList: [],
1123 |
1124 | // Handle when the DOM is ready
1125 | ready: function() {
1126 | // Make sure that the DOM is not already loaded
1127 | if ( !jQuery.isReady ) {
1128 | // Remember that the DOM is ready
1129 | jQuery.isReady = true;
1130 |
1131 | // If there are functions bound, to execute
1132 | if ( jQuery.readyList ) {
1133 | // Execute all of them
1134 | for ( var i = 0; i < jQuery.readyList.length; i++ )
1135 | jQuery.readyList[i].apply( document );
1136 |
1137 | // Reset the list of functions
1138 | jQuery.readyList = null;
1139 | }
1140 | }
1141 | }
1142 | });
1143 |
1144 | new function(){
1145 |
1146 | var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
1147 | "mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," +
1148 | "submit,keydown,keypress,keyup,error").split(",");
1149 |
1150 | // Go through all the event names, but make sure that
1151 | // it is enclosed properly
1152 | for ( var i = 0; i < e.length; i++ ) new function(){
1153 |
1154 | var o = e[i];
1155 |
1156 | // Handle event binding
1157 | jQuery.fn[o] = function(f){
1158 | return f ? this.bind(o, f) : this.trigger(o);
1159 | };
1160 |
1161 | // Handle event unbinding
1162 | jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); };
1163 |
1164 | // Finally, handle events that only fire once
1165 | jQuery.fn["one"+o] = function(f){
1166 | // Attach the event listener
1167 | return this.each(function(){
1168 |
1169 | var count = 0;
1170 |
1171 | // Add the event
1172 | jQuery.event.add( this, o, function(e){
1173 | // If this function has already been executed, stop
1174 | if ( count++ ) return;
1175 |
1176 | // And execute the bound function
1177 | return f.apply(this, [e]);
1178 | });
1179 | });
1180 | };
1181 |
1182 | };
1183 |
1184 | // If Mozilla is used
1185 | if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
1186 | // Use the handy event callback
1187 | document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
1188 |
1189 | // If IE is used, use the excellent hack by Matthias Miller
1190 | // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
1191 | } else if ( jQuery.browser.msie ) {
1192 |
1193 | // Only works if you document.write() it
1194 | document.write("<\/script>");
1196 |
1197 | // Use the defer script hack
1198 | var script = document.getElementById("__ie_init");
1199 | script.onreadystatechange = function() {
1200 | if ( this.readyState != "complete" ) return;
1201 | this.parentNode.removeChild( this );
1202 | jQuery.ready();
1203 | };
1204 |
1205 | // Clear from memory
1206 | script = null;
1207 |
1208 | // If Safari is used
1209 | } else if ( jQuery.browser.safari ) {
1210 | // Continually check to see if the document.readyState is valid
1211 | jQuery.safariTimer = setInterval(function(){
1212 | // loaded and complete are both valid states
1213 | if ( document.readyState == "loaded" ||
1214 | document.readyState == "complete" ) {
1215 |
1216 | // If either one are found, remove the timer
1217 | clearInterval( jQuery.safariTimer );
1218 | jQuery.safariTimer = null;
1219 |
1220 | // and execute any waiting functions
1221 | jQuery.ready();
1222 | }
1223 | }, 10);
1224 | }
1225 |
1226 | // A fallback to window.onload, that will always work
1227 | jQuery.event.add( window, "load", jQuery.ready );
1228 |
1229 | };
1230 | jQuery.fn.extend({
1231 |
1232 | // overwrite the old show method
1233 | _show: jQuery.fn.show,
1234 |
1235 | show: function(speed,callback){
1236 | return speed ? this.animate({
1237 | height: "show", width: "show", opacity: "show"
1238 | }, speed, callback) : this._show();
1239 | },
1240 |
1241 | // Overwrite the old hide method
1242 | _hide: jQuery.fn.hide,
1243 |
1244 | hide: function(speed,callback){
1245 | return speed ? this.animate({
1246 | height: "hide", width: "hide", opacity: "hide"
1247 | }, speed, callback) : this._hide();
1248 | },
1249 |
1250 | slideDown: function(speed,callback){
1251 | return this.animate({height: "show"}, speed, callback);
1252 | },
1253 |
1254 | slideUp: function(speed,callback){
1255 | return this.animate({height: "hide"}, speed, callback);
1256 | },
1257 |
1258 | slideToggle: function(speed,callback){
1259 | return this.each(function(){
1260 | var state = $(this).is(":hidden") ? "show" : "hide";
1261 | $(this).animate({height: state}, speed, callback);
1262 | });
1263 | },
1264 |
1265 | fadeIn: function(speed,callback){
1266 | return this.animate({opacity: "show"}, speed, callback);
1267 | },
1268 |
1269 | fadeOut: function(speed,callback){
1270 | return this.animate({opacity: "hide"}, speed, callback);
1271 | },
1272 |
1273 | fadeTo: function(speed,to,callback){
1274 | return this.animate({opacity: to}, speed, callback);
1275 | },
1276 | animate: function(prop,speed,callback) {
1277 | return this.queue(function(){
1278 |
1279 | this.curAnim = prop;
1280 |
1281 | for ( var p in prop ) {
1282 | var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );
1283 | if ( prop[p].constructor == Number )
1284 | e.custom( e.cur(), prop[p] );
1285 | else
1286 | e[ prop[p] ]( prop );
1287 | }
1288 |
1289 | });
1290 | },
1291 | queue: function(type,fn){
1292 | if ( !fn ) {
1293 | fn = type;
1294 | type = "fx";
1295 | }
1296 |
1297 | return this.each(function(){
1298 | if ( !this.queue )
1299 | this.queue = {};
1300 |
1301 | if ( !this.queue[type] )
1302 | this.queue[type] = [];
1303 |
1304 | this.queue[type].push( fn );
1305 |
1306 | if ( this.queue[type].length == 1 )
1307 | fn.apply(this);
1308 | });
1309 | }
1310 |
1311 | });
1312 |
1313 | jQuery.extend({
1314 |
1315 | setAuto: function(e,p) {
1316 | if ( e.notAuto ) return;
1317 |
1318 | if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return;
1319 | if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return;
1320 |
1321 | // Remember the original height
1322 | var a = e.style[p];
1323 |
1324 | // Figure out the size of the height right now
1325 | var o = jQuery.curCSS(e,p,1);
1326 |
1327 | if ( p == "height" && e.scrollHeight != o ||
1328 | p == "width" && e.scrollWidth != o ) return;
1329 |
1330 | // Set the height to auto
1331 | e.style[p] = e.currentStyle ? "" : "auto";
1332 |
1333 | // See what the size of "auto" is
1334 | var n = jQuery.curCSS(e,p,1);
1335 |
1336 | // Revert back to the original size
1337 | if ( o != n && n != "auto" ) {
1338 | e.style[p] = a;
1339 | e.notAuto = true;
1340 | }
1341 | },
1342 |
1343 | speed: function(s,o) {
1344 | o = o || {};
1345 |
1346 | if ( o.constructor == Function )
1347 | o = { complete: o };
1348 |
1349 | var ss = { slow: 600, fast: 200 };
1350 | o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;
1351 |
1352 | // Queueing
1353 | o.oldComplete = o.complete;
1354 | o.complete = function(){
1355 | jQuery.dequeue(this, "fx");
1356 | if ( o.oldComplete && o.oldComplete.constructor == Function )
1357 | o.oldComplete.apply( this );
1358 | };
1359 |
1360 | return o;
1361 | },
1362 |
1363 | queue: {},
1364 |
1365 | dequeue: function(elem,type){
1366 | type = type || "fx";
1367 |
1368 | if ( elem.queue && elem.queue[type] ) {
1369 | // Remove self
1370 | elem.queue[type].shift();
1371 |
1372 | // Get next function
1373 | var f = elem.queue[type][0];
1374 |
1375 | if ( f ) f.apply( elem );
1376 | }
1377 | },
1378 |
1379 | /*
1380 | * I originally wrote fx() as a clone of moo.fx and in the process
1381 | * of making it small in size the code became illegible to sane
1382 | * people. You've been warned.
1383 | */
1384 |
1385 | fx: function( elem, options, prop ){
1386 |
1387 | var z = this;
1388 |
1389 | // The users options
1390 | z.o = {
1391 | duration: options.duration || 400,
1392 | complete: options.complete,
1393 | step: options.step
1394 | };
1395 |
1396 | // The element
1397 | z.el = elem;
1398 |
1399 | // The styles
1400 | var y = z.el.style;
1401 |
1402 | // Simple function for setting a style value
1403 | z.a = function(){
1404 | if ( options.step )
1405 | options.step.apply( elem, [ z.now ] );
1406 |
1407 | if ( prop == "opacity" ) {
1408 | if (jQuery.browser.mozilla && z.now == 1) z.now = 0.9999;
1409 | if (window.ActiveXObject)
1410 | y.filter = "alpha(opacity=" + z.now*100 + ")";
1411 | else
1412 | y.opacity = z.now;
1413 |
1414 | // My hate for IE will never die
1415 | } else if ( parseInt(z.now) )
1416 | y[prop] = parseInt(z.now) + "px";
1417 |
1418 | y.display = "block";
1419 | };
1420 |
1421 | // Figure out the maximum number to run to
1422 | z.max = function(){
1423 | return parseFloat( jQuery.css(z.el,prop) );
1424 | };
1425 |
1426 | // Get the current size
1427 | z.cur = function(){
1428 | var r = parseFloat( jQuery.curCSS(z.el, prop) );
1429 | return r && r > -10000 ? r : z.max();
1430 | };
1431 |
1432 | // Start an animation from one number to another
1433 | z.custom = function(from,to){
1434 | z.startTime = (new Date()).getTime();
1435 | z.now = from;
1436 | z.a();
1437 |
1438 | z.timer = setInterval(function(){
1439 | z.step(from, to);
1440 | }, 13);
1441 | };
1442 |
1443 | // Simple 'show' function
1444 | z.show = function( p ){
1445 | if ( !z.el.orig ) z.el.orig = {};
1446 |
1447 | // Remember where we started, so that we can go back to it later
1448 | z.el.orig[prop] = this.cur();
1449 |
1450 | z.custom( 0, z.el.orig[prop] );
1451 |
1452 | // Stupid IE, look what you made me do
1453 | if ( prop != "opacity" )
1454 | y[prop] = "1px";
1455 | };
1456 |
1457 | // Simple 'hide' function
1458 | z.hide = function(){
1459 | if ( !z.el.orig ) z.el.orig = {};
1460 |
1461 | // Remember where we started, so that we can go back to it later
1462 | z.el.orig[prop] = this.cur();
1463 |
1464 | z.o.hide = true;
1465 |
1466 | // Begin the animation
1467 | z.custom(z.el.orig[prop], 0);
1468 | };
1469 |
1470 | // IE has trouble with opacity if it does not have layout
1471 | if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout )
1472 | y.zoom = "1";
1473 |
1474 | // Remember the overflow of the element
1475 | if ( !z.el.oldOverlay )
1476 | z.el.oldOverflow = jQuery.css( z.el, "overflow" );
1477 |
1478 | // Make sure that nothing sneaks out
1479 | y.overflow = "hidden";
1480 |
1481 | // Each step of an animation
1482 | z.step = function(firstNum, lastNum){
1483 | var t = (new Date()).getTime();
1484 |
1485 | if (t > z.o.duration + z.startTime) {
1486 | // Stop the timer
1487 | clearInterval(z.timer);
1488 | z.timer = null;
1489 |
1490 | z.now = lastNum;
1491 | z.a();
1492 |
1493 | z.el.curAnim[ prop ] = true;
1494 |
1495 | var done = true;
1496 | for ( var i in z.el.curAnim )
1497 | if ( z.el.curAnim[i] !== true )
1498 | done = false;
1499 |
1500 | if ( done ) {
1501 | // Reset the overflow
1502 | y.overflow = z.el.oldOverflow;
1503 |
1504 | // Hide the element if the "hide" operation was done
1505 | if ( z.o.hide )
1506 | y.display = 'none';
1507 |
1508 | // Reset the property, if the item has been hidden
1509 | if ( z.o.hide ) {
1510 | for ( var p in z.el.curAnim ) {
1511 | y[ p ] = z.el.orig[p] + ( p == "opacity" ? "" : "px" );
1512 |
1513 | // set its height and/or width to auto
1514 | if ( p == 'height' || p == 'width' )
1515 | jQuery.setAuto( z.el, p );
1516 | }
1517 | }
1518 | }
1519 |
1520 | // If a callback was provided, execute it
1521 | if( done && z.o.complete && z.o.complete.constructor == Function )
1522 | // Execute the complete function
1523 | z.o.complete.apply( z.el );
1524 | } else {
1525 | // Figure out where in the animation we are and set the number
1526 | var p = (t - this.startTime) / z.o.duration;
1527 | z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;
1528 |
1529 | // Perform the next step of the animation
1530 | z.a();
1531 | }
1532 | };
1533 |
1534 | }
1535 |
1536 | });
1537 | // AJAX Plugin
1538 | // Docs Here:
1539 | // http://jquery.com/docs/ajax/
1540 | jQuery.fn.loadIfModified = function( url, params, callback ) {
1541 | this.load( url, params, callback, 1 );
1542 | };
1543 |
1544 | jQuery.fn.load = function( url, params, callback, ifModified ) {
1545 | if ( url.constructor == Function )
1546 | return this.bind("load", url);
1547 |
1548 | callback = callback || function(){};
1549 |
1550 | // Default to a GET request
1551 | var type = "GET";
1552 |
1553 | // If the second parameter was provided
1554 | if ( params ) {
1555 | // If it's a function
1556 | if ( params.constructor == Function ) {
1557 | // We assume that it's the callback
1558 | callback = params;
1559 | params = null;
1560 |
1561 | // Otherwise, build a param string
1562 | } else {
1563 | params = jQuery.param( params );
1564 | type = "POST";
1565 | }
1566 | }
1567 |
1568 | var self = this;
1569 |
1570 | // Request the remote document
1571 | jQuery.ajax( type, url, params,function(res, status){
1572 |
1573 | if ( status == "success" || !ifModified && status == "notmodified" ) {
1574 | // Inject the HTML into all the matched elements
1575 | self.html(res.responseText).each( callback, [res.responseText, status] );
1576 |
1577 | // Execute all the scripts inside of the newly-injected HTML
1578 | $("script", self).each(function(){
1579 | if ( this.src )
1580 | $.getScript( this.src );
1581 | else
1582 | eval.call( window, this.text || this.textContent || this.innerHTML || "" );
1583 | });
1584 | } else
1585 | callback.apply( self, [res.responseText, status] );
1586 |
1587 | }, ifModified);
1588 |
1589 | return this;
1590 | };
1591 |
1592 | // If IE is used, create a wrapper for the XMLHttpRequest object
1593 | if ( jQuery.browser.msie && typeof XMLHttpRequest == "undefined" )
1594 | XMLHttpRequest = function(){
1595 | return new ActiveXObject(
1596 | navigator.userAgent.indexOf("MSIE 5") >= 0 ?
1597 | "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
1598 | );
1599 | };
1600 |
1601 | // Attach a bunch of functions for handling common AJAX events
1602 | new function(){
1603 | var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(',');
1604 |
1605 | for ( var i = 0; i < e.length; i++ ) new function(){
1606 | var o = e[i];
1607 | jQuery.fn[o] = function(f){
1608 | return this.bind(o, f);
1609 | };
1610 | };
1611 | };
1612 |
1613 | jQuery.extend({
1614 | get: function( url, data, callback, type, ifModified ) {
1615 | if ( data.constructor == Function ) {
1616 | type = callback;
1617 | callback = data;
1618 | data = null;
1619 | }
1620 |
1621 | if ( data ) url += "?" + jQuery.param(data);
1622 |
1623 | // Build and start the HTTP Request
1624 | jQuery.ajax( "GET", url, null, function(r, status) {
1625 | if ( callback ) callback( jQuery.httpData(r,type), status );
1626 | }, ifModified);
1627 | },
1628 |
1629 | getIfModified: function( url, data, callback, type ) {
1630 | jQuery.get(url, data, callback, type, 1);
1631 | },
1632 |
1633 | getScript: function( url, data, callback ) {
1634 | jQuery.get(url, data, callback, "script");
1635 | },
1636 | post: function( url, data, callback, type ) {
1637 | // Build and start the HTTP Request
1638 | jQuery.ajax( "POST", url, jQuery.param(data), function(r, status) {
1639 | if ( callback ) callback( jQuery.httpData(r,type), status );
1640 | });
1641 | },
1642 |
1643 | // timeout (ms)
1644 | timeout: 0,
1645 |
1646 | ajaxTimeout: function(timeout) {
1647 | jQuery.timeout = timeout;
1648 | },
1649 |
1650 | // Last-Modified header cache for next request
1651 | lastModified: {},
1652 | ajax: function( type, url, data, ret, ifModified ) {
1653 | // If only a single argument was passed in,
1654 | // assume that it is a object of key/value pairs
1655 | if ( !url ) {
1656 | ret = type.complete;
1657 | var success = type.success;
1658 | var error = type.error;
1659 | data = type.data;
1660 | url = type.url;
1661 | type = type.type;
1662 | }
1663 |
1664 | // Watch for a new set of requests
1665 | if ( ! jQuery.active++ )
1666 | jQuery.event.trigger( "ajaxStart" );
1667 |
1668 | var requestDone = false;
1669 |
1670 | // Create the request object
1671 | var xml = new XMLHttpRequest();
1672 |
1673 | // Open the socket
1674 | xml.open(type || "GET", url, true);
1675 |
1676 | // Set the correct header, if data is being sent
1677 | if ( data )
1678 | xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
1679 |
1680 | // Set the If-Modified-Since header, if ifModified mode.
1681 | if ( ifModified )
1682 | xml.setRequestHeader("If-Modified-Since",
1683 | jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
1684 |
1685 | // Set header so calling script knows that it's an XMLHttpRequest
1686 | xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
1687 |
1688 | // Make sure the browser sends the right content length
1689 | if ( xml.overrideMimeType )
1690 | xml.setRequestHeader("Connection", "close");
1691 |
1692 | // Wait for a response to come back
1693 | var onreadystatechange = function(istimeout){
1694 | // The transfer is complete and the data is available, or the request timed out
1695 | if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) {
1696 | requestDone = true;
1697 |
1698 | var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ?
1699 | ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error";
1700 |
1701 | // Make sure that the request was successful or notmodified
1702 | if ( status != "error" ) {
1703 | // Cache Last-Modified header, if ifModified mode.
1704 | var modRes = xml.getResponseHeader("Last-Modified");
1705 | if ( ifModified && modRes ) jQuery.lastModified[url] = modRes;
1706 |
1707 | // If a local callback was specified, fire it
1708 | if ( success ) success( xml, status );
1709 |
1710 | // Fire the global callback
1711 | jQuery.event.trigger( "ajaxSuccess" );
1712 |
1713 | // Otherwise, the request was not successful
1714 | } else {
1715 | // If a local callback was specified, fire it
1716 | if ( error ) error( xml, status );
1717 |
1718 | // Fire the global callback
1719 | jQuery.event.trigger( "ajaxError" );
1720 | }
1721 |
1722 | // The request was completed
1723 | jQuery.event.trigger( "ajaxComplete" );
1724 |
1725 | // Handle the global AJAX counter
1726 | if ( ! --jQuery.active )
1727 | jQuery.event.trigger( "ajaxStop" );
1728 |
1729 | // Process result
1730 | if ( ret ) ret(xml, status);
1731 |
1732 | // Stop memory leaks
1733 | xml.onreadystatechange = function(){};
1734 | xml = null;
1735 |
1736 | }
1737 | };
1738 | xml.onreadystatechange = onreadystatechange;
1739 |
1740 | // Timeout checker
1741 | if(jQuery.timeout > 0)
1742 | setTimeout(function(){
1743 | // Check to see if the request is still happening
1744 | if (xml) {
1745 | // Cancel the request
1746 | xml.abort();
1747 |
1748 | if ( !requestDone ) onreadystatechange( "timeout" );
1749 |
1750 | // Clear from memory
1751 | xml = null;
1752 | }
1753 | }, jQuery.timeout);
1754 |
1755 | // Send the data
1756 | xml.send(data);
1757 | },
1758 |
1759 | // Counter for holding the number of active queries
1760 | active: 0,
1761 |
1762 | // Determines if an XMLHttpRequest was successful or not
1763 | httpSuccess: function(r) {
1764 | try {
1765 | return !r.status && location.protocol == "file:" ||
1766 | ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
1767 | jQuery.browser.safari && r.status == undefined;
1768 | } catch(e){}
1769 |
1770 | return false;
1771 | },
1772 |
1773 | // Determines if an XMLHttpRequest returns NotModified
1774 | httpNotModified: function(xml, url) {
1775 | try {
1776 | var xmlRes = xml.getResponseHeader("Last-Modified");
1777 |
1778 | // Firefox always returns 200. check Last-Modified date
1779 | return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
1780 | jQuery.browser.safari && xml.status == undefined;
1781 | } catch(e){}
1782 |
1783 | return false;
1784 | },
1785 |
1786 | // Get the data out of an XMLHttpRequest.
1787 | // Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
1788 | // otherwise return plain text.
1789 | httpData: function(r,type) {
1790 | var ct = r.getResponseHeader("content-type");
1791 | var data = !type && ct && ct.indexOf("xml") >= 0;
1792 | data = type == "xml" || data ? r.responseXML : r.responseText;
1793 |
1794 | // If the type is "script", eval it
1795 | if ( type == "script" ) eval.call( window, data );
1796 |
1797 | // Get the JavaScript object, if JSON is used.
1798 | if ( type == "json" ) eval( "data = " + data );
1799 |
1800 | return data;
1801 | },
1802 |
1803 | // Serialize an array of form elements or a set of
1804 | // key/values into a query string
1805 | param: function(a) {
1806 | var s = [];
1807 |
1808 | // If an array was passed in, assume that it is an array
1809 | // of form elements
1810 | if ( a.constructor == Array ) {
1811 | // Serialize the form elements
1812 | for ( var i = 0; i < a.length; i++ )
1813 | s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
1814 |
1815 | // Otherwise, assume that it's an object of key/value pairs
1816 | } else {
1817 | // Serialize the key/values
1818 | for ( var j in a )
1819 | s.push( j + "=" + encodeURIComponent( a[j] ) );
1820 | }
1821 |
1822 | // Return the resulting serialization
1823 | return s.join("&");
1824 | }
1825 |
1826 | });
1827 |
--------------------------------------------------------------------------------
/external/jquery-1.0.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery - New Wave Javascript
3 | *
4 | * Copyright (c) 2006 John Resig (jquery.com)
5 | * Dual licensed under the MIT (MIT-LICENSE.txt)
6 | * and GPL (GPL-LICENSE.txt) licenses.
7 | *
8 | * $Date: 2006-10-27 23:14:48 -0400 (Fri, 27 Oct 2006) $
9 | * $Rev: 509 $
10 | */
11 |
12 | // Global undefined variable
13 | window.undefined = window.undefined;
14 | function jQuery(a,c) {
15 |
16 | // Shortcut for document ready (because $(document).each() is silly)
17 | if ( a && a.constructor == Function && jQuery.fn.ready )
18 | return jQuery(document).ready(a);
19 |
20 | // Make sure that a selection was provided
21 | a = a || jQuery.context || document;
22 |
23 | // Watch for when a jQuery object is passed as the selector
24 | if ( a.jquery )
25 | return $( jQuery.merge( a, [] ) );
26 |
27 | // Watch for when a jQuery object is passed at the context
28 | if ( c && c.jquery )
29 | return $( c ).find(a);
30 |
31 | // If the context is global, return a new object
32 | if ( window == this )
33 | return new jQuery(a,c);
34 |
35 | // Handle HTML strings
36 | var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
37 | if ( m ) a = jQuery.clean( [ m[1] ] );
38 |
39 | // Watch for when an array is passed in
40 | this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
41 | // Assume that it is an array of DOM Elements
42 | jQuery.merge( a, [] ) :
43 |
44 | // Find the matching elements and save them for later
45 | jQuery.find( a, c ) );
46 |
47 | // See if an extra function was provided
48 | var fn = arguments[ arguments.length - 1 ];
49 |
50 | // If so, execute it in context
51 | if ( fn && fn.constructor == Function )
52 | this.each(fn);
53 | }
54 |
55 | // Map over the $ in case of overwrite
56 | if ( $ )
57 | jQuery._$ = $;
58 |
59 | // Map the jQuery namespace to the '$' one
60 | var $ = jQuery;
61 |
62 | jQuery.fn = jQuery.prototype = {
63 | jquery: "$Rev: 509 $",
64 |
65 | size: function() {
66 | return this.length;
67 | },
68 |
69 | get: function( num ) {
70 | // Watch for when an array (of elements) is passed in
71 | if ( num && num.constructor == Array ) {
72 |
73 | // Use a tricky hack to make the jQuery object
74 | // look and feel like an array
75 | this.length = 0;
76 | [].push.apply( this, num );
77 |
78 | return this;
79 | } else
80 | return num == undefined ?
81 |
82 | // Return a 'clean' array
83 | jQuery.map( this, function(a){ return a } ) :
84 |
85 | // Return just the object
86 | this[num];
87 | },
88 | each: function( fn, args ) {
89 | return jQuery.each( this, fn, args );
90 | },
91 |
92 | index: function( obj ) {
93 | var pos = -1;
94 | this.each(function(i){
95 | if ( this == obj ) pos = i;
96 | });
97 | return pos;
98 | },
99 |
100 | attr: function( key, value, type ) {
101 | // Check to see if we're setting style values
102 | return key.constructor != String || value != undefined ?
103 | this.each(function(){
104 | // See if we're setting a hash of styles
105 | if ( value == undefined )
106 | // Set all the styles
107 | for ( var prop in key )
108 | jQuery.attr(
109 | type ? this.style : this,
110 | prop, key[prop]
111 | );
112 |
113 | // See if we're setting a single key/value style
114 | else
115 | jQuery.attr(
116 | type ? this.style : this,
117 | key, value
118 | );
119 | }) :
120 |
121 | // Look for the case where we're accessing a style value
122 | jQuery[ type || "attr" ]( this[0], key );
123 | },
124 |
125 | css: function( key, value ) {
126 | return this.attr( key, value, "curCSS" );
127 | },
128 | text: function(e) {
129 | e = e || this;
130 | var t = "";
131 | for ( var j = 0; j < e.length; j++ ) {
132 | var r = e[j].childNodes;
133 | for ( var i = 0; i < r.length; i++ )
134 | t += r[i].nodeType != 1 ?
135 | r[i].nodeValue : jQuery.fn.text([ r[i] ]);
136 | }
137 | return t;
138 | },
139 | wrap: function() {
140 | // The elements to wrap the target around
141 | var a = jQuery.clean(arguments);
142 |
143 | // Wrap each of the matched elements individually
144 | return this.each(function(){
145 | // Clone the structure that we're using to wrap
146 | var b = a[0].cloneNode(true);
147 |
148 | // Insert it before the element to be wrapped
149 | this.parentNode.insertBefore( b, this );
150 |
151 | // Find he deepest point in the wrap structure
152 | while ( b.firstChild )
153 | b = b.firstChild;
154 |
155 | // Move the matched element to within the wrap structure
156 | b.appendChild( this );
157 | });
158 | },
159 | append: function() {
160 | return this.domManip(arguments, true, 1, function(a){
161 | this.appendChild( a );
162 | });
163 | },
164 | prepend: function() {
165 | return this.domManip(arguments, true, -1, function(a){
166 | this.insertBefore( a, this.firstChild );
167 | });
168 | },
169 | before: function() {
170 | return this.domManip(arguments, false, 1, function(a){
171 | this.parentNode.insertBefore( a, this );
172 | });
173 | },
174 | after: function() {
175 | return this.domManip(arguments, false, -1, function(a){
176 | this.parentNode.insertBefore( a, this.nextSibling );
177 | });
178 | },
179 | end: function() {
180 | return this.get( this.stack.pop() );
181 | },
182 | find: function(t) {
183 | return this.pushStack( jQuery.map( this, function(a){
184 | return jQuery.find(t,a);
185 | }), arguments );
186 | },
187 |
188 | clone: function(deep) {
189 | return this.pushStack( jQuery.map( this, function(a){
190 | return a.cloneNode( deep != undefined ? deep : true );
191 | }), arguments );
192 | },
193 |
194 | filter: function(t) {
195 | return this.pushStack(
196 | t.constructor == Array &&
197 | jQuery.map(this,function(a){
198 | for ( var i = 0; i < t.length; i++ )
199 | if ( jQuery.filter(t[i],[a]).r.length )
200 | return a;
201 | }) ||
202 |
203 | t.constructor == Boolean &&
204 | ( t ? this.get() : [] ) ||
205 |
206 | t.constructor == Function &&
207 | jQuery.grep( this, t ) ||
208 |
209 | jQuery.filter(t,this).r, arguments );
210 | },
211 |
212 | not: function(t) {
213 | return this.pushStack( t.constructor == String ?
214 | jQuery.filter(t,this,false).r :
215 | jQuery.grep(this,function(a){ return a != t; }), arguments );
216 | },
217 |
218 | add: function(t) {
219 | return this.pushStack( jQuery.merge( this, t.constructor == String ?
220 | jQuery.find(t) : t.constructor == Array ? t : [t] ), arguments );
221 | },
222 | is: function(expr) {
223 | return expr ? jQuery.filter(expr,this).r.length > 0 : this.length > 0;
224 | },
225 | domManip: function(args, table, dir, fn){
226 | var clone = this.size() > 1;
227 | var a = jQuery.clean(args);
228 |
229 | return this.each(function(){
230 | var obj = this;
231 |
232 | if ( table && this.nodeName == "TABLE" && a[0].nodeName != "THEAD" ) {
233 | var tbody = this.getElementsByTagName("tbody");
234 |
235 | if ( !tbody.length ) {
236 | obj = document.createElement("tbody");
237 | this.appendChild( obj );
238 | } else
239 | obj = tbody[0];
240 | }
241 |
242 | for ( var i = ( dir < 0 ? a.length - 1 : 0 );
243 | i != ( dir < 0 ? dir : a.length ); i += dir ) {
244 | fn.apply( obj, [ clone ? a[i].cloneNode(true) : a[i] ] );
245 | }
246 | });
247 | },
248 | pushStack: function(a,args) {
249 | var fn = args && args[args.length-1];
250 |
251 | if ( !fn || fn.constructor != Function ) {
252 | if ( !this.stack ) this.stack = [];
253 | this.stack.push( this.get() );
254 | this.get( a );
255 | } else {
256 | var old = this.get();
257 | this.get( a );
258 | if ( fn.constructor == Function )
259 | return this.each( fn );
260 | this.get( old );
261 | }
262 |
263 | return this;
264 | }
265 | };
266 |
267 | jQuery.extend = jQuery.fn.extend = function(obj,prop) {
268 | if ( !prop ) { prop = obj; obj = this; }
269 | for ( var i in prop ) obj[i] = prop[i];
270 | return obj;
271 | };
272 |
273 | jQuery.extend({
274 | init: function(){
275 | jQuery.initDone = true;
276 |
277 | jQuery.each( jQuery.macros.axis, function(i,n){
278 | jQuery.fn[ i ] = function(a) {
279 | var ret = jQuery.map(this,n);
280 | if ( a && a.constructor == String )
281 | ret = jQuery.filter(a,ret).r;
282 | return this.pushStack( ret, arguments );
283 | };
284 | });
285 |
286 | jQuery.each( jQuery.macros.to, function(i,n){
287 | jQuery.fn[ i ] = function(){
288 | var a = arguments;
289 | return this.each(function(){
290 | for ( var j = 0; j < a.length; j++ )
291 | $(a[j])[n]( this );
292 | });
293 | };
294 | });
295 |
296 | jQuery.each( jQuery.macros.each, function(i,n){
297 | jQuery.fn[ i ] = function() {
298 | return this.each( n, arguments );
299 | };
300 | });
301 |
302 | jQuery.each( jQuery.macros.filter, function(i,n){
303 | jQuery.fn[ n ] = function(num,fn) {
304 | return this.filter( ":" + n + "(" + num + ")", fn );
305 | };
306 | });
307 |
308 | jQuery.each( jQuery.macros.attr, function(i,n){
309 | n = n || i;
310 | jQuery.fn[ i ] = function(h) {
311 | return h == undefined ?
312 | this.length ? this[0][n] : null :
313 | this.attr( n, h );
314 | };
315 | });
316 |
317 | jQuery.each( jQuery.macros.css, function(i,n){
318 | jQuery.fn[ n ] = function(h) {
319 | return h == undefined ?
320 | ( this.length ? jQuery.css( this[0], n ) : null ) :
321 | this.css( n, h );
322 | };
323 | });
324 |
325 | },
326 | each: function( obj, fn, args ) {
327 | if ( obj.length == undefined )
328 | for ( var i in obj )
329 | fn.apply( obj[i], args || [i, obj[i]] );
330 | else
331 | for ( var i = 0; i < obj.length; i++ )
332 | fn.apply( obj[i], args || [i, obj[i]] );
333 | return obj;
334 | },
335 |
336 | className: {
337 | add: function(o,c){
338 | if (jQuery.className.has(o,c)) return;
339 | o.className += ( o.className ? " " : "" ) + c;
340 | },
341 | remove: function(o,c){
342 | o.className = !c ? "" :
343 | o.className.replace(
344 | new RegExp("(^|\\s*\\b[^-])"+c+"($|\\b(?=[^-]))", "g"), "");
345 | },
346 | has: function(e,a) {
347 | if ( e.className != undefined )
348 | e = e.className;
349 | return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e);
350 | }
351 | },
352 | swap: function(e,o,f) {
353 | for ( var i in o ) {
354 | e.style["old"+i] = e.style[i];
355 | e.style[i] = o[i];
356 | }
357 | f.apply( e, [] );
358 | for ( var i in o )
359 | e.style[i] = e.style["old"+i];
360 | },
361 |
362 | css: function(e,p) {
363 | if ( p == "height" || p == "width" ) {
364 | var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
365 |
366 | for ( var i in d ) {
367 | old["padding" + d[i]] = 0;
368 | old["border" + d[i] + "Width"] = 0;
369 | }
370 |
371 | jQuery.swap( e, old, function() {
372 | if (jQuery.css(e,"display") != "none") {
373 | oHeight = e.offsetHeight;
374 | oWidth = e.offsetWidth;
375 | } else {
376 | e = $(e.cloneNode(true)).css({
377 | visibility: "hidden", position: "absolute", display: "block"
378 | }).prependTo("body")[0];
379 |
380 | oHeight = e.clientHeight;
381 | oWidth = e.clientWidth;
382 |
383 | e.parentNode.removeChild(e);
384 | }
385 | });
386 |
387 | return p == "height" ? oHeight : oWidth;
388 | } else if ( p == "opacity" && jQuery.browser.msie )
389 | return parseFloat( jQuery.curCSS(e,"filter").replace(/[^0-9.]/,"") ) || 1;
390 |
391 | return jQuery.curCSS( e, p );
392 | },
393 |
394 | curCSS: function(elem, prop, force) {
395 | var ret;
396 |
397 | if (!force && elem.style[prop]) {
398 |
399 | ret = elem.style[prop];
400 |
401 | } else if (elem.currentStyle) {
402 |
403 | var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()});
404 | ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
405 |
406 | } else if (document.defaultView && document.defaultView.getComputedStyle) {
407 |
408 | prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
409 | var cur = document.defaultView.getComputedStyle(elem, null);
410 |
411 | if ( cur )
412 | ret = cur.getPropertyValue(prop);
413 | else if ( prop == 'display' )
414 | ret = 'none';
415 | else
416 | jQuery.swap(elem, { display: 'block' }, function() {
417 | ret = document.defaultView.getComputedStyle(this,null).getPropertyValue(prop);
418 | });
419 |
420 | }
421 |
422 | return ret;
423 | },
424 |
425 | clean: function(a) {
426 | var r = [];
427 | for ( var i = 0; i < a.length; i++ ) {
428 | if ( a[i].constructor == String ) {
429 |
430 | var table = "";
431 |
432 | if ( !a[i].indexOf("" + a[i] + "";
435 | } else if ( !a[i].indexOf("
" + a[i] + "";
438 | } else if ( !a[i].indexOf("
" + a[i] + "
";
441 | }
442 |
443 | var div = document.createElement("div");
444 | div.innerHTML = a[i];
445 |
446 | if ( table ) {
447 | div = div.firstChild;
448 | if ( table != "thead" ) div = div.firstChild;
449 | if ( table == "td" ) div = div.firstChild;
450 | }
451 |
452 | for ( var j = 0; j < div.childNodes.length; j++ )
453 | r.push( div.childNodes[j] );
454 | } else if ( a[i].jquery || a[i].length && !a[i].nodeType )
455 | for ( var k = 0; k < a[i].length; k++ )
456 | r.push( a[i][k] );
457 | else if ( a[i] !== null )
458 | r.push( a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) );
459 | }
460 | return r;
461 | },
462 |
463 | expr: {
464 | "": "m[2]== '*'||a.nodeName.toUpperCase()==m[2].toUpperCase()",
465 | "#": "a.getAttribute('id')&&a.getAttribute('id')==m[2]",
466 | ":": {
467 | // Position Checks
468 | lt: "im[3]-0",
470 | nth: "m[3]-0==i",
471 | eq: "m[3]-0==i",
472 | first: "i==0",
473 | last: "i==r.length-1",
474 | even: "i%2==0",
475 | odd: "i%2",
476 |
477 | // Child Checks
478 | "first-child": "jQuery.sibling(a,0).cur",
479 | "last-child": "jQuery.sibling(a,0).last",
480 | "only-child": "jQuery.sibling(a).length==1",
481 |
482 | // Parent Checks
483 | parent: "a.childNodes.length",
484 | empty: "!a.childNodes.length",
485 |
486 | // Text Check
487 | contains: "(a.innerText||a.innerHTML).indexOf(m[3])>=0",
488 |
489 | // Visibility
490 | visible: "a.type!='hidden'&&jQuery.css(a,'display')!='none'&&jQuery.css(a,'visibility')!='hidden'",
491 | hidden: "a.type=='hidden'||jQuery.css(a,'display')=='none'||jQuery.css(a,'visibility')=='hidden'",
492 |
493 | // Form elements
494 | enabled: "!a.disabled",
495 | disabled: "a.disabled",
496 | checked: "a.checked",
497 | selected: "a.selected"
498 | },
499 | ".": "jQuery.className.has(a,m[2])",
500 | "@": {
501 | "=": "z==m[4]",
502 | "!=": "z!=m[4]",
503 | "^=": "!z.indexOf(m[4])",
504 | "$=": "z.substr(z.length - m[4].length,m[4].length)==m[4]",
505 | "*=": "z.indexOf(m[4])>=0",
506 | "": "z"
507 | },
508 | "[": "jQuery.find(m[2],a).length"
509 | },
510 |
511 | token: [
512 | "\\.\\.|/\\.\\.", "a.parentNode",
513 | ">|/", "jQuery.sibling(a.firstChild)",
514 | "\\+", "jQuery.sibling(a).next",
515 | "~", function(a){
516 | var r = [];
517 | var s = jQuery.sibling(a);
518 | if ( s.n > 0 )
519 | for ( var i = s.n; i < s.length; i++ )
520 | r.push( s[i] );
521 | return r;
522 | }
523 | ],
524 | find: function( t, context ) {
525 | // Make sure that the context is a DOM Element
526 | if ( context && context.nodeType == undefined )
527 | context = null;
528 |
529 | // Set the correct context (if none is provided)
530 | context = context || jQuery.context || document;
531 |
532 | if ( t.constructor != String ) return [t];
533 |
534 | if ( !t.indexOf("//") ) {
535 | context = context.documentElement;
536 | t = t.substr(2,t.length);
537 | } else if ( !t.indexOf("/") ) {
538 | context = context.documentElement;
539 | t = t.substr(1,t.length);
540 | // FIX Assume the root element is right :(
541 | if ( t.indexOf("/") >= 1 )
542 | t = t.substr(t.indexOf("/"),t.length);
543 | }
544 |
545 | var ret = [context];
546 | var done = [];
547 | var last = null;
548 |
549 | while ( t.length > 0 && last != t ) {
550 | var r = [];
551 | last = t;
552 |
553 | t = jQuery.trim(t).replace( /^\/\//i, "" );
554 |
555 | var foundToken = false;
556 |
557 | for ( var i = 0; i < jQuery.token.length; i += 2 ) {
558 | var re = new RegExp("^(" + jQuery.token[i] + ")");
559 | var m = re.exec(t);
560 |
561 | if ( m ) {
562 | r = ret = jQuery.map( ret, jQuery.token[i+1] );
563 | t = jQuery.trim( t.replace( re, "" ) );
564 | foundToken = true;
565 | }
566 | }
567 |
568 | if ( !foundToken ) {
569 | if ( !t.indexOf(",") || !t.indexOf("|") ) {
570 | if ( ret[0] == context ) ret.shift();
571 | done = jQuery.merge( done, ret );
572 | r = ret = [context];
573 | t = " " + t.substr(1,t.length);
574 | } else {
575 | var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
576 | var m = re2.exec(t);
577 |
578 | if ( m[1] == "#" ) {
579 | // Ummm, should make this work in all XML docs
580 | var oid = document.getElementById(m[2]);
581 | r = ret = oid ? [oid] : [];
582 | t = t.replace( re2, "" );
583 | } else {
584 | if ( !m[2] || m[1] == "." ) m[2] = "*";
585 |
586 | for ( var i = 0; i < ret.length; i++ )
587 | r = jQuery.merge( r,
588 | m[2] == "*" ?
589 | jQuery.getAll(ret[i]) :
590 | ret[i].getElementsByTagName(m[2])
591 | );
592 | }
593 | }
594 | }
595 |
596 | if ( t ) {
597 | var val = jQuery.filter(t,r);
598 | ret = r = val.r;
599 | t = jQuery.trim(val.t);
600 | }
601 | }
602 |
603 | if ( ret && ret[0] == context ) ret.shift();
604 | done = jQuery.merge( done, ret );
605 |
606 | return done;
607 | },
608 |
609 | getAll: function(o,r) {
610 | r = r || [];
611 | var s = o.childNodes;
612 | for ( var i = 0; i < s.length; i++ )
613 | if ( s[i].nodeType == 1 ) {
614 | r.push( s[i] );
615 | jQuery.getAll( s[i], r );
616 | }
617 | return r;
618 | },
619 |
620 | attr: function(elem, name, value){
621 | var fix = {
622 | "for": "htmlFor",
623 | "class": "className",
624 | "float": "cssFloat",
625 | innerHTML: "innerHTML",
626 | className: "className"
627 | };
628 |
629 | if ( fix[name] ) {
630 | if ( value != undefined ) elem[fix[name]] = value;
631 | return elem[fix[name]];
632 | } else if ( elem.getAttribute ) {
633 | if ( value != undefined ) elem.setAttribute( name, value );
634 | return elem.getAttribute( name, 2 );
635 | } else {
636 | name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
637 | if ( value != undefined ) elem[name] = value;
638 | return elem[name];
639 | }
640 | },
641 |
642 | // The regular expressions that power the parsing engine
643 | parse: [
644 | // Match: [@value='test'], [@foo]
645 | [ "\\[ *(@)S *([!*$^=]*) *Q\\]", 1 ],
646 |
647 | // Match: [div], [div p]
648 | [ "(\\[)Q\\]", 0 ],
649 |
650 | // Match: :contains('foo')
651 | [ "(:)S\\(Q\\)", 0 ],
652 |
653 | // Match: :even, :last-chlid
654 | [ "([:.#]*)S", 0 ]
655 | ],
656 |
657 | filter: function(t,r,not) {
658 | // Figure out if we're doing regular, or inverse, filtering
659 | var g = not !== false ? jQuery.grep :
660 | function(a,f) {return jQuery.grep(a,f,true);};
661 |
662 | while ( t && /^[a-z[({<*:.#]/i.test(t) ) {
663 |
664 | var p = jQuery.parse;
665 |
666 | for ( var i = 0; i < p.length; i++ ) {
667 | var re = new RegExp( "^" + p[i][0]
668 |
669 | // Look for a string-like sequence
670 | .replace( 'S', "([a-z*_-][a-z0-9_-]*)" )
671 |
672 | // Look for something (optionally) enclosed with quotes
673 | .replace( 'Q', " *'?\"?([^'\"]*?)'?\"? *" ), "i" );
674 |
675 | var m = re.exec( t );
676 |
677 | if ( m ) {
678 | // Re-organize the match
679 | if ( p[i][1] )
680 | m = ["", m[1], m[3], m[2], m[4]];
681 |
682 | // Remove what we just matched
683 | t = t.replace( re, "" );
684 |
685 | break;
686 | }
687 | }
688 |
689 | // :not() is a special case that can be optomized by
690 | // keeping it out of the expression list
691 | if ( m[1] == ":" && m[2] == "not" )
692 | r = jQuery.filter(m[3],r,false).r;
693 |
694 | // Otherwise, find the expression to execute
695 | else {
696 | var f = jQuery.expr[m[1]];
697 | if ( f.constructor != String )
698 | f = jQuery.expr[m[1]][m[2]];
699 |
700 | // Build a custom macro to enclose it
701 | eval("f = function(a,i){" +
702 | ( m[1] == "@" ? "z=jQuery.attr(a,m[3]);" : "" ) +
703 | "return " + f + "}");
704 |
705 | // Execute it against the current filter
706 | r = g( r, f );
707 | }
708 | }
709 |
710 | // Return an array of filtered elements (r)
711 | // and the modified expression string (t)
712 | return { r: r, t: t };
713 | },
714 | trim: function(t){
715 | return t.replace(/^\s+|\s+$/g, "");
716 | },
717 | parents: function( elem ){
718 | var matched = [];
719 | var cur = elem.parentNode;
720 | while ( cur && cur != document ) {
721 | matched.push( cur );
722 | cur = cur.parentNode;
723 | }
724 | return matched;
725 | },
726 | sibling: function(elem, pos, not) {
727 | var elems = [];
728 |
729 | var siblings = elem.parentNode.childNodes;
730 | for ( var i = 0; i < siblings.length; i++ ) {
731 | if ( not === true && siblings[i] == elem ) continue;
732 |
733 | if ( siblings[i].nodeType == 1 )
734 | elems.push( siblings[i] );
735 | if ( siblings[i] == elem )
736 | elems.n = elems.length - 1;
737 | }
738 |
739 | return jQuery.extend( elems, {
740 | last: elems.n == elems.length - 1,
741 | cur: pos == "even" && elems.n % 2 == 0 || pos == "odd" && elems.n % 2 || elems[pos] == elem,
742 | prev: elems[elems.n - 1],
743 | next: elems[elems.n + 1]
744 | });
745 | },
746 | merge: function(first, second) {
747 | var result = [];
748 |
749 | // Move b over to the new array (this helps to avoid
750 | // StaticNodeList instances)
751 | for ( var k = 0; k < first.length; k++ )
752 | result[k] = first[k];
753 |
754 | // Now check for duplicates between a and b and only
755 | // add the unique items
756 | for ( var i = 0; i < second.length; i++ ) {
757 | var noCollision = true;
758 |
759 | // The collision-checking process
760 | for ( var j = 0; j < first.length; j++ )
761 | if ( second[i] == first[j] )
762 | noCollision = false;
763 |
764 | // If the item is unique, add it
765 | if ( noCollision )
766 | result.push( second[i] );
767 | }
768 |
769 | return result;
770 | },
771 | grep: function(elems, fn, inv) {
772 | // If a string is passed in for the function, make a function
773 | // for it (a handy shortcut)
774 | if ( fn.constructor == String )
775 | fn = new Function("a","i","return " + fn);
776 |
777 | var result = [];
778 |
779 | // Go through the array, only saving the items
780 | // that pass the validator function
781 | for ( var i = 0; i < elems.length; i++ )
782 | if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
783 | result.push( elems[i] );
784 |
785 | return result;
786 | },
787 | map: function(elems, fn) {
788 | // If a string is passed in for the function, make a function
789 | // for it (a handy shortcut)
790 | if ( fn.constructor == String )
791 | fn = new Function("a","return " + fn);
792 |
793 | var result = [];
794 |
795 | // Go through the array, translating each of the items to their
796 | // new value (or values).
797 | for ( var i = 0; i < elems.length; i++ ) {
798 | var val = fn(elems[i],i);
799 |
800 | if ( val !== null && val != undefined ) {
801 | if ( val.constructor != Array ) val = [val];
802 | result = jQuery.merge( result, val );
803 | }
804 | }
805 |
806 | return result;
807 | },
808 |
809 | /*
810 | * A number of helper functions used for managing events.
811 | * Many of the ideas behind this code orignated from Dean Edwards' addEvent library.
812 | */
813 | event: {
814 |
815 | // Bind an event to an element
816 | // Original by Dean Edwards
817 | add: function(element, type, handler) {
818 | // For whatever reason, IE has trouble passing the window object
819 | // around, causing it to be cloned in the process
820 | if ( jQuery.browser.msie && element.setInterval != undefined )
821 | element = window;
822 |
823 | // Make sure that the function being executed has a unique ID
824 | if ( !handler.guid )
825 | handler.guid = this.guid++;
826 |
827 | // Init the element's event structure
828 | if (!element.events)
829 | element.events = {};
830 |
831 | // Get the current list of functions bound to this event
832 | var handlers = element.events[type];
833 |
834 | // If it hasn't been initialized yet
835 | if (!handlers) {
836 | // Init the event handler queue
837 | handlers = element.events[type] = {};
838 |
839 | // Remember an existing handler, if it's already there
840 | if (element["on" + type])
841 | handlers[0] = element["on" + type];
842 | }
843 |
844 | // Add the function to the element's handler list
845 | handlers[handler.guid] = handler;
846 |
847 | // And bind the global event handler to the element
848 | element["on" + type] = this.handle;
849 |
850 | // Remember the function in a global list (for triggering)
851 | if (!this.global[type])
852 | this.global[type] = [];
853 | this.global[type].push( element );
854 | },
855 |
856 | guid: 1,
857 | global: {},
858 |
859 | // Detach an event or set of events from an element
860 | remove: function(element, type, handler) {
861 | if (element.events)
862 | if (type && element.events[type])
863 | if ( handler )
864 | delete element.events[type][handler.guid];
865 | else
866 | for ( var i in element.events[type] )
867 | delete element.events[type][i];
868 | else
869 | for ( var j in element.events )
870 | this.remove( element, j );
871 | },
872 |
873 | trigger: function(type,data,element) {
874 | // Touch up the incoming data
875 | data = data || [];
876 |
877 | // Handle a global trigger
878 | if ( !element ) {
879 | var g = this.global[type];
880 | if ( g )
881 | for ( var i = 0; i < g.length; i++ )
882 | this.trigger( type, data, g[i] );
883 |
884 | // Handle triggering a single element
885 | } else if ( element["on" + type] ) {
886 | // Pass along a fake event
887 | data.unshift( this.fix({ type: type, target: element }) );
888 |
889 | // Trigger the event
890 | element["on" + type].apply( element, data );
891 | }
892 | },
893 |
894 | handle: function(event) {
895 | if ( typeof jQuery == "undefined" ) return;
896 |
897 | event = event || jQuery.event.fix( window.event );
898 |
899 | // If no correct event was found, fail
900 | if ( !event ) return;
901 |
902 | var returnValue = true;
903 |
904 | var c = this.events[event.type];
905 |
906 | for ( var j in c ) {
907 | if ( c[j].apply( this, [event] ) === false ) {
908 | event.preventDefault();
909 | event.stopPropagation();
910 | returnValue = false;
911 | }
912 | }
913 |
914 | return returnValue;
915 | },
916 |
917 | fix: function(event) {
918 | if ( event ) {
919 | event.preventDefault = function() {
920 | this.returnValue = false;
921 | };
922 |
923 | event.stopPropagation = function() {
924 | this.cancelBubble = true;
925 | };
926 | }
927 |
928 | return event;
929 | }
930 |
931 | }
932 | });
933 |
934 | new function() {
935 | var b = navigator.userAgent.toLowerCase();
936 |
937 | // Figure out what browser is being used
938 | jQuery.browser = {
939 | safari: /webkit/.test(b),
940 | opera: /opera/.test(b),
941 | msie: /msie/.test(b) && !/opera/.test(b),
942 | mozilla: /mozilla/.test(b) && !/compatible/.test(b)
943 | };
944 |
945 | // Check to see if the W3C box model is being used
946 | jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
947 | };
948 |
949 | jQuery.macros = {
950 | to: {
951 | appendTo: "append",
952 | prependTo: "prepend",
953 | insertBefore: "before",
954 | insertAfter: "after"
955 | },
956 |
957 |
958 | css: "width,height,top,left,position,float,overflow,color,background".split(","),
959 |
960 | filter: [ "eq", "lt", "gt", "contains" ],
961 |
962 | attr: {
963 |
964 | val: "value",
965 |
966 | html: "innerHTML",
967 |
968 | id: null,
969 |
970 | title: null,
971 |
972 | name: null,
973 |
974 | href: null,
975 |
976 | src: null,
977 |
978 | rel: null
979 | },
980 |
981 | axis: {
982 |
983 | parent: "a.parentNode",
984 |
985 | ancestors: jQuery.parents,
986 |
987 | parents: jQuery.parents,
988 |
989 | next: "jQuery.sibling(a).next",
990 |
991 | prev: "jQuery.sibling(a).prev",
992 |
993 | siblings: jQuery.sibling,
994 |
995 | children: "a.childNodes"
996 | },
997 |
998 | each: {
999 |
1000 | removeAttr: function( key ) {
1001 | this.removeAttribute( key );
1002 | },
1003 | show: function(){
1004 | this.style.display = this.oldblock ? this.oldblock : "";
1005 | if ( jQuery.css(this,"display") == "none" )
1006 | this.style.display = "block";
1007 | },
1008 | hide: function(){
1009 | this.oldblock = this.oldblock || jQuery.css(this,"display");
1010 | if ( this.oldblock == "none" )
1011 | this.oldblock = "block";
1012 | this.style.display = "none";
1013 | },
1014 | toggle: function(){
1015 | $(this)[ $(this).is(":hidden") ? "show" : "hide" ].apply( $(this), arguments );
1016 | },
1017 | addClass: function(c){
1018 | jQuery.className.add(this,c);
1019 | },
1020 | removeClass: function(c){
1021 | jQuery.className.remove(this,c);
1022 | },
1023 | toggleClass: function( c ){
1024 | jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this,c);
1025 | },
1026 |
1027 | remove: function(a){
1028 | if ( !a || jQuery.filter( [this], a ).r )
1029 | this.parentNode.removeChild( this );
1030 | },
1031 | empty: function(){
1032 | while ( this.firstChild )
1033 | this.removeChild( this.firstChild );
1034 | },
1035 | bind: function( type, fn ) {
1036 | if ( fn.constructor == String )
1037 | fn = new Function("e", ( !fn.indexOf(".") ? "$(this)" : "return " ) + fn);
1038 | jQuery.event.add( this, type, fn );
1039 | },
1040 |
1041 | unbind: function( type, fn ) {
1042 | jQuery.event.remove( this, type, fn );
1043 | },
1044 | trigger: function( type, data ) {
1045 | jQuery.event.trigger( type, data, this );
1046 | }
1047 | }
1048 | };
1049 |
1050 | jQuery.init();jQuery.fn.extend({
1051 |
1052 | // We're overriding the old toggle function, so
1053 | // remember it for later
1054 | _toggle: jQuery.fn.toggle,
1055 | toggle: function(a,b) {
1056 | // If two functions are passed in, we're
1057 | // toggling on a click
1058 | return a && b && a.constructor == Function && b.constructor == Function ? this.click(function(e){
1059 | // Figure out which function to execute
1060 | this.last = this.last == a ? b : a;
1061 |
1062 | // Make sure that clicks stop
1063 | e.preventDefault();
1064 |
1065 | // and execute the function
1066 | return this.last.apply( this, [e] ) || false;
1067 | }) :
1068 |
1069 | // Otherwise, execute the old toggle function
1070 | this._toggle.apply( this, arguments );
1071 | },
1072 |
1073 | hover: function(f,g) {
1074 |
1075 | // A private function for haandling mouse 'hovering'
1076 | function handleHover(e) {
1077 | // Check if mouse(over|out) are still within the same parent element
1078 | var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
1079 |
1080 | // Traverse up the tree
1081 | while ( p && p != this ) p = p.parentNode;
1082 |
1083 | // If we actually just moused on to a sub-element, ignore it
1084 | if ( p == this ) return false;
1085 |
1086 | // Execute the right function
1087 | return (e.type == "mouseover" ? f : g).apply(this, [e]);
1088 | }
1089 |
1090 | // Bind the function to the two event listeners
1091 | return this.mouseover(handleHover).mouseout(handleHover);
1092 | },
1093 | ready: function(f) {
1094 | // If the DOM is already ready
1095 | if ( jQuery.isReady )
1096 | // Execute the function immediately
1097 | f.apply( document );
1098 |
1099 | // Otherwise, remember the function for later
1100 | else {
1101 | // Add the function to the wait list
1102 | jQuery.readyList.push( f );
1103 | }
1104 |
1105 | return this;
1106 | }
1107 | });
1108 |
1109 | jQuery.extend({
1110 | /*
1111 | * All the code that makes DOM Ready work nicely.
1112 | */
1113 | isReady: false,
1114 | readyList: [],
1115 |
1116 | // Handle when the DOM is ready
1117 | ready: function() {
1118 | // Make sure that the DOM is not already loaded
1119 | if ( !jQuery.isReady ) {
1120 | // Remember that the DOM is ready
1121 | jQuery.isReady = true;
1122 |
1123 | // If there are functions bound, to execute
1124 | if ( jQuery.readyList ) {
1125 | // Execute all of them
1126 | for ( var i = 0; i < jQuery.readyList.length; i++ )
1127 | jQuery.readyList[i].apply( document );
1128 |
1129 | // Reset the list of functions
1130 | jQuery.readyList = null;
1131 | }
1132 | }
1133 | }
1134 | });
1135 |
1136 | new function(){
1137 |
1138 | var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
1139 | "mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," +
1140 | "submit,keydown,keypress,keyup,error").split(",");
1141 |
1142 | // Go through all the event names, but make sure that
1143 | // it is enclosed properly
1144 | for ( var i = 0; i < e.length; i++ ) new function(){
1145 |
1146 | var o = e[i];
1147 |
1148 | // Handle event binding
1149 | jQuery.fn[o] = function(f){
1150 | return f ? this.bind(o, f) : this.trigger(o);
1151 | };
1152 |
1153 | // Handle event unbinding
1154 | jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); };
1155 |
1156 | // Finally, handle events that only fire once
1157 | jQuery.fn["one"+o] = function(f){
1158 | // Attach the event listener
1159 | return this.each(function(){
1160 |
1161 | var count = 0;
1162 |
1163 | // Add the event
1164 | jQuery.event.add( this, o, function(e){
1165 | // If this function has already been executed, stop
1166 | if ( count++ ) return;
1167 |
1168 | // And execute the bound function
1169 | return f.apply(this, [e]);
1170 | });
1171 | });
1172 | };
1173 |
1174 | };
1175 |
1176 | // If Mozilla is used
1177 | if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
1178 | // Use the handy event callback
1179 | document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
1180 |
1181 | // If IE is used, use the excellent hack by Matthias Miller
1182 | // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
1183 | } else if ( jQuery.browser.msie ) {
1184 |
1185 | // Only works if you document.write() it
1186 | document.write("<\/script>");
1188 |
1189 | // Use the defer script hack
1190 | var script = document.getElementById("__ie_init");
1191 | script.onreadystatechange = function() {
1192 | if ( this.readyState == "complete" )
1193 | jQuery.ready();
1194 | };
1195 |
1196 | // Clear from memory
1197 | script = null;
1198 |
1199 | // If Safari is used
1200 | } else if ( jQuery.browser.safari ) {
1201 | // Continually check to see if the document.readyState is valid
1202 | jQuery.safariTimer = setInterval(function(){
1203 | // loaded and complete are both valid states
1204 | if ( document.readyState == "loaded" ||
1205 | document.readyState == "complete" ) {
1206 |
1207 | // If either one are found, remove the timer
1208 | clearInterval( jQuery.safariTimer );
1209 | jQuery.safariTimer = null;
1210 |
1211 | // and execute any waiting functions
1212 | jQuery.ready();
1213 | }
1214 | }, 10);
1215 | }
1216 |
1217 | // A fallback to window.onload, that will always work
1218 | jQuery.event.add( window, "load", jQuery.ready );
1219 |
1220 | };
1221 | jQuery.fn.extend({
1222 |
1223 | // overwrite the old show method
1224 | _show: jQuery.fn.show,
1225 |
1226 | show: function(speed,callback){
1227 | return speed ? this.animate({
1228 | height: "show", width: "show", opacity: "show"
1229 | }, speed, callback) : this._show();
1230 | },
1231 |
1232 | // Overwrite the old hide method
1233 | _hide: jQuery.fn.hide,
1234 |
1235 | hide: function(speed,callback){
1236 | return speed ? this.animate({
1237 | height: "hide", width: "hide", opacity: "hide"
1238 | }, speed, callback) : this._hide();
1239 | },
1240 |
1241 | slideDown: function(speed,callback){
1242 | return this.animate({height: "show"}, speed, callback);
1243 | },
1244 |
1245 | slideUp: function(speed,callback){
1246 | return this.animate({height: "hide"}, speed, callback);
1247 | },
1248 |
1249 | slideToggle: function(speed,callback){
1250 | return this.each(function(){
1251 | var state = $(this).is(":hidden") ? "show" : "hide";
1252 | $(this).animate({height: state}, speed, callback);
1253 | });
1254 | },
1255 |
1256 | fadeIn: function(speed,callback){
1257 | return this.animate({opacity: "show"}, speed, callback);
1258 | },
1259 |
1260 | fadeOut: function(speed,callback){
1261 | return this.animate({opacity: "hide"}, speed, callback);
1262 | },
1263 |
1264 | fadeTo: function(speed,to,callback){
1265 | return this.animate({opacity: to}, speed, callback);
1266 | },
1267 | animate: function(prop,speed,callback) {
1268 | return this.queue(function(){
1269 |
1270 | this.curAnim = prop;
1271 |
1272 | for ( var p in prop ) {
1273 | var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );
1274 | if ( prop[p].constructor == Number )
1275 | e.custom( e.cur(), prop[p] );
1276 | else
1277 | e[ prop[p] ]( prop );
1278 | }
1279 |
1280 | });
1281 | },
1282 | queue: function(type,fn){
1283 | if ( !fn ) {
1284 | fn = type;
1285 | type = "fx";
1286 | }
1287 |
1288 | return this.each(function(){
1289 | if ( !this.queue )
1290 | this.queue = {};
1291 |
1292 | if ( !this.queue[type] )
1293 | this.queue[type] = [];
1294 |
1295 | this.queue[type].push( fn );
1296 |
1297 | if ( this.queue[type].length == 1 )
1298 | fn.apply(this);
1299 | });
1300 | }
1301 |
1302 | });
1303 |
1304 | jQuery.extend({
1305 |
1306 | setAuto: function(e,p) {
1307 | if ( e.notAuto ) return;
1308 |
1309 | if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return;
1310 | if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return;
1311 |
1312 | // Remember the original height
1313 | var a = e.style[p];
1314 |
1315 | // Figure out the size of the height right now
1316 | var o = jQuery.curCSS(e,p,1);
1317 |
1318 | if ( p == "height" && e.scrollHeight != o ||
1319 | p == "width" && e.scrollWidth != o ) return;
1320 |
1321 | // Set the height to auto
1322 | e.style[p] = e.currentStyle ? "" : "auto";
1323 |
1324 | // See what the size of "auto" is
1325 | var n = jQuery.curCSS(e,p,1);
1326 |
1327 | // Revert back to the original size
1328 | if ( o != n && n != "auto" ) {
1329 | e.style[p] = a;
1330 | e.notAuto = true;
1331 | }
1332 | },
1333 |
1334 | speed: function(s,o) {
1335 | o = o || {};
1336 |
1337 | if ( o.constructor == Function )
1338 | o = { complete: o };
1339 |
1340 | var ss = { slow: 600, fast: 200 };
1341 | o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;
1342 |
1343 | // Queueing
1344 | o.oldComplete = o.complete;
1345 | o.complete = function(){
1346 | jQuery.dequeue(this, "fx");
1347 | if ( o.oldComplete && o.oldComplete.constructor == Function )
1348 | o.oldComplete.apply( this );
1349 | };
1350 |
1351 | return o;
1352 | },
1353 |
1354 | queue: {},
1355 |
1356 | dequeue: function(elem,type){
1357 | type = type || "fx";
1358 |
1359 | if ( elem.queue && elem.queue[type] ) {
1360 | // Remove self
1361 | elem.queue[type].shift();
1362 |
1363 | // Get next function
1364 | var f = elem.queue[type][0];
1365 |
1366 | if ( f ) f.apply( elem );
1367 | }
1368 | },
1369 |
1370 | /*
1371 | * I originally wrote fx() as a clone of moo.fx and in the process
1372 | * of making it small in size the code became illegible to sane
1373 | * people. You've been warned.
1374 | */
1375 |
1376 | fx: function( elem, options, prop ){
1377 |
1378 | var z = this;
1379 |
1380 | // The users options
1381 | z.o = {
1382 | duration: options.duration || 400,
1383 | complete: options.complete,
1384 | step: options.step
1385 | };
1386 |
1387 | // The element
1388 | z.el = elem;
1389 |
1390 | // The styles
1391 | var y = z.el.style;
1392 |
1393 | // Simple function for setting a style value
1394 | z.a = function(){
1395 | if ( options.step )
1396 | options.step.apply( elem, [ z.now ] );
1397 |
1398 | if ( prop == "opacity" ) {
1399 | if (z.now == 1) z.now = 0.9999;
1400 | if (window.ActiveXObject)
1401 | y.filter = "alpha(opacity=" + z.now*100 + ")";
1402 | else
1403 | y.opacity = z.now;
1404 |
1405 | // My hate for IE will never die
1406 | } else if ( parseInt(z.now) )
1407 | y[prop] = parseInt(z.now) + "px";
1408 |
1409 | y.display = "block";
1410 | };
1411 |
1412 | // Figure out the maximum number to run to
1413 | z.max = function(){
1414 | return parseFloat( jQuery.css(z.el,prop) );
1415 | };
1416 |
1417 | // Get the current size
1418 | z.cur = function(){
1419 | var r = parseFloat( jQuery.curCSS(z.el, prop) );
1420 | return r && r > -10000 ? r : z.max();
1421 | };
1422 |
1423 | // Start an animation from one number to another
1424 | z.custom = function(from,to){
1425 | z.startTime = (new Date()).getTime();
1426 | z.now = from;
1427 | z.a();
1428 |
1429 | z.timer = setInterval(function(){
1430 | z.step(from, to);
1431 | }, 13);
1432 | };
1433 |
1434 | // Simple 'show' function
1435 | z.show = function( p ){
1436 | if ( !z.el.orig ) z.el.orig = {};
1437 |
1438 | // Remember where we started, so that we can go back to it later
1439 | z.el.orig[prop] = this.cur();
1440 |
1441 | z.custom( 0, z.el.orig[prop] );
1442 |
1443 | // Stupid IE, look what you made me do
1444 | if ( prop != "opacity" )
1445 | y[prop] = "1px";
1446 | };
1447 |
1448 | // Simple 'hide' function
1449 | z.hide = function(){
1450 | if ( !z.el.orig ) z.el.orig = {};
1451 |
1452 | // Remember where we started, so that we can go back to it later
1453 | z.el.orig[prop] = this.cur();
1454 |
1455 | z.o.hide = true;
1456 |
1457 | // Begin the animation
1458 | z.custom(z.el.orig[prop], 0);
1459 | };
1460 |
1461 | // IE has trouble with opacity if it does not have layout
1462 | if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout )
1463 | y.zoom = "1";
1464 |
1465 | // Remember the overflow of the element
1466 | if ( !z.el.oldOverlay )
1467 | z.el.oldOverflow = jQuery.css( z.el, "overflow" );
1468 |
1469 | // Make sure that nothing sneaks out
1470 | y.overflow = "hidden";
1471 |
1472 | // Each step of an animation
1473 | z.step = function(firstNum, lastNum){
1474 | var t = (new Date()).getTime();
1475 |
1476 | if (t > z.o.duration + z.startTime) {
1477 | // Stop the timer
1478 | clearInterval(z.timer);
1479 | z.timer = null;
1480 |
1481 | z.now = lastNum;
1482 | z.a();
1483 |
1484 | z.el.curAnim[ prop ] = true;
1485 |
1486 | var done = true;
1487 | for ( var i in z.el.curAnim )
1488 | if ( z.el.curAnim[i] !== true )
1489 | done = false;
1490 |
1491 | if ( done ) {
1492 | // Reset the overflow
1493 | y.overflow = z.el.oldOverflow;
1494 |
1495 | // Hide the element if the "hide" operation was done
1496 | if ( z.o.hide )
1497 | y.display = 'none';
1498 |
1499 | // Reset the property, if the item has been hidden
1500 | if ( z.o.hide ) {
1501 | for ( var p in z.el.curAnim ) {
1502 | y[ p ] = z.el.orig[p] + ( p == "opacity" ? "" : "px" );
1503 |
1504 | // set its height and/or width to auto
1505 | if ( p == 'height' || p == 'width' )
1506 | jQuery.setAuto( z.el, p );
1507 | }
1508 | }
1509 | }
1510 |
1511 | // If a callback was provided, execute it
1512 | if( done && z.o.complete && z.o.complete.constructor == Function )
1513 | // Execute the complete function
1514 | z.o.complete.apply( z.el );
1515 | } else {
1516 | // Figure out where in the animation we are and set the number
1517 | var p = (t - this.startTime) / z.o.duration;
1518 | z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;
1519 |
1520 | // Perform the next step of the animation
1521 | z.a();
1522 | }
1523 | };
1524 |
1525 | }
1526 |
1527 | });
1528 | // AJAX Plugin
1529 | // Docs Here:
1530 | // http://jquery.com/docs/ajax/
1531 | jQuery.fn.loadIfModified = function( url, params, callback ) {
1532 | this.load( url, params, callback, 1 );
1533 | };
1534 |
1535 | jQuery.fn.load = function( url, params, callback, ifModified ) {
1536 | if ( url.constructor == Function )
1537 | return this.bind("load", url);
1538 |
1539 | callback = callback || function(){};
1540 |
1541 | // Default to a GET request
1542 | var type = "GET";
1543 |
1544 | // If the second parameter was provided
1545 | if ( params ) {
1546 | // If it's a function
1547 | if ( params.constructor == Function ) {
1548 | // We assume that it's the callback
1549 | callback = params;
1550 | params = null;
1551 |
1552 | // Otherwise, build a param string
1553 | } else {
1554 | params = jQuery.param( params );
1555 | type = "POST";
1556 | }
1557 | }
1558 |
1559 | var self = this;
1560 |
1561 | // Request the remote document
1562 | jQuery.ajax( type, url, params,function(res, status){
1563 |
1564 | if ( status == "success" || !ifModified && status == "notmodified" ) {
1565 | // Inject the HTML into all the matched elements
1566 | self.html(res.responseText).each( callback, [res.responseText, status] );
1567 |
1568 | // Execute all the scripts inside of the newly-injected HTML
1569 | $("script", self).each(function(){
1570 | if ( this.src )
1571 | $.getScript( this.src );
1572 | else
1573 | eval.call( window, this.text || this.textContent || this.innerHTML || "" );
1574 | });
1575 | } else
1576 | callback.apply( self, [res.responseText, status] );
1577 |
1578 | }, ifModified);
1579 |
1580 | return this;
1581 | };
1582 |
1583 | // If IE is used, create a wrapper for the XMLHttpRequest object
1584 | if ( jQuery.browser.msie )
1585 | XMLHttpRequest = function(){
1586 | return new ActiveXObject(
1587 | navigator.userAgent.indexOf("MSIE 5") >= 0 ?
1588 | "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
1589 | );
1590 | };
1591 |
1592 | // Attach a bunch of functions for handling common AJAX events
1593 | new function(){
1594 | var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(',');
1595 |
1596 | for ( var i = 0; i < e.length; i++ ) new function(){
1597 | var o = e[i];
1598 | jQuery.fn[o] = function(f){
1599 | return this.bind(o, f);
1600 | };
1601 | };
1602 | };
1603 |
1604 | jQuery.extend({
1605 | get: function( url, data, callback, type, ifModified ) {
1606 | if ( data.constructor == Function ) {
1607 | type = callback;
1608 | callback = data;
1609 | data = null;
1610 | }
1611 |
1612 | if ( data ) url += "?" + jQuery.param(data);
1613 |
1614 | // Build and start the HTTP Request
1615 | jQuery.ajax( "GET", url, null, function(r, status) {
1616 | if ( callback ) callback( jQuery.httpData(r,type), status );
1617 | }, ifModified);
1618 | },
1619 |
1620 | getIfModified: function( url, data, callback, type ) {
1621 | jQuery.get(url, data, callback, type, 1);
1622 | },
1623 |
1624 | getScript: function( url, data, callback ) {
1625 | jQuery.get(url, data, callback, "script");
1626 | },
1627 | post: function( url, data, callback, type ) {
1628 | // Build and start the HTTP Request
1629 | jQuery.ajax( "POST", url, jQuery.param(data), function(r, status) {
1630 | if ( callback ) callback( jQuery.httpData(r,type), status );
1631 | });
1632 | },
1633 |
1634 | // timeout (ms)
1635 | timeout: 0,
1636 |
1637 | ajaxTimeout: function(timeout) {
1638 | jQuery.timeout = timeout;
1639 | },
1640 |
1641 | // Last-Modified header cache for next request
1642 | lastModified: {},
1643 | ajax: function( type, url, data, ret, ifModified ) {
1644 | // If only a single argument was passed in,
1645 | // assume that it is a object of key/value pairs
1646 | if ( !url ) {
1647 | ret = type.complete;
1648 | var success = type.success;
1649 | var error = type.error;
1650 | data = type.data;
1651 | url = type.url;
1652 | type = type.type;
1653 | }
1654 |
1655 | // Watch for a new set of requests
1656 | if ( ! jQuery.active++ )
1657 | jQuery.event.trigger( "ajaxStart" );
1658 |
1659 | var requestDone = false;
1660 |
1661 | // Create the request object
1662 | var xml = new XMLHttpRequest();
1663 |
1664 | // Open the socket
1665 | xml.open(type || "GET", url, true);
1666 |
1667 | // Set the correct header, if data is being sent
1668 | if ( data )
1669 | xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
1670 |
1671 | // Set the If-Modified-Since header, if ifModified mode.
1672 | if ( ifModified )
1673 | xml.setRequestHeader("If-Modified-Since",
1674 | jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
1675 |
1676 | // Set header so calling script knows that it's an XMLHttpRequest
1677 | xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
1678 |
1679 | // Make sure the browser sends the right content length
1680 | if ( xml.overrideMimeType )
1681 | xml.setRequestHeader("Connection", "close");
1682 |
1683 | // Wait for a response to come back
1684 | var onreadystatechange = function(istimeout){
1685 | // The transfer is complete and the data is available, or the request timed out
1686 | if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) {
1687 | requestDone = true;
1688 |
1689 | var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ?
1690 | ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error";
1691 |
1692 | // Make sure that the request was successful or notmodified
1693 | if ( status != "error" ) {
1694 | // Cache Last-Modified header, if ifModified mode.
1695 | var modRes = xml.getResponseHeader("Last-Modified");
1696 | if ( ifModified && modRes ) jQuery.lastModified[url] = modRes;
1697 |
1698 | // If a local callback was specified, fire it
1699 | if ( success ) success( xml, status );
1700 |
1701 | // Fire the global callback
1702 | jQuery.event.trigger( "ajaxSuccess" );
1703 |
1704 | // Otherwise, the request was not successful
1705 | } else {
1706 | // If a local callback was specified, fire it
1707 | if ( error ) error( xml, status );
1708 |
1709 | // Fire the global callback
1710 | jQuery.event.trigger( "ajaxError" );
1711 | }
1712 |
1713 | // The request was completed
1714 | jQuery.event.trigger( "ajaxComplete" );
1715 |
1716 | // Handle the global AJAX counter
1717 | if ( ! --jQuery.active )
1718 | jQuery.event.trigger( "ajaxStop" );
1719 |
1720 | // Process result
1721 | if ( ret ) ret(xml, status);
1722 |
1723 | // Stop memory leaks
1724 | xml.onreadystatechange = function(){};
1725 | xml = null;
1726 |
1727 | }
1728 | };
1729 | xml.onreadystatechange = onreadystatechange;
1730 |
1731 | // Timeout checker
1732 | if(jQuery.timeout > 0)
1733 | setTimeout(function(){
1734 | // Check to see if the request is still happening
1735 | if (xml) {
1736 | // Cancel the request
1737 | xml.abort();
1738 |
1739 | if ( !requestDone ) onreadystatechange( "timeout" );
1740 |
1741 | // Clear from memory
1742 | xml = null;
1743 | }
1744 | }, jQuery.timeout);
1745 |
1746 | // Send the data
1747 | xml.send(data);
1748 | },
1749 |
1750 | // Counter for holding the number of active queries
1751 | active: 0,
1752 |
1753 | // Determines if an XMLHttpRequest was successful or not
1754 | httpSuccess: function(r) {
1755 | try {
1756 | return !r.status && location.protocol == "file:" ||
1757 | ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
1758 | jQuery.browser.safari && r.status == undefined;
1759 | } catch(e){}
1760 |
1761 | return false;
1762 | },
1763 |
1764 | // Determines if an XMLHttpRequest returns NotModified
1765 | httpNotModified: function(xml, url) {
1766 | try {
1767 | var xmlRes = xml.getResponseHeader("Last-Modified");
1768 |
1769 | // Firefox always returns 200. check Last-Modified date
1770 | return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
1771 | jQuery.browser.safari && xml.status == undefined;
1772 | } catch(e){}
1773 |
1774 | return false;
1775 | },
1776 |
1777 | // Get the data out of an XMLHttpRequest.
1778 | // Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
1779 | // otherwise return plain text.
1780 | httpData: function(r,type) {
1781 | var ct = r.getResponseHeader("content-type");
1782 | var data = !type && ct && ct.indexOf("xml") >= 0;
1783 | data = type == "xml" || data ? r.responseXML : r.responseText;
1784 |
1785 | // If the type is "script", eval it
1786 | if ( type == "script" ) eval.call( window, data );
1787 |
1788 | return data;
1789 | },
1790 |
1791 | // Serialize an array of form elements or a set of
1792 | // key/values into a query string
1793 | param: function(a) {
1794 | var s = [];
1795 |
1796 | // If an array was passed in, assume that it is an array
1797 | // of form elements
1798 | if ( a.constructor == Array ) {
1799 | // Serialize the form elements
1800 | for ( var i = 0; i < a.length; i++ )
1801 | s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
1802 |
1803 | // Otherwise, assume that it's an object of key/value pairs
1804 | } else {
1805 | // Serialize the key/values
1806 | for ( var j in a )
1807 | s.push( j + "=" + encodeURIComponent( a[j] ) );
1808 | }
1809 |
1810 | // Return the resulting serialization
1811 | return s.join("&");
1812 | }
1813 |
1814 | });
1815 |
--------------------------------------------------------------------------------
/external/json2.js:
--------------------------------------------------------------------------------
1 | /*
2 | http://www.JSON.org/json2.js
3 | 2010-08-25
4 |
5 | Public Domain.
6 |
7 | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8 |
9 | See http://www.JSON.org/js.html
10 |
11 |
12 | This code should be minified before deployment.
13 | See http://javascript.crockford.com/jsmin.html
14 |
15 | USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16 | NOT CONTROL.
17 |
18 |
19 | This file creates a global JSON object containing two methods: stringify
20 | and parse.
21 |
22 | JSON.stringify(value, replacer, space)
23 | value any JavaScript value, usually an object or array.
24 |
25 | replacer an optional parameter that determines how object
26 | values are stringified for objects. It can be a
27 | function or an array of strings.
28 |
29 | space an optional parameter that specifies the indentation
30 | of nested structures. If it is omitted, the text will
31 | be packed without extra whitespace. If it is a number,
32 | it will specify the number of spaces to indent at each
33 | level. If it is a string (such as '\t' or ' '),
34 | it contains the characters used to indent at each level.
35 |
36 | This method produces a JSON text from a JavaScript value.
37 |
38 | When an object value is found, if the object contains a toJSON
39 | method, its toJSON method will be called and the result will be
40 | stringified. A toJSON method does not serialize: it returns the
41 | value represented by the name/value pair that should be serialized,
42 | or undefined if nothing should be serialized. The toJSON method
43 | will be passed the key associated with the value, and this will be
44 | bound to the value
45 |
46 | For example, this would serialize Dates as ISO strings.
47 |
48 | Date.prototype.toJSON = function (key) {
49 | function f(n) {
50 | // Format integers to have at least two digits.
51 | return n < 10 ? '0' + n : n;
52 | }
53 |
54 | return this.getUTCFullYear() + '-' +
55 | f(this.getUTCMonth() + 1) + '-' +
56 | f(this.getUTCDate()) + 'T' +
57 | f(this.getUTCHours()) + ':' +
58 | f(this.getUTCMinutes()) + ':' +
59 | f(this.getUTCSeconds()) + 'Z';
60 | };
61 |
62 | You can provide an optional replacer method. It will be passed the
63 | key and value of each member, with this bound to the containing
64 | object. The value that is returned from your method will be
65 | serialized. If your method returns undefined, then the member will
66 | be excluded from the serialization.
67 |
68 | If the replacer parameter is an array of strings, then it will be
69 | used to select the members to be serialized. It filters the results
70 | such that only members with keys listed in the replacer array are
71 | stringified.
72 |
73 | Values that do not have JSON representations, such as undefined or
74 | functions, will not be serialized. Such values in objects will be
75 | dropped; in arrays they will be replaced with null. You can use
76 | a replacer function to replace those with JSON values.
77 | JSON.stringify(undefined) returns undefined.
78 |
79 | The optional space parameter produces a stringification of the
80 | value that is filled with line breaks and indentation to make it
81 | easier to read.
82 |
83 | If the space parameter is a non-empty string, then that string will
84 | be used for indentation. If the space parameter is a number, then
85 | the indentation will be that many spaces.
86 |
87 | Example:
88 |
89 | text = JSON.stringify(['e', {pluribus: 'unum'}]);
90 | // text is '["e",{"pluribus":"unum"}]'
91 |
92 |
93 | text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94 | // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95 |
96 | text = JSON.stringify([new Date()], function (key, value) {
97 | return this[key] instanceof Date ?
98 | 'Date(' + this[key] + ')' : value;
99 | });
100 | // text is '["Date(---current time---)"]'
101 |
102 |
103 | JSON.parse(text, reviver)
104 | This method parses a JSON text to produce an object or array.
105 | It can throw a SyntaxError exception.
106 |
107 | The optional reviver parameter is a function that can filter and
108 | transform the results. It receives each of the keys and values,
109 | and its return value is used instead of the original value.
110 | If it returns what it received, then the structure is not modified.
111 | If it returns undefined then the member is deleted.
112 |
113 | Example:
114 |
115 | // Parse the text. Values that look like ISO date strings will
116 | // be converted to Date objects.
117 |
118 | myData = JSON.parse(text, function (key, value) {
119 | var a;
120 | if (typeof value === 'string') {
121 | a =
122 | /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123 | if (a) {
124 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125 | +a[5], +a[6]));
126 | }
127 | }
128 | return value;
129 | });
130 |
131 | myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132 | var d;
133 | if (typeof value === 'string' &&
134 | value.slice(0, 5) === 'Date(' &&
135 | value.slice(-1) === ')') {
136 | d = new Date(value.slice(5, -1));
137 | if (d) {
138 | return d;
139 | }
140 | }
141 | return value;
142 | });
143 |
144 |
145 | This is a reference implementation. You are free to copy, modify, or
146 | redistribute.
147 | */
148 |
149 | /*jslint evil: true, strict: false */
150 |
151 | /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152 | call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154 | lastIndex, length, parse, prototype, push, replace, slice, stringify,
155 | test, toJSON, toString, valueOf
156 | */
157 |
158 |
159 | // Create a JSON object only if one does not already exist. We create the
160 | // methods in a closure to avoid creating global variables.
161 |
162 | if (!this.JSON) {
163 | this.JSON = {};
164 | }
165 |
166 | (function () {
167 |
168 | function f(n) {
169 | // Format integers to have at least two digits.
170 | return n < 10 ? '0' + n : n;
171 | }
172 |
173 | if (typeof Date.prototype.toJSON !== 'function') {
174 |
175 | Date.prototype.toJSON = function (key) {
176 |
177 | return isFinite(this.valueOf()) ?
178 | this.getUTCFullYear() + '-' +
179 | f(this.getUTCMonth() + 1) + '-' +
180 | f(this.getUTCDate()) + 'T' +
181 | f(this.getUTCHours()) + ':' +
182 | f(this.getUTCMinutes()) + ':' +
183 | f(this.getUTCSeconds()) + 'Z' : null;
184 | };
185 |
186 | String.prototype.toJSON =
187 | Number.prototype.toJSON =
188 | Boolean.prototype.toJSON = function (key) {
189 | return this.valueOf();
190 | };
191 | }
192 |
193 | var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
194 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
195 | gap,
196 | indent,
197 | meta = { // table of character substitutions
198 | '\b': '\\b',
199 | '\t': '\\t',
200 | '\n': '\\n',
201 | '\f': '\\f',
202 | '\r': '\\r',
203 | '"' : '\\"',
204 | '\\': '\\\\'
205 | },
206 | rep;
207 |
208 |
209 | function quote(string) {
210 |
211 | // If the string contains no control characters, no quote characters, and no
212 | // backslash characters, then we can safely slap some quotes around it.
213 | // Otherwise we must also replace the offending characters with safe escape
214 | // sequences.
215 |
216 | escapable.lastIndex = 0;
217 | return escapable.test(string) ?
218 | '"' + string.replace(escapable, function (a) {
219 | var c = meta[a];
220 | return typeof c === 'string' ? c :
221 | '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
222 | }) + '"' :
223 | '"' + string + '"';
224 | }
225 |
226 |
227 | function str(key, holder) {
228 |
229 | // Produce a string from holder[key].
230 |
231 | var i, // The loop counter.
232 | k, // The member key.
233 | v, // The member value.
234 | length,
235 | mind = gap,
236 | partial,
237 | value = holder[key];
238 |
239 | // If the value has a toJSON method, call it to obtain a replacement value.
240 |
241 | if (value && typeof value === 'object' &&
242 | typeof value.toJSON === 'function') {
243 | value = value.toJSON(key);
244 | }
245 |
246 | // If we were called with a replacer function, then call the replacer to
247 | // obtain a replacement value.
248 |
249 | if (typeof rep === 'function') {
250 | value = rep.call(holder, key, value);
251 | }
252 |
253 | // What happens next depends on the value's type.
254 |
255 | switch (typeof value) {
256 | case 'string':
257 | return quote(value);
258 |
259 | case 'number':
260 |
261 | // JSON numbers must be finite. Encode non-finite numbers as null.
262 |
263 | return isFinite(value) ? String(value) : 'null';
264 |
265 | case 'boolean':
266 | case 'null':
267 |
268 | // If the value is a boolean or null, convert it to a string. Note:
269 | // typeof null does not produce 'null'. The case is included here in
270 | // the remote chance that this gets fixed someday.
271 |
272 | return String(value);
273 |
274 | // If the type is 'object', we might be dealing with an object or an array or
275 | // null.
276 |
277 | case 'object':
278 |
279 | // Due to a specification blunder in ECMAScript, typeof null is 'object',
280 | // so watch out for that case.
281 |
282 | if (!value) {
283 | return 'null';
284 | }
285 |
286 | // Make an array to hold the partial results of stringifying this object value.
287 |
288 | gap += indent;
289 | partial = [];
290 |
291 | // Is the value an array?
292 |
293 | if (Object.prototype.toString.apply(value) === '[object Array]') {
294 |
295 | // The value is an array. Stringify every element. Use null as a placeholder
296 | // for non-JSON values.
297 |
298 | length = value.length;
299 | for (i = 0; i < length; i += 1) {
300 | partial[i] = str(i, value) || 'null';
301 | }
302 |
303 | // Join all of the elements together, separated with commas, and wrap them in
304 | // brackets.
305 |
306 | v = partial.length === 0 ? '[]' :
307 | gap ? '[\n' + gap +
308 | partial.join(',\n' + gap) + '\n' +
309 | mind + ']' :
310 | '[' + partial.join(',') + ']';
311 | gap = mind;
312 | return v;
313 | }
314 |
315 | // If the replacer is an array, use it to select the members to be stringified.
316 |
317 | if (rep && typeof rep === 'object') {
318 | length = rep.length;
319 | for (i = 0; i < length; i += 1) {
320 | k = rep[i];
321 | if (typeof k === 'string') {
322 | v = str(k, value);
323 | if (v) {
324 | partial.push(quote(k) + (gap ? ': ' : ':') + v);
325 | }
326 | }
327 | }
328 | } else {
329 |
330 | // Otherwise, iterate through all of the keys in the object.
331 |
332 | for (k in value) {
333 | if (Object.hasOwnProperty.call(value, k)) {
334 | v = str(k, value);
335 | if (v) {
336 | partial.push(quote(k) + (gap ? ': ' : ':') + v);
337 | }
338 | }
339 | }
340 | }
341 |
342 | // Join all of the member texts together, separated with commas,
343 | // and wrap them in braces.
344 |
345 | v = partial.length === 0 ? '{}' :
346 | gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
347 | mind + '}' : '{' + partial.join(',') + '}';
348 | gap = mind;
349 | return v;
350 | }
351 | }
352 |
353 | // If the JSON object does not yet have a stringify method, give it one.
354 |
355 | if (typeof JSON.stringify !== 'function') {
356 | JSON.stringify = function (value, replacer, space) {
357 |
358 | // The stringify method takes a value and an optional replacer, and an optional
359 | // space parameter, and returns a JSON text. The replacer can be a function
360 | // that can replace values, or an array of strings that will select the keys.
361 | // A default replacer method can be provided. Use of the space parameter can
362 | // produce text that is more easily readable.
363 |
364 | var i;
365 | gap = '';
366 | indent = '';
367 |
368 | // If the space parameter is a number, make an indent string containing that
369 | // many spaces.
370 |
371 | if (typeof space === 'number') {
372 | for (i = 0; i < space; i += 1) {
373 | indent += ' ';
374 | }
375 |
376 | // If the space parameter is a string, it will be used as the indent string.
377 |
378 | } else if (typeof space === 'string') {
379 | indent = space;
380 | }
381 |
382 | // If there is a replacer, it must be a function or an array.
383 | // Otherwise, throw an error.
384 |
385 | rep = replacer;
386 | if (replacer && typeof replacer !== 'function' &&
387 | (typeof replacer !== 'object' ||
388 | typeof replacer.length !== 'number')) {
389 | throw new Error('JSON.stringify');
390 | }
391 |
392 | // Make a fake root object containing our value under the key of ''.
393 | // Return the result of stringifying the value.
394 |
395 | return str('', {'': value});
396 | };
397 | }
398 |
399 |
400 | // If the JSON object does not yet have a parse method, give it one.
401 |
402 | if (typeof JSON.parse !== 'function') {
403 | JSON.parse = function (text, reviver) {
404 |
405 | // The parse method takes a text and an optional reviver function, and returns
406 | // a JavaScript value if the text is a valid JSON text.
407 |
408 | var j;
409 |
410 | function walk(holder, key) {
411 |
412 | // The walk method is used to recursively walk the resulting structure so
413 | // that modifications can be made.
414 |
415 | var k, v, value = holder[key];
416 | if (value && typeof value === 'object') {
417 | for (k in value) {
418 | if (Object.hasOwnProperty.call(value, k)) {
419 | v = walk(value, k);
420 | if (v !== undefined) {
421 | value[k] = v;
422 | } else {
423 | delete value[k];
424 | }
425 | }
426 | }
427 | }
428 | return reviver.call(holder, key, value);
429 | }
430 |
431 |
432 | // Parsing happens in four stages. In the first stage, we replace certain
433 | // Unicode characters with escape sequences. JavaScript handles many characters
434 | // incorrectly, either silently deleting them, or treating them as line endings.
435 |
436 | text = String(text);
437 | cx.lastIndex = 0;
438 | if (cx.test(text)) {
439 | text = text.replace(cx, function (a) {
440 | return '\\u' +
441 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
442 | });
443 | }
444 |
445 | // In the second stage, we run the text against regular expressions that look
446 | // for non-JSON patterns. We are especially concerned with '()' and 'new'
447 | // because they can cause invocation, and '=' because it can cause mutation.
448 | // But just to be safe, we want to reject all unexpected forms.
449 |
450 | // We split the second stage into 4 regexp operations in order to work around
451 | // crippling inefficiencies in IE's and Safari's regexp engines. First we
452 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
453 | // replace all simple value tokens with ']' characters. Third, we delete all
454 | // open brackets that follow a colon or comma or that begin the text. Finally,
455 | // we look to see that the remaining characters are only whitespace or ']' or
456 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
457 |
458 | if (/^[\],:{}\s]*$/
459 | .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
460 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
461 | .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
462 |
463 | // In the third stage we use the eval function to compile the text into a
464 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
465 | // in JavaScript: it can begin a block or an object literal. We wrap the text
466 | // in parens to eliminate the ambiguity.
467 |
468 | j = eval('(' + text + ')');
469 |
470 | // In the optional fourth stage, we recursively walk the new structure, passing
471 | // each name/value pair to a reviver function for possible transformation.
472 |
473 | return typeof reviver === 'function' ?
474 | walk({'': j}, '') : j;
475 | }
476 |
477 | // If the text is not JSON parseable, then a SyntaxError is thrown.
478 |
479 | throw new SyntaxError('JSON.parse');
480 | };
481 | }
482 | }());
483 |
--------------------------------------------------------------------------------
/external/qunit.css:
--------------------------------------------------------------------------------
1 | /** Font Family and Sizes */
2 |
3 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
4 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
5 | }
6 |
7 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
8 | #qunit-tests { font-size: smaller; }
9 |
10 |
11 | /** Resets */
12 |
13 | #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 |
19 | /** Header */
20 |
21 | #qunit-header {
22 | padding: 0.5em 0 0.5em 1em;
23 |
24 | color: #8699a4;
25 | background-color: #0d3349;
26 |
27 | font-size: 1.5em;
28 | line-height: 1em;
29 | font-weight: normal;
30 |
31 | border-radius: 15px 15px 0 0;
32 | -moz-border-radius: 15px 15px 0 0;
33 | -webkit-border-top-right-radius: 15px;
34 | -webkit-border-top-left-radius: 15px;
35 | }
36 |
37 | #qunit-header a {
38 | text-decoration: none;
39 | color: #c2ccd1;
40 | }
41 |
42 | #qunit-header a:hover,
43 | #qunit-header a:focus {
44 | color: #fff;
45 | }
46 |
47 | #qunit-banner {
48 | height: 5px;
49 | }
50 |
51 | #qunit-testrunner-toolbar {
52 | padding: 0.5em 0 0.5em 2em;
53 | color: #5E740B;
54 | background-color: #eee;
55 | }
56 |
57 | #qunit-userAgent {
58 | padding: 0.5em 0 0.5em 2.5em;
59 | background-color: #2b81af;
60 | color: #fff;
61 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
62 | }
63 |
64 |
65 | /** Tests: Pass/Fail */
66 |
67 | #qunit-tests {
68 | list-style-position: inside;
69 | }
70 |
71 | #qunit-tests li {
72 | padding: 0.4em 0.5em 0.4em 2.5em;
73 | border-bottom: 1px solid #fff;
74 | list-style-position: inside;
75 | }
76 |
77 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
78 | display: none;
79 | }
80 |
81 | #qunit-tests li strong {
82 | cursor: pointer;
83 | }
84 |
85 | #qunit-tests ol {
86 | margin-top: 0.5em;
87 | padding: 0.5em;
88 |
89 | background-color: #fff;
90 |
91 | border-radius: 15px;
92 | -moz-border-radius: 15px;
93 | -webkit-border-radius: 15px;
94 |
95 | box-shadow: inset 0px 2px 13px #999;
96 | -moz-box-shadow: inset 0px 2px 13px #999;
97 | -webkit-box-shadow: inset 0px 2px 13px #999;
98 | }
99 |
100 | #qunit-tests table {
101 | border-collapse: collapse;
102 | margin-top: .2em;
103 | }
104 |
105 | #qunit-tests th {
106 | text-align: right;
107 | vertical-align: top;
108 | padding: 0 .5em 0 0;
109 | }
110 |
111 | #qunit-tests td {
112 | vertical-align: top;
113 | }
114 |
115 | #qunit-tests pre {
116 | margin: 0;
117 | white-space: pre-wrap;
118 | word-wrap: break-word;
119 | }
120 |
121 | #qunit-tests del {
122 | background-color: #e0f2be;
123 | color: #374e0c;
124 | text-decoration: none;
125 | }
126 |
127 | #qunit-tests ins {
128 | background-color: #ffcaca;
129 | color: #500;
130 | text-decoration: none;
131 | }
132 |
133 | /*** Test Counts */
134 |
135 | #qunit-tests b.counts { color: black; }
136 | #qunit-tests b.passed { color: #5E740B; }
137 | #qunit-tests b.failed { color: #710909; }
138 |
139 | #qunit-tests li li {
140 | margin: 0.5em;
141 | padding: 0.4em 0.5em 0.4em 0.5em;
142 | background-color: #fff;
143 | border-bottom: none;
144 | list-style-position: inside;
145 | }
146 |
147 | /*** Passing Styles */
148 |
149 | #qunit-tests li li.pass {
150 | color: #5E740B;
151 | background-color: #fff;
152 | border-left: 26px solid #C6E746;
153 | }
154 |
155 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
156 | #qunit-tests .pass .test-name { color: #366097; }
157 |
158 | #qunit-tests .pass .test-actual,
159 | #qunit-tests .pass .test-expected { color: #999999; }
160 |
161 | #qunit-banner.qunit-pass { background-color: #C6E746; }
162 |
163 | /*** Failing Styles */
164 |
165 | #qunit-tests li li.fail {
166 | color: #710909;
167 | background-color: #fff;
168 | border-left: 26px solid #EE5757;
169 | }
170 |
171 | #qunit-tests > li:last-child {
172 | border-radius: 0 0 15px 15px;
173 | -moz-border-radius: 0 0 15px 15px;
174 | -webkit-border-bottom-right-radius: 15px;
175 | -webkit-border-bottom-left-radius: 15px;
176 | }
177 |
178 | #qunit-tests .fail { color: #000000; background-color: #EE5757; }
179 | #qunit-tests .fail .test-name,
180 | #qunit-tests .fail .module-name { color: #000000; }
181 |
182 | #qunit-tests .fail .test-actual { color: #EE5757; }
183 | #qunit-tests .fail .test-expected { color: green; }
184 |
185 | #qunit-banner.qunit-fail { background-color: #EE5757; }
186 |
187 |
188 | /** Result */
189 |
190 | #qunit-testresult {
191 | padding: 0.5em 0.5em 0.5em 2.5em;
192 |
193 | color: #2b81af;
194 | background-color: #D2E0E6;
195 |
196 | border-bottom: 1px solid white;
197 | }
198 |
199 | /** Fixture */
200 |
201 | #qunit-fixture {
202 | position: absolute;
203 | top: -10000px;
204 | left: -10000px;
205 | }
206 |
--------------------------------------------------------------------------------
/external/qunit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * QUnit - A JavaScript Unit Testing Framework
3 | *
4 | * http://docs.jquery.com/QUnit
5 | *
6 | * Copyright (c) 2011 John Resig, Jörn Zaefferer
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * or GPL (GPL-LICENSE.txt) licenses.
9 | */
10 |
11 | (function(window) {
12 |
13 | var defined = {
14 | setTimeout: typeof window.setTimeout !== "undefined",
15 | sessionStorage: (function() {
16 | try {
17 | return !!sessionStorage.getItem;
18 | } catch(e){
19 | return false;
20 | }
21 | })()
22 | };
23 |
24 | var testId = 0;
25 |
26 | var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
27 | this.name = name;
28 | this.testName = testName;
29 | this.expected = expected;
30 | this.testEnvironmentArg = testEnvironmentArg;
31 | this.async = async;
32 | this.callback = callback;
33 | this.assertions = [];
34 | };
35 | Test.prototype = {
36 | init: function() {
37 | var tests = id("qunit-tests");
38 | if (tests) {
39 | var b = document.createElement("strong");
40 | b.innerHTML = "Running " + this.name;
41 | var li = document.createElement("li");
42 | li.appendChild( b );
43 | li.className = "running";
44 | li.id = this.id = "test-output" + testId++;
45 | tests.appendChild( li );
46 | }
47 | },
48 | setup: function() {
49 | if (this.module != config.previousModule) {
50 | if ( config.previousModule ) {
51 | QUnit.moduleDone( {
52 | name: config.previousModule,
53 | failed: config.moduleStats.bad,
54 | passed: config.moduleStats.all - config.moduleStats.bad,
55 | total: config.moduleStats.all
56 | } );
57 | }
58 | config.previousModule = this.module;
59 | config.moduleStats = { all: 0, bad: 0 };
60 | QUnit.moduleStart( {
61 | name: this.module
62 | } );
63 | }
64 |
65 | config.current = this;
66 | this.testEnvironment = extend({
67 | setup: function() {},
68 | teardown: function() {}
69 | }, this.moduleTestEnvironment);
70 | if (this.testEnvironmentArg) {
71 | extend(this.testEnvironment, this.testEnvironmentArg);
72 | }
73 |
74 | QUnit.testStart( {
75 | name: this.testName
76 | } );
77 |
78 | // allow utility functions to access the current test environment
79 | // TODO why??
80 | QUnit.current_testEnvironment = this.testEnvironment;
81 |
82 | try {
83 | if ( !config.pollution ) {
84 | saveGlobal();
85 | }
86 |
87 | this.testEnvironment.setup.call(this.testEnvironment);
88 | } catch(e) {
89 | QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message );
90 | }
91 | },
92 | run: function() {
93 | if ( this.async ) {
94 | QUnit.stop();
95 | }
96 |
97 | if ( config.notrycatch ) {
98 | this.callback.call(this.testEnvironment);
99 | return;
100 | }
101 | try {
102 | this.callback.call(this.testEnvironment);
103 | } catch(e) {
104 | fail("Test " + this.testName + " died, exception and test follows", e, this.callback);
105 | QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) );
106 | // else next test will carry the responsibility
107 | saveGlobal();
108 |
109 | // Restart the tests if they're blocking
110 | if ( config.blocking ) {
111 | start();
112 | }
113 | }
114 | },
115 | teardown: function() {
116 | try {
117 | checkPollution();
118 | this.testEnvironment.teardown.call(this.testEnvironment);
119 | } catch(e) {
120 | QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message );
121 | }
122 | },
123 | finish: function() {
124 | if ( this.expected && this.expected != this.assertions.length ) {
125 | QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
126 | }
127 |
128 | var good = 0, bad = 0,
129 | tests = id("qunit-tests");
130 |
131 | config.stats.all += this.assertions.length;
132 | config.moduleStats.all += this.assertions.length;
133 |
134 | if ( tests ) {
135 | var ol = document.createElement("ol");
136 |
137 | for ( var i = 0; i < this.assertions.length; i++ ) {
138 | var assertion = this.assertions[i];
139 |
140 | var li = document.createElement("li");
141 | li.className = assertion.result ? "pass" : "fail";
142 | li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed");
143 | ol.appendChild( li );
144 |
145 | if ( assertion.result ) {
146 | good++;
147 | } else {
148 | bad++;
149 | config.stats.bad++;
150 | config.moduleStats.bad++;
151 | }
152 | }
153 |
154 | // store result when possible
155 | QUnit.config.reorder && defined.sessionStorage && sessionStorage.setItem("qunit-" + this.testName, bad);
156 |
157 | if (bad == 0) {
158 | ol.style.display = "none";
159 | }
160 |
161 | var b = document.createElement("strong");
162 | b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")";
163 |
164 | addEvent(b, "click", function() {
165 | var next = b.nextSibling, display = next.style.display;
166 | next.style.display = display === "none" ? "block" : "none";
167 | });
168 |
169 | addEvent(b, "dblclick", function(e) {
170 | var target = e && e.target ? e.target : window.event.srcElement;
171 | if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
172 | target = target.parentNode;
173 | }
174 | if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
175 | window.location = QUnit.url({ filter: getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, "") });
176 | }
177 | });
178 |
179 | var li = id(this.id);
180 | li.className = bad ? "fail" : "pass";
181 | li.removeChild( li.firstChild );
182 | li.appendChild( b );
183 | li.appendChild( ol );
184 |
185 | } else {
186 | for ( var i = 0; i < this.assertions.length; i++ ) {
187 | if ( !this.assertions[i].result ) {
188 | bad++;
189 | config.stats.bad++;
190 | config.moduleStats.bad++;
191 | }
192 | }
193 | }
194 |
195 | try {
196 | QUnit.reset();
197 | } catch(e) {
198 | fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset);
199 | }
200 |
201 | QUnit.testDone( {
202 | name: this.testName,
203 | failed: bad,
204 | passed: this.assertions.length - bad,
205 | total: this.assertions.length
206 | } );
207 | },
208 |
209 | queue: function() {
210 | var test = this;
211 | synchronize(function() {
212 | test.init();
213 | });
214 | function run() {
215 | // each of these can by async
216 | synchronize(function() {
217 | test.setup();
218 | });
219 | synchronize(function() {
220 | test.run();
221 | });
222 | synchronize(function() {
223 | test.teardown();
224 | });
225 | synchronize(function() {
226 | test.finish();
227 | });
228 | }
229 | // defer when previous test run passed, if storage is available
230 | var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.testName);
231 | if (bad) {
232 | run();
233 | } else {
234 | synchronize(run);
235 | };
236 | }
237 |
238 | };
239 |
240 | var QUnit = {
241 |
242 | // call on start of module test to prepend name to all tests
243 | module: function(name, testEnvironment) {
244 | config.currentModule = name;
245 | config.currentModuleTestEnviroment = testEnvironment;
246 | },
247 |
248 | asyncTest: function(testName, expected, callback) {
249 | if ( arguments.length === 2 ) {
250 | callback = expected;
251 | expected = 0;
252 | }
253 |
254 | QUnit.test(testName, expected, callback, true);
255 | },
256 |
257 | test: function(testName, expected, callback, async) {
258 | var name = '' + testName + '', testEnvironmentArg;
259 |
260 | if ( arguments.length === 2 ) {
261 | callback = expected;
262 | expected = null;
263 | }
264 | // is 2nd argument a testEnvironment?
265 | if ( expected && typeof expected === 'object') {
266 | testEnvironmentArg = expected;
267 | expected = null;
268 | }
269 |
270 | if ( config.currentModule ) {
271 | name = '' + config.currentModule + ": " + name;
272 | }
273 |
274 | if ( !validTest(config.currentModule + ": " + testName) ) {
275 | return;
276 | }
277 |
278 | var test = new Test(name, testName, expected, testEnvironmentArg, async, callback);
279 | test.module = config.currentModule;
280 | test.moduleTestEnvironment = config.currentModuleTestEnviroment;
281 | test.queue();
282 | },
283 |
284 | /**
285 | * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
286 | */
287 | expect: function(asserts) {
288 | config.current.expected = asserts;
289 | },
290 |
291 | /**
292 | * Asserts true.
293 | * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
294 | */
295 | ok: function(a, msg) {
296 | a = !!a;
297 | var details = {
298 | result: a,
299 | message: msg
300 | };
301 | msg = escapeHtml(msg);
302 | QUnit.log(details);
303 | config.current.assertions.push({
304 | result: a,
305 | message: msg
306 | });
307 | },
308 |
309 | /**
310 | * Checks that the first two arguments are equal, with an optional message.
311 | * Prints out both actual and expected values.
312 | *
313 | * Prefered to ok( actual == expected, message )
314 | *
315 | * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
316 | *
317 | * @param Object actual
318 | * @param Object expected
319 | * @param String message (optional)
320 | */
321 | equal: function(actual, expected, message) {
322 | QUnit.push(expected == actual, actual, expected, message);
323 | },
324 |
325 | notEqual: function(actual, expected, message) {
326 | QUnit.push(expected != actual, actual, expected, message);
327 | },
328 |
329 | deepEqual: function(actual, expected, message) {
330 | QUnit.push(QUnit.equiv(actual, expected), actual, expected, message);
331 | },
332 |
333 | notDeepEqual: function(actual, expected, message) {
334 | QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);
335 | },
336 |
337 | strictEqual: function(actual, expected, message) {
338 | QUnit.push(expected === actual, actual, expected, message);
339 | },
340 |
341 | notStrictEqual: function(actual, expected, message) {
342 | QUnit.push(expected !== actual, actual, expected, message);
343 | },
344 |
345 | raises: function(block, expected, message) {
346 | var actual, ok = false;
347 |
348 | if (typeof expected === 'string') {
349 | message = expected;
350 | expected = null;
351 | }
352 |
353 | try {
354 | block();
355 | } catch (e) {
356 | actual = e;
357 | }
358 |
359 | if (actual) {
360 | // we don't want to validate thrown error
361 | if (!expected) {
362 | ok = true;
363 | // expected is a regexp
364 | } else if (QUnit.objectType(expected) === "regexp") {
365 | ok = expected.test(actual);
366 | // expected is a constructor
367 | } else if (actual instanceof expected) {
368 | ok = true;
369 | // expected is a validation function which returns true is validation passed
370 | } else if (expected.call({}, actual) === true) {
371 | ok = true;
372 | }
373 | }
374 |
375 | QUnit.ok(ok, message);
376 | },
377 |
378 | start: function() {
379 | config.semaphore--;
380 | if (config.semaphore > 0) {
381 | // don't start until equal number of stop-calls
382 | return;
383 | }
384 | if (config.semaphore < 0) {
385 | // ignore if start is called more often then stop
386 | config.semaphore = 0;
387 | }
388 | // A slight delay, to avoid any current callbacks
389 | if ( defined.setTimeout ) {
390 | window.setTimeout(function() {
391 | if ( config.timeout ) {
392 | clearTimeout(config.timeout);
393 | }
394 |
395 | config.blocking = false;
396 | process();
397 | }, 13);
398 | } else {
399 | config.blocking = false;
400 | process();
401 | }
402 | },
403 |
404 | stop: function(timeout) {
405 | config.semaphore++;
406 | config.blocking = true;
407 |
408 | if ( timeout && defined.setTimeout ) {
409 | clearTimeout(config.timeout);
410 | config.timeout = window.setTimeout(function() {
411 | QUnit.ok( false, "Test timed out" );
412 | QUnit.start();
413 | }, timeout);
414 | }
415 | },
416 |
417 | url: function( params ) {
418 | params = extend( extend( {}, QUnit.urlParams ), params );
419 | var querystring = "?",
420 | key;
421 | for ( key in params ) {
422 | querystring += encodeURIComponent( key ) + "=" +
423 | encodeURIComponent( params[ key ] ) + "&";
424 | }
425 | return window.location.pathname + querystring.slice( 0, -1 );
426 | }
427 | };
428 |
429 | // Backwards compatibility, deprecated
430 | QUnit.equals = QUnit.equal;
431 | QUnit.same = QUnit.deepEqual;
432 |
433 | // Maintain internal state
434 | var config = {
435 | // The queue of tests to run
436 | queue: [],
437 |
438 | // block until document ready
439 | blocking: true,
440 |
441 | // by default, run previously failed tests first
442 | // very useful in combination with "Hide passed tests" checked
443 | reorder: true,
444 |
445 | noglobals: false,
446 | notrycatch: false
447 | };
448 |
449 | // Load paramaters
450 | (function() {
451 | var location = window.location || { search: "", protocol: "file:" },
452 | params = location.search.slice( 1 ).split( "&" ),
453 | length = params.length,
454 | urlParams = {},
455 | current;
456 |
457 | if ( params[ 0 ] ) {
458 | for ( var i = 0; i < length; i++ ) {
459 | current = params[ i ].split( "=" );
460 | current[ 0 ] = decodeURIComponent( current[ 0 ] );
461 | // allow just a key to turn on a flag, e.g., test.html?noglobals
462 | current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
463 | urlParams[ current[ 0 ] ] = current[ 1 ];
464 | if ( current[ 0 ] in config ) {
465 | config[ current[ 0 ] ] = current[ 1 ];
466 | }
467 | }
468 | }
469 |
470 | QUnit.urlParams = urlParams;
471 | config.filter = urlParams.filter;
472 |
473 | // Figure out if we're running the tests from a server or not
474 | QUnit.isLocal = !!(location.protocol === 'file:');
475 | })();
476 |
477 | // Expose the API as global variables, unless an 'exports'
478 | // object exists, in that case we assume we're in CommonJS
479 | if ( typeof exports === "undefined" || typeof require === "undefined" ) {
480 | extend(window, QUnit);
481 | window.QUnit = QUnit;
482 | } else {
483 | extend(exports, QUnit);
484 | exports.QUnit = QUnit;
485 | }
486 |
487 | // define these after exposing globals to keep them in these QUnit namespace only
488 | extend(QUnit, {
489 | config: config,
490 |
491 | // Initialize the configuration options
492 | init: function() {
493 | extend(config, {
494 | stats: { all: 0, bad: 0 },
495 | moduleStats: { all: 0, bad: 0 },
496 | started: +new Date,
497 | updateRate: 1000,
498 | blocking: false,
499 | autostart: true,
500 | autorun: false,
501 | filter: "",
502 | queue: [],
503 | semaphore: 0
504 | });
505 |
506 | var tests = id( "qunit-tests" ),
507 | banner = id( "qunit-banner" ),
508 | result = id( "qunit-testresult" );
509 |
510 | if ( tests ) {
511 | tests.innerHTML = "";
512 | }
513 |
514 | if ( banner ) {
515 | banner.className = "";
516 | }
517 |
518 | if ( result ) {
519 | result.parentNode.removeChild( result );
520 | }
521 |
522 | if ( tests ) {
523 | result = document.createElement( "p" );
524 | result.id = "qunit-testresult";
525 | result.className = "result";
526 | tests.parentNode.insertBefore( result, tests );
527 | result.innerHTML = 'Running... ';
528 | }
529 | },
530 |
531 | /**
532 | * Resets the test setup. Useful for tests that modify the DOM.
533 | *
534 | * If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
535 | */
536 | reset: function() {
537 | if ( window.jQuery ) {
538 | jQuery( "#main, #qunit-fixture" ).html( config.fixture );
539 | } else {
540 | var main = id( 'main' ) || id( 'qunit-fixture' );
541 | if ( main ) {
542 | main.innerHTML = config.fixture;
543 | }
544 | }
545 | },
546 |
547 | /**
548 | * Trigger an event on an element.
549 | *
550 | * @example triggerEvent( document.body, "click" );
551 | *
552 | * @param DOMElement elem
553 | * @param String type
554 | */
555 | triggerEvent: function( elem, type, event ) {
556 | if ( document.createEvent ) {
557 | event = document.createEvent("MouseEvents");
558 | event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
559 | 0, 0, 0, 0, 0, false, false, false, false, 0, null);
560 | elem.dispatchEvent( event );
561 |
562 | } else if ( elem.fireEvent ) {
563 | elem.fireEvent("on"+type);
564 | }
565 | },
566 |
567 | // Safe object type checking
568 | is: function( type, obj ) {
569 | return QUnit.objectType( obj ) == type;
570 | },
571 |
572 | objectType: function( obj ) {
573 | if (typeof obj === "undefined") {
574 | return "undefined";
575 |
576 | // consider: typeof null === object
577 | }
578 | if (obj === null) {
579 | return "null";
580 | }
581 |
582 | var type = Object.prototype.toString.call( obj )
583 | .match(/^\[object\s(.*)\]$/)[1] || '';
584 |
585 | switch (type) {
586 | case 'Number':
587 | if (isNaN(obj)) {
588 | return "nan";
589 | } else {
590 | return "number";
591 | }
592 | case 'String':
593 | case 'Boolean':
594 | case 'Array':
595 | case 'Date':
596 | case 'RegExp':
597 | case 'Function':
598 | return type.toLowerCase();
599 | }
600 | if (typeof obj === "object") {
601 | return "object";
602 | }
603 | return undefined;
604 | },
605 |
606 | push: function(result, actual, expected, message) {
607 | var details = {
608 | result: result,
609 | message: message,
610 | actual: actual,
611 | expected: expected
612 | };
613 |
614 | message = escapeHtml(message) || (result ? "okay" : "failed");
615 | message = '' + message + "";
616 | expected = escapeHtml(QUnit.jsDump.parse(expected));
617 | actual = escapeHtml(QUnit.jsDump.parse(actual));
618 | var output = message + '