/*
 * jQuery ifixpng plugin
 * (previously known as pngfix)
 * Version 3.1.2  (2008/09/01)
 * @requires jQuery v1.2.6 or above, or a lower version with the dimensions plugin
 *
 * Based on the plugin by Kush M., http://jquery.khurshid.com
 *
 * Background position Fixed
 * Also fixes non-visible images
 * (c) Copyright Yereth Jansen (yereth@yereth.nl)
 * personal website: http://www.yereth.nl
 * Company website: http://www.wharf.nl
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * For a demonstration of the background-position being fixed:
 * http://www.yereth.nl/bgpos.html
 *
 * Plugin page:
 * http://plugins.jquery.com/project/iFixPng2
 *
 */

/**
 *
 * @example
 *
 * optional if location of pixel.gif if different to default which is images/pixel.gif
 * $.ifixpng('media/pixel.gif');
 *
 * $('img[@src$=.png], #panel').ifixpng();
 *
 * @apply hack to all png images and #panel which icluded png img in its css
 *
 * @name ifixpng
 * @type jQuery
 * @cat Plugins/Image
 * @return jQuery
 * @author jQuery Community
 */
;(function($) {

	/**
	 * helper variables and function
	 */
	$.ifixpng = function(customPixel) {
		$.ifixpng.pixel = customPixel;
	};

	$.ifixpng.regexp = {
		bg: /^url\(["']?(.*\.png([?].*)?)["']?\)$/i,
		img: /.*\.png([?].*)?$/i
	},

	$.ifixpng.getPixel = function() {
		return $.ifixpng.pixel || 'js/pixel.gif';
	};

	var hack = {
		base	: $('base').attr('href'),
		ltie7	: $.browser.msie && $.browser.version < 7,
		filter	: function(src) {
			return "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='"+src+"')";
		}
	};

	/**
	 * Applies ie png hack to selected dom elements
	 *
	 * $('img[@src$=.png]').ifixpng();
	 * @desc apply hack to all images with png extensions
	 *
	 * $('#panel, img[@src$=.png]').ifixpng();
	 * @desc apply hack to element #panel and all images with png extensions
	 *
	 * @name ifixpng
	 */

	$.fn.ifixpng = hack.ltie7 ? function() {
		function fixImage(image, source, width, height, hidden) {
			image.css({filter:hack.filter(source), width: width, height: height})
			  .attr({src:$.ifixpng.getPixel()})
			  .positionFix();
		}

    	return this.each(function() {
			var $$ = $(this);
			if ($$.is('img') || $$.is('input')) { // hack image tags present in dom
				var source, img;
				if (this.src && this.src.match($.ifixpng.regexp.img)) { // make sure it is png image
					// use source tag value if set
					source = (hack.base && this.src.substring(0,1)!='/' && this.src.indexOf(hack.base) === -1) ? hack.base + this.src : this.src;
					// If the width is not set, we have a problem; the image is not probably visible or not loaded
					// and we need a work around.
					if (!this.width || !this.height) {
						$(new Image()).one('load', function() {
							fixImage($$, source, this.width, this.height);
							$(this).remove();
						}).attr('src', source);
					// If the image already has dimensions (it's loaded and visible) we can fix it straight away.
					} else fixImage($$, source, this.width, this.height);
				}
			} else if (this.style) { // hack png css properties present inside css
				var imageSrc = $$.css('backgroundImage');
				// Background repeated images we cannot fix unfortunately
				if (imageSrc && imageSrc.match($.ifixpng.regexp.bg) && this.currentStyle.backgroundRepeat == 'no-repeat') {
					imageSrc = RegExp.$1;
					var x = this.currentStyle.backgroundPositionX || 0, y = this.currentStyle.backgroundPositionY || 0;
					if (x || y) {
						var css = {}, img;
						if (typeof x != 'undefined') {
							if (x == 'left') css.left = 0;
							// if right is 0, we have to check if the parent has an odd width, because of an IE bug
							else if (x == 'right') css.right = $$.width() % 2 === 1 ? -1 : 0;
							else css.left = x;
						}
						if (typeof y != 'undefined') {
							// if bottom is 0, we have to check if the parent has an odd height, because of an IE bug
							if (y == 'bottom') css.bottom = $$.height() % 2 === 1 ? -1 : 0;
							else if (y == 'top') css.top = 0;
							else css.top = y;
						}
						img = new Image();
						$(img).one('load', function() {
							var x,y, expr = {}, prop;
							// Now the image is loaded for sure, we can see if the background position needs fixing with an expression (in case of percentages)
							if (/center|%/.test(css.top)) {
								expr.top = "(this.parentNode.offsetHeight - this.offsetHeight) * " + (css.top == 'center' ? 0.5 : (parseInt(css.top) / 100));
								delete css.top;
							}
							if (/center|%/.test(css.left)) {
								expr.left = "(this.parentNode.offsetWidth - this.offsetWidth) * " + (css.left == 'center' ? 0.5 : (parseInt(css.left) / 100));
								delete css.left;
							}
							// Let's add the helper DIV which will simulate the background image
							$$.positionFix().css({backgroundImage: 'none'}).prepend(
								$('<div></div>').css(css).css({
									width: this.width,
									height: this.height,
									position: 'absolute',
									filter: hack.filter(imageSrc)
								})
							);
							if (expr.top || expr.left) {
								var elem = $$.children(':first')[0];
								for (prop in expr) elem.style.setExpression(prop, expr[prop], 'JavaScript');
							}
							$(this).remove();
						});
						img.src = imageSrc;
					} else {
						$$.css({backgroundImage: 'none', filter:hack.filter(imageSrc)});
					}
				}
			}
		});
	} : function() { return this; };

	/**
	 * positions selected item relatively
	 */
	$.fn.positionFix = function() {
		return this.each(function() {
			var $$ = $(this);
			if ($$.css('position') != 'absolute') $$.css({position:'relative'});
		});
	};

})(jQuery);

/* Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version: 1.0.3
 * Requires jQuery 1.1.3+
 * Docs: http://docs.jquery.com/Plugins/livequery
 */

(function($) {

$.extend($.fn, {
	livequery: function(type, fn, fn2) {
		var self = this, q;

		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;

		// See if Live Query already exists
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
					// Found the query, exit the each loop
					return (q = query) && false;
		});

		// Create new Live Query if it wasn't found
		q = q || new $.livequery(this.selector, this.context, type, fn, fn2);

		// Make sure it is running
		q.stopped = false;

		// Run it immediately for the first time
		q.run();

		// Contnue the chain
		return this;
	},

	expire: function(type, fn, fn2) {
		var self = this;

		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;

		// Find the Live Query based on arguments and stop it
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
					$.livequery.stop(query.id);
		});

		// Continue the chain
		return this;
	}
});

$.livequery = function(selector, context, type, fn, fn2) {
	this.selector = selector;
	this.context  = context || document;
	this.type     = type;
	this.fn       = fn;
	this.fn2      = fn2;
	this.elements = [];
	this.stopped  = false;

	// The id is the index of the Live Query in $.livequery.queries
	this.id = $.livequery.queries.push(this)-1;

	// Mark the functions for matching later on
	fn.$lqguid = fn.$lqguid || $.livequery.guid++;
	if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;

	// Return the Live Query
	return this;
};

$.livequery.prototype = {
	stop: function() {
		var query = this;

		if ( this.type )
			// Unbind all bound events
			this.elements.unbind(this.type, this.fn);
		else if (this.fn2)
			// Call the second function for all matched elements
			this.elements.each(function(i, el) {
				query.fn2.apply(el);
			});

		// Clear out matched elements
		this.elements = [];

		// Stop the Live Query from running until restarted
		this.stopped = true;
	},

	run: function() {
		// Short-circuit if stopped
		if ( this.stopped ) return;
		var query = this;

		var oEls = this.elements,
			els  = $(this.selector, this.context),
			nEls = els.not(oEls);

		// Set elements to the latest set of matched elements
		this.elements = els;

		if (this.type) {
			// Bind events to newly matched elements
			nEls.bind(this.type, this.fn);

			// Unbind events to elements no longer matched
			if (oEls.length > 0)
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						$.event.remove(el, query.type, query.fn);
				});
		}
		else {
			// Call the first function for newly matched elements
			nEls.each(function() {
				query.fn.apply(this);
			});

			// Call the second function for elements no longer matched
			if ( this.fn2 && oEls.length > 0 )
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						query.fn2.apply(el);
				});
		}
	}
};

$.extend($.livequery, {
	guid: 0,
	queries: [],
	queue: [],
	running: false,
	timeout: null,

	checkQueue: function() {
		if ( $.livequery.running && $.livequery.queue.length ) {
			var length = $.livequery.queue.length;
			// Run each Live Query currently in the queue
			while ( length-- )
				$.livequery.queries[ $.livequery.queue.shift() ].run();
		}
	},

	pause: function() {
		// Don't run anymore Live Queries until restarted
		$.livequery.running = false;
	},

	play: function() {
		// Restart Live Queries
		$.livequery.running = true;
		// Request a run of the Live Queries
		$.livequery.run();
	},

	registerPlugin: function() {
		$.each( arguments, function(i,n) {
			// Short-circuit if the method doesn't exist
			if (!$.fn[n]) return;

			// Save a reference to the original method
			var old = $.fn[n];

			// Create a new method
			$.fn[n] = function() {
				// Call the original method
				var r = old.apply(this, arguments);

				// Request a run of the Live Queries
				$.livequery.run();

				// Return the original methods result
				return r;
			}
		});
	},

	run: function(id) {
		if (id != undefined) {
			// Put the particular Live Query in the queue if it doesn't already exist
			if ( $.inArray(id, $.livequery.queue) < 0 )
				$.livequery.queue.push( id );
		}
		else
			// Put each Live Query in the queue if it doesn't already exist
			$.each( $.livequery.queries, function(id) {
				if ( $.inArray(id, $.livequery.queue) < 0 )
					$.livequery.queue.push( id );
			});

		// Clear timeout if it already exists
		if ($.livequery.timeout) clearTimeout($.livequery.timeout);
		// Create a timeout to check the queue and actually run the Live Queries
		$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
	},

	stop: function(id) {
		if (id != undefined)
			// Stop are particular Live Query
			$.livequery.queries[ id ].stop();
		else
			// Stop all Live Queries
			$.each( $.livequery.queries, function(id) {
				$.livequery.queries[ id ].stop();
			});
	}
});

// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');

// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });


// Save a reference to the original init method
var init = $.prototype.init;

// Create a new init method that exposes two new properties: selector and context
$.prototype.init = function(a,c) {
	// Call the original init and save the result
	var r = init.apply(this, arguments);

	// Copy over properties if they exist already
	if (a && a.selector)
		r.context = a.context, r.selector = a.selector;

	// Set properties
	if ( typeof a == 'string' )
		r.context = c || document, r.selector = a;

	// Return the result
	return r;
};

// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
$.prototype.init.prototype = $.prototype;

})(jQuery);

/**
 * @author Alexander Farkas
 * v. 1.02
 */
(function($) {
	$.extend($.fx.step,{
	    backgroundPosition: function(fx) {
            if (fx.state === 0 && typeof fx.end == 'string') {
                var start = $.curCSS(fx.elem,'backgroundPosition');
                start = toArray(start);
                fx.start = [start[0],start[2]];
                var end = toArray(fx.end);
                fx.end = [end[0],end[2]];
                fx.unit = [end[1],end[3]];
			}
            var nowPosX = [];
            nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
            nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
            fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

           function toArray(strg){
               strg = strg.replace(/left|top/g,'0px');
               strg = strg.replace(/right|bottom/g,'100%');
               strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
               var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
               return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
           }
        }
	});
})(jQuery);

