PageSourceSearch

https://www.piccom.org/assets/application.js

js piccom.org collected 2026-10-02 04:44:17 UTC 560,130 bytes, 19,042 lines download raw bytes

1/*!
2 * jQuery JavaScript Library v1.7.2
3 * http://jquery.com/
4 *
5 * Copyright 2011, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
8 *
9 * Includes Sizzle.js
10 * http://sizzlejs.com/
11 * Copyright 2011, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Wed Mar 21 12:46:34 2012 -0700
15 */
16
17(function( window, undefined ) {
18
19// Use the correct document accordingly with window argument (sandbox)
20var document = window.document,
21	navigator = window.navigator,
22	location = window.location;
23var jQuery = (function() {
24
25// Define a local copy of jQuery
26var jQuery = function( selector, context ) {
27		// The jQuery object is actually just the init constructor 'enhanced'
28		return new jQuery.fn.init( selector, context, rootjQuery );
29	},
30
31	// Map over jQuery in case of overwrite
32	_jQuery = window.jQuery,
33
34	// Map over the $ in case of overwrite
35	_$ = window.$,
36
37	// A central reference to the root jQuery(document)
38	rootjQuery,
39
40	// A simple way to check for HTML strings or ID strings
41	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
42	quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
43
44	// Check if a string has a non-whitespace character in it
45	rnotwhite = /\S/,
46
47	// Used for trimming whitespace
48	trimLeft = /^\s+/,
49	trimRight = /\s+$/,
50
51	// Match a standalone tag
52	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
53
54	// JSON RegExp
55	rvalidchars = /^[\],:{}\s]*$/,
56	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
57	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
58	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
59
60	// Useragent RegExp
61	rwebkit = /(webkit)[ \/]([\w.]+)/,
62	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
63	rmsie = /(msie) ([\w.]+)/,
64	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
65
66	// Matches dashed string for camelizing
67	rdashAlpha = /-([a-z]|[0-9])/ig,
68	rmsPrefix = /^-ms-/,
69
70	// Used by jQuery.camelCase as callback to replace()
71	fcamelCase = function( all, letter ) {
72		return ( letter + "" ).toUpperCase();
73	},
74
75	// Keep a UserAgent string for use with jQuery.browser
76	userAgent = navigator.userAgent,
77
78	// For matching the engine and version of the browser
79	browserMatch,
80
81	// The deferred used on DOM ready
82	readyList,
83
84	// The ready event handler
85	DOMContentLoaded,
86
87	// Save a reference to some core methods
88	toString = Object.prototype.toString,
89	hasOwn = Object.prototype.hasOwnProperty,
90	push = Array.prototype.push,
91	slice = Array.prototype.slice,
92	trim = String.prototype.trim,
93	indexOf = Array.prototype.indexOf,
94
95	// [[Class]] -> type pairs
96	class2type = {};
97
98jQuery.fn = jQuery.prototype = {
99	constructor: jQuery,
100	init: function( selector, context, rootjQuery ) {
101		var match, elem, ret, doc;
102
103		// Handle $(""), $(null), or $(undefined)
104		if ( !selector ) {
105			return this;
106		}
107
108		// Handle $(DOMElement)
109		if ( selector.nodeType ) {
110			this.context = this[0] = selector;
111			this.length = 1;
112			return this;
113		}
114
115		// The body element only exists once, optimize finding it
116		if ( selector === "body" && !context && document.body ) {
117			this.context = document;
118			this[0] = document.body;
119			this.selector = selector;
120			this.length = 1;
121			return this;
122		}
123
124		// Handle HTML strings
125		if ( typeof selector === "string" ) {
126			// Are we dealing with HTML string or an ID?
127			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
128				// Assume that strings that start and end with <> are HTML and skip the regex check
129				match = [ null, selector, null ];
130
131			} else {
132				match = quickExpr.exec( selector );
133			}
134
135			// Verify a match, and that no context was specified for #id
136			if ( match && (match[1] || !context) ) {
137
138				// HANDLE: $(html) -> $(array)
139				if ( match[1] ) {
140					context = context instanceof jQuery ? context[0] : context;
141					doc = ( context ? context.ownerDocument || context : document );
142
143					// If a single string is passed in and it's a single tag
144					// just do a createElement and skip the rest
145					ret = rsingleTag.exec( selector );
146
147					if ( ret ) {
148						if ( jQuery.isPlainObject( context ) ) {
149							selector = [ document.createElement( ret[1] ) ];
150							jQuery.fn.attr.call( selector, context, true );
151
152						} else {
153							selector = [ doc.createElement( ret[1] ) ];
154						}
155
156					} else {
157						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
158						selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
159					}
160
161					return jQuery.merge( this, selector );
162
163				// HANDLE: $("#id")
164				} else {
165					elem = document.getElementById( match[2] );
166
167					// Check parentNode to catch when Blackberry 4.6 returns
168					// nodes that are no longer in the document #6963
169					if ( elem && elem.parentNode ) {
170						// Handle the case where IE and Opera return items
171						// by name instead of ID
172						if ( elem.id !== match[2] ) {
173							return rootjQuery.find( selector );
174						}
175
176						// Otherwise, we inject the element directly into the jQuery object
177						this.length = 1;
178						this[0] = elem;
179					}
180
181					this.context = document;
182					this.selector = selector;
183					return this;
184				}
185
186			// HANDLE: $(expr, $(...))
187			} else if ( !context || context.jquery ) {
188				return ( context || rootjQuery ).find( selector );
189
190			// HANDLE: $(expr, context)
191			// (which is just equivalent to: $(context).find(expr)
192			} else {
193				return this.constructor( context ).find( selector );
194			}
195
196		// HANDLE: $(function)
197		// Shortcut for document ready
198		} else if ( jQuery.isFunction( selector ) ) {
199			return rootjQuery.ready( selector );
200		}
201
202		if ( selector.selector !== undefined ) {
203			this.selector = selector.selector;
204			this.context = selector.context;
205		}
206
207		return jQuery.makeArray( selector, this );
208	},
209
210	// Start with an empty selector
211	selector: "",
212
213	// The current version of jQuery being used
214	jquery: "1.7.2",
215
216	// The default length of a jQuery object is 0
217	length: 0,
218
219	// The number of elements contained in the matched element set
220	size: function() {
221		return this.length;
222	},
223
224	toArray: function() {
225		return slice.call( this, 0 );
226	},
227
228	// Get the Nth element in the matched element set OR
229	// Get the whole matched element set as a clean array
230	get: function( num ) {
231		return num == null ?
232
233			// Return a 'clean' array
234			this.toArray() :
235
236			// Return just the object
237			( num < 0 ? this[ this.length + num ] : this[ num ] );
238	},
239
240	// Take an array of elements and push it onto the stack
241	// (returning the new matched element set)
242	pushStack: function( elems, name, selector ) {
243		// Build a new jQuery matched element set
244		var ret = this.constructor();
245
246		if ( jQuery.isArray( elems ) ) {
247			push.apply( ret, elems );
248
249		} else {
250			jQuery.merge( ret, elems );
251		}
252
253		// Add the old object onto the stack (as a reference)
vendor: 4,209 bytes, lines 254-434
254		ret.prevObject = this;
255
256		ret.context = this.context;
257
258		if ( name === "find" ) {
259			ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
260		} else if ( name ) {
261			ret.selector = this.selector + "." + name + "(" + selector + ")";
262		}
263
264		// Return the newly-formed element set
265		return ret;
266	},
267
268	// Execute a callback for every element in the matched set.
269	// (You can seed the arguments with an array of args, but this is
270	// only used internally.)
271	each: function( callback, args ) {
272		return jQuery.each( this, callback, args );
273	},
274
275	ready: function( fn ) {
276		// Attach the listeners
277		jQuery.bindReady();
278
279		// Add the callback
280		readyList.add( fn );
281
282		return this;
283	},
284
285	eq: function( i ) {
286		i = +i;
287		return i === -1 ?
288			this.slice( i ) :
289			this.slice( i, i + 1 );
290	},
291
292	first: function() {
293		return this.eq( 0 );
294	},
295
296	last: function() {
297		return this.eq( -1 );
298	},
299
300	slice: function() {
301		return this.pushStack( slice.apply( this, arguments ),
302			"slice", slice.call(arguments).join(",") );
303	},
304
305	map: function( callback ) {
306		return this.pushStack( jQuery.map(this, function( elem, i ) {
307			return callback.call( elem, i, elem );
308		}));
309	},
310
311	end: function() {
312		return this.prevObject || this.constructor(null);
313	},
314
315	// For internal use only.
316	// Behaves like an Array's method, not like a jQuery method.
317	push: push,
318	sort: [].sort,
319	splice: [].splice
320};
321
322// Give the init function the jQuery prototype for later instantiation
323jQuery.fn.init.prototype = jQuery.fn;
324
325jQuery.extend = jQuery.fn.extend = function() {
326	var options, name, src, copy, copyIsArray, clone,
327		target = arguments[0] || {},
328		i = 1,
329		length = arguments.length,
330		deep = false;
331
332	// Handle a deep copy situation
333	if ( typeof target === "boolean" ) {
334		deep = target;
335		target = arguments[1] || {};
336		// skip the boolean and the target
337		i = 2;
338	}
339
340	// Handle case when target is a string or something (possible in deep copy)
341	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
342		target = {};
343	}
344
345	// extend jQuery itself if only one argument is passed
346	if ( length === i ) {
347		target = this;
348		--i;
349	}
350
351	for ( ; i < length; i++ ) {
352		// Only deal with non-null/undefined values
353		if ( (options = arguments[ i ]) != null ) {
354			// Extend the base object
355			for ( name in options ) {
356				src = target[ name ];
357				copy = options[ name ];
358
359				// Prevent never-ending loop
360				if ( target === copy ) {
361					continue;
362				}
363
364				// Recurse if we're merging plain objects or arrays
365				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
366					if ( copyIsArray ) {
367						copyIsArray = false;
368						clone = src && jQuery.isArray(src) ? src : [];
369
370					} else {
371						clone = src && jQuery.isPlainObject(src) ? src : {};
372					}
373
374					// Never move original objects, clone them
375					target[ name ] = jQuery.extend( deep, clone, copy );
376
377				// Don't bring in undefined values
378				} else if ( copy !== undefined ) {
379					target[ name ] = copy;
380				}
381			}
382		}
383	}
384
385	// Return the modified object
386	return target;
387};
388
389jQuery.extend({
390	noConflict: function( deep ) {
391		if ( window.$ === jQuery ) {
392			window.$ = _$;
393		}
394
395		if ( deep && window.jQuery === jQuery ) {
396			window.jQuery = _jQuery;
397		}
398
399		return jQuery;
400	},
401
402	// Is the DOM ready to be used? Set to true once it occurs.
403	isReady: false,
404
405	// A counter to track how many items to wait for before
406	// the ready event fires. See #6781
407	readyWait: 1,
408
409	// Hold (or release) the ready event
410	holdReady: function( hold ) {
411		if ( hold ) {
412			jQuery.readyWait++;
413		} else {
414			jQuery.ready( true );
415		}
416	},
417
418	// Handle when the DOM is ready
419	ready: function( wait ) {
420		// Either a released hold or an DOMready/load event and not yet ready
421		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
422			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
423			if ( !document.body ) {
424				return setTimeout( jQuery.ready, 1 );
425			}
426
427			// Remember that the DOM is ready
428			jQuery.isReady = true;
429
430			// If a normal DOM Ready event fired, decrement, and wait if need be
431			if ( wait !== true && --jQuery.readyWait > 0 ) {
432				return;
433			}
434
435			// If there are functions bound, to execute
436			readyList.fireWith( document, [ jQuery ] );
437
438			// Trigger any bound ready events
439			if ( jQuery.fn.trigger ) {
440				jQuery( document ).trigger( "ready" ).off( "ready" );
441			}
442		}
443	},
444
445	bindReady: function() {
446		if ( readyList ) {
447			return;
448		}
449
450		readyList = jQuery.Callbacks( "once memory" );
451
452		// Catch cases where $(document).ready() is called after the
453		// browser event has already occurred.
454		if ( document.readyState === "complete" ) {
455			// Handle it asynchronously to allow scripts the opportunity to delay ready
456			return setTimeout( jQuery.ready, 1 );
457		}
458
459		// Mozilla, Opera and webkit nightlies currently support this event
460		if ( document.addEventListener ) {
461			// Use the handy event callback
462			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
463
464			// A fallback to window.onload, that will always work
465			window.addEventListener( "load", jQuery.ready, false );
466
467		// If IE event model is used
468		} else if ( document.attachEvent ) {
469			// ensure firing before onload,
470			// maybe late but safe also for iframes
471			document.attachEvent( "onreadystatechange", DOMContentLoaded );
472
473			// A fallback to window.onload, that will always work
474			window.attachEvent( "onload", jQuery.ready );
475
476			// If IE and not a frame
477			// continually check to see if the document is ready
478			var toplevel = false;
479
480			try {
481				toplevel = window.frameElement == null;
482			} catch(e) {}
483
484			if ( document.documentElement.doScroll && toplevel ) {
485				doScrollCheck();
486			}
487		}
488	},
489
490	// See test/unit/core.js for details concerning isFunction.
491	// Since version 1.3, DOM methods and functions like alert
492	// aren't supported. They return false on IE (#2968).
493	isFunction: function( obj ) {
494		return jQuery.type(obj) === "function";
495	},
496
497	isArray: Array.isArray || function( obj ) {
498		return jQuery.type(obj) === "array";
499	},
500
501	isWindow: function( obj ) {
502		return obj != null && obj == obj.window;
503	},
504
505	isNumeric: function( obj ) {
506		return !isNaN( parseFloat(obj) ) && isFinite( obj );
507	},
508
509	type: function( obj ) {
510		return obj == null ?
511			String( obj ) :
512			class2type[ toString.call(obj) ] || "object";
513	},
514
515	isPlainObject: function( obj ) {
516		// Must be an Object.
517		// Because of IE, we also have to check the presence of the constructor property.
518		// Make sure that DOM nodes and window objects don't pass through, as well
519		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
520			return false;
521		}
522
523		try {
524			// Not own constructor property must be Object
525			if ( obj.constructor &&
526				!hasOwn.call(obj, "constructor") &&
527				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
528				return false;
529			}
530		} catch ( e ) {
531			// IE8,9 Will throw exceptions on certain host objects #9897
532			return false;
533		}
534
535		// Own properties are enumerated firstly, so to speed up,
536		// if last one is own, then all properties are own.
537
538		var key;
539		for ( key in obj ) {}
540
541		return key === undefined || hasOwn.call( obj, key );
542	},
543
544	isEmptyObject: function( obj ) {
545		for ( var name in obj ) {
546			return false;
547		}
548		return true;
549	},
550
551	error: function( msg ) {
552		throw new Error( msg );
553	},
554
555	parseJSON: function( data ) {
556		if ( typeof data !== "string" || !data ) {
557			return null;
558		}
559
560		// Make sure leading/trailing whitespace is removed (IE can't handle it)
561		data = jQuery.trim( data );
562
563		// Attempt to parse using the native JSON parser first
564		if ( window.JSON && window.JSON.parse ) {
565			return window.JSON.parse( data );
566		}
567
568		// Make sure the incoming data is actual JSON
569		// Logic borrowed from http://json.org/json2.js
570		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
571			.replace( rvalidtokens, "]" )
572			.replace( rvalidbraces, "")) ) {
573
574			return ( new Function( "return " + data ) )();
575
576		}
577		jQuery.error( "Invalid JSON: " + data );
578	},
579
580	// Cross-browser xml parsing
581	parseXML: function( data ) {
582		if ( typeof data !== "string" || !data ) {
583			return null;
584		}
585		var xml, tmp;
586		try {
587			if ( window.DOMParser ) { // Standard
588				tmp = new DOMParser();
589				xml = tmp.parseFromString( data , "text/xml" );
590			} else { // IE
591				xml = new ActiveXObject( "Microsoft.XMLDOM" );
592				xml.async = "false";
593				xml.loadXML( data );
594			}
595		} catch( e ) {
596			xml = undefined;
597		}
598		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
599			jQuery.error( "Invalid XML: " + data );
600		}
601		return xml;
602	},
603
604	noop: function() {},
605
606	// Evaluates a script in a global context
607	// Workarounds based on findings by Jim Driscoll
608	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
609	globalEval: function( data ) {
610		if ( data && rnotwhite.test( data ) ) {
611			// We use execScript on Internet Explorer
612			// We use an anonymous function so that context is window
613			// rather than jQuery in Firefox
614			( window.execScript || function( data ) {
615				window[ "eval" ].call( window, data );
616			} )( data );
617		}
618	},
619
620	// Convert dashed to camelCase; used by the css and data modules
621	// Microsoft forgot to hump their vendor prefix (#9572)
622	camelCase: function( string ) {
623		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
624	},
625
vendor: 7,502 bytes, lines 626-936
626	nodeName: function( elem, name ) {
627		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
628	},
629
630	// args is for internal usage only
631	each: function( object, callback, args ) {
632		var name, i = 0,
633			length = object.length,
634			isObj = length === undefined || jQuery.isFunction( object );
635
636		if ( args ) {
637			if ( isObj ) {
638				for ( name in object ) {
639					if ( callback.apply( object[ name ], args ) === false ) {
640						break;
641					}
642				}
643			} else {
644				for ( ; i < length; ) {
645					if ( callback.apply( object[ i++ ], args ) === false ) {
646						break;
647					}
648				}
649			}
650
651		// A special, fast, case for the most common use of each
652		} else {
653			if ( isObj ) {
654				for ( name in object ) {
655					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
656						break;
657					}
658				}
659			} else {
660				for ( ; i < length; ) {
661					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
662						break;
663					}
664				}
665			}
666		}
667
668		return object;
669	},
670
671	// Use native String.trim function wherever possible
672	trim: trim ?
673		function( text ) {
674			return text == null ?
675				"" :
676				trim.call( text );
677		} :
678
679		// Otherwise use our own trimming functionality
680		function( text ) {
681			return text == null ?
682				"" :
683				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
684		},
685
686	// results is for internal usage only
687	makeArray: function( array, results ) {
688		var ret = results || [];
689
690		if ( array != null ) {
691			// The window, strings (and functions) also have 'length'
692			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
693			var type = jQuery.type( array );
694
695			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
696				push.call( ret, array );
697			} else {
698				jQuery.merge( ret, array );
699			}
700		}
701
702		return ret;
703	},
704
705	inArray: function( elem, array, i ) {
706		var len;
707
708		if ( array ) {
709			if ( indexOf ) {
710				return indexOf.call( array, elem, i );
711			}
712
713			len = array.length;
714			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
715
716			for ( ; i < len; i++ ) {
717				// Skip accessing in sparse arrays
718				if ( i in array && array[ i ] === elem ) {
719					return i;
720				}
721			}
722		}
723
724		return -1;
725	},
726
727	merge: function( first, second ) {
728		var i = first.length,
729			j = 0;
730
731		if ( typeof second.length === "number" ) {
732			for ( var l = second.length; j < l; j++ ) {
733				first[ i++ ] = second[ j ];
734			}
735
736		} else {
737			while ( second[j] !== undefined ) {
738				first[ i++ ] = second[ j++ ];
739			}
740		}
741
742		first.length = i;
743
744		return first;
745	},
746
747	grep: function( elems, callback, inv ) {
748		var ret = [], retVal;
749		inv = !!inv;
750
751		// Go through the array, only saving the items
752		// that pass the validator function
753		for ( var i = 0, length = elems.length; i < length; i++ ) {
754			retVal = !!callback( elems[ i ], i );
755			if ( inv !== retVal ) {
756				ret.push( elems[ i ] );
757			}
758		}
759
760		return ret;
761	},
762
763	// arg is for internal usage only
764	map: function( elems, callback, arg ) {
765		var value, key, ret = [],
766			i = 0,
767			length = elems.length,
768			// jquery objects are treated as arrays
769			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
770
771		// Go through the array, translating each of the items to their
772		if ( isArray ) {
773			for ( ; i < length; i++ ) {
774				value = callback( elems[ i ], i, arg );
775
776				if ( value != null ) {
777					ret[ ret.length ] = value;
778				}
779			}
780
781		// Go through every key on the object,
782		} else {
783			for ( key in elems ) {
784				value = callback( elems[ key ], key, arg );
785
786				if ( value != null ) {
787					ret[ ret.length ] = value;
788				}
789			}
790		}
791
792		// Flatten any nested arrays
793		return ret.concat.apply( [], ret );
794	},
795
796	// A global GUID counter for objects
797	guid: 1,
798
799	// Bind a function to a context, optionally partially applying any
800	// arguments.
801	proxy: function( fn, context ) {
802		if ( typeof context === "string" ) {
803			var tmp = fn[ context ];
804			context = fn;
805			fn = tmp;
806		}
807
808		// Quick check to determine if target is callable, in the spec
809		// this throws a TypeError, but we will just return undefined.
810		if ( !jQuery.isFunction( fn ) ) {
811			return undefined;
812		}
813
814		// Simulated bind
815		var args = slice.call( arguments, 2 ),
816			proxy = function() {
817				return fn.apply( context, args.concat( slice.call( arguments ) ) );
818			};
819
820		// Set the guid of unique handler to the same of original handler, so it can be removed
821		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
822
823		return proxy;
824	},
825
826	// Mutifunctional method to get and set values to a collection
827	// The value/s can optionally be executed if it's a function
828	access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
829		var exec,
830			bulk = key == null,
831			i = 0,
832			length = elems.length;
833
834		// Sets many values
835		if ( key && typeof key === "object" ) {
836			for ( i in key ) {
837				jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
838			}
839			chainable = 1;
840
841		// Sets one value
842		} else if ( value !== undefined ) {
843			// Optionally, function values get executed if exec is true
844			exec = pass === undefined && jQuery.isFunction( value );
845
846			if ( bulk ) {
847				// Bulk operations only iterate when executing function values
848				if ( exec ) {
849					exec = fn;
850					fn = function( elem, key, value ) {
851						return exec.call( jQuery( elem ), value );
852					};
853
854				// Otherwise they run against the entire set
855				} else {
856					fn.call( elems, value );
857					fn = null;
858				}
859			}
860
861			if ( fn ) {
862				for (; i < length; i++ ) {
863					fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
864				}
865			}
866
867			chainable = 1;
868		}
869
870		return chainable ?
871			elems :
872
873			// Gets
874			bulk ?
875				fn.call( elems ) :
876				length ? fn( elems[0], key ) : emptyGet;
877	},
878
879	now: function() {
880		return ( new Date() ).getTime();
881	},
882
883	// Use of jQuery.browser is frowned upon.
884	// More details: http://docs.jquery.com/Utilities/jQuery.browser
885	uaMatch: function( ua ) {
886		ua = ua.toLowerCase();
887
888		var match = rwebkit.exec( ua ) ||
889			ropera.exec( ua ) ||
890			rmsie.exec( ua ) ||
891			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
892			[];
893
894		return { browser: match[1] || "", version: match[2] || "0" };
895	},
896
897	sub: function() {
898		function jQuerySub( selector, context ) {
899			return new jQuerySub.fn.init( selector, context );
900		}
901		jQuery.extend( true, jQuerySub, this );
902		jQuerySub.superclass = this;
903		jQuerySub.fn = jQuerySub.prototype = this();
904		jQuerySub.fn.constructor = jQuerySub;
905		jQuerySub.sub = this.sub;
906		jQuerySub.fn.init = function init( selector, context ) {
907			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
908				context = jQuerySub( context );
909			}
910
911			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
912		};
913		jQuerySub.fn.init.prototype = jQuerySub.fn;
914		var rootjQuerySub = jQuerySub(document);
915		return jQuerySub;
916	},
917
918	browser: {}
919});
920
921// Populate the class2type map
922jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
923	class2type[ "[object " + name + "]" ] = name.toLowerCase();
924});
925
926browserMatch = jQuery.uaMatch( userAgent );
927if ( browserMatch.browser ) {
928	jQuery.browser[ browserMatch.browser ] = true;
929	jQuery.browser.version = browserMatch.version;
930}
931
932// Deprecated, use jQuery.browser.webkit instead
933if ( jQuery.browser.webkit ) {
934	jQuery.browser.safari = true;
935}
936
937// IE doesn't match non-breaking spaces with \s
938if ( rnotwhite.test( "\xA0" ) ) {
939	trimLeft = /^[\s\xA0]+/;
940	trimRight = /[\s\xA0]+$/;
941}
942
943// All jQuery objects should point back to these
944rootjQuery = jQuery(document);
945
946// Cleanup functions for the document ready method
947if ( document.addEventListener ) {
948	DOMContentLoaded = function() {
949		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
950		jQuery.ready();
951	};
952
953} else if ( document.attachEvent ) {
954	DOMContentLoaded = function() {
955		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
956		if ( document.readyState === "complete" ) {
957			document.detachEvent( "onreadystatechange", DOMContentLoaded );
958			jQuery.ready();
959		}
960	};
961}
962
963// The DOM ready check for Internet Explorer
964function doScrollCheck() {
965	if ( jQuery.isReady ) {
966		return;
967	}
968
969	try {
970		// If IE is used, use the trick by Diego Perini
971		// http://javascript.nwbox.com/IEContentLoaded/
972		document.documentElement.doScroll("left");
973	} catch(e) {
974		setTimeout( doScrollCheck, 1 );
975		return;
976	}
977
978	// and execute any waiting functions
979	jQuery.ready();
980}
981
982return jQuery;
983
984})();
985
986
987// String to Object flags format cache
988var flagsCache = {};
989
990// Convert String-formatted flags into Object-formatted ones and store in cache
991function createFlags( flags ) {
992	var object = flagsCache[ flags ] = {},
993		i, length;
994	flags = flags.split( /\s+/ );
995	for ( i = 0, length = flags.length; i < length; i++ ) {
996		object[ flags[i] ] = true;
997	}
998	return object;
999}
1000
1001/*
1002 * Create a callback list using the following parameters:
1003 *
1004 *	flags:	an optional list of space-separated flags that will change how
1005 *			the callback list behaves
1006 *
1007 * By default a callback list will act like an event callback list and can be
1008 * "fired" multiple times.
1009 *
1010 * Possible flags:
1011 *
1012 *	once:			will ensure the callback list can only be fired once (like a Deferred)
1013 *
1014 *	memory:			will keep track of previous values and will call any callback added
1015 *					after the list has been fired right away with the latest "memorized"
1016 *					values (like a Deferred)
1017 *
1018 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
1019 *
1020 *	stopOnFalse:	interrupt callings when a callback returns false
1021 *
1022 */
1023jQuery.Callbacks = function( flags ) {
1024
1025	// Convert flags from String-formatted to Object-formatted
1026	// (we check in cache first)
1027	flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
1028
1029	var // Actual callback list
1030		list = [],
1031		// Stack of fire calls for repeatable lists
1032		stack = [],
1033		// Last fire value (for non-forgettable lists)
1034		memory,
1035		// Flag to know if list was already fired
1036		fired,
1037		// Flag to know if list is currently firing
1038		firing,
1039		// First callback to fire (used internally by add and fireWith)
1040		firingStart,
1041		// End of the loop when firing
1042		firingLength,
1043		// Index of currently firing callback (modified by remove if needed)
1044		firingIndex,
1045		// Add one or several callbacks to the list
1046		add = function( args ) {
1047			var i,
1048				length,
1049				elem,
1050				type,
1051				actual;
1052			for ( i = 0, length = args.length; i < length; i++ ) {
1053				elem = args[ i ];
1054				type = jQuery.type( elem );
1055				if ( type === "array" ) {
1056					// Inspect recursively
1057					add( elem );
1058				} else if ( type === "function" ) {
1059					// Add if not in unique mode and callback is not in
1060					if ( !flags.unique || !self.has( elem ) ) {
1061						list.push( elem );
1062					}
1063				}
1064			}
1065		},
1066		// Fire callbacks
1067		fire = function( context, args ) {
1068			args = args || [];
1069			memory = !flags.memory || [ context, args ];
1070			fired = true;
1071			firing = true;
1072			firingIndex = firingStart || 0;
1073			firingStart = 0;
1074			firingLength = list.length;
1075			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1076				if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1077					memory = true; // Mark as halted
1078					break;
1079				}
1080			}
1081			firing = false;
1082			if ( list ) {
1083				if ( !flags.once ) {
1084					if ( stack && stack.length ) {
1085						memory = stack.shift();
1086						self.fireWith( memory[ 0 ], memory[ 1 ] );
1087					}
1088				} else if ( memory === true ) {
1089					self.disable();
1090				} else {
1091					list = [];
1092				}
1093			}
1094		},
1095		// Actual Callbacks object
1096		self = {
1097			// Add a callback or a collection of callbacks to the list
1098			add: function() {
1099				if ( list ) {
1100					var length = list.length;
1101					add( arguments );
1102					// Do we need to add the callbacks to the
1103					// current firing batch?
1104					if ( firing ) {
1105						firingLength = list.length;
1106					// With memory, if we're not firing then
1107					// we should call right away, unless previous
1108					// firing was halted (stopOnFalse)
1109					} else if ( memory && memory !== true ) {
1110						firingStart = length;
1111						fire( memory[ 0 ], memory[ 1 ] );
1112					}
1113				}
1114				return this;
1115			},
1116			// Remove a callback from the list
1117			remove: function() {
1118				if ( list ) {
1119					var args = arguments,
1120						argIndex = 0,
1121						argLength = args.length;
1122					for ( ; argIndex < argLength ; argIndex++ ) {
1123						for ( var i = 0; i < list.length; i++ ) {
1124							if ( args[ argIndex ] === list[ i ] ) {
1125								// Handle firingIndex and firingLength
1126								if ( firing ) {
1127									if ( i <= firingLength ) {
1128										firingLength--;
1129										if ( i <= firingIndex ) {
1130											firingIndex--;
1131										}
1132									}
1133								}
1134								// Remove the element
1135								list.splice( i--, 1 );
1136								// If we have some unicity property then
1137								// we only need to do this once
1138								if ( flags.unique ) {
1139									break;
1140								}
1141							}
1142						}
1143					}
1144				}
1145				return this;
1146			},
1147			// Control if a given callback is in the list
1148			has: function( fn ) {
1149				if ( list ) {
1150					var i = 0,
1151						length = list.length;
1152					for ( ; i < length; i++ ) {
1153						if ( fn === list[ i ] ) {
1154							return true;
1155						}
1156					}
1157				}
1158				return false;
1159			},
1160			// Remove all callbacks from the list
1161			empty: function() {
1162				list = [];
1163				return this;
1164			},
1165			// Have the list do nothing anymore
1166			disable: function() {
1167				list = stack = memory = undefined;
1168				return this;
1169			},
1170			// Is it disabled?
1171			disabled: function() {
1172				return !list;
1173			},
1174			// Lock the list in its current state
1175			lock: function() {
1176				stack = undefined;
1177				if ( !memory || memory === true ) {
1178					self.disable();
1179				}
1180				return this;
1181			},
1182			// Is it locked?
1183			locked: function() {
1184				return !stack;
1185			},
1186			// Call all callbacks with the given context and arguments
1187			fireWith: function( context, args ) {
1188				if ( stack ) {
1189					if ( firing ) {
1190						if ( !flags.once ) {
1191							stack.push( [ context, args ] );
1192						}
1193					} else if ( !( flags.once && memory ) ) {
1194						fire( context, args );
1195					}
1196				}
1197				return this;
1198			},
1199			// Call all the callbacks with the given arguments
1200			fire: function() {
1201				self.fireWith( this, arguments );
1202				return this;
1203			},
1204			// To know if the callbacks have already been called at least once
1205			fired: function() {
1206				return !!fired;
1207			}
1208		};
1209
1210	return self;
1211};
1212
1213
1214
1215
1216var // Static reference to slice
1217	sliceDeferred = [].slice;
1218
1219jQuery.extend({
1220
1221	Deferred: function( func ) {
1222		var doneList = jQuery.Callbacks( "once memory" ),
1223			failList = jQuery.Callbacks( "once memory" ),
1224			progressList = jQuery.Callbacks( "memory" ),
1225			state = "pending",
1226			lists = {
1227				resolve: doneList,
1228				reject: failList,
1229				notify: progressList
1230			},
1231			promise = {
1232				done: doneList.add,
1233				fail: failList.add,
1234				progress: progressList.add,
1235
1236				state: function() {
1237					return state;
1238				},
1239
1240				// Deprecated
1241				isResolved: doneList.fired,
1242				isRejected: failList.fired,
1243
1244				then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1245					deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1246					return this;
1247				},
1248				always: function() {
1249					deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1250					return this;
1251				},
1252				pipe: function( fnDone, fnFail, fnProgress ) {
1253					return jQuery.Deferred(function( newDefer ) {
1254						jQuery.each( {
1255							done: [ fnDone, "resolve" ],
1256							fail: [ fnFail, "reject" ],
1257							progress: [ fnProgress, "notify" ]
1258						}, function( handler, data ) {
1259							var fn = data[ 0 ],
1260								action = data[ 1 ],
1261								returned;
1262							if ( jQuery.isFunction( fn ) ) {
1263								deferred[ handler ](function() {
1264									returned = fn.apply( this, arguments );
1265									if ( returned && jQuery.isFunction( returned.promise ) ) {
1266										returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1267									} else {
1268										newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1269									}
1270								});
1271							} else {
1272								deferred[ handler ]( newDefer[ action ] );
1273							}
1274						});
1275					}).promise();
1276				},
1277				// Get a promise for this deferred
1278				// If obj is provided, the promise aspect is added to the object
1279				promise: function( obj ) {
1280					if ( obj == null ) {
1281						obj = promise;
1282					} else {
1283						for ( var key in promise ) {
1284							obj[ key ] = promise[ key ];
1285						}
1286					}
1287					return obj;
1288				}
1289			},
1290			deferred = promise.promise({}),
1291			key;
1292
1293		for ( key in lists ) {
1294			deferred[ key ] = lists[ key ].fire;
1295			deferred[ key + "With" ] = lists[ key ].fireWith;
1296		}
1297
1298		// Handle state
1299		deferred.done( function() {
1300			state = "resolved";
1301		}, failList.disable, progressList.lock ).fail( function() {
1302			state = "rejected";
1303		}, doneList.disable, progressList.lock );
1304
1305		// Call given func if any
1306		if ( func ) {
1307			func.call( deferred, deferred );
1308		}
1309
1310		// All done!
1311		return deferred;
1312	},
1313
1314	// Deferred helper
1315	when: function( firstParam ) {
1316		var args = sliceDeferred.call( arguments, 0 ),
1317			i = 0,
1318			length = args.length,
1319			pValues = new Array( length ),
1320			count = length,
1321			pCount = length,
1322			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1323				firstParam :
1324				jQuery.Deferred(),
1325			promise = deferred.promise();
1326		function resolveFunc( i ) {
1327			return function( value ) {
1328				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1329				if ( !( --count ) ) {
1330					deferred.resolveWith( deferred, args );
1331				}
1332			};
1333		}
1334		function progressFunc( i ) {
1335			return function( value ) {
1336				pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1337				deferred.notifyWith( promise, pValues );
1338			};
1339		}
1340		if ( length > 1 ) {
1341			for ( ; i < length; i++ ) {
1342				if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1343					args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1344				} else {
1345					--count;
1346				}
1347			}
1348			if ( !count ) {
1349				deferred.resolveWith( deferred, args );
1350			}
1351		} else if ( deferred !== firstParam ) {
1352			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1353		}
1354		return promise;
1355	}
1356});
1357
1358
1359
1360
1361jQuery.support = (function() {
1362
1363	var support,
1364		all,
1365		a,
1366		select,
1367		opt,
1368		input,
1369		fragment,
1370		tds,
1371		events,
1372		eventName,
1373		i,
1374		isSupported,
1375		div = document.createElement( "div" ),
1376		documentElement = document.documentElement;
1377
1378	// Preliminary tests
1379	div.setAttribute("className", "t");
1380	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a>
1380<input type='checkbox'/>";
1381
1382	all = div.getElementsByTagName( "*" );
1383	a = div.getElementsByTagName( "a" )[ 0 ];
1384
1385	// Can't get basic test support
1386	if ( !all || !all.length || !a ) {
1387		return {};
1388	}
1389
1390	// First batch of supports tests
1391	select = document.createElement( "select" );
1392	opt = select.appendChild( document.createElement("option") );
1393	input = div.getElementsByTagName( "input" )[ 0 ];
1394
1395	support = {
1396		// IE strips leading whitespace when .innerHTML is used
1397		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1398
1399		// Make sure that tbody elements aren't automatically inserted
1400		// IE will insert them into empty tables
1401		tbody: !div.getElementsByTagName("tbody").length,
1402
1403		// Make sure that link elements get serialized correctly by innerHTML
1404		// This requires a wrapper element in IE
1405		htmlSerialize: !!div.getElementsByTagName("link").length,
1406
1407		// Get the style information from getAttribute
1408		// (IE uses .cssText instead)
1409		style: /top/.test( a.getAttribute("style") ),
1410
1411		// Make sure that URLs aren't manipulated
1412		// (IE normalizes it by default)
1413		hrefNormalized: ( a.getAttribute("href") === "/a" ),
1414
1415		// Make sure that element opacity exists
1416		// (IE uses filter instead)
1417		// Use a regex to work around a WebKit issue. See #5145
1418		opacity: /^0.55/.test( a.style.opacity ),
1419
1420		// Verify style float existence
1421		// (IE uses styleFloat instead of cssFloat)
1422		cssFloat: !!a.style.cssFloat,
1423
1424		// Make sure that if no value is specified for a checkbox
1425		// that it defaults to "on".
1426		// (WebKit defaults to "" instead)
1427		checkOn: ( input.value === "on" ),
1428
1429		// Make sure that a selected-by-default option has a working selected property.
1430		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1431		optSelected: opt.selected,
1432
1433		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1434		getSetAttribute: div.className !== "t",
1435
1436		// Tests for enctype support on a form(#6743)
1437		enctype: !!document.createElement("form").enctype,
1438
1439		// Makes sure cloning an html5 element does not cause problems
1440		// Where outerHTML is undefined, this still works
1441		html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1442
1443		// Will be defined later
1444		submitBubbles: true,
1445		changeBubbles: true,
1446		focusinBubbles: false,
1447		deleteExpando: true,
1448		noCloneEvent: true,
1449		inlineBlockNeedsLayout: false,
1450		shrinkWrapBlocks: false,
1451		reliableMarginRight: true,
1452		pixelMargin: true
1453	};
1454
1455	// jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead
1456	jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");
1457
1458	// Make sure checked status is properly cloned
1459	input.checked = true;
1460	support.noCloneChecked = input.cloneNode( true ).checked;
1461
1462	// Make sure that the options inside disabled selects aren't marked as disabled
1463	// (WebKit marks them as disabled)
1464	select.disabled = true;
1465	support.optDisabled = !opt.disabled;
1466
1467	// Test to see if it's possible to delete an expando from an element
1468	// Fails in Internet Explorer
1469	try {
1470		delete div.test;
1471	} catch( e ) {
1472		support.deleteExpando = false;
1473	}
1474
1475	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1476		div.attachEvent( "onclick", function() {
1477			// Cloning a node shouldn't copy over any
1478			// bound event handlers (IE does this)
1479			support.noCloneEvent = false;
1480		});
1481		div.cloneNode( true ).fireEvent( "onclick" );
1482	}
1483
1484	// Check if a radio maintains its value
1485	// after being appended to the DOM
1486	input = document.createElement("input");
1487	input.value = "t";
1488	input.setAttribute("type", "radio");
1489	support.radioValue = input.value === "t";
1490
1491	input.setAttribute("checked", "checked");
1492
1493	// #11217 - WebKit loses check when the name is after the checked attribute
1494	input.setAttribute( "name", "t" );
1495
1496	div.appendChild( input );
1497	fragment = document.createDocumentFragment();
1498	fragment.appendChild( div.lastChild );
1499
1500	// WebKit doesn't clone checked state correctly in fragments
1501	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1502
1503	// Check if a disconnected checkbox will retain its checked
1504	// value of true after appended to the DOM (IE6/7)
1505	support.appendChecked = input.checked;
1506
1507	fragment.removeChild( input );
1508	fragment.appendChild( div );
1509
1510	// Technique from Juriy Zaytsev
1511	// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1512	// We only care about the case where non-standard event systems
1513	// are used, namely in IE. Short-circuiting here helps us to
1514	// avoid an eval call (in setAttribute) which can cause CSP
1515	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1516	if ( div.attachEvent ) {
1517		for ( i in {
1518			submit: 1,
1519			change: 1,
1520			focusin: 1
1521		}) {
1522			eventName = "on" + i;
1523			isSupported = ( eventName in div );
1524			if ( !isSupported ) {
1525				div.setAttribute( eventName, "return;" );
1526				isSupported = ( typeof div[ eventName ] === "function" );
1527			}
1528			support[ i + "Bubbles" ] = isSupported;
1529		}
1530	}
1531
1532	fragment.removeChild( div );
1533
1534	// Null elements to avoid leaks in IE
1535	fragment = select = opt = div = input = null;
1536
1537	// Run tests that need a body at doc ready
1538	jQuery(function() {
1539		var container, outer, inner, table, td, offsetSupport,
1540			marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,
1541			paddingMarginBorderVisibility, paddingMarginBorder,
1542			body = document.getElementsByTagName("body")[0];
1543
1544		if ( !body ) {
1545			// Return for frameset docs that don't have a body
1546			return;
1547		}
1548
1549		conMarginTop = 1;
1550		paddingMarginBorder = "padding:0;margin:0;border:";
1551		positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";
1552		paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";
1553		style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";
1554		html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" +
1555			"<table " + style + "' cellpadding='0' cellspacing='0'>" +
1556			"<tr><td></td></tr></table>";
1557
1558		container = document.createElement("div");
1559		container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1560		body.insertBefore( container, body.firstChild );
1561
1562		// Construct the test element
1563		div = document.createElement("div");
1564		container.appendChild( div );
1565
1566		// Check if table cells still have offsetWidth/Height when they are set
1567		// to display:none and there are still other visible table cells in a
1568		// table row; if so, offsetWidth/Height are not reliable for use when
1569		// determining if an element has been hidden directly using
1570		// display:none (it is still safe to use offsets if a parent element is
1571		// hidden; don safety goggles and see bug #4512 for more information).
1572		// (only IE 8 fails this test)
1573		div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";
1574		tds = div.getElementsByTagName( "td" );
1575		isSupported = ( tds[ 0 ].offsetHeight === 0 );
1576
1577		tds[ 0 ].style.display = "";
1578		tds[ 1 ].style.display = "none";
1579
1580		// Check if empty table cells still have offsetWidth/Height
1581		// (IE <= 8 fail this test)
1582		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1583
1584		// Check if div with explicit width and no margin-right incorrectly
1585		// gets computed margin-right based on width of container. For more
1586		// info see bug #3333
1587		// Fails in WebKit before Feb 2011 nightlies
1588		// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1589		if ( window.getComputedStyle ) {
1590			div.innerHTML = "";
1591			marginDiv = document.createElement( "div" );
1592			marginDiv.style.width = "0";
1593			marginDiv.style.marginRight = "0";
1594			div.style.width = "2px";
1595			div.appendChild( marginDiv );
1596			support.reliableMarginRight =
1597				( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1598		}
1599
1600		if ( typeof div.style.zoom !== "undefined" ) {
1601			// Check if natively block-level elements act like inline-block
1602			// elements when setting their display to 'inline' and giving
1603			// them layout
1604			// (IE < 8 does this)
1605			div.innerHTML = "";
1606			div.style.width = div.style.padding = "1px";
1607			div.style.border = 0;
1608			div.style.overflow = "hidden";
1609			div.style.display = "inline";
1610			div.style.zoom = 1;
1611			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1612
1613			// Check if elements with layout shrink-wrap their children
1614			// (IE 6 does this)
1615			div.style.display = "block";
1616			div.style.overflow = "visible";
1617			div.innerHTML = "<div style='width:5px;'></div>";
1618			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1619		}
1620
1621		div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;
1622		div.innerHTML = html;
1623
1624		outer = div.firstChild;
1625		inner = outer.firstChild;
1626		td = outer.nextSibling.firstChild.firstChild;
1627
1628		offsetSupport = {
1629			doesNotAddBorder: ( inner.offsetTop !== 5 ),
1630			doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1631		};
1632
1633		inner.style.position = "fixed";
1634		inner.style.top = "20px";
1635
1636		// safari subtracts parent border width here which is 5px
1637		offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1638		inner.style.position = inner.style.top = "";
1639
1640		outer.style.overflow = "hidden";
1641		outer.style.position = "relative";
1642
1643		offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1644		offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1645
1646		if ( window.getComputedStyle ) {
1647			div.style.marginTop = "1%";
1648			support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
1649		}
1650
1651		if ( typeof container.style.zoom !== "undefined" ) {
1652			container.style.zoom = 1;
1653		}
1654
1655		body.removeChild( container );
1656		marginDiv = div = container = null;
1657
1658		jQuery.extend( support, offsetSupport );
1659	});
1660
1661	return support;
1662})();
1663
1664
1665
1666
1667var rbrace = /^(?:\{.*\}|\[.*\])$/,
1668	rmultiDash = /([A-Z])/g;
1669
1670jQuery.extend({
1671	cache: {},
1672
1673	// Please use with caution
1674	uuid: 0,
1675
1676	// Unique for each copy of jQuery on the page
1677	// Non-digits removed to match rinlinejQuery
1678	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1679
1680	// The following elements throw uncatchable exceptions if you
1681	// attempt to add expando properties to them.
1682	noData: {
1683		"embed": true,
1684		// Ban all objects except for Flash (which handle expandos)
1685		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1686		"applet": true
1687	},
1688
1689	hasData: function( elem ) {
1690		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1691		return !!elem && !isEmptyDataObject( elem );
1692	},
1693
1694	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1695		if ( !jQuery.acceptData( elem ) ) {
1696			return;
1697		}
1698
1699		var privateCache, thisCache, ret,
1700			internalKey = jQuery.expando,
1701			getByName = typeof name === "string",
1702
1703			// We have to handle DOM nodes and JS objects differently because IE6-7
1704			// can't GC object references properly across the DOM-JS boundary
1705			isNode = elem.nodeType,
1706
1707			// Only DOM nodes need the global jQuery cache; JS object data is
1708			// attached directly to the object so GC can occur automatically
1709			cache = isNode ? jQuery.cache : elem,
1710
1711			// Only defining an ID for JS objects if its cache already exists allows
1712			// the code to shortcut on the same path as a DOM node with no cache
1713			id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
1714			isEvents = name === "events";
1715
1716		// Avoid doing any more work than we need to when trying to get data on an
1717		// object that has no data at all
1718		if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
1719			return;
1720		}
1721
1722		if ( !id ) {
1723			// Only DOM nodes need a new unique ID for each element since their data
1724			// ends up in the global cache
1725			if ( isNode ) {
1726				elem[ internalKey ] = id = ++jQuery.uuid;
1727			} else {
1728				id = internalKey;
1729			}
1730		}
1731
1732		if ( !cache[ id ] ) {
1733			cache[ id ] = {};
1734
1735			// Avoids exposing jQuery metadata on plain JS objects when the object
1736			// is serialized using JSON.stringify
1737			if ( !isNode ) {
1738				cache[ id ].toJSON = jQuery.noop;
1739			}
1740		}
1741
1742		// An object can be passed to jQuery.data instead of a key/value pair; this gets
1743		// shallow copied over onto the existing cache
1744		if ( typeof name === "object" || typeof name === "function" ) {
1745			if ( pvt ) {
1746				cache[ id ] = jQuery.extend( cache[ id ], name );
1747			} else {
1748				cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1749			}
1750		}
1751
1752		privateCache = thisCache = cache[ id ];
1753
1754		// jQuery data() is stored in a separate object inside the object's internal data
1755		// cache in order to avoid key collisions between internal data and user-defined
1756		// data.
1757		if ( !pvt ) {
1758			if ( !thisCache.data ) {
1759				thisCache.data = {};
1760			}
1761
1762			thisCache = thisCache.data;
1763		}
1764
1765		if ( data !== undefined ) {
1766			thisCache[ jQuery.camelCase( name ) ] = data;
1767		}
1768
1769		// Users should not attempt to inspect the internal events object using jQuery.data,
1770		// it is undocumented and subject to change. But does anyone listen? No.
1771		if ( isEvents && !thisCache[ name ] ) {
1772			return privateCache.events;
1773		}
1774
1775		// Check for both converted-to-camel and non-converted data property names
1776		// If a data property was specified
1777		if ( getByName ) {
1778
1779			// First Try to find as-is property data
1780			ret = thisCache[ name ];
1781
1782			// Test for null|undefined property data
1783			if ( ret == null ) {
1784
1785				// Try to find the camelCased property
1786				ret = thisCache[ jQuery.camelCase( name ) ];
1787			}
1788		} else {
1789			ret = thisCache;
1790		}
1791
1792		return ret;
1793	},
1794
1795	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1796		if ( !jQuery.acceptData( elem ) ) {
1797			return;
1798		}
1799
1800		var thisCache, i, l,
1801
1802			// Reference to internal data cache key
1803			internalKey = jQuery.expando,
1804
1805			isNode = elem.nodeType,
1806
1807			// See jQuery.data for more information
1808			cache = isNode ? jQuery.cache : elem,
1809
1810			// See jQuery.data for more information
1811			id = isNode ? elem[ internalKey ] : internalKey;
1812
1813		// If there is already no cache entry for this object, there is no
1814		// purpose in continuing
1815		if ( !cache[ id ] ) {
1816			return;
1817		}
1818
1819		if ( name ) {
1820
1821			thisCache = pvt ? cache[ id ] : cache[ id ].data;
1822
1823			if ( thisCache ) {
1824
1825				// Support array or space separated string names for data keys
1826				if ( !jQuery.isArray( name ) ) {
1827
1828					// try the string as a key before any manipulation
1829					if ( name in thisCache ) {
1830						name = [ name ];
1831					} else {
1832
1833						// split the camel cased version by spaces unless a key with the spaces exists
1834						name = jQuery.camelCase( name );
1835						if ( name in thisCache ) {
1836							name = [ name ];
1837						} else {
1838							name = name.split( " " );
1839						}
1840					}
1841				}
1842
1843				for ( i = 0, l = name.length; i < l; i++ ) {
1844					delete thisCache[ name[i] ];
1845				}
1846
1847				// If there is no data left in the cache, we want to continue
1848				// and let the cache object itself get destroyed
1849				if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1850					return;
1851				}
1852			}
1853		}
1854
1855		// See jQuery.data for more information
1856		if ( !pvt ) {
1857			delete cache[ id ].data;
1858
1859			// Don't destroy the parent cache unless the internal data object
1860			// had been the only thing left in it
1861			if ( !isEmptyDataObject(cache[ id ]) ) {
1862				return;
1863			}
1864		}
1865
1866		// Browsers that fail expando deletion also refuse to delete expandos on
1867		// the window, but it will allow it on all other JS objects; other browsers
1868		// don't care
1869		// Ensure that `cache` is not a window object #10080
1870		if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1871			delete cache[ id ];
1872		} else {
1873			cache[ id ] = null;
1874		}
1875
1876		// We destroyed the cache and need to eliminate the expando on the node to avoid
1877		// false lookups in the cache for entries that no longer exist
1878		if ( isNode ) {
1879			// IE does not allow us to delete expando properties from nodes,
1880			// nor does it have a removeAttribute function on Document nodes;
1881			// we must handle all of these cases
1882			if ( jQuery.support.deleteExpando ) {
1883				delete elem[ internalKey ];
1884			} else if ( elem.removeAttribute ) {
1885				elem.removeAttribute( internalKey );
1886			} else {
1887				elem[ internalKey ] = null;
1888			}
1889		}
1890	},
1891
1892	// For internal use only.
1893	_data: function( elem, name, data ) {
1894		return jQuery.data( elem, name, data, true );
1895	},
1896
1897	// A method for determining if a DOM node can handle the data expando
1898	acceptData: function( elem ) {
1899		if ( elem.nodeName ) {
1900			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1901
1902			if ( match ) {
1903				return !(match === true || elem.getAttribute("classid") !== match);
1904			}
1905		}
1906
1907		return true;
1908	}
1909});
1910
1911jQuery.fn.extend({
1912	data: function( key, value ) {
1913		var parts, part, attr, name, l,
1914			elem = this[0],
1915			i = 0,
1916			data = null;
1917
1918		// Gets all values
1919		if ( key === undefined ) {
1920			if ( this.length ) {
1921				data = jQuery.data( elem );
1922
1923				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1924					attr = elem.attributes;
1925					for ( l = attr.length; i < l; i++ ) {
1926						name = attr[i].name;
1927
1928						if ( name.indexOf( "data-" ) === 0 ) {
1929							name = jQuery.camelCase( name.substring(5) );
1930
1931							dataAttr( elem, name, data[ name ] );
1932						}
1933					}
1934					jQuery._data( elem, "parsedAttrs", true );
1935				}
1936			}
1937
1938			return data;
1939		}
1940
1941		// Sets multiple values
1942		if ( typeof key === "object" ) {
1943			return this.each(function() {
1944				jQuery.data( this, key );
1945			});
1946		}
1947
1948		parts = key.split( ".", 2 );
1949		parts[1] = parts[1] ? "." + parts[1] : "";
1950		part = parts[1] + "!";
1951
1952		return jQuery.access( this, function( value ) {
1953
1954			if ( value === undefined ) {
1955				data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1956
1957				// Try to fetch any internally stored data first
1958				if ( data === undefined && elem ) {
1959					data = jQuery.data( elem, key );
1960					data = dataAttr( elem, key, data );
1961				}
1962
1963				return data === undefined && parts[1] ?
1964					this.data( parts[0] ) :
1965					data;
1966			}
1967
1968			parts[1] = value;
1969			this.each(function() {
1970				var self = jQuery( this );
1971
1972				self.triggerHandler( "setData" + part, parts );
1973				jQuery.data( this, key, value );
1974				self.triggerHandler( "changeData" + part, parts );
1975			});
1976		}, null, value, arguments.length > 1, null, false );
1977	},
1978
1979	removeData: function( key ) {
1980		return this.each(function() {
1981			jQuery.removeData( this, key );
1982		});
1983	}
1984});
1985
1986function dataAttr( elem, key, data ) {
1987	// If nothing was found internally, try to fetch any
1988	// data from the HTML5 data-* attribute
1989	if ( data === undefined && elem.nodeType === 1 ) {
1990
1991		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1992
1993		data = elem.getAttribute( name );
1994
1995		if ( typeof data === "string" ) {
1996			try {
1997				data = data === "true" ? true :
1998				data === "false" ? false :
1999				data === "null" ? null :
2000				jQuery.isNumeric( data ) ? +data :
2001					rbrace.test( data ) ? jQuery.parseJSON( data ) :
2002					data;
2003			} catch( e ) {}
2004
2005			// Make sure we set the data so it isn't changed later
2006			jQuery.data( elem, key, data );
2007
2008		} else {
2009			data = undefined;
2010		}
2011	}
2012
2013	return data;
2014}
2015
2016// checks a cache object for emptiness
2017function isEmptyDataObject( obj ) {
2018	for ( var name in obj ) {
2019
2020		// if the public data object is empty, the private is still empty
2021		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
2022			continue;
2023		}
2024		if ( name !== "toJSON" ) {
2025			return false;
2026		}
2027	}
2028
2029	return true;
2030}
2031
2032
2033
2034
2035function handleQueueMarkDefer( elem, type, src ) {
2036	var deferDataKey = type + "defer",
2037		queueDataKey = type + "queue",
2038		markDataKey = type + "mark",
2039		defer = jQuery._data( elem, deferDataKey );
2040	if ( defer &&
2041		( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
2042		( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
2043		// Give room for hard-coded callbacks to fire first
2044		// and eventually mark/queue something else on the element
2045		setTimeout( function() {
2046			if ( !jQuery._data( elem, queueDataKey ) &&
2047				!jQuery._data( elem, markDataKey ) ) {
2048				jQuery.removeData( elem, deferDataKey, true );
2049				defer.fire();
2050			}
2051		}, 0 );
2052	}
2053}
2054
2055jQuery.extend({
2056
2057	_mark: function( elem, type ) {
2058		if ( elem ) {
2059			type = ( type || "fx" ) + "mark";
2060			jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
2061		}
2062	},
2063
2064	_unmark: function( force, elem, type ) {
2065		if ( force !== true ) {
2066			type = elem;
2067			elem = force;
2068			force = false;
2069		}
2070		if ( elem ) {
2071			type = type || "fx";
2072			var key = type + "mark",
2073				count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
2074			if ( count ) {
2075				jQuery._data( elem, key, count );
2076			} else {
2077				jQuery.removeData( elem, key, true );
2078				handleQueueMarkDefer( elem, type, "mark" );
2079			}
2080		}
2081	},
2082
2083	queue: function( elem, type, data ) {
2084		var q;
2085		if ( elem ) {
2086			type = ( type || "fx" ) + "queue";
2087			q = jQuery._data( elem, type );
2088
2089			// Speed up dequeue by getting out quickly if this is just a lookup
2090			if ( data ) {
2091				if ( !q || jQuery.isArray(data) ) {
2092					q = jQuery._data( elem, type, jQuery.makeArray(data) );
2093				} else {
2094					q.push( data );
2095				}
2096			}
2097			return q || [];
2098		}
2099	},
2100
2101	dequeue: function( elem, type ) {
2102		type = type || "fx";
2103
2104		var queue = jQuery.queue( elem, type ),
2105			fn = queue.shift(),
2106			hooks = {};
2107
2108		// If the fx queue is dequeued, always remove the progress sentinel
2109		if ( fn === "inprogress" ) {
2110			fn = queue.shift();
2111		}
2112
2113		if ( fn ) {
2114			// Add a progress sentinel to prevent the fx queue from being
2115			// automatically dequeued
2116			if ( type === "fx" ) {
2117				queue.unshift( "inprogress" );
2118			}
2119
2120			jQuery._data( elem, type + ".run", hooks );
2121			fn.call( elem, function() {
2122				jQuery.dequeue( elem, type );
2123			}, hooks );
2124		}
2125
2126		if ( !queue.length ) {
2127			jQuery.removeData( elem, type + "queue " + type + ".run", true );
2128			handleQueueMarkDefer( elem, type, "queue" );
2129		}
2130	}
2131});
2132
2133jQuery.fn.extend({
2134	queue: function( type, data ) {
2135		var setter = 2;
2136
2137		if ( typeof type !== "string" ) {
2138			data = type;
2139			type = "fx";
2140			setter--;
2141		}
2142
2143		if ( arguments.length < setter ) {
2144			return jQuery.queue( this[0], type );
2145		}
2146
2147		return data === undefined ?
2148			this :
2149			this.each(function() {
2150				var queue = jQuery.queue( this, type, data );
2151
2152				if ( type === "fx" && queue[0] !== "inprogress" ) {
2153					jQuery.dequeue( this, type );
2154				}
2155			});
2156	},
2157	dequeue: function( type ) {
2158		return this.each(function() {
2159			jQuery.dequeue( this, type );
2160		});
2161	},
2162	// Based off of the plugin by Clint Helfers, with permission.
2163	// http://blindsignals.com/index.php/2009/07/jquery-delay/
2164	delay: function( time, type ) {
2165		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
2166		type = type || "fx";
2167
2168		return this.queue( type, function( next, hooks ) {
2169			var timeout = setTimeout( next, time );
2170			hooks.stop = function() {
2171				clearTimeout( timeout );
2172			};
2173		});
2174	},
2175	clearQueue: function( type ) {
2176		return this.queue( type || "fx", [] );
2177	},
2178	// Get a promise resolved when queues of a certain type
2179	// are emptied (fx is the type by default)
2180	promise: function( type, object ) {
2181		if ( typeof type !== "string" ) {
2182			object = type;
2183			type = undefined;
2184		}
2185		type = type || "fx";
2186		var defer = jQuery.Deferred(),
2187			elements = this,
2188			i = elements.length,
2189			count = 1,
2190			deferDataKey = type + "defer",
2191			queueDataKey = type + "queue",
2192			markDataKey = type + "mark",
2193			tmp;
2194		function resolve() {
2195			if ( !( --count ) ) {
2196				defer.resolveWith( elements, [ elements ] );
2197			}
2198		}
2199		while( i-- ) {
2200			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2201					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2202						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2203					jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
2204				count++;
2205				tmp.add( resolve );
2206			}
2207		}
2208		resolve();
2209		return defer.promise( object );
2210	}
2211});
2212
2213
2214
2215
2216var rclass = /[\n\t\r]/g,
2217	rspace = /\s+/,
2218	rreturn = /\r/g,
2219	rtype = /^(?:button|input)$/i,
2220	rfocusable = /^(?:button|input|object|select|textarea)$/i,
2221	rclickable = /^a(?:rea)?$/i,
2222	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2223	getSetAttribute = jQuery.support.getSetAttribute,
2224	nodeHook, boolHook, fixSpecified;
2225
2226jQuery.fn.extend({
2227	attr: function( name, value ) {
2228		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2229	},
2230
2231	removeAttr: function( name ) {
2232		return this.each(function() {
2233			jQuery.removeAttr( this, name );
2234		});
2235	},
2236
2237	prop: function( name, value ) {
2238		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2239	},
2240
2241	removeProp: function( name ) {
2242		name = jQuery.propFix[ name ] || name;
2243		return this.each(function() {
2244			// try/catch handles cases where IE balks (such as removing a property on window)
2245			try {
2246				this[ name ] = undefined;
2247				delete this[ name ];
2248			} catch( e ) {}
2249		});
2250	},
2251
2252	addClass: function( value ) {
2253		var classNames, i, l, elem,
2254			setClass, c, cl;
2255
2256		if ( jQuery.isFunction( value ) ) {
2257			return this.each(function( j ) {
2258				jQuery( this ).addClass( value.call(this, j, this.className) );
2259			});
2260		}
2261
2262		if ( value && typeof value === "string" ) {
2263			classNames = value.split( rspace );
2264
2265			for ( i = 0, l = this.length; i < l; i++ ) {
2266				elem = this[ i ];
2267
2268				if ( elem.nodeType === 1 ) {
2269					if ( !elem.className && classNames.length === 1 ) {
2270						elem.className = value;
2271
2272					} else {
2273						setClass = " " + elem.className + " ";
2274
2275						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2276							if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2277								setClass += classNames[ c ] + " ";
2278							}
2279						}
2280						elem.className = jQuery.trim( setClass );
2281					}
2282				}
2283			}
2284		}
2285
2286		return this;
2287	},
2288
2289	removeClass: function( value ) {
2290		var classNames, i, l, elem, className, c, cl;
2291
2292		if ( jQuery.isFunction( value ) ) {
2293			return this.each(function( j ) {
2294				jQuery( this ).removeClass( value.call(this, j, this.className) );
2295			});
2296		}
2297
2298		if ( (value && typeof value === "string") || value === undefined ) {
2299			classNames = ( value || "" ).split( rspace );
2300
2301			for ( i = 0, l = this.length; i < l; i++ ) {
2302				elem = this[ i ];
2303
2304				if ( elem.nodeType === 1 && elem.className ) {
2305					if ( value ) {
2306						className = (" " + elem.className + " ").replace( rclass, " " );
2307						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2308							className = className.replace(" " + classNames[ c ] + " ", " ");
2309						}
2310						elem.className = jQuery.trim( className );
2311
2312					} else {
2313						elem.className = "";
2314					}
2315				}
2316			}
2317		}
2318
2319		return this;
2320	},
2321
2322	toggleClass: function( value, stateVal ) {
2323		var type = typeof value,
2324			isBool = typeof stateVal === "boolean";
2325
2326		if ( jQuery.isFunction( value ) ) {
2327			return this.each(function( i ) {
2328				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2329			});
2330		}
2331
2332		return this.each(function() {
2333			if ( type === "string" ) {
2334				// toggle individual class names
2335				var className,
2336					i = 0,
2337					self = jQuery( this ),
2338					state = stateVal,
2339					classNames = value.split( rspace );
2340
2341				while ( (className = classNames[ i++ ]) ) {
2342					// check each className given, space seperated list
2343					state = isBool ? state : !self.hasClass( className );
2344					self[ state ? "addClass" : "removeClass" ]( className );
2345				}
2346
2347			} else if ( type === "undefined" || type === "boolean" ) {
2348				if ( this.className ) {
2349					// store className if set
2350					jQuery._data( this, "__className__", this.className );
2351				}
2352
2353				// toggle whole className
2354				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2355			}
2356		});
2357	},
2358
2359	hasClass: function( selector ) {
2360		var className = " " + selector + " ",
2361			i = 0,
2362			l = this.length;
2363		for ( ; i < l; i++ ) {
2364			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2365				return true;
2366			}
2367		}
2368
2369		return false;
2370	},
2371
2372	val: function( value ) {
2373		var hooks, ret, isFunction,
2374			elem = this[0];
2375
2376		if ( !arguments.length ) {
2377			if ( elem ) {
2378				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2379
2380				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2381					return ret;
2382				}
2383
2384				ret = elem.value;
2385
2386				return typeof ret === "string" ?
2387					// handle most common string cases
2388					ret.replace(rreturn, "") :
2389					// handle cases where value is null/undef or number
2390					ret == null ? "" : ret;
2391			}
2392
2393			return;
2394		}
2395
2396		isFunction = jQuery.isFunction( value );
2397
2398		return this.each(function( i ) {
2399			var self = jQuery(this), val;
2400
2401			if ( this.nodeType !== 1 ) {
2402				return;
2403			}
2404
2405			if ( isFunction ) {
2406				val = value.call( this, i, self.val() );
2407			} else {
2408				val = value;
2409			}
2410
2411			// Treat null/undefined as ""; convert numbers to string
2412			if ( val == null ) {
2413				val = "";
2414			} else if ( typeof val === "number" ) {
2415				val += "";
2416			} else if ( jQuery.isArray( val ) ) {
2417				val = jQuery.map(val, function ( value ) {
2418					return value == null ? "" : value + "";
2419				});
2420			}
2421
2422			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2423
2424			// If set returns undefined, fall back to normal setting
2425			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2426				this.value = val;
2427			}
2428		});
2429	}
2430});
2431
2432jQuery.extend({
2433	valHooks: {
2434		option: {
2435			get: function( elem ) {
2436				// attributes.value is undefined in Blackberry 4.7 but
2437				// uses .value. See #6932
2438				var val = elem.attributes.value;
2439				return !val || val.specified ? elem.value : elem.text;
2440			}
2441		},
2442		select: {
2443			get: function( elem ) {
2444				var value, i, max, option,
2445					index = elem.selectedIndex,
2446					values = [],
2447					options = elem.options,
2448					one = elem.type === "select-one";
2449
2450				// Nothing was selected
2451				if ( index < 0 ) {
2452					return null;
2453				}
2454
2455				// Loop through all the selected options
2456				i = one ? index : 0;
2457				max = one ? index + 1 : options.length;
2458				for ( ; i < max; i++ ) {
2459					option = options[ i ];
2460
2461					// Don't return options that are disabled or in a disabled optgroup
2462					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2463							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2464
2465						// Get the specific value for the option
2466						value = jQuery( option ).val();
2467
2468						// We don't need an array for one selects
2469						if ( one ) {
2470							return value;
2471						}
2472
2473						// Multi-Selects return an array
2474						values.push( value );
2475					}
2476				}
2477
2478				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2479				if ( one && !values.length && options.length ) {
2480					return jQuery( options[ index ] ).val();
2481				}
2482
2483				return values;
2484			},
2485
2486			set: function( elem, value ) {
2487				var values = jQuery.makeArray( value );
2488
2489				jQuery(elem).find("option").each(function() {
2490					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2491				});
2492
2493				if ( !values.length ) {
2494					elem.selectedIndex = -1;
2495				}
2496				return values;
2497			}
2498		}
2499	},
2500
2501	attrFn: {
2502		val: true,
2503		css: true,
2504		html: true,
2505		text: true,
2506		data: true,
2507		width: true,
2508		height: true,
2509		offset: true
2510	},
2511
2512	attr: function( elem, name, value, pass ) {
2513		var ret, hooks, notxml,
2514			nType = elem.nodeType;
2515
2516		// don't get/set attributes on text, comment and attribute nodes
2517		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2518			return;
2519		}
2520
2521		if ( pass && name in jQuery.attrFn ) {
2522			return jQuery( elem )[ name ]( value );
2523		}
2524
2525		// Fallback to prop when attributes are not supported
2526		if ( typeof elem.getAttribute === "undefined" ) {
2527			return jQuery.prop( elem, name, value );
2528		}
2529
2530		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2531
2532		// All attributes are lowercase
2533		// Grab necessary hook if one is defined
2534		if ( notxml ) {
2535			name = name.toLowerCase();
2536			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2537		}
2538
2539		if ( value !== undefined ) {
2540
2541			if ( value === null ) {
2542				jQuery.removeAttr( elem, name );
2543				return;
2544
2545			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2546				return ret;
2547
2548			} else {
2549				elem.setAttribute( name, "" + value );
2550				return value;
2551			}
2552
2553		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2554			return ret;
2555
2556		} else {
2557
2558			ret = elem.getAttribute( name );
2559
2560			// Non-existent attributes return null, we normalize to undefined
2561			return ret === null ?
2562				undefined :
2563				ret;
2564		}
2565	},
2566
2567	removeAttr: function( elem, value ) {
2568		var propName, attrNames, name, l, isBool,
2569			i = 0;
2570
2571		if ( value && elem.nodeType === 1 ) {
2572			attrNames = value.toLowerCase().split( rspace );
2573			l = attrNames.length;
2574
2575			for ( ; i < l; i++ ) {
2576				name = attrNames[ i ];
2577
vendor: 5,739 bytes, lines 2578-2775
2578				if ( name ) {
2579					propName = jQuery.propFix[ name ] || name;
2580					isBool = rboolean.test( name );
2581
2582					// See #9699 for explanation of this approach (setting first, then removal)
2583					// Do not do this for boolean attributes (see #10870)
2584					if ( !isBool ) {
2585						jQuery.attr( elem, name, "" );
2586					}
2587					elem.removeAttribute( getSetAttribute ? name : propName );
2588
2589					// Set corresponding property to false for boolean attributes
2590					if ( isBool && propName in elem ) {
2591						elem[ propName ] = false;
2592					}
2593				}
2594			}
2595		}
2596	},
2597
2598	attrHooks: {
2599		type: {
2600			set: function( elem, value ) {
2601				// We can't allow the type property to be changed (since it causes problems in IE)
2602				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2603					jQuery.error( "type property can't be changed" );
2604				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2605					// Setting the type on a radio button after the value resets the value in IE6-9
2606					// Reset value to it's default in case type is set after value
2607					// This is for element creation
2608					var val = elem.value;
2609					elem.setAttribute( "type", value );
2610					if ( val ) {
2611						elem.value = val;
2612					}
2613					return value;
2614				}
2615			}
2616		},
2617		// Use the value property for back compat
2618		// Use the nodeHook for button elements in IE6/7 (#1954)
2619		value: {
2620			get: function( elem, name ) {
2621				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2622					return nodeHook.get( elem, name );
2623				}
2624				return name in elem ?
2625					elem.value :
2626					null;
2627			},
2628			set: function( elem, value, name ) {
2629				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2630					return nodeHook.set( elem, value, name );
2631				}
2632				// Does not return so that setAttribute is also used
2633				elem.value = value;
2634			}
2635		}
2636	},
2637
2638	propFix: {
2639		tabindex: "tabIndex",
2640		readonly: "readOnly",
2641		"for": "htmlFor",
2642		"class": "className",
2643		maxlength: "maxLength",
2644		cellspacing: "cellSpacing",
2645		cellpadding: "cellPadding",
2646		rowspan: "rowSpan",
2647		colspan: "colSpan",
2648		usemap: "useMap",
2649		frameborder: "frameBorder",
2650		contenteditable: "contentEditable"
2651	},
2652
2653	prop: function( elem, name, value ) {
2654		var ret, hooks, notxml,
2655			nType = elem.nodeType;
2656
2657		// don't get/set properties on text, comment and attribute nodes
2658		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2659			return;
2660		}
2661
2662		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2663
2664		if ( notxml ) {
2665			// Fix name and attach hooks
2666			name = jQuery.propFix[ name ] || name;
2667			hooks = jQuery.propHooks[ name ];
2668		}
2669
2670		if ( value !== undefined ) {
2671			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2672				return ret;
2673
2674			} else {
2675				return ( elem[ name ] = value );
2676			}
2677
2678		} else {
2679			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2680				return ret;
2681
2682			} else {
2683				return elem[ name ];
2684			}
2685		}
2686	},
2687
2688	propHooks: {
2689		tabIndex: {
2690			get: function( elem ) {
2691				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2692				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2693				var attributeNode = elem.getAttributeNode("tabindex");
2694
2695				return attributeNode && attributeNode.specified ?
2696					parseInt( attributeNode.value, 10 ) :
2697					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2698						0 :
2699						undefined;
2700			}
2701		}
2702	}
2703});
2704
2705// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
2706jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
2707
2708// Hook for boolean attributes
2709boolHook = {
2710	get: function( elem, name ) {
2711		// Align boolean attributes with corresponding properties
2712		// Fall back to attribute presence where some booleans are not supported
2713		var attrNode,
2714			property = jQuery.prop( elem, name );
2715		return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2716			name.toLowerCase() :
2717			undefined;
2718	},
2719	set: function( elem, value, name ) {
2720		var propName;
2721		if ( value === false ) {
2722			// Remove boolean attributes when set to false
2723			jQuery.removeAttr( elem, name );
2724		} else {
2725			// value is true since we know at this point it's type boolean and not false
2726			// Set boolean attributes to the same name and set the DOM property
2727			propName = jQuery.propFix[ name ] || name;
2728			if ( propName in elem ) {
2729				// Only set the IDL specifically if it already exists on the element
2730				elem[ propName ] = true;
2731			}
2732
2733			elem.setAttribute( name, name.toLowerCase() );
2734		}
2735		return name;
2736	}
2737};
2738
2739// IE6/7 do not support getting/setting some attributes with get/setAttribute
2740if ( !getSetAttribute ) {
2741
2742	fixSpecified = {
2743		name: true,
2744		id: true,
2745		coords: true
2746	};
2747
2748	// Use this for any attribute in IE6/7
2749	// This fixes almost every IE6/7 issue
2750	nodeHook = jQuery.valHooks.button = {
2751		get: function( elem, name ) {
2752			var ret;
2753			ret = elem.getAttributeNode( name );
2754			return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
2755				ret.nodeValue :
2756				undefined;
2757		},
2758		set: function( elem, value, name ) {
2759			// Set the existing or create a new attribute node
2760			var ret = elem.getAttributeNode( name );
2761			if ( !ret ) {
2762				ret = document.createAttribute( name );
2763				elem.setAttributeNode( ret );
2764			}
2765			return ( ret.nodeValue = value + "" );
2766		}
2767	};
2768
2769	// Apply the nodeHook to tabindex
2770	jQuery.attrHooks.tabindex.set = nodeHook.set;
2771
2772	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
2773	// This is for removals
2774	jQuery.each([ "width", "height" ], function( i, name ) {
2775		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2776			set: function( elem, value ) {
2777				if ( value === "" ) {
2778					elem.setAttribute( name, "auto" );
2779					return value;
2780				}
2781			}
2782		});
2783	});
2784
2785	// Set contenteditable to false on removals(#10429)
2786	// Setting to empty string throws an error as an invalid value
2787	jQuery.attrHooks.contenteditable = {
2788		get: nodeHook.get,
2789		set: function( elem, value, name ) {
2790			if ( value === "" ) {
2791				value = "false";
2792			}
2793			nodeHook.set( elem, value, name );
2794		}
2795	};
2796}
2797
2798
2799// Some attributes require a special call on IE
2800if ( !jQuery.support.hrefNormalized ) {
2801	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2802		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2803			get: function( elem ) {
2804				var ret = elem.getAttribute( name, 2 );
2805				return ret === null ? undefined : ret;
2806			}
2807		});
2808	});
2809}
2810
2811if ( !jQuery.support.style ) {
2812	jQuery.attrHooks.style = {
2813		get: function( elem ) {
2814			// Return undefined in the case of empty string
2815			// Normalize to lowercase since IE uppercases css property names
2816			return elem.style.cssText.toLowerCase() || undefined;
2817		},
2818		set: function( elem, value ) {
2819			return ( elem.style.cssText = "" + value );
2820		}
2821	};
2822}
2823
2824// Safari mis-reports the default selected property of an option
2825// Accessing the parent's selectedIndex property fixes it
2826if ( !jQuery.support.optSelected ) {
2827	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2828		get: function( elem ) {
2829			var parent = elem.parentNode;
2830
2831			if ( parent ) {
2832				parent.selectedIndex;
2833
2834				// Make sure that it also works with optgroups, see #5701
2835				if ( parent.parentNode ) {
2836					parent.parentNode.selectedIndex;
2837				}
2838			}
2839			return null;
2840		}
2841	});
2842}
2843
2844// IE6/7 call enctype encoding
2845if ( !jQuery.support.enctype ) {
2846	jQuery.propFix.enctype = "encoding";
2847}
2848
2849// Radios and checkboxes getter/setter
2850if ( !jQuery.support.checkOn ) {
2851	jQuery.each([ "radio", "checkbox" ], function() {
2852		jQuery.valHooks[ this ] = {
2853			get: function( elem ) {
2854				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2855				return elem.getAttribute("value") === null ? "on" : elem.value;
2856			}
2857		};
2858	});
2859}
2860jQuery.each([ "radio", "checkbox" ], function() {
2861	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2862		set: function( elem, value ) {
2863			if ( jQuery.isArray( value ) ) {
2864				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2865			}
2866		}
2867	});
2868});
2869
2870
2871
2872
2873var rformElems = /^(?:textarea|input|select)$/i,
2874	rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2875	rhoverHack = /(?:^|\s)hover(\.\S+)?\b/,
2876	rkeyEvent = /^key/,
2877	rmouseEvent = /^(?:mouse|contextmenu)|click/,
2878	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2879	rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2880	quickParse = function( selector ) {
2881		var quick = rquickIs.exec( selector );
2882		if ( quick ) {
2883			//   0  1    2   3
2884			// [ _, tag, id, class ]
2885			quick[1] = ( quick[1] || "" ).toLowerCase();
2886			quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2887		}
2888		return quick;
2889	},
2890	quickIs = function( elem, m ) {
2891		var attrs = elem.attributes || {};
2892		return (
2893			(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2894			(!m[2] || (attrs.id || {}).value === m[2]) &&
2895			(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
2896		);
2897	},
2898	hoverHack = function( events ) {
2899		return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2900	};
2901
2902/*
2903 * Helper functions for managing events -- not part of the public interface.
2904 * Props to Dean Edwards' addEvent library for many of the ideas.
2905 */
2906jQuery.event = {
2907
2908	add: function( elem, types, handler, data, selector ) {
2909
2910		var elemData, eventHandle, events,
2911			t, tns, type, namespaces, handleObj,
2912			handleObjIn, quick, handlers, special;
2913
2914		// Don't attach events to noData or text/comment nodes (allow plain objects tho)
2915		if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2916			return;
2917		}
2918
2919		// Caller can pass in an object of custom data in lieu of the handler
2920		if ( handler.handler ) {
2921			handleObjIn = handler;
2922			handler = handleObjIn.handler;
2923			selector = handleObjIn.selector;
2924		}
2925
2926		// Make sure that the handler has a unique ID, used to find/remove it later
2927		if ( !handler.guid ) {
2928			handler.guid = jQuery.guid++;
2929		}
2930
2931		// Init the element's event structure and main handler, if this is the first
2932		events = elemData.events;
2933		if ( !events ) {
2934			elemData.events = events = {};
2935		}
2936		eventHandle = elemData.handle;
2937		if ( !eventHandle ) {
2938			elemData.handle = eventHandle = function( e ) {
2939				// Discard the second event of a jQuery.event.trigger() and
2940				// when an event is called after a page has unloaded
2941				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2942					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2943					undefined;
2944			};
2945			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2946			eventHandle.elem = elem;
2947		}
2948
2949		// Handle multiple events separated by a space
2950		// jQuery(...).bind("mouseover mouseout", fn);
2951		types = jQuery.trim( hoverHack(types) ).split( " " );
2952		for ( t = 0; t < types.length; t++ ) {
2953
2954			tns = rtypenamespace.exec( types[t] ) || [];
2955			type = tns[1];
vendor: 29,262 bytes, lines 2956-3929
2956			namespaces = ( tns[2] || "" ).split( "." ).sort();
2957
2958			// If event changes its type, use the special event handlers for the changed type
2959			special = jQuery.event.special[ type ] || {};
2960
2961			// If selector defined, determine special event api type, otherwise given type
2962			type = ( selector ? special.delegateType : special.bindType ) || type;
2963
2964			// Update special based on newly reset type
2965			special = jQuery.event.special[ type ] || {};
2966
2967			// handleObj is passed to all event handlers
2968			handleObj = jQuery.extend({
2969				type: type,
2970				origType: tns[1],
2971				data: data,
2972				handler: handler,
2973				guid: handler.guid,
2974				selector: selector,
2975				quick: selector && quickParse( selector ),
2976				namespace: namespaces.join(".")
2977			}, handleObjIn );
2978
2979			// Init the event handler queue if we're the first
2980			handlers = events[ type ];
2981			if ( !handlers ) {
2982				handlers = events[ type ] = [];
2983				handlers.delegateCount = 0;
2984
2985				// Only use addEventListener/attachEvent if the special events handler returns false
2986				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2987					// Bind the global event handler to the element
2988					if ( elem.addEventListener ) {
2989						elem.addEventListener( type, eventHandle, false );
2990
2991					} else if ( elem.attachEvent ) {
2992						elem.attachEvent( "on" + type, eventHandle );
2993					}
2994				}
2995			}
2996
2997			if ( special.add ) {
2998				special.add.call( elem, handleObj );
2999
3000				if ( !handleObj.handler.guid ) {
3001					handleObj.handler.guid = handler.guid;
3002				}
3003			}
3004
3005			// Add to the element's handler list, delegates in front
3006			if ( selector ) {
3007				handlers.splice( handlers.delegateCount++, 0, handleObj );
3008			} else {
3009				handlers.push( handleObj );
3010			}
3011
3012			// Keep track of which events have ever been used, for event optimization
3013			jQuery.event.global[ type ] = true;
3014		}
3015
3016		// Nullify elem to prevent memory leaks in IE
3017		elem = null;
3018	},
3019
3020	global: {},
3021
3022	// Detach an event or set of events from an element
3023	remove: function( elem, types, handler, selector, mappedTypes ) {
3024
3025		var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3026			t, tns, type, origType, namespaces, origCount,
3027			j, events, special, handle, eventType, handleObj;
3028
3029		if ( !elemData || !(events = elemData.events) ) {
3030			return;
3031		}
3032
3033		// Once for each type.namespace in types; type may be omitted
3034		types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
3035		for ( t = 0; t < types.length; t++ ) {
3036			tns = rtypenamespace.exec( types[t] ) || [];
3037			type = origType = tns[1];
3038			namespaces = tns[2];
3039
3040			// Unbind all events (on this namespace, if provided) for the element
3041			if ( !type ) {
3042				for ( type in events ) {
3043					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
3044				}
3045				continue;
3046			}
3047
3048			special = jQuery.event.special[ type ] || {};
3049			type = ( selector? special.delegateType : special.bindType ) || type;
3050			eventType = events[ type ] || [];
3051			origCount = eventType.length;
3052			namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3053
3054			// Remove matching events
3055			for ( j = 0; j < eventType.length; j++ ) {
3056				handleObj = eventType[ j ];
3057
3058				if ( ( mappedTypes || origType === handleObj.origType ) &&
3059					 ( !handler || handler.guid === handleObj.guid ) &&
3060					 ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
3061					 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
3062					eventType.splice( j--, 1 );
3063
3064					if ( handleObj.selector ) {
3065						eventType.delegateCount--;
3066					}
3067					if ( special.remove ) {
3068						special.remove.call( elem, handleObj );
3069					}
3070				}
3071			}
3072
3073			// Remove generic event handler if we removed something and no more handlers exist
3074			// (avoids potential for endless recursion during removal of special event handlers)
3075			if ( eventType.length === 0 && origCount !== eventType.length ) {
3076				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3077					jQuery.removeEvent( elem, type, elemData.handle );
3078				}
3079
3080				delete events[ type ];
3081			}
3082		}
3083
3084		// Remove the expando if it's no longer used
3085		if ( jQuery.isEmptyObject( events ) ) {
3086			handle = elemData.handle;
3087			if ( handle ) {
3088				handle.elem = null;
3089			}
3090
3091			// removeData also checks for emptiness and clears the expando if empty
3092			// so use it instead of delete
3093			jQuery.removeData( elem, [ "events", "handle" ], true );
3094		}
3095	},
3096
3097	// Events that are safe to short-circuit if no handlers are attached.
3098	// Native DOM events should not be added, they may have inline handlers.
3099	customEvent: {
3100		"getData": true,
3101		"setData": true,
3102		"changeData": true
3103	},
3104
3105	trigger: function( event, data, elem, onlyHandlers ) {
3106		// Don't do events on text and comment nodes
3107		if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
3108			return;
3109		}
3110
3111		// Event object or event type
3112		var type = event.type || event,
3113			namespaces = [],
3114			cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
3115
3116		// focus/blur morphs to focusin/out; ensure we're not firing them right now
3117		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
3118			return;
3119		}
3120
3121		if ( type.indexOf( "!" ) >= 0 ) {
3122			// Exclusive events trigger only for the exact event (no namespaces)
3123			type = type.slice(0, -1);
3124			exclusive = true;
3125		}
3126
3127		if ( type.indexOf( "." ) >= 0 ) {
3128			// Namespaced trigger; create a regexp to match event type in handle()
3129			namespaces = type.split(".");
3130			type = namespaces.shift();
3131			namespaces.sort();
3132		}
3133
3134		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3135			// No jQuery handlers for this event type, and it can't have inline handlers
3136			return;
3137		}
3138
3139		// Caller can pass in an Event, Object, or just an event type string
3140		event = typeof event === "object" ?
3141			// jQuery.Event object
3142			event[ jQuery.expando ] ? event :
3143			// Object literal
3144			new jQuery.Event( type, event ) :
3145			// Just the event type (string)
3146			new jQuery.Event( type );
3147
3148		event.type = type;
3149		event.isTrigger = true;
3150		event.exclusive = exclusive;
3151		event.namespace = namespaces.join( "." );
3152		event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3153		ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
3154
3155		// Handle a global trigger
3156		if ( !elem ) {
3157
3158			// TODO: Stop taunting the data cache; remove global events and always attach to document
3159			cache = jQuery.cache;
3160			for ( i in cache ) {
3161				if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3162					jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
3163				}
3164			}
3165			return;
3166		}
3167
3168		// Clean up the event in case it is being reused
3169		event.result = undefined;
3170		if ( !event.target ) {
3171			event.target = elem;
3172		}
3173
3174		// Clone any incoming data and prepend the event, creating the handler arg list
3175		data = data != null ? jQuery.makeArray( data ) : [];
3176		data.unshift( event );
3177
3178		// Allow special events to draw outside the lines
3179		special = jQuery.event.special[ type ] || {};
3180		if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3181			return;
3182		}
3183
3184		// Determine event propagation path in advance, per W3C events spec (#9951)
3185		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3186		eventPath = [[ elem, special.bindType || type ]];
3187		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3188
3189			bubbleType = special.delegateType || type;
3190			cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
3191			old = null;
3192			for ( ; cur; cur = cur.parentNode ) {
3193				eventPath.push([ cur, bubbleType ]);
3194				old = cur;
3195			}
3196
3197			// Only add window if we got to document (e.g., not plain obj or detached DOM)
3198			if ( old && old === elem.ownerDocument ) {
3199				eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3200			}
3201		}
3202
3203		// Fire handlers on the event path
3204		for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
3205
3206			cur = eventPath[i][0];
3207			event.type = eventPath[i][1];
3208
3209			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
3210			if ( handle ) {
3211				handle.apply( cur, data );
3212			}
3213			// Note that this is a bare JS function and not a jQuery handler
3214			handle = ontype && cur[ ontype ];
3215			if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
3216				event.preventDefault();
3217			}
3218		}
3219		event.type = type;
3220
3221		// If nobody prevented the default action, do it now
3222		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
3223
3224			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3225				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3226
3227				// Call a native DOM method on the target with the same name name as the event.
3228				// Can't use an .isFunction() check here because IE6/7 fails that test.
3229				// Don't do default actions on window, that's where global variables be (#6170)
3230				// IE<9 dies on focus/blur to hidden element (#1486)
3231				if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3232
3233					// Don't re-trigger an onFOO event when we call its FOO() method
3234					old = elem[ ontype ];
3235
3236					if ( old ) {
3237						elem[ ontype ] = null;
3238					}
3239
3240					// Prevent re-triggering of the same event, since we already bubbled it above
3241					jQuery.event.triggered = type;
3242					elem[ type ]();
3243					jQuery.event.triggered = undefined;
3244
3245					if ( old ) {
3246						elem[ ontype ] = old;
3247					}
3248				}
3249			}
3250		}
3251
3252		return event.result;
3253	},
3254
3255	dispatch: function( event ) {
3256
3257		// Make a writable jQuery.Event from the native event object
3258		event = jQuery.event.fix( event || window.event );
3259
3260		var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3261			delegateCount = handlers.delegateCount,
3262			args = [].slice.call( arguments, 0 ),
3263			run_all = !event.exclusive && !event.namespace,
3264			special = jQuery.event.special[ event.type ] || {},
3265			handlerQueue = [],
3266			i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
3267
3268		// Use the fix-ed jQuery.Event rather than the (read-only) native event
3269		args[0] = event;
3270		event.delegateTarget = this;
3271
3272		// Call the preDispatch hook for the mapped type, and let it bail if desired
3273		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3274			return;
3275		}
3276
3277		// Determine handlers that should run if there are delegated events
3278		// Avoid non-left-click bubbling in Firefox (#3861)
3279		if ( delegateCount && !(event.button && event.type === "click") ) {
3280
3281			// Pregenerate a single jQuery object for reuse with .is()
3282			jqcur = jQuery(this);
3283			jqcur.context = this.ownerDocument || this;
3284
3285			for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3286
3287				// Don't process events on disabled elements (#6911, #8165)
3288				if ( cur.disabled !== true ) {
3289					selMatch = {};
3290					matches = [];
3291					jqcur[0] = cur;
3292					for ( i = 0; i < delegateCount; i++ ) {
3293						handleObj = handlers[ i ];
3294						sel = handleObj.selector;
3295
3296						if ( selMatch[ sel ] === undefined ) {
3297							selMatch[ sel ] = (
3298								handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
3299							);
3300						}
3301						if ( selMatch[ sel ] ) {
3302							matches.push( handleObj );
3303						}
3304					}
3305					if ( matches.length ) {
3306						handlerQueue.push({ elem: cur, matches: matches });
3307					}
3308				}
3309			}
3310		}
3311
3312		// Add the remaining (directly-bound) handlers
3313		if ( handlers.length > delegateCount ) {
3314			handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3315		}
3316
3317		// Run delegates first; they may want to stop propagation beneath us
3318		for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3319			matched = handlerQueue[ i ];
3320			event.currentTarget = matched.elem;
3321
3322			for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3323				handleObj = matched.matches[ j ];
3324
3325				// Triggered event must either 1) be non-exclusive and have no namespace, or
3326				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3327				if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3328
3329					event.data = handleObj.data;
3330					event.handleObj = handleObj;
3331
3332					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3333							.apply( matched.elem, args );
3334
3335					if ( ret !== undefined ) {
3336						event.result = ret;
3337						if ( ret === false ) {
3338							event.preventDefault();
3339							event.stopPropagation();
3340						}
3341					}
3342				}
3343			}
3344		}
3345
3346		// Call the postDispatch hook for the mapped type
3347		if ( special.postDispatch ) {
3348			special.postDispatch.call( this, event );
3349		}
3350
3351		return event.result;
3352	},
3353
3354	// Includes some event props shared by KeyEvent and MouseEvent
3355	// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3356	props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3357
3358	fixHooks: {},
3359
3360	keyHooks: {
3361		props: "char charCode key keyCode".split(" "),
3362		filter: function( event, original ) {
3363
3364			// Add which for key events
3365			if ( event.which == null ) {
3366				event.which = original.charCode != null ? original.charCode : original.keyCode;
3367			}
3368
3369			return event;
3370		}
3371	},
3372
3373	mouseHooks: {
3374		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3375		filter: function( event, original ) {
3376			var eventDoc, doc, body,
3377				button = original.button,
3378				fromElement = original.fromElement;
3379
3380			// Calculate pageX/Y if missing and clientX/Y available
3381			if ( event.pageX == null && original.clientX != null ) {
3382				eventDoc = event.target.ownerDocument || document;
3383				doc = eventDoc.documentElement;
3384				body = eventDoc.body;
3385
3386				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3387				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
3388			}
3389
3390			// Add relatedTarget, if necessary
3391			if ( !event.relatedTarget && fromElement ) {
3392				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3393			}
3394
3395			// Add which for click: 1 === left; 2 === middle; 3 === right
3396			// Note: button is not normalized, so don't use it
3397			if ( !event.which && button !== undefined ) {
3398				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3399			}
3400
3401			return event;
3402		}
3403	},
3404
3405	fix: function( event ) {
3406		if ( event[ jQuery.expando ] ) {
3407			return event;
3408		}
3409
3410		// Create a writable copy of the event object and normalize some properties
3411		var i, prop,
3412			originalEvent = event,
3413			fixHook = jQuery.event.fixHooks[ event.type ] || {},
3414			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3415
3416		event = jQuery.Event( originalEvent );
3417
3418		for ( i = copy.length; i; ) {
3419			prop = copy[ --i ];
3420			event[ prop ] = originalEvent[ prop ];
3421		}
3422
3423		// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3424		if ( !event.target ) {
3425			event.target = originalEvent.srcElement || document;
3426		}
3427
3428		// Target should not be a text node (#504, Safari)
3429		if ( event.target.nodeType === 3 ) {
3430			event.target = event.target.parentNode;
3431		}
3432
3433		// For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3434		if ( event.metaKey === undefined ) {
3435			event.metaKey = event.ctrlKey;
3436		}
3437
3438		return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3439	},
3440
3441	special: {
3442		ready: {
3443			// Make sure the ready event is setup
3444			setup: jQuery.bindReady
3445		},
3446
3447		load: {
3448			// Prevent triggered image.load events from bubbling to window.load
3449			noBubble: true
3450		},
3451
3452		focus: {
3453			delegateType: "focusin"
3454		},
3455		blur: {
3456			delegateType: "focusout"
3457		},
3458
3459		beforeunload: {
3460			setup: function( data, namespaces, eventHandle ) {
3461				// We only want to do this special case on windows
3462				if ( jQuery.isWindow( this ) ) {
3463					this.onbeforeunload = eventHandle;
3464				}
3465			},
3466
3467			teardown: function( namespaces, eventHandle ) {
3468				if ( this.onbeforeunload === eventHandle ) {
3469					this.onbeforeunload = null;
3470				}
3471			}
3472		}
3473	},
3474
3475	simulate: function( type, elem, event, bubble ) {
3476		// Piggyback on a donor event to simulate a different one.
3477		// Fake originalEvent to avoid donor's stopPropagation, but if the
3478		// simulated event prevents default then we do the same on the donor.
3479		var e = jQuery.extend(
3480			new jQuery.Event(),
3481			event,
3482			{ type: type,
3483				isSimulated: true,
3484				originalEvent: {}
3485			}
3486		);
3487		if ( bubble ) {
3488			jQuery.event.trigger( e, null, elem );
3489		} else {
3490			jQuery.event.dispatch.call( elem, e );
3491		}
3492		if ( e.isDefaultPrevented() ) {
3493			event.preventDefault();
3494		}
3495	}
3496};
3497
3498// Some plugins are using, but it's undocumented/deprecated and will be removed.
3499// The 1.7 special event interface should provide all the hooks needed now.
3500jQuery.event.handle = jQuery.event.dispatch;
3501
3502jQuery.removeEvent = document.removeEventListener ?
3503	function( elem, type, handle ) {
3504		if ( elem.removeEventListener ) {
3505			elem.removeEventListener( type, handle, false );
3506		}
3507	} :
3508	function( elem, type, handle ) {
3509		if ( elem.detachEvent ) {
3510			elem.detachEvent( "on" + type, handle );
3511		}
3512	};
3513
3514jQuery.Event = function( src, props ) {
3515	// Allow instantiation without the 'new' keyword
3516	if ( !(this instanceof jQuery.Event) ) {
3517		return new jQuery.Event( src, props );
3518	}
3519
3520	// Event object
3521	if ( src && src.type ) {
3522		this.originalEvent = src;
3523		this.type = src.type;
3524
3525		// Events bubbling up the document may have been marked as prevented
3526		// by a handler lower down the tree; reflect the correct value.
3527		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3528			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3529
3530	// Event type
3531	} else {
3532		this.type = src;
3533	}
3534
3535	// Put explicitly provided properties onto the event object
3536	if ( props ) {
3537		jQuery.extend( this, props );
3538	}
3539
3540	// Create a timestamp if incoming event doesn't have one
3541	this.timeStamp = src && src.timeStamp || jQuery.now();
3542
3543	// Mark it as fixed
3544	this[ jQuery.expando ] = true;
3545};
3546
3547function returnFalse() {
3548	return false;
3549}
3550function returnTrue() {
3551	return true;
3552}
3553
3554// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3555// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3556jQuery.Event.prototype = {
3557	preventDefault: function() {
3558		this.isDefaultPrevented = returnTrue;
3559
3560		var e = this.originalEvent;
3561		if ( !e ) {
3562			return;
3563		}
3564
3565		// if preventDefault exists run it on the original event
3566		if ( e.preventDefault ) {
3567			e.preventDefault();
3568
3569		// otherwise set the returnValue property of the original event to false (IE)
3570		} else {
3571			e.returnValue = false;
3572		}
3573	},
3574	stopPropagation: function() {
3575		this.isPropagationStopped = returnTrue;
3576
3577		var e = this.originalEvent;
3578		if ( !e ) {
3579			return;
3580		}
3581		// if stopPropagation exists run it on the original event
3582		if ( e.stopPropagation ) {
3583			e.stopPropagation();
3584		}
3585		// otherwise set the cancelBubble property of the original event to true (IE)
3586		e.cancelBubble = true;
3587	},
3588	stopImmediatePropagation: function() {
3589		this.isImmediatePropagationStopped = returnTrue;
3590		this.stopPropagation();
3591	},
3592	isDefaultPrevented: returnFalse,
3593	isPropagationStopped: returnFalse,
3594	isImmediatePropagationStopped: returnFalse
3595};
3596
3597// Create mouseenter/leave events using mouseover/out and event-time checks
3598jQuery.each({
3599	mouseenter: "mouseover",
3600	mouseleave: "mouseout"
3601}, function( orig, fix ) {
3602	jQuery.event.special[ orig ] = {
3603		delegateType: fix,
3604		bindType: fix,
3605
3606		handle: function( event ) {
3607			var target = this,
3608				related = event.relatedTarget,
3609				handleObj = event.handleObj,
3610				selector = handleObj.selector,
3611				ret;
3612
3613			// For mousenter/leave call the handler if related is outside the target.
3614			// NB: No relatedTarget if the mouse left/entered the browser window
3615			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3616				event.type = handleObj.origType;
3617				ret = handleObj.handler.apply( this, arguments );
3618				event.type = fix;
3619			}
3620			return ret;
3621		}
3622	};
3623});
3624
3625// IE submit delegation
3626if ( !jQuery.support.submitBubbles ) {
3627
3628	jQuery.event.special.submit = {
3629		setup: function() {
3630			// Only need this for delegated form submit events
3631			if ( jQuery.nodeName( this, "form" ) ) {
3632				return false;
3633			}
3634
3635			// Lazy-add a submit handler when a descendant form may potentially be submitted
3636			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3637				// Node name check avoids a VML-related crash in IE (#9807)
3638				var elem = e.target,
3639					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3640				if ( form && !form._submit_attached ) {
3641					jQuery.event.add( form, "submit._submit", function( event ) {
3642						event._submit_bubble = true;
3643					});
3644					form._submit_attached = true;
3645				}
3646			});
3647			// return undefined since we don't need an event listener
3648		},
3649		
3650		postDispatch: function( event ) {
3651			// If form was submitted by the user, bubble the event up the tree
3652			if ( event._submit_bubble ) {
3653				delete event._submit_bubble;
3654				if ( this.parentNode && !event.isTrigger ) {
3655					jQuery.event.simulate( "submit", this.parentNode, event, true );
3656				}
3657			}
3658		},
3659
3660		teardown: function() {
3661			// Only need this for delegated form submit events
3662			if ( jQuery.nodeName( this, "form" ) ) {
3663				return false;
3664			}
3665
3666			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3667			jQuery.event.remove( this, "._submit" );
3668		}
3669	};
3670}
3671
3672// IE change delegation and checkbox/radio fix
3673if ( !jQuery.support.changeBubbles ) {
3674
3675	jQuery.event.special.change = {
3676
3677		setup: function() {
3678
3679			if ( rformElems.test( this.nodeName ) ) {
3680				// IE doesn't fire change on a check/radio until blur; trigger it on click
3681				// after a propertychange. Eat the blur-change in special.change.handle.
3682				// This still fires onchange a second time for check/radio after blur.
3683				if ( this.type === "checkbox" || this.type === "radio" ) {
3684					jQuery.event.add( this, "propertychange._change", function( event ) {
3685						if ( event.originalEvent.propertyName === "checked" ) {
3686							this._just_changed = true;
3687						}
3688					});
3689					jQuery.event.add( this, "click._change", function( event ) {
3690						if ( this._just_changed && !event.isTrigger ) {
3691							this._just_changed = false;
3692							jQuery.event.simulate( "change", this, event, true );
3693						}
3694					});
3695				}
3696				return false;
3697			}
3698			// Delegated event; lazy-add a change handler on descendant inputs
3699			jQuery.event.add( this, "beforeactivate._change", function( e ) {
3700				var elem = e.target;
3701
3702				if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3703					jQuery.event.add( elem, "change._change", function( event ) {
3704						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3705							jQuery.event.simulate( "change", this.parentNode, event, true );
3706						}
3707					});
3708					elem._change_attached = true;
3709				}
3710			});
3711		},
3712
3713		handle: function( event ) {
3714			var elem = event.target;
3715
3716			// Swallow native change events from checkbox/radio, we already triggered them above
3717			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3718				return event.handleObj.handler.apply( this, arguments );
3719			}
3720		},
3721
3722		teardown: function() {
3723			jQuery.event.remove( this, "._change" );
3724
3725			return rformElems.test( this.nodeName );
3726		}
3727	};
3728}
3729
3730// Create "bubbling" focus and blur events
3731if ( !jQuery.support.focusinBubbles ) {
3732	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3733
3734		// Attach a single capturing handler while someone wants focusin/focusout
3735		var attaches = 0,
3736			handler = function( event ) {
3737				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3738			};
3739
3740		jQuery.event.special[ fix ] = {
3741			setup: function() {
3742				if ( attaches++ === 0 ) {
3743					document.addEventListener( orig, handler, true );
3744				}
3745			},
3746			teardown: function() {
3747				if ( --attaches === 0 ) {
3748					document.removeEventListener( orig, handler, true );
3749				}
3750			}
3751		};
3752	});
3753}
3754
3755jQuery.fn.extend({
3756
3757	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3758		var origFn, type;
3759
3760		// Types can be a map of types/handlers
3761		if ( typeof types === "object" ) {
3762			// ( types-Object, selector, data )
3763			if ( typeof selector !== "string" ) { // && selector != null
3764				// ( types-Object, data )
3765				data = data || selector;
3766				selector = undefined;
3767			}
3768			for ( type in types ) {
3769				this.on( type, selector, data, types[ type ], one );
3770			}
3771			return this;
3772		}
3773
3774		if ( data == null && fn == null ) {
3775			// ( types, fn )
3776			fn = selector;
3777			data = selector = undefined;
3778		} else if ( fn == null ) {
3779			if ( typeof selector === "string" ) {
3780				// ( types, selector, fn )
3781				fn = data;
3782				data = undefined;
3783			} else {
3784				// ( types, data, fn )
3785				fn = data;
3786				data = selector;
3787				selector = undefined;
3788			}
3789		}
3790		if ( fn === false ) {
3791			fn = returnFalse;
3792		} else if ( !fn ) {
3793			return this;
3794		}
3795
3796		if ( one === 1 ) {
3797			origFn = fn;
3798			fn = function( event ) {
3799				// Can use an empty set, since event contains the info
3800				jQuery().off( event );
3801				return origFn.apply( this, arguments );
3802			};
3803			// Use same guid so caller can remove using origFn
3804			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3805		}
3806		return this.each( function() {
3807			jQuery.event.add( this, types, fn, data, selector );
3808		});
3809	},
3810	one: function( types, selector, data, fn ) {
3811		return this.on( types, selector, data, fn, 1 );
3812	},
3813	off: function( types, selector, fn ) {
3814		if ( types && types.preventDefault && types.handleObj ) {
3815			// ( event )  dispatched jQuery.Event
3816			var handleObj = types.handleObj;
3817			jQuery( types.delegateTarget ).off(
3818				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3819				handleObj.selector,
3820				handleObj.handler
3821			);
3822			return this;
3823		}
3824		if ( typeof types === "object" ) {
3825			// ( types-object [, selector] )
3826			for ( var type in types ) {
3827				this.off( type, selector, types[ type ] );
3828			}
3829			return this;
3830		}
3831		if ( selector === false || typeof selector === "function" ) {
3832			// ( types [, fn] )
3833			fn = selector;
3834			selector = undefined;
3835		}
3836		if ( fn === false ) {
3837			fn = returnFalse;
3838		}
3839		return this.each(function() {
3840			jQuery.event.remove( this, types, fn, selector );
3841		});
3842	},
3843
3844	bind: function( types, data, fn ) {
3845		return this.on( types, null, data, fn );
3846	},
3847	unbind: function( types, fn ) {
3848		return this.off( types, null, fn );
3849	},
3850
3851	live: function( types, data, fn ) {
3852		jQuery( this.context ).on( types, this.selector, data, fn );
3853		return this;
3854	},
3855	die: function( types, fn ) {
3856		jQuery( this.context ).off( types, this.selector || "**", fn );
3857		return this;
3858	},
3859
3860	delegate: function( selector, types, data, fn ) {
3861		return this.on( types, selector, data, fn );
3862	},
3863	undelegate: function( selector, types, fn ) {
3864		// ( namespace ) or ( selector, types [, fn] )
3865		return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3866	},
3867
3868	trigger: function( type, data ) {
3869		return this.each(function() {
3870			jQuery.event.trigger( type, data, this );
3871		});
3872	},
3873	triggerHandler: function( type, data ) {
3874		if ( this[0] ) {
3875			return jQuery.event.trigger( type, data, this[0], true );
3876		}
3877	},
3878
3879	toggle: function( fn ) {
3880		// Save reference to arguments for access in closure
3881		var args = arguments,
3882			guid = fn.guid || jQuery.guid++,
3883			i = 0,
3884			toggler = function( event ) {
3885				// Figure out which function to execute
3886				var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3887				jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3888
3889				// Make sure that clicks stop
3890				event.preventDefault();
3891
3892				// and execute the function
3893				return args[ lastToggle ].apply( this, arguments ) || false;
3894			};
3895
3896		// link all the functions, so any of them can unbind this click handler
3897		toggler.guid = guid;
3898		while ( i < args.length ) {
3899			args[ i++ ].guid = guid;
3900		}
3901
3902		return this.click( toggler );
3903	},
3904
3905	hover: function( fnOver, fnOut ) {
3906		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3907	}
3908});
3909
3910jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3911	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3912	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3913
3914	// Handle event binding
3915	jQuery.fn[ name ] = function( data, fn ) {
3916		if ( fn == null ) {
3917			fn = data;
3918			data = null;
3919		}
3920
3921		return arguments.length > 0 ?
3922			this.on( name, null, data, fn ) :
3923			this.trigger( name );
3924	};
3925
3926	if ( jQuery.attrFn ) {
3927		jQuery.attrFn[ name ] = true;
3928	}
3929
3930	if ( rkeyEvent.test( name ) ) {
3931		jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3932	}
3933
3934	if ( rmouseEvent.test( name ) ) {
3935		jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3936	}
3937});
3938
3939
3940
3941/*!
3942 * Sizzle CSS Selector Engine
3943 *  Copyright 2011, The Dojo Foundation
3944 *  Released under the MIT, BSD, and GPL Licenses.
3945 *  More information: http://sizzlejs.com/
3946 */
3947(function(){
3948
3949var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3950	expando = "sizcache" + (Math.random() + '').replace('.', ''),
3951	done = 0,
3952	toString = Object.prototype.toString,
3953	hasDuplicate = false,
3954	baseHasDuplicate = true,
3955	rBackslash = /\\/g,
3956	rReturn = /\r\n/g,
3957	rNonWord = /\W/;
3958
3959// Here we check if the JavaScript engine is using some sort of
3960// optimization where it does not always call our comparision
3961// function. If that is the case, discard the hasDuplicate value.
3962//   Thus far that includes Google Chrome.
3963[0, 0].sort(function() {
3964	baseHasDuplicate = false;
3965	return 0;
3966});
3967
3968var Sizzle = function( selector, context, results, seed ) {
3969	results = results || [];
3970	context = context || document;
3971
3972	var origContext = context;
3973
3974	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3975		return [];
3976	}
3977
3978	if ( !selector || typeof selector !== "string" ) {
3979		return results;
3980	}
3981
3982	var m, set, checkSet, extra, ret, cur, pop, i,
3983		prune = true,
3984		contextXML = Sizzle.isXML( context ),
3985		parts = [],
3986		soFar = selector;
3987
3988	// Reset the position of the chunker regexp (start from head)
3989	do {
3990		chunker.exec( "" );
3991		m = chunker.exec( soFar );
3992
3993		if ( m ) {
3994			soFar = m[3];
3995
3996			parts.push( m[1] );
3997
3998			if ( m[2] ) {
3999				extra = m[3];
4000				break;
4001			}
4002		}
4003	} while ( m );
4004
4005	if ( parts.length > 1 && origPOS.exec( selector ) ) {
4006
4007		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4008			set = posProcess( parts[0] + parts[1], context, seed );
4009
4010		} else {
4011			set = Expr.relative[ parts[0] ] ?
4012				[ context ] :
4013				Sizzle( parts.shift(), context );
4014
4015			while ( parts.length ) {
4016				selector = parts.shift();
4017
4018				if ( Expr.relative[ selector ] ) {
4019					selector += parts.shift();
4020				}
4021
4022				set = posProcess( selector, set, seed );
4023			}
4024		}
4025
4026	} else {
4027		// Take a shortcut and set the context if the root selector is an ID
4028		// (but not if it'll be faster if the inner selector is an ID)
4029		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4030				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4031
4032			ret = Sizzle.find( parts.shift(), context, contextXML );
4033			context = ret.expr ?
4034				Sizzle.filter( ret.expr, ret.set )[0] :
4035				ret.set[0];
4036		}
4037
4038		if ( context ) {
4039			ret = seed ?
4040				{ expr: parts.pop(), set: makeArray(seed) } :
4041				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4042
4043			set = ret.expr ?
4044				Sizzle.filter( ret.expr, ret.set ) :
4045				ret.set;
4046
4047			if ( parts.length > 0 ) {
4048				checkSet = makeArray( set );
4049
4050			} else {
4051				prune = false;
4052			}
4053
4054			while ( parts.length ) {
4055				cur = parts.pop();
4056				pop = cur;
4057
4058				if ( !Expr.relative[ cur ] ) {
4059					cur = "";
4060				} else {
4061					pop = parts.pop();
4062				}
4063
4064				if ( pop == null ) {
4065					pop = context;
4066				}
4067
4068				Expr.relative[ cur ]( checkSet, pop, contextXML );
4069			}
4070
4071		} else {
4072			checkSet = parts = [];
4073		}
4074	}
4075
4076	if ( !checkSet ) {
4077		checkSet = set;
4078	}
4079
4080	if ( !checkSet ) {
4081		Sizzle.error( cur || selector );
4082	}
4083
4084	if ( toString.call(checkSet) === "[object Array]" ) {
4085		if ( !prune ) {
4086			results.push.apply( results, checkSet );
4087
4088		} else if ( context && context.nodeType === 1 ) {
4089			for ( i = 0; checkSet[i] != null; i++ ) {
4090				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4091					results.push( set[i] );
4092				}
4093			}
4094
4095		} else {
4096			for ( i = 0; checkSet[i] != null; i++ ) {
4097				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4098					results.push( set[i] );
4099				}
4100			}
4101		}
4102
4103	} else {
4104		makeArray( checkSet, results );
4105	}
4106
4107	if ( extra ) {
4108		Sizzle( extra, origContext, results, seed );
4109		Sizzle.uniqueSort( results );
4110	}
4111
4112	return results;
4113};
4114
4115Sizzle.uniqueSort = function( results ) {
4116	if ( sortOrder ) {
4117		hasDuplicate = baseHasDuplicate;
4118		results.sort( sortOrder );
4119
4120		if ( hasDuplicate ) {
4121			for ( var i = 1; i < results.length; i++ ) {
4122				if ( results[i] === results[ i - 1 ] ) {
4123					results.splice( i--, 1 );
4124				}
4125			}
4126		}
4127	}
4128
4129	return results;
4130};
4131
4132Sizzle.matches = function( expr, set ) {
4133	return Sizzle( expr, null, null, set );
4134};
4135
4136Sizzle.matchesSelector = function( node, expr ) {
4137	return Sizzle( expr, null, null, [node] ).length > 0;
4138};
4139
4140Sizzle.find = function( expr, context, isXML ) {
4141	var set, i, len, match, type, left;
4142
4143	if ( !expr ) {
4144		return [];
4145	}
4146
4147	for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4148		type = Expr.order[i];
4149
4150		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4151			left = match[1];
4152			match.splice( 1, 1 );
4153
4154			if ( left.substr( left.length - 1 ) !== "\\" ) {
4155				match[1] = (match[1] || "").replace( rBackslash, "" );
4156				set = Expr.find[ type ]( match, context, isXML );
4157
4158				if ( set != null ) {
4159					expr = expr.replace( Expr.match[ type ], "" );
4160					break;
4161				}
4162			}
4163		}
4164	}
4165
4166	if ( !set ) {
4167		set = typeof context.getElementsByTagName !== "undefined" ?
4168			context.getElementsByTagName( "*" ) :
4169			[];
4170	}
4171
4172	return { set: set, expr: expr };
4173};
4174
4175Sizzle.filter = function( expr, set, inplace, not ) {
4176	var match, anyFound,
4177		type, found, item, filter, left,
4178		i, pass,
4179		old = expr,
4180		result = [],
4181		curLoop = set,
4182		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4183
4184	while ( expr && set.length ) {
4185		for ( type in Expr.filter ) {
4186			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4187				filter = Expr.filter[ type ];
4188				left = match[1];
4189
4190				anyFound = false;
4191
4192				match.splice(1,1);
4193
4194				if ( left.substr( left.length - 1 ) === "\\" ) {
4195					continue;
4196				}
4197
4198				if ( curLoop === result ) {
4199					result = [];
4200				}
4201
4202				if ( Expr.preFilter[ type ] ) {
4203					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4204
4205					if ( !match ) {
4206						anyFound = found = true;
4207
4208					} else if ( match === true ) {
4209						continue;
4210					}
4211				}
4212
4213				if ( match ) {
4214					for ( i = 0; (item = curLoop[i]) != null; i++ ) {
4215						if ( item ) {
4216							found = filter( item, match, i, curLoop );
4217							pass = not ^ found;
4218
4219							if ( inplace && found != null ) {
4220								if ( pass ) {
4221									anyFound = true;
4222
4223								} else {
4224									curLoop[i] = false;
4225								}
4226
4227							} else if ( pass ) {
4228								result.push( item );
4229								anyFound = true;
4230							}
4231						}
4232					}
4233				}
4234
4235				if ( found !== undefined ) {
4236					if ( !inplace ) {
4237						curLoop = result;
4238					}
4239
4240					expr = expr.replace( Expr.match[ type ], "" );
4241
4242					if ( !anyFound ) {
4243						return [];
4244					}
4245
4246					break;
4247				}
4248			}
4249		}
4250
4251		// Improper expression
4252		if ( expr === old ) {
4253			if ( anyFound == null ) {
4254				Sizzle.error( expr );
4255
4256			} else {
4257				break;
4258			}
4259		}
4260
4261		old = expr;
4262	}
4263
4264	return curLoop;
4265};
4266
4267Sizzle.error = function( msg ) {
4268	throw new Error( "Syntax error, unrecognized expression: " + msg );
4269};
4270
4271/**
4272 * Utility function for retreiving the text value of an array of DOM nodes
4273 * @param {Array|Element} elem
4274 */
4275var getText = Sizzle.getText = function( elem ) {
4276    var i, node,
4277		nodeType = elem.nodeType,
4278		ret = "";
4279
4280	if ( nodeType ) {
4281		if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
4282			// Use textContent || innerText for elements
4283			if ( typeof elem.textContent === 'string' ) {
4284				return elem.textContent;
4285			} else if ( typeof elem.innerText === 'string' ) {
4286				// Replace IE's carriage returns
4287				return elem.innerText.replace( rReturn, '' );
4288			} else {
4289				// Traverse it's children
4290				for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
4291					ret += getText( elem );
4292				}
4293			}
4294		} else if ( nodeType === 3 || nodeType === 4 ) {
4295			return elem.nodeValue;
4296		}
4297	} else {
4298
4299		// If no nodeType, this is expected to be an array
4300		for ( i = 0; (node = elem[i]); i++ ) {
4301			// Do not traverse comment nodes
4302			if ( node.nodeType !== 8 ) {
4303				ret += getText( node );
4304			}
4305		}
4306	}
4307	return ret;
4308};
4309
4310var Expr = Sizzle.selectors = {
4311	order: [ "ID", "NAME", "TAG" ],
4312
4313	match: {
4314		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4315		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4316		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4317		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4318		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4319		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4320		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4321		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4322	},
4323
4324	leftMatch: {},
4325
4326	attrMap: {
4327		"class": "className",
4328		"for": "htmlFor"
4329	},
4330
4331	attrHandle: {
4332		href: function( elem ) {
4333			return elem.getAttribute( "href" );
4334		},
4335		type: function( elem ) {
4336			return elem.getAttribute( "type" );
4337		}
4338	},
4339
4340	relative: {
4341		"+": function(checkSet, part){
4342			var isPartStr = typeof part === "string",
4343				isTag = isPartStr && !rNonWord.test( part ),
4344				isPartStrNotTag = isPartStr && !isTag;
4345
4346			if ( isTag ) {
4347				part = part.toLowerCase();
4348			}
4349
4350			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4351				if ( (elem = checkSet[i]) ) {
4352					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4353
4354					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4355						elem || false :
4356						elem === part;
4357				}
4358			}
4359
4360			if ( isPartStrNotTag ) {
4361				Sizzle.filter( part, checkSet, true );
4362			}
4363		},
4364
4365		">": function( checkSet, part ) {
4366			var elem,
4367				isPartStr = typeof part === "string",
4368				i = 0,
4369				l = checkSet.length;
4370
4371			if ( isPartStr && !rNonWord.test( part ) ) {
4372				part = part.toLowerCase();
4373
4374				for ( ; i < l; i++ ) {
4375					elem = checkSet[i];
4376
4377					if ( elem ) {
4378						var parent = elem.parentNode;
4379						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4380					}
4381				}
4382
4383			} else {
4384				for ( ; i < l; i++ ) {
4385					elem = checkSet[i];
4386
4387					if ( elem ) {
4388						checkSet[i] = isPartStr ?
4389							elem.parentNode :
4390							elem.parentNode === part;
4391					}
4392				}
4393
4394				if ( isPartStr ) {
4395					Sizzle.filter( part, checkSet, true );
4396				}
4397			}
4398		},
4399
4400		"": function(checkSet, part, isXML){
4401			var nodeCheck,
4402				doneName = done++,
4403				checkFn = dirCheck;
4404
4405			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4406				part = part.toLowerCase();
4407				nodeCheck = part;
4408				checkFn = dirNodeCheck;
4409			}
4410
4411			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4412		},
4413
4414		"~": function( checkSet, part, isXML ) {
4415			var nodeCheck,
4416				doneName = done++,
4417				checkFn = dirCheck;
4418
4419			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4420				part = part.toLowerCase();
4421				nodeCheck = part;
4422				checkFn = dirNodeCheck;
4423			}
4424
4425			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4426		}
4427	},
4428
4429	find: {
4430		ID: function( match, context, isXML ) {
4431			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4432				var m = context.getElementById(match[1]);
4433				// Check parentNode to catch when Blackberry 4.6 returns
4434				// nodes that are no longer in the document #6963
4435				return m && m.parentNode ? [m] : [];
4436			}
4437		},
4438
4439		NAME: function( match, context ) {
4440			if ( typeof context.getElementsByName !== "undefined" ) {
4441				var ret = [],
4442					results = context.getElementsByName( match[1] );
4443
4444				for ( var i = 0, l = results.length; i < l; i++ ) {
4445					if ( results[i].getAttribute("name") === match[1] ) {
4446						ret.push( results[i] );
4447					}
4448				}
4449
4450				return ret.length === 0 ? null : ret;
4451			}
4452		},
4453
4454		TAG: function( match, context ) {
4455			if ( typeof context.getElementsByTagName !== "undefined" ) {
4456				return context.getElementsByTagName( match[1] );
4457			}
4458		}
4459	},
4460	preFilter: {
4461		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4462			match = " " + match[1].replace( rBackslash, "" ) + " ";
4463
4464			if ( isXML ) {
4465				return match;
4466			}
4467
4468			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4469				if ( elem ) {
4470					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4471						if ( !inplace ) {
4472							result.push( elem );
4473						}
4474
4475					} else if ( inplace ) {
4476						curLoop[i] = false;
4477					}
4478				}
4479			}
4480
4481			return false;
4482		},
4483
4484		ID: function( match ) {
4485			return match[1].replace( rBackslash, "" );
4486		},
4487
4488		TAG: function( match, curLoop ) {
4489			return match[1].replace( rBackslash, "" ).toLowerCase();
4490		},
4491
4492		CHILD: function( match ) {
4493			if ( match[1] === "nth" ) {
4494				if ( !match[2] ) {
4495					Sizzle.error( match[0] );
4496				}
4497
4498				match[2] = match[2].replace(/^\+|\s*/g, '');
4499
4500				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4501				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4502					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4503					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4504
4505				// calculate the numbers (first)n+(last) including if they are negative
4506				match[2] = (test[1] + (test[2] || 1)) - 0;
4507				match[3] = test[3] - 0;
4508			}
4509			else if ( match[2] ) {
4510				Sizzle.error( match[0] );
4511			}
4512
4513			// TODO: Move to normal caching system
4514			match[0] = done++;
4515
4516			return match;
4517		},
4518
4519		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4520			var name = match[1] = match[1].replace( rBackslash, "" );
4521
4522			if ( !isXML && Expr.attrMap[name] ) {
4523				match[1] = Expr.attrMap[name];
4524			}
4525
4526			// Handle if an un-quoted value was used
4527			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4528
4529			if ( match[2] === "~=" ) {
4530				match[4] = " " + match[4] + " ";
4531			}
4532
4533			return match;
4534		},
4535
4536		PSEUDO: function( match, curLoop, inplace, result, not ) {
4537			if ( match[1] === "not" ) {
4538				// If we're dealing with a complex expression, or a simple one
4539				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4540					match[3] = Sizzle(match[3], null, null, curLoop);
4541
4542				} else {
4543					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4544
4545					if ( !inplace ) {
4546						result.push.apply( result, ret );
4547					}
4548
4549					return false;
4550				}
4551
4552			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4553				return true;
4554			}
4555
4556			return match;
4557		},
4558
4559		POS: function( match ) {
4560			match.unshift( true );
4561
4562			return match;
4563		}
4564	},
4565
4566	filters: {
4567		enabled: function( elem ) {
4568			return elem.disabled === false && elem.type !== "hidden";
4569		},
4570
4571		disabled: function( elem ) {
4572			return elem.disabled === true;
4573		},
4574
4575		checked: function( elem ) {
4576			return elem.checked === true;
4577		},
4578
4579		selected: function( elem ) {
4580			// Accessing this property makes selected-by-default
4581			// options in Safari work properly
4582			if ( elem.parentNode ) {
4583				elem.parentNode.selectedIndex;
4584			}
4585
4586			return elem.selected === true;
4587		},
4588
4589		parent: function( elem ) {
4590			return !!elem.firstChild;
4591		},
4592
4593		empty: function( elem ) {
4594			return !elem.firstChild;
4595		},
4596
4597		has: function( elem, i, match ) {
4598			return !!Sizzle( match[3], elem ).length;
4599		},
4600
4601		header: function( elem ) {
4602			return (/h\d/i).test( elem.nodeName );
4603		},
4604
4605		text: function( elem ) {
4606			var attr = elem.getAttribute( "type" ), type = elem.type;
4607			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4608			// use getAttribute instead to test this case
4609			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4610		},
4611
4612		radio: function( elem ) {
4613			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4614		},
4615
4616		checkbox: function( elem ) {
4617			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4618		},
4619
4620		file: function( elem ) {
4621			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4622		},
4623
4624		password: function( elem ) {
4625			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4626		},
4627
4628		submit: function( elem ) {
4629			var name = elem.nodeName.toLowerCase();
4630			return (name === "input" || name === "button") && "submit" === elem.type;
4631		},
4632
4633		image: function( elem ) {
4634			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4635		},
4636
4637		reset: function( elem ) {
4638			var name = elem.nodeName.toLowerCase();
4639			return (name === "input" || name === "button") && "reset" === elem.type;
4640		},
4641
4642		button: function( elem ) {
4643			var name = elem.nodeName.toLowerCase();
4644			return name === "input" && "button" === elem.type || name === "button";
4645		},
4646
4647		input: function( elem ) {
4648			return (/input|select|textarea|button/i).test( elem.nodeName );
4649		},
4650
4651		focus: function( elem ) {
4652			return elem === elem.ownerDocument.activeElement;
4653		}
4654	},
4655	setFilters: {
4656		first: function( elem, i ) {
4657			return i === 0;
4658		},
4659
4660		last: function( elem, i, match, array ) {
4661			return i === array.length - 1;
4662		},
4663
4664		even: function( elem, i ) {
4665			return i % 2 === 0;
4666		},
4667
4668		odd: function( elem, i ) {
4669			return i % 2 === 1;
4670		},
4671
4672		lt: function( elem, i, match ) {
4673			return i < match[3] - 0;
4674		},
4675
4676		gt: function( elem, i, match ) {
4677			return i > match[3] - 0;
4678		},
4679
4680		nth: function( elem, i, match ) {
4681			return match[3] - 0 === i;
4682		},
4683
4684		eq: function( elem, i, match ) {
4685			return match[3] - 0 === i;
4686		}
4687	},
4688	filter: {
4689		PSEUDO: function( elem, match, i, array ) {
4690			var name = match[1],
4691				filter = Expr.filters[ name ];
4692
4693			if ( filter ) {
4694				return filter( elem, i, match, array );
4695
4696			} else if ( name === "contains" ) {
4697				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
4698
4699			} else if ( name === "not" ) {
4700				var not = match[3];
4701
4702				for ( var j = 0, l = not.length; j < l; j++ ) {
4703					if ( not[j] === elem ) {
4704						return false;
4705					}
4706				}
4707
4708				return true;
4709
4710			} else {
4711				Sizzle.error( name );
4712			}
4713		},
4714
4715		CHILD: function( elem, match ) {
4716			var first, last,
4717				doneName, parent, cache,
4718				count, diff,
4719				type = match[1],
4720				node = elem;
4721
4722			switch ( type ) {
4723				case "only":
4724				case "first":
4725					while ( (node = node.previousSibling) ) {
4726						if ( node.nodeType === 1 ) {
4727							return false;
4728						}
4729					}
4730
4731					if ( type === "first" ) {
4732						return true;
4733					}
4734
4735					node = elem;
4736
4737					/* falls through */
4738				case "last":
4739					while ( (node = node.nextSibling) ) {
4740						if ( node.nodeType === 1 ) {
4741							return false;
4742						}
4743					}
4744
4745					return true;
4746
4747				case "nth":
4748					first = match[2];
4749					last = match[3];
4750
4751					if ( first === 1 && last === 0 ) {
4752						return true;
4753					}
4754
4755					doneName = match[0];
4756					parent = elem.parentNode;
4757
4758					if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
4759						count = 0;
4760
4761						for ( node = parent.firstChild; node; node = node.nextSibling ) {
4762							if ( node.nodeType === 1 ) {
4763								node.nodeIndex = ++count;
4764							}
4765						}
4766
4767						parent[ expando ] = doneName;
4768					}
4769
4770					diff = elem.nodeIndex - last;
4771
4772					if ( first === 0 ) {
4773						return diff === 0;
4774
4775					} else {
4776						return ( diff % first === 0 && diff / first >= 0 );
4777					}
4778			}
4779		},
4780
4781		ID: function( elem, match ) {
4782			return elem.nodeType === 1 && elem.getAttribute("id") === match;
4783		},
4784
4785		TAG: function( elem, match ) {
4786			return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
4787		},
4788
4789		CLASS: function( elem, match ) {
4790			return (" " + (elem.className || elem.getAttribute("class")) + " ")
4791				.indexOf( match ) > -1;
4792		},
4793
4794		ATTR: function( elem, match ) {
4795			var name = match[1],
4796				result = Sizzle.attr ?
4797					Sizzle.attr( elem, name ) :
4798					Expr.attrHandle[ name ] ?
4799					Expr.attrHandle[ name ]( elem ) :
4800					elem[ name ] != null ?
4801						elem[ name ] :
4802						elem.getAttribute( name ),
4803				value = result + "",
4804				type = match[2],
4805				check = match[4];
4806
4807			return result == null ?
4808				type === "!=" :
4809				!type && Sizzle.attr ?
4810				result != null :
4811				type === "=" ?
4812				value === check :
4813				type === "*=" ?
4814				value.indexOf(check) >= 0 :
4815				type === "~=" ?
4816				(" " + value + " ").indexOf(check) >= 0 :
4817				!check ?
4818				value && result !== false :
4819				type === "!=" ?
4820				value !== check :
4821				type === "^=" ?
4822				value.indexOf(check) === 0 :
4823				type === "$=" ?
4824				value.substr(value.length - check.length) === check :
4825				type === "|=" ?
4826				value === check || value.substr(0, check.length + 1) === check + "-" :
4827				false;
4828		},
4829
4830		POS: function( elem, match, i, array ) {
4831			var name = match[2],
4832				filter = Expr.setFilters[ name ];
4833
4834			if ( filter ) {
4835				return filter( elem, i, match, array );
4836			}
4837		}
4838	}
4839};
4840
4841var origPOS = Expr.match.POS,
4842	fescape = function(all, num){
4843		return "\\" + (num - 0 + 1);
4844	};
4845
4846for ( var type in Expr.match ) {
4847	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4848	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4849}
4850// Expose origPOS
4851// "global" as in regardless of relation to brackets/parens
4852Expr.match.globalPOS = origPOS;
4853
4854var makeArray = function( array, results ) {
4855	array = Array.prototype.slice.call( array, 0 );
4856
4857	if ( results ) {
4858		results.push.apply( results, array );
4859		return results;
4860	}
4861
4862	return array;
4863};
4864
4865// Perform a simple check to determine if the browser is capable of
4866// converting a NodeList to an array using builtin methods.
4867// Also verifies that the returned array holds DOM nodes
4868// (which is not the case in the Blackberry browser)
4869try {
4870	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4871
4872// Provide a fallback method if it does not work
4873} catch( e ) {
4874	makeArray = function( array, results ) {
4875		var i = 0,
4876			ret = results || [];
4877
4878		if ( toString.call(array) === "[object Array]" ) {
4879			Array.prototype.push.apply( ret, array );
4880
4881		} else {
4882			if ( typeof array.length === "number" ) {
4883				for ( var l = array.length; i < l; i++ ) {
4884					ret.push( array[i] );
4885				}
4886
4887			} else {
4888				for ( ; array[i]; i++ ) {
4889					ret.push( array[i] );
4890				}
4891			}
4892		}
4893
4894		return ret;
4895	};
4896}
4897
4898var sortOrder, siblingCheck;
4899
4900if ( document.documentElement.compareDocumentPosition ) {
4901	sortOrder = function( a, b ) {
4902		if ( a === b ) {
4903			hasDuplicate = true;
4904			return 0;
4905		}
4906
4907		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4908			return a.compareDocumentPosition ? -1 : 1;
4909		}
4910
4911		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4912	};
4913
4914} else {
4915	sortOrder = function( a, b ) {
4916		// The nodes are identical, we can exit early
4917		if ( a === b ) {
4918			hasDuplicate = true;
4919			return 0;
4920
4921		// Fallback to using sourceIndex (in IE) if it's available on both nodes
4922		} else if ( a.sourceIndex && b.sourceIndex ) {
4923			return a.sourceIndex - b.sourceIndex;
4924		}
4925
4926		var al, bl,
4927			ap = [],
4928			bp = [],
4929			aup = a.parentNode,
4930			bup = b.parentNode,
4931			cur = aup;
4932
4933		// If the nodes are siblings (or identical) we can do a quick check
4934		if ( aup === bup ) {
4935			return siblingCheck( a, b );
4936
4937		// If no parents were found then the nodes are disconnected
4938		} else if ( !aup ) {
4939			return -1;
4940
4941		} else if ( !bup ) {
4942			return 1;
4943		}
4944
4945		// Otherwise they're somewhere else in the tree so we need
4946		// to build up a full list of the parentNodes for comparison
4947		while ( cur ) {
4948			ap.unshift( cur );
4949			cur = cur.parentNode;
4950		}
4951
4952		cur = bup;
4953
4954		while ( cur ) {
4955			bp.unshift( cur );
4956			cur = cur.parentNode;
4957		}
4958
4959		al = ap.length;
4960		bl = bp.length;
4961
4962		// Start walking down the tree looking for a discrepancy
4963		for ( var i = 0; i < al && i < bl; i++ ) {
4964			if ( ap[i] !== bp[i] ) {
4965				return siblingCheck( ap[i], bp[i] );
4966			}
4967		}
4968
4969		// We ended someplace up the tree so do a sibling check
4970		return i === al ?
4971			siblingCheck( a, bp[i], -1 ) :
4972			siblingCheck( ap[i], b, 1 );
4973	};
4974
4975	siblingCheck = function( a, b, ret ) {
4976		if ( a === b ) {
4977			return ret;
4978		}
4979
4980		var cur = a.nextSibling;
4981
4982		while ( cur ) {
4983			if ( cur === b ) {
4984				return -1;
4985			}
4986
4987			cur = cur.nextSibling;
4988		}
4989
4990		return 1;
4991	};
4992}
4993
4994// Check to see if the browser returns elements by name when
4995// querying by getElementById (and provide a workaround)
4996(function(){
4997	// We're going to inject a fake input element with a specified name
4998	var form = document.createElement("div"),
4999		id = "script" + (new Date()).getTime(),
5000		root = document.documentElement;
5001
5002	form.innerHTML = "<a name='" + id + "'/>";
5003
5004	// Inject it into the root element, check its status, and remove it quickly
5005	root.insertBefore( form, root.firstChild );
5006
5007	// The workaround has to do additional checks after a getElementById
5008	// Which slows things down for other browsers (hence the branching)
5009	if ( document.getElementById( id ) ) {
5010		Expr.find.ID = function( match, context, isXML ) {
5011			if ( typeof context.getElementById !== "undefined" && !isXML ) {
5012				var m = context.getElementById(match[1]);
5013
5014				return m ?
5015					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
5016						[m] :
5017						undefined :
5018					[];
5019			}
5020		};
5021
5022		Expr.filter.ID = function( elem, match ) {
5023			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
5024
5025			return elem.nodeType === 1 && node && node.nodeValue === match;
5026		};
5027	}
5028
5029	root.removeChild( form );
5030
5031	// release memory in IE
5032	root = form = null;
5033})();
5034
5035(function(){
5036	// Check to see if the browser returns only elements
5037	// when doing getElementsByTagName("*")
5038
5039	// Create a fake element
5040	var div = document.createElement("div");
5041	div.appendChild( document.createComment("") );
5042
5043	// Make sure no comments are found
5044	if ( div.getElementsByTagName("*").length > 0 ) {
5045		Expr.find.TAG = function( match, context ) {
5046			var results = context.getElementsByTagName( match[1] );
5047
5048			// Filter out possible comments
5049			if ( match[1] === "*" ) {
5050				var tmp = [];
5051
5052				for ( var i = 0; results[i]; i++ ) {
5053					if ( results[i].nodeType === 1 ) {
5054						tmp.push( results[i] );
5055					}
5056				}
5057
5058				results = tmp;
5059			}
5060
5061			return results;
5062		};
5063	}
5064
5065	// Check to see if an attribute returns normalized href attributes
5066	div.innerHTML = "<a href='#'></a>";
5067
5068	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5069			div.firstChild.getAttribute("href") !== "#" ) {
5070
5071		Expr.attrHandle.href = function( elem ) {
5072			return elem.getAttribute( "href", 2 );
5073		};
5074	}
5075
5076	// release memory in IE
5077	div = null;
5078})();
5079
5080if ( document.querySelectorAll ) {
5081	(function(){
5082		var oldSizzle = Sizzle,
5083			div = document.createElement("div"),
5084			id = "__sizzle__";
5085
5086		div.innerHTML = "<p class='TEST'></p>";
5087
5088		// Safari can't handle uppercase or unicode characters when
5089		// in quirks mode.
5090		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5091			return;
5092		}
5093
5094		Sizzle = function( query, context, extra, seed ) {
5095			context = context || document;
5096
5097			// Only use querySelectorAll on non-XML documents
5098			// (ID selectors don't work in non-HTML documents)
5099			if ( !seed && !Sizzle.isXML(context) ) {
5100				// See if we find a selector to speed up
5101				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5102
5103				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5104					// Speed-up: Sizzle("TAG")
5105					if ( match[1] ) {
5106						return makeArray( context.getElementsByTagName( query ), extra );
5107
5108					// Speed-up: Sizzle(".CLASS")
5109					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5110						return makeArray( context.getElementsByClassName( match[2] ), extra );
5111					}
5112				}
5113
5114				if ( context.nodeType === 9 ) {
5115					// Speed-up: Sizzle("body")
5116					// The body element only exists once, optimize finding it
5117					if ( query === "body" && context.body ) {
5118						return makeArray( [ context.body ], extra );
5119
5120					// Speed-up: Sizzle("#ID")
5121					} else if ( match && match[3] ) {
5122						var elem = context.getElementById( match[3] );
5123
5124						// Check parentNode to catch when Blackberry 4.6 returns
5125						// nodes that are no longer in the document #6963
5126						if ( elem && elem.parentNode ) {
5127							// Handle the case where IE and Opera return items
5128							// by name instead of ID
5129							if ( elem.id === match[3] ) {
5130								return makeArray( [ elem ], extra );
5131							}
5132
5133						} else {
5134							return makeArray( [], extra );
5135						}
5136					}
5137
5138					try {
5139						return makeArray( context.querySelectorAll(query), extra );
5140					} catch(qsaError) {}
5141
5142				// qSA works strangely on Element-rooted queries
5143				// We can work around this by specifying an extra ID on the root
5144				// and working up from there (Thanks to Andrew Dupont for the technique)
5145				// IE 8 doesn't work on object elements
5146				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5147					var oldContext = context,
5148						old = context.getAttribute( "id" ),
5149						nid = old || id,
5150						hasParent = context.parentNode,
5151						relativeHierarchySelector = /^\s*[+~]/.test( query );
5152
5153					if ( !old ) {
5154						context.setAttribute( "id", nid );
5155					} else {
5156						nid = nid.replace( /'/g, "\\$&" );
5157					}
5158					if ( relativeHierarchySelector && hasParent ) {
5159						context = context.parentNode;
5160					}
5161
5162					try {
5163						if ( !relativeHierarchySelector || hasParent ) {
5164							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5165						}
5166
5167					} catch(pseudoError) {
5168					} finally {
5169						if ( !old ) {
5170							oldContext.removeAttribute( "id" );
5171						}
5172					}
5173				}
5174			}
5175
5176			return oldSizzle(query, context, extra, seed);
5177		};
5178
5179		for ( var prop in oldSizzle ) {
5180			Sizzle[ prop ] = oldSizzle[ prop ];
5181		}
5182
5183		// release memory in IE
5184		div = null;
5185	})();
5186}
5187
5188(function(){
5189	var html = document.documentElement,
5190		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5191
5192	if ( matches ) {
5193		// Check to see if it's possible to do matchesSelector
5194		// on a disconnected node (IE 9 fails this)
5195		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5196			pseudoWorks = false;
5197
5198		try {
5199			// This should fail with an exception
5200			// Gecko does not error, returns false instead
5201			matches.call( document.documentElement, "[test!='']:sizzle" );
5202
5203		} catch( pseudoError ) {
5204			pseudoWorks = true;
5205		}
5206
5207		Sizzle.matchesSelector = function( node, expr ) {
5208			// Make sure that attribute selectors are quoted
5209			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5210
5211			if ( !Sizzle.isXML( node ) ) {
5212				try {
5213					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5214						var ret = matches.call( node, expr );
5215
5216						// IE 9's matchesSelector returns false on disconnected nodes
5217						if ( ret || !disconnectedMatch ||
5218								// As well, disconnected nodes are said to be in a document
5219								// fragment in IE 9, so check for that
5220								node.document && node.document.nodeType !== 11 ) {
5221							return ret;
5222						}
5223					}
5224				} catch(e) {}
5225			}
5226
5227			return Sizzle(expr, null, null, [node]).length > 0;
5228		};
5229	}
5230})();
5231
5232(function(){
5233	var div = document.createElement("div");
5234
5235	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5236
5237	// Opera can't find a second classname (in 9.6)
5238	// Also, make sure that getElementsByClassName actually exists
5239	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5240		return;
5241	}
5242
5243	// Safari caches class attributes, doesn't catch changes (in 3.2)
5244	div.lastChild.className = "e";
5245
5246	if ( div.getElementsByClassName("e").length === 1 ) {
5247		return;
5248	}
5249
5250	Expr.order.splice(1, 0, "CLASS");
5251	Expr.find.CLASS = function( match, context, isXML ) {
5252		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5253			return context.getElementsByClassName(match[1]);
5254		}
5255	};
5256
5257	// release memory in IE
5258	div = null;
5259})();
5260
5261function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5262	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5263		var elem = checkSet[i];
5264
5265		if ( elem ) {
5266			var match = false;
5267
5268			elem = elem[dir];
5269
5270			while ( elem ) {
5271				if ( elem[ expando ] === doneName ) {
5272					match = checkSet[elem.sizset];
5273					break;
5274				}
5275
5276				if ( elem.nodeType === 1 && !isXML ){
5277					elem[ expando ] = doneName;
5278					elem.sizset = i;
5279				}
5280
5281				if ( elem.nodeName.toLowerCase() === cur ) {
5282					match = elem;
5283					break;
5284				}
5285
5286				elem = elem[dir];
5287			}
5288
5289			checkSet[i] = match;
5290		}
5291	}
5292}
5293
5294function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5295	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5296		var elem = checkSet[i];
5297
5298		if ( elem ) {
5299			var match = false;
5300
5301			elem = elem[dir];
5302
5303			while ( elem ) {
5304				if ( elem[ expando ] === doneName ) {
5305					match = checkSet[elem.sizset];
5306					break;
5307				}
5308
5309				if ( elem.nodeType === 1 ) {
5310					if ( !isXML ) {
5311						elem[ expando ] = doneName;
5312						elem.sizset = i;
5313					}
5314
5315					if ( typeof cur !== "string" ) {
5316						if ( elem === cur ) {
5317							match = true;
5318							break;
5319						}
5320
5321					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5322						match = elem;
5323						break;
5324					}
5325				}
5326
5327				elem = elem[dir];
5328			}
5329
5330			checkSet[i] = match;
5331		}
5332	}
5333}
5334
5335if ( document.documentElement.contains ) {
5336	Sizzle.contains = function( a, b ) {
5337		return a !== b && (a.contains ? a.contains(b) : true);
5338	};
5339
5340} else if ( document.documentElement.compareDocumentPosition ) {
5341	Sizzle.contains = function( a, b ) {
5342		return !!(a.compareDocumentPosition(b) & 16);
5343	};
5344
5345} else {
5346	Sizzle.contains = function() {
5347		return false;
5348	};
5349}
5350
5351Sizzle.isXML = function( elem ) {
5352	// documentElement is verified for cases where it doesn't yet exist
5353	// (such as loading iframes in IE - #4833)
5354	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5355
5356	return documentElement ? documentElement.nodeName !== "HTML" : false;
5357};
5358
5359var posProcess = function( selector, context, seed ) {
5360	var match,
5361		tmpSet = [],
5362		later = "",
5363		root = context.nodeType ? [context] : context;
5364
5365	// Position selectors must be done after the filter
5366	// And so must :not(positional) so we move all PSEUDOs to the end
5367	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5368		later += match[0];
5369		selector = selector.replace( Expr.match.PSEUDO, "" );
5370	}
5371
5372	selector = Expr.relative[selector] ? selector + "*" : selector;
5373
5374	for ( var i = 0, l = root.length; i < l; i++ ) {
5375		Sizzle( selector, root[i], tmpSet, seed );
5376	}
5377
5378	return Sizzle.filter( later, tmpSet );
5379};
5380
5381// EXPOSE
5382// Override sizzle attribute retrieval
5383Sizzle.attr = jQuery.attr;
5384Sizzle.selectors.attrMap = {};
5385jQuery.find = Sizzle;
5386jQuery.expr = Sizzle.selectors;
5387jQuery.expr[":"] = jQuery.expr.filters;
5388jQuery.unique = Sizzle.uniqueSort;
5389jQuery.text = Sizzle.getText;
5390jQuery.isXMLDoc = Sizzle.isXML;
5391jQuery.contains = Sizzle.contains;
5392
5393
5394})();
5395
5396
5397var runtil = /Until$/,
5398	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5399	// Note: This RegExp should be improved, or likely pulled from Sizzle
5400	rmultiselector = /,/,
5401	isSimple = /^.[^:#\[\.,]*$/,
5402	slice = Array.prototype.slice,
5403	POS = jQuery.expr.match.globalPOS,
5404	// methods guaranteed to produce a unique set when starting from a unique set
5405	guaranteedUnique = {
5406		children: true,
5407		contents: true,
5408		next: true,
5409		prev: true
5410	};
5411
5412jQuery.fn.extend({
5413	find: function( selector ) {
5414		var self = this,
5415			i, l;
5416
5417		if ( typeof selector !== "string" ) {
5418			return jQuery( selector ).filter(function() {
5419				for ( i = 0, l = self.length; i < l; i++ ) {
5420					if ( jQuery.contains( self[ i ], this ) ) {
5421						return true;
5422					}
5423				}
5424			});
5425		}
5426
5427		var ret = this.pushStack( "", "find", selector ),
5428			length, n, r;
5429
5430		for ( i = 0, l = this.length; i < l; i++ ) {
5431			length = ret.length;
5432			jQuery.find( selector, this[i], ret );
5433
5434			if ( i > 0 ) {
5435				// Make sure that the results are unique
5436				for ( n = length; n < ret.length; n++ ) {
5437					for ( r = 0; r < length; r++ ) {
5438						if ( ret[r] === ret[n] ) {
5439							ret.splice(n--, 1);
5440							break;
5441						}
5442					}
5443				}
5444			}
5445		}
5446
5447		return ret;
5448	},
5449
5450	has: function( target ) {
5451		var targets = jQuery( target );
5452		return this.filter(function() {
5453			for ( var i = 0, l = targets.length; i < l; i++ ) {
5454				if ( jQuery.contains( this, targets[i] ) ) {
5455					return true;
5456				}
5457			}
5458		});
5459	},
5460
5461	not: function( selector ) {
5462		return this.pushStack( winnow(this, selector, false), "not", selector);
5463	},
5464
5465	filter: function( selector ) {
5466		return this.pushStack( winnow(this, selector, true), "filter", selector );
5467	},
5468
5469	is: function( selector ) {
5470		return !!selector && (
5471			typeof selector === "string" ?
5472				// If this is a positional selector, check membership in the returned set
5473				// so $("p:first").is("p:last") won't return true for a doc with two "p".
5474				POS.test( selector ) ?
5475					jQuery( selector, this.context ).index( this[0] ) >= 0 :
5476					jQuery.filter( selector, this ).length > 0 :
5477				this.filter( selector ).length > 0 );
5478	},
5479
5480	closest: function( selectors, context ) {
5481		var ret = [], i, l, cur = this[0];
5482
5483		// Array (deprecated as of jQuery 1.7)
5484		if ( jQuery.isArray( selectors ) ) {
5485			var level = 1;
5486
5487			while ( cur && cur.ownerDocument && cur !== context ) {
5488				for ( i = 0; i < selectors.length; i++ ) {
5489
5490					if ( jQuery( cur ).is( selectors[ i ] ) ) {
5491						ret.push({ selector: selectors[ i ], elem: cur, level: level });
5492					}
5493				}
5494
5495				cur = cur.parentNode;
5496				level++;
5497			}
5498
5499			return ret;
5500		}
5501
5502		// String
5503		var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5504				jQuery( selectors, context || this.context ) :
5505				0;
5506
5507		for ( i = 0, l = this.length; i < l; i++ ) {
5508			cur = this[i];
5509
5510			while ( cur ) {
5511				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5512					ret.push( cur );
5513					break;
5514
5515				} else {
5516					cur = cur.parentNode;
5517					if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5518						break;
5519					}
5520				}
5521			}
5522		}
5523
5524		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5525
5526		return this.pushStack( ret, "closest", selectors );
5527	},
5528
5529	// Determine the position of an element within
5530	// the matched set of elements
5531	index: function( elem ) {
5532
5533		// No argument, return index in parent
5534		if ( !elem ) {
5535			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5536		}
5537
5538		// index in selector
5539		if ( typeof elem === "string" ) {
5540			return jQuery.inArray( this[0], jQuery( elem ) );
5541		}
5542
5543		// Locate the position of the desired element
5544		return jQuery.inArray(
5545			// If it receives a jQuery object, the first element is used
5546			elem.jquery ? elem[0] : elem, this );
5547	},
5548
5549	add: function( selector, context ) {
5550		var set = typeof selector === "string" ?
5551				jQuery( selector, context ) :
5552				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5553			all = jQuery.merge( this.get(), set );
5554
5555		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5556			all :
5557			jQuery.unique( all ) );
5558	},
5559
5560	andSelf: function() {
5561		return this.add( this.prevObject );
5562	}
5563});
5564
5565// A painfully simple check to see if an element is disconnected
5566// from a document (should be improved, where feasible).
5567function isDisconnected( node ) {
5568	return !node || !node.parentNode || node.parentNode.nodeType === 11;
5569}
5570
5571jQuery.each({
5572	parent: function( elem ) {
5573		var parent = elem.parentNode;
5574		return parent && parent.nodeType !== 11 ? parent : null;
5575	},
5576	parents: function( elem ) {
5577		return jQuery.dir( elem, "parentNode" );
5578	},
5579	parentsUntil: function( elem, i, until ) {
5580		return jQuery.dir( elem, "parentNode", until );
5581	},
5582	next: function( elem ) {
5583		return jQuery.nth( elem, 2, "nextSibling" );
5584	},
5585	prev: function( elem ) {
5586		return jQuery.nth( elem, 2, "previousSibling" );
5587	},
5588	nextAll: function( elem ) {
5589		return jQuery.dir( elem, "nextSibling" );
5590	},
5591	prevAll: function( elem ) {
5592		return jQuery.dir( elem, "previousSibling" );
5593	},
5594	nextUntil: function( elem, i, until ) {
5595		return jQuery.dir( elem, "nextSibling", until );
5596	},
5597	prevUntil: function( elem, i, until ) {
5598		return jQuery.dir( elem, "previousSibling", until );
5599	},
5600	siblings: function( elem ) {
5601		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5602	},
5603	children: function( elem ) {
5604		return jQuery.sibling( elem.firstChild );
5605	},
5606	contents: function( elem ) {
5607		return jQuery.nodeName( elem, "iframe" ) ?
5608			elem.contentDocument || elem.contentWindow.document :
5609			jQuery.makeArray( elem.childNodes );
5610	}
5611}, function( name, fn ) {
5612	jQuery.fn[ name ] = function( until, selector ) {
5613		var ret = jQuery.map( this, fn, until );
5614
5615		if ( !runtil.test( name ) ) {
5616			selector = until;
5617		}
5618
5619		if ( selector && typeof selector === "string" ) {
5620			ret = jQuery.filter( selector, ret );
5621		}
5622
5623		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5624
5625		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5626			ret = ret.reverse();
5627		}
5628
5629		return this.pushStack( ret, name, slice.call( arguments ).join(",") );
5630	};
5631});
5632
5633jQuery.extend({
5634	filter: function( expr, elems, not ) {
5635		if ( not ) {
5636			expr = ":not(" + expr + ")";
5637		}
5638
5639		return elems.length === 1 ?
5640			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5641			jQuery.find.matches(expr, elems);
5642	},
5643
5644	dir: function( elem, dir, until ) {
5645		var matched = [],
5646			cur = elem[ dir ];
5647
5648		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5649			if ( cur.nodeType === 1 ) {
5650				matched.push( cur );
5651			}
5652			cur = cur[dir];
5653		}
5654		return matched;
5655	},
5656
5657	nth: function( cur, result, dir, elem ) {
5658		result = result || 1;
5659		var num = 0;
5660
5661		for ( ; cur; cur = cur[dir] ) {
5662			if ( cur.nodeType === 1 && ++num === result ) {
5663				break;
5664			}
5665		}
5666
5667		return cur;
5668	},
5669
5670	sibling: function( n, elem ) {
5671		var r = [];
5672
5673		for ( ; n; n = n.nextSibling ) {
5674			if ( n.nodeType === 1 && n !== elem ) {
5675				r.push( n );
5676			}
5677		}
5678
5679		return r;
5680	}
5681});
5682
5683// Implement the identical functionality for filter and not
5684function winnow( elements, qualifier, keep ) {
5685
5686	// Can't pass null or undefined to indexOf in Firefox 4
5687	// Set to 0 to skip string check
5688	qualifier = qualifier || 0;
5689
5690	if ( jQuery.isFunction( qualifier ) ) {
5691		return jQuery.grep(elements, function( elem, i ) {
5692			var retVal = !!qualifier.call( elem, i, elem );
5693			return retVal === keep;
5694		});
5695
5696	} else if ( qualifier.nodeType ) {
5697		return jQuery.grep(elements, function( elem, i ) {
5698			return ( elem === qualifier ) === keep;
5699		});
5700
5701	} else if ( typeof qualifier === "string" ) {
5702		var filtered = jQuery.grep(elements, function( elem ) {
5703			return elem.nodeType === 1;
5704		});
5705
5706		if ( isSimple.test( qualifier ) ) {
5707			return jQuery.filter(qualifier, filtered, !keep);
5708		} else {
5709			qualifier = jQuery.filter( qualifier, filtered );
5710		}
5711	}
5712
5713	return jQuery.grep(elements, function( elem, i ) {
5714		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5715	});
5716}
5717
5718
5719
5720
5721function createSafeFragment( document ) {
5722	var list = nodeNames.split( "|" ),
vendor: 3,444 bytes, lines 5723-5852
5723	safeFrag = document.createDocumentFragment();
5724
5725	if ( safeFrag.createElement ) {
5726		while ( list.length ) {
5727			safeFrag.createElement(
5728				list.pop()
5729			);
5730		}
5731	}
5732	return safeFrag;
5733}
5734
5735var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5736		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5737	rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5738	rleadingWhitespace = /^\s+/,
5739	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5740	rtagName = /<([\w:]+)/,
5741	rtbody = /<tbody/i,
5742	rhtml = /<|&#?\w+;/,
5743	rnoInnerhtml = /<(?:script|style)/i,
5744	rnocache = /<(?:script|object|embed|option|style)/i,
5745	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5746	// checked="checked" or checked
5747	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5748	rscriptType = /\/(java|ecma)script/i,
5749	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5750	wrapMap = {
5751		option: [ 1, "<select multiple='multiple'>", "</select>" ],
5752		legend: [ 1, "<fieldset>", "</fieldset>" ],
5753		thead: [ 1, "<table>", "</table>" ],
5754		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5755		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5756		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5757		area: [ 1, "<map>", "</map>" ],
5758		_default: [ 0, "", "" ]
5759	},
5760	safeFragment = createSafeFragment( document );
5761
5762wrapMap.optgroup = wrapMap.option;
5763wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5764wrapMap.th = wrapMap.td;
5765
5766// IE can't serialize <link> and <script> tags normally
5767if ( !jQuery.support.htmlSerialize ) {
5768	wrapMap._default = [ 1, "div<div>", "</div>" ];
5769}
5770
5771jQuery.fn.extend({
5772	text: function( value ) {
5773		return jQuery.access( this, function( value ) {
5774			return value === undefined ?
5775				jQuery.text( this ) :
5776				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5777		}, null, value, arguments.length );
5778	},
5779
5780	wrapAll: function( html ) {
5781		if ( jQuery.isFunction( html ) ) {
5782			return this.each(function(i) {
5783				jQuery(this).wrapAll( html.call(this, i) );
5784			});
5785		}
5786
5787		if ( this[0] ) {
5788			// The elements to wrap the target around
5789			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5790
5791			if ( this[0].parentNode ) {
5792				wrap.insertBefore( this[0] );
5793			}
5794
5795			wrap.map(function() {
5796				var elem = this;
5797
5798				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5799					elem = elem.firstChild;
5800				}
5801
5802				return elem;
5803			}).append( this );
5804		}
5805
5806		return this;
5807	},
5808
5809	wrapInner: function( html ) {
5810		if ( jQuery.isFunction( html ) ) {
5811			return this.each(function(i) {
5812				jQuery(this).wrapInner( html.call(this, i) );
5813			});
5814		}
5815
5816		return this.each(function() {
5817			var self = jQuery( this ),
5818				contents = self.contents();
5819
5820			if ( contents.length ) {
5821				contents.wrapAll( html );
5822
5823			} else {
5824				self.append( html );
5825			}
5826		});
5827	},
5828
5829	wrap: function( html ) {
5830		var isFunction = jQuery.isFunction( html );
5831
5832		return this.each(function(i) {
5833			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5834		});
5835	},
5836
5837	unwrap: function() {
5838		return this.parent().each(function() {
5839			if ( !jQuery.nodeName( this, "body" ) ) {
5840				jQuery( this ).replaceWith( this.childNodes );
5841			}
5842		}).end();
5843	},
5844
5845	append: function() {
5846		return this.domManip(arguments, true, function( elem ) {
5847			if ( this.nodeType === 1 ) {
5848				this.appendChild( elem );
5849			}
5850		});
5851	},
5852
5853	prepend: function() {
5854		return this.domManip(arguments, true, function( elem ) {
5855			if ( this.nodeType === 1 ) {
5856				this.insertBefore( elem, this.firstChild );
5857			}
5858		});
5859	},
5860
5861	before: function() {
5862		if ( this[0] && this[0].parentNode ) {
5863			return this.domManip(arguments, false, function( elem ) {
5864				this.parentNode.insertBefore( elem, this );
5865			});
5866		} else if ( arguments.length ) {
5867			var set = jQuery.clean( arguments );
5868			set.push.apply( set, this.toArray() );
5869			return this.pushStack( set, "before", arguments );
5870		}
5871	},
5872
5873	after: function() {
5874		if ( this[0] && this[0].parentNode ) {
5875			return this.domManip(arguments, false, function( elem ) {
5876				this.parentNode.insertBefore( elem, this.nextSibling );
5877			});
5878		} else if ( arguments.length ) {
5879			var set = this.pushStack( this, "after", arguments );
5880			set.push.apply( set, jQuery.clean(arguments) );
5881			return set;
5882		}
5883	},
5884
5885	// keepData is for internal use only--do not document
5886	remove: function( selector, keepData ) {
5887		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5888			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5889				if ( !keepData && elem.nodeType === 1 ) {
5890					jQuery.cleanData( elem.getElementsByTagName("*") );
5891					jQuery.cleanData( [ elem ] );
5892				}
5893
5894				if ( elem.parentNode ) {
5895					elem.parentNode.removeChild( elem );
5896				}
5897			}
5898		}
5899
5900		return this;
5901	},
5902
5903	empty: function() {
5904		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5905			// Remove element nodes and prevent memory leaks
5906			if ( elem.nodeType === 1 ) {
5907				jQuery.cleanData( elem.getElementsByTagName("*") );
5908			}
5909
5910			// Remove any remaining nodes
5911			while ( elem.firstChild ) {
5912				elem.removeChild( elem.firstChild );
5913			}
5914		}
5915
5916		return this;
5917	},
5918
5919	clone: function( dataAndEvents, deepDataAndEvents ) {
5920		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5921		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5922
5923		return this.map( function () {
5924			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5925		});
5926	},
5927
5928	html: function( value ) {
5929		return jQuery.access( this, function( value ) {
5930			var elem = this[0] || {},
5931				i = 0,
5932				l = this.length;
5933
5934			if ( value === undefined ) {
5935				return elem.nodeType === 1 ?
5936					elem.innerHTML.replace( rinlinejQuery, "" ) :
5937					null;
5938			}
5939
5940
5941			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5942				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5943				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5944
5945				value = value.replace( rxhtmlTag, "<$1></$2>" );
5946
5947				try {
5948					for (; i < l; i++ ) {
5949						// Remove element nodes and prevent memory leaks
5950						elem = this[i] || {};
5951						if ( elem.nodeType === 1 ) {
5952							jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5953							elem.innerHTML = value;
5954						}
5955					}
5956
5957					elem = 0;
5958
5959				// If using innerHTML throws an exception, use the fallback method
5960				} catch(e) {}
5961			}
5962
5963			if ( elem ) {
5964				this.empty().append( value );
5965			}
5966		}, null, value, arguments.length );
5967	},
5968
5969	replaceWith: function( value ) {
5970		if ( this[0] && this[0].parentNode ) {
5971			// Make sure that the elements are removed from the DOM before they are inserted
5972			// this can help fix replacing a parent with child elements
5973			if ( jQuery.isFunction( value ) ) {
5974				return this.each(function(i) {
5975					var self = jQuery(this), old = self.html();
5976					self.replaceWith( value.call( this, i, old ) );
5977				});
5978			}
5979
5980			if ( typeof value !== "string" ) {
5981				value = jQuery( value ).detach();
5982			}
5983
5984			return this.each(function() {
5985				var next = this.nextSibling,
5986					parent = this.parentNode;
5987
5988				jQuery( this ).remove();
5989
5990				if ( next ) {
5991					jQuery(next).before( value );
5992				} else {
5993					jQuery(parent).append( value );
5994				}
5995			});
5996		} else {
5997			return this.length ?
5998				this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5999				this;
6000		}
6001	},
6002
6003	detach: function( selector ) {
6004		return this.remove( selector, true );
6005	},
6006
6007	domManip: function( args, table, callback ) {
6008		var results, first, fragment, parent,
6009			value = args[0],
6010			scripts = [];
6011
6012		// We can't cloneNode fragments that contain checked, in WebKit
6013		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
6014			return this.each(function() {
6015				jQuery(this).domManip( args, table, callback, true );
6016			});
6017		}
6018
6019		if ( jQuery.isFunction(value) ) {
6020			return this.each(function(i) {
6021				var self = jQuery(this);
6022				args[0] = value.call(this, i, table ? self.html() : undefined);
6023				self.domManip( args, table, callback );
6024			});
6025		}
6026
6027		if ( this[0] ) {
6028			parent = value && value.parentNode;
6029
6030			// If we're in a fragment, just use that instead of building a new one
6031			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6032				results = { fragment: parent };
6033
6034			} else {
6035				results = jQuery.buildFragment( args, this, scripts );
6036			}
6037
6038			fragment = results.fragment;
6039
6040			if ( fragment.childNodes.length === 1 ) {
6041				first = fragment = fragment.firstChild;
6042			} else {
6043				first = fragment.firstChild;
6044			}
6045
6046			if ( first ) {
6047				table = table && jQuery.nodeName( first, "tr" );
6048
6049				for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6050					callback.call(
6051						table ?
6052							root(this[i], first) :
6053							this[i],
6054						// Make sure that we do not leak memory by inadvertently discarding
6055						// the original fragment (which might have attached data) instead of
6056						// using it; in addition, use the original fragment object for the last
6057						// item instead of first because it can end up being emptied incorrectly
6058						// in certain situations (Bug #8070).
6059						// Fragments from the fragment cache must always be cloned and never used
6060						// in place.
6061						results.cacheable || ( l > 1 && i < lastIndex ) ?
6062							jQuery.clone( fragment, true, true ) :
6063							fragment
6064					);
6065				}
6066			}
6067
6068			if ( scripts.length ) {
6069				jQuery.each( scripts, function( i, elem ) {
6070					if ( elem.src ) {
6071						jQuery.ajax({
6072							type: "GET",
6073							global: false,
6074							url: elem.src,
6075							async: false,
6076							dataType: "script"
6077						});
6078					} else {
6079						jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6080					}
6081
6082					if ( elem.parentNode ) {
6083						elem.parentNode.removeChild( elem );
6084					}
6085				});
6086			}
6087		}
6088
6089		return this;
6090	}
6091});
6092
6093function root( elem, cur ) {
6094	return jQuery.nodeName(elem, "table") ?
6095		(elem.getElementsByTagName("tbody")[0] ||
6096		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6097		elem;
6098}
6099
6100function cloneCopyEvent( src, dest ) {
6101
6102	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6103		return;
6104	}
6105
6106	var type, i, l,
6107		oldData = jQuery._data( src ),
6108		curData = jQuery._data( dest, oldData ),
6109		events = oldData.events;
6110
6111	if ( events ) {
6112		delete curData.handle;
6113		curData.events = {};
6114
6115		for ( type in events ) {
6116			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6117				jQuery.event.add( dest, type, events[ type ][ i ] );
6118			}
6119		}
6120	}
6121
6122	// make the cloned public data object a copy from the original
6123	if ( curData.data ) {
6124		curData.data = jQuery.extend( {}, curData.data );
6125	}
6126}
6127
6128function cloneFixAttributes( src, dest ) {
6129	var nodeName;
6130
6131	// We do not need to do anything for non-Elements
6132	if ( dest.nodeType !== 1 ) {
6133		return;
6134	}
6135
6136	// clearAttributes removes the attributes, which we don't want,
6137	// but also removes the attachEvent events, which we *do* want
6138	if ( dest.clearAttributes ) {
6139		dest.clearAttributes();
6140	}
6141
6142	// mergeAttributes, in contrast, only merges back on the
6143	// original attributes, not the events
6144	if ( dest.mergeAttributes ) {
6145		dest.mergeAttributes( src );
6146	}
6147
6148	nodeName = dest.nodeName.toLowerCase();
6149
6150	// IE6-8 fail to clone children inside object elements that use
6151	// the proprietary classid attribute value (rather than the type
6152	// attribute) to identify the type of content to display
6153	if ( nodeName === "object" ) {
6154		dest.outerHTML = src.outerHTML;
6155
6156	} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6157		// IE6-8 fails to persist the checked state of a cloned checkbox
6158		// or radio button. Worse, IE6-7 fail to give the cloned element
6159		// a checked appearance if the defaultChecked value isn't also set
6160		if ( src.checked ) {
6161			dest.defaultChecked = dest.checked = src.checked;
6162		}
6163
6164		// IE6-7 get confused and end up setting the value of a cloned
6165		// checkbox/radio button to an empty string instead of "on"
6166		if ( dest.value !== src.value ) {
6167			dest.value = src.value;
6168		}
6169
6170	// IE6-8 fails to return the selected option to the default selected
6171	// state when cloning options
6172	} else if ( nodeName === "option" ) {
6173		dest.selected = src.defaultSelected;
6174
6175	// IE6-8 fails to set the defaultValue to the correct value when
6176	// cloning other types of input fields
6177	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6178		dest.defaultValue = src.defaultValue;
6179
6180	// IE blanks contents when cloning scripts
6181	} else if ( nodeName === "script" && dest.text !== src.text ) {
6182		dest.text = src.text;
6183	}
6184
6185	// Event data gets referenced instead of copied if the expando
6186	// gets copied too
6187	dest.removeAttribute( jQuery.expando );
6188
6189	// Clear flags for bubbling special change/submit events, they must
6190	// be reattached when the newly cloned events are first activated
6191	dest.removeAttribute( "_submit_attached" );
6192	dest.removeAttribute( "_change_attached" );
6193}
6194
6195jQuery.buildFragment = function( args, nodes, scripts ) {
6196	var fragment, cacheable, cacheresults, doc,
6197	first = args[ 0 ];
6198
6199	// nodes may contain either an explicit document object,
6200	// a jQuery collection or context object.
6201	// If nodes[0] contains a valid object to assign to doc
6202	if ( nodes && nodes[0] ) {
6203		doc = nodes[0].ownerDocument || nodes[0];
6204	}
6205
6206	// Ensure that an attr object doesn't incorrectly stand in as a document object
6207	// Chrome and Firefox seem to allow this to occur and will throw exception
6208	// Fixes #8950
6209	if ( !doc.createDocumentFragment ) {
6210		doc = document;
6211	}
6212
6213	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6214	// Cloning options loses the selected state, so don't cache them
6215	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6216	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6217	// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6218	if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
6219		first.charAt(0) === "<" && !rnocache.test( first ) &&
6220		(jQuery.support.checkClone || !rchecked.test( first )) &&
6221		(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6222
6223		cacheable = true;
6224
6225		cacheresults = jQuery.fragments[ first ];
6226		if ( cacheresults && cacheresults !== 1 ) {
6227			fragment = cacheresults;
6228		}
6229	}
6230
6231	if ( !fragment ) {
6232		fragment = doc.createDocumentFragment();
6233		jQuery.clean( args, doc, fragment, scripts );
6234	}
6235
6236	if ( cacheable ) {
6237		jQuery.fragments[ first ] = cacheresults ? fragment : 1;
6238	}
6239
6240	return { fragment: fragment, cacheable: cacheable };
6241};
6242
6243jQuery.fragments = {};
6244
6245jQuery.each({
6246	appendTo: "append",
6247	prependTo: "prepend",
6248	insertBefore: "before",
6249	insertAfter: "after",
6250	replaceAll: "replaceWith"
6251}, function( name, original ) {
6252	jQuery.fn[ name ] = function( selector ) {
6253		var ret = [],
6254			insert = jQuery( selector ),
6255			parent = this.length === 1 && this[0].parentNode;
6256
6257		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6258			insert[ original ]( this[0] );
6259			return this;
6260
6261		} else {
6262			for ( var i = 0, l = insert.length; i < l; i++ ) {
6263				var elems = ( i > 0 ? this.clone(true) : this ).get();
6264				jQuery( insert[i] )[ original ]( elems );
6265				ret = ret.concat( elems );
6266			}
6267
6268			return this.pushStack( ret, name, insert.selector );
6269		}
6270	};
6271});
6272
6273function getAll( elem ) {
6274	if ( typeof elem.getElementsByTagName !== "undefined" ) {
6275		return elem.getElementsByTagName( "*" );
6276
6277	} else if ( typeof elem.querySelectorAll !== "undefined" ) {
6278		return elem.querySelectorAll( "*" );
6279
6280	} else {
6281		return [];
6282	}
6283}
6284
6285// Used in clean, fixes the defaultChecked property
6286function fixDefaultChecked( elem ) {
6287	if ( elem.type === "checkbox" || elem.type === "radio" ) {
6288		elem.defaultChecked = elem.checked;
6289	}
6290}
6291// Finds all inputs and passes them to fixDefaultChecked
6292function findInputs( elem ) {
6293	var nodeName = ( elem.nodeName || "" ).toLowerCase();
6294	if ( nodeName === "input" ) {
6295		fixDefaultChecked( elem );
6296	// Skip scripts, get other children
6297	} else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
6298		jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6299	}
6300}
6301
6302// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
6303function shimCloneNode( elem ) {
6304	var div = document.createElement( "div" );
6305	safeFragment.appendChild( div );
6306
6307	div.innerHTML = elem.outerHTML;
6308	return div.firstChild;
6309}
6310
6311jQuery.extend({
6312	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6313		var srcElements,
6314			destElements,
6315			i,
6316			// IE<=8 does not properly clone detached, unknown element nodes
6317			clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?
6318				elem.cloneNode( true ) :
6319				shimCloneNode( elem );
6320
6321		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6322				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6323			// IE copies events bound via attachEvent when using cloneNode.
6324			// Calling detachEvent on the clone will also remove the events
6325			// from the original. In order to get around this, we use some
6326			// proprietary methods to clear the events. Thanks to MooTools
6327			// guys for this hotness.
6328
6329			cloneFixAttributes( elem, clone );
6330
6331			// Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6332			srcElements = getAll( elem );
6333			destElements = getAll( clone );
6334
6335			// Weird iteration because IE will replace the length property
6336			// with an element if you are cloning the body and one of the
6337			// elements on the page has a name or id of "length"
6338			for ( i = 0; srcElements[i]; ++i ) {
6339				// Ensure that the destination node is not null; Fixes #9587
6340				if ( destElements[i] ) {
6341					cloneFixAttributes( srcElements[i], destElements[i] );
6342				}
6343			}
6344		}
6345
6346		// Copy the events from the original to the clone
6347		if ( dataAndEvents ) {
6348			cloneCopyEvent( elem, clone );
6349
6350			if ( deepDataAndEvents ) {
6351				srcElements = getAll( elem );
6352				destElements = getAll( clone );
6353
6354				for ( i = 0; srcElements[i]; ++i ) {
6355					cloneCopyEvent( srcElements[i], destElements[i] );
6356				}
6357			}
6358		}
6359
6360		srcElements = destElements = null;
6361
6362		// Return the cloned set
6363		return clone;
6364	},
6365
6366	clean: function( elems, context, fragment, scripts ) {
6367		var checkScriptType, script, j,
6368				ret = [];
6369
6370		context = context || document;
6371
6372		// !context.createElement fails in IE with an error but returns typeof 'object'
6373		if ( typeof context.createElement === "undefined" ) {
6374			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6375		}
6376
6377		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6378			if ( typeof elem === "number" ) {
6379				elem += "";
6380			}
6381
6382			if ( !elem ) {
6383				continue;
6384			}
6385
6386			// Convert html string into DOM nodes
6387			if ( typeof elem === "string" ) {
6388				if ( !rhtml.test( elem ) ) {
6389					elem = context.createTextNode( elem );
6390				} else {
6391					// Fix "XHTML"-style tags in all browsers
6392					elem = elem.replace(rxhtmlTag, "<$1></$2>");
6393
6394					// Trim whitespace, otherwise indexOf won't work as expected
6395					var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
6396						wrap = wrapMap[ tag ] || wrapMap._default,
6397						depth = wrap[0],
6398						div = context.createElement("div"),
6399						safeChildNodes = safeFragment.childNodes,
6400						remove;
6401
6402					// Append wrapper element to unknown element safe doc fragment
6403					if ( context === document ) {
6404						// Use the fragment we've already created for this document
6405						safeFragment.appendChild( div );
6406					} else {
6407						// Use a fragment created with the owner document
6408						createSafeFragment( context ).appendChild( div );
6409					}
6410
6411					// Go to html and back, then peel off extra wrappers
6412					div.innerHTML = wrap[1] + elem + wrap[2];
6413
6414					// Move to the right depth
6415					while ( depth-- ) {
6416						div = div.lastChild;
6417					}
6418
6419					// Remove IE's autoinserted <tbody> from table fragments
6420					if ( !jQuery.support.tbody ) {
6421
6422						// String was a <table>, *may* have spurious <tbody>
6423						var hasBody = rtbody.test(elem),
6424							tbody = tag === "table" && !hasBody ?
6425								div.firstChild && div.firstChild.childNodes :
6426
6427								// String was a bare <thead> or <tfoot>
6428								wrap[1] === "<table>" && !hasBody ?
6429									div.childNodes :
6430									[];
6431
6432						for ( j = tbody.length - 1; j >= 0 ; --j ) {
6433							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6434								tbody[ j ].parentNode.removeChild( tbody[ j ] );
6435							}
6436						}
6437					}
6438
6439					// IE completely kills leading whitespace when innerHTML is used
6440					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6441						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6442					}
6443
6444					elem = div.childNodes;
6445
6446					// Clear elements from DocumentFragment (safeFragment or otherwise)
6447					// to avoid hoarding elements. Fixes #11356
6448					if ( div ) {
6449						div.parentNode.removeChild( div );
6450
6451						// Guard against -1 index exceptions in FF3.6
6452						if ( safeChildNodes.length > 0 ) {
6453							remove = safeChildNodes[ safeChildNodes.length - 1 ];
6454
6455							if ( remove && remove.parentNode ) {
6456								remove.parentNode.removeChild( remove );
6457							}
6458						}
6459					}
6460				}
6461			}
6462
6463			// Resets defaultChecked for any radios and checkboxes
6464			// about to be appended to the DOM in IE 6/7 (#8060)
6465			var len;
6466			if ( !jQuery.support.appendChecked ) {
6467				if ( elem[0] && typeof (len = elem.length) === "number" ) {
6468					for ( j = 0; j < len; j++ ) {
6469						findInputs( elem[j] );
6470					}
6471				} else {
6472					findInputs( elem );
6473				}
6474			}
6475
6476			if ( elem.nodeType ) {
6477				ret.push( elem );
6478			} else {
6479				ret = jQuery.merge( ret, elem );
6480			}
6481		}
6482
6483		if ( fragment ) {
6484			checkScriptType = function( elem ) {
6485				return !elem.type || rscriptType.test( elem.type );
6486			};
6487			for ( i = 0; ret[i]; i++ ) {
6488				script = ret[i];
6489				if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {
6490					scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );
6491
6492				} else {
6493					if ( script.nodeType === 1 ) {
6494						var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType );
6495
6496						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6497					}
6498					fragment.appendChild( script );
6499				}
6500			}
6501		}
6502
6503		return ret;
6504	},
6505
6506	cleanData: function( elems ) {
6507		var data, id,
6508			cache = jQuery.cache,
6509			special = jQuery.event.special,
6510			deleteExpando = jQuery.support.deleteExpando;
6511
6512		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6513			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6514				continue;
6515			}
6516
6517			id = elem[ jQuery.expando ];
6518
6519			if ( id ) {
6520				data = cache[ id ];
6521
6522				if ( data && data.events ) {
6523					for ( var type in data.events ) {
6524						if ( special[ type ] ) {
6525							jQuery.event.remove( elem, type );
6526
6527						// This is a shortcut to avoid jQuery.event.remove's overhead
6528						} else {
6529							jQuery.removeEvent( elem, type, data.handle );
6530						}
6531					}
6532
6533					// Null the DOM reference to avoid IE6/7/8 leak (#7054)
6534					if ( data.handle ) {
6535						data.handle.elem = null;
6536					}
6537				}
6538
6539				if ( deleteExpando ) {
6540					delete elem[ jQuery.expando ];
6541
6542				} else if ( elem.removeAttribute ) {
6543					elem.removeAttribute( jQuery.expando );
6544				}
6545
6546				delete cache[ id ];
6547			}
6548		}
6549	}
6550});
6551
6552
6553
6554
6555var ralpha = /alpha\([^)]*\)/i,
6556	ropacity = /opacity=([^)]*)/,
6557	// fixed for IE9, see #8346
6558	rupper = /([A-Z]|^ms)/g,
6559	rnum = /^[\-+]?(?:\d*\.)?\d+$/i,
6560	rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
6561	rrelNum = /^([\-+])=([\-+.\de]+)/,
6562	rmargin = /^margin/,
6563
6564	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6565
6566	// order is important!
6567	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6568
6569	curCSS,
6570
6571	getComputedStyle,
6572	currentStyle;
6573
6574jQuery.fn.css = function( name, value ) {
6575	return jQuery.access( this, function( elem, name, value ) {
6576		return value !== undefined ?
6577			jQuery.style( elem, name, value ) :
6578			jQuery.css( elem, name );
6579	}, name, value, arguments.length > 1 );
6580};
6581
6582jQuery.extend({
6583	// Add in style property hooks for overriding the default
6584	// behavior of getting and setting a style property
6585	cssHooks: {
6586		opacity: {
6587			get: function( elem, computed ) {
6588				if ( computed ) {
6589					// We should always get a number back from opacity
6590					var ret = curCSS( elem, "opacity" );
6591					return ret === "" ? "1" : ret;
6592
6593				} else {
6594					return elem.style.opacity;
6595				}
6596			}
6597		}
6598	},
6599
6600	// Exclude the following css properties to add px
6601	cssNumber: {
6602		"fillOpacity": true,
6603		"fontWeight": true,
6604		"lineHeight": true,
6605		"opacity": true,
6606		"orphans": true,
6607		"widows": true,
6608		"zIndex": true,
6609		"zoom": true
6610	},
6611
6612	// Add in properties whose names you wish to fix before
6613	// setting or getting the value
6614	cssProps: {
6615		// normalize float css property
6616		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6617	},
6618
6619	// Get and set the style property on a DOM Node
6620	style: function( elem, name, value, extra ) {
6621		// Don't set styles on text and comment nodes
6622		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6623			return;
6624		}
6625
6626		// Make sure that we're working with the right name
6627		var ret, type, origName = jQuery.camelCase( name ),
6628			style = elem.style, hooks = jQuery.cssHooks[ origName ];
6629
6630		name = jQuery.cssProps[ origName ] || origName;
6631
6632		// Check if we're setting a value
6633		if ( value !== undefined ) {
6634			type = typeof value;
6635
6636			// convert relative number strings (+= or -=) to relative numbers. #7345
6637			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6638				value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6639				// Fixes bug #9237
6640				type = "number";
6641			}
6642
6643			// Make sure that NaN and null values aren't set. See: #7116
6644			if ( value == null || type === "number" && isNaN( value ) ) {
6645				return;
6646			}
6647
6648			// If a number was passed in, add 'px' to the (except for certain CSS properties)
6649			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6650				value += "px";
6651			}
6652
6653			// If a hook was provided, use that value, otherwise just set the specified value
6654			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6655				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6656				// Fixes bug #5509
6657				try {
6658					style[ name ] = value;
6659				} catch(e) {}
6660			}
6661
6662		} else {
6663			// If a hook was provided get the non-computed value from there
6664			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6665				return ret;
6666			}
6667
6668			// Otherwise just get the value from the style object
6669			return style[ name ];
6670		}
6671	},
6672
6673	css: function( elem, name, extra ) {
6674		var ret, hooks;
6675
6676		// Make sure that we're working with the right name
6677		name = jQuery.camelCase( name );
6678		hooks = jQuery.cssHooks[ name ];
6679		name = jQuery.cssProps[ name ] || name;
6680
6681		// cssFloat needs a special treatment
6682		if ( name === "cssFloat" ) {
6683			name = "float";
6684		}
6685
6686		// If a hook was provided get the computed value from there
6687		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6688			return ret;
6689
6690		// Otherwise, if a way to get the computed value exists, use that
6691		} else if ( curCSS ) {
6692			return curCSS( elem, name );
6693		}
6694	},
6695
6696	// A method for quickly swapping in/out CSS properties to get correct calculations
6697	swap: function( elem, options, callback ) {
6698		var old = {},
6699			ret, name;
6700
6701		// Remember the old values, and insert the new ones
6702		for ( name in options ) {
6703			old[ name ] = elem.style[ name ];
6704			elem.style[ name ] = options[ name ];
6705		}
6706
6707		ret = callback.call( elem );
6708
6709		// Revert the old values
6710		for ( name in options ) {
6711			elem.style[ name ] = old[ name ];
6712		}
6713
6714		return ret;
6715	}
6716});
6717
6718// DEPRECATED in 1.3, Use jQuery.css() instead
6719jQuery.curCSS = jQuery.css;
6720
6721if ( document.defaultView && document.defaultView.getComputedStyle ) {
6722	getComputedStyle = function( elem, name ) {
6723		var ret, defaultView, computedStyle, width,
6724			style = elem.style;
6725
6726		name = name.replace( rupper, "-$1" ).toLowerCase();
6727
6728		if ( (defaultView = elem.ownerDocument.defaultView) &&
6729				(computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6730
6731			ret = computedStyle.getPropertyValue( name );
6732			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6733				ret = jQuery.style( elem, name );
6734			}
6735		}
6736
6737		// A tribute to the "awesome hack by Dean Edwards"
6738		// WebKit uses "computed value (percentage if specified)" instead of "used value" for margins
6739		// which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6740		if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {
6741			width = style.width;
6742			style.width = ret;
6743			ret = computedStyle.width;
6744			style.width = width;
6745		}
6746
6747		return ret;
6748	};
6749}
6750
6751if ( document.documentElement.currentStyle ) {
6752	currentStyle = function( elem, name ) {
6753		var left, rsLeft, uncomputed,
6754			ret = elem.currentStyle && elem.currentStyle[ name ],
6755			style = elem.style;
6756
6757		// Avoid setting ret to empty string here
6758		// so we don't default to auto
6759		if ( ret == null && style && (uncomputed = style[ name ]) ) {
6760			ret = uncomputed;
6761		}
6762
6763		// From the awesome hack by Dean Edwards
6764		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6765
6766		// If we're not dealing with a regular pixel number
6767		// but a number that has a weird ending, we need to convert it to pixels
6768		if ( rnumnonpx.test( ret ) ) {
6769
6770			// Remember the original values
6771			left = style.left;
6772			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6773
6774			// Put in the new values to get a computed value out
6775			if ( rsLeft ) {
6776				elem.runtimeStyle.left = elem.currentStyle.left;
6777			}
6778			style.left = name === "fontSize" ? "1em" : ret;
6779			ret = style.pixelLeft + "px";
6780
6781			// Revert the changed values
6782			style.left = left;
6783			if ( rsLeft ) {
6784				elem.runtimeStyle.left = rsLeft;
6785			}
6786		}
6787
6788		return ret === "" ? "auto" : ret;
6789	};
6790}
6791
6792curCSS = getComputedStyle || currentStyle;
6793
6794function getWidthOrHeight( elem, name, extra ) {
6795
6796	// Start with offset property
6797	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6798		i = name === "width" ? 1 : 0,
6799		len = 4;
6800
6801	if ( val > 0 ) {
6802		if ( extra !== "border" ) {
6803			for ( ; i < len; i += 2 ) {
6804				if ( !extra ) {
6805					val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
6806				}
6807				if ( extra === "margin" ) {
6808					val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
6809				} else {
6810					val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6811				}
6812			}
6813		}
6814
6815		return val + "px";
6816	}
6817
6818	// Fall back to computed then uncomputed css if necessary
6819	val = curCSS( elem, name );
6820	if ( val < 0 || val == null ) {
6821		val = elem.style[ name ];
6822	}
6823
6824	// Computed unit is not pixels. Stop here and return.
6825	if ( rnumnonpx.test(val) ) {
6826		return val;
6827	}
6828
6829	// Normalize "", auto, and prepare for extra
6830	val = parseFloat( val ) || 0;
6831
6832	// Add padding, border, margin
6833	if ( extra ) {
6834		for ( ; i < len; i += 2 ) {
6835			val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
6836			if ( extra !== "padding" ) {
6837				val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6838			}
6839			if ( extra === "margin" ) {
6840				val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
6841			}
6842		}
6843	}
6844
6845	return val + "px";
6846}
6847
6848jQuery.each([ "height", "width" ], function( i, name ) {
6849	jQuery.cssHooks[ name ] = {
6850		get: function( elem, computed, extra ) {
6851			if ( computed ) {
6852				if ( elem.offsetWidth !== 0 ) {
6853					return getWidthOrHeight( elem, name, extra );
6854				} else {
6855					return jQuery.swap( elem, cssShow, function() {
6856						return getWidthOrHeight( elem, name, extra );
6857					});
6858				}
6859			}
6860		},
6861
6862		set: function( elem, value ) {
6863			return rnum.test( value ) ?
6864				value + "px" :
6865				value;
6866		}
6867	};
6868});
6869
6870if ( !jQuery.support.opacity ) {
6871	jQuery.cssHooks.opacity = {
6872		get: function( elem, computed ) {
6873			// IE uses filters for opacity
6874			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6875				( parseFloat( RegExp.$1 ) / 100 ) + "" :
6876				computed ? "1" : "";
6877		},
6878
6879		set: function( elem, value ) {
6880			var style = elem.style,
6881				currentStyle = elem.currentStyle,
6882				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6883				filter = currentStyle && currentStyle.filter || style.filter || "";
6884
6885			// IE has trouble with opacity if it does not have layout
6886			// Force it by setting the zoom level
6887			style.zoom = 1;
6888
6889			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6890			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6891
6892				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6893				// if "filter:" is present at all, clearType is disabled, we want to avoid this
6894				// style.removeAttribute is IE Only, but so apparently is this code path...
6895				style.removeAttribute( "filter" );
6896
6897				// if there there is no filter style applied in a css rule, we are done
6898				if ( currentStyle && !currentStyle.filter ) {
6899					return;
6900				}
6901			}
6902
6903			// otherwise, set new filter values
6904			style.filter = ralpha.test( filter ) ?
6905				filter.replace( ralpha, opacity ) :
6906				filter + " " + opacity;
6907		}
6908	};
6909}
6910
6911jQuery(function() {
6912	// This hook cannot be added until DOM ready because the support test
6913	// for it is not run until after DOM ready
6914	if ( !jQuery.support.reliableMarginRight ) {
6915		jQuery.cssHooks.marginRight = {
6916			get: function( elem, computed ) {
6917				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6918				// Work around by temporarily setting element display to inline-block
6919				return jQuery.swap( elem, { "display": "inline-block" }, function() {
6920					if ( computed ) {
6921						return curCSS( elem, "margin-right" );
6922					} else {
6923						return elem.style.marginRight;
6924					}
6925				});
6926			}
6927		};
6928	}
6929});
6930
6931if ( jQuery.expr && jQuery.expr.filters ) {
6932	jQuery.expr.filters.hidden = function( elem ) {
6933		var width = elem.offsetWidth,
6934			height = elem.offsetHeight;
6935
6936		return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "dis
vendor: 23,952 bytes, lines 6936-7813
6936play" )) === "none");
6937	};
6938
6939	jQuery.expr.filters.visible = function( elem ) {
6940		return !jQuery.expr.filters.hidden( elem );
6941	};
6942}
6943
6944// These hooks are used by animate to expand properties
6945jQuery.each({
6946	margin: "",
6947	padding: "",
6948	border: "Width"
6949}, function( prefix, suffix ) {
6950
6951	jQuery.cssHooks[ prefix + suffix ] = {
6952		expand: function( value ) {
6953			var i,
6954
6955				// assumes a single number if not a string
6956				parts = typeof value === "string" ? value.split(" ") : [ value ],
6957				expanded = {};
6958
6959			for ( i = 0; i < 4; i++ ) {
6960				expanded[ prefix + cssExpand[ i ] + suffix ] =
6961					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6962			}
6963
6964			return expanded;
6965		}
6966	};
6967});
6968
6969
6970
6971
6972var r20 = /%20/g,
6973	rbracket = /\[\]$/,
6974	rCRLF = /\r?\n/g,
6975	rhash = /#.*$/,
6976	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6977	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6978	// #7653, #8125, #8152: local protocol detection
6979	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6980	rnoContent = /^(?:GET|HEAD)$/,
6981	rprotocol = /^\/\//,
6982	rquery = /\?/,
6983	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6984	rselectTextarea = /^(?:select|textarea)/i,
6985	rspacesAjax = /\s+/,
6986	rts = /([?&])_=[^&]*/,
6987	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6988
6989	// Keep a copy of the old load method
6990	_load = jQuery.fn.load,
6991
6992	/* Prefilters
6993	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6994	 * 2) These are called:
6995	 *    - BEFORE asking for a transport
6996	 *    - AFTER param serialization (s.data is a string if s.processData is true)
6997	 * 3) key is the dataType
6998	 * 4) the catchall symbol "*" can be used
6999	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7000	 */
7001	prefilters = {},
7002
7003	/* Transports bindings
7004	 * 1) key is the dataType
7005	 * 2) the catchall symbol "*" can be used
7006	 * 3) selection will start with transport dataType and THEN go to "*" if needed
7007	 */
7008	transports = {},
7009
7010	// Document location
7011	ajaxLocation,
7012
7013	// Document location segments
7014	ajaxLocParts,
7015
7016	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7017	allTypes = ["*/"] + ["*"];
7018
7019// #8138, IE may throw an exception when accessing
7020// a field from window.location if document.domain has been set
7021try {
7022	ajaxLocation = location.href;
7023} catch( e ) {
7024	// Use the href attribute of an A element
7025	// since IE will modify it given document.location
7026	ajaxLocation = document.createElement( "a" );
7027	ajaxLocation.href = "";
7028	ajaxLocation = ajaxLocation.href;
7029}
7030
7031// Segment location into parts
7032ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7033
7034// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7035function addToPrefiltersOrTransports( structure ) {
7036
7037	// dataTypeExpression is optional and defaults to "*"
7038	return function( dataTypeExpression, func ) {
7039
7040		if ( typeof dataTypeExpression !== "string" ) {
7041			func = dataTypeExpression;
7042			dataTypeExpression = "*";
7043		}
7044
7045		if ( jQuery.isFunction( func ) ) {
7046			var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
7047				i = 0,
7048				length = dataTypes.length,
7049				dataType,
7050				list,
7051				placeBefore;
7052
7053			// For each dataType in the dataTypeExpression
7054			for ( ; i < length; i++ ) {
7055				dataType = dataTypes[ i ];
7056				// We control if we're asked to add before
7057				// any existing element
7058				placeBefore = /^\+/.test( dataType );
7059				if ( placeBefore ) {
7060					dataType = dataType.substr( 1 ) || "*";
7061				}
7062				list = structure[ dataType ] = structure[ dataType ] || [];
7063				// then we add to the structure accordingly
7064				list[ placeBefore ? "unshift" : "push" ]( func );
7065			}
7066		}
7067	};
7068}
7069
7070// Base inspection function for prefilters and transports
7071function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7072		dataType /* internal */, inspected /* internal */ ) {
7073
7074	dataType = dataType || options.dataTypes[ 0 ];
7075	inspected = inspected || {};
7076
7077	inspected[ dataType ] = true;
7078
7079	var list = structure[ dataType ],
7080		i = 0,
7081		length = list ? list.length : 0,
7082		executeOnly = ( structure === prefilters ),
7083		selection;
7084
7085	for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7086		selection = list[ i ]( options, originalOptions, jqXHR );
7087		// If we got redirected to another dataType
7088		// we try there if executing only and not done already
7089		if ( typeof selection === "string" ) {
7090			if ( !executeOnly || inspected[ selection ] ) {
7091				selection = undefined;
7092			} else {
7093				options.dataTypes.unshift( selection );
7094				selection = inspectPrefiltersOrTransports(
7095						structure, options, originalOptions, jqXHR, selection, inspected );
7096			}
7097		}
7098	}
7099	// If we're only executing or nothing was selected
7100	// we try the catchall dataType if not done already
7101	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7102		selection = inspectPrefiltersOrTransports(
7103				structure, options, originalOptions, jqXHR, "*", inspected );
7104	}
7105	// unnecessary when only executing (prefilters)
7106	// but it'll be ignored by the caller in that case
7107	return selection;
7108}
7109
7110// A special extend for ajax options
7111// that takes "flat" options (not to be deep extended)
7112// Fixes #9887
7113function ajaxExtend( target, src ) {
7114	var key, deep,
7115		flatOptions = jQuery.ajaxSettings.flatOptions || {};
7116	for ( key in src ) {
7117		if ( src[ key ] !== undefined ) {
7118			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7119		}
7120	}
7121	if ( deep ) {
7122		jQuery.extend( true, target, deep );
7123	}
7124}
7125
7126jQuery.fn.extend({
7127	load: function( url, params, callback ) {
7128		if ( typeof url !== "string" && _load ) {
7129			return _load.apply( this, arguments );
7130
7131		// Don't do a request if no elements are being requested
7132		} else if ( !this.length ) {
7133			return this;
7134		}
7135
7136		var off = url.indexOf( " " );
7137		if ( off >= 0 ) {
7138			var selector = url.slice( off, url.length );
7139			url = url.slice( 0, off );
7140		}
7141
7142		// Default to a GET request
7143		var type = "GET";
7144
7145		// If the second parameter was provided
7146		if ( params ) {
7147			// If it's a function
7148			if ( jQuery.isFunction( params ) ) {
7149				// We assume that it's the callback
7150				callback = params;
7151				params = undefined;
7152
7153			// Otherwise, build a param string
7154			} else if ( typeof params === "object" ) {
7155				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7156				type = "POST";
7157			}
7158		}
7159
7160		var self = this;
7161
7162		// Request the remote document
7163		jQuery.ajax({
7164			url: url,
7165			type: type,
7166			dataType: "html",
7167			data: params,
7168			// Complete callback (responseText is used internally)
7169			complete: function( jqXHR, status, responseText ) {
7170				// Store the response as specified by the jqXHR object
7171				responseText = jqXHR.responseText;
7172				// If successful, inject the HTML into all the matched elements
7173				if ( jqXHR.isResolved() ) {
7174					// #4825: Get the actual response in case
7175					// a dataFilter is present in ajaxSettings
7176					jqXHR.done(function( r ) {
7177						responseText = r;
7178					});
7179					// See if a selector was specified
7180					self.html( selector ?
7181						// Create a dummy div to hold the results
7182						jQuery("<div>")
7183							// inject the contents of the document in, removing the scripts
7184							// to avoid any 'Permission Denied' errors in IE
7185							.append(responseText.replace(rscript, ""))
7186
7187							// Locate the specified elements
7188							.find(selector) :
7189
7190						// If not, just inject the full result
7191						responseText );
7192				}
7193
7194				if ( callback ) {
7195					self.each( callback, [ responseText, status, jqXHR ] );
7196				}
7197			}
7198		});
7199
7200		return this;
7201	},
7202
7203	serialize: function() {
7204		return jQuery.param( this.serializeArray() );
7205	},
7206
7207	serializeArray: function() {
7208		return this.map(function(){
7209			return this.elements ? jQuery.makeArray( this.elements ) : this;
7210		})
7211		.filter(function(){
7212			return this.name && !this.disabled &&
7213				( this.checked || rselectTextarea.test( this.nodeName ) ||
7214					rinput.test( this.type ) );
7215		})
7216		.map(function( i, elem ){
7217			var val = jQuery( this ).val();
7218
7219			return val == null ?
7220				null :
7221				jQuery.isArray( val ) ?
7222					jQuery.map( val, function( val, i ){
7223						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7224					}) :
7225					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7226		}).get();
7227	}
7228});
7229
7230// Attach a bunch of functions for handling common AJAX events
7231jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7232	jQuery.fn[ o ] = function( f ){
7233		return this.on( o, f );
7234	};
7235});
7236
7237jQuery.each( [ "get", "post" ], function( i, method ) {
7238	jQuery[ method ] = function( url, data, callback, type ) {
7239		// shift arguments if data argument was omitted
7240		if ( jQuery.isFunction( data ) ) {
7241			type = type || callback;
7242			callback = data;
7243			data = undefined;
7244		}
7245
7246		return jQuery.ajax({
7247			type: method,
7248			url: url,
7249			data: data,
7250			success: callback,
7251			dataType: type
7252		});
7253	};
7254});
7255
7256jQuery.extend({
7257
7258	getScript: function( url, callback ) {
7259		return jQuery.get( url, undefined, callback, "script" );
7260	},
7261
7262	getJSON: function( url, data, callback ) {
7263		return jQuery.get( url, data, callback, "json" );
7264	},
7265
7266	// Creates a full fledged settings object into target
7267	// with both ajaxSettings and settings fields.
7268	// If target is omitted, writes into ajaxSettings.
7269	ajaxSetup: function( target, settings ) {
7270		if ( settings ) {
7271			// Building a settings object
7272			ajaxExtend( target, jQuery.ajaxSettings );
7273		} else {
7274			// Extending ajaxSettings
7275			settings = target;
7276			target = jQuery.ajaxSettings;
7277		}
7278		ajaxExtend( target, settings );
7279		return target;
7280	},
7281
7282	ajaxSettings: {
7283		url: ajaxLocation,
7284		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7285		global: true,
7286		type: "GET",
7287		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7288		processData: true,
7289		async: true,
7290		/*
7291		timeout: 0,
7292		data: null,
7293		dataType: null,
7294		username: null,
7295		password: null,
7296		cache: null,
7297		traditional: false,
7298		headers: {},
7299		*/
7300
7301		accepts: {
7302			xml: "application/xml, text/xml",
7303			html: "text/html",
7304			text: "text/plain",
7305			json: "application/json, text/javascript",
7306			"*": allTypes
7307		},
7308
7309		contents: {
7310			xml: /xml/,
7311			html: /html/,
7312			json: /json/
7313		},
7314
7315		responseFields: {
7316			xml: "responseXML",
7317			text: "responseText"
7318		},
7319
7320		// List of data converters
7321		// 1) key format is "source_type destination_type" (a single space in-between)
7322		// 2) the catchall symbol "*" can be used for source_type
7323		converters: {
7324
7325			// Convert anything to text
7326			"* text": window.String,
7327
7328			// Text to html (true = no transformation)
7329			"text html": true,
7330
7331			// Evaluate text as a json expression
7332			"text json": jQuery.parseJSON,
7333
7334			// Parse text as xml
7335			"text xml": jQuery.parseXML
7336		},
7337
7338		// For options that shouldn't be deep extended:
7339		// you can add your own custom options here if
7340		// and when you create one that shouldn't be
7341		// deep extended (see ajaxExtend)
7342		flatOptions: {
7343			context: true,
7344			url: true
7345		}
7346	},
7347
7348	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7349	ajaxTransport: addToPrefiltersOrTransports( transports ),
7350
7351	// Main method
7352	ajax: function( url, options ) {
7353
7354		// If url is an object, simulate pre-1.5 signature
7355		if ( typeof url === "object" ) {
7356			options = url;
7357			url = undefined;
7358		}
7359
7360		// Force options to be an object
7361		options = options || {};
7362
7363		var // Create the final options object
7364			s = jQuery.ajaxSetup( {}, options ),
7365			// Callbacks context
7366			callbackContext = s.context || s,
7367			// Context for global events
7368			// It's the callbackContext if one was provided in the options
7369			// and if it's a DOM node or a jQuery collection
7370			globalEventContext = callbackContext !== s &&
7371				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7372						jQuery( callbackContext ) : jQuery.event,
7373			// Deferreds
7374			deferred = jQuery.Deferred(),
7375			completeDeferred = jQuery.Callbacks( "once memory" ),
7376			// Status-dependent callbacks
7377			statusCode = s.statusCode || {},
7378			// ifModified key
7379			ifModifiedKey,
7380			// Headers (they are sent all at once)
7381			requestHeaders = {},
7382			requestHeadersNames = {},
7383			// Response headers
7384			responseHeadersString,
7385			responseHeaders,
7386			// transport
7387			transport,
7388			// timeout handle
7389			timeoutTimer,
7390			// Cross-domain detection vars
7391			parts,
7392			// The jqXHR state
7393			state = 0,
7394			// To know if global events are to be dispatched
7395			fireGlobals,
7396			// Loop variable
7397			i,
7398			// Fake xhr
7399			jqXHR = {
7400
7401				readyState: 0,
7402
7403				// Caches the header
7404				setRequestHeader: function( name, value ) {
7405					if ( !state ) {
7406						var lname = name.toLowerCase();
7407						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7408						requestHeaders[ name ] = value;
7409					}
7410					return this;
7411				},
7412
7413				// Raw string
7414				getAllResponseHeaders: function() {
7415					return state === 2 ? responseHeadersString : null;
7416				},
7417
7418				// Builds headers hashtable if needed
7419				getResponseHeader: function( key ) {
7420					var match;
7421					if ( state === 2 ) {
7422						if ( !responseHeaders ) {
7423							responseHeaders = {};
7424							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7425								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7426							}
7427						}
7428						match = responseHeaders[ key.toLowerCase() ];
7429					}
7430					return match === undefined ? null : match;
7431				},
7432
7433				// Overrides response content-type header
7434				overrideMimeType: function( type ) {
7435					if ( !state ) {
7436						s.mimeType = type;
7437					}
7438					return this;
7439				},
7440
7441				// Cancel the request
7442				abort: function( statusText ) {
7443					statusText = statusText || "abort";
7444					if ( transport ) {
7445						transport.abort( statusText );
7446					}
7447					done( 0, statusText );
7448					return this;
7449				}
7450			};
7451
7452		// Callback for when everything is done
7453		// It is defined here because jslint complains if it is declared
7454		// at the end of the function (which would be more logical and readable)
7455		function done( status, nativeStatusText, responses, headers ) {
7456
7457			// Called once
7458			if ( state === 2 ) {
7459				return;
7460			}
7461
7462			// State is "done" now
7463			state = 2;
7464
7465			// Clear timeout if it exists
7466			if ( timeoutTimer ) {
7467				clearTimeout( timeoutTimer );
7468			}
7469
7470			// Dereference transport for early garbage collection
7471			// (no matter how long the jqXHR object will be used)
7472			transport = undefined;
7473
7474			// Cache response headers
7475			responseHeadersString = headers || "";
7476
7477			// Set readyState
7478			jqXHR.readyState = status > 0 ? 4 : 0;
7479
7480			var isSuccess,
7481				success,
7482				error,
7483				statusText = nativeStatusText,
7484				response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7485				lastModified,
7486				etag;
7487
7488			// If successful, handle type chaining
7489			if ( status >= 200 && status < 300 || status === 304 ) {
7490
7491				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7492				if ( s.ifModified ) {
7493
7494					if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7495						jQuery.lastModified[ ifModifiedKey ] = lastModified;
7496					}
7497					if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7498						jQuery.etag[ ifModifiedKey ] = etag;
7499					}
7500				}
7501
7502				// If not modified
7503				if ( status === 304 ) {
7504
7505					statusText = "notmodified";
7506					isSuccess = true;
7507
7508				// If we have data
7509				} else {
7510
7511					try {
7512						success = ajaxConvert( s, response );
7513						statusText = "success";
7514						isSuccess = true;
7515					} catch(e) {
7516						// We have a parsererror
7517						statusText = "parsererror";
7518						error = e;
7519					}
7520				}
7521			} else {
7522				// We extract error from statusText
7523				// then normalize statusText and status for non-aborts
7524				error = statusText;
7525				if ( !statusText || status ) {
7526					statusText = "error";
7527					if ( status < 0 ) {
7528						status = 0;
7529					}
7530				}
7531			}
7532
7533			// Set data for the fake xhr object
7534			jqXHR.status = status;
7535			jqXHR.statusText = "" + ( nativeStatusText || statusText );
7536
7537			// Success/Error
7538			if ( isSuccess ) {
7539				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7540			} else {
7541				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7542			}
7543
7544			// Status-dependent callbacks
7545			jqXHR.statusCode( statusCode );
7546			statusCode = undefined;
7547
7548			if ( fireGlobals ) {
7549				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7550						[ jqXHR, s, isSuccess ? success : error ] );
7551			}
7552
7553			// Complete
7554			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7555
7556			if ( fireGlobals ) {
7557				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7558				// Handle the global AJAX counter
7559				if ( !( --jQuery.active ) ) {
7560					jQuery.event.trigger( "ajaxStop" );
7561				}
7562			}
7563		}
7564
7565		// Attach deferreds
7566		deferred.promise( jqXHR );
7567		jqXHR.success = jqXHR.done;
7568		jqXHR.error = jqXHR.fail;
7569		jqXHR.complete = completeDeferred.add;
7570
7571		// Status-dependent callbacks
7572		jqXHR.statusCode = function( map ) {
7573			if ( map ) {
7574				var tmp;
7575				if ( state < 2 ) {
7576					for ( tmp in map ) {
7577						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7578					}
7579				} else {
7580					tmp = map[ jqXHR.status ];
7581					jqXHR.then( tmp, tmp );
7582				}
7583			}
7584			return this;
7585		};
7586
7587		// Remove hash character (#7531: and string promotion)
7588		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7589		// We also use the url parameter if available
7590		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7591
7592		// Extract dataTypes list
7593		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7594
7595		// Determine if a cross-domain request is in order
7596		if ( s.crossDomain == null ) {
7597			parts = rurl.exec( s.url.toLowerCase() );
7598			s.crossDomain = !!( parts &&
7599				( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7600					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7601						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7602			);
7603		}
7604
7605		// Convert data if not already a string
7606		if ( s.data && s.processData && typeof s.data !== "string" ) {
7607			s.data = jQuery.param( s.data, s.traditional );
7608		}
7609
7610		// Apply prefilters
7611		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7612
7613		// If request was aborted inside a prefilter, stop there
7614		if ( state === 2 ) {
7615			return false;
7616		}
7617
7618		// We can fire global events as of now if asked to
7619		fireGlobals = s.global;
7620
7621		// Uppercase the type
7622		s.type = s.type.toUpperCase();
7623
7624		// Determine if request has content
7625		s.hasContent = !rnoContent.test( s.type );
7626
7627		// Watch for a new set of requests
7628		if ( fireGlobals && jQuery.active++ === 0 ) {
7629			jQuery.event.trigger( "ajaxStart" );
7630		}
7631
7632		// More options handling for requests with no content
7633		if ( !s.hasContent ) {
7634
7635			// If data is available, append data to url
7636			if ( s.data ) {
7637				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7638				// #9682: remove data so that it's not used in an eventual retry
7639				delete s.data;
7640			}
7641
7642			// Get ifModifiedKey before adding the anti-cache parameter
7643			ifModifiedKey = s.url;
7644
7645			// Add anti-cache in url if needed
7646			if ( s.cache === false ) {
7647
7648				var ts = jQuery.now(),
7649					// try replacing _= if it is there
7650					ret = s.url.replace( rts, "$1_=" + ts );
7651
7652				// if nothing was replaced, add timestamp to the end
7653				s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7654			}
7655		}
7656
7657		// Set the correct header, if data is being sent
7658		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7659			jqXHR.setRequestHeader( "Content-Type", s.contentType );
7660		}
7661
7662		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7663		if ( s.ifModified ) {
7664			ifModifiedKey = ifModifiedKey || s.url;
7665			if ( jQuery.lastModified[ ifModifiedKey ] ) {
7666				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7667			}
7668			if ( jQuery.etag[ ifModifiedKey ] ) {
7669				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7670			}
7671		}
7672
7673		// Set the Accepts header for the server, depending on the dataType
7674		jqXHR.setRequestHeader(
7675			"Accept",
7676			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7677				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7678				s.accepts[ "*" ]
7679		);
7680
7681		// Check for headers option
7682		for ( i in s.headers ) {
7683			jqXHR.setRequestHeader( i, s.headers[ i ] );
7684		}
7685
7686		// Allow custom headers/mimetypes and early abort
7687		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7688				// Abort if not done already
7689				jqXHR.abort();
7690				return false;
7691
7692		}
7693
7694		// Install callbacks on deferreds
7695		for ( i in { success: 1, error: 1, complete: 1 } ) {
7696			jqXHR[ i ]( s[ i ] );
7697		}
7698
7699		// Get transport
7700		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7701
7702		// If no transport, we auto-abort
7703		if ( !transport ) {
7704			done( -1, "No Transport" );
7705		} else {
7706			jqXHR.readyState = 1;
7707			// Send global event
7708			if ( fireGlobals ) {
7709				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7710			}
7711			// Timeout
7712			if ( s.async && s.timeout > 0 ) {
7713				timeoutTimer = setTimeout( function(){
7714					jqXHR.abort( "timeout" );
7715				}, s.timeout );
7716			}
7717
7718			try {
7719				state = 1;
7720				transport.send( requestHeaders, done );
7721			} catch (e) {
7722				// Propagate exception as error if not done
7723				if ( state < 2 ) {
7724					done( -1, e );
7725				// Simply rethrow otherwise
7726				} else {
7727					throw e;
7728				}
7729			}
7730		}
7731
7732		return jqXHR;
7733	},
7734
7735	// Serialize an array of form elements or a set of
7736	// key/values into a query string
7737	param: function( a, traditional ) {
7738		var s = [],
7739			add = function( key, value ) {
7740				// If value is a function, invoke it and return its value
7741				value = jQuery.isFunction( value ) ? value() : value;
7742				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7743			};
7744
7745		// Set traditional to true for jQuery <= 1.3.2 behavior.
7746		if ( traditional === undefined ) {
7747			traditional = jQuery.ajaxSettings.traditional;
7748		}
7749
7750		// If an array was passed in, assume that it is an array of form elements.
7751		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7752			// Serialize the form elements
7753			jQuery.each( a, function() {
7754				add( this.name, this.value );
7755			});
7756
7757		} else {
7758			// If traditional, encode the "old" way (the way 1.3.2 or older
7759			// did it), otherwise encode params recursively.
7760			for ( var prefix in a ) {
7761				buildParams( prefix, a[ prefix ], traditional, add );
7762			}
7763		}
7764
7765		// Return the resulting serialization
7766		return s.join( "&" ).replace( r20, "+" );
7767	}
7768});
7769
7770function buildParams( prefix, obj, traditional, add ) {
7771	if ( jQuery.isArray( obj ) ) {
7772		// Serialize array item.
7773		jQuery.each( obj, function( i, v ) {
7774			if ( traditional || rbracket.test( prefix ) ) {
7775				// Treat each array item as a scalar.
7776				add( prefix, v );
7777
7778			} else {
7779				// If array item is non-scalar (array or object), encode its
7780				// numeric index to resolve deserialization ambiguity issues.
7781				// Note that rack (as of 1.0.0) can't currently deserialize
7782				// nested arrays properly, and attempting to do so may cause
7783				// a server error. Possible fixes are to modify rack's
7784				// deserialization algorithm or to provide an option or flag
7785				// to force array serialization to be shallow.
7786				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7787			}
7788		});
7789
7790	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
7791		// Serialize object item.
7792		for ( var name in obj ) {
7793			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7794		}
7795
7796	} else {
7797		// Serialize scalar item.
7798		add( prefix, obj );
7799	}
7800}
7801
7802// This is still on the jQuery object... for now
7803// Want to move this to jQuery.ajax some day
7804jQuery.extend({
7805
7806	// Counter for holding the number of active queries
7807	active: 0,
7808
7809	// Last-Modified header cache for next request
7810	lastModified: {},
7811	etag: {}
7812
7813}
7813);
7814
7815/* Handles responses to an ajax request:
7816 * - sets all responseXXX fields accordingly
7817 * - finds the right dataType (mediates between content-type and expected dataType)
7818 * - returns the corresponding response
7819 */
7820function ajaxHandleResponses( s, jqXHR, responses ) {
7821
7822	var contents = s.contents,
7823		dataTypes = s.dataTypes,
7824		responseFields = s.responseFields,
7825		ct,
7826		type,
7827		finalDataType,
7828		firstDataType;
7829
7830	// Fill responseXXX fields
7831	for ( type in responseFields ) {
7832		if ( type in responses ) {
7833			jqXHR[ responseFields[type] ] = responses[ type ];
7834		}
7835	}
7836
7837	// Remove auto dataType and get content-type in the process
7838	while( dataTypes[ 0 ] === "*" ) {
7839		dataTypes.shift();
7840		if ( ct === undefined ) {
7841			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7842		}
7843	}
7844
7845	// Check if we're dealing with a known content-type
7846	if ( ct ) {
7847		for ( type in contents ) {
7848			if ( contents[ type ] && contents[ type ].test( ct ) ) {
7849				dataTypes.unshift( type );
7850				break;
7851			}
7852		}
7853	}
7854
7855	// Check to see if we have a response for the expected dataType
7856	if ( dataTypes[ 0 ] in responses ) {
7857		finalDataType = dataTypes[ 0 ];
7858	} else {
7859		// Try convertible dataTypes
7860		for ( type in responses ) {
7861			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7862				finalDataType = type;
7863				break;
7864			}
7865			if ( !firstDataType ) {
7866				firstDataType = type;
7867			}
7868		}
7869		// Or just use first one
7870		finalDataType = finalDataType || firstDataType;
7871	}
7872
7873	// If we found a dataType
7874	// We add the dataType to the list if needed
7875	// and return the corresponding response
7876	if ( finalDataType ) {
7877		if ( finalDataType !== dataTypes[ 0 ] ) {
7878			dataTypes.unshift( finalDataType );
7879		}
7880		return responses[ finalDataType ];
7881	}
7882}
7883
7884// Chain conversions given the request and the original response
7885function ajaxConvert( s, response ) {
7886
7887	// Apply the dataFilter if provided
7888	if ( s.dataFilter ) {
7889		response = s.dataFilter( response, s.dataType );
7890	}
7891
7892	var dataTypes = s.dataTypes,
7893		converters = {},
7894		i,
7895		key,
7896		length = dataTypes.length,
7897		tmp,
7898		// Current and previous dataTypes
7899		current = dataTypes[ 0 ],
7900		prev,
7901		// Conversion expression
7902		conversion,
7903		// Conversion function
7904		conv,
7905		// Conversion functions (transitive conversion)
7906		conv1,
7907		conv2;
7908
7909	// For each dataType in the chain
7910	for ( i = 1; i < length; i++ ) {
7911
7912		// Create converters map
7913		// with lowercased keys
7914		if ( i === 1 ) {
7915			for ( key in s.converters ) {
7916				if ( typeof key === "string" ) {
7917					converters[ key.toLowerCase() ] = s.converters[ key ];
7918				}
7919			}
7920		}
7921
7922		// Get the dataTypes
7923		prev = current;
7924		current = dataTypes[ i ];
7925
7926		// If current is auto dataType, update it to prev
7927		if ( current === "*" ) {
7928			current = prev;
7929		// If no auto and dataTypes are actually different
7930		} else if ( prev !== "*" && prev !== current ) {
7931
7932			// Get the converter
7933			conversion = prev + " " + current;
7934			conv = converters[ conversion ] || converters[ "* " + current ];
7935
7936			// If there is no direct converter, search transitively
7937			if ( !conv ) {
7938				conv2 = undefined;
7939				for ( conv1 in converters ) {
7940					tmp = conv1.split( " " );
7941					if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7942						conv2 = converters[ tmp[1] + " " + current ];
7943						if ( conv2 ) {
7944							conv1 = converters[ conv1 ];
7945							if ( conv1 === true ) {
7946								conv = conv2;
7947							} else if ( conv2 === true ) {
7948								conv = conv1;
7949							}
7950							break;
7951						}
7952					}
7953				}
7954			}
7955			// If we found no converter, dispatch an error
7956			if ( !( conv || conv2 ) ) {
7957				jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7958			}
7959			// If found converter is not an equivalence
7960			if ( conv !== true ) {
7961				// Convert with 1 or 2 converters accordingly
7962				response = conv ? conv( response ) : conv2( conv1(response) );
7963			}
7964		}
7965	}
7966	return response;
7967}
7968
7969
7970
7971
7972var jsc = jQuery.now(),
7973	jsre = /(\=)\?(&|$)|\?\?/i;
7974
7975// Default jsonp settings
7976jQuery.ajaxSetup({
7977	jsonp: "callback",
7978	jsonpCallback: function() {
7979		return jQuery.expando + "_" + ( jsc++ );
7980	}
7981});
7982
7983// Detect, normalize options and install callbacks for jsonp requests
7984jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7985
7986	var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );
7987
7988	if ( s.dataTypes[ 0 ] === "jsonp" ||
7989		s.jsonp !== false && ( jsre.test( s.url ) ||
7990				inspectData && jsre.test( s.data ) ) ) {
7991
7992		var responseContainer,
7993			jsonpCallback = s.jsonpCallback =
7994				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7995			previous = window[ jsonpCallback ],
7996			url = s.url,
7997			data = s.data,
7998			replace = "$1" + jsonpCallback + "$2";
7999
8000		if ( s.jsonp !== false ) {
8001			url = url.replace( jsre, replace );
8002			if ( s.url === url ) {
8003				if ( inspectData ) {
8004					data = data.replace( jsre, replace );
8005				}
8006				if ( s.data === data ) {
8007					// Add callback manually
8008					url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
8009				}
8010			}
8011		}
8012
8013		s.url = url;
8014		s.data = data;
8015
8016		// Install callback
8017		window[ jsonpCallback ] = function( response ) {
8018			responseContainer = [ response ];
8019		};
8020
8021		// Clean-up function
8022		jqXHR.always(function() {
8023			// Set callback back to previous value
8024			window[ jsonpCallback ] = previous;
8025			// Call if it was a function and we have a response
8026			if ( responseContainer && jQuery.isFunction( previous ) ) {
8027				window[ jsonpCallback ]( responseContainer[ 0 ] );
8028			}
8029		});
8030
8031		// Use data converter to retrieve json after script execution
8032		s.converters["script json"] = function() {
8033			if ( !responseContainer ) {
8034				jQuery.error( jsonpCallback + " was not called" );
8035			}
8036			return responseContainer[ 0 ];
8037		};
8038
8039		// force json dataType
8040		s.dataTypes[ 0 ] = "json";
8041
8042		// Delegate to script
8043		return "script";
8044	}
8045});
8046
8047
8048
8049
8050// Install script dataType
8051jQuery.ajaxSetup({
8052	accepts: {
8053		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8054	},
8055	contents: {
8056		script: /javascript|ecmascript/
8057	},
8058	converters: {
8059		"text script": function( text ) {
8060			jQuery.globalEval( text );
8061			return text;
8062		}
8063	}
8064});
8065
8066// Handle cache's special case and global
8067jQuery.ajaxPrefilter( "script", function( s ) {
8068	if ( s.cache === undefined ) {
8069		s.cache = false;
vendor: 3,904 bytes, lines 8070-8225
8070	}
8071	if ( s.crossDomain ) {
8072		s.type = "GET";
8073		s.global = false;
8074	}
8075});
8076
8077// Bind script tag hack transport
8078jQuery.ajaxTransport( "script", function(s) {
8079
8080	// This transport only deals with cross domain requests
8081	if ( s.crossDomain ) {
8082
8083		var script,
8084			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8085
8086		return {
8087
8088			send: function( _, callback ) {
8089
8090				script = document.createElement( "script" );
8091
8092				script.async = "async";
8093
8094				if ( s.scriptCharset ) {
8095					script.charset = s.scriptCharset;
8096				}
8097
8098				script.src = s.url;
8099
8100				// Attach handlers for all browsers
8101				script.onload = script.onreadystatechange = function( _, isAbort ) {
8102
8103					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8104
8105						// Handle memory leak in IE
8106						script.onload = script.onreadystatechange = null;
8107
8108						// Remove the script
8109						if ( head && script.parentNode ) {
8110							head.removeChild( script );
8111						}
8112
8113						// Dereference the script
8114						script = undefined;
8115
8116						// Callback if not abort
8117						if ( !isAbort ) {
8118							callback( 200, "success" );
8119						}
8120					}
8121				};
8122				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8123				// This arises when a base node is used (#2709 and #4378).
8124				head.insertBefore( script, head.firstChild );
8125			},
8126
8127			abort: function() {
8128				if ( script ) {
8129					script.onload( 0, 1 );
8130				}
8131			}
8132		};
8133	}
8134});
8135
8136
8137
8138
8139var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8140	xhrOnUnloadAbort = window.ActiveXObject ? function() {
8141		// Abort all pending requests
8142		for ( var key in xhrCallbacks ) {
8143			xhrCallbacks[ key ]( 0, 1 );
8144		}
8145	} : false,
8146	xhrId = 0,
8147	xhrCallbacks;
8148
8149// Functions to create xhrs
8150function createStandardXHR() {
8151	try {
8152		return new window.XMLHttpRequest();
8153	} catch( e ) {}
8154}
8155
8156function createActiveXHR() {
8157	try {
8158		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8159	} catch( e ) {}
8160}
8161
8162// Create the request object
8163// (This is still attached to ajaxSettings for backward compatibility)
8164jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8165	/* Microsoft failed to properly
8166	 * implement the XMLHttpRequest in IE7 (can't request local files),
8167	 * so we use the ActiveXObject when it is available
8168	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8169	 * we need a fallback.
8170	 */
8171	function() {
8172		return !this.isLocal && createStandardXHR() || createActiveXHR();
8173	} :
8174	// For all other browsers, use the standard XMLHttpRequest object
8175	createStandardXHR;
8176
8177// Determine support properties
8178(function( xhr ) {
8179	jQuery.extend( jQuery.support, {
8180		ajax: !!xhr,
8181		cors: !!xhr && ( "withCredentials" in xhr )
8182	});
8183})( jQuery.ajaxSettings.xhr() );
8184
8185// Create transport if the browser can provide an xhr
8186if ( jQuery.support.ajax ) {
8187
8188	jQuery.ajaxTransport(function( s ) {
8189		// Cross domain only allowed if supported through XMLHttpRequest
8190		if ( !s.crossDomain || jQuery.support.cors ) {
8191
8192			var callback;
8193
8194			return {
8195				send: function( headers, complete ) {
8196
8197					// Get a new xhr
8198					var xhr = s.xhr(),
8199						handle,
8200						i;
8201
8202					// Open the socket
8203					// Passing null username, generates a login popup on Opera (#2865)
8204					if ( s.username ) {
8205						xhr.open( s.type, s.url, s.async, s.username, s.password );
8206					} else {
8207						xhr.open( s.type, s.url, s.async );
8208					}
8209
8210					// Apply custom fields if provided
8211					if ( s.xhrFields ) {
8212						for ( i in s.xhrFields ) {
8213							xhr[ i ] = s.xhrFields[ i ];
8214						}
8215					}
8216
8217					// Override mime type if needed
8218					if ( s.mimeType && xhr.overrideMimeType ) {
8219						xhr.overrideMimeType( s.mimeType );
8220					}
8221
8222					// X-Requested-With header
8223					// For cross-domain requests, seeing as conditions for a preflight are
8224					// akin to a jigsaw puzzle, we simply never set it to be sure.
8225					// (it can always be set on a per-request basis or even using ajaxSetup)
8226					// For same-domain requests, won't change header if already provided.
8227					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8228						headers[ "X-Requested-With" ] = "XMLHttpRequest";
8229					}
8230
8231					// Need an extra try/catch for cross domain requests in Firefox 3
8232					try {
8233						for ( i in headers ) {
8234							xhr.setRequestHeader( i, headers[ i ] );
8235						}
8236					} catch( _ ) {}
8237
8238					// Do send the request
8239					// This may raise an exception which is actually
8240					// handled in jQuery.ajax (so no try/catch here)
8241					xhr.send( ( s.hasContent && s.data ) || null );
8242
8243					// Listener
8244					callback = function( _, isAbort ) {
8245
8246						var status,
8247							statusText,
8248							responseHeaders,
8249							responses,
8250							xml;
8251
8252						// Firefox throws exceptions when accessing properties
8253						// of an xhr when a network error occured
8254						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8255						try {
8256
8257							// Was never called and is aborted or complete
8258							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8259
8260								// Only called once
8261								callback = undefined;
8262
8263								// Do not keep as active anymore
8264								if ( handle ) {
8265									xhr.onreadystatechange = jQuery.noop;
8266									if ( xhrOnUnloadAbort ) {
8267										delete xhrCallbacks[ handle ];
8268									}
8269								}
8270
8271								// If it's an abort
8272								if ( isAbort ) {
8273									// Abort it manually if needed
8274									if ( xhr.readyState !== 4 ) {
8275										xhr.abort();
8276									}
8277								} else {
8278									status = xhr.status;
8279									responseHeaders = xhr.getAllResponseHeaders();
8280									responses = {};
8281									xml = xhr.responseXML;
8282
8283									// Construct response list
8284									if ( xml && xml.documentElement /* #4958 */ ) {
8285										responses.xml = xml;
8286									}
8287
8288									// When requesting binary data, IE6-9 will throw an exception
8289									// on any attempt to access responseText (#11426)
8290									try {
8291										responses.text = xhr.responseText;
8292									} catch( _ ) {
8293									}
8294
8295									// Firefox throws an exception when accessing
8296									// statusText for faulty cross-domain requests
8297									try {
8298										statusText = xhr.statusText;
8299									} catch( e ) {
8300										// We normalize with Webkit giving an empty statusText
8301										statusText = "";
8302									}
8303
8304									// Filter status for non standard behaviors
8305
8306									// If the request is local and we have data: assume a success
8307									// (success with no data won't get notified, that's the best we
8308									// can do given current implementations)
8309									if ( !status && s.isLocal && !s.crossDomain ) {
8310										status = responses.text ? 200 : 404;
8311									// IE - #1450: sometimes returns 1223 when it should be 204
8312									} else if ( status === 1223 ) {
8313										status = 204;
8314									}
8315								}
8316							}
8317						} catch( firefoxAccessException ) {
8318							if ( !isAbort ) {
8319								complete( -1, firefoxAccessException );
8320							}
8321						}
8322
8323						// Call complete if needed
8324						if ( responses ) {
8325							complete( status, statusText, responses, responseHeaders );
8326						}
8327					};
8328
8329					// if we're in sync mode or it's in cache
8330					// and has been retrieved directly (IE6 & IE7)
8331					// we need to manually fire the callback
8332					if ( !s.async || xhr.readyState === 4 ) {
8333						callback();
8334					} else {
8335						handle = ++xhrId;
8336						if ( xhrOnUnloadAbort ) {
8337							// Create the active xhrs callbacks list if needed
8338							// and attach the unload handler
8339							if ( !xhrCallbacks ) {
8340								xhrCallbacks = {};
8341								jQuery( window ).unload( xhrOnUnloadAbort );
8342							}
8343							// Add to list of active xhrs callbacks
8344							xhrCallbacks[ handle ] = callback;
8345						}
8346						xhr.onreadystatechange = callback;
8347					}
8348				},
8349
8350				abort: function() {
8351					if ( callback ) {
8352						callback(0,1);
8353					}
8354				}
8355			};
8356		}
8357	});
8358}
8359
8360
8361
8362
8363var elemdisplay = {},
8364	iframe, iframeDoc,
8365	rfxtypes = /^(?:toggle|show|hide)$/,
8366	rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8367	timerId,
8368	fxAttrs = [
8369		// height animations
8370		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8371		// width animations
8372		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8373		// opacity animations
8374		[ "opacity" ]
8375	],
8376	fxNow;
8377
8378jQuery.fn.extend({
8379	show: function( speed, easing, callback ) {
8380		var elem, display;
8381
8382		if ( speed || speed === 0 ) {
8383			return this.animate( genFx("show", 3), speed, easing, callback );
8384
8385		} else {
8386			for ( var i = 0, j = this.length; i < j; i++ ) {
8387				elem = this[ i ];
8388
8389				if ( elem.style ) {
8390					display = elem.style.display;
8391
8392					// Reset the inline display of this element to learn if it is
8393					// being hidden by cascaded rules or not
8394					if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8395						display = elem.style.display = "";
8396					}
8397
8398					// Set elements which have been overridden with display: none
8399					// in a stylesheet to whatever the default browser style is
8400					// for such an element
8401					if ( (display === "" && jQuery.css(elem, "display") === "none") ||
8402						!jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
8403						jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
8404					}
8405				}
8406			}
8407
8408			// Set the display of most of the elements in a second loop
8409			// to avoid the constant reflow
8410			for ( i = 0; i < j; i++ ) {
8411				elem = this[ i ];
8412
8413				if ( elem.style ) {
8414					display = elem.style.display;
8415
8416					if ( display === "" || display === "none" ) {
8417						elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
8418					}
8419				}
8420			}
8421
8422			return this;
8423		}
8424	},
8425
8426	hide: function( speed, easing, callback ) {
8427		if ( speed || speed === 0 ) {
8428			return this.animate( genFx("hide", 3), speed, easing, callback);
8429
8430		} else {
8431			var elem, display,
8432				i = 0,
8433				j = this.length;
8434
8435			for ( ; i < j; i++ ) {
8436				elem = this[i];
8437				if ( elem.style ) {
8438					display = jQuery.css( elem, "display" );
8439
8440					if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
8441						jQuery._data( elem, "olddisplay", display );
8442					}
8443				}
8444			}
8445
8446			// Set the display of the elements in a second loop
8447			// to avoid the constant reflow
8448			for ( i = 0; i < j; i++ ) {
8449				if ( this[i].style ) {
8450					this[i].style.display = "none";
8451				}
8452			}
8453
8454			return this;
8455		}
8456	},
8457
8458	// Save the old toggle function
8459	_toggle: jQuery.fn.toggle,
8460
8461	toggle: function( fn, fn2, callback ) {
8462		var bool = typeof fn === "boolean";
8463
8464		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8465			this._toggle.apply( this, arguments );
8466
8467		} else if ( fn == null || bool ) {
8468			this.each(function() {
8469				var state = bool ? fn : jQuery(this).is(":hidden");
8470				jQuery(this)[ state ? "show" : "hide" ]();
8471			});
8472
8473		} else {
8474			this.animate(genFx("toggle", 3), fn, fn2, callback);
8475		}
8476
8477		return this;
8478	},
8479
8480	fadeTo: function( speed, to, easing, callback ) {
8481		return this.filter(":hidden").css("opacity", 0).show().end()
8482					.animate({opacity: to}, speed, easing, callback);
8483	},
8484
8485	animate: function( prop, speed, easing, callback ) {
8486		var optall = jQuery.speed( speed, easing, callback );
8487
8488		if ( jQuery.isEmptyObject( prop ) ) {
8489			return this.each( optall.complete, [ false ] );
8490		}
8491
8492		// Do not change referenced properties as per-property easing will be lost
8493		prop = jQuery.extend( {}, prop );
8494
8495		function doAnimation() {
8496			// XXX 'this' does not always have a nodeName when running the
8497			// test suite
8498
8499			if ( optall.queue === false ) {
8500				jQuery._mark( this );
8501			}
8502
8503			var opt = jQuery.extend( {}, optall ),
8504				isElement = this.nodeType === 1,
8505				hidden = isElement && jQuery(this).is(":hidden"),
8506				name, val, p, e, hooks, replace,
8507				parts, start, end, unit,
8508				method;
8509
8510			// will store per property easing and be used to determine when an animation is complete
8511			opt.animatedProperties = {};
8512
8513			// first pass over propertys to expand / normalize
8514			for ( p in prop ) {
8515				name = jQuery.camelCase( p );
8516				if ( p !== name ) {
8517					prop[ name ] = prop[ p ];
8518					delete prop[ p ];
8519				}
8520
8521				if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) {
8522					replace = hooks.expand( prop[ name ] );
8523					delete prop[ name ];
8524
8525					// not quite $.extend, this wont overwrite keys already present.
8526					// also - reusing 'p' from above because we have the correct "name"
8527					for ( p in replace ) {
8528						if ( ! ( p in prop ) ) {
8529							prop[ p ] = replace[ p ];
8530						}
8531					}
8532				}
8533			}
8534
8535			for ( name in prop ) {
8536				val = prop[ name ];
8537				// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8538				if ( jQuery.isArray( val ) ) {
8539					opt.animatedProperties[ name ] = val[ 1 ];
8540					val = prop[ name ] = val[ 0 ];
8541				} else {
8542					opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8543				}
8544
8545				if ( val === "hide" && hidden || val === "show" && !hidden ) {
8546					return opt.complete.call( this );
8547				}
8548
8549				if ( isElement && ( name === "height" || name === "width" ) ) {
8550					// Make sure that nothing sneaks out
8551					// Record all 3 overflow attributes because IE does not
8552					// change the overflow attribute when overflowX and
8553					// overflowY are set to the same value
8554					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8555
8556					// Set display property to inline-block for height/width
8557					// animations on inline elements that are having width/height animated
8558					if ( jQuery.css( this, "display" ) === "inline" &&
8559							jQuery.css( this, "float" ) === "none" ) {
8560
8561						// inline-level elements accept inline-block;
8562						// block-level elements need to be inline with layout
8563						if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
8564							this.style.display = "inline-block";
8565
8566						} else {
8567							this.style.zoom = 1;
8568						}
8569					}
8570				}
8571			}
8572
8573			if ( opt.overflow != null ) {
8574				this.style.overflow = "hidden";
8575			}
8576
8577			for ( p in prop ) {
8578				e = new jQuery.fx( this, opt, p );
8579				val = prop[ p ];
8580
8581				if ( rfxtypes.test( val ) ) {
8582
8583					// Tracks whether to show or hide based on private
8584					// data attached to the element
8585					method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
8586					if ( method ) {
8587						jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
8588						e[ method ]();
8589					} else {
8590						e[ val ]();
8591					}
8592
8593				} else {
8594					parts = rfxnum.exec( val );
8595					start = e.cur();
8596
8597					if ( parts ) {
8598						end = parseFloat( parts[2] );
8599						unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8600
8601						// We need to compute starting value
8602						if ( unit !== "px" ) {
8603							jQuery.style( this, p, (end || 1) + unit);
8604							start = ( (end || 1) / e.cur() ) * start;
8605							jQuery.style( this, p, start + unit);
8606						}
8607
8608						// If a +=/-= token was provided, we're doing a relative animation
8609						if ( parts[1] ) {
8610							end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8611						}
8612
8613						e.custom( start, end, unit );
8614
8615					} else {
8616						e.custom( start, val, "" );
8617					}
8618				}
8619			}
8620
8621			// For JS strict compliance
8622			return true;
8623		}
8624
8625		return optall.queue === false ?
8626			this.each( doAnimation ) :
8627			this.queue( optall.queue, doAnimation );
8628	},
8629
8630	stop: function( type, clearQueue, gotoEnd ) {
8631		if ( typeof type !== "string" ) {
8632			gotoEnd = clearQueue;
8633			clearQueue = type;
8634			type = undefined;
8635		}
8636		if ( clearQueue && type !== false ) {
8637			this.queue( type || "fx", [] );
8638		}
8639
8640		return this.each(function() {
8641			var index,
8642				hadTimers = false,
8643				timers = jQuery.timers,
8644				data = jQuery._data( this );
8645
8646			// clear marker counters if we know they won't be
8647			if ( !gotoEnd ) {
8648				jQuery._unmark( true, this );
8649			}
8650
8651			function stopQueue( elem, data, index ) {
8652				var hooks = data[ index ];
8653				jQuery.removeData( elem, index, true );
8654				hooks.stop( gotoEnd );
8655			}
8656
8657			if ( type == null ) {
8658				for ( index in data ) {
8659					if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {
8660						stopQueue( this, data, index );
8661					}
8662				}
8663			} else if ( data[ index = type + ".run" ] && data[ index ].stop ){
8664				stopQueue( this, data, index );
8665			}
8666
8667			for ( index = timers.length; index--; ) {
8668				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
8669					if ( gotoEnd ) {
8670
8671						// force the next step to be the last
8672						timers[ index ]( true );
8673					} else {
8674						timers[ index ].saveState();
8675					}
8676					hadTimers = true;
8677					timers.splice( index, 1 );
8678				}
8679			}
8680
8681			// start the next in the queue if the last step wasn't forced
8682			// timers currently will call their complete callbacks, which will dequeue
8683			// but only if they were gotoEnd
8684			if ( !( gotoEnd && hadTimers ) ) {
8685				jQuery.dequeue( this, type );
8686			}
8687		});
8688	}
8689
8690});
8691
8692// Animations created synchronously will run synchronously
8693function createFxNow() {
8694	setTimeout( clearFxNow, 0 );
8695	return ( fxNow = jQuery.now() );
8696}
8697
8698function clearFxNow() {
8699	fxNow = undefined;
8700}
8701
8702// Generate parameters to create a standard animation
8703function genFx( type, num ) {
8704	var obj = {};
8705
8706	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
8707		obj[ this ] = type;
8708	});
8709
8710	return obj;
8711}
8712
8713// Generate shortcuts for custom animations
8714jQuery.each({
8715	slideDown: genFx( "show", 1 ),
8716	slideUp: genFx( "hide", 1 ),
8717	slideToggle: genFx( "toggle", 1 ),
8718	fadeIn: { opacity: "show" },
8719	fadeOut: { opacity: "hide" },
8720	fadeToggle: { opacity: "toggle" }
8721}, function( name, props ) {
8722	jQuery.fn[ name ] = function( speed, easing, callback ) {
8723		return this.animate( props, speed, easing, callback );
8724	};
8725});
8726
8727jQuery.extend({
8728	speed: function( speed, easing, fn ) {
8729		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8730			complete: fn || !fn && easing ||
8731				jQuery.isFunction( speed ) && speed,
8732			duration: speed,
8733			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8734		};
8735
8736		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8737			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8738
8739		// normalize opt.queue - true/undefined/null -> "fx"
8740		if ( opt.queue == null || opt.queue === true ) {
8741			opt.queue = "fx";
8742		}
8743
8744		// Queueing
8745		opt.old = opt.complete;
8746
8747		opt.complete = function( noUnmark ) {
8748			if ( jQuery.isFunction( opt.old ) ) {
8749				opt.old.call( this );
8750			}
8751
8752			if ( opt.queue ) {
8753				jQuery.dequeue( this, opt.queue );
8754			} else if ( noUnmark !== false ) {
8755				jQuery._unmark( this );
8756			}
8757		};
8758
8759		return opt;
8760	},
8761
8762	easing: {
8763		linear: function( p ) {
8764			return p;
8765		},
8766		swing: function( p ) {
8767			return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;
8768		}
8769	},
8770
8771	timers: [],
8772
8773	fx: function( elem, options, prop ) {
8774		this.options = options;
8775		this.elem = elem;
8776		this.prop = prop;
8777
8778		options.orig = options.orig || {};
8779	}
8780
8781});
8782
8783jQuery.fx.prototype = {
8784	// Simple function for setting a style value
8785	update: function() {
8786		if ( this.options.step ) {
8787			this.options.step.call( this.elem, this.now, this );
8788		}
8789
8790		( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
8791	},
8792
8793	// Get the current size
8794	cur: function() {
8795		if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
8796			return this.elem[ this.prop ];
8797		}
8798
8799		var parsed,
8800			r = jQuery.css( this.elem, this.prop );
8801		// Empty strings, null, undefined and "auto" are converted to 0,
8802		// complex values such as "rotate(1rad)" are returned as is,
8803		// simple values such as "10px" are parsed to Float.
8804		return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8805	},
8806
8807	// Start an animation from one number to another
8808	custom: function( from, to, unit ) {
8809		var self = this,
8810			fx = jQuery.fx;
8811
8812		this.startTime = fxNow || createFxNow();
8813		this.end = to;
8814		this.now = this.start = from;
8815		this.pos = this.state = 0;
8816		this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8817
8818		function t( gotoEnd ) {
8819			return self.step( gotoEnd );
8820		}
8821
8822		t.queue = this.options.queue;
8823		t.elem = this.elem;
8824		t.saveState = function() {
8825			if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
8826				if ( self.options.hide ) {
8827					jQuery._data( self.elem, "fxshow" + self.prop, self.start );
8828				} else if ( self.options.show ) {
8829					jQuery._data( self.elem, "fxshow" + self.prop, self.end );
8830				}
8831			}
8832		};
8833
8834		if ( t() && jQuery.timers.push(t) && !timerId ) {
8835			timerId = setInterval( fx.tick, fx.interval );
8836		}
8837	},
8838
8839	// Simple 'show' function
8840	show: function() {
8841		var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
8842
8843		// Remember where we started, so that we can go back to it later
8844		this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
8845		this.options.show = true;
8846
8847		// Begin the animation
8848		// Make sure that we start at a small width/height to avoid any flash of content
8849		if ( dataShow !== undefined ) {
8850			// This show is picking up where a previous hide or show left off
8851			this.custom( this.cur(), dataShow );
8852		} else {
8853			this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
8854		}
8855
8856		// Start by showing the element
8857		jQuery( this.elem ).show();
8858	},
8859
8860	// Simple 'hide' function
8861	hide: function() {
8862		// Remember where we started, so that we can go back to it later
8863		this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
8864		this.options.hide = true;
8865
8866		// Begin the animation
8867		this.custom( this.cur(), 0 );
8868	},
8869
8870	// Each step of an animation
8871	step: function( gotoEnd ) {
8872		var p, n, complete,
8873			t = fxNow || createFxNow(),
8874			done = true,
8875			elem = this.elem,
8876			options = this.options;
8877
8878		if ( gotoEnd || t >= options.duration + this.startTime ) {
8879			this.now = this.end;
8880			this.pos = this.state = 1;
8881			this.update();
8882
8883			options.animatedProperties[ this.prop ] = true;
8884
8885			for ( p in options.animatedProperties ) {
8886				if ( options.animatedProperties[ p ] !== true ) {
8887					done = false;
8888				}
8889			}
8890
8891			if ( done ) {
8892				// Reset the overflow
8893				if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8894
8895					jQuery.each( [ "", "X", "Y" ], function( index, value ) {
8896						elem.style[ "overflow" + value ] = options.overflow[ index ];
8897					});
8898				}
8899
8900				// Hide the element if the "hide" operation was done
8901				if ( options.hide ) {
8902					jQuery( elem ).hide();
8903				}
8904
8905				// Reset the properties, if the item has been hidden or shown
8906				if ( options.hide || options.show ) {
8907					for ( p in options.animatedProperties ) {
8908						jQuery.style( elem, p, options.orig[ p ] );
8909						jQuery.removeData( elem, "fxshow" + p, true );
8910						// Toggle data is no longer needed
8911						jQuery.removeData( elem, "toggle" + p, true );
8912					}
8913				}
8914
8915				// Execute the complete function
8916				// in the event that the complete function throws an exception
8917				// we must ensure it won't be called twice. #5684
8918
8919				complete = options.complete;
8920				if ( complete ) {
8921
8922					options.complete = false;
8923					complete.call( elem );
8924				}
8925			}
8926
8927			return false;
8928
8929		} else {
8930			// classical easing cannot be used with an Infinity duration
8931			if ( options.duration == Infinity ) {
8932				this.now = t;
8933			} else {
8934				n = t - this.startTime;
8935				this.state = n / options.duration;
8936
8937				// Perform the easing function, defaults to swing
8938				this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
8939				this.now = this.start + ( (this.end - this.start) * this.pos );
8940			}
8941			// Perform the next step of the animation
8942			this.update();
8943		}
8944
8945		return true;
8946	}
8947};
8948
8949jQuery.extend( jQuery.fx, {
8950	tick: function() {
8951		var timer,
8952			timers = jQuery.timers,
8953			i = 0;
8954
8955		for ( ; i < timers.length; i++ ) {
8956			timer = timers[ i ];
8957			// Checks the timer has not already been removed
8958			if ( !timer() && timers[ i ] === timer ) {
8959				timers.splice( i--, 1 );
8960			}
8961		}
8962
8963		if ( !timers.length ) {
8964			jQuery.fx.stop();
8965		}
8966	},
8967
8968	interval: 13,
8969
8970	stop: function() {
8971		clearInterval( timerId );
8972		timerId = null;
8973	},
8974
8975	speeds: {
8976		slow: 600,
8977		fast: 200,
8978		// Default speed
8979		_default: 400
8980	},
8981
8982	step: {
8983		opacity: function( fx ) {
8984			jQuery.style( fx.elem, "opacity", fx.now );
8985		},
8986
8987		_default: function( fx ) {
8988			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8989				fx.elem.style[ fx.prop ] = fx.now + fx.unit;
8990			} else {
8991				fx.elem[ fx.prop ] = fx.now;
8992			}
8993		}
8994	}
8995});
8996
8997// Ensure props that can't be negative don't go there on undershoot easing
8998jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) {
8999	// exclude marginTop, marginLeft, marginBottom and marginRight from this list
9000	if ( prop.indexOf( "margin" ) ) {
9001		jQuery.fx.step[ prop ] = function( fx ) {
9002			jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
9003		};
9004	}
9005});
9006
9007if ( jQuery.expr && jQuery.expr.filters ) {
9008	jQuery.expr.filters.animated = function( elem ) {
9009		return jQuery.grep(jQuery.timers, function( fn ) {
9010			return elem === fn.elem;
9011		}).length;
9012	};
9013}
9014
9015// Try to restore the default display value of an element
9016function defaultDisplay( nodeName ) {
9017
9018	if ( !elemdisplay[ nodeName ] ) {
9019
9020		var body = document.body,
9021			elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
9022			display = elem.css( "display" );
9023		elem.remove();
9024
9025		// If the simple way fails,
9026		// get element's real default display by attaching it to a temp iframe
9027		if ( display === "none" || display === "" ) {
9028			// No iframe to use yet, so create it
9029			if ( !iframe ) {
9030				iframe = document.createElement( "iframe" );
9031				iframe.frameBorder = iframe.width = iframe.height = 0;
9032			}
9033
9034			body.appendChild( iframe );
9035
9036			// Create a cacheable copy of the iframe document on first call.
9037			// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
9038			// document to it; WebKit & Firefox won't allow reusing the iframe document.
9039			if ( !iframeDoc || !iframe.createElement ) {
9040				iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
9041				iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );
9042				iframeDoc.close();
9043			}
9044
9045			elem = iframeDoc.createElement( nodeName );
9046
9047			iframeDoc.body.appendChild( elem );
9048
9049			display = jQuery.css( elem, "display" );
9050			body.removeChild( iframe );
9051		}
9052
9053		// Store the correct default display
9054		elemdisplay[ nodeName ] = display;
9055	}
9056
9057	return elemdisplay[ nodeName ];
9058}
9059
9060
9061
9062
9063var getOffset,
9064	rtable = /^t(?:able|d|h)$/i,
9065	rroot = /^(?:body|html)$/i;
9066
9067if ( "getBoundingClientRect" in document.documentElement ) {
9068	getOffset = function( elem, doc, docElem, box ) {
9069		try {
9070			box = elem.getBoundingClientRect();
9071		} catch(e) {}
9072
9073		// Make sure we're not dealing with a disconnected DOM node
9074		if ( !box || !jQuery.contains( docElem, elem ) ) {
9075			return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
9076		}
9077
9078		var body = doc.body,
9079			win = getWindow( doc ),
9080			clientTop  = docElem.clientTop  || body.clientTop  || 0,
9081			clientLeft = docElem.clientLeft || body.clientLeft || 0,
9082			scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
9083			scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
9084			top  = box.top  + scrollTop  - clientTop,
9085			left = box.left + scrollLeft - clientLeft;
9086
9087		return { top: top, left: left };
9088	};
9089
9090} else {
9091	getOffset = function( elem, doc, docElem ) {
9092		var computedStyle,
9093			offsetParent = elem.offsetParent,
9094			prevOffsetParent = elem,
9095			body = doc.body,
9096			defaultView = doc.defaultView,
9097			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9098			top = elem.offsetTop,
9099			left = elem.offsetLeft;
9100
9101		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9102			if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9103				break;
9104			}
9105
9106			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9107			top  -= elem.scrollTop;
9108			left -= elem.scrollLeft;
9109
9110			if ( elem === offsetParent ) {
9111				top  += elem.offsetTop;
9112				left += elem.offsetLeft;
9113
9114				if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9115					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9116					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9117				}
9118
9119				prevOffsetParent = offsetParent;
9120				offsetParent = elem.offsetParent;
9121			}
9122
9123			if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9124				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9125				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9126			}
9127
9128			prevComputedStyle = computedStyle;
9129		}
9130
9131		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9132			top  += body.offsetTop;
9133			left += body.offsetLeft;
9134		}
9135
9136		if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9137			top  += Math.max( docElem.scrollTop, body.scrollTop );
9138			left += Math.max( docElem.scrollLeft, body.scrollLeft );
9139		}
9140
9141		return { top: top, left: left };
9142	};
9143}
9144
9145jQuery.fn.offset = function( options ) {
9146	if ( arguments.length ) {
9147		return options === undefined ?
9148			this :
9149			this.each(function( i ) {
9150				jQuery.offset.setOffset( this, options, i );
9151			});
9152	}
9153
9154	var elem = this[0],
9155		doc = elem && elem.ownerDocument;
9156
9157	if ( !doc ) {
9158		return null;
9159	}
9160
9161	if ( elem === doc.body ) {
9162		return jQuery.offset.bodyOffset( elem );
9163	}
9164
9165	return getOffset( elem, doc, doc.documentElement );
9166};
9167
9168jQuery.offset = {
9169
9170	bodyOffset: function( body ) {
9171		var top = body.offsetTop,
9172			left = body.offsetLeft;
9173
9174		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9175			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9176			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9177		}
9178
9179		return { top: top, left: left };
9180	},
9181
9182	setOffset: function( elem, options, i ) {
9183		var position = jQuery.css( elem, "position" );
9184
9185		// set position first, in-case top/left are set even on static elem
9186		if ( position === "static" ) {
9187			elem.style.position = "relative";
9188		}
9189
9190		var curElem = jQuery( elem ),
9191			curOffset = curElem.offset(),
9192			curCSSTop = jQuery.css( elem, "top" ),
9193			curCSSLeft = jQuery.css( elem, "left" ),
9194			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9195			props = {}, curPosition = {}, curTop, curLeft;
9196
9197		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9198		if ( calculatePosition ) {
9199			curPosition = curElem.position();
9200			curTop = curPosition.top;
9201			curLeft = curPosition.left;
9202		} else {
9203			curTop = parseFloat( curCSSTop ) || 0;
9204			curLeft = parseFloat( curCSSLeft ) || 0;
9205		}
9206
9207		if ( jQuery.isFunction( options ) ) {
9208			options = options.call( elem, i, curOffset );
9209		}
9210
9211		if ( options.top != null ) {
9212			props.top = ( options.top - curOffset.top ) + curTop;
9213		}
9214		if ( options.left != null ) {
9215			props.left = ( options.left - curOffset.left ) + curLeft;
9216		}
9217
9218		if ( "using" in options ) {
9219			options.using.call( elem, props );
9220		} else {
9221			curElem.css( props );
9222		}
9223	}
9224};
9225
9226
9227jQuery.fn.extend({
9228
9229	position: function() {
9230		if ( !this[0] ) {
9231			return null;
9232		}
9233
9234		var elem = this[0],
9235
9236		// Get *real* offsetParent
9237		offsetParent = this.offsetParent(),
9238
9239		// Get correct offsets
9240		offset       = this.offset(),
9241		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9242
9243		// Subtract element margins
9244		// note: when an element has margin: auto the offsetLeft and marginLeft
9245		// are the same in Safari causing offset.left to incorrectly be 0
9246		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9247		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9248
9249		// Add offsetParent borders
9250		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9251		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9252
9253		// Subtract the two offsets
9254		return {
9255			top:  offset.top  - parentOffset.top,
9256			left: offset.left - parentOffset.left
9257		};
9258	},
9259
9260	offsetParent: function() {
9261		return this.map(function() {
9262			var offsetParent = this.offsetParent || document.body;
9263			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9264				offsetParent = offsetParent.offsetParent;
9265			}
9266			return offsetParent;
9267		});
9268	}
9269});
9270
9271
9272// Create scrollLeft and scrollTop methods
9273jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9274	var top = /Y/.test( prop );
9275
9276	jQuery.fn[ method ] = function( val ) {
9277		return jQuery.access( this, function( elem, method, val ) {
9278			var win = getWindow( elem );
9279
9280			if ( val === undefined ) {
9281				return win ? (prop in win) ? win[ prop ] :
9282					jQuery.support.boxModel && win.document.documentElement[ method ] ||
9283						win.document.body[ method ] :
9284					elem[ method ];
9285			}
9286
9287			if ( win ) {
9288				win.scrollTo(
9289					!top ? val : jQuery( win ).scrollLeft(),
9290					 top ? val : jQuery( win ).scrollTop()
9291				);
9292
9293			} else {
9294				elem[ method ] = val;
9295			}
9296		}, method, val, arguments.length, null );
9297	};
9298});
9299
9300function getWindow( elem ) {
9301	return jQuery.isWindow( elem ) ?
9302		elem :
9303		elem.nodeType === 9 ?
9304			elem.defaultView || elem.parentWindow :
9305			false;
9306}
9307
9308
9309
9310
9311// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
9312jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9313	var clientProp = "client" + name,
9314		scrollProp = "scroll" + name,
9315		offsetProp = "offset" + name;
9316
9317	// innerHeight and innerWidth
9318	jQuery.fn[ "inner" + name ] = function() {
9319		var elem = this[0];
9320		return elem ?
9321			elem.style ?
9322			parseFloat( jQuery.css( elem, type, "padding" ) ) :
9323			this[ type ]() :
9324			null;
9325	};
9326
9327	// outerHeight and outerWidth
9328	jQuery.fn[ "outer" + name ] = function( margin ) {
9329		var elem = this[0];
9330		return elem ?
9331			elem.style ?
9332			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9333			this[ type ]() :
9334			null;
9335	};
9336
9337	jQuery.fn[ type ] = function( value ) {
9338		return jQuery.access( this, function( elem, type, value ) {
9339			var doc, docElemProp, orig, ret;
9340
9341			if ( jQuery.isWindow( elem ) ) {
9342				// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9343				doc = elem.document;
9344				docElemProp = doc.documentElement[ clientProp ];
9345				return jQuery.support.boxModel && docElemProp ||
9346					doc.body && doc.body[ clientProp ] || docElemProp;
9347			}
9348
9349			// Get document width or height
9350			if ( elem.nodeType === 9 ) {
9351				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9352				doc = elem.documentElement;
9353
9354				// when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]
9355				// so we can't use max, as it'll choose the incorrect offset[Width/Height]
9356				// instead we use the correct client[Width/Height]
9357				// support:IE6
9358				if ( doc[ clientProp ] >= doc[ scrollProp ] ) {
9359					return doc[ clientProp ];
9360				}
9361
9362				return Math.max(
9363					elem.body[ scrollProp ], doc[ scrollProp ],
9364					elem.body[ offsetProp ], doc[ offsetProp ]
9365				);
9366			}
9367
9368			// Get width or height on the element
9369			if ( value === undefined ) {
9370				orig = jQuery.css( elem, type );
9371				ret = parseFloat( orig );
9372				return jQuery.isNumeric( ret ) ? ret : orig;
9373			}
9374
9375			// Set the width or height on the element
9376			jQuery( elem ).css( type, value );
9377		}, type, value, arguments.length, null );
9378	};
9379});
9380
9381
9382
9383
9384// Expose jQuery to the global object
9385window.jQuery = window.$ = jQuery;
9386
9387// Expose jQuery as an AMD module, but only for AMD loaders that
9388// understand the issues with loading multiple versions of jQuery
9389// in a page that all might call define(). The loader will indicate
9390// they have special allowances for multiple jQuery versions by
9391// specifying define.amd.jQuery = true. Register as a named module,
9392// since jQuery can be concatenated with other files that may use define,
9393// but not use a proper concatenation script that understands anonymous
9394// AMD modules. A named AMD is safest and most robust way to register.
9395// Lowercase jquery is used because AMD module names are derived from
9396// file names, and jQuery is normally delivered in a lowercase file name.
9397// Do this after creating the global so that if an AMD module wants to call
9398// noConflict to hide this version of jQuery, it will work.
9399if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9400	define( "jquery", [], function () { return jQuery; } );
9401}
9402
9403
9404
9405})( window );
9406(function($, undefined) {
9407
9408/**
9409 * Unobtrusive scripting adapter for jQuery
9410 * https://github.com/rails/jquery-ujs
9411 *
9412 * Requires jQuery 1.7.0 or later.
9413 *
9414 * Released under the MIT license
9415 *
9416 */
9417
9418  // Cut down on the number of issues from people inadvertently including jquery_ujs twice
9419  // by detecting and raising an error when it happens.
9420  if ( $.rails !== undefined ) {
9421    $.error('jquery-ujs has already been loaded!');
9422  }
9423
9424  // Shorthand to make it a little easier to call public rails functions from within rails.js
9425  var rails;
9426
9427  $.rails = rails = {
9428    // Link elements bound by jquery-ujs
9429    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]',
9430
9431    // Button elements boud jquery-ujs
9432    buttonClickSelector: 'button[data-remote]',
9433
9434    // Select elements bound by jquery-ujs
9435    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
9436
9437    // Form elements bound by jquery-ujs
9438    formSubmitSelector: 'form',
9439
9440    // Form input elements bound by jquery-ujs
9441    formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])',
9442
9443    // Form input elements disabled during form submission
9444    disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]',
9445
9446    // Form input elements re-enabled after form submission
9447    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled',
9448
9449    // Form required input elements
9450    requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])',
9451
9452    // Form file input elements
9453    fileInputSelector: 'input[type=file]',
9454
9455    // Link onClick disable selector with possible reenable after remote submission
9456    linkDisableSelector: 'a[data-disable-with]',
9457
9458    // Make sure that every Ajax request sends the CSRF token
9459    CSRFProtection: function(xhr) {
9460      var token = $('meta[name="csrf-token"]').attr('content');
9461      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
9462    },
9463
9464    // Triggers an event on an element and returns false if the event result is false
9465    fire: function(obj, name, data) {
9466      var event = $.Event(name);
9467      obj.trigger(event, data);
9468      return event.result !== false;
9469    },
9470
9471    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
9472    confirm: function(message) {
9473      return confirm(message);
9474    },
9475
9476    // Default ajax function, may be overridden with custom function in $.rails.ajax
9477    ajax: function(options) {
9478      return $.ajax(options);
9479    },
9480
9481    // Default way to get an element's href. May be overridden at $.rails.href.
9482    href: function(element) {
9483      return element.attr('href');
9484    },
9485
9486    // Submits "remote" forms and links with ajax
9487    handleRemote: function(element) {
9488      var method, url, data, elCrossDomain, crossDomain, withCredentials, dataType, options;
9489
9490      if (rails.fire(element, 'ajax:before')) {
9491        elCrossDomain = element.data('cross-domain');
9492        crossDomain = elCrossDomain === undefined ? null : elCrossDomain;
9493        withCredentials = element.data('with-credentials') || null;
9494        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
9495
9496        if (element.is('form')) {
9497          method = element.attr('method');
9498          url = element.attr('action');
9499          data = element.serializeArray();
9500          // memoized value from clicked submit button
9501          var button = element.data('ujs:submit-button');
9502          if (button) {
9503            data.push(button);
9504            element.data('ujs:submit-button', null);
9505          }
9506        } else if (element.is(rails.inputChangeSelector)) {
9507          method = element.data('method');
9508          url = element.data('url');
9509          data = element.serialize();
9510          if (element.data('params')) data = data + "&" + element.data('params');
9511        } else if (element.is(rails.buttonClickSelector)) {
9512          method = element.data('method') || 'get';
9513          url = element.data('url');
9514          data = element.serialize();
9515          if (element.data('params')) data = data + "&" + element.data('params');
9516        } else {
9517          method = element.data('method');
9518          url = rails.href(element);
9519          data = element.data('params') || null;
9520        }
9521
9522        options = {
9523          type: method || 'GET', data: data, dataType: dataType,
9524          // stopping the "ajax:beforeSend" event will cancel the ajax request
9525          beforeSend: function(xhr, settings) {
9526            if (settings.dataType === undefined) {
9527              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
9528            }
9529            return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
9530          },
9531          success: function(data, status, xhr) {
9532            element.trigger('ajax:success', [data, status, xhr]);
9533          },
9534          complete: function(xhr, status) {
9535            element.trigger('ajax:complete', [xhr, status]);
9536          },
9537          error: function(xhr, status, error) {
9538            element.trigger('ajax:error', [xhr, status, error]);
9539          },
9540          crossDomain: crossDomain
9541        };
9542
9543        // There is no withCredentials for IE6-8 when
9544        // "Enable native XMLHTTP support" is disabled
9545        if (withCredentials) {
9546          options.xhrFields = {
9547            withCredentials: withCredentials
9548          };
9549        }
9550
9551        // Only pass url to `ajax` options if not blank
9552        if (url) { options.url = url; }
9553
9554        var jqxhr = rails.ajax(options);
9555        element.trigger('ajax:send', jqxhr);
9556        return jqxhr;
9557      } else {
9558        return false;
9559      }
9560    },
9561
9562    // Handles "data-method" on links such as:
9563    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
9564    handleMethod: function(link) {
9565      var href = rails.href(link),
9566        method = link.data('method'),
9567        target = link.attr('target'),
9568        csrf_token = $('meta[name=csrf-token]').attr('content'),
9569        csrf_param = $('meta[name=csrf-param]').attr('content'),
9570        form = $('<form method="post" action="' + href + '"></form>'),
9571        metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
9572
9573      if (csrf_param !== undefined && csrf_token !== undefined) {
9574        metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
9575      }
9576
9577      if (target) { form.attr('target', target); }
9578
9579      form.hide().append(metadata_input).appendTo('body');
9580      form.submit();
9581    },
9582
9583    /* Disables form elements:
9584      - Caches element value in 'ujs:enable-with' data store
9585      - Replaces element text with value of 'data-disable-with' attribute
9586      - Sets disabled property to true
9587    */
9588    disableFormElements: function(form) {
9589      form.find(rails.disableSelector).each(function() {
9590        var element = $(this), method = element.is('button') ? 'html' : 'val';
9591        element.data('ujs:enable-with', element[method]());
9592        element[method](element.data('disable-with'));
9593        element.prop('disabled', true);
9594      });
9595    },
9596
9597    /* Re-enables disabled form elements:
9598      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
9599      - Sets disabled property to false
9600    */
9601    enableFormElements: function(form) {
9602      form.find(rails.enableSelector).each(function() {
9603        var element = $(this), method = element.is('button') ? 'html' : 'val';
9604        if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
9605        element.prop('disabled', false);
9606      });
9607    },
9608
9609   /* For 'data-confirm' attribute:
9610      - Fires `confirm` event
9611      - Shows the confirmation dialog
9612      - Fires the `confirm:complete` event
9613
9614      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
9615      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
9616      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
9617      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
9618   */
9619    allowAction: function(element) {
9620      var message = element.data('confirm'),
9621          answer = false, callback;
9622      if (!message) { return true; }
9623
9624      if (rails.fire(element, 'confirm')) {
9625        answer = rails.confirm(message);
9626        callback = rails.fire(element, 'confirm:complete', [answer]);
9627      }
9628      return answer && callback;
9629    },
9630
9631    // Helper function which checks for blank inputs in a form that match the specified CSS selector
9632    blankInputs: function(form, specifiedSelector, nonBlank) {
9633      var inputs = $(), input, valueToCheck,
9634          selector = specifiedSelector || 'input,textarea',
9635          allInputs = form.find(selector);
9636
9637      allInputs.each(function() {
9638        input = $(this);
9639        valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : input.val();
9640        // If nonBlank and valueToCheck are both truthy, or nonBlank and valueToCheck are both falsey
9641        if (!valueToCheck === !nonBlank) {
9642
9643          // Don't count unchecked required radio if other radio with same name is checked
9644          if (input.is('input[type=radio]') && allInputs.filter('input[type=radio]:checked[name="' + input.attr('name') + '"]').length) {
9645            return true; // Skip to next input
9646          }
9647
9648          inputs = inputs.add(input);
9649        }
9650      });
9651      return inputs.length ? inputs : false;
9652    },
9653
9654    // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
9655    nonBlankInputs: function(form, specifiedSelector) {
9656      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
9657    },
9658
9659    // Helper function, needed to provide consistent behavior in IE
9660    stopEverything: function(e) {
9661      $(e.target).trigger('ujs:everythingStopped');
9662      e.stopImmediatePropagation();
9663      return false;
9664    },
9665
9666    //  replace element's html with the 'data-disable-with' after storing original html
9667    //  and prevent clicking on it
9668    disableElement: function(element) {
9669      element.data('ujs:enable-with', element.html()); // store enabled state
9670      element.html(element.data('disable-with')); // set to disabled state
9671      element.bind('click.railsDisable', function(e) { // prevent further clicking
9672        return rails.stopEverything(e);
9673      });
9674    },
9675
9676    // restore element to its original state which was disabled by 'disableElement' above
9677    enableElement: function(element) {
9678      if (element.data('ujs:enable-with') !== undefined) {
9679        element.html(element.data('ujs:enable-with')); // set to old enabled state
9680        element.removeData('ujs:enable-with'); // clean up cache
9681      }
9682      element.unbind('click.railsDisable'); // enable element
9683    }
9684
9685  };
9686
9687  if (rails.fire($(document), 'rails:attachBindings')) {
9688
9689    $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
9690
9691    $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() {
9692        rails.enableElement($(this));
9693    });
9694
9695    $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) {
9696      var link = $(this), method = link.data('method'), data = link.data('params');
9697      if (!rails.allowAction(link)) return rails.stopEverything(e);
9698
9699      if (link.is(rails.linkDisableSelector)) rails.disableElement(link);
9700
9701      if (link.data('remote') !== undefined) {
9702        if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; }
9703
9704        var handleRemote = rails.handleRemote(link);
9705        // response from rails.handleRemote() will either be false or a deferred object promise.
9706        if (handleRemote === false) {
9707          rails.enableElement(link);
9708        } else {
9709          handleRemote.error( function() { rails.enableElement(link); } );
9710        }
9711        return false;
9712
9713      } else if (link.data('method')) {
9714        rails.handleMethod(link);
9715        return false;
9716      }
9717    });
9718
9719    $(document).delegate(rails.buttonClickSelector, 'click.rails', function(e) {
9720      var button = $(this);
9721      if (!rails.allowAction(button)) return rails.stopEverything(e);
9722
9723      rails.handleRemote(button);
9724      return false;
9725    });
9726
9727    $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) {
9728      var link = $(this);
9729      if (!rails.allowAction(link)) return rails.stopEverything(e);
9730
9731      rails.handleRemote(link);
9732      return false;
9733    });
9734
9735    $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
9736      var form = $(this),
9737        remote = form.data('remote') !== undefined,
9738        blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
9739        nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
9740
9741      if (!rails.allowAction(form)) return rails.stopEverything(e);
9742
9743      // skip other logic when required values are missing or file upload is present
9744      if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
9745        return rails.stopEverything(e);
9746      }
9747
9748      if (remote) {
9749        if (nonBlankFileInputs) {
9750          // slight timeout so that the submit button gets properly serialized
9751          // (make it easy for event handler to serialize form without disabled values)
9752          setTimeout(function(){ rails.disableFormElements(form); }, 13);
9753          var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
9754
9755          // re-enable form elements if event bindings return false (canceling normal form submission)
9756          if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
9757
9758          return aborted;
9759        }
9760
9761        rails.handleRemote(form);
9762        return false;
9763
9764      } else {
9765        // slight timeout so that the submit button gets properly serialized
9766        setTimeout(function(){ rails.disableFormElements(form); }, 13);
9767      }
9768    });
9769
9770    $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) {
9771      var button = $(this);
9772
9773      if (!rails.allowAction(button)) return rails.stopEverything(event);
9774
9775      // register the pressed submit button
9776      var name = button.attr('name'),
9777        data = name ? {name:name, value:button.val()} : null;
9778
9779      button.closest('form').data('ujs:submit-button', data);
9780    });
9781
9782    $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) {
9783      if (this == event.target) rails.disableFormElements($(this));
9784    });
9785
9786    $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) {
9787      if (this == event.target) rails.enableFormElements($(this));
9788    });
9789
9790    $(function(){
9791      // making sure that all forms have actual up-to-date token(cached forms contain old one)
9792      var csrf_token = $('meta[name=csrf-token]').attr('content');
9793      var csrf_param = $('meta[name=csrf-param]').attr('content');
9794      $('form input[name="' + csrf_param + '"]').val(csrf_token);
9795    });
9796  }
9797
9798})( jQuery );
9799/*! http://mths.be/placeholder v2.0.7 by @mathias */
9800
9801;(function(window, document, $) {
9802
9803	var isInputSupported = 'placeholder' in document.createElement('input'),
9804	    isTextareaSupported = 'placeholder' in document.createElement('textarea'),
9805	    prototype = $.fn,
9806	    valHooks = $.valHooks,
9807	    hooks,
9808	    placeholder;
9809
9810	if (isInputSupported && isTextareaSupported) {
9811
9812		placeholder = prototype.placeholder = function() {
9813			return this;
9814		};
9815
9816		placeholder.input = placeholder.textarea = true;
9817
9818	} else {
9819
9820		placeholder = prototype.placeholder = function() {
9821			var $this = this;
9822			$this
9823				.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
9824				.not('.placeholder')
9825				.bind({
9826					'focus.placeholder': clearPlaceholder,
9827					'blur.placeholder': setPlaceholder
9828				})
9829				.data('placeholder-enabled', true)
9830				.trigger('blur.placeholder');
9831			return $this;
9832		};
9833
9834		placeholder.input = isInputSupported;
9835		placeholder.textarea = isTextareaSupported;
9836
9837		hooks = {
9838			'get': function(element) {
9839				var $element = $(element);
9840				return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
9841			},
9842			'set': function(element, value) {
9843				var $element = $(element);
9844				if (!$element.data('placeholder-enabled')) {
9845					return element.value = value;
9846				}
9847				if (value == '') {
9848					element.value = value;
9849					// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
9850					if (element != document.activeElement) {
9851						// We can't use `triggerHandler` here because of dummy text/password inputs :(
9852						setPlaceholder.call(element);
9853					}
9854				} else if ($element.hasClass('placeholder')) {
9855					clearPlaceholder.call(element, true, value) || (element.value = value);
9856				} else {
9857					element.value = value;
9858				}
9859				// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
9860				return $element;
9861			}
9862		};
9863
9864		isInputSupported || (valHooks.input = hooks);
9865		isTextareaSupported || (valHooks.textarea = hooks);
9866
9867		$(function() {
9868			// Look for forms
9869			$(document).delegate('form', 'submit.placeholder', function() {
9870				// Clear the placeholder values so they don't get submitted
9871				var $inputs = $('.placeholder', this).each(clearPlaceholder);
9872				setTimeout(function() {
9873					$inputs.each(setPlaceholder);
9874				}, 10);
9875			});
9876		});
9877
9878		// Clear placeholder values upon page reload
9879		$(window).bind('beforeunload.placeholder', function() {
9880			$('.placeholder').each(function() {
9881				this.value = '';
9882			});
9883		});
9884
9885	}
9886
9887	function args(elem) {
9888		// Return an object of element attributes
9889		var newAttrs = {},
9890		    rinlinejQuery = /^jQuery\d+$/;
9891		$.each(elem.attributes, function(i, attr) {
9892			if (attr.specified && !rinlinejQuery.test(attr.name)) {
9893				newAttrs[attr.name] = attr.value;
9894			}
9895		});
9896		return newAttrs;
9897	}
9898
9899	function clearPlaceholder(event, value) {
9900		var input = this,
9901		    $input = $(input);
9902		if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
9903			if ($input.data('placeholder-password')) {
9904				$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
9905				// If `clearPlaceholder` was called from `$.valHooks.input.set`
9906				if (event === true) {
9907					return $input[0].value = value;
9908				}
9909				$input.focus();
9910			} else {
9911				input.value = '';
9912				$input.removeClass('placeholder');
9913				input == document.activeElement && input.select();
9914			}
9915		}
9916	}
9917
9918	function setPlaceholder() {
9919		var $replacement,
9920		    input = this,
9921		    $input = $(input),
9922		    $origInput = $input,
9923		    id = this.id;
9924		if (input.value == '') {
9925			if (input.type == 'password') {
9926				if (!$input.data('placeholder-textinput')) {
9927					try {
9928						$replacement = $input.clone().attr({ 'type': 'text' });
9929					} catch(e) {
9930						$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
9931					}
9932					$replacement
9933						.removeAttr('name')
9934						.data({
9935							'placeholder-password': true,
9936							'placeholder-id': id
9937						})
9938						.bind('focus.placeholder', clearPlaceholder);
9939					$input
9940						.data({
9941							'placeholder-textinput': $replacement,
9942							'placeholder-id': id
9943						})
9944						.before($replacement);
9945				}
9946				$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
9947				// Note: `$input[0] != input` now!
9948			}
9949			$input.addClass('placeholder');
9950			$input[0].value = $input.attr('placeholder');
9951		} else {
9952			$input.removeClass('placeholder');
9953		}
9954	}
9955
9956}(this, document, jQuery));
9957/*
9958 * jQuery Orbit Plugin 1.4.0
9959 * www.ZURB.com/playground
9960 * Copyright 2010, ZURB
9961 * Free to use under the MIT license.
9962 * http://www.opensource.org/licenses/mit-license.php
9963*/
9964
9965
9966
9967(function ($) {
9968  'use strict';
9969
9970  $.fn.findFirstImage = function () {
9971    return this.first()
9972            .find('img')
9973            .andSelf().filter('img')
9974            .first();
9975  };
9976
9977  var ORBIT = {
9978
9979    defaults: {
9980      animation: 'horizontal-push',     // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push
9981      animationSpeed: 600,              // how fast animations are
9982      timer: true,                      // display timer?
9983      advanceSpeed: 4000,               // if timer is enabled, time between transitions
9984      pauseOnHover: false,              // if you hover pauses the slider
9985      startClockOnMouseOut: false,      // if clock should start on MouseOut
9986      startClockOnMouseOutAfter: 1000,  // how long after MouseOut should the timer start again
9987      directionalNav: true,             // manual advancing directional navs
9988      directionalNavRightText: 'Right', // text of right directional element for accessibility
9989      directionalNavLeftText: 'Left',   // text of left directional element for accessibility
9990      captions: true,                   // do you want captions?
9991      captionAnimation: 'fade',         // fade, slideOpen, none
9992      captionAnimationSpeed: 600,       // if so how quickly should they animate in
9993      resetTimerOnClick: false,         // true resets the timer instead of pausing slideshow progress on manual navigation
9994      bullets: false,                   // true or false to activate the bullet navigation
9995      bulletThumbs: false,              // thumbnails for the bullets
9996      bulletThumbLocation: '',          // relative path to thumbnails from this file
9997      bulletThumbsHideOnSmall: true,	// hide thumbs on small devices
9998      afterSlideChange: $.noop,         // callback to execute after slide changes
9999      afterLoadComplete: $.noop,        // callback to execute after everything has been loaded
10000      fluid: true,
10001      centerBullets: true,              // center bullet nav with js, turn this off if you want to position the bullet nav manually
10002      singleCycle: false,               // cycles through orbit slides only once
10003      slideNumber: false,               // display slide numbers?
10004      stackOnSmall: false               // stack slides on small devices (i.e. phones)
10005    },
10006
10007    activeSlide: 0,
10008    numberSlides: 0,
10009    orbitWidth: null,
10010    orbitHeight: null,
10011    locked: null,
10012    timerRunning: null,
10013    degrees: 0,
10014    wrapperHTML: '<div class="orbit-wrapper" />',
10015    timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>',
10016    captionHTML: '<div class="orbit-caption"></div>',
10017    directionalNavHTML: '<div class="slider-nav hide-for-small"><span class="right"></span><span class="left"></span></div>',
10018    bulletHTML: '<ul class="orbit-bullets"></ul>',
10019    slideNumberHTML: '<span class="orbit-slide-counter"></span>',
10020
10021    init: function (element, options) {
10022      var $imageSlides,
10023          imagesLoadedCount = 0,
10024          self = this;
10025
10026      // Bind functions to correct context
10027      this.clickTimer = $.proxy(this.clickTimer, this);
10028      this.addBullet = $.proxy(this.addBullet, this);
10029      this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
10030      this.stopClock = $.proxy(this.stopClock, this);
10031      this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
10032      this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
10033      this.rotateTimer = $.proxy(this.rotateTimer, this);
10034
10035      this.options = $.extend({}, this.defaults, options);
10036      if (this.options.timer === 'false') this.options.timer = false;
10037      if (this.options.captions === 'false') this.options.captions = false;
10038      if (this.options.directionalNav === 'false') this.options.directionalNav = false;
10039
10040      this.$element = $(element);
10041      this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
10042      this.$slides = this.$element.children('img, a, div, figure, li');
10043
10044      this.$element.on('movestart', function(e) {
10045        // If the movestart is heading off in an upwards or downwards
10046        // direction, prevent it so that the browser scrolls normally.
10047        if ((e.distX > e.distY && e.distX < -e.distY) ||
10048            (e.distX < e.distY && e.distX > -e.distY)) {
10049          e.preventDefault();
10050        }
10051      });
10052
10053      this.$element.bind('orbit.next', function () {
10054        self.shift('next');
10055      });
10056
10057      this.$element.bind('orbit.prev', function () {
10058        self.shift('prev');
10059      });
10060
10061      this.$element.bind('swipeleft', function () {
10062        $(this).trigger('orbit.next');
10063      });
10064
10065      this.$element.bind('swiperight', function () {
10066        $(this).trigger('orbit.prev');
10067      });
10068
10069      this.$element.bind('orbit.goto', function (event, index) {
10070        self.shift(index);
10071      });
10072
10073      this.$element.bind('orbit.start', function (event, index) {
10074        self.startClock();
10075      });
10076
10077      this.$element.bind('orbit.stop', function (event, index) {
10078        self.stopClock();
10079      });
10080
10081      $imageSlides = this.$slides.filter('img');
10082
10083      if ($imageSlides.length === 0) {
10084        this.loaded();
10085      } else {
10086        $imageSlides.bind('imageready', function () {
10087          imagesLoadedCount += 1;
10088          if (imagesLoadedCount === $imageSlides.length) {
10089            self.loaded();
10090          }
10091        });
10092      }
10093    },
10094
10095    loaded: function () {
10096      this.$element
10097        .addClass('orbit')
10098        .css({width: '1px', height: '1px'});
10099
10100      if (this.options.stackOnSmall) {
10101        this.$element.addClass('orbit-stack-on-small');
10102      }
10103
10104      this.$slides.addClass('orbit-slide').css({"opacity" : 0});
10105
10106      this.setDimentionsFromLargestSlide();
10107      this.updateOptionsIfOnlyOneSlide();
10108      this.setupFirstSlide();
10109      this.notifySlideChange();
10110
10111      if (this.options.timer) {
10112        this.setupTimer();
10113        this.startClock();
10114      }
10115
10116      if (this.options.captions) {
10117        this.setupCaptions();
10118      }
10119
10120      if (this.options.directionalNav) {
10121        this.setupDirectionalNav();
10122      }
10123
10124      if (this.options.bullets) {
10125        this.setupBulletNav();
10126        this.setActiveBullet();
10127      }
10128
10129      this.options.afterLoadComplete.call(this);
10130      Holder.run();
10131    },
10132
10133    currentSlide: function () {
10134      return this.$slides.eq(this.activeSlide);
10135    },
10136
10137    notifySlideChange: function() {
10138      if (this.options.slideNumber) {
10139        var txt = (this.activeSlide+1) + ' of ' + this.$slides.length;
10140        this.$element.trigger("orbit.change", {slideIndex: this.activeSlide, slideCount: this.$slides.length});
10141        if (this.$counter === undefined) {
10142          var $counter = $(this.slideNumberHTML).html(txt);
10143          this.$counter = $counter;
10144          this.$wrapper.append(this.$counter);
10145        } else {
10146          this.$counter.html(txt);
10147        }
10148      }
10149    },
10150
10151    setDimentionsFromLargestSlide: function () {
10152      //Collect all slides and set slider size of largest image
10153      var self = this,
10154          $fluidPlaceholder;
10155
10156      self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
10157      self.$element.add(self.$wrapper).height(this.$slides.first().height());
10158      self.orbitWidth = this.$slides.first().outerWidth();
10159      self.orbitHeight = this.$slides.first().height();
10160      $fluidPlaceholder = this.$slides.first().findFirstImage().clone();
10161
10162
10163      this.$slides.each(function () {
10164        var slide = $(this),
10165            slideWidth = slide.outerWidth(),
10166            slideHeight = slide.height();
10167
10168        if (slideWidth > self.$element.outerWidth()) {
10169          self.$element.add(self.$wrapper).width(slideWidth);
10170          self.orbitWidth = self.$element.outerWidth();
10171        }
10172        if (slideHeight > self.$element.height()) {
10173          self.$element.add(self.$wrapper).height(slideHeight);
10174          self.orbitHeight = self.$element.height();
10175          $fluidPlaceholder = $(this).findFirstImage().clone();
10176        }
10177        self.numberSlides += 1;
10178      });
10179
10180      if (this.options.fluid) {
10181        if (typeof this.options.fluid === "string") {
10182          // $fluidPlaceholder = $("<img>").attr("src", "http://placehold.it/" + this.options.fluid);
10183          $fluidPlaceholder = $("<img>").attr("data-src", "holder.js/" + this.options.fluid);
10184          //var inner = $("<div/>").css({"display":"inline-block", "width":"2px", "height":"2px"});
10185          //$fluidPlaceholder = $("<div/>").css({"float":"left"});
10186          //$fluidPlaceholder.wrapInner(inner);
10187
10188          //$fluidPlaceholder = $("<div/>").css({"height":"1px", "width":"2px"});
10189          //$fluidPlaceholder = $("<div style='display:inline-block;width:2px;height:1px;'></div>");
10190        }
10191
10192        self.$element.prepend($fluidPlaceholder);
10193        $fluidPlaceholder.addClass('fluid-placeholder');
10194        self.$element.add(self.$wrapper).css({width: 'inherit'});
10195        self.$element.add(self.$wrapper).css({height: 'inherit'});
10196
10197        $(window).bind('resize', function () {
10198          self.orbitWidth = self.$element.outerWidth();
10199          self.orbitHeight = self.$element.height();
10200        });
10201      }
10202    },
10203
10204    //Animation locking functions
10205    lock: function () {
10206      this.locked = true;
10207    },
10208
10209    unlock: function () {
10210      this.locked = false;
10211    },
10212
10213    updateOptionsIfOnlyOneSlide: function () {
10214      if(this.$slides.length === 1) {
10215        this.options.directionalNav = false;
10216        this.options.timer = false;
10217        this.options.bullets = false;
10218      }
10219    },
10220
10221    setupFirstSlide: function () {
10222      //Set initial front photo z-index and fades it in
10223      var self = this;
10224      this.$slides.first()
10225        .css({"z-index" : 3, "opacity" : 1})
10226        .fadeIn(function() {
10227          //brings in all other slides IF css declares a display: none
10228          self.$slides.css({"display":"block"})
10229      });
10230    },
10231
10232    startClock: function () {
10233      var self = this;
10234
10235      if(!this.options.timer) {
10236        return false;
10237      }
10238
10239      if (this.$timer.is(':hidden')) {
10240        this.clock = setInterval(function () {
10241          self.$element.trigger('orbit.next');
10242        }, this.options.advanceSpeed);
10243      } else {
10244        this.timerRunning = true;
10245        this.$pause.removeClass('active');
10246        this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false);
10247      }
10248    },
10249
10250    rotateTimer: function (reset) {
10251      var degreeCSS = "rotate(" + this.degrees + "deg)";
10252      this.degrees += 2;
10253      this.$rotator.css({
10254        "-webkit-transform": degreeCSS,
10255        "-moz-transform": degreeCSS,
10256        "-o-transform": degreeCSS,
10257        "-ms-transform": degreeCSS
10258      });
10259      if (reset) {
10260        this.degrees = 0;
10261        this.$rotator.removeClass('move');
10262        this.$mask.removeClass('move');
10263      }
10264      if(this.degrees > 180) {
10265        this.$rotator.addClass('move');
10266        this.$mask.addClass('move');
10267      }
10268      if(this.degrees > 360) {
10269        this.$rotator.removeClass('move');
10270        this.$mask.removeClass('move');
10271        this.degrees = 0;
10272        this.$element.trigger('orbit.next');
10273      }
10274    },
10275
10276    stopClock: function () {
10277      if (!this.options.timer) {
10278        return false;
10279      } else {
10280        this.timerRunning = false;
10281        clearInterval(this.clock);
10282        this.$pause.addClass('active');
10283      }
10284    },
10285
10286    setupTimer: function () {
10287      this.$timer = $(this.timerHTML);
10288      this.$wrapper.append(this.$timer);
10289
10290      this.$rotator = this.$timer.find('.rotator');
10291      this.$mask = this.$timer.find('.mask');
10292      this.$pause = this.$timer.find('.pause');
10293
10294      this.$timer.click(this.clickTimer);
10295
10296      if (this.options.startClockOnMouseOut) {
10297        this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
10298        this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
10299      }
10300
10301      if (this.options.pauseOnHover) {
10302        this.$wrapper.mouseenter(this.stopClock);
10303      }
10304    },
10305
10306    startTimerAfterMouseLeave: function () {
10307      var self = this;
10308
10309      this.outTimer = setTimeout(function() {
10310        if(!self.timerRunning){
10311          self.startClock();
10312        }
10313      }, this.options.startClockOnMouseOutAfter)
10314    },
10315
10316    clearClockMouseLeaveTimer: function () {
10317      clearTimeout(this.outTimer);
10318    },
10319
10320    clickTimer: function () {
10321      if(!this.timerRunning) {
10322          this.startClock();
10323      } else {
10324          this.stopClock();
10325      }
10326    },
10327
10328    setupCaptions: function () {
10329      this.$caption = $(this.captionHTML);
10330      this.$wrapper.append(this.$caption);
10331      this.setCaption();
10332    },
10333
10334    setCaption: function () {
10335      var captionLocation = this.currentSlide().attr('data-caption'),
10336          captionHTML;
10337
10338      if (!this.options.captions) {
10339        return false;
10340      }
10341
10342      //Set HTML for the caption if it exists
10343      if (captionLocation) {
10344        //if caption text is blank, don't show captions
10345        if ($.trim($(captionLocation).text()).length < 1){
10346          return false;
10347        }
10348        
10349        // if location selector starts with '#', remove it so we don't see id="#selector"
10350        if (captionLocation.charAt(0) == '#') {
10351            captionLocation = captionLocation.substring(1, captionLocation.length);
10352        }
10353        captionHTML = $('#' + captionLocation).html(); //get HTML from the matching HTML entity
10354        this.$caption
10355          .attr('id', captionLocation) // Add ID caption TODO why is the id being set?
10356          .html(captionHTML); // Change HTML in Caption
10357          //Animations for Caption entrances
10358        switch (this.options.captionAnimation) {
10359          case 'none':
10360            this.$caption.show();
10361            break;
10362          case 'fade':
10363            this.$caption.fadeIn(this.options.captionAnimationSpeed);
10364            break;
10365          case 'slideOpen':
10366            this.$caption.slideDown(this.options.captionAnimationSpeed);
10367            break;
10368        }
10369      } else {
10370        //Animations for Caption exits
10371        switch (this.options.captionAnimation) {
10372          case 'none':
10373            this.$caption.hide();
10374            break;
10375          case 'fade':
10376            this.$caption.fadeOut(this.options.captionAnimationSpeed);
10377            break;
10378          case 'slideOpen':
10379            this.$caption.slideUp(this.options.captionAnimationSpeed);
10380            break;
10381        }
10382      }
10383    },
10384
10385    setupDirectionalNav: function () {
10386      var self = this,
10387          $directionalNav = $(this.directionalNavHTML);
10388
10389      $directionalNav.find('.right').html(this.options.directionalNavRightText);
10390      $directionalNav.find('.left').html(this.options.directionalNavLeftText);
10391
10392      this.$wrapper.append($directionalNav);
10393
10394      this.$wrapper.find('.left').click(function () {
10395        self.stopClock();
10396        if (self.options.resetTimerOnClick) {
10397          self.rotateTimer(true);
10398          self.startClock();
10399        }
10400        self.$element.trigger('orbit.prev');
10401      });
10402
10403      this.$wrapper.find('.right').click(function () {
10404        self.stopClock();
10405        if (self.options.resetTimerOnClick) {
10406          self.rotateTimer(true);
10407          self.startClock();
10408        }
10409        self.$element.trigger('orbit.next');
10410      });
10411    },
10412
10413    setupBulletNav: function () {
10414      this.$bullets = $(this.bulletHTML);
10415      this.$wrapper.append(this.$bullets);
10416      this.$slides.each(this.addBullet);
10417      this.$element.addClass('with-bullets');
10418      if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
10419      if (this.options.bulletThumbsHideOnSmall) this.$bullets.addClass('hide-for-small');
10420    },
10421
10422    addBullet: function (index, slide) {
10423      var position = index + 1,
10424          $li = $('<li>' + (position) + '</li>'),
10425          thumbName,
10426          self = this;
10427
10428      if (this.options.bulletThumbs) {
10429        thumbName = $(slide).attr('data-thumb');
10430        if (thumbName) {
10431          $li
10432            .addClass('has-thumb')
10433            .css({background: "url(" + this.options.bulletThumbLocation + thumb
10433Name + ") no-repeat"});;
10434        }
10435      }
10436      this.$bullets.append($li);
10437      $li.data('index', index);
10438      $li.click(function () {
10439        self.stopClock();
10440        if (self.options.resetTimerOnClick) {
10441          self.rotateTimer(true);
10442          self.startClock();
10443        }
10444        self.$element.trigger('orbit.goto', [$li.data('index')])
10445      });
10446    },
10447
10448    setActiveBullet: function () {
10449      if(!this.options.bullets) { return false; } else {
10450        this.$bullets.find('li')
10451          .removeClass('active')
10452          .eq(this.activeSlide)
10453          .addClass('active');
10454      }
10455    },
10456
10457    resetAndUnlock: function () {
10458      this.$slides
10459        .eq(this.prevActiveSlide)
10460        .css({"z-index" : 1});
10461      this.unlock();
10462      this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
10463    },
10464
10465    shift: function (direction) {
10466      var slideDirection = direction;
10467
10468      //remember previous activeSlide
10469      this.prevActiveSlide = this.activeSlide;
10470
10471      //exit function if bullet clicked is same as the current image
10472      if (this.prevActiveSlide == slideDirection) { return false; }
10473
10474      if (this.$slides.length == "1") { return false; }
10475      if (!this.locked) {
10476        this.lock();
10477        //deduce the proper activeImage
10478        if (direction == "next") {
10479          this.activeSlide++;
10480          if (this.activeSlide == this.numberSlides) {
10481              this.activeSlide = 0;
10482          }
10483        } else if (direction == "prev") {
10484          this.activeSlide--
10485          if (this.activeSlide < 0) {
10486            this.activeSlide = this.numberSlides - 1;
10487          }
10488        } else {
10489          this.activeSlide = direction;
10490          if (this.prevActiveSlide < this.activeSlide) {
10491            slideDirection = "next";
10492          } else if (this.prevActiveSlide > this.activeSlide) {
10493            slideDirection = "prev"
10494          }
10495        }
10496
10497        //set to correct bullet
10498        this.setActiveBullet();
10499        this.notifySlideChange();
10500
10501        //set previous slide z-index to one below what new activeSlide will be
10502        this.$slides
10503          .eq(this.prevActiveSlide)
10504          .css({"z-index" : 2});
10505
10506        //fade
10507        if (this.options.animation == "fade") {
10508          this.$slides
10509            .eq(this.activeSlide)
10510            .css({"opacity" : 0, "z-index" : 3})
10511            .animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
10512          this.$slides
10513              .eq(this.prevActiveSlide)
10514              .animate({"opacity":0}, this.options.animationSpeed);
10515        }
10516
10517        //horizontal-slide
10518        if (this.options.animation == "horizontal-slide") {
10519          if (slideDirection == "next") {
10520            this.$slides
10521              .eq(this.activeSlide)
10522              .css({"left": this.orbitWidth, "z-index" : 3})
10523              .css("opacity", 1)
10524              .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
10525          }
10526          if (slideDirection == "prev") {
10527            this.$slides
10528              .eq(this.activeSlide)
10529              .css({"left": -this.orbitWidth, "z-index" : 3})
10530              .css("opacity", 1)
10531              .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
10532          }
10533          this.$slides
10534              .eq(this.prevActiveSlide)
10535              .css("opacity", 0);
10536        }
10537
10538        //vertical-slide
10539        if (this.options.animation == "vertical-slide") {
10540          if (slideDirection == "prev") {
10541            this.$slides
10542              .eq(this.activeSlide)
10543              .css({"top": this.orbitHeight, "z-index" : 3})
10544              .css("opacity", 1)
10545              .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
10546            this.$slides
10547              .eq(this.prevActiveSlide)
10548              .css("opacity", 0);
10549          }
10550          if (slideDirection == "next") {
10551            this.$slides
10552              .eq(this.activeSlide)
10553              .css({"top": -this.orbitHeight, "z-index" : 3})
10554              .css("opacity", 1)
10555              .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
10556          }
10557          this.$slides
10558              .eq(this.prevActiveSlide)
10559              .css("opacity", 0);
10560        }
10561
10562        //horizontal-push
10563        if (this.options.animation == "horizontal-push") {
10564          if (slideDirection == "next") {
10565            this.$slides
10566              .eq(this.activeSlide)
10567              .css({"left": this.orbitWidth, "z-index" : 3})
10568              .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
10569            this.$slides
10570              .eq(this.prevActiveSlide)
10571              .animate({"left" : -this.orbitWidth}, this.options.animationSpeed, "", function(){
10572                $(this).css({"opacity" : 0});
10573              });
10574          }
10575          if (slideDirection == "prev") {
10576            this.$slides
10577              .eq(this.activeSlide)
10578              .css({"left": -this.orbitWidth, "z-index" : 3})
10579              .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
10580            this.$slides
10581              .eq(this.prevActiveSlide)
10582              .animate({"left" : this.orbitWidth}, this.options.animationSpeed, "", function(){
10583                $(this).css({"opacity" : 0});
10584              });
10585          }
10586        }
10587
10588        //vertical-push
10589        if (this.options.animation == "vertical-push") {
10590          if (slideDirection == "next") {
10591            this.$slides
10592              .eq(this.activeSlide)
10593              .css({top: -this.orbitHeight, "z-index" : 3})
10594              .css("opacity", 1)
10595              .animate({top : 0, "opacity":1}, this.options.animationSpeed, this.resetAndUnlock);
10596            this.$slides
10597              .eq(this.prevActiveSlide)
10598              .css("opacity", 0)
10599              .animate({top : this.orbitHeight}, this.options.animationSpeed, "");
10600          }
10601          if (slideDirection == "prev") {
10602            this.$slides
10603              .eq(this.activeSlide)
10604              .css({top: this.orbitHeight, "z-index" : 3})
10605              .css("opacity", 1)
10606              .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
10607            this.$slides
10608              .eq(this.prevActiveSlide)
10609              .css("opacity", 0)
10610              .animate({top : -this.orbitHeight}, this.options.animationSpeed);
10611          }
10612        }
10613
10614        this.setCaption();
10615      }
10616
10617      // if on last slide and singleCycle is true, don't loop through slides again
10618      // .length is zero based so must minus 1 to match activeSlide index
10619      if (this.activeSlide === this.$slides.length-1 && this.options.singleCycle) {
10620        this.stopClock();
10621      }
10622    }
10623  };
10624
10625  $.fn.orbit = function (options) {
10626    return this.each(function () {
10627      var orbit = $.extend({}, ORBIT);
10628      orbit.init(this, options);
10629    });
10630  };
10631
10632})(jQuery);
10633
10634/*!
10635 * jQuery imageready Plugin
10636 * http://www.zurb.com/playground/
10637 *
10638 * Copyright 2011, ZURB
10639 * Released under the MIT License
10640 */
10641(function ($) {
10642
10643  var options = {};
10644
10645  $.event.special.imageready = {
10646
10647    setup: function (data, namespaces, eventHandle) {
10648      options = data || options;
10649    },
10650
10651    add: function (handleObj) {
10652      var $this = $(this),
10653          src;
10654
10655      if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
10656        if (options.forceLoad) {
10657          src = $this.attr('src');
10658          $this.attr('src', '');
10659          bindToLoad(this, handleObj.handler);
10660          $this.attr('src', src);
10661        } else if ( this.complete || this.readyState === 4 ) {
10662          handleObj.handler.apply(this, arguments);
10663        } else {
10664          bindToLoad(this, handleObj.handler);
10665        }
10666      }
10667    },
10668
10669    teardown: function (namespaces) {
10670      $(this).unbind('.imageready');
10671    }
10672  };
10673
10674  function bindToLoad(element, callback) {
10675    var $this = $(element);
10676
10677    $this.bind('load.imageready', function () {
10678       callback.apply(element, arguments);
10679       $this.unbind('load.imageready');
10680     });
10681  }
10682
10683}(jQuery));
10684
10685/*
10686
10687Holder - 1.3 - client side image placeholders
10688(c) 2012 Ivan Malopinsky / http://imsky.co
10689
10690Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
10691Commercial use requires attribution.
10692
10693*/
10694
10695var Holder = Holder || {};
10696(function (app, win) {
10697
10698var preempted = false,
10699fallback = false,
10700canvas = document.createElement('canvas');
10701
10702//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
10703function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}};
10704
10705//https://gist.github.com/991057 by Jed Schmidt with modifications
10706function selector(a){
10707	a=a.match(/^(\W)?(.*)/);var b=document["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2]);
10708	var ret=[];	b!=null&&(b.length?ret=b:b.length==0?ret=b:ret=[b]);	return ret;
10709}
10710
10711//shallow object property extend
10712function extend(a,b){var c={};for(var d in a)c[d]=a[d];for(var e in b)c[e]=b[e];return c}
10713
10714function draw(ctx, dimensions, template) {
10715	var dimension_arr = [dimensions.height, dimensions.width].sort();
10716	var maxFactor = Math.round(dimension_arr[1] / 16),
10717		minFactor = Math.round(dimension_arr[0] / 16);
10718	var text_height = Math.max(template.size, maxFactor);
10719	canvas.width = dimensions.width;
10720	canvas.height = dimensions.height;
10721	ctx.textAlign = "center";
10722	ctx.textBaseline = "middle";
10723	ctx.fillStyle = template.background;
10724	ctx.fillRect(0, 0, dimensions.width, dimensions.height);
10725	ctx.fillStyle = template.foreground;
10726	ctx.font = "bold " + text_height + "px sans-serif";
10727	var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height);
10728	if (Math.round(ctx.measureText(text).width) / dimensions.width > 1) {
10729		text_height = Math.max(minFactor, template.size);
10730	}
10731	ctx.font = "bold " + text_height + "px sans-serif";
10732	ctx.fillText(text, (dimensions.width / 2), (dimensions.height / 2), dimensions.width);
10733	return canvas.toDataURL("image/png");
10734}
10735
10736if (!canvas.getContext) {
10737	fallback = true;
10738} else {
10739	if (canvas.toDataURL("image/png").indexOf("data:image/png") < 0) {
10740		//Android doesn't support data URI
10741		fallback = true;
10742	} else {
10743		var ctx = canvas.getContext("2d");
10744	}
10745}
10746
10747var settings = {
10748	domain: "holder.js",
10749	images: "img",
10750	themes: {
10751		"gray": {
10752			background: "#eee",
10753			foreground: "#aaa",
10754			size: 12
10755		},
10756		"social": {
10757			background: "#3a5a97",
10758			foreground: "#fff",
10759			size: 12
10760		},
10761		"industrial": {
10762			background: "#434A52",
10763			foreground: "#C2F200",
10764			size: 12
10765		}
10766	}
10767};
10768
10769
10770
10771app.flags = {
10772	dimensions: {
10773		regex: /([0-9]+)x([0-9]+)/,
10774		output: function(val){
10775			var exec = this.regex.exec(val);
10776			return {
10777				width: +exec[1],
10778				height: +exec[2]
10779			}
10780		}
10781	},
10782	colors: {
10783		regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
10784		output: function(val){
10785			var exec = this.regex.exec(val);
10786			return {
10787					size: settings.themes.gray.size,
10788					foreground: "#" + exec[2],
10789					background: "#" + exec[1]
10790					}
10791		}
10792	},
10793	text: {
10794		regex: /text\:(.*)/,
10795		output: function(val){
10796			return this.regex.exec(val)[1];
10797		}
10798	}
10799}
10800
10801for(var flag in app.flags){
10802	app.flags[flag].match = function (val){
10803		return val.match(this.regex)
10804	}
10805}
10806
10807app.add_theme = function (name, theme) {
10808	name != null && theme != null && (settings.themes[name] = theme);
10809	return app;
10810};
10811
10812app.add_image = function (src, el) {
10813	var node = selector(el);
10814	if (node.length) {
10815		for (var i = 0, l = node.length; i < l; i++) {
10816			var img = document.createElement("img")
10817			img.setAttribute("data-src", src);
10818			node[i].appendChild(img);
10819		}
10820	}
10821	return app;
10822};
10823
10824app.run = function (o) {
10825	var options = extend(settings, o),
10826		images = selector(options.images),
10827		preempted = true;
10828
10829	for (var l = images.length, i = 0; i < l; i++) {
10830		var theme = settings.themes.gray;
10831		var src = images[i].getAttribute("data-src") || images[i].getAttribute("src");
10832		if (src && !! ~src.indexOf(options.domain)) {
10833			var render = false,
10834				dimensions = null,
10835				text = null;
10836			var flags = src.substr(src.indexOf(options.domain) + options.domain.length + 1).split("/");
10837			for (sl = flags.length, j = 0; j < sl; j++) {
10838				if (app.flags.dimensions.match(flags[j])) {
10839					render = true;
10840					dimensions = app.flags.dimensions.output(flags[j]);
10841				} else if (app.flags.colors.match(flags[j])) {
10842					theme = app.flags.colors.output(flags[j]);
10843				} else if (options.themes[flags[j]]) {
10844					//If a theme is specified, it will override custom colors
10845					theme = options.themes[flags[j]];
10846				} else if (app.flags.text.match(flags[j])) {
10847					text = app.flags.text.output(flags[j]);
10848				}
10849			}
10850			if (render) {
10851				images[i].setAttribute("data-src", src);
10852				var dimensions_caption = dimensions.width + "x" + dimensions.height;
10853				images[i].setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
10854
10855				// Fallback
10856        // images[i].style.width = dimensions.width + "px";
10857        // images[i].style.height = dimensions.height + "px";
10858				images[i].style.backgroundColor = theme.background;
10859
10860				var theme = (text ? extend(theme, {
10861						text: text
10862					}) : theme);
10863
10864				if (!fallback) {
10865					images[i].setAttribute("src", draw(ctx, dimensions, theme));
10866				}
10867			}
10868		}
10869	}
10870	return app;
10871};
10872contentLoaded(win, function () {
10873	preempted || app.run()
10874})
10875
10876})(Holder, window);
10877;(function ($, window, undefined) {
10878  'use strict';
10879  
10880  $.fn.foundationMediaQueryViewer = function (options) {
10881    var settings = $.extend(options,{toggleKey:77}), // Press 'M'
10882        $doc = $(document);
10883
10884    $doc.on("keyup.mediaQueryViewer", ":input", function (e){
10885      if (e.which === settings.toggleKey) {
10886        e.stopPropagation();
10887      }
10888    });
10889    $doc.on("keyup.mediaQueryViewer", function (e) {
10890      var $mqViewer = $('#fqv');
10891
10892      if (e.which === settings.toggleKey) { 
10893        if ($mqViewer.length > 0) {
10894          $mqViewer.remove();
10895        } else {
10896          $('body').prepend('<div id="fqv" style="position:fixed;top:4px;left:4px;z-index:999;color:#fff;"><p style="font-size:12px;background:rgba(0,0,0,0.75);padding:5px;margin-bottom:1px;line-height:1.2;"><span class="left">Media:</span> <span style="font-weight:bold;" class="show-for-xlarge">Extra Large</span><span style="font-weight:bold;" class="show-for-large">Large</span><span style="font-weight:bold;" class="show-for-medium">Medium</span><span style="font-weight:bold;" class="show-for-small">Small</span><span style="font-weight:bold;" class="show-for-landscape">Landscape</span><span style="font-weight:bold;" class="show-for-portrait">Portrait</span><span style="font-weight:bold;" class="show-for-touch">Touch</span></p></div>');
10897        }
10898      }
10899    });
10900
10901  };
10902
10903})(jQuery, this);
10904/*
10905**********************************************************
10906* prettyEmbed.js | https://github.com/mike-zarandona/prettyembed.js
10907* 
10908* Version:		v1.2.1
10909* Author:		Mike Zarandona
10910* Release:		July 31 2014
10911* 
10912* Reqs:			jQuery  |  http://jquery.com
10913* 				waitForImages  |  https://github.com/alexanderdickson/waitForImages
10914* 
10915* Optional:		FitVids.js  |  http://fitvidsjs.com
10916* 
10917* Usage:		$('#video-placeholder-element').prettyEmbed({
10918* 					videoID: 'aBcDeFg12345',
10919* 					previewSize: '',
10920* 					customPreviewImage: '',
10921* 
10922* 					showInfo: true,
10923* 					showControls: true,
10924* 					loop: false,
10925*					closedCaptions: false,
10926* 					colorScheme: 'dark',
10927* 					showRelated: false,
10928* 
10929* 					useFitVids: true
10930* 				});
10931**********************************************************
10932*/
10933
10934
10935(function ($, undefined) {
10936	$.fn.prettyEmbed = function (options) {
10937
10938		// Override defaults with specified options
10939		options = $.extend({}, $.fn.prettyEmbed.options, options);
10940
10941		// Test for mobile devices
10942		var mobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent))? true : false;
10943
10944		// Inject styles if not already present
10945		if ( $('#pretty-embed-style').length === 0 ) {
10946			var styles = $('<style />', {
10947				id:		'pretty-embed-style',
10948				html:	'.pretty-embed{position:relative;cursor:pointer;display:block}.pretty-embed img{width:100%;height:auto}.pretty-embed iframe{border:0 solid transparent}.pretty-embed:after{display:block;content:"";position:absolute;top:50%;margin-top:-19px;left:50%;margin-left:-27px;width:54px;height:38px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABMCAYAAACIylL7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAABmxJREFUeF7t3W9MVlUcB3BNs3Kt1h/XC9eL6kWCAg6E8h/YMLKFm4v+GNZCfYHQnDoNVzjLYbZG8SLCVqSrHGgWtnDWbK1CK/sHi5oF8n+9IMcqiIqA6PT9Xs6Nx+tPAkSec+9zfu7zgnvuOffhfr3Avc997pk0XjUrahZNgytgJsyCRFgC6XAfZEEObIZ8KIBCeB5eglehHN6Cd+Bd+AA+huPwBXwF30At/KDVQ9P/OAXu+t8Cx/gaOOYnUAXc1ntQCRWwH16Dl6EYnoWdsA22QC6shvthOdwGSRAN18OVcAlM1rtpYgsbZiCLYRO8CIeBO7AZfoG/4B9QloP7gvvkV2iBGuB/Qv4HyINUmK537/gVBo2BV6ATpBdmjd0fwJ8qt4Le42MsDHA17IW/QdqYNX54NB6CmXr3j67QMQHaQBrcunA6IFXHMLJChxT4TQ9gTbxeyNBxDF9Y8Wawv6vCj3+sLNCxyIUVLoLPdAcr/BrgUh3P2YVGnitJHa3w2aTjObPQMBl4Iil1ssLnR7hYxzRUWMirElIHK/xW6JiGCguLPCtZ5jigYxosLKDGkBUss3TBNB2XE9hNIY2WmZJ1XE5gD3saLfPk67icwEo8jZZ53tZxOYF95Gm0zHNKx+UExjf4pJUsc/wOUxnWVP2FtJJllhkM7BrPQstcsQyM9x9IjZZ5bmdgvElGajTK7DmzVXxCvNgWQR5kYPd6FhppXuI8dfr0abVjxw4VFxcnrhMBNjIw3nYmNRqFgQ0MDChWU1OT2rxls5oTM0dcN8B2MjDeHyg1GiU0MFZfX5+qrq5WuY/kqujZ0WKfANrNwHhzpNRoFG9gbnV1damqqiq1Zu0aFRUdJfYNkP0MjDc1So1GOVdgLB5t7e3t6uj7R1Xmqkyxf0AcYWAHPAuNNFxgbvFoa2trU5WHK1XGPRniOD53nIHxdmup0SgjCYzlHm0tLS3q4JsHVfrydHE8n6phYB96FhpppIG55R5tDG7fvn0qLS1NHNdn6hmYL25rG21gLPdoa21tdU4FSktLVcqSFHF8n2hjYL64U2osgbnlHm0MrqGhQRUXF6uFixaK2zFcOwPj56SkRqOcT2Cs0KON6urqVGFhoUq6JUncnqE6IiYwtzo7O/872ujkyZOqYGeBX65TRl5gLO/RRrW1tSp/W76Km2v0dcrIDMyt0N9tLl7u4nXKmNgY8XWEWWQHxpKONjpx4oTKyc0RX0sY2cDcCj3ampubB8/d7jDu3M0GFlq9vb2qoqLC5KsjNjC3+CNw5QMrxW0bxAZWU1OjslZnids0UOQGxvOv7HXZKirKV++hRV5gjY2NasPGDX59lzpyAuNfgHlb85y7r6TxfcIJLNAXf3mOtf2J7aaeCI+Wc/E3kG+vdHR0qF1P7zL9UtNotTKwQL2ByYu7RUVFQb3p1HkDMxC3CHR3d6uS3SUqMSlR7B8Qzi0CfCag1GiUcwXW09Oj9uzdo+YvmC/2C5hjDMyXt7nxMlJZWZlKTkkW1w8o5zY3PhFUajSKG1h/f79zvS91aaq4XsCVM7DHPQuNlDAvwbnfcNmdy8T2CFHCwHzxYQjLUcDAfPFxI8vhfNzIFx/osxyrGBj/SY2WeZyPzPJBzPbR5f4Qw8CmgH3sgz9c6z5YxT7JzXyDD1bRgfniAnCEq3fCYuELzisirWSZ45COywnsIU+jZZ7HdFxOYDd4Gi3zLNJxOYERp2uSVrTCjxM/nPlkbSzwxVX7CFWuYxoqLIz3rGSZI13HNFRYSJytTupghU8rDJ5/eQsNd4esaJlhvY7n7EIjp/PgXJBSR2vicb7OoefVS4UV+Az7n3UHK3z+hEQdy/CFFTkfIychlQayLrweuEvHMbJCBz5a9ns9gDVx2mGxjmF0hY6XwZPAuT+kwa3xMwCcbfa6wb1/HoVBroL1cAz6QNqgNTa8isGZfOeC3uPjWBj0cuDk29nwDLwBnHybE5N1g51CeAj3Bd/H+gn4F9+nwBnYOTM8D4CFMPxfgReysHHOoTkdZsCNEAvzYSlw6nd3evt1sAG2wnZ4Ctwp7jkD+x54HfgsR36DnGr+CHDqeU47wiP9c/gS+Pm20GnuvVPau9z274B9qoEXCrgTOZ47rT0/a8D5lLltTmtfCi/Ac8DXydf7KHCHr4VMWAFpsAD4PfN75z7gvpiid8841KRJ/wIcsey9MCgPGwAAAABJRU5ErkJggg==);-webkit-background-size:cover;background-size:cover}.pretty-embed.play:after{display:none}.pretty-embed:hover:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABMCAYAAACIylL7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAABwhJREFUeF7t3GlsVFUYBuCDIi4xGreA1O6dmXbaYQ2oCAriGjUuRDSiETVRISGCu2BcAH8gagKKpnWJ5UcBFVQIGhMDFGwVGcqU0m2WtkPpIqNSbEHaQj/fM5yh9HLAAlP6TTlv8iSdc+899/a8PenMnxHRSp3LIQ2ASyAO0mEUjIe7YTJMhWnwAsyBebAQFkM2fAl58A18Dz/Az7ABNsFm2AIeKIZypRIC/8MLkfO3g5zDDXLOXyAf5L1+hNWwEpZBLuTAh/AezIfX4UWYDk/AQ3APTIDR4IR4uBTOh35qmc5sdmU5BsC4XS7HLPgE1sAWqIK/4QB0ABlhci3kmuyBaiiCHyAHXsZaToSL1PJGL5jUBZ9BE5ARVfsgD64DteKnmNos++W1WY4v4CCQ0aM6YBXEqeU/uaCskRAETGacQSGYqGroXnZm2m+Cf4CMXtEKk1QdJw5OdECTutDoPQdgjKpFn2Cm/RwoBDJY8MEFqp5jE3TaJ1suMHrfLFVP19Q47f3ADWSwUgvnqZo6g8FRR51k8HKfqqkz1U77B0AGS8tVTYdTnWGT/EAGS3thgKpLiKoMWyqQwdqNqq5wYY9bDhr8zFF1CRHIsC0BMlj7VtWFwtJt64EM1ryqLiH86bYAkMFaC/SXZfVXL3QnGbxcJXyOtCuAjJgwRBbmtAwafN0qvI608UDc+ZwO8g8fqj12FnlUFvagZZAl/8hh1PZHI9W99Sb5XJnac84CM0WlPW0aEHe+EcOIDh0imWa/n2qen0VeZ7r23D5svixsjmWQpaMLk2lva6PQVjdVTXuWKtPt2mv6oI9FhT3tPSDuvJbCItm3dy/V5+dT4ImpVOGwaa/tQ5aJCltaDhB33uH6wmTkbvuroYHqfvqJ/A8/pL2+j1grym2py4G4q8Q7xOMVFkkLdtsfwSDtWv09+e6/VztPjNskC1tjGWSpO4XJRHZbY3U11X61grx33qGdL0YVibK01HVA3FV0s7BIIrtNFrdzaS5VTpygnTfGVMrCCi2DLFUMO7nCZI7stpoaagwEKJidTRVjb9DOHyOCojQt1Q3E3akUFsmR3SaL8/moZtEiKr92tPY+zDXIwjyWQZbKT6MwmS67DRoqKqh6wQIqGzFcez+mQmJHaqoHiLuyoadXWCQtTU2du00WV1pKVW+/TaUul/a+zMjCUlBYCl7wVjZ0SFQKk7HuNqne46HAq69SqTNDe38mQqIEhQFxF83CIunyvy1SnNtN/pkzaUe6Q/scvQyFpaCwFLxgrrQHCpPR7TaprrCQvE8/rX2WXhQS21EYEHelQ3qmsEi67LaqKgrm5lLZhAnaZ+lFsVPYjh4uTKa9tZV2ff01ld1+u/YZGAiJYhQGxF1PF9ZcUEC+SZO092YEhSWjsGS8YG6Hq2cK2+feSoEpU7T3ZCgkPCgMiLuSKBe2v6SEqp58ijz4y9XdjylZWDIKS8YL3krwwTYahf3r9VLN9OnkwQd
10948R3X2YC4ltSckeIO62Z51eYQfw7i8463kUlaadP0aEC3NbBlk61cLa6utp5+zZ5LHZtfPGmAZRlJRcCMRd8UkW1rZ7N9XOnUvbHOna+WJUjSxsnWWQpe4W1r5nD9UteJc8zkztPDGuUmxNTF4DxJ0n88SFHWxupvpFi8njGqq9vo8okoUtswyydLzCDu3fT43ZOVQ8fKT2uj5mo3AnJuUAcbfNUlhHayvtzl1KxaOv1Z7fR60V7oSkhUDcbcvMChfW0d5OoRVf0fYxY7Xn9XF5YktC0mwg7orwJuLPb7+jkvE3a4+fJZbIwqZZBg2+5onf45MeBDJiwkxZ2HjLoMHXFLE5PikDyIgJt8rCLoeOowYNvlzit2sSz4UWIIO9K8NfrIIf/JYDBj9yU/UPF/brNYnrgAzWKsNlyfwal/ghkMHaKlWXEIVxiY8BGay9puoKF5ZsOWjwM1bVFS5MFMQleoEMlpqg6zdrFwxOXAhksJSnaurML4MTRgAZLN2tauoMBqXNR51k8FADhz9/WbNpcMIDm65OIIORwQkzVD3HBif0g/wuFxi9qRw6v69el41XJ6TCX0BGr9oPo1QtJw5OvA7+VhcaZ96/cJeqo3vJH5TghDIg44xqgHGqhpMLLrwwf1D8W7AXMJnRgw5BHtZ8oFr+U8+GQfGXwQzYCG1ARtQ0wRcwDNSKRzGY9GIYB89sGBi/AFbAFqiFZjgIZITJtWiBRiiHAlgJi0FugBvgxO8CezLrB8afAxfBVZACQ+B6uAXugckwFZ6F5+AVeAPegYWwGD6Bz2EpLIeVsBrWws+wHjbCb/A7eKAYypXAcUSOl4C8ZitshgKQ88m5f4Q1sArkvXPhU/gI3gf5nPJ5X4IZ8BQ8AvfBbTAG5O8sf3e5BnItzlXLE4UI8R86m8y4ltOs9gAAAABJRU5ErkJggg==)}'
10949			}).appendTo('head');
10950		}
10951
10952		// Error Checking
10953		if (options.useFitVids) {
10954			if (!$.isFunction($.fn.fitVids)) {
10955				console.error('PrettyEmbed.js Error:  options.useFitVids is set to true; FitVids not found!');
10956			}
10957		}
10958
10959		// Store $('this') in a variable to minimize DOM searches
10960		var elem;
10961
10962		// if no selector, only fire on .pretty-embed
10963		if ( $(this).length === 0 ) { elem = $('.pretty-embed'); }
10964		else { elem = $(this); }
10965
10966		// Main setup loop
10967		elem.each(function() {
10968
10969			// Tag the selected elements
10970			$(this).addClass('pretty-embed');
10971
10972			var $newDOMElement,
10973				thisVideoID = '',
10974				thisPreviewSize = '',
10975				thisCustomPreviewImage = '',
10976				thisShowInfo,
10977				thisShowControls,
10978				thisLoop,
10979				thisClosedCaptions,
10980				thisLocalization,
10981				thisColorScheme,
10982				thisShowRelated,
10983				thisAllowFullScreen,
10984				fullScreenFlag;
10985
10986			// videoID
10987			if ( $(this).attr('data-pe-videoid') !== undefined ) { thisVideoID = $(this).attr('data-pe-videoid'); }
10988			else if ( $(this).attr('href') !== undefined ) { thisVideoID = youtube_parser( $(this).attr('href') ); }
10989			else { thisVideoID = options.videoID; }
10990
10991			// previewsize
10992			if ( $(this).attr('data-pe-preview-size') !== undefined ) { thisPreviewSize = $(this).attr('data-pe-preview-size'); }
10993			else if ( options.previewSize !== undefined ) { thisPreviewSize = options.previewSize; }
10994			else { thisPreviewSize = undefined; }
10995
10996			// custom placeholder
10997			if ( $(this).attr('data-pe-custom-preview-image') !== undefined ) { thisCustomPreviewImage = $(this).attr('data-pe-custom-preview-image'); }
10998			else if ( options.customPreviewImage !== undefined ) { thisCustomPreviewImage = options.customPreviewImage; }
10999			else { thisCustomPreviewImage = undefined; }
11000
11001			// showinfo
11002			if ( $(this).attr('data-pe-show-info') !== undefined ) { thisShowInfo = $(this).attr('data-pe-show-info'); }
11003			else if ( options.showInfo !== undefined ) { thisShowInfo = options.showInfo; }
11004			else { thisShowInfo = undefined; }
11005
11006			// show controls
11007			if ( $(this).attr('data-pe-show-controls') !== undefined ) { thisShowControls = $(this).attr('data-pe-show-controls'); }
11008			else if ( options.showControls !== undefined ) { thisShowControls = options.showControls; }
11009			else { thisShowControls = undefined; }
11010
11011			// loop
11012			if ( $(this).attr('data-pe-loop') !== undefined ) { thisLoop = $(this).attr('data-pe-loop'); }
11013			else if ( options.loop !== undefined ) { thisLoop = options.loop; }
11014			else { thisLoop = undefined; }
11015
11016			// closed captions
11017			if ( $(this).attr('data-pe-closed-captions') !== undefined ) { thisClosedCaptions = $(this).attr('data-pe-closed-captions'); }
11018			else if ( options.closedCaptions !== undefined ) { thisClosedCaptions = options.closedCaptions; }
11019			else { thisClosedCaptions = undefined; }
11020
11021			// localization
11022			if ( $(this).attr('data-pe-localization') !== undefined ) { thisLocalization = $(this).attr('data-pe-localization'); }
11023			else if ( options.localization !== undefined ) { thisLocalization = options.localization; }
11024			else { thisLocalization = undefined; }
11025
11026			// color scheme
11027			if ( $(this).attr('data-pe-color-scheme') !== undefined ) { thisColorScheme = $(this).attr('data-pe-color-scheme'); }
11028			else if ( options.colorScheme !== undefined ) { thisColorScheme = options.colorScheme; }
11029			else { thisColorScheme = undefined; }
11030
11031			// show related
11032			if ( $(this).attr('data-pe-show-related') !== undefined ) { thisShowRelated = $(this).attr('data-pe-show-related'); }
11033			else if ( options.showRelated !== undefined ) { thisShowRelated = options.showRelated; }
11034			else { thisShowRelated = undefined; }
11035
11036			// allow full screen
11037			if ( $(this).attr('data-pe-allow-fullscreen') !== undefined ) { thisAllowFullScreen = $(this).attr('data-pe-allow-fullscreen'); }
11038			else if ( options.allowFullScreen !== undefined ) { thisAllowFullScreen = options.allowFullScreen; }
11039			else { thisAllowFullScreen = undefined; }
11040
11041
11042			// If this element is an <a/>, create a placeholder replacement
11043			if ( $(this).is('a') ) {
11044
11045				// build the DOM structure
11046				$newDOMElement = $('<div />').addClass('pretty-embed');
11047
11048				// rebuild the data-pe- attributes
11049				$newDOMElement.attr('data-pe-videoid', thisVideoID)
11050							  .attr('data-pe-preview-size', thisPreviewSize)
11051							  .attr('data-pe-custom-preview-image', thisCustomPreviewImage)
11052							  .attr('data-pe-show-info', thisShowInfo)
11053							  .attr('data-pe-show-controls', thisShowControls)
11054							  .attr('data-pe-loop', thisLoop)
11055							  .attr('data-pe-closed-captions', thisClosedCaptions)
11056							  .attr('data-pe-localization', thisLocalization)
11057							  .attr('data-pe-color-scheme', thisColorScheme)
11058							  .attr('data-pe-show-related', thisShowRelated)
11059							  .attr('data-pe-allow-fullscreen', thisAllowFullScreen);
11060
11061				// append the new element, and remove the <a/>
11062				$(this).after($newDOMElement);
11063			}
11064
11065			// Write the options.customPreviewImage OR choose a size
11066			if ( thisCustomPreviewImage !== undefined && thisCustomPreviewImage !== '' ) {
11067				$(this).html('<img src="' + thisCustomPreviewImage + '" width="100%" alt="YouTube Video Preview" />');
11068			}
11069			else {
11070				var previewSizePrefix = '';
11071
11072				switch (thisPreviewSize) {
11073					case 'thumb-default':
11074						previewSizePrefix = 'default';
11075						break;
11076					case 'thumb-1':
11077						previewSizePrefix = '1';
11078						break;
11079					case 'thumb-2':
11080						previewSizePrefix = '2';
11081						break;
11082					case 'thumb-3':
11083						previewSizePrefix = '3';
11084						break;
11085					case 'default':
11086						previewSizePrefix = 'mqdefault';
11087						break;
11088					case 'medium':
11089						previewSizePrefix = '0';
11090						break;
11091					case 'high':
11092						previewSizePrefix = 'hqdefault';
11093						break;
11094					default:	// 'hd' or max-resolution quality
11095						previewSizePrefix = 'maxresdefault';
11096						break;
11097				}
11098
11099				// Write the <img/> element
11100				$(this).html('<img src="//img.youtube.com/vi/' + thisVideoID + '/' + previewSizePrefix + '.jpg" width="100%" alt="YouTube Video Preview" />');
11101			}
11102
11103			if ( $(this).is('a') ) {
11104				$newDOMElement.html( $(this).html() );
11105				$(this).remove();
11106			}
11107
11108			// if mobile, go straight to iframe
11109			if (mobile) {
11110				$(window).on('load', function() {
11111					$('.pretty-embed').trigger('click');
11112				});
11113			}
11114		});
11115
11116
11117
11118		// Click handler: load the video
11119		$('body').on('click', '.pretty-embed', function(e) {
11120			e.preventDefault();
11121
11122			clickEventRunner( $(this) );
11123		});
11124
11125
11126
11127		/**
11128		 * Function: clickEventRunner(obj)
11129		 * Contains the functionality for .on('click') events
11130		 * obj = the current object referenced passed from $(this)
11131		 */
11132		function clickEventRunner(obj) {
11133			var wrapperWidth = obj.find('img').outerWidth(true),
11134				wrapperHeight = obj.find('img').outerHeight(true),
11135				playerOptions = '',
11136				thisVideoID = '';
11137
11138			// videoid - set from data-pe- attribute or options
11139			if ( obj.attr('data-pe-videoid') !== undefined ) { thisVideoID = obj.attr('data-pe-videoid'); }
11140			else if ( options.videoID !== undefined ) { thisVideoID = options.videoID; }
11141			else {
11142				thisVideoID = undefined;
11143				console.error('PrettyEmbed.js Error:  Misformed or missing video ID.');
11144			}
11145
11146
11147			// Assemble the player options string
11148			// showInfo
11149			if ( (obj.attr('data-pe-show-info') === 'false') || (options.showInfo === false) ) { playerOptions += '&showinfo=0'; }
11150
11151			// showControls
11152			if ( (obj.attr('data-pe-show-controls') === 'false') || (options.showControls === false) ) { playerOptions += '&controls=0'; }
11153
11154			// loop
11155			if ( (obj.attr('data-pe-loop') === 'true') || (options.loop === true) ) { playerOptions += '&loop=1'; }
11156
11157			// closed captions
11158			if ( (obj.attr('data-pe-closed-captions') === 'true') || (options.closedCaptions === true) ) { playerOptions += '&cc_load_policy=1'; }
11159
11160			// localization
11161			if ( (obj.attr('data-pe-localization') !== undefined) || (options.localization !== undefined) ) {
11162				if ( obj.attr('data-pe-localization') !== undefined ) {
11163					playerOptions += '&hl=' + obj.attr('data-pe-localization');
11164				}
11165				else if ( options.localization !== undefined ) {
11166					playerOptions += '&hl=' + options.localization;
11167				}
11168			}
11169
11170			// colorScheme
11171			if ( (obj.attr('data-pe-color-scheme') == 'light') || (options.colorScheme == 'light') ) { playerOptions += '&theme=light'; }
11172
11173			// showRelated
11174			if ( (obj.attr('data-pe-show-related') === 'false') || (options.showRelated === false) ) { playerOptions += '&rel=0'; } else { playerOptions += '&rel=1'; }
11175
11176			// allow full screen
11177			if ( (obj.attr('data-pe-allow-fullscreen') === 'false') || (options.allowFullScreen === false) ) { fullScreenFlag = ''; } else { fullScreenFlag = 'allowfullscreen '; }
11178
11179			// Write the YouTube video iFrame into the element at the exact dimensions it is now
11180			obj.html('<iframe width="' + wrapperWidth + '" height="' + wrapperHeight + '" ' + fullScreenFlag + 'style="border:none;" src="//www.youtube.com/embed/' + thisVideoID + '?autoplay=1' + playerOptions + '"></iframe>')
11181				// Remove the YouTube 'play' button using a CSS class
11182				.addClass('play');
11183
11184			// If we're using FitVids, call it now
11185			if (options.useFitVids) {
11186				if ( $.isFunction($.fn.fitVids) ) {
11187					obj.parent().fitVids();
11188				}
11189			}
11190		}
11191
11192
11193
11194		// Helper function: get video ID from youtube URLs
11195		function youtube_parser(url) {
11196			var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
11197			var match = url.match(regExp);
11198			if (match && match[7].length == 11) {
11199				return match[7];
11200			} else {
11201				console.error('PrettyEmbed.js Error:  Bad URL.');
11202			}
11203		}
11204
11205
11206
11207		// Default the defaults
11208		$.fn.prettyEmbed.options = {
11209			videoID: '',
11210			previewSize: '',
11211			customPreviewImage: '',
11212
11213			// Embed controls
11214			showInfo: true,
11215			showControls: true,
11216			loop: false,
11217			closedCaptions: false,
11218
11219			colorScheme: 'dark',
11220			showRelated: false,
11221
11222			// FitVids.js
11223			useFitVids: false
11224		};
11225	};
11226})(jQuery);
11227/*!
11228* jQuery Cycle2; version: 2.1.6 build: 20141007
11229* http://jquery.malsup.com/cycle2/
11230* Copyright (c) 2014 M. Alsup; Dual licensed: MIT/GPL
11231*/
11232
11233/* Cycle2 core engine */
11234
11235;(function($) {
11236"use strict";
11237
11238var version = '2.1.6';
11239
11240$.fn.cycle = function( options ) {
11241    // fix mistakes with the ready state
11242    var o;
11243    if ( this.length === 0 && !$.isReady ) {
11244        o = { s: this.selector, c: this.context };
11245        $.fn.cycle.log('requeuing slideshow (dom not ready)');
11246        $(function() {
11247            $( o.s, o.c ).cycle(options);
11248        });
11249        return this;
11250    }
11251
11252    return this.each(function() {
11253        var data, opts, shortName, val;
11254        var container = $(this);
11255        var log = $.fn.cycle.log;
11256
11257        if ( container.data('cycle.opts') )
11258            return; // already initialized
11259
11260        if ( container.data('cycle-log') === false || 
11261            ( options && options.log === false ) ||
11262            ( opts && opts.log === false) ) {
11263            log = $.noop;
11264        }
11265
11266        log('--c2 init--');
11267        data = container.data();
11268        for (var p in data) {
11269            // allow props to be accessed sans 'cycle' prefix and log the overrides
11270            if (data.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) {
11271                val = data[p];
11272                shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase);
11273                log(shortName+':', val, '('+typeof val +')');
11274                data[shortName] = val;
11275            }
11276        }
11277
11278        opts = $.extend( {}, $.fn.cycle.defaults, data, options || {});
11279
11280        opts.timeoutId = 0;
11281        opts.paused = opts.paused || false; // #57
11282        opts.container = container;
11283        opts._maxZ = opts.maxZ;
11284
11285        opts.API = $.extend ( { _container: container }, $.fn.cycle.API );
11286        opts.API.log = log;
11287        opts.API.trigger = function( eventName, args ) {
11288            opts.container.trigger( eventName, args );
11289            return opts.API;
11290        };
11291
11292        container.data( 'cycle.opts', opts );
11293        container.data( 'cycle.API', opts.API );
11294
11295        // opportunity for plugins to modify opts and API
11296        opts.API.trigger('cycle-bootstrap', [ opts, opts.API ]);
11297
11298        opts.API.addInitialSlides();
11299        opts.API.preInitSlideshow();
11300
11301        if ( opts.slides.length )
11302            opts.API.initSlideshow();
11303    });
11304};
11305
11306$.fn.cycle.API = {
11307    opts: function() {
11308        return this._container.data( 'cycle.opts' );
11309    },
11310    addInitialSlides: function() {
11311        var opts = this.opts();
11312        var slides = opts.slides;
11313        opts.slideCount = 0;
11314        opts.slides = $(); // empty set
11315        
11316        // add slides that already exist
11317        slides = slides.jquery ? slides : opts.container.find( slides );
11318
11319        if ( opts.random ) {
11320            slides.sort(function() {return Math.random() - 0.5;});
11321        }
11322
11323        opts.API.add( slides );
11324    },
11325
11326    preInitSlideshow: function() {
11327        var opts = this.opts();
11328        opts.API.trigger('cycle-pre-initialize', [ opts ]);
11329        var tx = $.fn.cycle.transitions[opts.fx];
11330        if (tx && $.isFunction(tx.preInit))
11331            tx.preInit( opts );
11332        opts._preInitialized = true;
11333    },
11334
11335    postInitSlideshow: function() {
11336        var opts = this.opts();
11337        opts.API.trigger('cycle-post-initialize', [ opts ]);
11338        var tx = $.fn.cycle.transitions[opts.fx];
11339        if (tx && $.isFunction(tx.postInit))
11340            tx.postInit( opts );
11341    },
11342
11343    initSlideshow: function() {
11344        var opts = this.opts();
11345        var pauseObj = opts.container;
11346        var slideOpts;
11347        opts.API.calcFirstSlide();
11348
11349        if ( opts.container.css('position') == 'static' )
11350            opts.container.css('position', 'relative');
11351
11352        $(opts.slides[opts.currSlide]).css({
11353            opacity: 1,
11354            display: 'block',
11355            visibility: 'visible'
11356        });
11357        opts.API.stackSlides( opts.slides[opts.currSlide], opts.slides[opts.nextSlide], !opts.reverse );
11358
11359        if ( opts.pauseOnHover ) {
11360            // allow pauseOnHover to specify an element
11361            if ( opts.pauseOnHover !== true )
11362                pauseObj = $( opts.pauseOnHover );
11363
11364            pauseObj.hover(
11365                function(){ opts.API.pause( true ); }, 
11366                function(){ opts.API.resume( true ); }
11367            );
11368        }
11369
11370        // stage initial transition
11371        if ( opts.timeout ) {
11372            slideOpts = opts.API.getSlideOpts( opts.currSlide );
11373            opts.API.queueTransition( slideOpts, slideOpts.timeout + opts.delay );
11374        }
11375
11376        opts._initialized = true;
11377        opts.API.updateView( true );
11378        opts.API.trigger('cycle-initialized', [ opts ]);
11379        opts.API.postInitSlideshow();
11380    },
11381
11382    pause: function( hover ) {
11383        var opts = this.opts(),
11384            slideOpts = opts.API.getSlideOpts(),
11385            alreadyPaused = opts.hoverPaused || opts.paused;
11386
11387        if ( hover )
11388            opts.hoverPaused = true; 
11389        else
11390            opts.paused = true;
11391
11392        if ( ! alreadyPaused ) {
11393            opts.container.addClass('cycle-paused');
11394            opts.API.trigger('cycle-paused', [ opts ]).log('cycle-paused');
11395
11396            if ( slideOpts.timeout ) {
11397                clearTimeout( opts.timeoutId );
11398                opts.timeoutId = 0;
11399                
11400                // determine how much time is left for the current slide
11401                opts._remainingTimeout -= ( $.now() - opts._lastQueue );
11402                if ( opts._remainingTimeout < 0 || isNaN(opts._remainingTimeout) )
11403                    opts._remainingTimeout = undefined;
11404            }
11405        }
11406    },
11407
11408    resume: function( hover ) {
11409        var opts = this.opts(),
11410            alreadyResumed = !opts.hoverPaused && !opts.paused,
11411            remaining;
11412
11413        if ( hover )
11414            opts.hoverPaused = false; 
11415        else
11416            opts.paused = false;
11417
11418    
11419        if ( ! alreadyResumed ) {
11420            opts.container.removeClass('cycle-paused');
11421            // #gh-230; if an animation is in progress then don't queue a new transition; it will
11422            // happen naturally
11423            if ( opts.slides.filter(':animated').length === 0 )
11424                opts.API.queueTransition( opts.API.getSlideOpts(), opts._remainingTimeout );
11425            opts.API.trigger('cycle-resumed', [ opts, opts._remainingTimeout ] ).log('cycle-resumed');
11426        }
11427    },
11428
11429    add: function( slides, prepend ) {
11430        var opts = this.opts();
11431        var oldSlideCount = opts.slideCount;
11432        var startSlideshow = false;
11433        var len;
11434
11435        if ( $.type(slides) == 'string')
11436            slides = $.trim( slides );
11437
11438        $( slides ).each(function(i) {
11439            var slideOpts;
11440            var slide = $(this);
11441
11442            if ( prepend )
11443                opts.container.prepend( slide );
11444            else
11445                opts.container.append( slide );
11446
11447            opts.slideCount++;
11448            slideOpts = opts.API.buildSlideOpts( slide );
11449
11450            if ( prepend )
11451                opts.slides = $( slide ).add( opts.slides );
11452            else
11453                opts.slides = opts.slides.add( slide );
11454
11455            opts.API.initSlide( slideOpts, slide, --opts._maxZ );
11456
11457            slide.data('cycle.opts', slideOpts);
11458            opts.API.trigger('cycle-slide-added', [ opts, slideOpts, slide ]);
11459        });
11460
11461        opts.API.updateView( true );
11462
11463        startSlideshow = opts._preInitialized && (oldSlideCount < 2 && opts.slideCount >= 1);
11464        if ( startSlideshow ) {
11465            if ( !opts._initialized )
11466                opts.API.initSlideshow();
11467            else if ( opts.timeout ) {
11468                len = opts.slides.length;
11469                opts.nextSlide = opts.reverse ? len - 1 : 1;
11470                if ( !opts.timeoutId ) {
11471                    opts.API.queueTransition( opts );
11472                }
11473            }
11474        }
11475    },
11476
11477    calcFirstSlide: function() {
11478        var opts = this.opts();
11479        var firstSlideIndex;
11480        firstSlideIndex = parseInt( opts.startingSlide || 0, 10 );
11481        if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0)
11482            firstSlideIndex = 0;
11483
11484        opts.currSlide = firstSlideIndex;
11485        if ( opts.reverse ) {
11486            opts.nextSlide = firstSlideIndex - 1;
11487            if (opts.nextSlide < 0)
11488                opts.nextSlide = opts.slides.length - 1;
11489        }
11490        else {
11491            opts.nextSlide = firstSlideIndex + 1;
11492            if (opts.nextSlide == opts.slides.length)
11493                opts.nextSlide = 0;
11494        }
11495    },
11496
11497    calcNextSlide: function() {
11498        var opts = this.opts();
11499        var roll;
11500        if ( opts.reverse ) {
11501            roll = (opts.nextSlide - 1) < 0;
11502            opts.nextSlide = roll ? opts.slideCount - 1 : opts.nextSlide-1;
11503            opts.currSlide = roll ? 0 : opts.nextSlide+1;
11504        }
11505        else {
11506            roll = (opts.nextSlide + 1) == opts.slides.length;
11507            opts.nextSlide = roll ? 0 : opts.nextSlide+1;
11508            opts.currSlide = roll ? opts.slides.length-1 : opts.nextSlide-1;
11509        }
11510    },
11511
11512    calcTx: function( slideOpts, manual ) {
11513        var opts = slideOpts;
11514        var tx;
11515
11516        if ( opts._tempFx )
11517            tx = $.fn.cycle.transitions[opts._tempFx];
11518        else if ( manual && opts.manualFx )
11519            tx = $.fn.cycle.transitions[opts.manualFx];
11520
11521        if ( !tx )
11522            tx = $.fn.cycle.transitions[opts.fx];
11523
11524        opts._tempFx = null;
11525        this.opts()._tempFx = null;
11526
11527        if (!tx) {
11528            tx = $.fn.cycle.transitions.fade;
11529            opts.API.log('Transition "' + opts.fx + '" not found.  Using fade.');
11530        }
11531        return tx;
11532    },
11533
11534    prepareTx: function( manual, fwd ) {
11535        var opts = this.opts();
11536        var after, curr, next, slideOpts, tx;
11537
11538        if ( opts.slideCount < 2 ) {
11539            opts.timeoutId = 0;
11540            return;
11541        }
11542        if ( manual && ( !opts.busy || opts.manualTrump ) ) {
11543            opts.API.stopTransition();
11544            opts.busy = false;
11545            clearTimeout(opts.timeoutId);
11546            opts.timeoutId = 0;
11547        }
11548        if ( opts.busy )
11549            return;
11550        if ( opts.timeoutId === 0 && !manual )
11551            return;
11552
11553        curr = opts.slides[opts.currSlide];
11554        next = opts.slides[opts.nextSlide];
11555        slideOpts = opts.API.getSlideOpts( opts.nextSlide );
11556        tx = opts.API.calcTx( slideOpts, manual );
11557
11558        opts._tx = tx;
11559
11560        if ( manual && slideOpts.manualSpeed !== undefined )
11561            slideOpts.speed = slideOpts.manualSpeed;
11562
11563        // if ( opts.nextSlide === opts.currSlide )
11564        //     opts.API.calcNextSlide();
11565
11566        // ensure that:
11567        //      1. advancing to a different slide
11568        //      2. this is either a manual event (prev/next, pager, cmd) or 
11569        //              a timer event and slideshow is not paused
11570        if ( opts.nextSlide != opts.currSlide && 
11571            (manual || (!opts.paused && !opts.hoverPaused && opts.timeout) )) { // #62
11572
11573            opts.API.trigger('cycle-before', [ slideOpts, curr, next, fwd ]);
11574            if ( tx.before )
11575                tx.before( slideOpts, curr, next, fwd );
11576
11577            after = function() {
11578                opts.busy = false;
11579                // #76; bail if slideshow has been destroyed
11580                if (! opts.container.data( 'cycle.opts' ) )
11581                    return;
11582
11583                if (tx.after)
11584                    tx.after( slideOpts, curr, next, fwd );
11585                opts.API.trigger('cycle-after', [ slideOpts, curr, next, fwd ]);
11586                opts.API.queueTransition( slideOpts);
11587                opts.API.updateView( true );
11588            };
11589
11590            opts.busy = true;
11591            if (tx.transition)
11592                tx.transition(slideOpts, curr, next, fwd, after);
11593            else
11594                opts.API.doTransition( slideOpts, curr, next, fwd, after);
11595
11596            opts.API.calcNextSlide();
11597            opts.API.updateView();
11598        } else {
11599            opts.API.queueTransition( slideOpts );
11600        }
11601    },
11602
11603    // perform the actual animation
11604    doTransition: function( slideOpts, currEl, nextEl, fwd, callback) {
11605        var opts = slideOpts;
11606        var curr = $(currEl), next = $(nextEl);
11607        var fn = function() {
11608            // make sure animIn has something so that callback doesn't trigger immediately
11609            next.animate(opts.animIn || { opacity: 1}, opts.speed, opts.easeIn || opts.easing, callback);
11610        };
11611
11612        next.css(opts.cssBefore || {});
11613        curr.animate(opts.animOut || {}, opts.speed, opts.easeOut || opts.easing, function() {
11614            curr.css(opts.cssAfter || {});
11615            if (!opts.sync) {
11616                fn();
11617            }
11618        });
11619        if (opts.sync) {
11620            fn();
11621        }
11622    },
11623
11624    queueTransition: function( slideOpts, specificTimeout ) {
11625        var opts = this.opts();
11626        var timeout = specificTimeout !== undefined ? specificTimeout : slideOpts.timeout;
11627        if (opts.nextSlide === 0 && --opts.loop === 0) {
11628            opts.API.log('terminating; loop=0');
11629            opts.timeout = 0;
11630            if ( timeout ) {
11631                setTimeout(function() {
11632                    opts.API.trigger('cycle-finished', [ opts ]);
11633                }, timeout);
11634            }
11635            else {
11636                opts.API.trigger('cycle-finished', [ opts ]);
11637            }
11638            // reset nextSlide
11639            opts.nextSlide = opts.currSlide;
11640            return;
11641        }
11642        if ( opts.continueAuto !== undefined ) {
11643            if ( opts.continueAuto === false || 
11644                ($.isFunction(opts.continueAuto) && opts.continueAuto() === false )) {
11645                opts.API.log('terminating automatic transitions');
11646                opts.timeout = 0;
11647                if ( opts.timeoutId )
11648                    clearTimeout(opts.timeoutId);
11649                return;
11650            }
11651        }
11652        if ( timeout ) {
11653            opts._lastQueue = $.now();
11654            if ( specificTimeout === undefined )
11655                opts._remainingTimeout = slideOpts.timeout;
11656
11657            if ( !opts.paused && ! opts.hoverPaused ) {
11658                opts.timeoutId = setTimeout(function() { 
11659                    opts.API.prepareTx( false, !opts.reverse ); 
11660                }, timeout );
11661            }
11662        }
11663    },
11664
11665    stopTransition: function() {
11666        var opts = this.opts();
11667        if ( opts.slides.filter(':animated').length ) {
11668            opts.slides.stop(false, true);
11669            opts.API.trigger('cycle-transition-stopped', [ opts ]);
11670        }
11671
11672        if ( opts._tx && opts._tx.stopTransition )
11673            opts._tx.stopTransition( opts );
11674    },
11675
11676    // advance slide forward or back
11677    advanceSlide: function( val ) {
11678        var opts = this.opts();
11679        clearTimeout(opts.timeoutId);
11680        opts.timeoutId = 0;
11681        opts.nextSlide = opts.currSlide + val;
11682        
11683        if (opts.nextSlide < 0)
11684            opts.nextSlide = opts.slides.length - 1;
11685        else if (opts.nextSlide >= opts.slides.length)
11686            opts.nextSlide = 0;
11687
11688        opts.API.prepareTx( true,  val >= 0 );
11689        return false;
11690    },
11691
11692    buildSlideOpts: function( slide ) {
11693        var opts = this.opts();
11694        var val, shortName;
11695        var slideOpts = slide.data() || {};
11696        for (var p in slideOpts) {
11697            // allow props to be accessed sans 'cycle' prefix and log the overrides
11698            if (slideOpts.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) {
11699                val = slideOpts[p];
11700                shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase);
11701                opts.API.log('['+(opts.slideCount-1)+']', shortName+':', val, '('+typeof val +')');
11702                slideOpts[shortName] = val;
11703            }
11704        }
11705
11706        slideOpts = $.extend( {}, $.fn.cycle.defaults, opts, slideOpts );
11707        slideOpts.slideNum = opts.slideCount;
11708
11709        try {
11710            // these props should always be read from the master state object
11711            delete slideOpts.API;
11712            delete slideOpts.slideCount;
11713            delete slideOpts.currSlide;
11714            delete slideOpts.nextSlide;
11715            delete slideOpts.slides;
11716        } catch(e) {
11717            // no op
11718        }
11719        return slideOpts;
11720    },
11721
11722    getSlideOpts: function( index ) {
11723        var opts = this.opts();
11724        if ( index === undefined )
11725            index = opts.currSlide;
11726
11727        var slide = opts.slides[index];
11728        var slideOpts = $(slide).data('cycle.opts');
11729        return $.extend( {}, opts, slideOpts );
11730    },
11731    
11732    initSlide: function( slideOpts, slide, suggestedZindex ) {
11733        var opts = this.opts();
11734        slide.css( slideOpts.slideCss || {} );
11735        if ( suggestedZindex > 0 )
11736            slide.css( 'zIndex', suggestedZindex );
11737
11738        // ensure that speed settings are sane
11739        if ( isNaN( slideOpts.speed ) )
11740            slideOpts.speed = $.fx.speeds[slideOpts.speed] || $.fx.speeds._default;
11741        if ( !slideOpts.sync )
11742            slideOpts.speed = slideOpts.speed / 2;
11743
11744        slide.addClass( opts.slideClass );
11745    },
11746
11747    updateView: function( isAfter, isDuring, forceEvent ) {
11748        var opts = this.opts();
11749        if ( !opts._initialized )
11750            return;
11751        var slideOpts = opts.API.getSlideOpts();
11752        var currSlide = opts.slides[ opts.currSlide ];
11753
11754        if ( ! isAfter && isDuring !== true ) {
11755            opts.API.trigger('cycle-update-view-before', [ opts, slideOpts, currSlide ]);
11756            if ( opts.updateView < 0 )
11757                return;
11758        }
11759
11760        if ( opts.slideActiveClass ) {
11761            opts.slides.removeClass( opts.slideActiveClass )
11762                .eq( opts.currSlide ).addClass( opts.slideActiveClass );
11763        }
11764
11765        if ( isAfter && opts.hideNonActive )
11766            opts.slides.filter( ':not(.' + opts.slideActiveClass + ')' ).css('visibility', 'hidden');
11767
11768        if ( opts.updateView === 0 ) {
11769            setTimeout(function() {
11770                opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]);
11771            }, slideOpts.speed / (opts.sync ? 2 : 1) );
11772        }
11773
11774        if ( opts.updateView !== 0 )
11775            opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]);
11776        
11777        if ( isAfter )
11778            opts.API.trigger('cycle-update-view-after', [ opts, slideOpts, currSlide ]);
11779    },
11780
11781    getComponent: function( name ) {
11782        var opts = this.opts();
11783        var selector = opts[name];
11784        if (typeof selector === 'string') {
11785            // if selector is a child, sibling combinator, adjancent selector then use find, otherwise query full dom
11786            return (/^\s*[\>|\+|~]/).test( selector ) ? opts.container.find( selector ) : $( selector );
11787        }
11788        if (selector.jquery)
11789            return selector;
11790        
11791        return $(selector);
11792    },
11793
11794    stackSlides: function( curr, next, fwd ) {
11795        var opts = this.opts();
11796        if ( !curr ) {
11797            curr = opts.slides[opts.currSlide];
11798            next = opts.slides[opts.nextSlide];
11799            fwd = !opts.reverse;
11800        }
11801
11802        // reset the zIndex for the common case:
11803        // curr slide on top,  next slide beneath, and the rest in order to be shown
11804        $(curr).css('zIndex', opts.maxZ);
11805
11806        var i;
11807        var z = opts.maxZ - 2;
11808        var len = opts.slideCount;
11809        if (fwd) {
11810            for ( i = opts.currSlide + 1; i < len; i++ )
11811                $( opts.slides[i] ).css( 'zIndex', z-- );
11812            for ( i = 0; i < opts.currSlide; i++ )
11813                $( opts.slides[i] ).css( 'zIndex', z-- );
11814        }
11815        else {
11816            for ( i = opts.currSlide - 1; i >= 0; i-- )
11817                $( opts.slides[i] ).css( 'zIndex', z-- );
11818            for ( i = len - 1; i > opts.currSlide; i-- )
11819                $( opts.slides[i] ).css( 'zIndex', z-- );
11820        }
11821
11822        $(next).css('zIndex', opts.maxZ - 1);
11823    },
11824
11825    getSlideIndex: function( el ) {
11826        return this.opts().slides.index( el );
11827    }
11828
11829}; // API
11830
11831// default logger
11832$.fn.cycle.log = function log() {
11833    /*global console:true */
11834    if (window.console && console.log)
11835        console.log('[cycle2] ' + Array.prototype.join.call(arguments, ' ') );
11836};
11837
11838$.fn.cycle.version = function() { return 'Cycle2: ' + version; };
11839
11840// helper functions
11841
11842function lowerCase(s) {
11843    return (s || '').toLowerCase();
11844}
11845
11846// expose transition object
11847$.fn.cycle.transitions = {
11848    custom: {
11849    },
11850    none: {
11851        before: function( opts, curr, next, fwd ) {
11852            opts.API.stackSlides( next, curr, fwd );
11853            opts.cssBefore = { opacity: 1, visibility: 'visible', display: 'block' };
11854        }
11855    },
11856    fade: {
11857        before: function( opts, curr, next, fwd ) {
11858            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
11859            opts.API.stackSlides( curr, next, fwd );
11860            opts.cssBefore = $.extend(css, { opacity: 0, visibility: 'visible', display: 'block' });
11861            opts.animIn = { opacity: 1 };
11862            opts.animOut = { opacity: 0 };
11863        }
11864    },
11865    fadeout: {
11866        before: function( opts , curr, next, fwd ) {
11867            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
11868            opts.API.stackSlides( curr, next, fwd );
11869            opts.cssBefore = $.extend(css, { opacity: 1, visibility: 'visible', display: 'block' });
11870            opts.animOut = { opacity: 0 };
11871        }
11872    },
11873    scrollHorz: {
11874        before: function( opts, curr, next, fwd ) {
11875            opts.API.stackSlides( curr, next, fwd );
11876            var w = opts.container.css('overflow','hidden').width();
11877            opts.cssBefore = { left: fwd ? w : - w, top: 0, opacity: 1, visibility: 'visible', display: 'block' };
11878            opts.cssAfter = { zIndex: opts._maxZ - 2, left: 0 };
11879            opts.animIn = { left: 0 };
11880            opts.animOut = { left: fwd ? -w : w };
11881        }
11882    }
11883};
11884
11885// @see: http://jquery.malsup.com/cycle2/api
11886$.fn.cycle.defaults = {
11887    allowWrap:        true,
11888    autoSelector:     '.cycle-slideshow[data-cycle-auto-init!=false]',
11889    delay:            0,
11890    easing:           null,
11891    fx:              'fade',
11892    hideNonActive:    true,
11893    loop:             0,
11894    manualFx:         undefined,
11895    manualSpeed:      undefined,
11896    manualTrump:      true,
11897    maxZ:             100,
11898    pauseOnHover:     false,
11899    reverse:          false,
11900    slideActiveClass: 'cycle-slide-active',
11901    slideClass:       'cycle-slide',
11902    slideCss:         { position: 'absolute', top: 0, left: 0 },
11903    slides:          '> img',
11904    speed:            500,
11905    startingSlide:    0,
11906    sync:             true,
11907    timeout:          4000,
11908    updateView:       0
11909};
11910
11911// automatically find and run slideshows
11912$(document).ready(function() {
11913    $( $.fn.cycle.defaults.autoSelector ).cycle();
11914});
11915
11916})(jQuery);
11917
11918/*! Cycle2 autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130913 */
11919(function($) {
11920"use strict";
11921
11922$.extend($.fn.cycle.defaults, {
11923    autoHeight: 0, // setting this option to false disables autoHeight logic
11924    autoHeightSpeed: 250,
11925    autoHeightEasing: null
11926});    
11927
11928$(document).on( 'cycle-initialized', function( e, opts ) {
11929    var autoHeight = opts.autoHeight;
11930    var t = $.type( autoHeight );
11931    var resizeThrottle = null;
11932    var ratio;
11933
11934    if ( t !== 'string' && t !== 'number' )
11935        return;
11936
11937    // bind events
11938    opts.container.on( 'cycle-slide-added cycle-slide-removed', initAutoHeight );
11939    opts.container.on( 'cycle-destroyed', onDestroy );
11940
11941    if ( autoHeight == 'container' ) {
11942        opts.container.on( 'cycle-before', onBefore );
11943    }
11944    else if ( t === 'string' && /\d+\:\d+/.test( autoHeight ) ) { 
11945        // use ratio
11946        ratio = autoHeight.match(/(\d+)\:(\d+)/);
11947        ratio = ratio[1] / ratio[2];
11948        opts._autoHeightRatio = ratio;
11949    }
11950
11951    // if autoHeight is a number then we don't need to recalculate the sentinel
11952    // index on resize
11953    if ( t !== 'number' ) {
11954        // bind unique resize handler per slideshow (so it can be 'off-ed' in onDestroy)
11955        opts._autoHeightOnResize = function () {
11956            clearTimeout( resizeThrottle );
11957            resizeThrottle = setTimeout( onResize, 50 );
11958        };
11959
11960        $(window).on( 'resize orientationchange', opts._autoHeightOnResize );
11961    }
11962
11963    setTimeout( onResize, 30 );
11964
11965    function onResize() {
11966        initAutoHeight( e, opts );
11967    }
11968});
11969
11970function initAutoHeight( e, opts ) {
11971    var clone, height, sentinelIndex;
11972    var autoHeight = opts.autoHeight;
11973
11974    if ( autoHeight == 'container' ) {
11975        height = $( opts.slides[ opts.currSlide ] ).outerHeight();
11976        opts.container.height( height );
11977    }
11978    else if ( opts._autoHeightRatio ) { 
11979        opts.container.height( opts.container.width() / opts._autoHeightRatio );
11980    }
11981    else if ( autoHeight === 'calc' || ( $.type( autoHeight ) == 'number' && autoHeight >= 0 ) ) {
11982        if ( autoHeight === 'calc' )
11983            sentinelIndex = calcSentinelIndex( e, opts );
11984        else if ( autoHeight >= opts.slides.length )
11985            sentinelIndex = 0;
11986        else 
11987            sentinelIndex = autoHeight;
11988
11989        // only recreate sentinel if index is different
11990        if ( sentinelIndex == opts._sentinelIndex )
11991            return;
11992
11993        opts._sentinelIndex = sentinelIndex;
11994        if ( opts._sentinel )
11995            opts._sentinel.remove();
11996
11997        // clone existing slide as sentinel
11998        clone = $( opts.slides[ sentinelIndex ].cloneNode(true) );
11999        
12000        // #50; remove special attributes from cloned content
12001        clone.removeAttr( 'id name rel' ).find( '[id],[name],[rel]' ).removeAttr( 'id name rel' );
12002
12003        clone.css({
12004            position: 'static',
12005            visibility: 'hidden',
12006            display: 'block'
12007        }).prependTo( opts.container ).addClass('cycle-sentinel cycle-slide').removeClass('cycle-slide-active');
12008        clone.find( '*' ).css( 'visibility', 'hidden' );
12009
12010        opts._sentinel = clone;
12011    }
12012}    
12013
12014function calcSentinelIndex( e, opts ) {
12015    var index = 0, max = -1;
12016
12017    // calculate tallest slide index
12018    opts.slides.each(function(i) {
12019        var h = $(this).height();
12020        if ( h > max ) {
12021            max = h;
12022            index = i;
12023        }
12024    });
12025    return index;
12026}
12027
12028function onBefore( e, opts, outgoing, incoming, forward ) {
12029    var h = $(incoming).outerHeight();
12030    opts.container.animate( { height: h }, opts.autoHeightSpeed, opts.autoHeightEasing );
12031}
12032
12033function onDestroy( e, opts ) {
12034    if ( opts._autoHeightOnResize ) {
12035        $(window).off( 'resize orientationchange', opts._autoHeightOnResize );
12036        opts._autoHeightOnResize = null;
12037    }
12038    opts.container.off( 'cycle-slide-added cycle-slide-removed', initAutoHeight );
12039    opts.container.off( 'cycle-destroyed', onDestroy );
12040    opts.container.off( 'cycle-before', onBefore );
12041
12042    if ( opts._sentinel ) {
12043        opts._sentinel.remove();
12044        opts._sentinel = null;
12045    }
12046}
12047
12048})(jQuery);
12049
12050/*! caption plugin for Cycle2;  version: 20130306 */
12051(function($) {
12052"use strict";
12053
12054$.extend($.fn.cycle.defaults, {
12055    caption:          '> .cycle-caption',
12056    captionTemplate:  '{{slideNum}} / {{slideCount}}',
12057    overlay:          '> .cycle-overlay',
12058    overlayTemplate:  '<div>{{title}}</div><div>{{desc}}</div>',
12059    captionModule:    'caption'
12060});    
12061
12062$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) {
12063    if ( opts.captionModule !== 'caption' )
12064        return;
12065    var el;
12066    $.each(['caption','overlay'], function() {
12067        var name = this; 
12068        var template = slideOpts[name+'Template'];
12069        var el = opts.API.getComponent( name );
12070        if( el.length && template ) {
12071            el.html( opts.API.tmpl( template, slideOpts, opts, currSlide ) );
12072            el.show();
12073        }
12074        else {
12075            el.hide();
12076        }
12077    });
12078});
12079
12080$(document).on( 'cycle-destroyed', function( e, opts ) {
12081    var el;
12082    $.each(['caption','overlay'], function() {
12083        var name = this, template = opts[name+'Template'];
12084        if ( opts[name] && template ) {
12085            el = opts.API.getComponent( 'caption' );
12086            el.empty();
12087        }
12088    });
12089});
12090
12091})(jQuery);
12092
12093/*! command plugin for Cycle2;  version: 20140415 */
12094(function($) {
12095"use strict";
12096
12097var c2 = $.fn.cycle;
12098
12099$.fn.cycle = function( options ) {
12100    var cmd, cmdFn, opts;
12101    var args = $.makeArray( arguments );
12102
12103    if ( $.type( options ) == 'number' ) {
12104        return this.cycle( 'goto', options );
12105    }
12106
12107    if ( $.type( options ) == 'string' ) {
12108        return this.each(function() {
12109            var cmdArgs;
12110            cmd = options;
12111            opts = $(this).data('cycle.opts');
12112
12113            if ( opts === undefined ) {
12114                c2.log('slideshow must be initialized before sending commands; "' + cmd + '" ignored');
12115                return;
12116            }
12117            else {
12118                cmd = cmd == 'goto' ? 'jump' : cmd; // issue #3; change 'goto' to 'jump' internally
12119                cmdFn = opts.API[ cmd ];
12120                if ( $.isFunction( cmdFn )) {
12121                    cmdArgs = $.makeArray( args );
12122                    cmdArgs.shift();
12123                    return cmdFn.apply( opts.API, cmdArgs );
12124                }
12125                else {
12126                    c2.log( 'unknown command: ', cmd );
12127                }
12128            }
12129        });
12130    }
12131    else {
12132        return c2.apply( this, arguments );
12133    }
12134};
12135
12136// copy props
12137$.extend( $.fn.cycle, c2 );
12138
12139$.extend( c2.API, {
12140    next: function() {
12141        var opts = this.opts();
12142        if ( opts.busy && ! opts.manualTrump )
12143            return;
12144
12145        var count = opts.reverse ? -1 : 1;
12146        if ( opts.allowWrap === false && ( opts.currSlide + count ) >= opts.slideCount )
12147            return;
12148
12149        opts.API.advanceSlide( count );
12150        opts.API.trigger('cycle-next', [ opts ]).log('cycle-next');
12151    },
12152
12153    prev: function() {
12154        var opts = this.opts();
12155        if ( opts.busy && ! opts.manualTrump )
12156            return;
12157        var count = opts.reverse ? 1 : -1;
12158        if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 )
12159            return;
12160
12161        opts.API.advanceSlide( count );
12162        opts.API.trigger('cycle-prev', [ opts ]).log('cycle-prev');
12163    },
12164
12165    destroy: function() {
12166        this.stop(); //#204
12167
12168        var opts = this.opts();
12169        var clean = $.isFunction( $._data ) ? $._data : $.noop;  // hack for #184 and #201
12170        clearTimeout(opts.timeoutId);
12171        opts.timeoutId = 0;
12172        opts.API.stop();
12173        opts.API.trigger( 'cycle-destroyed', [ opts ] ).log('cycle-destroyed');
12174        opts.container.removeData();
12175        clean( opts.container[0], 'parsedAttrs', false );
12176
12177        // #75; remove inline styles
12178        if ( ! opts.retainStylesOnDestroy ) {
12179            opts.container.removeAttr( 'style' );
12180            opts.slides.removeAttr( 'style' );
12181            opts.slides.removeClass( opts.slideActiveClass );
12182        }
12183        opts.slides.each(function() {
12184            var slide = $(this);
12185            slide.removeData();
12186            slide.removeClass( opts.slideClass );
12187            clean( this, 'parsedAttrs', false );
12188        });
12189    },
12190
12191    jump: function( index, fx ) {
12192        // go to the requested slide
12193        var fwd;
12194        var opts = this.opts();
12195        if ( opts.busy && ! opts.manualTrump )
12196            return;
12197        var num = parseInt( index, 10 );
12198        if (isNaN(num) || num < 0 || num >= opts.slides.length) {
12199            opts.API.log('goto: invalid slide index: ' + num);
12200            return;
12201        }
12202        if (num == opts.currSlide) {
12203            opts.API.log('goto: skipping, already on slide', num);
12204            return;
12205        }
12206        opts.nextSlide = num;
12207        clearTimeout(opts.timeoutId);
12208        opts.timeoutId = 0;
12209        opts.API.log('goto: ', num, ' (zero-index)');
12210        fwd = opts.currSlide < opts.nextSlide;
12211        opts._tempFx = fx;
12212        opts.API.prepareTx( true, fwd );
12213    },
12214
12215    stop: function() {
12216        var opts = this.opts();
12217        var pauseObj = opts.container;
12218        clearTimeout(opts.timeoutId);
12219        opts.timeoutId = 0;
12220        opts.API.stopTransition();
12221        if ( opts.pauseOnHover ) {
12222            if ( opts.pauseOnHover !== true )
12223                pauseObj = $( opts.pauseOnHover );
12224            pauseObj.off('mouseenter mouseleave');
12225        }
12226        opts.API.trigger('cycle-stopped', [ opts ]).log('cycle-stopped');
12227    },
12228
12229    reinit: function() {
12230        var opts = this.opts();
12231        opts.API.destroy();
12232        opts.container.cycle();
12233    },
12234
12235    remove: function( index ) {
12236        var opts = this.opts();
12237        var slide, slideToRemove, slides = [], slideNum = 1;
12238        for ( var i=0; i < opts.slides.length; i++ ) {
12239            slide = opts.slides[i];
12240            if ( i == index ) {
12241                slideToRemove = slide;
12242            }
12243            else {
12244                slides.push( slide );
12245                $( slide ).data('cycle.opts').slideNum = slideNum;
12246                slideNum++;
12247            }
12248        }
12249        if ( slideToRemove ) {
12250            opts.slides = $( slides );
12251            opts.slideCount--;
12252            $( slideToRemove ).remove();
12253            if (index == opts.currSlide)
12254                opts.API.advanceSlide( 1 );
12255            else if ( index < opts.currSlide )
12256                opts.currSlide--;
12257            else
12258                opts.currSlide++;
12259
12260            opts.API.trigger('cycle-slide-removed', [ opts, index, slideToRemove ]).log('cycle-slide-removed');
12261            opts.API.updateView();
12262        }
12263    }
12264
12265});
12266
12267// listen for clicks on elements with data-cycle-cmd attribute
12268$(document).on('click.cycle', '[data-cycle-cmd]', function(e) {
12269    // issue cycle command
12270    e.preventDefault();
12271    var el = $(this);
12272    var command = el.data('cycle-cmd');
12273    var context = el.data('cycle-context') || '.cycle-slideshow';
12274    $(context).cycle(command, el.data('cycle-arg'));
12275});
12276
12277
12278})(jQuery);
12279
12280/*! hash plugin for Cycle2;  version: 20130905 */
12281(function($) {
12282"use strict";
12283
12284$(document).on( 'cycle-pre-initialize', function( e, opts ) {
12285    onHashChange( opts, true );
12286
12287    opts._onHashChange = function() {
12288        onHashChange( opts, false );
12289    };
12290
12291    $( window ).on( 'hashchange', opts._onHashChange);
12292});
12293
12294$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) {
12295    if ( slideOpts.hash && ( '#' + slideOpts.hash ) != window.location.hash ) {
12296        opts._hashFence = true;
12297        window.location.hash = slideOpts.hash;
12298    }
12299});
12300
12301$(document).on( 'cycle-destroyed', function( e, opts) {
12302    if ( opts._onHashChange ) {
12303        $( window ).off( 'hashchange', opts._onHashChange );
12304    }
12305});
12306
12307function onHashChange( opts, setStartingSlide ) {
12308    var hash;
12309    if ( opts._hashFence ) {
12310        opts._hashFence = false;
12311        return;
12312    }
12313    
12314    hash = window.location.hash.substring(1);
12315
12316    opts.slides.each(function(i) {
12317        if ( $(this).data( 'cycle-hash' ) == hash ) {
12318            if ( setStartingSlide === true ) {
12319                opts.startingSlide = i;
12320            }
12321            else {
12322                var fwd = opts.currSlide < i;
12323                opts.nextSlide = i;
12324                opts.API.prepareTx( true, fwd );
12325            }
12326            return false;
12327        }
12328    });
12329}
12330
12331})(jQuery);
12332
12333/*! loader plugin for Cycle2;  version: 20131121 */
12334(function($) {
12335"use strict";
12336
12337$.extend($.fn.cycle.defaults, {
12338    loader: false
12339});
12340
12341$(document).on( 'cycle-bootstrap', function( e, opts ) {
12342    var addFn;
12343
12344    if ( !opts.loader )
12345        return;
12346
12347    // override API.add for this slideshow
12348    addFn = opts.API.add;
12349    opts.API.add = add;
12350
12351    function add( slides, prepend ) {
12352        var slideArr = [];
12353        if ( $.type( slides ) == 'string' )
12354            slides = $.trim( slides );
12355        else if ( $.type( slides) === 'array' ) {
12356            for (var i=0; i < slides.length; i++ )
12357                slides[i] = $(slides[i])[0];
12358        }
12359
12360        slides = $( slides );
12361        var slideCount = slides.length;
12362
12363        if ( ! slideCount )
12364            return;
12365
12366        slides.css('visibility','hidden').appendTo('body').each(function(i) { // appendTo fixes #56
12367            var count = 0;
12368            var slide = $(this);
12369            var images = slide.is('img') ? slide : slide.find('img');
12370            slide.data('index', i);
12371            // allow some images to be marked as unimportant (and filter out images w/o src value)
12372            images = images.filter(':not(.cycle-loader-ignore)').filter(':not([src=""])');
12373            if ( ! images.length ) {
12374                --slideCount;
12375                slideArr.push( slide );
12376                return;
12377            }
12378
12379            count = images.length;
12380            images.each(function() {
12381                // add images that are already loaded
12382                if ( this.complete ) {
12383                    imageLoaded();
12384                }
12385                else {
12386                    $(this).load(function() {
12387                        imageLoaded();
12388                    }).on("error", function() {
12389                        if ( --count === 0 ) {
12390                            // ignore this slide
12391                            opts.API.log('slide skipped; img not loaded:', this.src);
12392                            if ( --slideCount === 0 && opts.loader == 'wait') {
12393                                addFn.apply( opts.API, [ slideArr, prepend ] );
12394                            }
12395                        }
12396                    });
12397                }
12398            });
12399
12400            function imageLoaded() {
12401                if ( --count === 0 ) {
12402                    --slideCount;
12403                    addSlide( slide );
12404                }
12405            }
12406        });
12407
12408        if ( slideCount )
12409            opts.container.addClass('cycle-loading');
12410        
12411
12412        function addSlide( slide ) {
12413            var curr;
12414            if ( opts.loader == 'wait' ) {
12415                slideArr.push( slide );
12416                if ( slideCount === 0 ) {
12417                    // #59; sort slides into original markup order
12418                    slideArr.sort( sorter );
12419                    addFn.apply( opts.API, [ slideArr, prepend ] );
12420                    opts.container.removeClass('cycle-loading');
12421                }
12422            }
12423            else {
12424                curr = $(opts.slides[opts.currSlide]);
12425                addFn.apply( opts.API, [ slide, prepend ] );
12426                curr.show();
12427                opts.container.removeClass('cycle-loading');
12428            }
12429        }
12430
12431        function sorter(a, b) {
12432            return a.data('index') - b.data('index');
12433        }
12434    }
12435});
12436
12437})(jQuery);
12438
12439/*! pager plugin for Cycle2;  version: 20140415 */
12440(function($) {
12441"use strict";
12442
12443$.extend($.fn.cycle.defaults, {
12444    pager:            '> .cycle-pager',
12445    pagerActiveClass: 'cycle-pager-active',
12446    pagerEvent:       'click.cycle',
12447    pagerEventBubble: undefined,
12448    pagerTemplate:    '<span>&bull;</span>'
12449});
12450
12451$(document).on( 'cycle-bootstrap', function( e, opts, API ) {
12452    // add method to API
12453    API.buildPagerLink = buildPagerLink;
12454});
12455
12456$(document).on( 'cycle-slide-added', function( e, opts, slideOpts, slideAdded ) {
12457    if ( opts.pager ) {
12458        opts.API.buildPagerLink ( opts, slideOpts, slideAdded );
12459        opts.API.page = page;
12460    }
12461});
12462
12463$(document).on( 'cycle-slide-removed', function( e, opts, index, slideRemoved ) {
12464    if ( opts.pager ) {
12465        var pagers = opts.API.getComponent( 'pager' );
12466        pagers.each(function() {
12467            var pager = $(this);
12468            $( pager.children()[index] ).remove();
12469        });
12470    }
12471});
12472
12473$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) {
12474    var pagers;
12475
12476    if ( opts.pager ) {
12477        pagers = opts.API.getComponent( 'pager' );
12478        pagers.each(function() {
12479           $(this).children().removeClass( opts.pagerActiveClass )
12480            .eq( opts.currSlide ).addClass( opts.pagerActiveClass );
12481        });
12482    }
12483});
12484
12485$(document).on( 'cycle-destroyed', function( e, opts ) {
12486    var pager = opts.API.getComponent( 'pager' );
12487
12488    if ( pager ) {
12489        pager.children().off( opts.pagerEvent ); // #202
12490        if ( opts.pagerTemplate )
12491            pager.empty();
12492    }
12493});
12494
12495function buildPagerLink( opts, slideOpts, slide ) {
12496    var pagerLink;
12497    var pagers = opts.API.getComponent( 'pager' );
12498    pagers.each(function() {
12499        var pager = $(this);
12500        if ( slideOpts.pagerTemplate ) {
12501            var markup = opts.API.tmpl( slideOpts.pagerTemplate, slideOpts, opts, slide[0] );
12502            pagerLink = $( markup ).appendTo( pager );
12503        }
12504        else {
12505            pagerLink = pager.children().eq( opts.slideCount - 1 );
12506        }
12507        pagerLink.on( opts.pagerEvent, function(e) {
12508            if ( ! opts.pagerEventBubble )
12509                e.preventDefault();
12510            opts.API.page( pager, e.currentTarget);
12511        });
12512    });
12513}
12514
12515function page( pager, target ) {
12516    /*jshint validthis:true */
12517    var opts = this.opts();
12518    if ( opts.busy && ! opts.manualTrump )
12519        return;
12520
12521    var index = pager.children().index( target );
12522    var nextSlide = index;
12523    var fwd = opts.currSlide < nextSlide;
12524    if (opts.currSlide == nextSlide) {
12525        return; // no op, clicked pager for the currently displayed slide
12526    }
12527    opts.nextSlide = nextSlide;
12528    opts._tempFx = opts.pagerFx;
12529    opts.API.prepareTx( true, fwd );
12530    opts.API.trigger('cycle-pager-activated', [opts, pager, target ]);
12531}
12532
12533})(jQuery);
12534
12535/*! prevnext plugin for Cycle2;  version: 20140408 */
12536(function($) {
12537"use strict";
12538
12539$.extend($.fn.cycle.defaults, {
12540    next:           '> .cycle-next',
12541    nextEvent:      'click.cycle',
12542    disabledClass:  'disabled',
12543    prev:           '> .cycle-prev',
12544    prevEvent:      'click.cycle',
12545    swipe:          false
12546});
12547
12548$(document).on( 'cycle-initialized', function( e, opts ) {
12549    opts.API.getComponent( 'next' ).on( opts.nextEvent, function(e) {
12550        e.preventDefault();
12551        opts.API.next();
12552    });
12553
12554    opts.API.getComponent( 'prev' ).on( opts.prevEvent, function(e) {
12555        e.preventDefault();
12556        opts.API.prev();
12557    });
12558
12559    if ( opts.swipe ) {
12560        var nextEvent = opts.swipeVert ? 'swipeUp.cycle' : 'swipeLeft.cycle swipeleft.cycle';
12561        var prevEvent = opts.swipeVert ? 'swipeDown.cycle' : 'swipeRight.cycle swiperight.cycle';
12562        opts.container.on( nextEvent, function(e) {
12563            opts._tempFx = opts.swipeFx;
12564            opts.API.next();
12565        });
12566        opts.container.on( prevEvent, function() {
12567            opts._tempFx = opts.swipeFx;
12568            opts.API.prev();
12569        });
12570    }
12571});
12572
12573$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) {
12574    if ( opts.allowWrap )
12575        return;
12576
12577    var cls = opts.disabledClass;
12578    var next = opts.API.getComponent( 'next' );
12579    var prev = opts.API.getComponent( 'prev' );
12580    var prevBoundry = opts._prevBoundry || 0;
12581    var nextBoundry = (opts._nextBoundry !== undefined)?opts._nextBoundry:opts.slideCount - 1;
12582
12583    if ( opts.currSlide == nextBoundry )
12584        next.addClass( cls ).prop( 'disabled', true );
12585    else
12586        next.removeClass( cls ).prop( 'disabled', false );
12587
12588    if ( opts.currSlide === prevBoundry )
12589        prev.addClass( cls ).prop( 'disabled', true );
12590    else
12591        prev.removeClass( cls ).prop( 'disabled', false );
12592});
12593
12594
12595$(document).on( 'cycle-destroyed', function( e, opts ) {
12596    opts.API.getComponent( 'prev' ).off( opts.nextEvent );
12597    opts.API.getComponent( 'next' ).off( opts.prevEvent );
12598    opts.container.off( 'swipeleft.cycle swiperight.cycle swipeLeft.cycle swipeRight.cycle swipeUp.cycle swipeDown.cycle' );
12599});
12600
12601})(jQuery);
12602
12603/*! progressive loader plugin for Cycle2;  version: 20130315 */
12604(function($) {
12605"use strict";
12606
12607$.extend($.fn.cycle.defaults, {
12608    progressive: false
12609});
12610
12611$(document).on( 'cycle-pre-initialize', function( e, opts ) {
12612    if ( !opts.progressive )
12613        return;
12614
12615    var API = opts.API;
12616    var nextFn = API.next;
12617    var prevFn = API.prev;
12618    var prepareTxFn = API.prepareTx;
12619    var type = $.type( opts.progressive );
12620    var slides, scriptEl;
12621
12622    if ( type == 'array' ) {
12623        slides = opts.progressive;
12624    }
12625    else if ($.isFunction( opts.progressive ) ) {
12626        slides = opts.progressive( opts );
12627    }
12628    else if ( type == 'string' ) {
12629        scriptEl = $( opts.progressive );
12630        slides = $.trim( scriptEl.html() );
12631        if ( !slides )
12632            return;
12633        // is it json array?
12634        if ( /^(\[)/.test( slides ) ) {
12635            try {
12636                slides = $.parseJSON( slides );
12637            }
12638            catch(err) {
12639                API.log( 'error parsing progressive slides', err );
12640                return;
12641            }
12642        }
12643        else {
12644            // plain text, split on delimeter
12645            slides = slides.split( new RegExp( scriptEl.data('cycle-split') || '\n') );
12646            
12647            // #95; look for empty slide
12648            if ( ! slides[ slides.length - 1 ] )
12649                slides.pop();
12650        }
12651    }
12652
12653
12654
12655    if ( prepareTxFn ) {
12656        API.prepareTx = function( manual, fwd ) {
12657            var index, slide;
12658
12659            if ( manual || slides.length === 0 ) {
12660                prepareTxFn.apply( opts.API, [ manual, fwd ] );
12661                return;
12662            }
12663
12664            if ( fwd && opts.currSlide == ( opts.slideCount-1) ) {
12665                slide = slides[ 0 ];
12666                slides = slides.slice( 1 );
12667                opts.container.one('cycle-slide-added', function(e, opts ) {
12668                    setTimeout(function() {
12669                        opts.API.advanceSlide( 1 );
12670                    },50);
12671                });
12672                opts.API.add( slide );
12673            }
12674            else if ( !fwd && opts.currSlide === 0 ) {
12675                index = slides.length-1;
12676                slide = slides[ index ];
12677                slides = slides.slice( 0, index );
12678                opts.container.one('cycle-slide-added', function(e, opts ) {
12679                    setTimeout(function() {
12680                        opts.currSlide = 1;
12681                        opts.API.advanceSlide( -1 );
12682                    },50);
12683                });
12684                opts.API.add( slide, true );
12685            }
12686            else {
12687                prepareTxFn.apply( opts.API, [ manual, fwd ] );
12688            }
12689        };
12690    }
12691
12692    if ( nextFn ) {
12693        API.next = function() {
12694            var opts = this.opts();
12695            if ( slides.length && opts.currSlide == ( opts.slideCount - 1 ) ) {
12696                var slide = slides[ 0 ];
12697                slides = slides.slice( 1 );
12698                opts.container.one('cycle-slide-added', function(e, opts ) {
12699                    nextFn.apply( opts.API );
12700                    opts.container.removeClass('cycle-loading');
12701                });
12702                opts.container.addClass('cycle-loading');
12703                opts.API.add( slide );
12704            }
12705            else {
12706                nextFn.apply( opts.API );    
12707            }
12708        };
12709    }
12710    
12711    if ( prevFn ) {
12712        API.prev = function() {
12713            var opts = this.opts();
12714            if ( slides.length && opts.currSlide === 0 ) {
12715                var index = slides.length-1;
12716                var slide = slides[ index ];
12717                slides = slides.slice( 0, index );
12718                opts.container.one('cycle-slide-added', function(e, opts ) {
12719                    opts.currSlide = 1;
12720                    opts.API.advanceSlide( -1 );
12721                    opts.container.removeClass('cycle-loading');
12722                });
12723                opts.container.addClass('cycle-loading');
12724                opts.API.add( slide, true );
12725            }
12726            else {
12727                prevFn.apply( opts.API );
12728            }
12729        };
12730    }
12731});
12732
12733})(jQuery);
12734
12735/*! tmpl plugin for Cycle2;  version: 20121227 */
12736(function($) {
12737"use strict";
12738
12739$.extend($.fn.cycle.defaults, {
12740    tmplRegex: '{{((.)?.*?)}}'
12741});
12742
12743$.extend($.fn.cycle.API, {
12744    tmpl: function( str, opts /*, ... */) {
12745        var regex = new RegExp( opts.tmplRegex || $.fn.cycle.defaults.tmplRegex, 'g' );
12746        var args = $.makeArray( arguments );
12747        args.shift();
12748        return str.replace(regex, function(_, str) {
12749            var i, j, obj, prop, names = str.split('.');
12750            for (i=0; i < args.length; i++) {
12751                obj = args[i];
12752                if ( ! obj )
12753                    continue;
12754                if (names.length > 1) {
12755                    prop = obj;
12756                    for (j=0; j < names.length; j++) {
12757                        obj = prop;
12758                        prop = prop[ names[j] ] || str;
12759                    }
12760                } else {
12761                    prop = obj[str];
12762                }
12763
12764                if ($.isFunction(prop))
12765                    return prop.apply(obj, args);
12766                if (prop !== undefined && prop !== null && prop != str)
12767                    return prop;
12768            }
12769            return str;
12770        });
12771    }
12772});    
12773
12774})(jQuery);
12775;(function ($, window, undefined) {
12776  'use strict';
12777
12778  var $doc = $(document),
12779      Modernizr = window.Modernizr;
12780
12781  $(document).ready(function() {
12782    $.fn.foundationAlerts           ? $doc.foundationAlerts() : null;
12783    $.fn.foundationButtons          ? $doc.foundationButtons() : null;
12784    $.fn.foundationAccordion        ? $doc.foundationAccordion() : null;
12785    $.fn.foundationNavigation       ? $doc.foundationNavigation() : null;
12786    $.fn.foundationTopBar           ? $doc.foundationTopBar() : null;
12787    $.fn.foundationCustomForms      ? $doc.foundationCustomForms() : null;
12788    $.fn.foundationMediaQueryViewer ? $doc.foundationMediaQueryViewer() : null;
12789    $.fn.foundationTabs             ? $doc.foundationTabs({callback : $.foundation.customForms.appendCustomMarkup}) : null;
12790    $.fn.foundationTooltips         ? $doc.foundationTooltips() : null;
12791    $.fn.foundationMagellan         ? $doc.foundationMagellan() : null;
12792    $.fn.foundationClearing         ? $doc.foundationClearing() : null;
12793
12794    $.fn.placeholder                ? $('input, textarea').placeholder() : null;
12795  });
12796
12797  // UNCOMMENT THE LINE YOU WANT BELOW IF YOU WANT IE8 SUPPORT AND ARE USING .block-grids
12798  // $('.block-grid.two-up>li:nth-child(2n+1)').css({clear: 'both'});
12799  // $('.block-grid.three-up>li:nth-child(3n+1)').css({clear: 'both'});
12800  // $('.block-grid.four-up>li:nth-child(4n+1)').css({clear: 'both'});
12801  // $('.block-grid.five-up>li:nth-child(5n+1)').css({clear: 'both'});
12802
12803  // Hide address bar on mobile devices (except if #hash present, so we don't mess up deep linking).
12804  if (Modernizr.touch && !window.location.hash) {
12805    $(window).load(function () {
12806      setTimeout(function () {
12807        // At load, if user hasn't scrolled more than 20px or so...
12808  			if( $(window).scrollTop() < 20 ) {
12809          window.scrollTo(0, 1);
12810        }
12811      }, 0);
12812    });
12813  }
12814
12815})(jQuery, this);
12816/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
12817 * Build: http://modernizr.com/download/#-inlinesvg-svg-svgclippaths-touch-shiv-mq-cssclasses-teststyles-prefixes-ie8compat-load
12818 */
12819
12820;window.Modernizr=function(a,b,c){function y(a){j.cssText=a}function z(a,b){return y(m.join(a+";")+(b||""))}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={svg:"http://www.w3.org/2000/svg"},o={},p={},q={},r=[],s=r.slice,t,u=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},v=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return u("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},w={}.hasOwnProperty,x;!A(w,"undefined")&&!A(w.call,"undefined")?x=function(a,b){return w.call(a,b)}:x=function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;
vendor: 8,261 bytes, lines 12820-12847
12820var d=s.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(s.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(s.call(arguments)))};return e}),o.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:u(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},o.svg=function(){return!!b.createElementNS&&!!b.createElementNS(n.svg,"svg").createSVGRect},o.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="<svg/>",(a.firstChild&&a.firstChild.namespaceURI)==n.svg},o.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(l.call(b.createElementNS(n.svg,"clipPath")))};for(var D in o)x(o,D)&&(t=D.toLowerCase(),e[t]=o[D](),r.push((e[t]?"":"no-")+t));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=m,e.mq=v,e.testStyles=u,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+r.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))},Modernizr.addTest("ie8compat",function(){return!window.addEventListener&&document.documentMode&&document.documentMode===7});
12821/*! http://mths.be/placeholder v2.0.7 by @mathias */
12822
12823;(function(window, document, $) {
12824
12825	var isInputSupported = 'placeholder' in document.createElement('input'),
12826	    isTextareaSupported = 'placeholder' in document.createElement('textarea'),
12827	    prototype = $.fn,
12828	    valHooks = $.valHooks,
12829	    hooks,
12830	    placeholder;
12831
12832	if (isInputSupported && isTextareaSupported) {
12833
12834		placeholder = prototype.placeholder = function() {
12835			return this;
12836		};
12837
12838		placeholder.input = placeholder.textarea = true;
12839
12840	} else {
12841
12842		placeholder = prototype.placeholder = function() {
12843			var $this = this;
12844			$this
12845				.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
12846				.not('.placeholder')
12847				.bind({
12848					'focus.placeholder': clearPlaceholder,
12849					'blur.placeholder': setPlaceholder
12850				})
12851				.data('placeholder-enabled', true)
12852				.trigger('blur.placeholder');
12853			return $this;
12854		};
12855
12856		placeholder.input = isInputSupported;
12857		placeholder.textarea = isTextareaSupported;
12858
12859		hooks = {
12860			'get': function(element) {
12861				var $element = $(element);
12862				return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
12863			},
12864			'set': function(element, value) {
12865				var $element = $(element);
12866				if (!$element.data('placeholder-enabled')) {
12867					return element.value = value;
12868				}
12869				if (value == '') {
12870					element.value = value;
12871					// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
12872					if (element != document.activeElement) {
12873						// We can't use `triggerHandler` here because of dummy text/password inputs :(
12874						setPlaceholder.call(element);
12875					}
12876				} else if ($element.hasClass('placeholder')) {
12877					clearPlaceholder.call(element, true, value) || (element.value = value);
12878				} else {
12879					element.value = value;
12880				}
12881				// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
12882				return $element;
12883			}
12884		};
12885
12886		isInputSupported || (valHooks.input = hooks);
12887		isTextareaSupported || (valHooks.textarea = hooks);
12888
12889		$(function() {
12890			// Look for forms
12891			$(document).delegate('form', 'submit.placeholder', function() {
12892				// Clear the placeholder values so they don't get submitted
12893				var $inputs = $('.placeholder', this).each(clearPlaceholder);
12894				setTimeout(function() {
12895					$inputs.each(setPlaceholder);
12896				}, 10);
12897			});
12898		});
12899
12900		// Clear placeholder values upon page reload
12901		$(window).bind('beforeunload.placeholder', function() {
12902			$('.placeholder').each(function() {
12903				this.value = '';
12904			});
12905		});
12906
12907	}
12908
12909	function args(elem) {
12910		// Return an object of element attributes
12911		var newAttrs = {},
12912		    rinlinejQuery = /^jQuery\d+$/;
12913		$.each(elem.attributes, function(i, attr) {
12914			if (attr.specified && !rinlinejQuery.test(attr.name)) {
12915				newAttrs[attr.name] = attr.value;
12916			}
12917		});
12918		return newAttrs;
12919	}
12920
12921	function clearPlaceholder(event, value) {
12922		var input = this,
12923		    $input = $(input);
12924		if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
12925			if ($input.data('placeholder-password')) {
12926				$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
12927				// If `clearPlaceholder` was called from `$.valHooks.input.set`
12928				if (event === true) {
12929					return $input[0].value = value;
12930				}
12931				$input.focus();
12932			} else {
12933				input.value = '';
12934				$input.removeClass('placeholder');
12935				input == document.activeElement && input.select();
12936			}
12937		}
12938	}
12939
12940	function setPlaceholder() {
12941		var $replacement,
12942		    input = this,
12943		    $input = $(input),
12944		    $origInput = $input,
12945		    id = this.id;
12946		if (input.value == '') {
12947			if (input.type == 'password') {
12948				if (!$input.data('placeholder-textinput')) {
12949					try {
12950						$replacement = $input.clone().attr({ 'type': 'text' });
12951					} catch(e) {
12952						$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
12953					}
12954					$replacement
12955						.removeAttr('name')
12956						.data({
12957							'placeholder-password': true,
12958							'placeholder-id': id
12959						})
12960						.bind('focus.placeholder', clearPlaceholder);
12961					$input
12962						.data({
12963							'placeholder-textinput': $replacement,
12964							'placeholder-id': id
12965						})
12966						.before($replacement);
12967				}
12968				$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
12969				// Note: `$input[0] != input` now!
12970			}
12971			$input.addClass('placeholder');
12972			$input[0].value = $input.attr('placeholder');
12973		} else {
12974			$input.removeClass('placeholder');
12975		}
12976	}
12977
12978}(this, document, jQuery));
12979;(function ($, window, undefined) {
12980  'use strict';
12981  
12982  $.fn.foundationAlerts = function (options) {
12983    var settings = $.extend({
12984      callback: $.noop
12985    }, options);
12986    
12987    $(document).on("click", ".alert-box a.close", function (e) {
12988      e.preventDefault();
12989      $(this).closest(".alert-box").fadeOut(function () {
12990        $(this).remove();
12991        // Do something else after the alert closes
12992        settings.callback();
12993      });
12994    });
12995    
12996  };
12997
12998})(jQuery, this);
12999;(function ($, window, undefined){
13000  'use strict';
13001
13002  $.fn.foundationAccordion = function (options) {
13003
13004    // DRY up the logic used to determine if the event logic should execute.
13005    var hasHover = function(accordion) {
13006      return accordion.hasClass('hover') && !Modernizr.touch
13007    };
13008
13009    $(document).on('mouseenter', '.accordion li', function () {
13010        var p = $(this).parent();
13011
13012        if (hasHover(p)) {
13013          var flyout = $(this).children('.content').first();
13014
13015          $('.content', p).not(flyout).hide().parent('li').removeClass('active');
13016          flyout.show(0, function () {
13017            flyout.parent('li').addClass('active');
13018          });
13019        }
13020      }
13021    );
13022
13023    $(document).on('click.fndtn', '.accordion li .title', function () {
13024        var li = $(this).closest('li'),
13025            p = li.parent();
13026
13027        if(!hasHover(p)) {
13028          var flyout = li.children('.content').first();
13029
13030          if (li.hasClass('active')) {
13031            p.find('li').removeClass('active').end().find('.content').hide();
13032          } else {
13033            $('.content', p).not(flyout).hide().parent('li').removeClass('active');
13034            flyout.show(0, function () {
13035              flyout.parent('li').addClass('active');
13036            });
13037          }
13038        }
13039      }
13040     );
13041
13042  };
13043
13044})( jQuery, this );
13045
13046;(function ($, window, undefined) {
13047  'use strict';
13048
13049  $.fn.foundationButtons = function (options) {
13050    var $doc = $(document),
13051        config = $.extend({
13052          dropdownAsToggle:false,
13053          activeClass:'active'
13054        }, options),
13055
13056    // close all dropdowns except for the dropdown passed
13057      closeDropdowns = function (dropdown) {
13058        // alert(dropdown.html());
13059        $('.button.dropdown').find('ul').not(dropdown).removeClass('show-dropdown');
13060      },
13061    // reset all toggle states except for the button passed
13062      resetToggles = function (button) {
13063        // alert(button.html());
13064        var buttons = $('.button.dropdown').not(button);
13065        buttons.add($('> span.' + config.activeClass, buttons)).removeClass(config.activeClass);
13066      };
13067
13068    // Prevent event propagation on disabled buttons
13069    $doc.on('click.fndtn', '.button.disabled', function (e) {
13070      e.preventDefault();
13071    });
13072
13073    $('.button.dropdown > ul', this).addClass('no-hover');
13074
13075    // reset other active states
13076    $doc.on('click.fndtn', '.button.dropdown:not(.split), .button.dropdown.split span', function (e) {
13077      var $el = $(this),
13078          button = $el.closest('.button.dropdown'),
13079          dropdown = $('> ul', button);
13080          
13081        // If the click is registered on an actual link or on button element then do not preventDefault which stops the browser from following the link
13082        if ($.inArray(e.target.nodeName, ['A', 'BUTTON'])){
13083          e.preventDefault();
13084        }
13085
13086      // close other dropdowns
13087      setTimeout(function () {
13088        closeDropdowns(config.dropdownAsToggle ? '' : dropdown);
13089        dropdown.toggleClass('show-dropdown');
13090
13091        if (config.dropdownAsToggle) {
13092          resetToggles(button);
13093          $el.toggleClass(config.activeClass);
13094        }
13095      }, 0);
13096    });
13097
13098    // close all dropdowns and deactivate all buttons
13099    $doc.on('click.fndtn', 'body, html', function (e) {
13100      if (undefined == e.originalEvent) { return; }
13101      // check original target instead of stopping event propagation to play nice with other events
13102      if (!$(e.originalEvent.target).is('.button.dropdown:not(.split), .button.dropdown.split span')) {
13103        closeDropdowns();
13104        if (config.dropdownAsToggle) {
13105          resetToggles();
13106        }
13107      }
13108    });
13109
13110    // Positioning the Flyout List
13111    var normalButtonHeight  = $('.button.dropdown:not(.large):not(.small):not(.tiny):visible', this).outerHeight() - 1,
13112        largeButtonHeight   = $('.button.large.dropdown:visible', this).outerHeight() - 1,
13113        smallButtonHeight   = $('.button.small.dropdown:visible', this).outerHeight() - 1,
13114        tinyButtonHeight    = $('.button.tiny.dropdown:visible', this).outerHeight() - 1;
13115
13116    $('.button.dropdown:not(.large):not(.small):not(.tiny) > ul', this).css('top', normalButtonHeight);
13117    $('.button.dropdown.large > ul', this).css('top', largeButtonHeight);
13118    $('.button.dropdown.small > ul', this).css('top', smallButtonHeight);
13119    $('.button.dropdown.tiny > ul', this).css('top', tinyButtonHeight);
13120
13121    $('.button.dropdown.up:not(.large):not(.small):not(.tiny) > ul', this).css('top', 'auto').css('bottom', normalButtonHeight - 2);
13122    $('.button.dropdown.up.large > ul', this).css('top', 'auto').css('bottom', largeButtonHeight - 2);
13123    $('.button.dropdown.up.small > ul', this).css('top', 'auto').css('bottom', smallButtonHeight - 2);
13124    $('.button.dropdown.up.tiny > ul', this).css('top', 'auto').css('bottom', tinyButtonHeight - 2);
13125
13126  };
13127
13128})( jQuery, this );
13129/*
13130 * jQuery Foundation Tooltips 2.0.2
13131 * http://foundation.zurb.com
13132 * Copyright 2012, ZURB
13133 * Free to use under the MIT license.
13134 * http://www.opensource.org/licenses/mit-license.php
13135*/
13136
13137/*jslint unparam: true, browser: true, indent: 2 */
13138
13139
13140;(function ($, window, undefined) {
13141  'use strict';
13142  
13143  var settings = {
13144      bodyHeight : 0,
13145      selector : '.has-tip',
13146      additionalInheritableClasses : [],
13147      tooltipClass : '.tooltip',
13148      tipTemplate : function (selector, content) {
13149        return '<span data-selector="' + selector + '" class="' + settings.tooltipClass.substring(1) + '">' + content + '<span class="nub"></span></span>';
13150      }
13151    },
13152    methods = {
13153      init : function (options) {
13154        settings = $.extend(settings, options);
13155
13156        // alias the old targetClass option
13157        settings.selector = settings.targetClass ? settings.targetClass : settings.selector;
13158
13159        return this.each(function () {
13160          var $body = $('body');
13161
13162          if (Modernizr.touch) {
13163            $body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.selector, function (e) {
13164              e.preventDefault();
13165              $(settings.tooltipClass).hide();
13166              methods.showOrCreateTip($(this));
13167            });
13168            $body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.tooltipClass, function (e) {
13169              e.preventDefault();
13170              $(this).fadeOut(150);
13171            });
13172          } else {
13173            $body.on('mouseenter.tooltip mouseleave.tooltip', settings.selector, function (e) {
13174              var $this = $(this);
13175
13176              if (e.type === 'mouseenter') {
13177                methods.showOrCreateTip($this);
13178              } else if (e.type === 'mouseleave') {
13179                methods.hide($this);
13180              }
13181            });
13182          }
13183
13184          $(this).data('tooltips', true);
13185
13186        });
13187      },
13188      showOrCreateTip : function ($target, content) {
13189        var $tip = methods.getTip($target);
13190
13191        if ($tip && $tip.length > 0) {
13192          methods.show($target);
13193        } else {
13194          methods.create($target, content);
13195        }
13196      },
13197      getTip : function ($target) {
13198        var selector = methods.selector($target),
13199          tip = null;
13200
13201        if (selector) {
13202          tip = $('span[data-selector=' + selector + ']' + settings.tooltipClass);
13203        }
13204        return (tip.length > 0) ? tip : false;
13205      },
13206      selector : function ($target) {
13207        var id = $target.attr('id'),
13208          dataSelector = $target.data('selector');
13209
13210        if (id === undefined && dataSelector === undefined) {
13211          dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
13212          $target.attr('data-selector', dataSelector);
13213        }
13214        return (id) ? id : dataSelector;
13215      },
13216      create : function ($target, content) {
13217        var $tip = $(settings.tipTemplate(methods.selector($target),
13218          $('<div>').html(content ? content : $target.attr('title')).html())),
13219          classes = methods.inheritable_classes($target);
13220
13221        $tip.addClass(classes).appendTo('body');
13222        if (Modernizr.touch) {
13223          $tip.append('<span class="tap-to-close">tap to close </span>');
13224        }
13225        $target.removeAttr('title');
13226        methods.show($target);
13227      },
13228      reposition : function (target, tip, classes) {
13229        var width, nub, nubHeight, nubWidth, column, objPos;
13230
13231        tip.css('visibility', 'hidden').show();
13232
13233        width = target.data('width');
13234        nub = tip.children('.nub');
13235        nubHeight = nub.outerHeight();
13236        nubWidth = nub.outerWidth();
13237
13238        objPos = function (obj, top, right, bottom, left, width) {
13239          return obj.css({
13240            'top' : top,
13241            'bottom' : bottom,
13242            'left' : left,
13243            'right' : right,
13244            'max-width' : (width) ? width : 'auto'
13245          }).end();
13246        };
13247
13248        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
13249        objPos(nub, -nubHeight, 'auto', 'auto', 10);
13250
13251        if ($(window).width() < 767) {
13252          if (target.data('mobile-width')) {
13253            tip.width(target.data('mobile-width')).css('left', 15).addClass('tip-override');
13254          } else {
13255            column = target.closest('.columns');
13256            if (column.length < 0) {
13257              // if not using Foundation
13258              column = $('body');
13259            }
13260            if (column.outerWidth()) {
13261              tip.width(column.outerWidth() - 25).css('left', 15).addClass('tip-override');
13262            } else {
13263              var tmp_width = Math.ceil($(window).width() * 0.9);
13264              tip.width(tmp_width).css('left', 15).addClass('tip-override');
13265            }
13266          }
13267          objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
13268        } else {
13269          if (classes && classes.indexOf('tip-top') > -1) {
13270            objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', target.offset().left, width)
13271              .removeClass('tip-override');
13272            objPos(nub, 'auto', 'auto', -nubHeight, 'auto');
13273          } else if (classes && classes.indexOf('tip-left') > -1) {
13274            objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left - tip.outerWidth() - 10), width)
13275              .removeClass('tip-override');
13276            objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -nubHeight, 'auto', 'auto');
13277          } else if (classes && classes.indexOf('tip-right') > -1) {
13278            objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width)
13279              .removeClass('tip-override');
13280            objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -nubHeight);
13281          } else if (classes && classes.indexOf('tip-centered-top') > -1) {
13282            objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', (target.offset().left + ((target.outerWidth() - tip.outerWidth()) / 2) ), width)
13283              .removeClass('tip-override');
13284            objPos(nub, 'auto', ((tip.outerWidth() / 2) -(nubHeight / 2)), -nubHeight, 'auto');
13285          } else if (classes && classes.indexOf('tip-centered-bottom') > -1) {
13286            objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', (target.offset().left + ((target.outerWidth() - tip.outerWidth()) / 2) ), width)
13287              .removeClass('tip-override');
13288            objPos(nub, -nubHeight, ((tip.outerWidth() / 2) -(nubHeight / 2)), 'auto', 'auto');
13289          }
13290        }
13291        tip.css('visibility', 'visible').hide();
13292      },
13293      inheritable_classes : function (target) {
13294        var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'tip-centered-top', 'tip-centered-bottom', 'noradius'].concat(settings.additionalInheritableClasses),
13295          classes = target.attr('class'),
13296          filtered = classes ? $.map(classes.split(' '), function (el, i) {
13297              if ($.inArray(el, inheritables) !== -1) {
13298                return el;
13299              }
13300          }).join(' ') : '';
13301          
13302        return $.trim(filtered);
13303      },
13304      show : function ($target) {
13305        var $tip = methods.getTip($target);
13306
13307        methods.reposition($target, $tip, $target.attr('class'));
13308        $tip.fadeIn(150);
13309      },
13310      hide : function ($target) {
13311        var $tip = methods.getTip($target);
13312
13313        $tip.fadeOut(150);
13314      },
13315      reload : function () {
13316        var $self = $(this);
13317
13318        return ($self.data('tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
13319      },
13320      destroy : function () {
13321        return this.each(function () {
13322          $(window).off('.tooltip');
13323          $(settings.selector).off('.tooltip');
13324          $(settings.tooltipClass).each(function (i) {
13325            $($(settings.selector).get(i)).attr('title', $(this).text());
13326          }).remove();
13327        });
13328      }
13329    };
13330
13331  $.fn.foundationTooltips = function (method) {
13332    if (methods[method]) {
13333      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
13334    } else if (typeof method === 'object' || !method) {
13335      return methods.init.apply(this, arguments);
13336    } else {
13337      $.error('Method ' +  method + ' does not exist on jQuery.foundationTooltips');
13338    }
13339  };
13340}(jQuery, this));
13341/*
13342 * jQuery Custom Forms Plugin 1.0
13343 * www.ZURB.com
13344 * Copyright 2010, ZURB
13345 * Free to use under the MIT license.
13346 * http://www.opensource.org/licenses/mit-license.php
13347*/
13348
13349
13350(function( $ ){
13351
13352  /**
13353   * Helper object used to quickly adjust all hidden parent element's, display and visibility properties.
13354   * This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal
13355   * we cannot accurately determine the list-item elements width property, since the modal'
13355s display property is set
13356   * to 'none'.
13357   *
13358   * This object will help us work around that problem.
13359   *
13360   * NOTE: This could also be plugin.
13361   *
13362   * @function hiddenFix
13363   */
13364  var hiddenFix = function() {
13365
13366    return {
13367      /**
13368       * Sets all hidden parent elements and self to visibile.
13369       *
13370       * @method adjust
13371       * @param {jQuery Object} $child
13372       */
13373
13374      // We'll use this to temporarily store style properties.
13375      tmp : [],
13376
13377      // We'll use this to set hidden parent elements.
13378      hidden : null,
13379
13380      adjust : function( $child ) {
13381        // Internal reference.
13382        var _self = this;
13383
13384        // Set all hidden parent elements, including this element.
13385        _self.hidden = $child.parents().andSelf().filter( ":hidden" );
13386
13387        // Loop through all hidden elements.
13388        _self.hidden.each( function() {
13389
13390          // Cache the element.
13391          var $elem = $( this );
13392
13393          // Store the style attribute.
13394          // Undefined if element doesn't have a style attribute.
13395          _self.tmp.push( $elem.attr( 'style' ) );
13396
13397          // Set the element's display property to block,
13398          // but ensure it's visibility is hidden.
13399          $elem.css( { 'visibility' : 'hidden', 'display' : 'block' } );
13400        });
13401
13402      }, // end adjust
13403
13404      /**
13405       * Resets the elements previous state.
13406       *
13407       * @method reset
13408       */
13409      reset : function() {
13410        // Internal reference.
13411        var _self = this;
13412        // Loop through our hidden element collection.
13413        _self.hidden.each( function( i ) {
13414          // Cache this element.
13415          var $elem = $( this ),
13416              _tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element.
13417
13418          // If the stored value is undefined.
13419          if( _tmp === undefined )
13420            // Remove the style attribute.
13421            $elem.removeAttr( 'style' );
13422          else
13423            // Otherwise, reset the element style attribute.
13424            $elem.attr( 'style', _tmp );
13425
13426        });
13427        // Reset the tmp array.
13428        _self.tmp = [];
13429        // Reset the hidden elements variable.
13430        _self.hidden = null;
13431
13432      } // end reset
13433
13434    }; // end return
13435
13436  };
13437
13438  jQuery.foundation = jQuery.foundation || {};
13439  jQuery.foundation.customForms = jQuery.foundation.customForms || {};
13440
13441  $.foundation.customForms.appendCustomMarkup = function ( options ) {
13442
13443    var defaults = {
13444      disable_class: "no-custom"
13445    };
13446
13447    options = $.extend( defaults, options );
13448
13449    function appendCustomMarkup(idx, sel) {
13450      var $this = $(sel).hide(),
13451          type  = $this.attr('type'),
13452          $span = $this.next('span.custom.' + type);
13453
13454      if ($span.length === 0) {
13455        $span = $('<span class="custom ' + type + '"></span>').insertAfter($this);
13456      }
13457
13458      $span.toggleClass('checked', $this.is(':checked'));
13459      $span.toggleClass('disabled', $this.is(':disabled'));
13460    }
13461
13462    function appendCustomSelect(idx, sel) {
13463      var hiddenFixObj = hiddenFix();
13464          //
13465          // jQueryify the <select> element and cache it.
13466          //
13467      var $this = $( sel ),
13468          //
13469          // Find the custom drop down element.
13470          //
13471          $customSelect = $this.next( 'div.custom.dropdown' ),
13472          //
13473          // Find the custom select element within the custom drop down.
13474          //
13475          $customList = $customSelect.find( 'ul' ),
13476          //
13477          // Find the custom a.current element.
13478          //
13479          $selectCurrent = $customSelect.find( ".current" ),
13480          //
13481          // Find the custom a.selector element (the drop-down icon).
13482          //
13483          $selector = $customSelect.find( ".selector" ),
13484          //
13485          // Get the <options> from the <select> element.
13486          //
13487          $options = $this.find( 'option' ),
13488          //
13489          // Filter down the selected options
13490          //
13491          $selectedOption = $options.filter( ':selected' ),
13492          //
13493          // Initial max width.
13494          //
13495          maxWidth = 0,
13496          //
13497          // We'll use this variable to create the <li> elements for our custom select.
13498          //
13499          liHtml = '',
13500          //
13501          // We'll use this to cache the created <li> elements within our custom select.
13502          //
13503          $listItems
13504      ;
13505      var $currentSelect = false;
13506      //
13507      // Should we not create a custom list?
13508      //
13509      if ( $this.hasClass( options.disable_class ) ) return;
13510
13511      //
13512      // Did we not create a custom select element yet?
13513      //
13514      if ( $customSelect.length === 0 ) {
13515        //
13516        // Let's create our custom select element!
13517        //
13518
13519            //
13520            // Determine what select size to use.
13521            //
13522        var customSelectSize = $this.hasClass( 'small' )   ? 'small'   :
13523                               $this.hasClass( 'medium' )  ? 'medium'  :
13524                               $this.hasClass( 'large' )   ? 'large'   :
13525                               $this.hasClass( 'expand' )  ? 'expand'  : ''
13526        ;
13527        //
13528        // Build our custom list.
13529        //
13530        $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>');
13531        //
13532        // Grab the selector element
13533        //
13534        $selector = $customSelect.find( ".selector" );
13535        //
13536        // Grab the unordered list element from the custom list.
13537        //
13538        $customList = $customSelect.find( "ul" );
13539        //
13540        // Build our <li> elements.
13541        //
13542        liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
13543        //
13544        // Append our <li> elements to the custom list (<ul>).
13545        //
13546        $customList.append( liHtml );
13547        //
13548        // Insert the the currently selected list item before all other elements.
13549        // Then, find the element and assign it to $currentSelect.
13550        //
13551
13552        $currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
13553        //
13554        // Add the custom select element after the <select> element.
13555        //
13556        $this.after( $customSelect )
13557        //
13558        //then hide the <select> element.
13559        //
13560        .hide();
13561
13562      } else {
13563        //
13564        // Create our list item <li> elements.
13565        //
13566        liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
13567        //
13568        // Refresh the ul with options from the select in case the supplied markup doesn't match.
13569        // Clear what's currently in the <ul> element.
13570        //
13571        $customList.html( '' )
13572        //
13573        // Populate the list item <li> elements.
13574        //
13575        .append( liHtml );
13576
13577      } // endif $customSelect.length === 0
13578
13579      //
13580      // Determine whether or not the custom select element should be disabled.
13581      //
13582      $customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) );
13583      //
13584      // Cache our List item elements.
13585      //
13586      $listItems = $customList.find( 'li' );
13587
13588      //
13589      // Determine which elements to select in our custom list.
13590      //
13591      $options.each( function ( index ) {
13592
13593        if ( this.selected ) {
13594          //
13595          // Add the selected class to the current li element
13596          //
13597          $listItems.eq( index ).addClass( 'selected' );
13598          //
13599          // Update the current element with the option value.
13600          //
13601          if ($currentSelect) {
13602            $currentSelect.html( $( this ).html() );
13603          }
13604
13605        }
13606
13607      });
13608
13609      //
13610      // Update the custom <ul> list width property.
13611      //
13612      $customList.css( 'width', 'auto' );
13613      //
13614      // Set the custom select width property.
13615      //
13616      $customSelect.css( 'width', 'auto' );
13617
13618      //
13619      // If we're not specifying a predetermined form size.
13620      //
13621      if ( !$customSelect.is( '.small, .medium, .large, .expand' ) ) {
13622
13623        // ------------------------------------------------------------------------------------
13624        // This is a work-around for when elements are contained within hidden parents.
13625        // For example, when custom-form elements are inside of a hidden reveal modal.
13626        //
13627        // We need to display the current custom list element as well as hidden parent elements
13628        // in order to properly calculate the list item element's width property.
13629        // -------------------------------------------------------------------------------------
13630
13631        //
13632        // Show the drop down.
13633        // This should ensure that the list item's width values are properly calculated.
13634        //
13635        $customSelect.addClass( 'open' );
13636        //
13637        // Quickly, display all parent elements.
13638        // This should help us calcualate the width of the list item's within the drop down.
13639        //
13640        hiddenFixObj.adjust( $customList );
13641        //
13642        // Grab the largest list item width.
13643        //
13644        maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth;
13645        //
13646        // Okay, now reset the parent elements.
13647        // This will hide them again.
13648        //
13649        hiddenFixObj.reset();
13650        //
13651        // Finally, hide the drop down.
13652        //
13653        $customSelect.removeClass( 'open' );
13654        //
13655        // Set the custom list width.
13656        //
13657        $customSelect.width( maxWidth + 18);
13658        //
13659        // Set the custom list element (<ul />) width.
13660        //
13661        $customList.width(  maxWidth + 16 );
13662
13663      } // endif
13664
13665    }
13666
13667    $('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup);
13668    $('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup);
13669    $('form.custom select[data-customforms!=disabled]').each(appendCustomSelect);
13670  };
13671
13672  var refreshCustomSelect = function($select) {
13673    var maxWidth = 0,
13674        $customSelect = $select.next();
13675    $options = $select.find('option');
13676    $customSelect.find('ul').html('');
13677
13678    $options.each(function () {
13679      $li = $('<li>' + $(this).html() + '</li>');
13680      $customSelect.find('ul').append($li);
13681    });
13682
13683    // re-populate
13684    $options.each(function (index) {
13685      if (this.selected) {
13686        $customSelect.find('li').eq(index).addClass('selected');
13687        $customSelect.find('.current').html($(this).html());
13688      }
13689    });
13690
13691    // fix width
13692    $customSelect.removeAttr('style')
13693      .find('ul').removeAttr('style');
13694    $customSelect.find('li').each(function () {
13695      $customSelect.addClass('open');
13696      if ($(this).outerWidth() > maxWidth) {
13697        maxWidth = $(this).outerWidth();
13698      }
13699      $customSelect.removeClass('open');
13700    });
13701    $customSelect.css('width', maxWidth + 18 + 'px');
13702    $customSelect.find('ul').css('width', maxWidth + 16 + 'px');
13703
13704  };
13705
13706  var toggleCheckbox = function($element) {
13707    var $input = $element.prev(),
13708        input = $input[0];
13709
13710    if (false === $input.is(':disabled')) {
13711        input.checked = ((input.checked) ? false : true);
13712        $element.toggleClass('checked');
13713
13714        $input.trigger('change');
13715    }
13716  };
13717
13718  var toggleRadio = function($element) {
13719    var $input = $element.prev(),
13720        $form = $input.closest('form.custom'),
13721        input = $input[0];
13722
13723    if (false === $input.is(':disabled')) {
13724      $form.find('input:radio[name="' + $input.attr('name') + '"]').next().not($element).removeClass('checked');
13725      if ( !$element.hasClass('checked') ) {
13726        $element.toggleClass('checked');
13727      }
13728      input.checked = $element.hasClass('checked');
13729
13730      $input.trigger('change');
13731    }
13732  };
13733
13734  $(document).on('click', 'form.custom span.custom.checkbox', function (event) {
13735    event.preventDefault();
13736    event.stopPropagation();
13737
13738    toggleCheckbox($(this));
13739  });
13740
13741  $(document).on('click', 'form.custom span.custom.radio', function (event) {
13742    event.preventDefault();
13743    event.stopPropagation();
13744
13745    toggleRadio($(this));
13746  });
13747
13748  $(document).on('change', 'form.custom select[data-customforms!=disabled]', function (event) {
13749    refreshCustomSelect($(this));
13750  });
13751
13752  $(document).on('click', 'form.custom label', function (event) {
13753    var $associatedElement = $('#' + $(this).attr('for') + '[data-customforms!=disabled]'),
13754        $customCheckbox,
13755        $customRadio;
13756    if ($associatedElement.length !== 0) {
13757      if ($associatedElement.attr('type') === 'checkbox') {
13758        event.preventDefault();
13759        $customCheckbox = $(this).find('span.custom.checkbox');
13760        //the checkbox might be outside after the label
13761        if ($customCheckbox.length == 0) {
13762            $customCheckbox = $(this).next('span.custom.checkbox');
13763        }
13764        //the checkbox might be outside before the label
13765        if ($customCheckbox.length == 0) {
13766            $customCheckbox = $(this).prev('span.custom.checkbox');
13767        }
13768        toggleCheckbox($customCheckbox);
13769      } else if ($associatedElement.attr('type') === 'radio') {
13770        event.preventDefault();
13771        $customRadio = $(this).find('span.custom.radio');
13772        //the radio might be outside after the label
13773        if ($customRadio.length == 0) {
13774            $customRadio = $(this).next('span.custom.radio');
13775        }
13776        //the radio might be outside before the label
13777        if ($customRadio.length == 0) {
13778            $customRadio = $(this).prev('span.custom.radio');
13779        }
13780        toggleRadio($customRadio);
13781      }
13782    }
13783  });
13784
13785  $(document).on('click', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (event) {
13786    var $this = $(this),
13787        $dropdown = $this.closest('div.custom.dropdown'),
13788        $select = $dropdown.prev();
13789
13790    event.preventDefault();
13791    $('div.dropdown').removeClass('open');
13792
13793    if (false === $select.is(':disabled')) {
13794        $dropdown.toggleClass('open');
13795
13796        if ($dropdown.hasClass('open')) {
13797          $(document).bind('click.customdropdown', function (event) {
13798            $dropdown.removeClass('open');
13799            $(document).unbind('.customdropdown');
13800          });
13801        } else {
13802          $(document).unbind('.customdropdown');
13803        }
13804        return false;
13805    }
13806  });
13807
13808  $(document).on('click', 'form.custom div.custom.dropdown li', function (event) {
13809    var $this = $(this),
13810        $customDropdown = $this.closest('div.custom.dropdown'),
13811        $select = $customDropdown.prev(),
13812        selectedIndex = 0;
13813
13814    event.preventDefault();
13815    event.stopPropagation();
13816    $('div.dropdown').removeClass('open');
13817
13818    $this
13819      .closest('ul')
13820      .find('li')
13821      .removeClass('selected');
13822    $this.addClass('selected');
13823
13824    $customDropdown
13825      .removeClass('open')
13826      .find('a.current')
13827      .html($this.html());
13828
13829    $this.closest('ul').find('li').each(function (index) {
13830      if ($this[0] == this) {
13831        selectedIndex = index;
13832      }
13833
13834    });
13835    $select[0].selectedIndex = selectedIndex;
13836
13837    $select.trigger('change');
13838  });
13839
13840
13841  $.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup;
13842
13843})( jQuery );
13844;(function ($, window, document, undefined) {
13845  'use strict';
13846
13847  var settings = {
13848        callback: $.noop,
13849        deep_linking: true,
13850        init: false
13851      },
13852
13853      methods = {
13854        init : function (options) {
13855          settings = $.extend({}, settings, options);
13856
13857          return this.each(function () {
13858            if (!settings.init) methods.events();
13859
13860            if (settings.deep_linking) methods.from_hash();
13861          });
13862        },
13863
13864        events : function () {
13865          $(document).on('click.fndtn', '.tabs a', function (e) {
13866            methods.set_tab($(this).parent('dd, li'), e);
13867          });
13868          
13869          settings.init = true;
13870        },
13871
13872        set_tab : function ($tab, e) {
13873          var $activeTab = $tab.closest('dl, ul').find('.active'),
13874              target = $tab.children('a').attr("href"),
13875              hasHash = /^#/.test(target),
13876              $content = $(target + 'Tab');
13877
13878          if (hasHash && $content.length > 0) {
13879            // Show tab content
13880            if (e && !settings.deep_linking) e.preventDefault();
13881            $content.closest('.tabs-content').children('li').removeClass('active').hide();
13882            $content.css('display', 'block').addClass('active');
13883          }
13884
13885          // Make active tab
13886          $activeTab.removeClass('active');
13887          $tab.addClass('active');
13888
13889          settings.callback();
13890        },
13891
13892        from_hash : function () {
13893          var hash = window.location.hash,
13894              $tab = $('a[href="' + hash + '"]');
13895
13896          $tab.trigger('click.fndtn');
13897        }
13898      }
13899
13900  $.fn.foundationTabs = function (method) {
13901    if (methods[method]) {
13902      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
13903    } else if (typeof method === 'object' || !method) {
13904      return methods.init.apply(this, arguments);
13905    } else {
13906      $.error('Method ' +  method + ' does not exist on jQuery.foundationTabs');
13907    }
13908  };
13909}(jQuery, this, this.document));
13910;(function ($, window, undefined) {
13911  'use strict';
13912
13913  $.fn.foundationNavigation = function (options) {
13914
13915    var lockNavBar = false;
13916    // Windows Phone, sadly, does not register touch events :(
13917    if (Modernizr.touch || navigator.userAgent.match(/Windows Phone/i)) {
13918      $(document).on('click.fndtn touchstart.fndtn', '.nav-bar a.flyout-toggle', function (e) {
13919        e.preventDefault();
13920        var flyout = $(this).siblings('.flyout').first();
13921        if (lockNavBar === false) {
13922          $('.nav-bar .flyout').not(flyout).slideUp(500);
13923          flyout.slideToggle(500, function () {
13924            lockNavBar = false;
13925          });
13926        }
13927        lockNavBar = true;
13928      });
13929      $('.nav-bar>li.has-flyout', this).addClass('is-touch');
13930    } else {
13931      $('.nav-bar>li.has-flyout', this).on('mouseenter mouseleave', function (e) {
13932        if (e.type == 'mouseenter') {
13933          $('.nav-bar').find('.flyout').hide();
13934          $(this).children('.flyout').show();
13935        }
13936
13937        if (e.type == 'mouseleave') {
13938          var flyout = $(this).children('.flyout'),
13939              inputs = flyout.find('input'),
13940              hasFocus = function (inputs) {
13941                var focus;
13942                if (inputs.length > 0) {
13943                  inputs.each(function () {
13944                    if ($(this).is(":focus")) {
13945                      focus = true;
13946                    }
13947                  });
13948                  return focus;
13949                }
13950
13951                return false;
13952              };
13953
13954          if (!hasFocus(inputs)) {
13955            $(this).children('.flyout').hide();
13956          }
13957        }
13958
13959      });
13960    }
13961
13962  };
13963
13964})( jQuery, this );
13965/*
13966 * jQuery Foundation Top Bar 2.0.4
13967 * http://foundation.zurb.com
13968 * Copyright 2012, ZURB
13969 * Free to use under the MIT license.
13970 * http://www.opensource.org/licenses/mit-license.php
13971*/
13972
13973/*jslint unparam: true, browser: true, indent: 2 */
13974
13975
13976;(function ($, window, undefined) {
13977  'use strict';
13978
13979  var settings = {
13980      index : 0,
13981      initialized : false
13982    },
13983
13984    methods = {
13985      init : function (options) {
13986        return this.each(function () {
13987          settings = $.extend(settings, options);
13988          settings.$w = $(window),
13989          settings.$topbar = $('nav.top-bar'),
13990          settings.$section = settings.$topbar.find('section'),
13991          settings.$titlebar = settings.$topbar.children('ul:first');
13992
13993          var breakpoint = $("<div class='top-bar-js-breakpoint'/>").appendTo("body");
13994          settings.breakPoint = breakpoint.width();
13995          breakpoint.remove();
13996
13997          if (!settings.initialized) {
13998            methods.assemble();
13999            settings.initialized = true;
14000          }
14001
14002          if (!settings.height) {
14003            methods.largestUL();
14004          }
14005
14006          if (settings.$topbar.parent().hasClass('fixed')) {
14007            $('body').css('padding-top',settings.$topbar.outerHeight())
14008          }
14009
14010          $('.top-bar .toggle-topbar').off('click.fndtn').on('click.fndtn', function (e) {
14011            e.preventDefault();
14012
14013            if (methods.breakpoint()) {
14014              settings.$topbar.toggleClass('expanded');
14015              settings.$topbar.css('min-height', '');
14016            }
14017
14018            if (!settings.$topbar.hasClass('expanded')) {
14019              settings.$section.css({left: '0%'});
14020              settings.$section.find('>.name').css({left: '100%'});
14021              settings.$section.find('li.moved').removeClass('moved');
14022              settings.index = 0;
14023            }
14024          });
14025
14026          // Show the Dropdown Levels on Click
14027          $('.top-bar .has-dropdown>a').off('click.fndtn').on('click.fndtn', function (e) {
14028            if (Modernizr.touch || methods.breakpoint())
14029              e.preventDefault();
14030
14031            if (methods.breakpoint()) {
14032              var $this = $(this),
14033                  $selectedLi = $this.closest('li');
14034
14035              settings.index += 1;
14036              $selectedLi.addClass('moved');
14037              settings.$section.css({left: -(100 * settings.index) + '%'});
14038              settings.$section.find('>.name').css({left: 100 * settings.index + '%'});
14039
14040              $this.siblings('ul').height(settings.height + settings.$titlebar.outerHeight(true));
14041              settings.$topbar.css('min-height', settings.height + settings.$titlebar.outerHeight(true) * 2)
14042            }
14043          });
14044
14045          $(window).on('resize.fndtn.topbar',function() {
14046            if (!methods.breakpoint()) {
14047              settings.$topbar.css('min-height', '');
14048            }
14049          });
14050
14051          // Go up a level on Click
14052          $('.top-bar .has-dropdown .back').off('click.fndtn').on('click.fndtn', function (e) {
14053            e.preventDefault();
14054
14055            var $this = $(this),
14056              $movedLi = $this.closest('li.moved'),
14057              $previousLevelUl = $movedLi.parent();
14058
14059            settings.index -= 1;
14060            settings.$section.css({left: -(100 * settings.index) + '%'});
14061            settings.$section.find('>.name').css({'left': 100 * settings.index + '%'});
14062
14063            if (settings.index === 0) {
14064              settings.$topbar.css('min-height', 0);
14065            }
14066
14067            setTimeout(function () {
14068              $movedLi.removeClass('moved');
14069            }, 300);
14070          });
14071        });
14072      },
14073
14074      breakpoint : function () {
14075        return settings.$w.width() < settings.breakPoint;
14076      },
14077
14078      assemble : function () {
14079        // Pull element out of the DOM for manipulation
14080        settings.$section.detach();
14081
14082        settings.$section.find('.has-dropdown>a').each(function () {
14083          var $link = $(this),
14084              $dropdown = $link.siblings('.dropdown'),
14085              $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li>');
14086
14087          // Copy link to subnav
14088          $titleLi.find('h5>a').html($link.html());
14089          $dropdown.prepend($titleLi);
14090        });
14091
14092        // Put element back in the DOM
14093        settings.$section.appendTo(settings.$topbar);
14094      },
14095
14096      largestUL : function () {
14097        var uls = settings.$topbar.find('section ul ul'),
14098            largest = uls.first(),
14099            total = 0;
14100
14101        uls.each(function () {
14102          if ($(this).children('li').length > largest.children('li').length) {
14103            largest = $(this);
14104          }
14105        });
14106
14107        largest.children('li').each(function () { total += $(this).outerHeight(true); });
14108
14109        settings.height = total;
14110      }
14111    };
14112
14113  $.fn.foundationTopBar = function (method) {
14114    if (methods[method]) {
14115      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
14116    } else if (typeof method === 'object' || !method) {
14117      return methods.init.apply(this, arguments);
14118    } else {
14119      $.error('Method ' +  method + ' does not exist on jQuery.foundationTopBar');
14120    }
14121  };
14122
14123  // Monitor scroll position for sticky
14124  if ($('.sticky').length > 0) {
14125    var distance = $('.sticky').length ? $('.sticky').offset().top: 0,
14126        $window = $(window);
14127
14128      $window.scroll(function() {
14129        if ( $window.scrollTop() >= distance ) {
14130           $(".sticky").addClass("fixed");
14131        }
14132
14133       else if ( $window.scrollTop() < distance ) {
14134          $(".sticky").removeClass("fixed");
14135       }
14136    });
14137  }
14138
14139}(jQuery, this));
14140/*
14141 * jQuery Reveal Plugin 1.1
14142 * www.ZURB.com
14143 * Copyright 2010, ZURB
14144 * Free to use under the MIT license.
14145 * http://www.opensource.org/licenses/mit-license.php
14146*/
14147/*globals jQuery */
14148
14149
14150(function ($) {
14151  'use strict';
14152  //
14153  // Global variable.
14154  // Helps us determine if the current modal is being queued for display.
14155  //
14156  var modalQueued = false;
14157
14158  //
14159  // Bind the live 'click' event to all anchor elemnets with the data-reveal-id attribute.
14160  //
14161  $(document).on('click', 'a[data-reveal-id]', function ( event ) {
14162    //
14163    // Prevent default action of the event.
14164    //
14165    event.preventDefault();
14166    //
14167    // Get the clicked anchor data-reveal-id attribute value.
14168    //
14169    var modalLocation = $( this ).attr( 'data-reveal-id' );
14170    //
14171    // Find the element with that modalLocation id and call the reveal plugin.
14172    //
14173    $( '#' + modalLocation ).reveal( $( this ).data() );
14174
14175  });
14176
14177  /**
14178   * @module reveal
14179   * @property {Object} [options] Reveal options
14180   */
14181  $.fn.reveal = function ( options ) {
14182      /*
14183       * Cache the document object.
14184       */
14185    var $doc = $( document ),
14186        /*
14187         * Default property values.
14188         */
14189        defaults = {
14190          /**
14191           * Possible options: fade, fadeAndPop, none
14192           *
14193           * @property animation
14194           * @type {String}
14195           * @default fadeAndPop
14196           */
14197          animation: 'fadeAndPop',
14198          /**
14199           * Speed at which the reveal should show. How fast animtions are.
14200           *
14201           * @property animationSpeed
14202           * @type {Integer}
14203           * @default 300
14204           */
14205          animationSpeed: 300,
14206          /**
14207           * Should the modal close when the background is clicked?
14208           *
14209           * @property closeOnBackgroundClick
14210           * @type {Boolean}
14211           * @default true
14212           */
14213          closeOnBackgroundClick: true,
14214          /**
14215           * Specify a class name for the 'close modal' element.
14216           * This element will close an open modal.
14217           *
14218           @example
14219           <a href='#close' class='close-reveal-modal'>Close Me</a>
14220           *
14221           * @property dismissModalClass
14222           * @type {String}
14223           * @default close-reveal-modal
14224           */
14225          dismissModalClass: 'close-reveal-modal',
14226          /**
14227           * Specify a callback function that triggers 'before' the modal opens.
14228           *
14229           * @property open
14230           * @type {Function}
14231           * @default function(){}
14232           */
14233          open: $.noop,
14234          /**
14235           * Specify a callback function that triggers 'after' the modal is opened.
14236           *
14237           * @property opened
14238           * @type {Function}
14239           * @default function(){}
14240           */
14241          opened: $.noop,
14242          /**
14243           * Specify a callback function that triggers 'before' the modal prepares to close.
14244           *
14245           * @property close
14246           * @type {Function}
14247           * @default function(){}
14248           */
14249          close: $.noop,
14250          /**
14251           * Specify a callback function that triggers 'after' the modal is closed.
14252           *
14253           * @property closed
14254           * @type {Function}
14255           * @default function(){}
14256           */
14257          closed: $.noop
14258        }
14259    ;
14260    //
14261    // Extend the default options.
14262    // This replaces the passed in option (options) values with default values.
14263    //
14264    options = $.extend( {}, defaults, options );
14265
14266    //
14267    // Apply the plugin functionality to each element in the jQuery collection.
14268    //
14269    return this.not('.reveal-modal.open').each( function () {
14270        //
14271        // Cache the modal element
14272        //
14273      var modal = $( this ),
14274        //
14275        // Get the current css 'top' property value in decimal format.
14276        //
14277        topMeasure = parseInt( modal.css( 'top' ), 10 ),
14278        //
14279        // Calculate the top offset.
14280        //
14281        topOffset = modal.height() + topMeasure,
14282        //
14283        // Helps determine if the modal is locked.
14284        // This way we keep the modal from triggering while it's in the middle of animating.
14285        //
14286        locked = false,
14287        //
14288        // Get the modal background element.
14289        //
14290        modalBg = $( '.reveal-modal-bg' ),
14291        //
14292        // Show modal properties
14293        //
14294        cssOpts = {
14295          //
14296          // Used, when we show the modal.
14297          //
14298          open : {
14299            //
14300            // Set the 'top' property to the document scroll minus the calculated top offset.
14301            //
14302            'top': 0,
14303            //
14304            // Opacity gets set to 0.
14305            //
14306            'opacity': 0,
14307            //
14308            // Show the modal
14309            //
14310            'visibility': 'visible',
14311            //
14312            // Ensure it's displayed as a block element.
14313            //
14314            'display': 'block'
14315          },
14316          //
14317          // Used, when we hide the modal.
14318          //
14319          close : {
14320            //
14321            // Set the default 'top' property value.
14322            //
14323            'top': topMeasure,
14324            //
14325            // Has full opacity.
14326            //
14327            'opacity': 1,
14328            //
14329            // Hide the modal
14330            //
14331            'visibility': 'hidden',
14332            //
14333            // Ensure the elment is hidden.
14334            //
14335            'display': 'none'
14336          }
14337
14338        },
14339        //
14340        // Initial closeButton variable.
14341        //
14342        $closeButton
14343      ;
14344
14345      //
14346      // Do we have a modal background element?
14347      //
14348      if ( modalBg.length === 0 ) {
14349        //
14350        // No we don't. So, let's create one.
14351        //
14352        modalBg = $( '<div />', { 'class' : 'reveal-modal-bg' } )
14353        //
14354        // Then insert it after the modal element.
14355        //
14356        .insertAfter( modal );
14357        //
14358        // Now, fade it out a bit.
14359        //
14360        modalBg.fadeTo( 'fast', 0.8 );
14361      }
14362
14363      //
14364      // Helper Methods
14365      //
14366
14367      /**
14368       * Unlock the modal for animation.
14369       *
14370       * @method unlockModal
14371       */
14372      function unlockModal() {
14373        locked = false;
14374      }
14375
14376      /**
14377       * Lock the modal to prevent further animation.
14378       *
14379       * @method lockModal
14380       */
14381      function lockModal() {
14382        locked = true;
14383      }
14384
14385      /**
14386       * Closes all open modals.
14387       *
14388       * @method closeOpenModal
14389       */
14390      function closeOpenModals() {
14391        //
14392        // Get all reveal-modal elements with the .open class.
14393        //
14394        var $openModals = $( ".reveal-modal.open" );
14395        //
14396        // Do we have modals to close?
14397        //
14398        if ( $openModals.length === 1 ) {
14399          //
14400          // Set the modals for animation queuing.
14401          //
14402          modalQueued = true;
14403          //
14404          // Trigger the modal close event.
14405          //
14406          $openModals.trigger( "reveal:close" );
14407        }
14408
14409      }
14410      /**
14411       * Animates the modal opening.
14412       * Handles the modal 'open' event.
14413       *
14414       * @method openAnimation
14415       */
14416      function openAnimation() {
14417        //
14418        // First, determine if we're in the middle of animation.
14419        //
14420        if ( !locked ) {
14421          //
14422          // We're not animating, let's lock the modal for animation.
14423          //
14424          lockModal();
14425          //
14426          // Close any opened modals.
14427          //
14428          closeOpenModals();
14429          //
14430          // Now, add the open class to this modal.
14431          //
14432          modal.addClass( "open" );
14433
14434          //
14435          // Are we executing the 'fadeAndPop' animation?
14436          //
14437          if ( options.animation === "fadeAndPop" ) {
14438            //
14439            // Yes, we're doing the 'fadeAndPop' animation.
14440            // Okay, set the modal css properties.
14441            //
14442            //
14443            // Set the 'top' property to the document scroll minus the calculated top offset.
14444            //
14445            cssOpts.open.top = $doc.scrollTop() - topOffset;
14446            //
14447            // Flip the opacity to 0.
14448            //
14449            cssOpts.open.opacity = 0;
14450            //
14451            // Set the css options.
14452            //
14453            modal.css( cssOpts.open );
14454            //
14455            // Fade in the background element, at half the speed of the modal element.
14456            // So, faster than the modal element.
14457            //
14458            modalBg.fadeIn( options.animationSpeed / 2 );
14459
14460            //
14461            // Let's delay the next animation queue.
14462            // We'll wait until the background element is faded in.
14463            //
14464            modal.delay( options.animationSpeed / 2 )
14465            //
14466            // Animate the following css properties.
14467            //
14468            .animate( {
14469              //
14470              // Set the 'top' property to the document scroll plus the calculated top measure.
14471              //
14472              "top": $doc.scrollTop() + topMeasure + 'px',
14473              //
14474              // Set it to full opacity.
14475              //
14476              "opacity": 1
14477
14478            },
14479            /*
14480             * Fade speed.
14481             */
14482            options.animationSpeed,
14483            /*
14484             * End of animation callback.
14485             */
14486            function () {
14487              //
14488              // Trigger the modal reveal:opened event.
14489              // This should trigger the functions set in the options.opened property.
14490              //
14491              modal.trigger( 'reveal:opened' );
14492
14493            }); // end of animate.
14494
14495          } // end if 'fadeAndPop'
14496
14497          //
14498          // Are executing the 'fade' animation?
14499          //
14500          if ( options.animation === "fade" ) {
14501            //
14502            // Yes, were executing 'fade'.
14503            // Okay, let's set the modal properties.
14504            //
14505            cssOpts.open.top = $doc.scrollTop() + topMeasure;
14506            //
14507            // Flip the opacity to 0.
14508            //
14509            cssOpts.open.opacity = 0;
14510            //
14511            // Set the css options.
14512            //
14513            modal.css( cssOpts.open );
14514            //
14515            // Fade in the modal background at half the speed of the modal.
14516            // So, faster than modal.
14517            //
14518            modalBg.fadeIn( options.animationSpeed / 2 );
14519
14520            //
14521            // Delay the modal animation.
14522            // Wait till the modal background is done animating.
14523            //
14524            modal.delay( options.animationSpeed / 2 )
14525            //
14526            // Now animate the modal.
14527            //
14528            .animate( {
14529              //
14530              // Set to full opacity.
14531              //
14532              "opacity": 1
14533            },
14534
14535            /*
14536             * Animation speed.
14537             */
14538            options.animationSpeed,
14539
14540            /*
14541             * End of animation callback.
14542             */
14543            function () {
14544              //
14545              // Trigger the modal reveal:opened event.
14546              // This should trigger the functions set in the options.opened property.
14547              //
14548              modal.trigger( 'reveal:opened' );
14549
14550            });
14551
14552          } // end if 'fade'
14553
14554          //
14555          // Are we not animating?
14556          //
14557          if ( options.animation === "none" ) {
14558            //
14559            // We're not animating.
14560            // Okay, let's set the modal css properties.
14561            //
14562            //
14563            // Set the top property.
14564            //
14565            cssOpts.open.top = $doc.scrollTop() + topMeasure;
14566            //
14567            // Set the opacity property to full opacity, since we're not fading (animating).
14568            //
14569            cssOpts.open.opacity = 1;
14570            //
14571            // Set the css property.
14572            //
14573            modal.css( cssOpts.open );
14574            //
14575            // Show the modal Background.
14576            //
14577            modalBg.css( { "display": "block" } );
14578            //
14579            // Trigger the modal opened event.
14580            //
14581            modal.trigger( 'reveal:opened' );
14582
14583          } // end if animating 'none'
14584
14585        }// end if !locked
14586
14587      }// end openAnimation
14588
14589
14590      function openVideos() {
14591        var video = modal.find('.flex-video'),
14592            iframe = video.find('iframe');
14593        if (iframe.length > 0) {
14594          iframe.attr("src", iframe.data("src"));
14595          video.fadeIn(100);
14596        }
14597      }
14598
14599      //
14600      // Bind the reveal 'open' event.
14601      // When the event is triggered, openAnimation is called
14602      // along with any function set in the options.open property.
14603      //
14604      modal.bind( 'reveal:open.reveal', openAnimation );
14605      modal.bind( 'reveal:open.reveal', openVideos);
14606
14607      /**
14608       * Closes the modal element(s)
14609       * Handles the modal 'close' event.
14610       *
14611       * @method closeAnimation
14612       */
14613      function closeAnimation() {
14614        //
14615        // First, determine if we're in the middle of animation.
14616        //
14617        if ( !locked ) {
14618          //
14619          // We're not animating, let's lock the modal for animation.
14620          //
14621          lockModal();
14622          //
14623          // Clear the modal of the open class.
14624          //
14625          modal.removeClass( "open" );
14626
14627          //
14628          // Are we using the 'fadeAndPop' animation?
14629          //
14630          if ( options.animation === "fadeAndPop" ) {
14631            //
14632            // Yes, okay, let's set the animation properties.
14633            //
14634            modal.animate( {
14635              //
14636              // Set the top property to the document scrollTop minus calculated topOffset.
14637              //
14638              "top":  $doc.scrollTop() - topOffset + 'px',
14639              //
14640              // Fade the modal out, by using the opacity property.
14641              //
14642              "opacity": 0
14643
14644            },
14645            /*
14646             * Fade speed.
14647             */
14648            options.animationSpeed / 2,
14649            /*
14650             * End of animation callback.
14651             */
14652            function () {
14653              //
14654              // Set the css hidden options.
14655              //
14656              modal.css( cssOpts.close );
14657
14658            });
14659            //
14660            // Is the modal animation queued?
14661            //
14662            if ( !modalQueued ) {
14663              //
14664              // Oh, the modal(s) are mid animating.
14665              // Let's delay the animation queue.
14666              //
14667              modalBg.delay( options.animationSpeed )
14668              //
14669              // Fade out the modal background.
14670              //
14671              .fadeOut(
14672              /*
14673               * Animation speed.
14674               */
14675              options.animationSpeed,
14676             /*
14677              * End of animation callback.
14678              */
14679              function () {
14680                //
14681                // Trigger the modal 'closed' event.
14682                // This should trigger any method set in the options.closed property.
14683                //
14684                modal.trigger( 'reveal:closed' );
14685
14686              });
14687
14688            } else {
14689              //
14690              // We're not mid queue.
14691              // Trigger the modal 'closed' event.
14692              // This should trigger any method set in the options.closed propety.
14693              //
14694              modal.trigger( 'reveal:closed' );
14695
14696            } // end if !modalQueued
14697
14698          } // end if animation 'fadeAndPop'
14699
14700          //
14701          // Are we using the 'fade' animation.
14702          //
14703          if ( options.animation === "fade" ) {
14704            //
14705            // Yes, we're using the 'fade' animation.
14706            //
14707            modal.animate( { "opacity" : 0 },
14708              /*
14709               * Animation speed.
14710               */
14711              options.animationSpeed,
14712              /*
14713               * End of animation callback.
14714               */
14715              function () {
14716              //
14717              // Set the css close options.
14718              //
14719              modal.css( cssOpts.close );
14720
14721            }); // end animate
14722
14723            //
14724            // Are we mid animating the modal(s)?
14725            //
14726            if ( !modalQueued ) {
14727              //
14728              // Oh, the modal(s) are mid animating.
14729              // Let's delay the animation queue.
14730              //
14731              modalBg.delay( options.animationSpeed )
14732              //
14733              // Let's fade out the modal background element.
14734              //
14735              .fadeOut(
14736              /*
14737               * Animation speed.
14738               */
14739              options.animationSpeed,
14740                /*
14741                 * End of animation callback.
14742                 */
14743                function () {
14744                  //
14745                  // Trigger the modal 'closed' event.
14746                  // This should trigger any method set in the options.closed propety.
14747                  //
14748                  modal.trigger( 'reveal:closed' );
14749
14750              }); // end fadeOut
14751
14752            } else {
14753              //
14754              // We're not mid queue.
14755              // Trigger the modal 'closed' event.
14756              // This should trigger any method set in the options.closed propety.
14757              //
14758              modal.trigger( 'reveal:closed' );
14759
14760            } // end if !modalQueued
14761
14762          } // end if animation 'fade'
14763
14764          //
14765          // Are we not animating?
14766          //
14767          if ( options.animation === "none" ) {
14768            //
14769            // We're not animating.
14770            // Set the modal close css options.
14771            //
14772            modal.css( cssOpts.close );
14773            //
14774            // Is the modal in the middle of an animation queue?
14775            //
14776            if ( !modalQueued ) {
14777              //
14778              // It's not mid queueu. Just hide it.
14779              //
14780              modalBg.css( { 'display': 'none' } );
14781            }
14782            //
14783            // Trigger the modal 'closed' event.
14784            // This should trigger any method set in the options.closed propety.
14785            //
14786            modal.trigger( 'reveal:closed' );
14787
14788          } // end if not animating
14789          //
14790          // Reset the modalQueued variable.
14791          //
14792          modalQueued = false;
14793        } // end if !locked
14794
14795      } // end closeAnimation
14796
14797      /**
14798       * Destroys the modal and it's events.
14799       *
14800       * @method destroy
14801       */
14802      function destroy() {
14803        //
14804        // Unbind all .reveal events from the modal.
14805        //
14806        modal.unbind( '.reveal' );
14807        //
14808        // Unbind all .reveal events from the modal background.
14809        //
14810        modalBg.unbind( '.reveal' );
14811        //
14812        // Unbind all .reveal events from the modal 'close' button.
14813        //
14814        $closeButton.unbind( '.reveal' );
14815        //
14816        // Unbind all .reveal events from the body.
14817        //
14818        $( 'body' ).unbind( '.reveal' );
14819
14820      }
14821
14822      function closeVideos() {
14823        var video = modal.find('.flex-video'),
14824            iframe = video.find('iframe');
14825        if (iframe.length > 0) {
14826          iframe.data("src", iframe.attr("src"));
14827          iframe.attr("src", "");
14828          video.fadeOut(100);  
14829        }
14830      }
14831
14832      //
14833      // Bind the modal 'close' event
14834      //
14835      modal.bind( 'reveal:close.reveal', closeAnimation );
14836      modal.bind( 'reveal:closed.reveal', closeVideos );
14837      //
14838      // Bind the modal 'opened' + 'closed' event
14839      // Calls the unlockModal method.
14840      //
14841      modal.bind( 'reveal:opened.reveal reveal:closed.reveal', unlockModal );
14842      //
14843      // Bind the modal 'closed' event.
14844      // Calls the destroy method.
14845      //
14846      modal.bind( 'reveal:closed.reveal', destroy );
14847      //
14848      // Bind the modal 'open' event
14849      // Handled by the options.open property function.
14850      //
14851      modal.bind( 'reveal:open.reveal', options.open );
14852      //
14853      // Bind the modal 'opened' event.
14854      // Handled by the options.opened property function.
14855      //
14856      modal.bind( 'reveal:opened.reveal', options.opened );
14857      //
14858      // Bind the modal 'close' event.
14859      // Handled by the options.close property function.
14860      //
14861      modal.bind( 'reveal:close.reveal', options.close );
14862      //
14863      // Bind the modal 'closed' event.
14864      // Handled by the options.closed property function.
14865      //
14866      modal.bind( 'reveal:closed.reveal', options.closed );
14867
14868      //
14869      // We're running this for the first time.
14870      // Trigger the modal 'open' event.
14871      //
14872      modal.trigger( 'reveal:open' );
14873
14874      //
14875      // Get the closeButton variable element(s).
14876      //
14877     $closeButton = $( '.' + options.dismissModalClass )
14878     //
14879     // Bind the element 'click' event and handler.
14880     //
14881     .bind( 'click.reveal', function () {
14882        //
14883        // Trigger the modal 'close' event.
14884        //
14885        modal.trigger( 'reveal:close' );
14886
14887      });
14888
14889     //
14890     // Should we close the modal background on click?
14891     //
14892     if ( options.closeOnBackgroundClick ) {
14893      //
14894      // Yes, close the modal background on 'click'
14895      // Set the modal background css 'cursor' propety to pointer.
14896      // Adds a pointer symbol when you mouse over the modal background.
14897      //
14898      modalBg.css( { "cursor": "pointer" } );
14899      //
14900      // Bind a 'click' event handler to the modal background.
14901      //
14902      modalBg.bind( 'click.reveal', function () {
14903        //
14904        // Trigger the modal 'close' event.
14905        //
14906        modal.trigger( 'reveal:close' );
14907
14908      });
14909
14910     }
14911
14912     //
14913     // Bind keyup functions on the body element.
14914     // We'll want to close the modal when the 'escape' key is hit.
14915     //
14916     $( 'body' ).bind( 'keyup.reveal', function ( event ) {
14917      //
14918      // Did the escape key get triggered?
14919      //
14920       if ( event.which === 27 ) { // 27 is the keycode for the Escape key
14921         //
14922         // Escape key was triggered.
14923         // Trigger the modal 'close' event.
14924         //
14925         modal.trigger( 'reveal:close' );
14926       }
14927
14928      }); // end $(body)
14929
14930    }); // end this.each
14931
14932  }; // end $.fn
14933
14934} ( jQuery ) );
14935/*
14936 * jQuery Foundation Magellan 0.1.0
14937 * http://foundation.zurb.com
14938 * Copyright 2012, ZURB
14939 * Free to use under the MIT license.
14940 * http://www.opensource.org/licenses/mit-license.php
14941*/
14942
14943/*jslint unparam: true, browser: true, indent: 2 */
14944
14945
14946;(function ($, window, undefined) {
14947  'use strict';
14948
14949  $.fn.foundationMagellan = function(options) {
14950    var $window = $(window),
14951  		$document = $(document),
14952  		$fixedMagellan = $('[data-magellan-expedition=fixed]'),
14953    	defaults = {
14954	      threshold: ($fixedMagellan.length) ? $fixedMagellan.outerHeight(true) : 0,
14955	      activeClass: 'active'
14956	    },
14957		options = $.extend({}, defaults, options);
14958	
14959    // Indicate we have arrived at a destination
14960    $document.on('magellan.arrival', '[data-magellan-arrival]', function(e) {
14961		var $destination = $(this),
14962      		$expedition = $destination.closest('[data-magellan-expedition]'),
14963			activeClass = $expedition.attr('data-magellan-active-class') || options.activeClass;
14964      $destination
14965        .closest('[data-magellan-expedition]')
14966        .find('[data-magellan-arrival]')
14967        .not(this)
14968        .removeClass(activeClass);
14969      $destination.addClass(activeClass);
14970    });
14971
14972    // Set starting point as the current destination
14973    var $expedition = $('[data-magellan-expedition]');
14974    $expedition.find('[data-magellan-arrival]:first')
14975      .addClass($expedition.attr('data-magellan-active-class') || options.activeClass);
14976
14977    // Update fixed position
14978    $fixedMagellan.on('magellan.update-position', function(){
14979      var $el = $(this);
14980      $el.data("magellan-fixed-position","");
14981      $el.data("magellan-top-offset", "");
14982    })
14983    .trigger('magellan.update-position');
14984
14985    $window.on('resize.magellan', function() {
14986      $fixedMagellan.trigger('magellan.update-position');
14987    });
14988    
14989    $window.on('scroll.magellan', function() {
14990      var windowScrollTop = $window.scrollTop();
14991      $fixedMagellan.each(function() {
14992        var $expedition = $(this);
14993        if ($expedition.data("magellan-top-offset") === "") {
14994          $expedition.data("magellan-top-offset", $expedition.offset().top);
14995        }
14996        var fixed_position = (windowScrollTop + options.threshold) > $expedition.data("magellan-top-offset");
14997        if ($expedition.data("magellan-fixed-position") != fixed_position) {
14998          $expedition.data("magellan-fixed-position", fixed_position);
14999          if (fixed_position) {
15000            $expedition.css({position:"fixed", top:0});
15001          } else {
15002            $expedition.css({position:"", top:""});
15003          }
15004        }
15005      });
15006    });
15007
15008    // Determine when a destination has been reached, ah0y!
15009    var $lastDestination = $('[data-magellan-destination]:last');
15010      // Determine if a destination has been set
15011    if ($lastDestination.length > 0) {
15012        $window.on('scroll.magellan', function (e) {
15013            var windowScrollTop = $window.scrollTop(),
15014                scrolltopPlusHeight = windowScrollTop + $window.outerHeight(true),
15015                lastDestinationTop = Math.ceil($lastDestination.offset().top);
15016            $('[data-magellan-destination]').each(function () {
15017                var $destination = $(this),
15018                    destination_name = $destination.attr('data-magellan-destination'),
15019                    topOffset = $destination.offset().top - windowScrollTop;
15020                if (topOffset <= options.threshold) {
15021                    $('[data-magellan-arrival=' + destination_name + ']').trigger('magellan.arrival');
15022                }
15023                // In large screens we may hit the bottom of the page and dont reach the top of the last magellan-destination, so lets force it
15024                if (scrolltopPlusHeight >= $document.outerHeight(true) && lastDestinationTop > windowScrollTop && lastDestinationTop < scrolltopPlusHeight) {
15025                    $('[data-magellan-arrival]:last').trigger('magellan.arrival');
15026                }
15027            });
15028        });
15029    }
15030  };
15031}(jQuery, this));
15032/*
15033 * jQuery Foundation Joyride Plugin 2.0.3
15034 * http://foundation.zurb.com
15035 * Copyright 2012, ZURB
15036 * Free to use under the MIT license.
15037 * http://www.opensource.org/licenses/mit-license.php
15038*/
15039
15040/*jslint unparam: true, browser: true, indent: 2 */
15041
15042
15043;(function ($, window, undefined) {
15044  'use strict';
15045
15046  var defaults = {
15047      'version'              : '2.0.3',
15048      'tipLocation'          : 'bottom',  // 'top' or 'bottom' in relation to parent
15049      'nubPosition'          : 'auto',    // override on a per tooltip bases
15050      'scrollSpeed'          : 300,       // Page scrolling speed in milliseconds
15051      'timer'                : 0,         // 0 = no timer , all other numbers = timer in milliseconds
15052      'startTimerOnClick'    : true,      // true or false - true requires clicking the first button start the timer
15053      'startOffset'          : 0,         // the index of the tooltip you want to start on (index of the li)
15054      'nextButton'           : true,      // true or false to control whether a next button is used
15055      'tipAnimation'         : 'fade',    // 'pop' or 'fade' in each tip
15056      'pauseAfter'           : [],        // array of indexes where to pause the tour after
15057      'tipAnimationFadeSpeed': 300,       // when tipAnimation = 'fade' this is speed in milliseconds for the transition
15058      'cookieMonster'        : false,     // true or false to control whether cookies are used
15059      'cookieName'           : 'joyride', // Name the cookie you'll use
15060      'cookieDomain'         : false,     // Will this cookie be attached to a domain, ie. '.notableapp.com'
15061      'tipContainer'         : 'body',    // Where will the tip be attached
15062      'postRideCallback'     : $.noop,    // A method to call once the tour closes (canceled or complete)
15063      'postStepCallback'     : $.noop,    // A method to call after each step
15064      'template' : { // HTML segments for tip layout
15065        'link'    : '<a href="#close" class="joyride-close-tip">X</a>',
15066        'timer'   : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',
15067        'tip'     : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',
15068        'wrapper' : '<div class="joyride-content-wrapper"></div>',
15069        'button'  : '<a href="#" class="small button joyride-next-tip"></a>'
15070      }
15071    },
15072
15073    Modernizr = Modernizr || false,
15074
15075    settings = {},
15076
15077    methods = {
15078
15079      init : function (opts) {
15080        return this.each(function () {
15081
15082          if ($.isEmptyObject(settings)) {
15083            settings = $.extend(true, defaults, opts);
15084
15085            // non configurable settings
15086            settings.document = window.document;
15087            settings.$document = $(settings.document);
15088            settings.$window = $(window);
15089            settings.$content_el = $(this);
15090            settings.body_offset = $(settings.tipContainer).position();
15091            settings.$tip_content = $('> li', settings.$content_el);
15092            settings.paused = false;
15093            settings.attempts = 0;
15094
15095            settings.tipLocationPatterns = {
15096              top: ['bottom'],
15097              bottom: [], // bottom should not need to be repositioned
15098              left: ['right', 'top', 'bottom'],
15099              right: ['left', 'top', 'bottom']
15100            };
15101
15102            // are we using jQuery 1.7+
15103            methods.jquery_check();
15104
15105            // can we create cookies?
15106            if (!$.isFunction($.cookie)) {
15107              settings.cookieMonster = false;
15108            }
15109
15110            // generate the tips and insert into dom.
15111            if (!settings.cookieMonster || !$.cookie(settings.cookieName)) {
15112
15113              settings.$tip_content.each(function (index) {
15114                methods.create({$li : $(this), index : index});
15115              });
15116
15117              // show first tip
15118              if (!settings.startTimerOnClick && settings.timer > 0) {
15119                methods.show('init');
15120                methods.startTimer();
15121              } else {
15122                methods.show('init');
15123              }
15124
15125            }
15126
15127            settings.$document.on('click.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) {
15128              e.preventDefault();
15129
15130              if (settings.$li.next().length < 1) {
15131                methods.end();
15132              } else if (settings.timer > 0) {
15133                clearTimeout(settings.automate);
15134                methods.hide();
15135                methods.show();
15136                methods.startTimer();
15137              } else {
15138                methods.hide();
15139                methods.show();
15140              }
15141
15142            });
15143
15144            settings.$document.on('click.joyride', '.joyride-close-tip', function (e) {
15145              e.preventDefault();
15146              methods.end();
15147            });
15148
15149            settings.$window.bind('resize.joyride', function (e) {
15150              if (methods.is_phone()) {
15151                methods.pos_phone();
15152              } else {
15153                methods.pos_default();
15154              }
15155            });
15156          } else {
15157            methods.restart();
15158          }
15159
15160        });
15161      },
15162
15163      // call this method when you want to resume the tour
15164      resume : function () {
15165        methods.set_li();
15166        methods.show();
15167      },
15168
15169      tip_template : function (opts) {
15170        var $blank, content;
15171
15172        opts.tip_class = opts.tip_class || '';
15173
15174        $blank = $(settings.template.tip).addClass(opts.tip_class);
15175        content = $.trim($(opts.li).html()) +
15176          methods.button_text(opts.button_text) +
15177          settings.template.link +
15178          methods.timer_instance(opts.index);
15179
15180        $blank.append($(settings.template.wrapper));
15181        $blank.first().attr('data-index', opts.index);
15182        $('.joyride-content-wrapper', $blank).append(content);
15183
15184        return $blank[0];
15185      },
15186
15187      timer_instance : function (index) {
15188        var txt;
15189
15190        if ((index === 0 && settings.startTimerOnClick && settings.timer > 0) || settings.timer === 0) {
15191          txt = '';
15192        } else {
15193          txt = methods.outerHTML($(settings.template.timer)[0]);
15194        }
15195        return txt;
15196      },
15197
15198      button_text : function (txt) {
15199        if (settings.nextButton) {
15200          txt = $.trim(txt) || 'Next';
15201          txt = methods.outerHTML($(settings.template.button).append(txt)[0]);
15202        } else {
15203          txt = '';
15204        }
15205        return txt;
15206      },
15207
15208      create : function (opts) {
15209        // backwards compatibility with data-text attribute
15210        var buttonText = opts.$li.attr('data-button') || opts.$li.attr('data-text'),
15211          tipClass = opts.$li.attr('class'),
15212          $tip_content = $(methods.tip_template({
15213            tip_class : tipClass,
15214            index : opts.index,
15215            button_text : buttonText,
15216            li : opts.$li
15217          }));
15218
15219        $(settings.tipContainer).append($tip_content);
15220      },
15221
15222      show : function (init) {
15223        var opts = {}, ii, opts_arr = [], opts_len = 0, p,
15224            $timer = null;
15225
15226        // are we paused?
15227        if (settings.$li === undefined || ($.inArray(settings.$li.index(), settings.pauseAfter) === -1)) {
15228
15229          // don't go to the next li if the tour was paused
15230          if (settings.paused) {
15231            settings.paused = false;
15232          } else {
15233            methods.set_li(init);
15234          }
15235
15236          settings.attempts = 0;
15237
15238          if (settings.$li.length && settings.$target.length > 0) {
15239            opts_arr = (settings.$li.data('options') || ':').split(';');
15240            opts_len = opts_arr.length;
15241
15242            // parse options
15243            for (ii = opts_len - 1; ii >= 0; ii--) {
15244              p = opts_arr[ii].split(':');
15245
15246              if (p.length === 2) {
15247                opts[$.trim(p[0])] = $.trim(p[1]);
15248              }
15249            }
15250
15251            settings.tipSettings = $.extend({}, settings, opts);
15252
15253            settings.tipSettings.tipLocationPattern = settings.tipLocationPatterns[settings.tipSettings.tipLocation];
15254
15255            // scroll if not modal
15256            if (!/body/i.test(settings.$target.selector)) {
15257              methods.scroll_to();
15258            }
15259
15260            if (methods.is_phone()) {
15261              methods.pos_phone(true);
15262            } else {
15263              methods.pos_default(true);
15264            }
15265
15266            $timer = $('.joyride-timer-indicator', settings.$next_tip);
15267
15268            if (/pop/i.test(settings.tipAnimation)) {
15269
15270              $timer.outerWidth(0);
15271
15272              if (settings.timer > 0) {
15273
15274                settings.$next_tip.show();
15275                $timer.animate({
15276                  width: $('.joyride-timer-indicator-wrap', settings.$next_tip).outerWidth()
15277                }, settings.timer);
15278
15279              } else {
15280
15281                settings.$next_tip.show();
15282
15283              }
15284
15285
15286            } else if (/fade/i.test(settings.tipAnimation)) {
15287
15288              $timer.outerWidth(0);
15289
15290              if (settings.timer > 0) {
15291
15292                settings.$next_tip.fadeIn(settings.tipAnimationFadeSpeed);
15293
15294                settings.$next_tip.show();
15295                $timer.animate({
15296                  width: $('.joyride-timer-indicator-wrap', settings.$next_tip).outerWidth()
15297                }, settings.timer);
15298
15299              } else {
15300
15301                settings.$next_tip.fadeIn(settings.tipAnimationFadeSpeed);
15302
15303              }
15304            }
15305
15306            settings.$current_tip = settings.$next_tip;
15307
15308          // skip non-existent targets
15309          } else if (settings.$li && settings.$target.length < 1) {
15310
15311            methods.show();
15312
15313          } else {
15314
15315            methods.end();
15316
15317          }
15318        } else {
15319
15320          settings.paused = true;
15321
15322        }
15323
15324      },
15325
15326      // detect phones with media queries if supported.
15327      is_phone : function () {
15328        if (Modernizr) {
15329          return Modernizr.mq('only screen and (max-width: 767px)');
15330        }
15331
15332        return (settings.$window.width() < 767) ? true : false;
15333      },
15334
15335      hide : function () {
15336        settings.postStepCallback(settings.$li.index(), settings.$current_tip);
15337        $('.joyride-modal-bg').hide();
15338        settings.$current_tip.hide();
15339      },
15340
15341      set_li : function (init) {
15342        if (init) {
15343          settings.$li = settings.$tip_content.eq(settings.startOffset);
15344          methods.set_next_tip();
15345          settings.$current_tip = settings.$next_tip;
15346        } else {
15347          settings.$li = settings.$li.next();
15348          methods.set_next_tip();
15349        }
15350
15351        methods.set_target();
15352      },
15353
15354      set_next_tip : function () {
15355        settings.$next_tip = $('.joyride-tip-guide[data-index=' + settings.$li.index() + ']');
15356      },
15357
15358      set_target : function () {
15359        var cl = settings.$li.attr('data-class'),
15360            id = settings.$li.attr('data-id'),
15361            $sel = function () {
15362              if (id) {
15363                return $(settings.document.getElementById(id));
15364              } else if (cl) {
15365                return $('.' + cl).first();
15366              } else {
15367                return $('body');
15368              }
15369            };
15370
15371        settings.$target = $sel();
15372      },
15373
15374      scroll_to : function () {
15375        var window_half, tipOffset;
15376
15377        window_half = settings.$window.height() / 2;
15378        tipOffset = Math.ceil(settings.$target.offset().top - window_half + settings.$next_tip.outerHeight());
15379
15380        $("html, body").stop().animate({
15381          scrollTop: tipOffset
15382        }, settings.scrollSpeed);
15383      },
15384
15385      paused : function () {
15386        if (($.inArray((settings.$li.index() + 1), settings.pauseAfter) === -1)) {
15387          return true;
15388        }
15389
15390        return false;
15391      },
15392
15393      destroy : function () {
15394        settings.$document.off('.joyride');
15395        $(window).off('.joyride');
15396        $('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride');
15397        $('.joyride-tip-guide, .joyride-modal-bg').remove();
15398        clearTimeout(settings.automate);
15399        settings = {};
15400      },
15401
15402      restart : function () {
15403        methods.hide();
15404        settings.$li = undefined;
15405        methods.show('init');
15406      },
15407
15408      pos_default : function (init) {
15409        var half_fold = Math.ceil(settings.$window.height() / 2),
15410            tip_position = settings.$next_tip.offset(),
15411            $nub = $('.joyride-nub', settings.$next_tip),
15412            nub_height = Math.ceil($nub.outerHeight() / 2),
15413            toggle = init || false;
15414
15415        // tip must not be "display: none" to calculate position
15416        if (toggle) {
15417          settings.$next_tip.css('visibility', 'hidden');
15418          settings.$next_tip.show();
15419        }
15420
15421        if (!/body/i.test(settings.$target.selector)) {
15422
15423            if (methods.bottom()) {
15424              settings.$next_tip.css({
15425                top: (settings.$target.offset().top + nub_height + settings.$target.outerHeight()),
15426                left: settings.$target.offset().left});
15427
15428              methods.nub_position($nub, settings.tipSettings.nubPosition, 'top');
15429
15430            } else if (methods.top()) {
15431
15432              settings.$next_tip.css({
15433                top: (settings.$target.offset().top - settings.$next_tip.outerHeight() - nub_height),
15434                left: settings.$target.offset().left});
15435
15436              methods.nub_position($nub, settings.tipSettings.nubPosition, 'bottom');
15437
15438            } else if (methods.right()) {
15439
15440              settings.$next_tip.css({
15441                top: settings.$target.offset().top,
15442                left: (settings.$target.outerWidth() + settings.$target.offset().left)});
15443
15444              methods.nub_position($nub, settings.tipSettings.nubPosition, 'left');
15445
15446            } else if (methods.left()) {
15447
15448              settings.$next_tip.css({
15449                top: settings.$target.offset().top,
15450                left: (settings.$target.offset().left - settings.$next_tip.outerWidth() - nub_height)});
15451
15452              methods.nub_position($nub, settings.tipSettings.nubPosition, 'right');
15453
15454            }
15455
15456            if (!methods.visible(methods.corners(settings.$next_tip)) && settings.attempts < settings.tipSettings.tipLocationPattern.length) {
15457
15458              $nub.removeClass('bottom')
15459                .removeClass('top')
15460                .removeClass('right')
15461                .removeClass('left');
15462
15463              settings.tipSettings.tipLocation = settings.tipSettings.tipLocationPattern[settings.attempts];
15464
15465              settings.attempts++;
15466
15467              methods.pos_default(true);
15468
15469            }
15470
15471        } else if (settings.$li.length) {
15472
15473          methods.pos_modal($nub);
15474
15475        }
15476
15477        if (toggle) {
15478          settings.$next_tip.hide();
15479          settings.$next_tip.css('visibility', 'visible');
15480        }
15481
15482      },
15483
15484      pos_phone : function (init) {
15485        var tip_height = settings.$next_tip.outerHeight(),
15486            tip_offset = settings.$next_tip.offset(),
15487            target_height = settings.$target.outerHeight(),
15488            $nub = $('.joyride-nub', settings.$next_tip),
15489            nub_height = Math.ceil($nub.outerHeight() / 2),
15490            toggle = init || false;
15491
15492        $nub.removeClass('bottom')
15493          .removeClass('top')
15494          .removeClass('right')
15495          .removeClass('left');
15496
15497        if (toggle) {
15498          settings.$next_tip.css('visibility', 'hidden');
15499          settings.$next_tip.show();
15500        }
15501
15502        if (!/body/i.test(settings.$target.selector)) {
15503
15504          if (methods.top()) {
15505
15506              settings.$next_tip.offset({top: settings.$target.offset().top - tip_height - nub_height});
15507              $nub.addClass('bottom');
15508
15509          } else {
15510
15511            settings.$next_tip.offset({top: settings.$target.offset().top + target_height + nub_height});
15512            $nub.addClass('top');
15513
15514          }
15515
15516        } else if (settings.$li.length) {
15517
15518          methods.pos_modal($nub);
15519
15520        }
15521
15522        if (toggle) {
15523          settings.$next_tip.hide();
15524          settings.$next_tip.css('visibility', 'visible');
15525        }
15526      },
15527
15528      pos_modal : function ($nub) {
15529        methods.center();
15530        $nub.hide();
15531
15532        if ($('.joyride-modal-bg').length < 1) {
15533          $('body').append('<div class="joyride-modal-bg">').show();
15534        }
15535
15536        if (/pop/i.test(settings.tipAnimation)) {
15537          $('.joyride-modal-bg').show();
15538        } else {
15539          $('.joyride-modal-bg').fadeIn(settings.tipAnimationFadeSpeed);
15540        }
15541      },
15542
15543      center : function () {
15544        var $w = settings.$window;
15545
15546        settings.$next_tip.css({
15547          top : ((($w.height() - settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()),
15548          left : ((($w.width() - settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft())
15549        });
15550
15551        return true;
15552      },
15553
15554      bottom : function () {
15555        return /bottom/i.test(settings.tipSettings.tipLocation);
15556      },
15557
15558      top : function () {
15559        return /top/i.test(settings.tipSettings.tipLocation);
15560      },
15561
15562      right : function () {
15563        return /right/i.test(settings.tipSettings.tipLocation);
15564      },
15565
15566      left : function () {
15567        return /left/i.test(settings.tipSettings.tipLocation);
15568      },
15569
15570      corners : function (el) {
15571        var w = settings.$window,
15572            right = w.width() + w.scrollLeft(),
15573            bottom = w.width() + w.scrollTop();
15574
15575        return [
15576          el.offset().top <= w.scrollTop(),
15577          right <= el.offset().left + el.outerWidth(),
15578          bottom <= el.offset().top + el.outerHeight(),
15579          w.scrollLeft() >= el.offset().left
15580        ];
15581      },
15582
15583      visible : function (hidden_corners) {
15584        var i = hidden_corners.length;
15585
15586        while (i--) {
15587          if (hidden_corners[i]) return false;
15588        }
15589
15590        return true;
15591      },
15592
15593      nub_position : function (nub, pos, def) {
15594        if (pos === 'auto') {
15595          nub.addClass(def);
15596        } else {
15597          nub.addClass(pos);
15598        }
15599      },
15600
15601      startTimer : function () {
15602        if (settings.$li.length) {
15603          settings.automate = setTimeout(function () {
15604            methods.hide();
15605            methods.show();
15606            methods.startTimer();
15607          }, settings.timer);
15608        } else {
15609          clearTimeout(settings.automate);
15610        }
15611      },
15612
15613      end : function () {
15614        if (settings.cookieMonster) {
15615          $.cookie(settings.cookieName, 'ridden', { expires: 365, domain: settings.cookieDomain });
15616        }
15617
15618        if (settings.timer > 0) {
15619          clearTimeout(settings.automate);
15620        }
15621
15622        $('.joyride-modal-bg').hide();
15623        settings.$current_tip.hide();
15624        settings.postStepCallback(settings.$li.index(), settings.$current_tip);
15625        settings.postRideCallback(settings.$li.index(), settings.$current_tip);
15626      },
15627
15628      jquery_check : function () {
15629        // define on() and off() for older jQuery
15630        if (!$.isFunction($.fn.on)) {
15631
15632          $.fn.on = function (types, sel, fn) {
15633
15634            return this.delegate(sel, types, fn);
15635
15636          };
15637
15638          $.fn.off = function (types, sel, fn) {
15639
15640            return this.undelegate(sel, types, fn);
15641
15642          };
15643
15644          return false;
15645        }
15646
15647        return true;
15648      },
15649
15650      outerHTML : function (el) {
15651        // support FireFox < 11
15652        return el.outerHTML || new XMLSerializer().serializeToString(el);
15653      },
15654
15655      version : function () {
15656        return settings.version;
15657      }
15658
15659    };
15660
15661  $.fn.joyride = function (method) {
15662    if (methods[method]) {
15663      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
15664    } else if (typeof method === 'object' || !method) {
15665      return methods.init.apply(this, arguments);
15666    } else {
15667      $.error('Method ' +  method + ' does not exist on jQuery.joyride');
15668    }
15669  };
15670
15671}(jQuery, this));
15672/*
15673 * jQuery Foundation Clearing 1.2.1
15674 * http://foundation.zurb.com
15675 * Copyright 2012, ZURB
15676 * Free to use under the MIT license.
15677 * http://www.opensource.org/licenses/mit-license.php
15678*/
15679
15680/*jslint unparam: true, browser: true, indent: 2 */
15681
15682
15683;(function ($, window, document, undefined) {
15684  'use strict';
15685
15686  var defaults = {
15687        templates : {
15688          viewing : '<a href="#" class="clearing-close">&times;</a>' +
15689            '<div class="visible-img" style="display: none"><img src="#">' +
15690            '<p class="clearing-caption"></p><a href="#" class="clearing-main-left"></a>' +
15691            '<a href="#" class="clearing-main-right"></a></div>'
15692        },
15693
15694        // comma delimited list of selectors that, on click, will close clearing, 
15695        // add 'div.clearing-blackout, div.visible-img' to close on background click
15696        close_selectors : 'a.clearing-close',
15697
15698        // event initializers and locks
15699        initialized : false,
15700        locked : false
15701      },
15702
15703      cl = {
15704        init : function (options, extendMethods) {
15705          return this.find('ul[data-clearing]').each(function () {
15706            var doc = $(document),
15707                $el = $(this),
15708                options = options || {},
15709                extendMethods = extendMethods || {},
15710                settings = $el.data('fndtn.clearing.settings');
15711
15712            if (!settings) {
15713              options.$parent = $el.parent();
15714
15715              $el.data('fndtn.clearing.settings', $.extend({}, defaults, options));
15716
15717              cl.assemble($el.find('li'));
15718
15719              if (!defaults.initialized) {
15720                cl.events($el);
15721                if (Modernizr.touch) cl.swipe_events();
15722              }
15723
15724            }
15725          });
15726        },
15727
15728        events : function (el) {
15729          var settings = el.data('fndtn.clearing.settings');
15730
15731          $(document)
15732            .on('click.fndtn.clearing', 'ul[data-clearing] li', function (e, current, target) {
15733              var current = current || $(this),
15734                  target = target || current,
15735                  settings = current.parent().data('fndtn.clearing.settings');
15736
15737              e.preventDefault();
15738
15739              if (!settings) {
15740                current.parent().foundationClearing();
15741              }
15742
15743              // set current and target to the clicked li if not otherwise defined.
15744              cl.open($(e.target), current, target);
15745              cl.update_paddles(target);
15746            })
15747
15748            .on('click.fndtn.clearing', '.clearing-main-right', function (e) { cl.nav(e, 'next') })
15749            .on('click.fndtn.clearing', '.clearing-main-left', function (e) { cl.nav(e, 'prev') })
15750            .on('click.fndtn.clearing', settings.close_selectors, this.close)
15751            .on('keydown.fndtn.clearing', this.keydown);
15752
15753          $(window).on('resize.fndtn.clearing', this.resize);
15754
15755          defaults.initialized = true;
15756        },
15757
15758        swipe_events : function () {
15759          $(document)
15760            .bind('swipeleft', 'ul[data-clearing]', function (e) { cl.nav(e, 'next') })
15761            .bind('swiperight', 'ul[data-clearing]', function (e) { cl.nav(e, 'prev') })
15762            .bind('movestart', 'ul[data-clearing]', function (e) {
15763              if ((e.distX > e.distY && e.distX < -e.distY) ||
15764                  (e.distX < e.distY && e.distX > -e.distY)) {
15765                e.preventDefault();
15766              }
15767            });
15768        },
15769
15770        assemble : function ($li) {
15771          var $el = $li.parent(),
15772              settings = $el.data('fndtn.clearing.settings'),
15773              grid = $el.detach(),
15774              data = {
15775                grid: '<div class="carousel">' + this.outerHTML(grid[0]) + '</div>',
15776                viewing: settings.templates.viewing
15777              },
15778              wrapper = '<div class="clearing-assembled"><div>' + data.viewing + data.grid + '</div></div>';
15779
15780          return settings.$parent.append(wrapper);
15781        },
15782
15783        open : function ($image, current, target) {
15784          var root = target.closest('.clearing-assembled'),
15785              container = root.find('div:first'),
15786              visible_image = container.find('.visible-img'),
15787              image = visible_image.find('img').not($image);
15788
15789          if (!cl.locked()) {
15790
15791            // set the image to the selected thumbnail
15792            image.attr('src', this.load($image));
15793
15794            image.loaded(function () {
15795              // toggle the gallery if not visible
15796              root.addClass('clearing-blackout');
15797              container.addClass('clearing-container');
15798              this.caption(visible_image.find('.clearing-caption'), $image);
15799              visible_image.show();
15800              this.fix_height(target);
15801              this.center(image);
15802
15803              // shift the thumbnails if necessary
15804              this.shift(current, target, function () {
15805                target.siblings().removeClass('visible');
15806                target.addClass('visible');
15807              });
15808            }.bind(this));
15809          }
15810        },
15811
15812        close : function (e) {
15813          e.preventDefault();
15814
15815          var root = (function (target) {
15816                if (/blackout/.test(target.selector)) {
15817                  return target;
15818                } else {
15819                  return target.closest('.clearing-blackout');
15820                }
15821              }($(this))), container, visible_image;
15822
15823          if (this === e.target && root) {
15824            container = root.find('div:first'),
15825            visible_image = container.find('.visible-img');
15826
15827            defaults.prev_index = 0;
15828
15829            root.find('ul[data-clearing]').attr('style', '')
15830            root.removeClass('clearing-blackout');
15831            container.removeClass('clearing-container');
15832            visible_image.hide();
15833          }
15834
15835          return false;
15836        },
15837
15838        keydown : function (e) {
15839          var clearing = $('.clearing-blackout').find('ul[data-clearing]');
15840
15841          if (e.which === 39) cl.go(clearing, 'next');
15842          if (e.which === 37) cl.go(clearing, 'prev');
15843          if (e.which === 27) $('a.clearing-close').trigger('click');
15844        },
15845
15846        nav : function (e, direction) {
15847          var clearing = $('.clearing-blackout').find('ul[data-clearing]');
15848
15849          e.preventDefault();
15850          this.go(clearing, direction);
15851        },
15852
15853        resize : function () {
15854          var image = $('.clearing-blackout .visible-img').find('img');
15855
15856          if (image.length > 0) {
15857            cl.center(image);
15858          }
15859        },
15860
15861        fix_height : function (target) {
15862          var lis = target.siblings();
15863
15864          lis.each(function () {
15865              var li = $(this),
15866                  image = li.find('img');
15867
15868              if (li.height() > image.outerHeight()) {
15869                li.addClass('fix-height');
15870              }
15871            })
15872            .closest('ul').width(lis.length * 100 + '%');
15873        },
15874
15875        update_paddles : function (target) {
15876          var visible_image = target.closest('.carousel').siblings('.visible-img');
15877
15878          if (target.next().length > 0) {
15879            visible_image.find('.clearing-main-right').removeClass('disabled');
15880          } else {
15881            visible_image.find('.clearing-main-right').addClass('disabled');
15882          }
15883
15884          if (target.prev().length > 0) {
15885            visible_image.find('.clearing-main-left').removeClass('disabled');
15886          } else {
15887            visible_image.find('.clearing-main-left').addClass('disabled');
15888          }
15889        },
15890
15891        load : function ($image) {
15892          var href = $image.parent().attr('href');
15893
15894          this.preload($image);
15895
15896          if (href) return href;
15897          return $image.attr('src');
15898        },
15899
15900        preload : function ($image) {
15901          this.img($image.closest('li').next());
15902          this.img($image.closest('li').prev());
15903        },
15904
15905        img : function (img) {
15906          if (img.length > 0) {
15907            var new_img = new Image(),
15908                new_a = img.find('a');
15909
15910            if (new_a.length > 0) {
15911              new_img.src = new_a.attr('href');
15912            } else {
15913              new_img.src = img.find('img').attr('src');
15914            }
15915          }
15916        },
15917
15918        caption : function (container, $image) {
15919          var caption = $image.data('caption');
15920
15921          if (caption) {
15922            container.text(caption).show();
15923          } else {
15924            container.text('').hide();
15925          }
15926        },
15927
15928        go : function ($ul, direction) {
15929          var current = $ul.find('.visible'),
15930              target = current[direction]();
15931
15932          if (target.length > 0) {
15933            target.find('img').trigger('click', [current, target]);
15934          }
15935        },
15936
15937        shift : function (current, target, callback) {
15938          var clearing = target.parent(),
15939              old_index = defaults.prev_index,
15940              direction = this.direction(clearing, current, target),
15941              left = parseInt(clearing.css('left'), 10),
15942              width = target.outerWidth(),
15943              skip_shift;
15944
15945          // we use jQuery animate instead of CSS transitions because we
15946          // need a callback to unlock the next animation
15947          if (target.index() !== old_index && !/skip/.test(direction)){
15948            if (/left/.test(direction)) {
15949              this.lock();
15950              clearing.animate({left : left + width}, 300, this.unlock);
15951            } else if (/right/.test(direction)) {
15952              this.lock();
15953              clearing.animate({left : left - width}, 300, this.unlock);
15954            }
15955          } else if (/skip/.test(direction)) {
15956
15957            // the target image is not adjacent to the current image, so
15958            // do we scroll right or not
15959            skip_shift = target.index() - defaults.up_count;
15960            this.lock();
15961
15962            if (skip_shift > 0) {
15963              clearing.animate({left : -(skip_shift * width)}, 300, this.unlock);
15964            } else {
15965              clearing.animate({left : 0}, 300, this.unlock);
15966            }
15967          }
15968
15969          callback();
15970        },
15971
15972        lock : function () {
15973          defaults.locked = true;
15974        },
15975
15976        unlock : function () {
15977          defaults.locked = false;
15978        },
15979
15980        locked : function () {
15981          return defaults.locked;
15982        },
15983
15984        direction : function ($el, current, target) {
15985          var lis = $el.find('li'),
15986              li_width = lis.outerWidth() + (lis.outerWidth() / 4),
15987              up_count = Math.floor($('.clearing-container').outerWidth() / li_width) - 1,
15988              target_index = lis.index(target),
15989              response;
15990
15991          defaults.up_count = up_count;
15992
15993          if (this.adjacent(defaults.prev_index, target_index)) {
15994            if ((target_index > up_count) && target_index > defaults.prev_index) {
15995              response = 'right';
15996            } else if ((target_index > up_count - 1) && target_index <= defaults.prev_index) {
15997              response = 'left';
15998            } else {
15999              response = false;
16000            }
16001          } else {
16002            response = 'skip';
16003          }
16004
16005          defaults.prev_index = target_index;
16006
16007          return response;
16008        },
16009
16010        adjacent : function (current_index, target_index) {
16011          for (var i = target_index + 1; i >= target_index - 1; i--) {
16012            if (i === current_index) return true;
16013          }
16014          return false;
16015        },
16016
16017        center : function (target) {
16018          target.css({
16019            marginLeft : -(target.outerWidth() / 2),
16020            marginTop : -(target.outerHeight() / 2)
16021          });
16022        },
16023
16024        outerHTML : function (el) {
16025          // support FireFox < 11
16026          return el.outerHTML || new XMLSerializer().serializeToString(el);
16027        }
16028
16029      };
16030
16031  $.fn.foundationClearing = function (method) {
16032    if (cl[method]) {
16033      return cl[method].apply(this, Array.prototype.slice.call(arguments, 1));
16034    } else if (typeof method === 'object' || !method) {
16035      return cl.init.apply(this, arguments);
16036    } else {
16037      $.error('Method ' +  method + ' does not exist on jQuery.foundationClearing');
16038    }
16039  };
16040
16041  // jquery.imageready.js
16042  // @weblinc, @jsantell, (c) 2012
16043
16044  (function( $ ) {
16045    $.fn.loaded = function ( callback, userSettings ) {
16046      var
16047        options = $.extend( {}, $.fn.loaded.defaults, userSettings ),
16048        $images = this.find( 'img' ).add( this.filter( 'img' ) ),
16049        unloadedImages = $images.length;
16050
16051      function loaded () {
16052        unloadedImages -= 1;
16053        !unloadedImages && callback();
16054      }
16055
16056      function bindLoad () {
16057        this.one( 'load', loaded );
16058        if ( $.browser.msie ) {
16059          var
16060            src   = this.attr( 'src' ),
16061            param = src.match( /\?/ ) ? '&' : '?';
16062          param  += options.cachePrefix + '=' + ( new Date() ).getTime();
16063          this.attr( 'src', src + param );
16064        }
16065      }
16066
16067      return $images.each(function () {
16068        var $this = $( this );
16069        if ( !$this.attr( 'src' ) ) {
16070          loaded();
16071          return;
16072        }
16073        this.complete || this.readyState === 4 ?
16074          loaded() :
16075          bindLoad.call( $this );
16076      });
16077    };
16078
16079    $.fn.loaded.defaults = {
16080      cachePrefix: 'random'
16081    };
16082
16083  }(jQuery));
16084
16085}(jQuery, this, this.document));
16086/*
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104*/
16105;
16106/**
16107 * Overscroll v1.7.1
16108 *  A jQuery Plugin that emulates the iPhone scrolling experience in a browser.
16109 *  http://azoffdesign.com/overscroll
16110 *
16111 * Intended for use with the latest jQuery
16112 *  http://code.jquery.com/jquery-latest.js
16113 *
16114 * Copyright 2013, Jonathan Azoff
16115 * Licensed under the MIT license.
16116 *  https://github.com/azoff/overscroll/blob/master/mit.license
16117 *
16118 * For API documentation, see the README file
16119 *  http://azof.fr/pYCzuM
16120 *
16121 * Date: Monday, February 4th 2013
16122 */
16123
16124(function(global, dom, browser, math, wait, cancel, namespace, $, none){
16125
16126	// We want to run this plug-in in strict-mode
16127	// so that we may benefit from its optimizations
16128	'use strict';
16129
16130	// The key used to bind-instance specific data to an object
16131	var datakey = 'overscroll';
16132
16133	// runs feature detection for overscroll
16134	var compat = {
16135		animate: (function(){
16136			var fn = global.requestAnimationFrame    ||
16137				global.webkitRequestAnimationFrame ||
16138				global.mozRequestAnimationFrame    ||
16139				global.oRequestAnimationFrame      ||
16140				global.msRequestAnimationFrame     ||
16141				function(callback) { wait(callback, 1000/60); };
16142			return function(callback) {
16143				fn.call(global, callback);
16144			};
16145		})(),
16146		overflowScrolling: (function(){
16147			var style = '';
16148			var div = dom.createElement('div');
16149			var prefixes = ['webkit', 'moz', 'o', 'ms'];
16150			dom.body.appendChild(div);
16151			$.each(prefixes, function(i, prefix){
16152				div.style[prefix + 'OverflowScrolling'] = 'touch';
16153			});
16154			div.style.overflowScrolling = 'touch';
16155			var computedStyle = global.getComputedStyle(div);
16156			if (!!computedStyle.overflowScrolling) {
16157				style = 'overflow-scrolling';
16158			} else {
16159				$.each(prefixes, function(i, prefix){
16160					if (!!computedStyle[prefix + 'OverflowScrolling']) {
16161						style = '-' + prefix + '-overflow-scrolling';
16162					}
16163					return !style;
16164				});
16165			}
16166			div.parentNode.removeChild(div);
16167			return style;
16168		})(),
16169		cursor: (function() {
16170			var div = dom.createElement('div');
16171			var prefixes = ['webkit', 'moz'];
16172			var gmail = 'https://mail.google.com/mail/images/2/';
16173			var style = {
16174				grab:     'url('+gmail+'openhand.cur), move',
16175				grabbing: 'url('+gmail+'closedhand.cur), move'
16176			};
16177			dom.body.appendChild(div);
16178			$.each(prefixes, function(i, prefix){
16179				var found, cursor = '-' + prefix + '-grab';
16180				div.style.cursor = cursor;
16181				var computedStyle = global.getComputedStyle(div);
16182				found = computedStyle.cursor === cursor;
16183				if (found) {
16184					style = {
16185						grab:     '-' + prefix + '-grab',
16186						grabbing: '-' + prefix + '-grabbing'
16187					};
16188				}
16189				return !found;
16190			});
16191			div.parentNode.removeChild(div);
16192			return style;
16193		})()
16194	};
16195
16196	// These are all the events that could possibly
16197	// be used by the plug-in
16198	var events = {
16199		drag:       'mousemove touchmove',
16200		end:        'mouseup mouseleave click touchend touchcancel',
16201		hover:      'mouseenter mouseleave',
16202		ignored:    'select dragstart drag',
16203		scroll:     'scroll',
16204		start:      'mousedown touchstart',
16205		wheel:      'mousewheel DOMMouseScroll'
16206	};
16207
16208	// These settings are used to tweak drift settings
16209	// for the plug-in
16210	var settings = {
16211		captureThreshold:   3,
16212		driftDecay:         1.1,
16213		driftSequences:     22,
16214		driftTimeout:       100,
16215		scrollDelta:        15,
16216		thumbOpacity:       0.7,
16217		thumbThickness:     6,
16218		thumbTimeout:       400,
16219		wheelDelta:         20,
16220		wheelTicks:        120
16221	};
16222
16223	// These defaults are used to complement any options
16224	// passed into the plug-in entry point
16225	var defaults = {
16226		cancelOn:       'select,input,textarea',
16227		direction:      'multi',
16228		dragHold:       false,
16229		hoverThumbs:    false,
16230		scrollDelta:    settings.scrollDelta,
16231		showThumbs:     true,
16232		persistThumbs:  false,
16233		captureWheel:   true,
16234		wheelDelta:     settings.wheelDelta,
16235		wheelDirection: 'multi',
16236		zIndex:         999
16237	};
16238
16239	// Triggers a DOM event on the overscrolled element.
16240	// All events are namespaced under the overscroll name
16241	function triggerEvent(event, target) {
16242		target.trigger('overscroll:' + event);
16243	}
16244
16245	// Utility function to return a timestamp
16246	function time() {
16247		return (new Date()).getTime();
16248	}
16249
16250	// Captures the position from an event, modifies the properties
16251	// of the second argument to persist the position, and then
16252	// returns the modified object
16253	function capturePosition(event, position, index) {
16254		position.x = event.pageX;
16255		position.y = event.pageY;
16256		position.time = time();
16257		position.index = index;
16258		return position;
16259	}
16260
16261	// Used to move the thumbs around an overscrolled element
16262	function moveThumbs(thumbs, sizing, left, top) {
16263
16264		var ml, mt;
16265
16266		if (thumbs && thumbs.added) {
16267			if (thumbs.horizontal) {
16268				ml = left * (1 + sizing.container.width / sizing.container.scrollWidth);
16269				mt = top + sizing.thumbs.horizontal.top;
16270				thumbs.horizontal.css('margin', mt + 'px 0 0 ' + ml + 'px');
16271			}
16272			if (thumbs.vertical) {
16273				ml = left + sizing.thumbs.vertical.left;
16274				mt = top * (1 + sizing.container.height / sizing.container.scrollHeight);
16275				thumbs.vertical.css('margin', mt + 'px 0 0 ' + ml + 'px');
16276			}
16277		}
16278
16279	}
16280
16281	// Used to toggle the thumbs on and off
16282	// of an overscrolled element
16283	function toggleThumbs(thumbs, options, dragging) {
16284		if (thumbs && thumbs.added && !options.persistThumbs) {
16285			if (dragging) {
16286				if (thumbs.vertical) {
16287					thumbs.vertical.stop(true, true).fadeTo('fast', settings.thumbOpacity);
16288				}
16289				if (thumbs.horizontal) {
16290					thumbs.horizontal.stop(true, true).fadeTo('fast', settings.thumbOpacity);
16291				}
16292			} else {
16293				if (thumbs.vertical) {
16294					thumbs.vertical.fadeTo('fast', 0);
16295				}
16296				if (thumbs.horizontal) {
16297					thumbs.horizontal.fadeTo('fast', 0);
16298				}
16299			}
16300		}
16301	}
16302
16303	// Defers click event listeners to after a mouseup event.
16304	// Used to avoid unintentional clicks
16305	function deferClick(target) {
16306		var clicks, key = 'events';
16307		var events = $._data ? $._data(target[0], key) : target.data(key);
16308		if (events && events.click) {
16309			clicks = events.click.slice();
16310			target.off('click').one('click', function(){
16311				$.each(clicks, function(i, click){
16312					target.click(click);
16313				}); return false;
16314			});
16315		}
16316	}
16317
16318	// Toggles thumbs on hover. This event is only triggered
16319	// if the hoverThumbs option is set
16320	function hover(event) {
16321		var data = event.data,
16322		thumbs   = data.thumbs,
16323		options  = data.options,
16324		dragging = event.type === 'mouseenter';
16325		toggleThumbs(thumbs, options, dragging);
16326	}
16327
16328	// This function is only ever used when the overscrolled element
16329	// scrolled outside of the scope of this plugin.
16330	function scroll(event) {
16331		var data = event.data;
16332		if (!data.flags.dragged) {
16333			moveThumbs(data.thumbs, data.sizing, this.scrollLeft, this.scrollTop);
16334		}
16335	}
16336
16337	// handles mouse wheel scroll events
16338	function wheel(event) {
16339
16340		// prevent any default wheel behavior
16341		event.preventDefault();
16342
16343		var data = event.data,
16344		options = data.options,
16345		sizing = data.sizing,
16346		thumbs = data.thumbs,
16347		dwheel = data.wheel,
16348		flags = data.flags,
16349		original = event.originalEvent,
16350		delta = 0, deltaX = 0, deltaY = 0;
16351
16352		// stop any drifts
16353		flags.drifting = false;
16354
16355		// normalize the wheel ticks
16356		if (original.detail) {
16357			delta = -original.detail;
16358			if (original.detailX) {
16359				deltaX = -original.detailX;
16360			}
16361			if (original.detailY) {
16362				deltaY = -original.detailY;
16363			}
16364		} else if (original.wheelDelta) {
16365			delta = original.wheelDelta / settings.wheelTicks;
16366			if (original.wheelDeltaX) {
16367				deltaX = original.wheelDeltaX / settings.wheelTicks;
16368			}
16369			if (original.wheelDeltaY) {
16370				deltaY = original.wheelDeltaY / settings.wheelTicks;
16371			}
16372		}
16373
16374		// apply a pixel delta to each tick
16375		delta  *= options.wheelDelta;
16376		deltaX *= options.wheelDelta;
16377		deltaY *= options.wheelDelta;
16378
16379		// initialize flags if this is the first tick
16380		if (!dwheel) {
16381			data.target.data(datakey).dragging = flags.dragging = true;
16382			data.wheel = dwheel = { timeout: null };
16383			toggleThumbs(thumbs, options, true);
16384		}
16385
16386		// actually modify scroll offsets
16387		if (options.wheelDirection === 'vertical'){
16388			this.scrollTop -= delta;
16389		} else if ( options.wheelDirection === 'horizontal') {
16390			this.scrollLeft -= delta;
16391		} else {
16392			this.scrollLeft -= deltaX;
16393			this.scrollTop  -= deltaY || delta;
16394		}
16395
16396		if (dwheel.timeout) { cancel(dwheel.timeout); }
16397
16398		moveThumbs(thumbs, sizing, this.scrollLeft, this.scrollTop);
16399
16400		dwheel.timeout = wait(function() {
16401			data.target.data(datakey).dragging = flags.dragging = false;
16402			toggleThumbs(thumbs, options, data.wheel = null);
16403		}, settings.thumbTimeout);
16404
16405	}
16406
16407	// updates the current scroll offset during a mouse move
16408	function drag(event) {
16409
16410		event.preventDefault();
16411
16412		var data = event.data,
16413		touches  = event.originalEvent.touches,
16414		options  = data.options,
16415		sizing   = data.sizing,
16416		thumbs   = data.thumbs,
16417		position = data.position,
16418		flags    = data.flags,
16419		target   = data.target.get(0);
16420
16421
16422		// correct page coordinates for touch devices
16423		if (touches && touches.length) {
16424			event = touches[0];
16425		}
16426
16427		if (!flags.dragged) {
16428			toggleThumbs(thumbs, options, true);
16429		}
16430
16431		flags.dragged = true;
16432
16433		if (options.direction !== 'vertical') {
16434			target.scrollLeft -= (event.pageX - position.x);
16435		}
16436
16437		if (data.options.direction !== 'horizontal') {
16438			target.scrollTop -= (event.pageY - position.y);
16439		}
16440
16441		capturePosition(event, data.position);
16442
16443		if (--data.capture.index <= 0) {
16444			data.target.data(datakey).dragging = flags.dragging = true;
16445			capturePosition(event, data.capture, settings.captureThreshold);
16446		}
16447
16448		moveThumbs(thumbs, sizing, target.scrollLeft, target.scrollTop);
16449
16450	}
16451
16452	// sends the overscrolled element into a drift
16453	function drift(target, event, callback) {
16454
16455		var data   = event.data, dx, dy, xMod, yMod,
16456		capture    = data.capture,
16457		options    = data.options,
16458		sizing     = data.sizing,
16459		thumbs     = data.thumbs,
16460		elapsed    = time() - capture.time,
16461		scrollLeft = target.scrollLeft,
16462		scrollTop  = target.scrollTop,
16463		decay      = settings.driftDecay;
16464
16465		// only drift if enough time has passed since
16466		// the last capture event
16467		if (elapsed > settings.driftTimeout) {
16468			callback(data); return;
16469		}
16470
16471		// determine offset between last capture and current time
16472		dx = options.scrollDelta * (event.pageX - capture.x);
16473		dy = options.scrollDelta * (event.pageY - capture.y);
16474
16475		// update target scroll offsets
16476		if (options.direction !== 'vertical') {
16477			scrollLeft -= dx;
16478		} if (options.direction !== 'horizontal') {
16479			scrollTop -= dy;
16480		}
16481
16482		// split the distance to travel into a set of sequences
16483		xMod = dx / settings.driftSequences;
16484		yMod = dy / settings.driftSequences;
16485
16486		triggerEvent('driftstart', data.target);
16487
16488		data.drifting = true;
16489
16490		// animate the drift sequence
16491		compat.animate(function render() {
16492			if (data.drifting) {
16493				var min = 1, max = -1;
16494				data.drifting = false;
16495				if (yMod > min && target.scrollTop > scrollTop || yMod < max && target.scrollTop < scrollTop) {
16496					data.drifting = true;
16497					target.scrollTop -= yMod;
16498					yMod /= decay;
16499				}
16500				if (xMod > min && target.scrollLeft > scrollLeft || xMod < max && target.scrollLeft < scrollLeft) {
16501					data.drifting = true;
16502					target.scrollLeft -= xMod;
16503					xMod /= decay;
16504				}
16505				moveThumbs(thumbs, sizing, target.scrollLeft, target.scrollTop);
16506				compat.animate(render);
16507			} else {
16508				triggerEvent('driftend', data.target);
16509				callback(data);
16510			}
16511		});
16512
16513	}
16514
16515	// starts the drag operation and binds the mouse move handler
16516	function start(event) {
16517
16518		var data = event.data,
16519		touches  = event.originalEvent.touches,
16520		target   = data.target,
16521		dstart   = data.start = $(event.target),
16522		flags    = data.flags;
16523
16524		// stop any drifts
16525		flags.drifting = false;
16526
16527		// only start drag if the user has not explictly banned it.
16528		if (dstart.size() && !dstart.is(data.options.cancelOn)) {
16529
16530			// without this the simple "click" event won't be recognized on touch clients
16531			if (!touches) { event.preventDefault(); }
16532
16533			if (!compat.overflowScrolling) {
16534				target.css('cursor', compat.cursor.grabbing);
16535				target.data(datakey).dragging = flags.dragging = flags.dragged = false;
16536
16537				// apply the drag listeners to the doc or target
16538				if(data.options.dragHold) {
16539					$(document).on(events.drag, data, drag);
16540				} else {
16541					target.on(events.drag, data, drag);
16542				}
16543			}
16544
16545			data.position = capturePosition(event, {});
16546			data.capture = capturePosition(event, {}, settings.captureThreshold);
16547			triggerEvent('dragstart', target);
16548
16549		}
16550
16551	}
16552
16553	// ends the drag operation and unbinds the mouse move handler
16554	function stop(event) {
16555
16556		var data = event.data,
16557		target = data.target,
16558		options = data.options,
16559		flags = data.flags,
16560		thumbs = data.thumbs,
16561
16562		// hides the thumbs after the animation is done
16563		done = function () {
16564			if (thumbs && !options.hoverThumbs) {
16565				toggleThumbs(thumbs, options, false);
16566			}
16567		};
16568
16569		// remove drag listeners from doc or target
16570		if(options.dragHold) {
16571			$(document).unbind(events.drag, drag);
16572		} else {
16573			target.unbind(events.drag, drag);
16574		}
16575
16576		// only fire events and drift if we started with a
16577		// valid position
16578		if (data.position) {
16579
16580			triggerEvent('dragend', target);
16581
16582			// only drift if a drag passed our threshold
16583			if (flags.dragging && !compat.overflowScrolling) {
16584				drift(target.get(0), event, done);
16585			} else {
16586				done();
16587			}
16588
16589		}
16590
16591		// only if we moved, and the mouse down is the same as
16592		// the mouse up target do we defer the event
16593		if (flags.dragging && !compat.overflowScrolling && data.start && data.start.is(event.target)) {
16594			deferClick(data.start);
16595		}
16596
16597		// clear all internal flags and settings
16598		target.data(datakey).dragging =
16599			data.start     =
16600			data.capture   =
16601			data.position  =
16602			flags.dragged  =
16603			flags.dragging = false;
16604
16605		// set the cursor back to normal
16606		target.css('cursor', compat.cursor.grab);
16607
16608	}
16609
16610	// Ensures that a full set of options are provided
16611	// for the plug-in. Also does some validation
16612	function getOptions(options) {
16613
16614		// fill in missing values with defaults
16615		options = $.extend({}, defaults, options);
16616
16617		// check for inconsistent directional restrictions
16618		if (options.direction !== 'multi' && options.direction !== options.wheelDirection) {
16619			options.wheelDirection = options.direction;
16620		}
16621
16622		// ensure positive values for deltas
16623		options.scrollDelta = math.abs(parseFloat(options.scrollDelta));
16624		options.wheelDelta  = math.abs(parseFloat(options.wheelDelta));
16625
16626		// fix values for scroll offset
16627		options.scrollLeft = options.scrollLeft === none ? null : math.abs(parseFloat(options.scrollLeft));
16628		options.scrollTop  = options.scrollTop  === none ? null : math.abs(parseFloat(options.scrollTop));
16629
16630		return options;
16631
16632	}
16633
16634	// Returns the sizing information (bounding box) for the
16635	// target DOM element
16636	function getSizing(target) {
16637
16638		var $target  = $(target),
16639		width        = $target.width(),
16640		height       = $target.height(),
16641		scrollWidth  = width >= target.scrollWidth ? width : target.scrollWidth,
16642		scrollHeight = height >= target.scrollHeight ? height : target.scrollHeight,
16643		hasScroll    = scrollWidth > width || scrollHeight > height;
16644
16645		return {
16646			valid: hasScroll,
16647			container: {
16648				width: width,
16649				height: height,
16650				scrollWidth: scrollWidth,
16651				scrollHeight: scrollHeight
16652			},
16653			thumbs: {
16654				horizontal: {
16655					width: width * width / scrollWidth,
16656					height: settings.thumbThickness,
16657					corner: settings.thumbThickness / 2,
16658					left: 0,
16659					top: height - settings.thumbThickness
16660				},
16661				vertical: {
16662					width: settings.thumbThickness,
16663					height: height * height / scrollHeight,
16664					corner: settings.thumbThickness / 2,
16665					left: width - settings.thumbThickness,
16666					top: 0
16667				}
16668			}
16669		};
16670
16671	}
16672
16673	// Attempts to get (or implicitly creates) the
16674	// remover function for the target passed
16675	// in as an argument
16676	function getRemover(target, orCreate) {
16677
16678		var $target = $(target), thumbs,
16679		data        = $target.data(datakey) || {},
16680		style       = $target.attr('style'),
16681		fallback    = orCreate ? function () {
16682
16683			data = $target.data(datakey);
16684			thumbs = data.thumbs;
16685
16686			// restore original styles (if any)
16687			if (style) {
16688				$target.attr('style', style);
16689			} else {
16690				$target.removeAttr('style');
16691			}
16692
16693			// remove any created thumbs
16694			if (thumbs) {
16695				if (thumbs.horizontal) { thumbs.horizontal.remove(); }
16696				if (thumbs.vertical)   { thumbs.vertical.remove();   }
16697			}
16698
16699			// remove any bound overscroll events and data
16700			$target
16701				.removeData(datakey)
16702				.off(events.wheel,      wheel)
16703				.off(events.start,      start)
16704				.off(events.end,        stop)
16705				.off(events.ignored,    ignore);
16706
16707		} : $.noop;
16708
16709		return $.isFunction(data.remover) ? data.remover : fallback;
16710
16711	}
16712
16713	// Genterates CSS specific to a particular thumb.
16714	// It requires sizing data and options
16715	function getThumbCss(size, options) {
16716		return {
16717			position: 'absolute',
16718			opacity: options.persistThumbs ? settings.thumbOpacity : 0,
16719			'background-color': 'black',
16720			width: size.width + 'px',
16721			height: size.height + 'px',
16722			'border-radius': size.corner + 'px',
16723			'margin': size.top + 'px 0 0 ' + size.left + 'px',
16724			'z-index': options.zIndex
16725		};
16726	}
16727
16728	// Creates the DOM elements used as "thumbs" within
16729	// the target container.
16730	function createThumbs(target, sizing, options) {
16731
16732		var div = '<div/>',
16733		thumbs  = {},
16734		css     = false;
16735
16736		if (sizing.container.scrollWidth > 0 && options.direction !== 'vertical') {
16737			css = getThumbCss(sizing.thumbs.horizontal, options);
16738			thumbs.horizontal = $(div).css(css).prependTo(target);
16739		}
16740
16741		if (sizing.container.scrollHeight > 0 && options.direction !== 'horizontal') {
16742			css = getThumbCss(sizing.thumbs.vertical, options);
16743			thumbs.vertical = $(div).css(css).prependTo(target);
16744		}
16745
16746		thumbs.added = !!css;
16747
16748		return thumbs;
16749
16750	}
16751
16752	// ignores events on the overscroll element
16753	function ignore(event) {
16754		event.preventDefault();
16755	}
16756
16757	// This function takes a jQuery element, some
16758	// (optional) options, and sets up event metadata
16759	// for each instance the plug-in affects
16760	function setup(target, options) {
16761
16762		// create initial data properties for this instance
16763		options = getOptions(options);
16764		var sizing = getSizing(target),
16765		thumbs, data = {
16766			options: options, sizing: sizing,
16767			flags: { dragging: false },
16768			remover: getRemover(target, true)
16769		};
16770
16771		// only apply handlers if the overscrolled element
16772		// actually has an area to scroll
16773		if (sizing.valid) {
16774			// provide a circular-reference, enable events, and
16775			// apply any required CSS
16776			data.target = target = $(target).css({
16777				position: 'relative',
16778				cursor: compat.cursor.grab
16779			}).on(events.start, data, start)
16780				.on(events.end, data, stop)
16781				.on(events.ignored, data, ignore);
16782
16783			// apply the stop listeners for drag end
16784			if(options.dragHold) {
16785				$(document).on(events.end, data, stop);
16786			} else {
16787				data.target.on(events.end, data, stop);
16788			}
16789
16790			// apply any user-provided scroll offsets
16791			if (options.scrollLeft !== null) {
16792				target.scrollLeft(options.scrollLeft);
16793			} if (options.scrollTop !== null) {
16794				target.scrollTop(options.scrollTop);
16795			}
16796
16797			// use native oversroll, if it exists
16798			if (compat.overflowScrolling) {
16799				target.css(compat.overflowScrolling, 'touch');
16800			} else {
16801				target.on(events.scroll, data, scroll);
16802			}
16803
16804			// check to see if the user would like mousewheel support
16805			if (options.captureWheel) {
16806				target.on(events.wheel, data, wheel);
16807			}
16808
16809			// add thumbs and listeners (if we're showing them)
16810			if (options.showThumbs) {
16811				if (compat.overflowScrolling) {
16812					target.css('overflow', 'scroll');
16813				} else {
16814					target.css('overflow', 'hidden');
16815					data.thumbs = thumbs = createThumbs(target, sizing, options);
16816					if (thumbs.added) {
16817						moveThumbs(thumbs, sizing, target.scrollLeft(), target.scrollTop());
16818						if (options.hoverThumbs) {
16819							target.on(events.hover, data, hover);
16820						}
16821					}
16822				}
16823			} else {
16824				target.css('overflow', 'hidden');
16825			}
16826
16827			target.data(datakey, data);
16828		}
16829
16830	}
16831
16832	// Removes any event listeners and other instance-specific
16833	// data from the target. It attempts to leave the target
16834	// at the state it found it.
16835	function teardown(target) {
16836		getRemover(target)();
16837	}
16838
16839	// This is the entry-point for enabling the plug-in;
vendor: 6,514 bytes, lines 16840-17080
16840	// You can find it's exposure point at the end
16841	// of this closure
16842	function overscroll(options) {
16843		return this.removeOverscroll().each(function() {
16844			setup(this, options);
16845		});
16846	}
16847
16848	// This is the entry-point for disabling the plug-in;
16849	// You can find it's exposure point at the end
16850	// of this closure
16851	function removeOverscroll() {
16852		return this.each(function () {
16853			teardown(this);
16854		});
16855	}
16856
16857	// Extend overscroll to expose settings to the user
16858	overscroll.settings = settings;
16859
16860	// Extend jQuery's prototype to expose the plug-in.
16861	// If the supports native overflowScrolling, overscroll will not
16862	// attempt to override the browser's built in support
16863	$.extend(namespace, {
16864		overscroll:         overscroll,
16865		removeOverscroll:   removeOverscroll
16866	});
16867
16868})(window, document, navigator, Math, setTimeout, clearTimeout, jQuery.fn, jQuery);
16869/*!
16870 * fancyBox - jQuery Plugin
16871 * version: 2.1.4 (Thu, 10 Jan 2013)
16872 * @requires jQuery v1.6 or later
16873 *
16874 * Examples at http://fancyapps.com/fancybox/
16875 * License: www.fancyapps.com/fancybox/#license
16876 *
16877 * Copyright 2012 Janis Skarnelis - [email protected]
16878 *
16879 */
16880
16881
16882(function (window, document, $, undefined) {
16883	"use strict";
16884
16885	var W = $(window),
16886		D = $(document),
16887		F = $.fancybox = function () {
16888			F.open.apply( this, arguments );
16889		},
16890		IE =  navigator.userAgent.match(/msie/),
16891		didUpdate = null,
16892		isTouch	  = document.createTouch !== undefined,
16893
16894		isQuery	= function(obj) {
16895			return obj && obj.hasOwnProperty && obj instanceof $;
16896		},
16897		isString = function(str) {
16898			return str && $.type(str) === "string";
16899		},
16900		isPercentage = function(str) {
16901			return isString(str) && str.indexOf('%') > 0;
16902		},
16903		isScrollable = function(el) {
16904			return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
16905		},
16906		getScalar = function(orig, dim) {
16907			var value = parseInt(orig, 10) || 0;
16908
16909			if (dim && isPercentage(orig)) {
16910				value = F.getViewport()[ dim ] / 100 * value;
16911			}
16912
16913			return Math.ceil(value);
16914		},
16915		getValue = function(value, dim) {
16916			return getScalar(value, dim) + 'px';
16917		};
16918
16919	$.extend(F, {
16920		// The current version of fancyBox
16921		version: '2.1.4',
16922
16923		defaults: {
16924			padding : 15,
16925			margin  : 20,
16926
16927			width     : 800,
16928			height    : 600,
16929			minWidth  : 100,
16930			minHeight : 100,
16931			maxWidth  : 9999,
16932			maxHeight : 9999,
16933
16934			autoSize   : true,
16935			autoHeight : false,
16936			autoWidth  : false,
16937
16938			autoResize  : true,
16939			autoCenter  : !isTouch,
16940			fitToView   : true,
16941			aspectRatio : false,
16942			topRatio    : 0.5,
16943			leftRatio   : 0.5,
16944
16945			scrolling : 'auto', // 'auto', 'yes' or 'no'
16946			wrapCSS   : '',
16947
16948			arrows     : true,
16949			closeBtn   : true,
16950			closeClick : false,
16951			nextClick  : false,
16952			mouseWheel : true,
16953			autoPlay   : false,
16954			playSpeed  : 3000,
16955			preload    : 3,
16956			modal      : false,
16957			loop       : true,
16958
16959			ajax  : {
16960				dataType : 'html',
16961				headers  : { 'X-fancyBox': true }
16962			},
16963			iframe : {
16964				scrolling : 'auto',
16965				preload   : true
16966			},
16967			swf : {
16968				wmode: 'transparent',
16969				allowfullscreen   : 'true',
16970				allowscriptaccess : 'always'
16971			},
16972
16973			keys  : {
16974				next : {
16975					13 : 'left', // enter
16976					34 : 'up',   // page down
16977					39 : 'left', // right arrow
16978					40 : 'up'    // down arrow
16979				},
16980				prev : {
16981					8  : 'right',  // backspace
16982					33 : 'down',   // page up
16983					37 : 'right',  // left arrow
16984					38 : 'down'    // up arrow
16985				},
16986				close  : [27], // escape key
16987				play   : [32], // space - start/stop slideshow
16988				toggle : [70]  // letter "f" - toggle fullscreen
16989			},
16990
16991			direction : {
16992				next : 'left',
16993				prev : 'right'
16994			},
16995
16996			scrollOutside  : true,
16997
16998			// Override some properties
16999			index   : 0,
17000			type    : null,
17001			href    : null,
17002			content : null,
17003			title   : null,
17004
17005			// HTML templates
17006			tpl: {
17007				wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
17008				image    : '<img class="fancybox-image" src="{href}" alt="" />',
17009				iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
17010				error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
17011				closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
17012				next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
17013				prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
17014			},
17015
17016			// Properties for each animation type
17017			// Opening fancyBox
17018			openEffect  : 'fade', // 'elastic', 'fade' or 'none'
17019			openSpeed   : 250,
17020			openEasing  : 'swing',
17021			openOpacity : true,
17022			openMethod  : 'zoomIn',
17023
17024			// Closing fancyBox
17025			closeEffect  : 'fade', // 'elastic', 'fade' or 'none'
17026			closeSpeed   : 250,
17027			closeEasing  : 'swing',
17028			closeOpacity : true,
17029			closeMethod  : 'zoomOut',
17030
17031			// Changing next gallery item
17032			nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
17033			nextSpeed  : 250,
17034			nextEasing : 'swing',
17035			nextMethod : 'changeIn',
17036
17037			// Changing previous gallery item
17038			prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
17039			prevSpeed  : 250,
17040			prevEasing : 'swing',
17041			prevMethod : 'changeOut',
17042
17043			// Enable default helpers
17044			helpers : {
17045				overlay : true,
17046				title   : true
17047			},
17048
17049			// Callbacks
17050			onCancel     : $.noop, // If canceling
17051			beforeLoad   : $.noop, // Before loading
17052			afterLoad    : $.noop, // After loading
17053			beforeShow   : $.noop, // Before changing in current item
17054			afterShow    : $.noop, // After opening
17055			beforeChange : $.noop, // Before changing gallery item
17056			beforeClose  : $.noop, // Before closing
17057			afterClose   : $.noop  // After closing
17058		},
17059
17060		//Current state
17061		group    : {}, // Selected group
17062		opts     : {}, // Group options
17063		previous : null,  // Previous element
17064		coming   : null,  // Element being loaded
17065		current  : null,  // Currently loaded element
17066		isActive : false, // Is activated
17067		isOpen   : false, // Is currently open
17068		isOpened : false, // Have been fully opened at least once
17069
17070		wrap  : null,
17071		skin  : null,
17072		outer : null,
17073		inner : null,
17074
17075		player : {
17076			timer    : null,
17077			isActive : false
17078		},
17079
17080		// Loaders
vendor: 34,999 bytes, lines 17081-18558
17081		ajaxLoad   : null,
17082		imgPreload : null,
17083
17084		// Some collections
17085		transitions : {},
17086		helpers     : {},
17087
17088		/*
17089		 *	Static methods
17090		 */
17091
17092		open: function (group, opts) {
17093			if (!group) {
17094				return;
17095			}
17096
17097			if (!$.isPlainObject(opts)) {
17098				opts = {};
17099			}
17100
17101			// Close if already active
17102			if (false === F.close(true)) {
17103				return;
17104			}
17105
17106			// Normalize group
17107			if (!$.isArray(group)) {
17108				group = isQuery(group) ? $(group).get() : [group];
17109			}
17110
17111			// Recheck if the type of each element is `object` and set content type (image, ajax, etc)
17112			$.each(group, function(i, element) {
17113				var obj = {},
17114					href,
17115					title,
17116					content,
17117					type,
17118					rez,
17119					hrefParts,
17120					selector;
17121
17122				if ($.type(element) === "object") {
17123					// Check if is DOM element
17124					if (element.nodeType) {
17125						element = $(element);
17126					}
17127
17128					if (isQuery(element)) {
17129						obj = {
17130							href    : element.data('fancybox-href') || element.attr('href'),
17131							title   : element.data('fancybox-title') || element.attr('title'),
17132							isDom   : true,
17133							element : element
17134						};
17135
17136						if ($.metadata) {
17137							$.extend(true, obj, element.metadata());
17138						}
17139
17140					} else {
17141						obj = element;
17142					}
17143				}
17144
17145				href  = opts.href  || obj.href || (isString(element) ? element : null);
17146				title = opts.title !== undefined ? opts.title : obj.title || '';
17147
17148				content = opts.content || obj.content;
17149				type    = content ? 'html' : (opts.type  || obj.type);
17150
17151				if (!type && obj.isDom) {
17152					type = element.data('fancybox-type');
17153
17154					if (!type) {
17155						rez  = element.prop('class').match(/fancybox\.(\w+)/);
17156						type = rez ? rez[1] : null;
17157					}
17158				}
17159
17160				if (isString(href)) {
17161					// Try to guess the content type
17162					if (!type) {
17163						if (F.isImage(href)) {
17164							type = 'image';
17165
17166						} else if (F.isSWF(href)) {
17167							type = 'swf';
17168
17169						} else if (href.charAt(0) === '#') {
17170							type = 'inline';
17171
17172						} else if (isString(element)) {
17173							type    = 'html';
17174							content = element;
17175						}
17176					}
17177
17178					// Split url into two pieces with source url and content selector, e.g,
17179					// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
17180					if (type === 'ajax') {
17181						hrefParts = href.split(/\s+/, 2);
17182						href      = hrefParts.shift();
17183						selector  = hrefParts.shift();
17184					}
17185				}
17186
17187				if (!content) {
17188					if (type === 'inline') {
17189						if (href) {
17190							content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
17191
17192						} else if (obj.isDom) {
17193							content = element;
17194						}
17195
17196					} else if (type === 'html') {
17197						content = href;
17198
17199					} else if (!type && !href && obj.isDom) {
17200						type    = 'inline';
17201						content = element;
17202					}
17203				}
17204
17205				$.extend(obj, {
17206					href     : href,
17207					type     : type,
17208					content  : content,
17209					title    : title,
17210					selector : selector
17211				});
17212
17213				group[ i ] = obj;
17214			});
17215
17216			// Extend the defaults
17217			F.opts = $.extend(true, {}, F.defaults, opts);
17218
17219			// All options are merged recursive except keys
17220			if (opts.keys !== undefined) {
17221				F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
17222			}
17223
17224			F.group = group;
17225
17226			return F._start(F.opts.index);
17227		},
17228
17229		// Cancel image loading or abort ajax request
17230		cancel: function () {
17231			var coming = F.coming;
17232
17233			if (!coming || false === F.trigger('onCancel')) {
17234				return;
17235			}
17236
17237			F.hideLoading();
17238
17239			if (F.ajaxLoad) {
17240				F.ajaxLoad.abort();
17241			}
17242
17243			F.ajaxLoad = null;
17244
17245			if (F.imgPreload) {
17246				F.imgPreload.onload = F.imgPreload.onerror = null;
17247			}
17248
17249			if (coming.wrap) {
17250				coming.wrap.stop(true, true).trigger('onReset').remove();
17251			}
17252
17253			F.coming = null;
17254
17255			// If the first item has been canceled, then clear everything
17256			if (!F.current) {
17257				F._afterZoomOut( coming );
17258			}
17259		},
17260
17261		// Start closing animation if is open; remove immediately if opening/closing
17262		close: function (event) {
17263			F.cancel();
17264
17265			if (false === F.trigger('beforeClose')) {
17266				return;
17267			}
17268
17269			F.unbindEvents();
17270
17271			if (!F.isActive) {
17272				return;
17273			}
17274
17275			if (!F.isOpen || event === true) {
17276				$('.fancybox-wrap').stop(true).trigger('onReset').remove();
17277
17278				F._afterZoomOut();
17279
17280			} else {
17281				F.isOpen = F.isOpened = false;
17282				F.isClosing = true;
17283
17284				$('.fancybox-item, .fancybox-nav').remove();
17285
17286				F.wrap.stop(true, true).removeClass('fancybox-opened');
17287
17288				F.transitions[ F.current.closeMethod ]();
17289			}
17290		},
17291
17292		// Manage slideshow:
17293		//   $.fancybox.play(); - toggle slideshow
17294		//   $.fancybox.play( true ); - start
17295		//   $.fancybox.play( false ); - stop
17296		play: function ( action ) {
17297			var clear = function () {
17298					clearTimeout(F.player.timer);
17299				},
17300				set = function () {
17301					clear();
17302
17303					if (F.current && F.player.isActive) {
17304						F.player.timer = setTimeout(F.next, F.current.playSpeed);
17305					}
17306				},
17307				stop = function () {
17308					clear();
17309
17310					$('body').unbind('.player');
17311
17312					F.player.isActive = false;
17313
17314					F.trigger('onPlayEnd');
17315				},
17316				start = function () {
17317					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
17318						F.player.isActive = true;
17319
17320						$('body').bind({
17321							'afterShow.player onUpdate.player'   : set,
17322							'onCancel.player beforeClose.player' : stop,
17323							'beforeLoad.player' : clear
17324						});
17325
17326						set();
17327
17328						F.trigger('onPlayStart');
17329					}
17330				};
17331
17332			if (action === true || (!F.player.isActive && action !== false)) {
17333				start();
17334			} else {
17335				stop();
17336			}
17337		},
17338
17339		// Navigate to next gallery item
17340		next: function ( direction ) {
17341			var current = F.current;
17342
17343			if (current) {
17344				if (!isString(direction)) {
17345					direction = current.direction.next;
17346				}
17347
17348				F.jumpto(current.index + 1, direction, 'next');
17349			}
17350		},
17351
17352		// Navigate to previous gallery item
17353		prev: function ( direction ) {
17354			var current = F.current;
17355
17356			if (current) {
17357				if (!isString(direction)) {
17358					direction = current.direction.prev;
17359				}
17360
17361				F.jumpto(current.index - 1, direction, 'prev');
17362			}
17363		},
17364
17365		// Navigate to gallery item by index
17366		jumpto: function ( index, direction, router ) {
17367			var current = F.current;
17368
17369			if (!current) {
17370				return;
17371			}
17372
17373			index = getScalar(index);
17374
17375			F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
17376			F.router    = router || 'jumpto';
17377
17378			if (current.loop) {
17379				if (index < 0) {
17380					index = current.group.length + (index % current.group.length);
17381				}
17382
17383				index = index % current.group.length;
17384			}
17385
17386			if (current.group[ index ] !== undefined) {
17387				F.cancel();
17388
17389				F._start(index);
17390			}
17391		},
17392
17393		// Center inside viewport and toggle position type to fixed or absolute if needed
17394		reposition: function (e, onlyAbsolute) {
17395			var current = F.current,
17396				wrap    = current ? current.wrap : null,
17397				pos;
17398
17399			if (wrap) {
17400				pos = F._getPosition(onlyAbsolute);
17401
17402				if (e && e.type === 'scroll') {
17403					delete pos.position;
17404
17405					wrap.stop(true, true).animate(pos, 200);
17406
17407				} else {
17408					wrap.css(pos);
17409
17410					current.pos = $.extend({}, current.dim, pos);
17411				}
17412			}
17413		},
17414
17415		update: function (e) {
17416			var type = (e && e.type),
17417				anyway = !type || type === 'orientationchange';
17418
17419			if (anyway) {
17420				clearTimeout(didUpdate);
17421
17422				didUpdate = null;
17423			}
17424
17425			if (!F.isOpen || didUpdate) {
17426				return;
17427			}
17428
17429			didUpdate = setTimeout(function() {
17430				var current = F.current;
17431
17432				if (!current || F.isClosing) {
17433					return;
17434				}
17435
17436				F.wrap.removeClass('fancybox-tmp');
17437
17438				if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
17439					F._setDimension();
17440				}
17441
17442				if (!(type === 'scroll' && current.canShrink)) {
17443					F.reposition(e);
17444				}
17445
17446				F.trigger('onUpdate');
17447
17448				didUpdate = null;
17449
17450			}, (anyway && !isTouch ? 0 : 300));
17451		},
17452
17453		// Shrink content to fit inside viewport or restore if resized
17454		toggle: function ( action ) {
17455			if (F.isOpen) {
17456				F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
17457
17458				// Help browser to restore document dimensions
17459				if (isTouch) {
17460					F.wrap.removeAttr('style').addClass('fancybox-tmp');
17461
17462					F.trigger('onUpdate');
17463				}
17464
17465				F.update();
17466			}
17467		},
17468
17469		hideLoading: function () {
17470			D.unbind('.loading');
17471
17472			$('#fancybox-loading').remove();
17473		},
17474
17475		showLoading: function () {
17476			var el, viewport;
17477
17478			F.hideLoading();
17479
17480			el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
17481
17482			// If user will press the escape-button, the request will be canceled
17483			D.bind('keydown.loading', function(e) {
17484				if ((e.which || e.keyCode) === 27) {
17485					e.preventDefault();
17486
17487					F.cancel();
17488				}
17489			});
17490
17491			if (!F.defaults.fixed) {
17492				viewport = F.getViewport();
17493
17494				el.css({
17495					position : 'absolute',
17496					top  : (viewport.h * 0.5) + viewport.y,
17497					left : (viewport.w * 0.5) + viewport.x
17498				});
17499			}
17500		},
17501
17502		getViewport: function () {
17503			var locked = (F.current && F.current.locked) || false,
17504				rez    = {
17505					x: W.scrollLeft(),
17506					y: W.scrollTop()
17507				};
17508
17509			if (locked) {
17510				rez.w = locked[0].clientWidth;
17511				rez.h = locked[0].clientHeight;
17512
17513			} else {
17514				// See http://bugs.jquery.com/ticket/6724
17515				rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();
17516				rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
17517			}
17518
17519			return rez;
17520		},
17521
17522		// Unbind the keyboard / clicking actions
17523		unbindEvents: function () {
17524			if (F.wrap && isQuery(F.wrap)) {
17525				F.wrap.unbind('.fb');
17526			}
17527
17528			D.unbind('.fb');
17529			W.unbind('.fb');
17530		},
17531
17532		bindEvents: function () {
17533			var current = F.current,
17534				keys;
17535
17536			if (!current) {
17537				return;
17538			}
17539
17540			// Changing document height on iOS devices triggers a 'resize' event,
17541			// that can change document height... repeating infinitely
17542			W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
17543
17544			keys = current.keys;
17545
17546			if (keys) {
17547				D.bind('keydown.fb', function (e) {
17548					var code   = e.which || e.keyCode,
17549						target = e.target || e.srcElement;
17550
17551					// Skip esc key if loading, because showLoading will cancel preloading
17552					if (code === 27 && F.coming) {
17553						return false;
17554					}
17555
17556					// Ignore key combinations and key events within form elements
17557					if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
17558						$.each(keys, function(i, val) {
17559							if (current.group.length > 1 && val[ code ] !== undefined) {
17560								F[ i ]( val[ code ] );
17561
17562								e.preventDefault();
17563								return false;
17564							}
17565
17566							if ($.inArray(code, val) > -1) {
17567								F[ i ] ();
17568
17569								e.preventDefault();
17570								return false;
17571							}
17572						});
17573					}
17574				});
17575			}
17576
17577			if ($.fn.mousewheel && current.mouseWheel) {
17578				F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
17579					var target = e.target || null,
17580						parent = $(target),
17581						canScroll = false;
17582
17583					while (parent.length) {
17584						if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
17585							break;
17586						}
17587
17588						canScroll = isScrollable( parent[0] );
17589						parent    = $(parent).parent();
17590					}
17591
17592					if (delta !== 0 && !canScroll) {
17593						if (F.group.length > 1 && !current.canShrink) {
17594							if (deltaY > 0 || deltaX > 0) {
17595								F.prev( deltaY > 0 ? 'down' : 'left' );
17596
17597							} else if (deltaY < 0 || deltaX < 0) {
17598								F.next( deltaY < 0 ? 'up' : 'right' );
17599							}
17600
17601							e.preventDefault();
17602						}
17603					}
17604				});
17605			}
17606		},
17607
17608		trigger: function (event, o) {
17609			var ret, obj = o || F.coming || F.current;
17610
17611			if (!obj) {
17612				return;
17613			}
17614
17615			if ($.isFunction( obj[event] )) {
17616				ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
17617			}
17618
17619			if (ret === false) {
17620				return false;
17621			}
17622
17623			if (obj.helpers) {
17624				$.each(obj.helpers, function (helper, opts) {
17625					if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
17626						opts = $.extend(true, {}, F.helpers[helper].defaults, opts);
17627
17628						F.helpers[helper][event](opts, obj);
17629					}
17630				});
17631			}
17632
17633			$.event.trigger(event + '.fb');
17634		},
17635
17636		isImage: function (str) {
17637			return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i);
17638		},
17639
17640		isSWF: function (str) {
17641			return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
17642		},
17643
17644		_start: function (index) {
17645			var coming = {},
17646				obj,
17647				href,
17648				type,
17649				margin,
17650				padding;
17651
17652			index = getScalar( index );
17653			obj   = F.group[ index ] || null;
17654
17655			if (!obj) {
17656				return false;
17657			}
17658
17659			coming = $.extend(true, {}, F.opts, obj);
17660
17661			// Convert margin and padding properties to array - top, right, bottom, left
17662			margin  = coming.margin;
17663			padding = coming.padding;
17664
17665			if ($.type(margin) === 'number') {
17666				coming.margin = [margin, margin, margin, margin];
17667			}
17668
17669			if ($.type(padding) === 'number') {
17670				coming.padding = [padding, padding, padding, padding];
17671			}
17672
17673			// 'modal' propery is just a shortcut
17674			if (coming.modal) {
17675				$.extend(true, coming, {
17676					closeBtn   : false,
17677					closeClick : false,
17678					nextClick  : false,
17679					arrows     : false,
17680					mouseWheel : false,
17681					keys       : null,
17682					helpers: {
17683						overlay : {
17684							closeClick : false
17685						}
17686					}
17687				});
17688			}
17689
17690			// 'autoSize' property is a shortcut, too
17691			if (coming.autoSize) {
17692				coming.autoWidth = coming.autoHeight = true;
17693			}
17694
17695			if (coming.width === 'auto') {
17696				coming.autoWidth = true;
17697			}
17698
17699			if (coming.height === 'auto') {
17700				coming.autoHeight = true;
17701			}
17702
17703			/*
17704			 * Add reference to the group, so it`s possible to access from callbacks, example:
17705			 * afterLoad : function() {
17706			 *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
17707			 * }
17708			 */
17709
17710			coming.group  = F.group;
17711			coming.index  = index;
17712
17713			// Give a chance for callback or helpers to update coming item (type, title, etc)
17714			F.coming = coming;
17715
17716			if (false === F.trigger('beforeLoad')) {
17717				F.coming = null;
17718
17719				return;
17720			}
17721
17722			type = coming.type;
17723			href = coming.href;
17724
17725			if (!type) {
17726				F.coming = null;
17727
17728				//If we can not determine content type then drop silently or display next/prev item if looping through gallery
17729				if (F.current && F.router && F.router !== 'jumpto') {
17730					F.current.index = index;
17731
17732					return F[ F.router ]( F.direction );
17733				}
17734
17735				return false;
17736			}
17737
17738			F.isActive = true;
17739
17740			if (type === 'image' || type === 'swf') {
17741				coming.autoHeight = coming.autoWidth = false;
17742				coming.scrolling  = 'visible';
17743			}
17744
17745			if (type === 'image') {
17746				coming.aspectRatio = true;
17747			}
17748
17749			if (type === 'iframe' && isTouch) {
17750				coming.scrolling = 'scroll';
17751			}
17752
17753			// Build the neccessary markup
17754			coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
17755
17756			$.extend(coming, {
17757				skin  : $('.fancybox-skin',  coming.wrap),
17758				outer : $('.fancybox-outer', coming.wrap),
17759				inner : $('.fancybox-inner', coming.wrap)
17760			});
17761
17762			$.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
17763				coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
17764			});
17765
17766			F.trigger('onReady');
17767
17768			// Check before try to load; 'inline' and 'html' types need content, others - href
17769			if (type === 'inline' || type === 'html') {
17770				if (!coming.content || !coming.content.length) {
17771					return F._error( 'content' );
17772				}
17773
17774			} else if (!href) {
17775				return F._error( 'href' );
17776			}
17777
17778			if (type === 'image') {
17779				F._loadImage();
17780
17781			} else if (type === 'ajax') {
17782				F._loadAjax();
17783
17784			} else if (type === 'iframe') {
17785				F._loadIframe();
17786
17787			} else {
17788				F._afterLoad();
17789			}
17790		},
17791
17792		_error: function ( type ) {
17793			$.extend(F.coming, {
17794				type       : 'html',
17795				autoWidth  : true,
17796				autoHeight : true,
17797				minWidth   : 0,
17798				minHeight  : 0,
17799				scrolling  : 'no',
17800				hasError   : type,
17801				content    : F.coming.tpl.error
17802			});
17803
17804			F._afterLoad();
17805		},
17806
17807		_loadImage: function () {
17808			// Reset preload image so it is later possible to check "complete" property
17809			var img = F.imgPreload = new Image();
17810
17811			img.onload = function () {
17812				this.onload = this.onerror = null;
17813
17814				F.coming.width  = this.width;
17815				F.coming.height = this.height;
17816
17817				F._afterLoad();
17818			};
17819
17820			img.onerror = function () {
17821				this.onload = this.onerror = null;
17822
17823				F._error( 'image' );
17824			};
17825
17826			img.src = F.coming.href;
17827
17828			if (img.complete !== true) {
17829				F.showLoading();
17830			}
17831		},
17832
17833		_loadAjax: function () {
17834			var coming = F.coming;
17835
17836			F.showLoading();
17837
17838			F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
17839				url: coming.href,
17840				error: function (jqXHR, textStatus) {
17841					if (F.coming && textStatus !== 'abort') {
17842						F._error( 'ajax', jqXHR );
17843
17844					} else {
17845						F.hideLoading();
17846					}
17847				},
17848				success: function (data, textStatus) {
17849					if (textStatus === 'success') {
17850						coming.content = data;
17851
17852						F._afterLoad();
17853					}
17854				}
17855			}));
17856		},
17857
17858		_loadIframe: function() {
17859			var coming = F.coming,
17860				iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
17861					.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
17862					.attr('src', coming.href);
17863
17864			// This helps IE
17865			$(coming.wrap).bind('onReset', function () {
17866				try {
17867					$(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
17868				} catch (e) {}
17869			});
17870
17871			if (coming.iframe.preload) {
17872				F.showLoading();
17873
17874				iframe.one('load', function() {
17875					$(this).data('ready', 1);
17876
17877					// iOS will lose scrolling if we resize
17878					if (!isTouch) {
17879						$(this).bind('load.fb', F.update);
17880					}
17881
17882					// Without this trick:
17883					//   - iframe won't scroll on iOS devices
17884					//   - IE7 sometimes displays empty iframe
17885					$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
17886
17887					F._afterLoad();
17888				});
17889			}
17890
17891			coming.content = iframe.appendTo( coming.inner );
17892
17893			if (!coming.iframe.preload) {
17894				F._afterLoad();
17895			}
17896		},
17897
17898		_preloadImages: function() {
17899			var group   = F.group,
17900				current = F.current,
17901				len     = group.length,
17902				cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,
17903				item,
17904				i;
17905
17906			for (i = 1; i <= cnt; i += 1) {
17907				item = group[ (current.index + i ) % len ];
17908
17909				if (item.type === 'image' && item.href) {
17910					new Image().src = item.href;
17911				}
17912			}
17913		},
17914
17915		_afterLoad: function () {
17916			var coming   = F.coming,
17917				previous = F.current,
17918				placeholder = 'fancybox-placeholder',
17919				current,
17920				content,
17921				type,
17922				scrolling,
17923				href,
17924				embed;
17925
17926			F.hideLoading();
17927
17928			if (!coming || F.isActive === false) {
17929				return;
17930			}
17931
17932			if (false === F.trigger('afterLoad', coming, previous)) {
17933				coming.wrap.stop(true).trigger('onReset').remove();
17934
17935				F.coming = null;
17936
17937				return;
17938			}
17939
17940			if (previous) {
17941				F.trigger('beforeChange', previous);
17942
17943				previous.wrap.stop(true).removeClass('fancybox-opened')
17944					.find('.fancybox-item, .fancybox-nav')
17945					.remove();
17946			}
17947
17948			F.unbindEvents();
17949
17950			current   = coming;
17951			content   = coming.content;
17952			type      = coming.type;
17953			scrolling = coming.scrolling;
17954
17955			$.extend(F, {
17956				wrap  : current.wrap,
17957				skin  : current.skin,
17958				outer : current.outer,
17959				inner : current.inner,
17960				current  : current,
17961				previous : previous
17962			});
17963
17964			href = current.href;
17965
17966			switch (type) {
17967				case 'inline':
17968				case 'ajax':
17969				case 'html':
17970					if (current.selector) {
17971						content = $('<div>').html(content).find(current.selector);
17972
17973					} else if (isQuery(content)) {
17974						if (!content.data(placeholder)) {
17975							content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
17976						}
17977
17978						content = content.show().detach();
17979
17980						current.wrap.bind('onReset', function () {
17981							if ($(this).find(content).length) {
17982								content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
17983							}
17984						});
17985					}
17986				break;
17987
17988				case 'image':
17989					content = current.tpl.image.replace('{href}', href);
17990				break;
17991
17992				case 'swf':
17993					content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
17994					embed   = '';
17995
17996					$.each(current.swf, function(name, val) {
17997						content += '<param name="' + name + '" value="' + val + '"></param>';
17998						embed   += ' ' + name + '="' + val + '"';
17999					});
18000
18001					content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
18002				break;
18003			}
18004
18005			if (!(isQuery(content) && content.parent().is(current.inner))) {
18006				current.inner.append( content );
18007			}
18008
18009			// Give a chance for helpers or callbacks to update elements
18010			F.trigger('beforeShow');
18011
18012			// Set scrolling before calculating dimensions
18013			current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
18014
18015			// Set initial dimensions and start position
18016			F._setDimension();
18017
18018			F.reposition();
18019
18020			F.isOpen = false;
18021			F.coming = null;
18022
18023			F.bindEvents();
18024
18025			if (!F.isOpened) {
18026				$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
18027
18028			} else if (previous.prevMethod) {
18029				F.transitions[ previous.prevMethod ]();
18030			}
18031
18032			F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
18033
18034			F._preloadImages();
18035		},
18036
18037		_setDimension: function () {
18038			var viewport   = F.getViewport(),
18039				steps      = 0,
18040				canShrink  = false,
18041				canExpand  = false,
18042				wrap       = F.wrap,
18043				skin       = F.skin,
18044				inner      = F.inner,
18045				current    = F.current,
18046				width      = current.width,
18047				height     = current.height,
18048				minWidth   = current.minWidth,
18049				minHeight  = current.minHeight,
18050				maxWidth   = current.maxWidth,
18051				maxHeight  = current.maxHeight,
18052				scrolling  = current.scrolling,
18053				scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,
18054				margin     = current.margin,
18055				wMargin    = getScalar(margin[1] + margin[3]),
18056				hMargin    = getScalar(margin[0] + margin[2]),
18057				wPadding,
18058				hPadding,
18059				wSpace,
18060				hSpace,
18061				origWidth,
18062				origHeight,
18063				origMaxWidth,
18064				origMaxHeight,
18065				ratio,
18066				width_,
18067				height_,
18068				maxWidth_,
18069				maxHeight_,
18070				iframe,
18071				body;
18072
18073			// Reset dimensions so we could re-check actual size
18074			wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
18075
18076			wPadding = getScalar(skin.outerWidth(true)  - skin.width());
18077			hPadding = getScalar(skin.outerHeight(true) - skin.height());
18078
18079			// Any space between content and viewport (margin, padding, border, title)
18080			wSpace = wMargin + wPadding;
18081			hSpace = hMargin + hPadding;
18082
18083			origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;
18084			origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
18085
18086			if (current.type === 'iframe') {
18087				iframe = current.content;
18088
18089				if (current.autoHeight && iframe.data('ready') === 1) {
18090					try {
18091						if (iframe[0].contentWindow.document.location) {
18092							inner.width( origWidth ).height(9999);
18093
18094							body = iframe.contents().find('body');
18095
18096							if (scrollOut) {
18097								body.css('overflow-x', 'hidden');
18098							}
18099
18100							origHeight = body.height();
18101						}
18102
18103					} catch (e) {}
18104				}
18105
18106			} else if (current.autoWidth || current.autoHeight) {
18107				inner.addClass( 'fancybox-tmp' );
18108
18109				// Set width or height in case we need to calculate only one dimension
18110				if (!current.autoWidth) {
18111					inner.width( origWidth );
18112				}
18113
18114				if (!current.autoHeight) {
18115					inner.height( origHeight );
18116				}
18117
18118				if (current.autoWidth) {
18119					origWidth = inner.width();
18120				}
18121
18122				if (current.autoHeight) {
18123					origHeight = inner.height();
18124				}
18125
18126				inner.removeClass( 'fancybox-tmp' );
18127			}
18128
18129			width  = getScalar( origWidth );
18130			height = getScalar( origHeight );
18131
18132			ratio  = origWidth / origHeight;
18133
18134			// Calculations for the content
18135			minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
18136			maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
18137
18138			minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
18139			maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
18140
18141			// These will be used to determine if wrap can fit in the viewport
18142			origMaxWidth  = maxWidth;
18143			origMaxHeight = maxHeight;
18144
18145			if (current.fitToView) {
18146				maxWidth  = Math.min(viewport.w - wSpace, maxWidth);
18147				maxHeight = Math.min(viewport.h - hSpace, maxHeight);
18148			}
18149
18150			maxWidth_  = viewport.w - wMargin;
18151			maxHeight_ = viewport.h - hMargin;
18152
18153			if (current.aspectRatio) {
18154				if (width > maxWidth) {
18155					width  = maxWidth;
18156					height = getScalar(width / ratio);
18157				}
18158
18159				if (height > maxHeight) {
18160					height = maxHeight;
18161					width  = getScalar(height * ratio);
18162				}
18163
18164				if (width < minWidth) {
18165					width  = minWidth;
18166					height = getScalar(width / ratio);
18167				}
18168
18169				if (height < minHeight) {
18170					height = minHeight;
18171					width  = getScalar(height * ratio);
18172				}
18173
18174			} else {
18175				width = Math.max(minWidth, Math.min(width, maxWidth));
18176
18177				if (current.autoHeight && current.type !== 'iframe') {
18178					inner.width( width );
18179
18180					height = inner.height();
18181				}
18182
18183				height = Math.max(minHeight, Math.min(height, maxHeight));
18184			}
18185
18186			// Try to fit inside viewport (including the title)
18187			if (current.fitToView) {
18188				inner.width( width ).height( height );
18189
18190				wrap.width( width + wPadding );
18191
18192				// Real wrap dimensions
18193				width_  = wrap.width();
18194				height_ = wrap.height();
18195
18196				if (current.aspectRatio) {
18197					while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
18198						if (steps++ > 19) {
18199							break;
18200						}
18201
18202						height = Math.max(minHeight, Math.min(maxHeight, height - 10));
18203						width  = getScalar(height * ratio);
18204
18205						if (width < minWidth) {
18206							width  = minWidth;
18207							height = getScalar(width / ratio);
18208						}
18209
18210						if (width > maxWidth) {
18211							width  = maxWidth;
18212							height = getScalar(width / ratio);
18213						}
18214
18215						inner.width( width ).height( height );
18216
18217						wrap.width( width + wPadding );
18218
18219						width_  = wrap.width();
18220						height_ = wrap.height();
18221					}
18222
18223				} else {
18224					width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));
18225					height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
18226				}
18227			}
18228
18229			if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
18230				width += scrollOut;
18231			}
18232
18233			inner.width( width ).height( height );
18234
18235			wrap.width( width + wPadding );
18236
18237			width_  = wrap.width();
18238			height_ = wrap.height();
18239
18240			canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
18241			canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
18242
18243			$.extend(current, {
18244				dim : {
18245					width	: getValue( width_ ),
18246					height	: getValue( height_ )
18247				},
18248				origWidth  : origWidth,
18249				origHeight : origHeight,
18250				canShrink  : canShrink,
18251				canExpand  : canExpand,
18252				wPadding   : wPadding,
18253				hPadding   : hPadding,
18254				wrapSpace  : height_ - skin.outerHeight(true),
18255				skinSpace  : skin.height() - height
18256			});
18257
18258			if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
18259				inner.height('auto');
18260			}
18261		},
18262
18263		_getPosition: function (onlyAbsolute) {
18264			var current  = F.current,
18265				viewport = F.getViewport(),
18266				margin   = current.margin,
18267				width    = F.wrap.width()  + margin[1] + margin[3],
18268				height   = F.wrap.height() + margin[0] + margin[2],
18269				rez      = {
18270					position: 'absolute',
18271					top  : margin[0],
18272					left : margin[3]
18273				};
18274
18275			if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
18276				rez.position = 'fixed';
18277
18278			} else if (!current.locked) {
18279				rez.top  += viewport.y;
18280				rez.left += viewport.x;
18281			}
18282
18283			rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));
18284			rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));
18285
18286			return rez;
18287		},
18288
18289		_afterZoomIn: function () {
18290			var current = F.current;
18291
18292			if (!current) {
18293				return;
18294			}
18295
18296			F.isOpen = F.isOpened = true;
18297
18298			F.wrap.css('overflow', 'visible').addClass('fancybox-opened');
18299
18300			F.update();
18301
18302			// Assign a click event
18303			if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
18304				F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
18305					if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
18306						e.preventDefault();
18307
18308						F[ current.closeClick ? 'close' : 'next' ]();
18309					}
18310				});
18311			}
18312
18313			// Create a close button
18314			if (current.closeBtn) {
18315				$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
18316					e.preventDefault();
18317
18318					F.close();
18319				});
18320			}
18321
18322			// Create navigation arrows
18323			if (current.arrows && F.group.length > 1) {
18324				if (current.loop || current.index > 0) {
18325					$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
18326				}
18327
18328				if (current.loop || current.index < F.group.length - 1) {
18329					$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
18330				}
18331			}
18332
18333			F.trigger('afterShow');
18334
18335			// Stop the slideshow if this is the last item
18336			if (!current.loop && current.index === current.group.length - 1) {
18337				F.play( false );
18338
18339			} else if (F.opts.autoPlay && !F.player.isActive) {
18340				F.opts.autoPlay = false;
18341
18342				F.play();
18343			}
18344		},
18345
18346		_afterZoomOut: function ( obj ) {
18347			obj = obj || F.current;
18348
18349			$('.fancybox-wrap').trigger('onReset').remove();
18350
18351			$.extend(F, {
18352				group  : {},
18353				opts   : {},
18354				router : false,
18355				current   : null,
18356				isActive  : false,
18357				isOpened  : false,
18358				isOpen    : false,
18359				isClosing : false,
18360				wrap   : null,
18361				skin   : null,
18362				outer  : null,
18363				inner  : null
18364			});
18365
18366			F.trigger('afterClose', obj);
18367		}
18368	});
18369
18370	/*
18371	 *	Default transitions
18372	 */
18373
18374	F.transitions = {
18375		getOrigPosition: function () {
18376			var current  = F.current,
18377				element  = current.element,
18378				orig     = current.orig,
18379				pos      = {},
18380				width    = 50,
18381				height   = 50,
18382				hPadding = current.hPadding,
18383				wPadding = current.wPadding,
18384				viewport = F.getViewport();
18385
18386			if (!orig && current.isDom && element.is(':visible')) {
18387				orig = element.find('img:first');
18388
18389				if (!orig.length) {
18390					orig = element;
18391				}
18392			}
18393
18394			if (isQuery(orig)) {
18395				pos = orig.offset();
18396
18397				if (orig.is('img')) {
18398					width  = orig.outerWidth();
18399					height = orig.outerHeight();
18400				}
18401
18402			} else {
18403				pos.top  = viewport.y + (viewport.h - height) * current.topRatio;
18404				pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;
18405			}
18406
18407			if (F.wrap.css('position') === 'fixed' || current.locked) {
18408				pos.top  -= viewport.y;
18409				pos.left -= viewport.x;
18410			}
18411
18412			pos = {
18413				top     : getValue(pos.top  - hPadding * current.topRatio),
18414				left    : getValue(pos.left - wPadding * current.leftRatio),
18415				width   : getValue(width  + wPadding),
18416				height  : getValue(height + hPadding)
18417			};
18418
18419			return pos;
18420		},
18421
18422		step: function (now, fx) {
18423			var ratio,
18424				padding,
18425				value,
18426				prop       = fx.prop,
18427				current    = F.current,
18428				wrapSpace  = current.wrapSpace,
18429				skinSpace  = current.skinSpace;
18430
18431			if (prop === 'width' || prop === 'height') {
18432				ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
18433
18434				if (F.isClosing) {
18435					ratio = 1 - ratio;
18436				}
18437
18438				padding = prop === 'width' ? current.wPadding : current.hPadding;
18439				value   = now - padding;
18440
18441				F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );
18442				F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
18443			}
18444		},
18445
18446		zoomIn: function () {
18447			var current  = F.current,
18448				startPos = current.pos,
18449				effect   = current.openEffect,
18450				elastic  = effect === 'elastic',
18451				endPos   = $.extend({opacity : 1}, startPos);
18452
18453			// Remove "position" property that breaks older IE
18454			delete endPos.position;
18455
18456			if (elastic) {
18457				startPos = this.getOrigPosition();
18458
18459				if (current.openOpacity) {
18460					startPos.opacity = 0.1;
18461				}
18462
18463			} else if (effect === 'fade') {
18464				startPos.opacity = 0.1;
18465			}
18466
18467			F.wrap.css(startPos).animate(endPos, {
18468				duration : effect === 'none' ? 0 : current.openSpeed,
18469				easing   : current.openEasing,
18470				step     : elastic ? this.step : null,
18471				complete : F._afterZoomIn
18472			});
18473		},
18474
18475		zoomOut: function () {
18476			var current  = F.current,
18477				effect   = current.closeEffect,
18478				elastic  = effect === 'elastic',
18479				endPos   = {opacity : 0.1};
18480
18481			if (elastic) {
18482				endPos = this.getOrigPosition();
18483
18484				if (current.closeOpacity) {
18485					endPos.opacity = 0.1;
18486				}
18487			}
18488
18489			F.wrap.animate(endPos, {
18490				duration : effect === 'none' ? 0 : current.closeSpeed,
18491				easing   : current.closeEasing,
18492				step     : elastic ? this.step : null,
18493				complete : F._afterZoomOut
18494			});
18495		},
18496
18497		changeIn: function () {
18498			var current   = F.current,
18499				effect    = current.nextEffect,
18500				startPos  = current.pos,
18501				endPos    = { opacity : 1 },
18502				direction = F.direction,
18503				distance  = 200,
18504				field;
18505
18506			startPos.opacity = 0.1;
18507
18508			if (effect === 'elastic') {
18509				field = direction === 'down' || direction === 'up' ? 'top' : 'left';
18510
18511				if (direction === 'down' || direction === 'right') {
18512					startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
18513					endPos[ field ]   = '+=' + distance + 'px';
18514
18515				} else {
18516					startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
18517					endPos[ field ]   = '-=' + distance + 'px';
18518				}
18519			}
18520
18521			// Workaround for http://bugs.jquery.com/ticket/12273
18522			if (effect === 'none') {
18523				F._afterZoomIn();
18524
18525			} else {
18526				F.wrap.css(startPos).animate(endPos, {
18527					duration : current.nextSpeed,
18528					easing   : current.nextEasing,
18529					complete : F._afterZoomIn
18530				});
18531			}
18532		},
18533
18534		changeOut: function () {
18535			var previous  = F.previous,
18536				effect    = previous.prevEffect,
18537				endPos    = { opacity : 0.1 },
18538				direction = F.direction,
18539				distance  = 200;
18540
18541			if (effect === 'elastic') {
18542				endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
18543			}
18544
18545			previous.wrap.animate(endPos, {
18546				duration : effect === 'none' ? 0 : previous.prevSpeed,
18547				easing   : previous.prevEasing,
18548				complete : function () {
18549					$(this).trigger('onReset').remove();
18550				}
18551			});
18552		}
18553	};
18554
18555	/*
18556	 *	Overlay helper
18557	 */
18558
18559	F.helpers.overlay = {
18560		defaults : {
18561			closeClick : true,  // if true, fancyBox will be closed when user clicks on the overlay
18562			speedOut   : 200,   // duration of fadeOut animation
18563			showEarly  : true,  // indicates if should be opened immediately or wait until the content is ready
18564			css        : {},    // custom CSS properties
18565			locked     : !isTouch,  // if true, the content will be locked into overlay
18566			fixed      : true   // if false, the overlay CSS position property will not be set to "fixed"
18567		},
18568
18569		overlay : null,   // current handle
18570		fixed   : false,  // indicates if the overlay has position "fixed"
18571
18572		// Public methods
18573		create : function(opts) {
18574			opts = $.extend({}, this.defaults, opts);
18575
18576			if (this.overlay) {
18577				this.close();
18578			}
18579
18580			this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( 'body' );
18581			this.fixed   = false;
18582
18583			if (opts.fixed && F.defaults.fixed) {
18584				this.overlay.addClass('fancybox-overlay-fixed');
18585
18586				this.fixed = true;
18587			}
18588		},
18589
18590		open : function(opts) {
18591			var that = this;
18592
18593			opts = $.extend({}, this.defaults, opts);
18594
18595			if (this.overlay) {
18596				this.overlay.unbind('.overlay').width('auto').height('auto');
18597
18598			} else {
18599				this.create(opts);
18600			}
18601
18602			if (!this.fixed) {
18603				W.bind('resize.overlay', $.proxy( this.update, this) );
18604
18605				this.update();
18606			}
18607
18608			if (opts.closeClick) {
18609				this.overlay.bind('click.overlay', function(e) {
18610					if ($(e.target).hasClass('fancybox-overlay')) {
18611						if (F.isActive) {
18612							F.close();
18613						} else {
18614							that.close();
18615						}
18616					}
18617				});
18618			}
18619
18620			this.overlay.css( opts.css ).show();
18621		},
18622
18623		close : function() {
18624			$('.fancybox-overlay').remove();
18625
18626			W.unbind('resize.overlay');
18627
18628			this.overlay = null;
18629
18630			if (this.margin !== false) {
18631				$('body').css('margin-right', this.margin);
18632
18633				this.margin = false;
18634			}
18635
18636			if (this.el) {
18637				this.el.removeClass('fancybox-lock');
18638			}
18639		},
18640
18641		// Private, callbacks
18642
18643		update : function () {
18644			var width = '100%', offsetWidth;
18645
18646			// Reset width/height so it will not mess
18647			this.overlay.width(width).height('100%');
18648
18649			// jQuery does not return reliable result for IE
18650			if (IE) {
18651				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
18652
18653				if (D.width() > offsetWidth) {
18654					width = D.width();
18655				}
18656
18657			} else if (D.width() > W.width()) {
18658				width = D.width();
18659			}
18660
18661			this.overlay.width(width).height(D.height());
18662		},
18663
18664		// This is where we can manipulate DOM, because later it would cause iframes to reload
18665		onReady : function (opts, obj) {
18666			$('.fancybox-overlay').stop(true, true);
18667
18668			if (!this.overlay) {
18669				this.margin = D.height() > W.height() || $('body').css('overflow-y') === 'scroll' ? $('body').css('margin-right') : false;
18670				this.el     = document.all && !document.querySelector ? $('html') : $('body');
18671
18672				this.create(opts);
18673			}
18674
18675			if (opts.locked && this.fixed) {
18676				obj.locked = this.overlay.append( obj.wrap );
18677				obj.fixed  = false;
18678			}
18679
18680			if (opts.showEarly === true) {
18681				this.beforeShow.apply(this, arguments);
18682			}
18683		},
18684
18685		beforeShow : function(opts, obj) {
18686			if (obj.locked) {
18687				this.el.addClass('fancybox-lock');
18688
18689				if (this.margin !== false) {
18690					$('body').css('margin-right', getScalar( this.margin ) + obj.scrollbarWidth);
18691				}
18692			}
18693
18694			this.open(opts);
18695		},
18696
18697		onUpdate : function() {
18698			if (!this.fixed) {
18699				this.update();
18700			}
18701		},
18702
18703		afterClose: function (opts) {
18704			// Remove overlay if exists and fancyBox is not opening
18705			// (e.g., it is not being open using afterClose callback)
18706			if (this.overlay && !F.isActive) {
18707				this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
18708			}
18709		}
18710	};
18711
18712	/*
18713	 *	Title helper
18714	 */
18715
18716	F.helpers.title = {
18717		defaults : {
18718			type     : 'float', // 'float', 'inside', 'outside' or 'over',
18719			position : 'bottom' // 'top' or 'bottom'
18720		},
18721
18722		beforeShow: function (opts) {
18723			var current = F.current,
18724				text    = current.title,
18725				type    = opts.type,
18726				title,
18727				target;
18728
18729			if ($.isFunction(text)) {
18730				text = text.call(current.element, current);
18731			}
18732
18733			if (!isString(text) || $.trim(text) === '') {
18734				return;
18735			}
18736
18737			title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
18737' + text + '</div>');
18738
18739			switch (type) {
18740				case 'inside':
18741					target = F.skin;
18742				break;
18743
18744				case 'outside':
18745					target = F.wrap;
18746				break;
18747
18748				case 'over':
18749					target = F.inner;
18750				break;
18751
18752				default: // 'float'
18753					target = F.skin;
18754
18755					title.appendTo('body');
18756
18757					if (IE) {
18758						title.width( title.width() );
18759					}
18760
18761					title.wrapInner('<span class="child"></span>');
18762
18763					//Increase bottom margin so this title will also fit into viewport
18764					F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
18765				break;
18766			}
18767
18768			title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);
18769		}
18770	};
18771
18772	// jQuery plugin initialization
18773	$.fn.fancybox = function (options) {
18774		var index,
18775			that     = $(this),
18776			selector = this.selector || '',
18777			run      = function(e) {
18778				var what = $(this).blur(), idx = index, relType, relVal;
18779
18780				if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
18781					relType = options.groupAttr || 'data-fancybox-group';
18782					relVal  = what.attr(relType);
18783
18784					if (!relVal) {
18785						relType = 'rel';
18786						relVal  = what.get(0)[ relType ];
18787					}
18788
18789					if (relVal && relVal !== '' && relVal !== 'nofollow') {
18790						what = selector.length ? $(selector) : that;
18791						what = what.filter('[' + relType + '="' + relVal + '"]');
18792						idx  = what.index(this);
18793					}
18794
18795					options.index = idx;
18796
18797					// Stop an event from bubbling if everything is fine
18798					if (F.open(what, options) !== false) {
18799						e.preventDefault();
18800					}
18801				}
18802			};
18803
18804		options = options || {};
18805		index   = options.index || 0;
18806
18807		if (!selector || options.live === false) {
18808			that.unbind('click.fb-start').bind('click.fb-start', run);
18809
18810		} else {
18811			D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
18812		}
18813
18814		this.filter('[data-fancybox-start=1]').trigger('click');
18815
18816		return this;
18817	};
18818
18819	// Tests that need a body at doc ready
18820	D.ready(function() {
18821		if ( $.scrollbarWidth === undefined ) {
18822			// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
18823			$.scrollbarWidth = function() {
18824				var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
18825					child  = parent.children(),
18826					width  = child.innerWidth() - child.height( 99 ).innerWidth();
18827
18828				parent.remove();
18829
18830				return width;
18831			};
18832		}
18833
18834		if ( $.support.fixedPosition === undefined ) {
18835			$.support.fixedPosition = (function() {
18836				var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
18837					fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
18838
18839				elem.remove();
18840
18841				return fixed;
18842			}());
18843		}
18844
18845		$.extend(F.defaults, {
18846			scrollbarWidth : $.scrollbarWidth(),
18847			fixed  : $.support.fixedPosition,
18848			parent : $('body')
18849		});
18850	});
18851
18852}(window, document, jQuery));
18853(function(c){function g(b,a){this.element=b;this.options=c.extend({},h,a);c(this.element).data("max-height",this.options.maxHeight);c(this.element).data("height-margin",this.options.heightMargin);delete this.options.maxHeight;if(this.options.embedCSS&&!k){var d=".readmore-js-toggle, .readmore-js-section { "+this.options.sectionCSS+" } .readmore-js-section { overflow: hidden; }",e=document.createElement("style");e.type="text/css";e.styleSheet?e.styleSheet.cssText=d:e.appendChild(document.createTextNode(d));
18854document.getElementsByTagName("head")[0].appendChild(e);k=!0}this._defaults=h;this._name=f;this.init()}var f="readmore",h={speed:100,maxHeight:200,heightMargin:16,moreLink:'<a href="#">Read More</a>',lessLink:'<a href="#">Close</a>',embedCSS:!0,sectionCSS:"display: block; width: 100%;",startOpen:!1,expandedClass:"readmore-js-expanded",collapsedClass:"readmore-js-collapsed",beforeToggle:function(){},afterToggle:function(){}},k=!1;g.prototype={init:function(){var b=this;c(this.element).each(function(){var a=
18855c(this),d=a.css("max-height").replace(/[^-\d\.]/g,"")>a.data("max-height")?a.css("max-height").replace(/[^-\d\.]/g,""):a.data("max-height"),e=a.data("height-margin");"none"!=a.css("max-height")&&a.css("max-height","none");b.setBoxHeight(a);if(a.outerHeight(!0)<=d+e)return!0;a.addClass("readmore-js-section "+b.options.collapsedClass).data("c
18855ollapsedHeight",d);a.after(c(b.options.startOpen?b.options.lessLink:b.options.moreLink).on("click",function(c){b.toggleSlider(this,a,c)}).addClass("readmore-js-toggle"));
18856b.options.startOpen||a.css({height:d})});c(window).on("resize",function(a){b.resizeBoxes()})},toggleSlider:function(b,a,d){d.preventDefault();var e=this;d=newLink=sectionClass="";var f=!1;d=c(a).data("collapsedHeight");c(a).height()<=d?(d=c(a).data("expandedHeight")+"px",newLink="lessLink",f=!0,sectionClass=e.options.expandedClass):(newLink="moreLink",sectionClass=e.options.collapsedClass);e.options.beforeToggle(b,a,f);c(a).animate({height:d},{duration:e.options.speed,complete:function(){e.options.afterToggle(b,
18857a,f);c(b).replaceWith(c(e.options[newLink]).on("click",function(b){e.toggleSlider(this,a,b)}).addClass("readmore-js-toggle"));c(this).removeClass(e.options.collapsedClass+" "+e.options.expandedClass).addClass(sectionClass)}})},setBoxHeight:function(b){var a=b.clone().css({height:"auto",width:b.width(),overflow:"hidden"}).insertAfter(b),c=a.outerHeight(!0);a.remove();b.data("expandedHeight",c)},resizeBoxes:function(){var b=this;c(".readmore-js-section").each(function(){var a=c(this);b.setBoxHeight(a);
18858(a.height()>a.data("expandedHeight")||a.hasClass(b.options.expandedClass)&&a.height()<a.data("expandedHeight"))&&a.css("height",a.data("expandedHeight"))})},destroy:function(){var b=this;c(this.element).each(function(){var a=c(this);a.removeClass("readmore-js-section "+b.options.collapsedClass+" "+b.options.expandedClass).css({"max-height":"",height:"auto"}).next(".readmore-js-toggle").remove();a.removeData()})}};c.fn[f]=function(b){var a=arguments;if(void 0===b||"object"===typeof b)return this.each(function(){if(c.data(this,
18859"plugin_"+f)){var a=c.data(this,"plugin_"+f);a.destroy.apply(a)}c.data(this,"plugin_"+f,new g(this,b))});if("string"===typeof b&&"_"!==b[0]&&"init"!==b)return this.each(function(){var d=c.data(this,"plugin_"+f);d instanceof g&&"function"===typeof d[b]&&d[b].apply(d,Array.prototype.slice.call(a,1))})}})(jQuery);
18860Rcms = {
18861  navigation: {
18862    highlightCurrent: function() {
18863      $('[data-nav]').each(function() {
18864        var type = $(this).attr('data-type');
18865        var id = $(this).attr('data-id');
18866        var link = $('li[data-type="' + type + '"][data-id="' + id + '"]', this);
18867        if (link.length > 0) {
18868          link.addClass('active');
18869          Rcms.navigation.highlightParents(link);
18870        }
18871      });
18872    },
18873    highlightParents: function(current) {
18874      _self = this;
18875      $(current).parents('li').each(function() {
18876        $(this).addClass('active');
18877        _self.highlightParents(this);
18878      });
18879    }
18880  }
18881}
18882;
18883function formFieldsToObj(selector) {
18884  return $('.filter').serializeArray().filter(function(item){ return item.value !== ""; }).reduce(function(m,o){ m[o.name] = o.value; return m; }, {});
18885}
18886
18887// highlight the current page
18888Rcms.navigation.highlightCurrent();
18889$().prettyEmbed();
18890$(document).ready(function() {
18891  $('.fancybox-video').fancybox({
18892    minWidth: 560,
18893    minHeight: 330,
18894    padding: 20
18895  });
18896
18897  $('.fancybox-overlay').click(function() {
18898    $.fancybox.close();
18899  });
18900
18901  $('#featuredContent').orbit({
18902    animation: 'horizontal-push',
18903    timer: true,
18904    advanceSpeed: 6000
18905  });
18906
18907  var $slideshow = $("#programSlideshow");
18908  var $dragged = $("#programSlideshow ul");
18909
18910  // narrows program slideshow width to content
18911  var comP = 0;
18912  $dragged.find("img").each(function() {
18913    comP += parseInt($(this).attr('width'));
18914  });
18915  $dragged.css("width", comP);
18916
18917  $slideshow.overscroll({
18918    scrollLeft: 0,
18919    scrollTop: 0,
18920    direction: "horizontal",
18921    wheelDirection: "horizontal",
18922    wheelDelta: 80,
18923    scrollDelta: 5.7
18924  });
18925
18926  $("#grab").fadeTo(250,1);
18927
18928  $("#programSlideshow ul, #grab").mousedown(function(){
18929    $("#grab").fadeTo(200,0, function(){$(this).css("top","-5000px");});
18930  });
18931
18932  if ($("body").hasClass("mobile")) {
18933    $("#grab").hide();
18934  }
18935
18936  $('.expandable').readmore({
18937    maxHeight: 198,
18938    lessLink: '<a href="#">Show Less</a>'
18939  });
18940
18941});
18942
18943// filter
18944var $filter = $('.filter');
18945function catchClicksToRemoveFilterMenus() {
18946  $('.filter__values.active').removeClass('active');
18947  document.removeEventListener('click', catchClicksToRemoveFilterMenus);
18948  document.removeEventListener('touchstart', catchClicksToRemoveFilterMenus);
18949}
18950
18951function handleFilterValueChoice(evt) {
18952  var $this = $(this);
18953  var $currentVal = $this.parents('.filter__option').find('.filter__current-value');
18954  var $input = $this.parents('.filter__option').find('.filter__input');
18955
18956  if ($currentVal.html() === $this.html()) {
18957    catchClicksToRemoveFilterMenus();
18958    return false;
18959  }
18960
18961  $currentVal.html($this.html());
18962  $input.val($this.attr('data-value'));
18963  catchClicksToRemoveFilterMenus();
18964  $filter.submit();
18965  $('.filter :input[value=""]').removeAttr('disabled');
18966  evt.stopPropagation();
18967}
18968
18969if ($filter) {
18970  $filter.submit(function () {
18971    $(this).find(':input[value=""]').attr('disabled', 'disabled');
18972    return true;
18973  });
18974
18975  $('.filter__current-value').click(function (evt) {
18976    var $this = $(this);
18977    var $values = $this.find('~ .filter__values');
18978    if ($values.hasClass('active')) {
18979      catchClicksToRemoveFilterMenus();
18980    } else {
18981      $filter.find('.filter__values').each(function () {
18982        $(this).removeClass('active');
18983      });
18984      $values.addClass('active');
18985      document.addEventListener('click', catchClicksToRemoveFilterMenus);
18986      document.addEventListener('touchstart', catchClicksToRemoveFilterMenus);
18987      evt.stopPropagation();
18988    }
18989  });
18990
18991  $('.filter__value').bind('click', handleFilterValueChoice);
18992  $('.filter__value').bind('touchstart', handleFilterValueChoice);
18993
18994  $('.filter__values__content').each(function () {
18995    if (parseInt($(this).css('height')) >= parseInt($(this).css('max-height'))) {
18996      $(this).parent().append('<div class="filter__more active"></div>');
18997    }
18998
18999    $(this).bind('scroll', function () {
19000      $arrow = $(this).parent().find('.filter__more');
19001
19002      if (this.offsetHeight + this.scrollTop >= this.scrollHeight) {
19003        $arrow.removeClass('active');
19004      } else {
19005        if (!$arrow.hasClass('active')) {
19006          $arrow.addClass('active');
19007        }
19008      }
19009    });
19010  });
19011}
19012;
19013// This is a manifest file that'll be compiled into application.js, which will include all the files
19014// listed below.
19015//
19016// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
19017// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
19018//
19019// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
19020// the compiled file.
19021//
19022// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
19023// GO AFTER THE REQUIRES BELOW.
19024//
19025
19026
19027
19028
19029
19030
19031
19032
19033
19034
19035
19036
19037
19038
19039
19040
19041
19042;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.