/*
 * jQuery validation plug-in 1.5.5
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
 * http://docs.jquery.com/Plugins/Validation
 *
 * Copyright (c) 2006 - 2008 Jörn Zaefferer
 *
 * $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

(function($) {

$.extend($.fn, {
	// http://docs.jquery.com/Plugins/Validation/validate
	validate: function( options ) {

		// if nothing is selected, return nothing; can't chain anyway
		if (!this.length) {
			options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
			return;
		}

		// check if a validator for this form was already created
		var validator = $.data(this[0], 'validator');
		if ( validator ) {
			return validator;
		}

		validator = new $.validator( options, this[0] );
		$.data(this[0], 'validator', validator);

		if ( validator.settings.onsubmit ) {

			// allow suppresing validation by adding a cancel class to the submit button
			this.find("input, button").filter(".cancel").click(function() {
				validator.cancelSubmit = true;
			});

			// when a submitHandler is used, capture the submitting button
			if (validator.settings.submitHandler) {
				this.find("input, button").filter(":submit").click(function() {
					validator.submitButton = this;
				});
			}

			// validate the form on submit
			this.submit( function( event ) {
				if ( validator.settings.debug )
					// prevent form submit to be able to see console output
					event.preventDefault();

				function handle() {
					if ( validator.settings.submitHandler ) {
						if (validator.submitButton) {
							// insert a hidden input as a replacement for the missing submit button
							var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
						}
						validator.settings.submitHandler.call( validator, validator.currentForm );
						if (validator.submitButton) {
							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
							hidden.remove();
						}
						return false;
					}
					return true;
				}

				// prevent submit for invalid forms or custom submit handlers
				if ( validator.cancelSubmit ) {
					validator.cancelSubmit = false;
					return handle();
				}
				if ( validator.form() ) {
					if ( validator.pendingRequest ) {
						validator.formSubmitted = true;
						return false;
					}
					return handle();
				} else {
					validator.focusInvalid();
					return false;
				}
			});
		}

		return validator;
	},
	// http://docs.jquery.com/Plugins/Validation/valid
	valid: function() {
        if ( $(this[0]).is('form')) {
            return this.validate().form();
        } else {
            var valid = true;
            var validator = $(this[0].form).validate();
            this.each(function() {
				valid &= validator.element(this);
            });
            return valid;
        }
    },
	// attributes: space seperated list of attributes to retrieve and remove
	removeAttrs: function(attributes) {
		var result = {},
			$element = this;
		$.each(attributes.split(/\s/), function(index, value) {
			result[value] = $element.attr(value);
			$element.removeAttr(value);
		});
		return result;
	},
	// http://docs.jquery.com/Plugins/Validation/rules
	rules: function(command, argument) {
		var element = this[0];

		if (command) {
			var settings = $.data(element.form, 'validator').settings;
			var staticRules = settings.rules;
			var existingRules = $.validator.staticRules(element);
			switch(command) {
			case "add":
				$.extend(existingRules, $.validator.normalizeRule(argument));
				staticRules[element.name] = existingRules;
				if (argument.messages)
					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
				break;
			case "remove":
				if (!argument) {
					delete staticRules[element.name];
					return existingRules;
				}
				var filtered = {};
				$.each(argument.split(/\s/), function(index, method) {
					filtered[method] = existingRules[method];
					delete existingRules[method];
				});
				return filtered;
			}
		}

		var data = $.validator.normalizeRules(
		$.extend(
			{},
			$.validator.metadataRules(element),
			$.validator.classRules(element),
			$.validator.attributeRules(element),
			$.validator.staticRules(element)
		), element);

		// make sure required is at front
		if (data.required) {
			var param = data.required;
			delete data.required;
			data = $.extend({required: param}, data);
		}

		return data;
	}
});

// Custom selectors
$.extend($.expr[":"], {
	// http://docs.jquery.com/Plugins/Validation/blank
	blank: function(a) {return !$.trim(a.value);},
	// http://docs.jquery.com/Plugins/Validation/filled
	filled: function(a) {return !!$.trim(a.value);},
	// http://docs.jquery.com/Plugins/Validation/unchecked
	unchecked: function(a) {return !a.checked;}
});

// constructor for validator
$.validator = function( options, form ) {
	this.settings = $.extend( {}, $.validator.defaults, options );
	this.currentForm = form;
	this.init();
};

$.validator.format = function(source, params) {
	if ( arguments.length == 1 )
		return function() {
			var args = $.makeArray(arguments);
			args.unshift(source);
			return $.validator.format.apply( this, args );
		};
	if ( arguments.length > 2 && params.constructor != Array  ) {
		params = $.makeArray(arguments).slice(1);
	}
	if ( params.constructor != Array ) {
		params = [ params ];
	}
	$.each(params, function(i, n) {
		source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
	});
	return source;
};

$.extend($.validator, {

	defaults: {
		messages: {},
		groups: {},
		rules: {},
		errorClass: "error",
		validClass: "valid",
		errorElement: "label",
		focusInvalid: true,
		errorContainer: $( [] ),
		errorLabelContainer: $( [] ),
		onsubmit: true,
		ignore: [],
		ignoreTitle: false,
		onfocusin: function(element) {
			this.lastActive = element;

			// hide error label and remove error class on focus if enabled
			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
				this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
				this.errorsFor(element).hide();
			}
		},
		onfocusout: function(element) {
			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
				this.element(element);
			}
		},
		onkeyup: function(element) {
			if ( element.name in this.submitted || element == this.lastElement ) {
				this.element(element);
			}
		},
		onclick: function(element) {
			if ( element.name in this.submitted )
				this.element(element);
		},
		highlight: function( element, errorClass, validClass ) {
			$(element).addClass(errorClass).removeClass(validClass);
		},
		unhighlight: function( element, errorClass, validClass ) {
			$(element).removeClass(errorClass).addClass(validClass);
		}
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
	setDefaults: function(settings) {
		$.extend( $.validator.defaults, settings );
	},

	messages: {
		required: "This field is required.",
		remote: "Please fix this field.",
		email: "Please enter a valid email address.",
		url: "Please enter a valid URL.",
		date: "Please enter a valid date.",
		dateISO: "Please enter a valid date (ISO).",
		dateDE: "Bitte geben Sie ein gültiges Datum ein.",
		number: "Please enter a valid number.",
		numberDE: "Bitte geben Sie eine Nummer ein.",
		digits: "Please enter only digits",
		creditcard: "Please enter a valid credit card number.",
		equalTo: "Please enter the same value again.",
		accept: "Please enter a value with a valid extension.",
		maxlength: $.validator.format("Please enter no more than {0} characters."),
		minlength: $.validator.format("Please enter at least {0} characters."),
		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
		range: $.validator.format("Please enter a value between {0} and {1}."),
		max: $.validator.format("Please enter a value less than or equal to {0}."),
		min: $.validator.format("Please enter a value greater than or equal to {0}.")
	},

	autoCreateRanges: false,

	prototype: {

		init: function() {
			this.labelContainer = $(this.settings.errorLabelContainer);
			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
			this.submitted = {};
			this.valueCache = {};
			this.pendingRequest = 0;
			this.pending = {};
			this.invalid = {};
			this.reset();

			var groups = (this.groups = {});
			$.each(this.settings.groups, function(key, value) {
				$.each(value.split(/\s/), function(index, name) {
					groups[name] = key;
				});
			});
			var rules = this.settings.rules;
			$.each(rules, function(key, value) {
				rules[key] = $.validator.normalizeRule(value);
			});

			function delegate(event) {
				var validator = $.data(this[0].form, "validator");
				validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
			}
			$(this.currentForm)
				.delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)
				.delegate("click", ":radio, :checkbox", delegate);

			if (this.settings.invalidHandler)
				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/form
		form: function() {
			this.checkForm();
			$.extend(this.submitted, this.errorMap);
			this.invalid = $.extend({}, this.errorMap);
			if (!this.valid())
				$(this.currentForm).triggerHandler("invalid-form", [this]);
			this.showErrors();
			return this.valid();
		},

		checkForm: function() {
			this.prepareForm();
			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
				this.check( elements[i] );
			}
			return this.valid();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/element
		element: function( element ) {
			element = this.clean( element );
			this.lastElement = element;
			this.prepareElement( element );
			this.currentElements = $(element);
			var result = this.check( element );
			if ( result ) {
				delete this.invalid[element.name];
			} else {
				this.invalid[element.name] = true;
			}
			if ( !this.numberOfInvalids() ) {
				// Hide error containers on last error
				this.toHide = this.toHide.add( this.containers );
			}
			this.showErrors();
			return result;
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
		showErrors: function(errors) {
			if(errors) {
				// add items to error list and map
				$.extend( this.errorMap, errors );
				this.errorList = [];
				for ( var name in errors ) {
					this.errorList.push({
						message: errors[name],
						element: this.findByName(name)[0]
					});
				}
				// remove items from success list
				this.successList = $.grep( this.successList, function(element) {
					return !(element.name in errors);
				});
			}
			this.settings.showErrors
				? this.settings.showErrors.call( this, this.errorMap, this.errorList )
				: this.defaultShowErrors();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
		resetForm: function() {
			if ( $.fn.resetForm )
				$( this.currentForm ).resetForm();
			this.submitted = {};
			this.prepareForm();
			this.hideErrors();
			this.elements().removeClass( this.settings.errorClass );
		},

		numberOfInvalids: function() {
			return this.objectLength(this.invalid);
		},

		objectLength: function( obj ) {
			var count = 0;
			for ( var i in obj )
				count++;
			return count;
		},

		hideErrors: function() {
			this.addWrapper( this.toHide ).hide();
		},

		valid: function() {
			return this.size() == 0;
		},

		size: function() {
			return this.errorList.length;
		},

		focusInvalid: function() {
			if( this.settings.focusInvalid ) {
				try {
					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").focus();
				} catch(e) {
					// ignore IE throwing errors when focusing hidden elements
				}
			}
		},

		findLastActive: function() {
			var lastActive = this.lastActive;
			return lastActive && $.grep(this.errorList, function(n) {
				return n.element.name == lastActive.name;
			}).length == 1 && lastActive;
		},

		elements: function() {
			var validator = this,
				rulesCache = {};

			// select all valid inputs inside the form (no submit or reset buttons)
			// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
			return $([]).add(this.currentForm.elements)
			.filter(":input")
			.not(":submit, :reset, :image, [disabled]")
			.not( this.settings.ignore )
			.filter(function() {
				!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

				// select only the first element for each name, and only those with rules specified
				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
					return false;

				rulesCache[this.name] = true;
				return true;
			});
		},

		clean: function( selector ) {
			return $( selector )[0];
		},

		errors: function() {
			return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
		},

		reset: function() {
			this.successList = [];
			this.errorList = [];
			this.errorMap = {};
			this.toShow = $([]);
			this.toHide = $([]);
			this.formSubmitted = false;
			this.currentElements = $([]);
		},

		prepareForm: function() {
			this.reset();
			this.toHide = this.errors().add( this.containers );
		},

		prepareElement: function( element ) {
			this.reset();
			this.toHide = this.errorsFor(element);
		},

		check: function( element ) {
			element = this.clean( element );

			// if radio/checkbox, validate first element in group instead
			if (this.checkable(element)) {
				element = this.findByName( element.name )[0];
			}

			var rules = $(element).rules();
			var dependencyMismatch = false;
			for( method in rules ) {
				var rule = { method: method, parameters: rules[method] };
				try {
					var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );

					// if a method indicates that the field is optional and therefore valid,
					// don't mark it as valid when there are no other rules
					if ( result == "dependency-mismatch" ) {
						dependencyMismatch = true;
						continue;
					}
					dependencyMismatch = false;

					if ( result == "pending" ) {
						this.toHide = this.toHide.not( this.errorsFor(element) );
						return;
					}

					if( !result ) {
						this.formatAndAdd( element, rule );
						return false;
					}
				} catch(e) {
					this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
						 + ", check the '" + rule.method + "' method");
					throw e;
				}
			}
			if (dependencyMismatch)
				return;
			if ( this.objectLength(rules) )
				this.successList.push(element);
			return true;
		},

		// return the custom message for the given element and validation method
		// specified in the element's "messages" metadata
		customMetaMessage: function(element, method) {
			if (!$.metadata)
				return;

			var meta = this.settings.meta
				? $(element).metadata()[this.settings.meta]
				: $(element).metadata();

			return meta && meta.messages && meta.messages[method];
		},

		// return the custom message for the given element name and validation method
		customMessage: function( name, method ) {
			var m = this.settings.messages[name];
			return m && (m.constructor == String
				? m
				: m[method]);
		},

		// return the first defined argument, allowing empty strings
		findDefined: function() {
			for(var i = 0; i < arguments.length; i++) {
				if (arguments[i] !== undefined)
					return arguments[i];
			}
			return undefined;
		},

		defaultMessage: function( element, method) {
			return this.findDefined(
				this.customMessage( element.name, method ),
				this.customMetaMessage( element, method ),
				// title is never undefined, so handle empty string as undefined
				!this.settings.ignoreTitle && element.title || undefined,
				$.validator.messages[method],
				"<strong>Warning: No message defined for " + element.name + "</strong>"
			);
		},

		formatAndAdd: function( element, rule ) {
			var message = this.defaultMessage( element, rule.method );
			if ( typeof message == "function" )
				message = message.call(this, rule.parameters, element);
			this.errorList.push({
				message: message,
				element: element
			});
			this.errorMap[element.name] = message;
			this.submitted[element.name] = message;
		},

		addWrapper: function(toToggle) {
			if ( this.settings.wrapper )
				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
			return toToggle;
		},

		defaultShowErrors: function() {
			for ( var i = 0; this.errorList[i]; i++ ) {
				var error = this.errorList[i];
				this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
				this.showLabel( error.element, error.message );
			}
			if( this.errorList.length ) {
				this.toShow = this.toShow.add( this.containers );
			}
			if (this.settings.success) {
				for ( var i = 0; this.successList[i]; i++ ) {
					this.showLabel( this.successList[i] );
				}
			}
			if (this.settings.unhighlight) {
				for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
				}
			}
			this.toHide = this.toHide.not( this.toShow );
			this.hideErrors();
			this.addWrapper( this.toShow ).show();
		},

		validElements: function() {
			return this.currentElements.not(this.invalidElements());
		},

		invalidElements: function() {
			return $(this.errorList).map(function() {
				return this.element;
			});
		},

		showLabel: function(element, message) {
			var label = this.errorsFor( element );
			if ( label.length ) {
				// refresh error/success class
				label.removeClass().addClass( this.settings.errorClass );

				// check if we have a generated label, replace the message then
				label.attr("generated") && label.html(message);
			} else {
				// create label
				label = $("<" + this.settings.errorElement + "/>")
					.attr({"for":  this.idOrName(element), generated: true})
					.addClass(this.settings.errorClass)
					.html(message || "");
				if ( this.settings.wrapper ) {
					// make sure the element is visible, even in IE
					// actually showing the wrapped element is handled elsewhere
					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
				}
				if ( !this.labelContainer.append(label).length )
					this.settings.errorPlacement
						? this.settings.errorPlacement(label, $(element) )
						: label.insertAfter(element);
			}
			if ( !message && this.settings.success ) {
				label.text("");
				typeof this.settings.success == "string"
					? label.addClass( this.settings.success )
					: this.settings.success( label );
			}
			this.toShow = this.toShow.add(label);
		},

		errorsFor: function(element) {
			return this.errors().filter("[for='" + this.idOrName(element) + "']");
		},

		idOrName: function(element) {
			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
		},

		checkable: function( element ) {
			return /radio|checkbox/i.test(element.type);
		},

		findByName: function( name ) {
			// select by name and filter by form for performance over form.find("[name=...]")
			var form = this.currentForm;
			return $(document.getElementsByName(name)).map(function(index, element) {
				return element.form == form && element.name == name && element  || null;
			});
		},

		getLength: function(value, element) {
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				return $("option:selected", element).length;
			case 'input':
				if( this.checkable( element) )
					return this.findByName(element.name).filter(':checked').length;
			}
			return value.length;
		},

		depend: function(param, element) {
			return this.dependTypes[typeof param]
				? this.dependTypes[typeof param](param, element)
				: true;
		},

		dependTypes: {
			"boolean": function(param, element) {
				return param;
			},
			"string": function(param, element) {
				return !!$(param, element.form).length;
			},
			"function": function(param, element) {
				return param(element);
			}
		},

		optional: function(element) {
			return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
		},

		startRequest: function(element) {
			if (!this.pending[element.name]) {
				this.pendingRequest++;
				this.pending[element.name] = true;
			}
		},

		stopRequest: function(element, valid) {
			this.pendingRequest--;
			// sometimes synchronization fails, make sure pendingRequest is never < 0
			if (this.pendingRequest < 0)
				this.pendingRequest = 0;
			delete this.pending[element.name];
			if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
				$(this.currentForm).submit();
			} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
				$(this.currentForm).triggerHandler("invalid-form", [this]);
			}
		},

		previousValue: function(element) {
			return $.data(element, "previousValue") || $.data(element, "previousValue", previous = {
				old: null,
				valid: true,
				message: this.defaultMessage( element, "remote" )
			});
		}

	},

	classRuleSettings: {
		required: {required: true},
		email: {email: true},
		url: {url: true},
		date: {date: true},
		dateISO: {dateISO: true},
		dateDE: {dateDE: true},
		number: {number: true},
		numberDE: {numberDE: true},
		digits: {digits: true},
		creditcard: {creditcard: true}
	},

	addClassRules: function(className, rules) {
		className.constructor == String ?
			this.classRuleSettings[className] = rules :
			$.extend(this.classRuleSettings, className);
	},

	classRules: function(element) {
		var rules = {};
		var classes = $(element).attr('class');
		classes && $.each(classes.split(' '), function() {
			if (this in $.validator.classRuleSettings) {
				$.extend(rules, $.validator.classRuleSettings[this]);
			}
		});
		return rules;
	},

	attributeRules: function(element) {
		var rules = {};
		var $element = $(element);

		for (method in $.validator.methods) {
			var value = $element.attr(method);
			if (value) {
				rules[method] = value;
			}
		}

		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
		if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
			delete rules.maxlength;
		}

		return rules;
	},

	metadataRules: function(element) {
		if (!$.metadata) return {};

		var meta = $.data(element.form, 'validator').settings.meta;
		return meta ?
			$(element).metadata()[meta] :
			$(element).metadata();
	},

	staticRules: function(element) {
		var rules = {};
		var validator = $.data(element.form, 'validator');
		if (validator.settings.rules) {
			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
		}
		return rules;
	},

	normalizeRules: function(rules, element) {
		// handle dependency check
		$.each(rules, function(prop, val) {
			// ignore rule when param is explicitly false, eg. required:false
			if (val === false) {
				delete rules[prop];
				return;
			}
			if (val.param || val.depends) {
				var keepRule = true;
				switch (typeof val.depends) {
					case "string":
						keepRule = !!$(val.depends, element.form).length;
						break;
					case "function":
						keepRule = val.depends.call(element, element);
						break;
				}
				if (keepRule) {
					rules[prop] = val.param !== undefined ? val.param : true;
				} else {
					delete rules[prop];
				}
			}
		});

		// evaluate parameters
		$.each(rules, function(rule, parameter) {
			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
		});

		// clean number parameters
		$.each(['minlength', 'maxlength', 'min', 'max'], function() {
			if (rules[this]) {
				rules[this] = Number(rules[this]);
			}
		});
		$.each(['rangelength', 'range'], function() {
			if (rules[this]) {
				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
			}
		});

		if ($.validator.autoCreateRanges) {
			// auto-create ranges
			if (rules.min && rules.max) {
				rules.range = [rules.min, rules.max];
				delete rules.min;
				delete rules.max;
			}
			if (rules.minlength && rules.maxlength) {
				rules.rangelength = [rules.minlength, rules.maxlength];
				delete rules.minlength;
				delete rules.maxlength;
			}
		}

		// To support custom messages in metadata ignore rule methods titled "messages"
		if (rules.messages) {
			delete rules.messages
		}

		return rules;
	},

	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
	normalizeRule: function(data) {
		if( typeof data == "string" ) {
			var transformed = {};
			$.each(data.split(/\s/), function() {
				transformed[this] = true;
			});
			data = transformed;
		}
		return data;
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
	addMethod: function(name, method, message) {
		$.validator.methods[name] = method;
		$.validator.messages[name] = message || $.validator.messages[name];
		if (method.length < 3) {
			$.validator.addClassRules(name, $.validator.normalizeRule(name));
		}
	},

	methods: {

		// http://docs.jquery.com/Plugins/Validation/Methods/required
		required: function(value, element, param) {
			// check if dependency is met
			if ( !this.depend(param, element) )
				return "dependency-mismatch";
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				var options = $("option:selected", element);
				return options.length > 0 && ( element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
			case 'input':
				if ( this.checkable(element) )
					return this.getLength(value, element) > 0;
			default:
				return $.trim(value).length > 0;
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/remote
		remote: function(value, element, param) {
			if ( this.optional(element) )
				return "dependency-mismatch";

			var previous = this.previousValue(element);

			if (!this.settings.messages[element.name] )
				this.settings.messages[element.name] = {};
			this.settings.messages[element.name].remote = typeof previous.message == "function" ? previous.message(value) : previous.message;

			param = typeof param == "string" && {url:param} || param;

			if ( previous.old !== value ) {
				previous.old = value;
				var validator = this;
				this.startRequest(element);
				var data = {};
				data[element.name] = value;
				$.ajax($.extend(true, {
					url: param,
					mode: "abort",
					port: "validate" + element.name,
					dataType: "json",
					data: data,
					success: function(response) {
						var valid = response === true;
						if ( valid ) {
							var submitted = validator.formSubmitted;
							validator.prepareElement(element);
							validator.formSubmitted = submitted;
							validator.successList.push(element);
							validator.showErrors();
						} else {
							var errors = {};
							errors[element.name] = previous.message = response || validator.defaultMessage( element, "remote" );
							validator.showErrors(errors);
						}
						previous.valid = valid;
						validator.stopRequest(element, valid);
					}
				}, param));
				return "pending";
			} else if( this.pending[element.name] ) {
				return "pending";
			}
			return previous.valid;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
		minlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
		maxlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
		rangelength: function(value, element, param) {
			var length = this.getLength($.trim(value), element);
			return this.optional(element) || ( length >= param[0] && length <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/min
		min: function( value, element, param ) {
			return this.optional(element) || value >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/max
		max: function( value, element, param ) {
			return this.optional(element) || value <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/range
		range: function( value, element, param ) {
			return this.optional(element) || ( value >= param[0] && value <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/email
		email: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/url
		url: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
			return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/date
		date: function(value, element) {
			return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
		dateISO: function(value, element) {
			return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/dateDE
		dateDE: function(value, element) {
			return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/number
		number: function(value, element) {
			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/numberDE
		numberDE: function(value, element) {
			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/digits
		digits: function(value, element) {
			return this.optional(element) || /^\d+$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
		// based on http://en.wikipedia.org/wiki/Luhn
		creditcard: function(value, element) {
			if ( this.optional(element) )
				return "dependency-mismatch";
			// accept only digits and dashes
			if (/[^0-9-]+/.test(value))
				return false;
			var nCheck = 0,
				nDigit = 0,
				bEven = false;

			value = value.replace(/\D/g, "");

			for (n = value.length - 1; n >= 0; n--) {
				var cDigit = value.charAt(n);
				var nDigit = parseInt(cDigit, 10);
				if (bEven) {
					if ((nDigit *= 2) > 9)
						nDigit -= 9;
				}
				nCheck += nDigit;
				bEven = !bEven;
			}

			return (nCheck % 10) == 0;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/accept
		accept: function(value, element, param) {
			param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
			return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
		equalTo: function(value, element, param) {
			return value == $(param).val();
		}

	}

});

// deprecated, use $.validator.format instead
$.format = $.validator.format;

})(jQuery);

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
;(function($) {
	var ajax = $.ajax;
	var pendingRequests = {};
	$.ajax = function(settings) {
		// create settings for compatibility with ajaxSetup
		settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
		var port = settings.port;
		if (settings.mode == "abort") {
			if ( pendingRequests[port] ) {
				pendingRequests[port].abort();
			}
			return (pendingRequests[port] = ajax.apply(this, arguments));
		}
		return ajax.apply(this, arguments);
	};
})(jQuery);

// provides cross-browser focusin and focusout events
// IE has native support, in other browsers, use event caputuring (neither bubbles)

// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target

// provides triggerEvent(type: String, target: Element) to trigger delegated events
;(function($) {
	$.each({
		focus: 'focusin',
		blur: 'focusout'
	}, function( original, fix ){
		$.event.special[fix] = {
			setup:function() {
				if ( $.browser.msie ) return false;
				this.addEventListener( original, $.event.special[fix].handler, true );
			},
			teardown:function() {
				if ( $.browser.msie ) return false;
				this.removeEventListener( original,
				$.event.special[fix].handler, true );
			},
			handler: function(e) {
				arguments[0] = $.event.fix(e);
				arguments[0].type = fix;
				return $.event.handle.apply(this, arguments);
			}
		};
	});
	$.extend($.fn, {
		delegate: function(type, delegate, handler) {
			return this.bind(type, function(event) {
				var target = $(event.target);
				if (target.is(delegate)) {
					return handler.apply(target, arguments);
				}
			});
		},
		triggerEvent: function(type, target) {
			return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
		}
	})
})(jQuery);


/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 *
 * Open source under the BSD License.
 *
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});




/*

	GalleryView - jQuery Content Gallery Plugin
	Author: 		Jack Anderson
	Version:		2.0 (May 5, 2009)
	Documentation: 	http://www.spaceforaname.com/galleryview/

	Please use this development script if you intend to make changes to the
	plugin code.  For production sites, please use jquery.galleryview-2.0-pack.js.

	See CHANGELOG.txt for a review of changes and LICENSE.txt for the applicable
	licensing information.


*/

//Global variable to check if window is already loaded
//Used for calling GalleryView after page has loaded
var window_loaded = false;

(function($){
	$.fn.galleryView = function(options) {
		var opts = $.extend($.fn.galleryView.defaults,options);

		var id;
		var iterator = 0;
		var item_count = 0;
		var slide_method;
		var theme_path;
		var paused = false;

		//Element dimensions
		var gallery_width;
		var gallery_height;
		var pointer_height;
		var pointer_width;
		var strip_width;
		var strip_height;
		var wrapper_width;
		var f_frame_width;
		var f_frame_height;
		var frame_caption_size = 20;
		var gallery_padding;
		var filmstrip_margin;
		var filmstrip_orientation;


		//Arrays used to scale frames and panels
		var frame_img_scale = new Object();
		var panel_img_scale = new Object();
		var img_h = new Object();
		var img_w = new Object();

		//Flag indicating whether to scale panel images
		var scale_panel_images = true;

		var panel_nav_displayed = false;

		//Define jQuery objects for reuse
		var j_gallery;
		var j_filmstrip;
		var j_frames;
		var j_frame_img_wrappers;
		var j_panels;
		var j_pointer;


/************************************************/
/*	Plugin Methods								*/
/************************************************/

	//Transition from current item to item 'i'
		function showItem(i) {
			//Disable next/prev buttons until transition is complete
			$('.nav-next-overlay',j_gallery).unbind('click');
			$('.nav-prev-overlay',j_gallery).unbind('click');
			$('.nav-next',j_gallery).unbind('click');
			$('.nav-prev',j_gallery).unbind('click');
			j_frames.unbind('click');

			//Fade out all frames while fading in target frame
			if(opts.show_filmstrip) {
				j_frames.removeClass('current').find('img').stop().animate({
					'opacity':opts.frame_opacity
				},opts.transition_speed);
				j_frames.eq(i).addClass('current').find('img').stop().animate({
					'opacity':1.0
				},opts.transition_speed);
			}

			//If the gallery has panels and the panels should fade, fade out all panels while fading in target panel
			if(opts.show_panels && opts.fade_panels) {
				j_panels.fadeOut(opts.transition_speed).eq(i%item_count).fadeIn(opts.transition_speed,function(){
					if(!opts.show_filmstrip) {
						$('.nav-prev-overlay',j_gallery).click(showPrevItem);
						$('.nav-next-overlay',j_gallery).click(showNextItem);
						$('.nav-prev',j_gallery).click(showPrevItem);
						$('.nav-next',j_gallery).click(showNextItem);
					}
				});
			}

			//If gallery has a filmstrip, handle animation of frames
			if(opts.show_filmstrip) {
				//Slide either pointer or filmstrip, depending on transition method
				if(slide_method=='strip') {
					//Stop filmstrip if it's currently in motion
					j_filmstrip.stop();

					if(filmstrip_orientation=='horizontal') {
						//Determine distance between pointer (eventual destination) and target frame
						var distance = getPos(j_frames[i]).left - (getPos(j_pointer[0]).left+(pointer_width/2)-(f_frame_width/2));
						var diststr = (distance>=0?'-=':'+=')+Math.abs(distance)+'px';

						//Animate filmstrip and slide target frame under pointer
						j_filmstrip.animate({
							'left':diststr
						},opts.transition_speed,opts.easing,function(){
							//Always ensure that there are a sufficient number of hidden frames on either
							//side of the filmstrip to avoid empty frames
							var old_i = i;
							if(i>item_count) {
								i = i%item_count;
								iterator = i;
								j_filmstrip.css('left','-'+((f_frame_width+opts.frame_gap)*i)+'px');
							} else if (i<=(item_count-strip_size)) {
								i = (i%item_count)+item_count;
								iterator = i;
								j_filmstrip.css('left','-'+((f_frame_width+opts.frame_gap)*i)+'px');
							}
							//If the target frame has changed due to filmstrip shifting,
							//Make sure new target frame has 'current' class and correct size/opacity settings
							if(old_i != i) {
								j_frames.eq(old_i).removeClass('current').find('img').css({
									'opacity':opts.frame_opacity
								});
								j_frames.eq(i).addClass('current').find('img').css({
									'opacity':1.0
								});
							}
							if(!opts.fade_panels) {
								j_panels.hide().eq(i%item_count).show();
							}

							//Enable navigation now that animation is complete
							$('.nav-prev-overlay',j_gallery).click(showPrevItem);
							$('.nav-next-overlay',j_gallery).click(showNextItem);
							$('.nav-prev',j_gallery).click(showPrevItem);
							$('.nav-next',j_gallery).click(showNextItem);
							enableFrameClicking();
						});
					} else {
						//Determine distance between pointer (eventual destination) and target frame
						var distance = getPos(j_frames[i]).top - (getPos(j_pointer[0]).top+(pointer_height)-(f_frame_height/2));
						var diststr = (distance>=0?'-=':'+=')+Math.abs(distance)+'px';

						//Animate filmstrip and slide target frame under pointer
						j_filmstrip.animate({
							'top':diststr
						},opts.transition_speed,opts.easing,function(){
							//Always ensure that there are a sufficient number of hidden frames on either
							//side of the filmstrip to avoid empty frames
							var old_i = i;
							if(i>item_count) {
								i = i%item_count;
								iterator = i;
								j_filmstrip.css('top','-'+((f_frame_height+opts.frame_gap)*i)+'px');
							} else if (i<=(item_count-strip_size)) {
								i = (i%item_count)+item_count;
								iterator = i;
								j_filmstrip.css('top','-'+((f_frame_height+opts.frame_gap)*i)+'px');
							}
							//If the target frame has changed due to filmstrip shifting,
							//Make sure new target frame has 'current' class and correct size/opacity settings
							if(old_i != i) {
								j_frames.eq(old_i).removeClass('current').find('img').css({
									'opacity':opts.frame_opacity
								});
								j_frames.eq(i).addClass('current').find('img').css({
									'opacity':1.0
								});
							}
							if(!opts.fade_panels) {
								j_panels.hide().eq(i%item_count).show();
							}

							//Enable navigation now that animation is complete
							$('.nav-prev-overlay',j_gallery).click(showPrevItem);
							$('.nav-next-overlay',j_gallery).click(showNextItem);
							$('.nav-prev',j_gallery).click(showPrevItem);
							$('.nav-next',j_gallery).click(showNextItem);
							enableFrameClicking();
						});
					}
				} else if(slide_method=='pointer') {
					//Stop pointer if it's currently in motion
					j_pointer.stop();
					//Get position of target frame
					var pos = getPos(j_frames[i]);

					if(filmstrip_orientation=='horizontal') {
						//Slide the pointer over the target frame
						j_pointer.animate({
							'left':(pos.left+(f_frame_width/2)-(pointer_width/2)+'px')
						},opts.transition_speed,opts.easing,function(){
							if(!opts.fade_panels) {
								j_panels.hide().eq(i%item_count).show();
							}
							$('.nav-prev-overlay',j_gallery).click(showPrevItem);
							$('.nav-next-overlay',j_gallery).click(showNextItem);
							$('.nav-prev',j_gallery).click(showPrevItem);
							$('.nav-next',j_gallery).click(showNextItem);
							enableFrameClicking();
						});
					} else {//Slide the pointer over the target frame
						j_pointer.animate({
							'top':(pos.top+(f_frame_height/2)-(pointer_height)+'px')
						},opts.transition_speed,opts.easing,function(){
							if(!opts.fade_panels) {
								j_panels.hide().eq(i%item_count).show();
							}
							$('.nav-prev-overlay',j_gallery).click(showPrevItem);
							$('.nav-next-overlay',j_gallery).click(showNextItem);
							$('.nav-prev',j_gallery).click(showPrevItem);
							$('.nav-next',j_gallery).click(showNextItem);
							enableFrameClicking();
						});
					}
				}

			}
		};

	//Find padding and border widths applied to element
	//If border is non-numerical ('thin','medium', etc) set to zero
		function extraWidth(el) {
			if(!el) return 0;
			if(el.length==0) return 0;
			el = el.eq(0);
			var ew = 0;
			ew += getInt(el.css('paddingLeft'));
			ew += getInt(el.css('paddingRight'));
			ew += getInt(el.css('borderLeftWidth'));
			ew += getInt(el.css('borderRightWidth'));
			return ew;
		}
	//Find padding and border heights applied to element
	//If border is non-numerical ('thin','medium', etc) set to zero
		function extraHeight(el) {
			if(!el) return 0;
			if(el.length==0) return 0;
			el = el.eq(0);
			var eh = 0;
			eh += getInt(el.css('paddingTop'));
			eh += getInt(el.css('paddingBottom'));
			eh += getInt(el.css('borderTopWidth'));
			eh += getInt(el.css('borderBottomWidth'));
			return eh;
		}

	//Halt transition timer, move to next item, restart timer
		function showNextItem() {

			$(document).stopTime("transition");
			if(++iterator==j_frames.length) {iterator=0;}
			showItem(iterator);
			if(!paused) {
				$(document).everyTime(opts.transition_interval,"transition",function(){
					showNextItem();
				});
			}
		};

	//Halt transition timer, move to previous item, restart timer
		function showPrevItem() {
			$(document).stopTime("transition");
			if(--iterator<0) {iterator = item_count-1;}
			showItem(iterator);
			if(!paused) {
				$(document).everyTime(opts.transition_interval,"transition",function(){
					showNextItem();
				});
			}
		};

	//Get absolute position of element in relation to top-left corner of gallery
	//If el=gallery, return position of gallery within browser viewport
		function getPos(el) {
			var left = 0, top = 0;
			var el_id = el.id;
			if(el.offsetParent) {
				do {
					left += el.offsetLeft;
					top += el.offsetTop;
				} while(el = el.offsetParent);
			}
			//If we want the position of the gallery itself, return it
			if(el_id == id) {return {'left':left,'top':top};}
			//Otherwise, get position of element relative to gallery
			else {
				var gPos = getPos(j_gallery[0]);
				var gLeft = gPos.left;
				var gTop = gPos.top;

				return {'left':left-gLeft,'top':top-gTop};
			}
		};

	//Add onclick event to each frame
		function enableFrameClicking() {
			j_frames.each(function(i){
				//If there isn't a link in this frame, set up frame to slide on click
				//Frames with links will handle themselves
				if($('a',this).length==0) {
					$(this).click(function(){
						if(iterator!=i) {
							$(document).stopTime("transition");
							showItem(i);
							iterator = i;
							if(!paused) {
								$(document).everyTime(opts.transition_interval,"transition",function(){
									showNextItem();
								});
							}
						}
					});
				}
			});
		};

	//Construct gallery panels from '.panel' <div>s
		function buildPanels() {
			//If there are panel captions, add overlay divs
			j_panels.each(function(i){
		   		if($('.panel-overlay',this).length>0) {
					$(this).append('<div class="overlay-background"></div>');
				}
		   	});
			if(!opts.show_filmstrip) {
				//Add navigation buttons
				$('<img />').addClass('nav-next').attr('src',theme_path+opts.nav_theme+'/next1.gif').appendTo(j_gallery).css({
					'position':'absolute',
					'zIndex':'1100',
					'cursor':'pointer',
					'top':((opts.panel_height-22)/2)+gallery_padding+'px',
					'right':'10px',
					'display':'none'
				}).click(showNextItem);
				$('<img />').addClass('nav-prev').attr('src',theme_path+opts.nav_theme+'/prev1.gif').appendTo(j_gallery).css({
					'position':'absolute',
					'zIndex':'1100',
					'cursor':'pointer',
					'top':((opts.panel_height-22)/2)+gallery_padding+'px',
					'left':'10px',
					'display':'none'
				}).click(showPrevItem);

				$('<img />').addClass('nav-next-overlay').attr('src',theme_path+opts.nav_theme+'/panel-nav-next.gif').appendTo(j_gallery).css({
					'position':'absolute',
					'zIndex':'1099',
					'top':((opts.panel_height-22)/2)+gallery_padding-10+'px',
					'right':'0',
					'display':'none',
					'cursor':'pointer',
					'opacity':0.75
				}).click(showNextItem);

				$('<img />').addClass('nav-prev-overlay').attr('src',theme_path+opts.nav_theme+'/panel-nav-prev.gif').appendTo(j_gallery).css({
					'position':'absolute',
					'zIndex':'1099',
					'top':((opts.panel_height-22)/2)+gallery_padding-10+'px',
					'left':'0',
					'display':'none',
					'cursor':'pointer',
					'opacity':0.75
				}).click(showPrevItem);
			}
			j_panels.each(function(i){
				$(this).css({
					'width':(opts.panel_width-extraWidth(j_panels))+'px',
					'height':(opts.panel_height-extraHeight(j_panels))+'px',
					'position':'absolute',
					'overflow':'hidden',
					'display':'none'
				});
				switch(opts.filmstrip_position) {
					case 'top': $(this).css({
									'top':strip_height+Math.max(gallery_padding,filmstrip_margin)+'px',
									'left':gallery_padding+'px'
								}); break;
					case 'left': $(this).css({
								 	'top':gallery_padding+'px',
									'left':strip_width+Math.max(gallery_padding,filmstrip_margin)+'px'
								 }); break;
					default: $(this).css({'top':gallery_padding+'px','left':gallery_padding+'px'}); break;
				}
			});
			$('.panel-overlay',j_panels).css({
				'position':'absolute',
				'zIndex':'999',
				'width':(opts.panel_width-extraWidth($('.panel-overlay',j_panels)))+'px',
				'left':'0'
			});
			$('.overlay-background',j_panels).css({
				'position':'absolute',
				'zIndex':'998',
				'width':opts.panel_width+'px',
				'left':'0',
				'opacity':opts.overlay_opacity
			});
			if(opts.overlay_position=='top') {
				$('.panel-overlay',j_panels).css('top',0);
				$('.overlay-background',j_panels).css('top',0);
			} else {
				$('.panel-overlay',j_panels).css('bottom',0);
				$('.overlay-background',j_panels).css('bottom',0);
			}

			$('.panel iframe',j_panels).css({
				'width':opts.panel_width+'px',
				'height':opts.panel_height+'px',
				'border':'0'
			});

			if(scale_panel_images) {
				$('img',j_panels).each(function(i){
					$(this).css({
						'height':panel_img_scale[i%item_count]*img_h[i%item_count],
						'width':panel_img_scale[i%item_count]*img_w[i%item_count],
						'position':'relative',
						'top':(opts.panel_height-(panel_img_scale[i%item_count]*img_h[i%item_count]))/2+'px',
						'left':(opts.panel_width-(panel_img_scale[i%item_count]*img_w[i%item_count]))/2+'px'
					});
				});
			}
		};

	//Construct filmstrip from '.filmstrip' <ul>
		function buildFilmstrip() {
			//Add wrapper to filmstrip to hide extra frames
			j_filmstrip.wrap('<div class="strip_wrapper"></div>');
			if(slide_method=='strip') {
				j_frames.clone().appendTo(j_filmstrip);
				j_frames.clone().appendTo(j_filmstrip);
				j_frames = $('li',j_filmstrip);
			}
			//If captions are enabled, add caption divs and fill with the image titles
			if(opts.show_captions) {
				j_frames.append('<div class="caption"></div>').each(function(i){
					$(this).find('.caption').html($(this).find('img').attr('title'));
					//$(this).find('.caption').html(i);
				});
			}
			j_filmstrip.css({
				'listStyle':'none',
				'margin':'0',
				'padding':'0',
				'width':strip_width+'px',
				'position':'absolute',
				'zIndex':'900',
				'top':(filmstrip_orientation=='vertical' && slide_method=='strip'?-((f_frame_height+opts.frame_gap)*iterator):0)+'px',
				'left':(filmstrip_orientation=='horizontal' && slide_method=='strip'?-((f_frame_width+opts.frame_gap)*iterator):0)+'px',
				'height':strip_height+'px'
			});
			j_frames.css({
				'float':'left',
				'position':'relative',
				'height':f_frame_height+(opts.show_captions?frame_caption_size:0)+'px',
				'width':f_frame_width+'px',
				'zIndex':'901',
				'padding':'0',
				'cursor':'pointer'
			});
			switch(opts.filmstrip_position) {
				case 'top': j_frames.css({
								'marginBottom':filmstrip_margin+'px',
								'marginRight':opts.frame_gap+'px'
							}); break;
				case 'bottom': j_frames.css({
								'marginTop':filmstrip_margin+'px',
								'marginRight':opts.frame_gap+'px'
							}); break;
				case 'left': j_frames.css({
								'marginRight':filmstrip_margin+'px',
								'marginBottom':opts.frame_gap+'px'
							}); break;
				case 'right': j_frames.css({
								'marginLeft':filmstrip_margin+'px',
								'marginBottom':opts.frame_gap+'px'
							}); break;
			}
			$('.img_wrap',j_frames).each(function(i){
				$(this).css({
					'height':Math.min(opts.frame_height,img_h[i%item_count]*frame_img_scale[i%item_count])+'px',
					'width':Math.min(opts.frame_width,img_w[i%item_count]*frame_img_scale[i%item_count])+'px',
					'position':'relative',
					'top':(opts.show_captions && opts.filmstrip_position=='top'?frame_caption_size:0)+Math.max(0,(opts.frame_height-(frame_img_scale[i%item_count]*img_h[i%item_count]))/2)+'px',
					'left':Math.max(0,(opts.frame_width-(frame_img_scale[i%item_count]*img_w[i%item_count]))/2)+'px',
					'overflow':'hidden'
				});
			});
			$('img',j_frames).each(function(i){
				$(this).css({
					'opacity':opts.frame_opacity,
					'height':img_h[i%item_count]*frame_img_scale[i%item_count]+'px',
					'width':img_w[i%item_count]*frame_img_scale[i%item_count]+'px',
					'position':'relative',
					'top':Math.min(0,(opts.frame_height-(frame_img_scale[i%item_count]*img_h[i%item_count]))/2)+'px',
					'left':Math.min(0,(opts.frame_width-(frame_img_scale[i%item_count]*img_w[i%item_count]))/2)+'px'

				}).mouseover(function(){
					$(this).stop().animate({'opacity':1.0},300);
				}).mouseout(function(){
					//Don't fade out current frame on mouseout
					if(!$(this).parent().parent().hasClass('current')) $(this).stop().animate({'opacity':opts.frame_opacity},300);
				});
			});
			$('.strip_wrapper',j_gallery).css({
				'position':'absolute',
				'overflow':'hidden'
			});
			if(filmstrip_orientation=='horizontal') {
				$('.strip_wrapper',j_gallery).css({
					'top':(opts.filmstrip_position=='top'?Math.max(gallery_padding,filmstrip_margin)+'px':opts.panel_height+gallery_padding+'px'),
					'left':((gallery_width-wrapper_width)/2)+gallery_padding+'px',
					'width':wrapper_width+'px',
					'height':strip_height+'px'
				});
			} else {
				$('.strip_wrapper',j_gallery).css({
					'left':(opts.filmstrip_position=='left'?Math.max(gallery_padding,filmstrip_margin)+'px':opts.panel_width+gallery_padding+'px'),
					'top':Math.max(gallery_padding,opts.frame_gap)+'px',
					'width':strip_width+'px',
					'height':wrapper_height+'px'
				});
			}
			$('.caption',j_gallery).css({
				'position':'absolute',
				'top':(opts.filmstrip_position=='bottom'?f_frame_height:0)+'px',
				'left':'0',
				'margin':'0',
				'width':f_frame_width+'px',
				'padding':'0',
				'height':frame_caption_size+'px',
				'overflow':'hidden',
				'lineHeight':frame_caption_size+'px'
			});
			var pointer = $('<div></div>');
			pointer.addClass('pointer').appendTo(j_gallery).css({
				 'position':'absolute',
				 'zIndex':'1000',
				 'width':'0px',
				 'fontSize':'0px',
				 'lineHeight':'0%',
				 'borderTopWidth':pointer_height+'px',
				 'borderRightWidth':(pointer_width/2)+'px',
				 'borderBottomWidth':pointer_height+'px',
				 'borderLeftWidth':(pointer_width/2)+'px',
				 'borderStyle':'solid'
			});

			//For IE6, use predefined color string in place of transparent (see stylesheet)
			var transColor = $.browser.msie && $.browser.version.substr(0,1)=='6' ? 'pink' : 'transparent'

			if(!opts.show_panels) { pointer.css('borderColor',transColor); }

				switch(opts.filmstrip_position) {
					case 'top': pointer.css({
									'bottom':(opts.panel_height-(pointer_height*2)+gallery_padding+filmstrip_margin)+'px',
				 					'left':((gallery_width-wrapper_width)/2)+(slide_method=='strip'?0:((f_frame_width+opts.frame_gap)*iterator))+((f_frame_width/2)-(pointer_width/2))+gallery_padding+'px',
									'borderBottomColor':transColor,
									'borderRightColor':transColor,
									'borderLeftColor':transColor
								}); break;
					case 'bottom': pointer.css({
										'top':(opts.panel_height-(pointer_height*2)+gallery_padding+filmstrip_margin)+'px',
				 						'left':((gallery_width-wrapper_width)/2)+(slide_method=='strip'?0:((f_frame_width+opts.frame_gap)*iterator))+((f_frame_width/2)-(pointer_width/2))+gallery_padding+'px',
										'borderTopColor':transColor,
										'borderRightColor':transColor,
										'borderLeftColor':transColor
									}); break;
					case 'left': pointer.css({
									'right':(opts.panel_width-pointer_width+gallery_padding+filmstrip_margin)+'px',
				 					'top':(f_frame_height/2)-(pointer_height)+(slide_method=='strip'?0:((f_frame_height+opts.frame_gap)*iterator))+gallery_padding+'px',
									'borderBottomColor':transColor,
									'borderRightColor':transColor,
									'borderTopColor':transColor
								}); break;
					case 'right': pointer.css({
									'left':(opts.panel_width-pointer_width+gallery_padding+filmstrip_margin)+'px',
				 					'top':(f_frame_height/2)-(pointer_height)+(slide_method=='strip'?0:((f_frame_height+opts.frame_gap)*iterator))+gallery_padding+'px',
									'borderBottomColor':transColor,
									'borderLeftColor':transColor,
									'borderTopColor':transColor
								}); break;
				}

			j_pointer = $('.pointer',j_gallery);

			//Add navigation buttons
			var navNext = $('<img />');
			navNext.addClass('nav-next').attr('src',theme_path+opts.nav_theme+'/next1.gif').appendTo(j_gallery).css({
				'position':'absolute',
				'cursor':'pointer'
			}).click(showNextItem);
			var navPrev = $('<img />');
			navPrev.addClass('nav-prev').attr('src',theme_path+opts.nav_theme+'/prev1.gif').appendTo(j_gallery).css({
				'position':'absolute',
				'cursor':'pointer'
			}).click(showPrevItem);
			if(filmstrip_orientation=='horizontal') {
				navNext.css({
					'top':(opts.filmstrip_position=='top'?Math.max(gallery_padding,filmstrip_margin):opts.panel_height+filmstrip_margin+gallery_padding)+((f_frame_height-22)/2)+'px',
					'right':((gallery_width+(gallery_padding*2))/2)-(wrapper_width/2)-opts.frame_gap-22+'px'
				});
				navPrev.css({
					'top':(opts.filmstrip_position=='top'?Math.max(gallery_padding,filmstrip_margin):opts.panel_height+filmstrip_margin+gallery_padding)+((f_frame_height-22)/2)+'px',
					'left':((gallery_width+(gallery_padding*2))/2)-(wrapper_width/2)-opts.frame_gap-22+'px'
				 });
			} else {
				navNext.css({
					'left':(opts.filmstrip_position=='left'?Math.max(gallery_padding,filmstrip_margin):opts.panel_width+filmstrip_margin+gallery_padding)+((f_frame_width-22)/2)+13+'px',
					'top':wrapper_height+(Math.max(gallery_padding,opts.frame_gap)*2)+'px'
				});
				navPrev.css({
					'left':(opts.filmstrip_position=='left'?Math.max(gallery_padding,filmstrip_margin):opts.panel_width+filmstrip_margin+gallery_padding)+((f_frame_width-22)/2)-13+'px',
					'top':wrapper_height+(Math.max(gallery_padding,opts.frame_gap)*2)+'px'
				});
			}
		};

	//Check mouse to see if it is within the borders of the panel
	//More reliable than 'mouseover' event when elements overlay the panel
		function mouseIsOverGallery(x,y) {
			var pos = getPos(j_gallery[0]);
			var top = pos.top;
			var left = pos.left;
			return x > left && x < left+gallery_width+(filmstrip_orientation=='horizontal'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin)) && y > top && y < top+gallery_height+(filmstrip_orientation=='vertical'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin));
		};

		function getInt(i) {
			i = parseInt(i,10);
			if(isNaN(i)) { i = 0; }
			return i;
		}

		function buildGallery() {
			var gallery_images = opts.show_filmstrip?$('img',j_frames):$('img',j_panels);
			gallery_images.each(function(i){
				img_h[i] = this.height;
				img_w[i] = this.width;
				if(opts.frame_scale=='nocrop') {
					frame_img_scale[i] = Math.min(opts.frame_height/img_h[i],opts.frame_width/img_w[i]);
				} else {
					frame_img_scale[i] = Math.max(opts.frame_height/img_h[i],opts.frame_width/img_w[i]);
				}

				if(opts.panel_scale=='nocrop') {
					panel_img_scale[i] = Math.min(opts.panel_height/img_h[i],opts.panel_width/img_w[i]);
				} else {
					panel_img_scale[i] = Math.max(opts.panel_height/img_h[i],opts.panel_width/img_w[i]);
				}
			});

	/************************************************/
	/*	Apply CSS Styles							*/
	/************************************************/
			j_gallery.css({
				'position':'relative',
				'width':gallery_width+(filmstrip_orientation=='horizontal'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin))+'px',
				'height':gallery_height+(filmstrip_orientation=='vertical'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin))+'px'
			});

	/************************************************/
	/*	Build filmstrip and/or panels				*/
	/************************************************/
			if(opts.show_filmstrip) {
				buildFilmstrip();
				enableFrameClicking();
			}
			if(opts.show_panels) {
				buildPanels();
			}

	/************************************************/
	/*	Add events to various elements				*/
	/************************************************/
			if(opts.pause_on_hover || (opts.show_panels && !opts.show_filmstrip)) {
				$().mousemove(function(e){
					if(mouseIsOverGallery(e.pageX,e.pageY)) {
						if(opts.pause_on_hover) {
							if(!paused) {
								$(document).oneTime(500,"animation_pause",function(){
									$(document).stopTime("transition");
									paused=true;
								});
							}
						}
						if(opts.show_panels && !opts.show_filmstrip && !panel_nav_displayed) {
							$('.nav-next-overlay').fadeIn('fast');
							$('.nav-prev-overlay').fadeIn('fast');
							$('.nav-next',j_gallery).fadeIn('fast');
							$('.nav-prev',j_gallery).fadeIn('fast');
							panel_nav_displayed = true;
						}
					} else {
						if(opts.pause_on_hover) {
							$(document).stopTime("animation_pause");
							if(paused) {
								$(document).everyTime(opts.transition_interval,"transition",function(){
									showNextItem();
								});
								paused = false;
							}
						}
						if(opts.show_panels && !opts.show_filmstrip && panel_nav_displayed) {
							$('.nav-next-overlay').fadeOut('fast');
							$('.nav-prev-overlay').fadeOut('fast');
							$('.nav-next',j_gallery).fadeOut('fast');
							$('.nav-prev',j_gallery).fadeOut('fast');
							panel_nav_displayed = false;
						}
					}
				});
			}


	/****************************************************************/
	/*	Initiate Automated Animation								*/
	/****************************************************************/

			//Hide loading box
			j_filmstrip.css('visibility','visible');
			j_gallery.css('visibility','visible');
			$('.loader',j_gallery).fadeOut('1000',function(){
				//Show the 'first' panel
				showItem(iterator);
				//If we have more than one item, begin automated transitions
				if(item_count > 1) {
					$(document).everyTime(opts.transition_interval,"transition",function(){
						showNextItem();
					});
				}
			});
		}

/************************************************/
/*	Main Plugin Code							*/
/************************************************/
		return this.each(function() {
			//Hide <ul>
			$(this).css('visibility','hidden');

			//Wrap <ul> in <div> and transfer ID to container <div>
			//Assign filmstrip class to <ul>
			$(this).wrap("<div></div>");
			j_gallery = $(this).parent();
			j_gallery.css('visibility','hidden').attr('id',$(this).attr('id')).addClass('gallery');
			$(this).removeAttr('id').addClass('filmstrip');

			$(document).stopTime("transition");
			$(document).stopTime("animation_pause");

			id = j_gallery.attr('id');

			//If there is no defined panel content, we will scale panel images
			scale_panel_images = $('.panel-content',j_gallery).length==0;

			//Define dimensions of pointer <div>
			pointer_height = opts.pointer_size;
			pointer_width = opts.pointer_size*2;

			//Determine filmstrip orientation (vertical or horizontal)
			//Do not show captions on vertical filmstrips
			filmstrip_orientation = (opts.filmstrip_position=='top'||opts.filmstrip_position=='bottom'?'horizontal':'vertical');
			if(filmstrip_orientation=='vertical') opts.show_captions = false;

			//Determine path between current page and plugin images
			//Scan script tags and look for path to GalleryView plugin
			/*
			PRIMOSTUDIO MODIF FOR COMRESSEION

			$('script').each(function(i){
				var s = $(this);
				if(s.attr('src') && s.attr('src').match(/jquery\.galleryview/)){
					loader_path = s.attr('src').split('jquery.galleryview')[0];
					theme_path = s.attr('src').split('jquery.galleryview')[0]+'themes/';
				}
			});

			PRIMOSTUDIO MODIF FOR COMRESSEION
			*/
			loader_path = '/js/';
			theme_path = '/js/themes/';


			j_filmstrip = $('.filmstrip',j_gallery);
			j_frames = $('li',j_filmstrip);
			j_frames.addClass('frame');

			//If the user wants panels, generate them using the filmstrip images
			if(opts.show_panels) {
				for(i=j_frames.length-1;i>=0;i--) {
					if(j_frames.eq(i).find('.panel-content').length>0) {
						j_frames.eq(i).find('.panel-content').remove().prependTo(j_gallery).addClass('panel');
					} else {
						p = $('<div>');
						p.addClass('panel');
						im = $('<img />');
						im.attr('src',j_frames.eq(i).find('img').eq(0).attr('src')).appendTo(p);
						p.prependTo(j_gallery);
						j_frames.eq(i).find('.panel-overlay').remove().appendTo(p);
					}
				}
			} else {
				$('.panel-overlay',j_frames).remove();
				$('.panel-content',j_frames).remove();
			}

			//If the user doesn't want a filmstrip, delete it
			if(!opts.show_filmstrip) { j_filmstrip.remove(); }
			else {
				//Wrap the frame images (and links, if applicable) in container divs
				//These divs will handle cropping and zooming of the images
				j_frames.each(function(i){
					if($(this).find('a').length>0) {
						$(this).find('a').wrap('<div class="img_wrap"></div>');
					} else {
						$(this).find('img').wrap('<div class="img_wrap"></div>');
					}
				});
				j_frame_img_wrappers = $('.img_wrap',j_frames);
			}

			j_panels = $('.panel',j_gallery);

			if(!opts.show_panels) {
				opts.panel_height = 0;
				opts.panel_width = 0;
			}


			//Determine final frame dimensions, accounting for user-added padding and border
			f_frame_width = opts.frame_width+extraWidth(j_frame_img_wrappers);
			f_frame_height = opts.frame_height+extraHeight(j_frame_img_wrappers);

			//Number of frames in filmstrip
			item_count = opts.show_panels?j_panels.length:j_frames.length;

			//Number of frames that can display within the gallery block
			//64 = width of block for navigation button * 2 + 20
			if(filmstrip_orientation=='horizontal') {
				strip_size = opts.show_panels?Math.floor((opts.panel_width-((opts.frame_gap+22)*2))/(f_frame_width+opts.frame_gap)):Math.min(item_count,opts.filmstrip_size);
			} else {
				strip_size = opts.show_panels?Math.floor((opts.panel_height-(opts.frame_gap+22))/(f_frame_height+opts.frame_gap)):Math.min(item_count,opts.filmstrip_size);
			}

			/************************************************/
			/*	Determine transition method for filmstrip	*/
			/************************************************/
					//If more items than strip size, slide filmstrip
					//Otherwise, slide pointer
					if(strip_size >= item_count) {
						slide_method = 'pointer';
						strip_size = item_count;
					}
					else {slide_method = 'strip';}

					iterator = (strip_size<item_count?item_count:0)+opts.start_frame-1;

			/************************************************/
			/*	Determine dimensions of various elements	*/
			/************************************************/
					filmstrip_margin = (opts.show_panels?getInt(j_filmstrip.css('marginTop')):0);
					j_filmstrip.css('margin','0px');

					if(filmstrip_orientation=='horizontal') {
						//Width of gallery block
						gallery_width = opts.show_panels?opts.panel_width:(strip_size*(f_frame_width+opts.frame_gap))+44+opts.frame_gap;

						//Height of gallery block = screen + filmstrip + captions (optional)
						gallery_height = (opts.show_panels?opts.panel_height:0)+(opts.show_filmstrip?f_frame_height+filmstrip_margin+(opts.show_captions?frame_caption_size:0):0);
					} else {
						//Width of gallery block
						gallery_height = opts.show_panels?opts.panel_height:(strip_size*(f_frame_height+opts.frame_gap))+22;

						//Height of gallery block = screen + filmstrip + captions (optional)
						gallery_width = (opts.show_panels?opts.panel_width:0)+(opts.show_filmstrip?f_frame_width+filmstrip_margin:0);
					}



					//Width of filmstrip
					if(filmstrip_orientation=='horizontal') {
						if(slide_method == 'pointer') {strip_width = (f_frame_width*item_count)+(opts.frame_gap*(item_count));}
						else {strip_width = (f_frame_width*item_count*3)+(opts.frame_gap*(item_count*3));}
					} else {
						strip_width = (f_frame_width+filmstrip_margin);
					}

					if(filmstrip_orientation=='horizontal') {
						strip_height = (f_frame_height+filmstrip_margin+(opts.show_captions?frame_caption_size:0));
					} else {
						if(slide_method == 'pointer') {strip_height = (f_frame_height*item_count+opts.frame_gap*(item_count));}
						else {strip_height = (f_frame_height*item_count*3)+(opts.frame_gap*(item_count*3));}
					}

					//Width of filmstrip wrapper (to hide overflow)
					wrapper_width = ((strip_size*f_frame_width)+((strip_size-1)*opts.frame_gap));
					wrapper_height = ((strip_size*f_frame_height)+((strip_size-1)*opts.frame_gap));


					gallery_padding = getInt(j_gallery.css('paddingTop'));
					j_gallery.css('padding','0px');
			/********************************************************/
			/*	PLACE LOADING BOX OVER GALLERY UNTIL IMAGES LOAD	*/
			/********************************************************/
					galleryPos = getPos(j_gallery[0]);
					$('<div>').addClass('loader').css({
						'position':'absolute',
						'zIndex':'32666',
						'opacity':1,
						'top':'0px',
						'left':'0px',
						'width':gallery_width+(filmstrip_orientation=='horizontal'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin))+'px',
						'height':gallery_height+(filmstrip_orientation=='vertical'?(gallery_padding*2):gallery_padding+Math.max(gallery_padding,filmstrip_margin))+'px'
					}).appendTo(j_gallery);


			if(!window_loaded) {
				$(window).load(function(){
					window_loaded = true;
					buildGallery();
				});
			} else {
				buildGallery();
			}

		});
	};

	$.fn.galleryView.defaults = {

		show_panels: true,
		show_filmstrip: true,

		panel_width: 600,
		panel_height: 400,
		frame_width: 60,
		frame_height: 40,

		start_frame: 1,
		filmstrip_size: 3,
		transition_speed: 800,
		transition_interval: 4000,

		overlay_opacity: 0.7,
		frame_opacity: 0.3,

		pointer_size: 8,

		nav_theme: 'dark',
		easing: 'swing',

		filmstrip_position: 'bottom',
		overlay_position: 'bottom',

		panel_scale: 'nocrop',
		frame_scale: 'crop',

		frame_gap: 5,

		show_captions: false,
		fade_panels: true,
		pause_on_hover: false
	};
})(jQuery);


/**
 * jQuery.timers - Timer abstractions for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/02/08
 *
 * @author Blair Mitchelmore
 * @version 1.1.2
 *
 **/

jQuery.fn.extend({
	everyTime: function(interval, label, fn, times, belay) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, times, belay);
		});
	},
	oneTime: function(interval, label, fn) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, 1);
		});
	},
	stopTime: function(label, fn) {
		return this.each(function() {
			jQuery.timer.remove(this, label, fn);
		});
	}
});

jQuery.event.special

jQuery.extend({
	timer: {
		global: [],
		guid: 1,
		dataKey: "jQuery.timer",
		regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
		powers: {
			// Yeah this is major overkill...
			'ms': 1,
			'cs': 10,
			'ds': 100,
			's': 1000,
			'das': 10000,
			'hs': 100000,
			'ks': 1000000
		},
		timeParse: function(value) {
			if (value == undefined || value == null)
				return null;
			var result = this.regex.exec(jQuery.trim(value.toString()));
			if (result[2]) {
				var num = parseFloat(result[1]);
				var mult = this.powers[result[2]] || 1;
				return num * mult;
			} else {
				return value;
			}
		},
		add: function(element, interval, label, fn, times, belay) {
			var counter = 0;

			if (jQuery.isFunction(label)) {
				if (!times)
					times = fn;
				fn = label;
				label = interval;
			}

			interval = jQuery.timer.timeParse(interval);

			if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
				return;

			if (times && times.constructor != Number) {
				belay = !!times;
				times = 0;
			}

			times = times || 0;
			belay = belay || false;

			var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});

			if (!timers[label])
				timers[label] = {};

			fn.timerID = fn.timerID || this.guid++;

			var handler = function() {
				if (belay && this.inProgress)
					return;
				this.inProgress = true;
				if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
					jQuery.timer.remove(element, label, fn);
				this.inProgress = false;
			};

			handler.timerID = fn.timerID;

			if (!timers[label][fn.timerID])
				timers[label][fn.timerID] = window.setInterval(handler,interval);

			this.global.push( element );

		},
		remove: function(element, label, fn) {
			var timers = jQuery.data(element, this.dataKey), ret;

			if ( timers ) {

				if (!label) {
					for ( label in timers )
						this.remove(element, label, fn);
				} else if ( timers[label] ) {
					if ( fn ) {
						if ( fn.timerID ) {
							window.clearInterval(timers[label][fn.timerID]);
							delete timers[label][fn.timerID];
						}
					} else {
						for ( var fn in timers[label] ) {
							window.clearInterval(timers[label][fn]);
							delete timers[label][fn];
						}
					}

					for ( ret in timers[label] ) break;
					if ( !ret ) {
						ret = null;
						delete timers[label];
					}
				}

				for ( ret in timers ) break;
				if ( !ret )
					jQuery.removeData(element, this.dataKey);
			}
		}
	}
});

jQuery(window).bind("unload", function() {
	jQuery.each(jQuery.timer.global, function(index, item) {
		jQuery.timer.remove(item);
	});
});


/*
 * jquery.tools 1.1.1 - The missing UI library for the Web
 *
 * [tools.tooltip-1.1.1]
 *
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * -----
 *
 * File generated: Fri Sep 18 10:48:58 GMT+00:00 2009
 */
(function(c){c.tools=c.tools||{};c.tools.tooltip={version:"1.1.1",conf:{effect:"toggle",fadeOutSpeed:"fast",tip:null,predelay:0,delay:30,opacity:1,lazy:undefined,position:["top","center"],offset:[0,0],cancelDefault:true,relative:false,events:{def:"mouseover,mouseout",input:"focus,blur",widget:"focus mouseover,blur mouseout"},api:false},addEffect:function(d,f,e){b[d]=[f,e]}};var b={toggle:[function(d){var e=this.getConf();this.getTip().css({opacity:e.opacity}).show();d.call()},function(d){this.getTip().hide();d.call()}],fade:[function(d){this.getTip().fadeIn(this.getConf().fadeInSpeed,d)},function(d){this.getTip().fadeOut(this.getConf().fadeOutSpeed,d)}]};function a(e,f){var o=this,j=c(this);e.data("tooltip",o);var k=e.next();if(f.tip){k=c(f.tip);if(k.length>1){k=e.nextAll(f.tip).eq(0);if(!k.length){k=e.parent().nextAll(f.tip).eq(0)}}}function n(t){var s=f.relative?e.position().top:e.offset().top,r=f.relative?e.position().left:e.offset().left,u=f.position[0];s-=k.outerHeight()-f.offset[0];r+=e.outerWidth()+f.offset[1];var p=k.outerHeight()+e.outerHeight();if(u=="center"){s+=p/2}if(u=="bottom"){s+=p}u=f.position[1];var q=k.outerWidth()+e.outerWidth();if(u=="center"){r-=q/2}if(u=="left"){r-=q}return{top:s,left:r}}var h=e.is(":input"),d=h&&e.is(":checkbox, :radio, select, :button"),g=e.attr("type"),m=f.events[g]||f.events[h?(d?"widget":"input"):"def"];m=m.split(/,\s*/);e.bind(m[0],function(q){var p=k.data("trigger");if(p&&p[0]!=this){k.hide()}q.target=this;o.show(q);k.hover(o.show,function(){o.hide(q)})});e.bind(m[1],function(p){o.hide(p)});if(!c.browser.msie&&!h){e.mousemove(function(){if(!o.isShown()){e.triggerHandler("mouseover")}})}if(f.opacity<1){k.css("opacity",f.opacity)}var l=0,i=e.attr("title");if(i&&f.cancelDefault){e.removeAttr("title");e.data("title",i)}c.extend(o,{show:function(q){if(q){e=c(q.target)}clearTimeout(k.data("timer"));if(k.is(":animated")||k.is(":visible")){return o}function p(){k.data("trigger",e);var s=n(q);if(f.tip&&i){k.html(e.data("title"))}var r=c.Event("onBeforeShow");j.trigger(r,[s]);if(r.isDefaultPrevented()){return o}s=n(q);k.css({position:"absolute",top:s.top,left:s.left});b[f.effect][0].call(o,function(){j.trigger("onShow")})}if(f.predelay){clearTimeout(l);l=setTimeout(p,f.predelay)}else{p()}return o},hide:function(q){clearTimeout(k.data("timer"));clearTimeout(l);if(!k.is(":visible")){return}function p(){var r=c.Event("onBeforeHide");j.trigger(r);if(r.isDefaultPrevented()){return}b[f.effect][1].call(o,function(){j.trigger("onHide")})}if(f.delay&&q){k.data("timer",setTimeout(p,f.delay))}else{p()}return o},isShown:function(){return k.is(":visible, :animated")},getConf:function(){return f},getTip:function(){return k},getTrigger:function(){return e},bind:function(p,q){j.bind(p,q);return o},onHide:function(p){return this.bind("onHide",p)},onBeforeShow:function(p){return this.bind("onBeforeShow",p)},onShow:function(p){return this.bind("onShow",p)},onBeforeHide:function(p){return this.bind("onBeforeHide",p)},unbind:function(p){j.unbind(p);return o}});c.each(f,function(p,q){if(c.isFunction(q)){o.bind(p,q)}})}c.prototype.tooltip=function(d){var e=this.eq(typeof d=="number"?d:0).data("tooltip");if(e){return e}var f=c.extend(true,{},c.tools.tooltip.conf);if(c.isFunction(d)){d={onBeforeShow:d}}else{if(typeof d=="string"){d={tip:d}}}d=c.extend(true,f,d);if(typeof d.position=="string"){d.position=d.position.split(/,?\s/)}if(d.lazy!==false&&(d.lazy===true||this.length>20)){this.one("mouseover",function(g){e=new a(c(this),d);e.show(g)})}else{this.each(function(){e=new a(c(this),d)})}return d.api?e:this}})(jQuery);






/***
* PRIMOSTUDIO JS
*
*/


$(window).bind('load', function() {
    var preload = new Array();
    $('.hover').each(function() {
        s = $(this).attr("src").replace(/_off\.(.+)$/i, '_on.$1');
        preload.push(s)
    });
    var img = document.createElement('img');
    $(img).bind('load', function() {
        if(preload[0]) {
            this.src = preload.shift();
        }
    }).trigger('load');
});
$(document).ready(function() {
	jQuery.ifixpng('js/pixel.gif');
	jQuery('img[src$=png]').ifixpng();
	/* general hovers */
	$('.hover').each(function() {
			if ($(this).attr("src").match(/_on\.(.+)$/i)) {
					$(this).removeClass('hover');
			}
	});
	$('.hover').hover(function() {
			s = $(this).attr('src').replace(/_off\.(.+)$/i, '_on.$1');
			$(this).attr('src', s);
	}, function() {
			s = $(this).attr('src').replace(/_on\.(.+)$/i, '_off.$1');
			$(this).attr('src', s);
	});
	// EXTERNAL LINKS
	$('a.external, a.btn-pdf, a.blank').attr('target','_blank');
	// HEAD MENU
	$('#head-menu li:not(.selected) a')
		.css( {backgroundPosition: "0 0"} )
		.mouseover(function(){
			$(this).stop().animate(
				{backgroundPosition:"(-160px 0)"},
				{duration:500})
			})
		.mouseout(function(){
			$(this).stop().animate(
				{backgroundPosition:"(0 0)"},
				{duration:500})
		});
	// SIDEBAR MENU
	/*
	$('#sidebar-menu li:not(.selected) ul').hide();
	$('#sidebar-menu li a').click(function() {
		$('#sidebar-menu li').removeClass('active');
		$(this).parent().addClass('active');
		var checkElement = $(this).next();
		if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
			return false;
		}
		if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
			$('#sidebar-menu ul:visible').slideUp('normal');
			//$('#sidebar-menu ul:visible').hide();
			$('#page-content').css('height','auto');
			checkElement.slideDown('normal',setPageHeight);
			return false;
		}
	});
	*/
	$('#apartments-menu li:not(.selected) ul, #chalets-menu li:not(.selected) ul').hide();
	$('#apartments-menu li a, #chalets-menu li a').click(function() {
		$('#apartments-menu li, #chalets-menu li').removeClass('active');
		$(this).parent().addClass('active');
		var checkElement = $(this).next();
		if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
			return false;
		}
		if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
			$('#apartments-menu ul:visible, #chalets-menu ul:visible').slideUp('normal');
			$('#page-content').css('height','auto');
			checkElement.slideDown('normal',setPageHeight);
			return false;
		}
	});


	/** MENU APPS **/

	$('#menu-reasons li:first').addClass('selected'); //Activate first tab

	$('#menu-apartment li a, #menu-page li a, #menu-reasons li a')
		.mouseover(function(){
			if(!$(this).parent().hasClass('selected')){
				$(this).css( {backgroundPosition: "0 0"} )
				$(this).stop().animate(
					{backgroundPosition:"(-220px 0)"},
					{duration:500})
			}
		})
		.mouseout(function(){
			if(!$(this).parent().hasClass('selected')){
				$(this).stop().animate(
					{backgroundPosition:"(0 0)"},
					{duration:500})
			}
		});

	/*** TABS **/
	//On Click Event
	$('.tab-nav li a').click(function() {
		//setPageTab($(this).attr('href'));
		//debug(window.location +' :: '+ $(this).attr('href'));

		//window.location = window.location + $(this).attr('href');
		var cloc = window.location.href
		var curl = cloc.split('#')[0];

		//debug(cloc +' :: '+ curl);

		window.location = curl + $(this).attr('href');

		window.location.reload();

		//return false;
	});

	$('#menu-reasons a').click(function() {
		//setPageTab($(this).attr('href'));

		var hash = $(this).attr('href');
		window.location.hash = hash;

		//debug($(this).attr('href') +' :: '+ window.location.hash);

		var h = hash.slice(0, -1);

		//debug($(h));

		$('#page-content').css('height','auto');
		$('.tabs:not('+h+')').hide();
		//var id = '#'+ $('.tab-nav li a[href="'+ hash +'"]').parent().parent().attr('id');

		$('#menu-reasons li a').css( {backgroundPosition: "0 0"} ).parent().removeClass('selected');
		$('#menu-reasons li a[href="'+ hash +'"]').css( {backgroundPosition: "-220px 0"}).parent().addClass('selected');

		$(h).fadeIn('normal',setPageHeight);

		return false;
	});

	var hash = window.location.hash;
	if(hash != ''){
		setPageTab(hash);
	}else{
		$('#menu-apartment li:first').addClass('selected'); //Activate first tab
		$('#menu-reasons li:first').addClass('selected'); //Activate first tab
		$('.tabs:gt(0)').hide(); //Hide all content
	}

	$('.btn-tabs').click(function() {
		$('#menu-apartment li a').css( {backgroundPosition: "0 0"} );
		$('#menu-apartment li a').parent().removeClass('selected');

		$('.tabs').hide();

		var activeTab = $(this).attr('href');
		$('#menu-apartment li a[href="'+ activeTab +'"]').parent().addClass('selected');
		$('#menu-apartment li a[href="'+ activeTab +'"]').css( {backgroundPosition: "-200px 0"} );

		$('#page-content').css('height','auto');
		$(activeTab).fadeIn('normal',setPageHeight);

		return false;
	});

	$('#page-content').css('height','auto');
	/*** TABS **/

	$('#faq-nav a, a.top').click(function() {
   scrollToID($(this).attr("href"));
   return false;
	});

	setPageHeight();

	/** CALENDAR **/
	$('table.calendar td a[title]').livequery(function(){ $(this).tooltip({tip: '#tip',offset: [-10, 0]});    });
	//$('#bt-prev-year, #bt-next-year').click(function(){
	$('#bt-prev-year, #bt-next-year').livequery('click', function(event) {
		var toLoad = $(this).attr('href') +' #calendar';
		//console.log(toLoad);
		$('#calendar-holder').hide('fast',loadContent);
		$('#loading').show('fast');
		function loadContent() {
			$('#calendar-holder').empty();
			$('#calendar-holder').load(toLoad,'',showNewContent())
		}
		function showNewContent() {
			$('#calendar-holder').show('fast',hideLoader());
		}
		function hideLoader() { $('#loading').hide(); }

		return false;
	});


	/** SLIDESHOW & GALLERY **/

	if($('#slideshow').length > 0)	initSlideShow();
	//
	$('#gallery').galleryView({
		panel_width: 480,
		panel_height: 320,
		frame_width: 50,
		frame_height: 50,
		transition_speed: 350,
		easing: 'easeInOutQuad',
		transition_interval: 0,
		background_color: 'transparent',
		border: 'none',
		nav_theme: 'light',
		easing: 'easeInOutQuad',
		pause_on_hover: true
	});


	/** NEWSLETTER SUBSCRIBE **/
	var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
	//$("#subscribe").livequery('click', function(event) {
	$("#subscribe").click( function() {
    var hasError = false;
		var emailVal = $("#newsletter_email").val();
//		alert(emailVal)
		if(emailVal == '' || !emailReg.test(emailVal)) {
			$("#newsletter_email").attr('value','Enter your email.');
			hasError = true;
		}
		if(hasError == false) {
			$("#newsletter_email").attr('value','Sending');
			$.post("/includes/newsletter.php",{ email: emailVal},function(data){
				$("#newsletter_email").attr('value','Subscribed');
			}
		 );
		}
		return false;
  });

});
function debug($obj) {
	if (window.console && window.console.debug)
	 window.console.debug('debug: %o', $obj);
};


function setPageTab(hash){
	//var hash= $(this).attr('href');

	window.location.hash = hash;

	var h = hash.slice(0, -1);
	$('#page-content').css('height','auto');
	$('.tabs:not('+h+')').hide();
	//var id = '#'+ $('.tab-nav li a[href="'+ hash +'"]').parent().parent().attr('id');

	$('.tab-nav li a').css( {backgroundPosition: "0 0"} ).parent().removeClass('selected');
	$('.tab-nav li a[href="'+ hash +'"]').css( {backgroundPosition: "-220px 0"}).parent().addClass('selected');

	$(h).fadeIn('normal',setPageHeight);

};

function setPageHeight(){
	var sb= $('#sidebar').height();
	var pc= $('#page-content').height();
if (pc < sb) $('#page-content').css('height',sb+'px');
};

function scrollToID(id){
 var targetOffset = $(id).offset().top;
 $('html, body').animate({scrollTop: targetOffset}, 500, function() {
	location.hash = id;
 });
};

function showImage(src){
	$('#galleryimage img').fadeOut('normal').remove();
	var largeImage = new Image();
	$(largeImage).attr('src', src).load(function(){
		$(largeImage).hide();
		$('#galleryimage').append(largeImage);
		$(largeImage).fadeIn('slow');
	});
};


function initSlideShow() {

	//Set the opacity of all images to 0
	$('#slideshow a').css({opacity: 0.0});

	//Get the first image and display it (set it to full opacity)
	$('#slideshow a:first').css({opacity: 1.0});

	//Set the caption background to semi-transparent
	$('#slideshow .caption').css({opacity: 0.7});

	//Resize the width of the caption according to the image width
	$('#slideshow .caption').css({width: $('#slideshow a').find('img').css('width')});

	//Get the caption of the first image from REL attribute and display it
	//var caption = $('#slideshow a:first').find('img').attr('rel');
	var caption = $('#slideshow a:first').attr('rel');
	if(caption.length > 0){
		$('#slideshow .content').html(caption).animate({opacity: 0.7}, 400);
	}else{
		$('#slideshow .caption').css({'opacity':'0','height':'1px'})
	}
	//Call the slideshow function to run the slideshow, 6000 = change to next image after 6 seconds
	setInterval('slideShow()',6000);


};
function slideShow() {

	//if no IMGs have the show class, grab the first image
	var current = ($('#slideshow a.show')?  $('#slideshow a.show') : $('#slideshow a:first'));

	//Get next image, if it reached the end of the slideshow, rotate it back to the first image
	var next = ((current.next().length) ? ((current.next().hasClass('caption'))? $('#slideshow a:first') :current.next()) : $('#slideshow a:first'));

	//Get next image caption
	//var caption = next.find('img').attr('rel');
	var caption = next.attr('rel');

	//Set the fade in effect for the next image, show class has higher z-index
	next.css({opacity: 0.0})
	.addClass('show')
	.animate({opacity: 1.0}, 1000);

	//Hide the current image
	current.animate({opacity: 0.0}, 1000)
	.removeClass('show');

	//Set the opacity to 0 and height to 1px
	//$('#slideshow .caption').animate({opacity: 0.0}, { queue:false, duration:50 }).animate({height: '1px'}, { queue:true, duration:300 });	//Animate the caption, opacity to 0.7 and heigth to 100px, a slide up effect
	//$('#slideshow .caption').animate({opacity: 0.7},100 ).animate({height: '60px'},500 );
	if(caption.length > 0){
		$('#slideshow .caption').animate({opacity: 0.0}, { queue:false, duration:50 }).animate({height: '1px'}, { queue:true, duration:300 }).animate({opacity: 0.7},100 ).animate({height: '60px'},500 );
	//Display the content
		$('#slideshow .content').html(caption);
	}else{
		$('#slideshow .caption').animate({opacity: 0.0}, { queue:false, duration:50 }).animate({height: '1px'}, { queue:true, duration:300 });
	}
};
function showGalleryImage(src,ttl){
	$('#gallery img').fadeOut('fast').remove();
	$('#gallery-caption').hide().empty();

	var largeImage = new Image();
!	$(largeImage).attr({'src': src}).load(function(){
		$(largeImage).hide();
		$('#gallery').append(largeImage);
		$(largeImage).fadeIn('normal');
		$('#gallery-caption').html(ttl).fadeIn("normal");
	});
};

