/*
 * jquery plugin -version 1000
 * jq.colorpicker.js	-Farbtastic 1.2
 * jq.form.js -version: 2.24
 * jq.hover.js -hoverIntent r5
 * jq.rating.js -jQuery Star Rating Plugin v1.1
 * jq.tabs.js -Tabs 3 - New Wave Tabs
 * jq.thickbox.js -Thickbox 3.1 - One Box To Rule Them All
 * jq.cookie.js -Cookie plugin - Klaus Hartl (stilbuero.de)
 * jq.timer.js -Timer plugin - http://jquery.offput.ca/timers/ 
 * jq.scroolto.js -ScrollTo - Copyright (c) 2007-2009 Ariel Flesler 
 *
 */

// $Id: jq-1000.js,v 1.1 2009/05/27 02:28:29 edgar Exp $

// Farbtastic 1.2

jQuery.fn.farbtastic = function (callback) {
	$.farbtastic(this, callback);
	return this;
};

jQuery.farbtastic = function (container, callback) {
	var container = $(container).get(0);
	return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
};

jQuery._farbtastic = function (container, callback) {
	// Store farbtastic object
	var fb = this;

	// Insert markup
	$(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
	var e = $('.farbtastic', container);
	fb.wheel = $('.wheel', container).get(0);
	// Dimensions
	fb.radius = 84;
	fb.square = 100;
	fb.width = 194;

	// Fix background PNGs in IE6
	if (navigator.appVersion.match(/MSIE [0-6]\./)) {
	$('*', e).each(function () {
		if (this.currentStyle.backgroundImage != 'none') {
			var image = this.currentStyle.backgroundImage;
			image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
			$(this).css({
			'backgroundImage': 'none',
			'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
			});
		}
	});
	}

	/**
	* Link to the given element(s) or callback.
	*/
	fb.linkTo = function (callback) {
	// Unbind previous nodes
	if (typeof fb.callback == 'object') {
		$(fb.callback).unbind('keyup', fb.updateValue);
	}

	// Reset color
	fb.color = null;

	// Bind callback or elements
	if (typeof callback == 'function') {
		fb.callback = callback;
	}
	else if (typeof callback == 'object' || typeof callback == 'string') {
		fb.callback = $(callback);
		fb.callback.bind('keyup', fb.updateValue);
		if (fb.callback.get(0).value) {
			fb.setColor(fb.callback.get(0).value);
		}
	}
	return this;
	};
	fb.updateValue = function (event) {
	if (this.value && this.value != fb.color) {
		fb.setColor(this.value);
	}
	};

	/**
	* Change color with HTML syntax #123456
	*/
	fb.setColor = function (color) {
	var unpack = fb.unpack(color);
	if (fb.color != color && unpack) {
		fb.color = color;
		fb.rgb = unpack;
		fb.hsl = fb.RGBToHSL(fb.rgb);
		fb.updateDisplay();
	}
	return this;
	};

	/**
	* Change color with HSL triplet [0..1, 0..1, 0..1]
	*/
	fb.setHSL = function (hsl) {
	fb.hsl = hsl;
	fb.rgb = fb.HSLToRGB(hsl);
	fb.color = fb.pack(fb.rgb);
	fb.updateDisplay();
	return this;
	};

	/////////////////////////////////////////////////////

	/**
	* Retrieve the coordinates of the given event relative to the center
	* of the widget.
	*/
	fb.widgetCoords = function (event) {
	var x, y;
	var el = event.target || event.srcElement;
	var reference = fb.wheel;

	if (typeof event.offsetX != 'undefined') {
		// Use offset coordinates and find common offsetParent
		var pos = { x: event.offsetX, y: event.offsetY };

		// Send the coordinates upwards through the offsetParent chain.
		var e = el;
		while (e) {
			e.mouseX = pos.x;
			e.mouseY = pos.y;
			pos.x += e.offsetLeft;
			pos.y += e.offsetTop;
			e = e.offsetParent;
		}

		// Look for the coordinates starting from the wheel widget.
		var e = reference;
		var offset = { x: 0, y: 0 };
		while (e) {
			if (typeof e.mouseX != 'undefined') {
			x = e.mouseX - offset.x;
			y = e.mouseY - offset.y;
			break;
			}
			offset.x += e.offsetLeft;
			offset.y += e.offsetTop;
			e = e.offsetParent;
		}

		// Reset stored coordinates
		e = el;
		while (e) {
			e.mouseX = undefined;
			e.mouseY = undefined;
			e = e.offsetParent;
		}
	}
	else {
		// Use absolute coordinates
		var pos = fb.absolutePosition(reference);
		x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
		y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
	}
	// Subtract distance to middle
	return { x: x - fb.width / 2, y: y - fb.width / 2 };
	};

	/**
	* Mousedown handler
	*/
	fb.mousedown = function (event) {
	// Capture mouse
	if (!document.dragging) {
		$(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
		document.dragging = true;
	}

	// Check which area is being dragged
	var pos = fb.widgetCoords(event);
	fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;

	// Process
	fb.mousemove(event);
	return false;
	};

	/**
	* Mousemove handler
	*/
	fb.mousemove = function (event) {
	// Get coordinates relative to color picker center
	var pos = fb.widgetCoords(event);

	// Set new HSL parameters
	if (fb.circleDrag) {
		var hue = Math.atan2(pos.x, -pos.y) / 6.28;
		if (hue < 0) hue += 1;
		fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
	}
	else {
		var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
		var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
		fb.setHSL([fb.hsl[0], sat, lum]);
	}
	return false;
	};

	/**
	* Mouseup handler
	*/
	fb.mouseup = function () {
	// Uncapture mouse
	$(document).unbind('mousemove', fb.mousemove);
	$(document).unbind('mouseup', fb.mouseup);
	document.dragging = false;
	};

	/**
	* Update the markers and styles
	*/
	fb.updateDisplay = function () {
	// Markers
	var angle = fb.hsl[0] * 6.28;
	$('.h-marker', e).css({
		left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
		top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
	});

	$('.sl-marker', e).css({
		left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
		top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
	});

	// Saturation/Luminance gradient
	$('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));

	// Linked elements or callback
	if (typeof fb.callback == 'object') {
		// Set background/foreground color
		$(fb.callback).css({
			backgroundColor: fb.color,
			color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
		});

		// Change linked value
		$(fb.callback).each(function() {
			if (this.value && this.value != fb.color) {
			this.value = fb.color;
			}
		});
	}
	else if (typeof fb.callback == 'function') {
		fb.callback.call(fb, fb.color);
	}
	};

	/**
	* Get absolute position of element
	*/
	fb.absolutePosition = function (el) {
	var r = { x: el.offsetLeft, y: el.offsetTop };
	// Resolve relative to offsetParent
	if (el.offsetParent) {
		var tmp = fb.absolutePosition(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
	};

	/* Various color utility functions */
	fb.pack = function (rgb) {
	var r = Math.round(rgb[0] * 255);
	var g = Math.round(rgb[1] * 255);
	var b = Math.round(rgb[2] * 255);
	return '#' + (r < 16 ? '0' : '') + r.toString(16) +
				(g < 16 ? '0' : '') + g.toString(16) +
				(b < 16 ? '0' : '') + b.toString(16);
	};

	fb.unpack = function (color) {
	if (color.length == 7) {
		return [parseInt('0x' + color.substring(1, 3)) / 255,
			parseInt('0x' + color.substring(3, 5)) / 255,
			parseInt('0x' + color.substring(5, 7)) / 255];
	}
	else if (color.length == 4) {
		return [parseInt('0x' + color.substring(1, 2)) / 15,
			parseInt('0x' + color.substring(2, 3)) / 15,
			parseInt('0x' + color.substring(3, 4)) / 15];
	}
	};

	fb.HSLToRGB = function (hsl) {
	var m1, m2, r, g, b;
	var h = hsl[0], s = hsl[1], l = hsl[2];
	m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
	m1 = l * 2 - m2;
	return [this.hueToRGB(m1, m2, h+0.33333),
			this.hueToRGB(m1, m2, h),
			this.hueToRGB(m1, m2, h-0.33333)];
	};

	fb.hueToRGB = function (m1, m2, h) {
	h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
	if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
	if (h * 2 < 1) return m2;
	if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
	return m1;
	};

	fb.RGBToHSL = function (rgb) {
	var min, max, delta, h, s, l;
	var r = rgb[0], g = rgb[1], b = rgb[2];
	min = Math.min(r, Math.min(g, b));
	max = Math.max(r, Math.max(g, b));
	delta = max - min;
	l = (min + max) / 2;
	s = 0;
	if (l > 0 && l < 1) {
		s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
	}
	h = 0;
	if (delta > 0) {
		if (max == r && max != g) h += (g - b) / delta;
		if (max == g && max != b) h += (2 + (b - r) / delta);
		if (max == b && max != r) h += (4 + (r - g) / delta);
		h /= 6;
	}
	return [h, s, l];
	};

	// Install mousedown handler (the others are set on the document on-demand)
	$('*', e).mousedown(fb.mousedown);

	// Init color
	fb.setColor('#000000');

	// Set linked elements/callback
	if (callback) {
	fb.linkTo(callback);
	}
};
/*
 * jQuery Form Plugin
 * version: 2.24 (10-MAR-2009)
 * @requires jQuery v1.2.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *	http://www.opensource.org/licenses/mit-license.php
 *	http://www.gnu.org/licenses/gpl.html
 */
;(function($) {

/*
	Usage Note:
	-----------
	Do not use both ajaxSubmit and ajaxForm on the same form.	These
	functions are intended to be exclusive.	Use ajaxSubmit if you want
	to bind your own submit handler to the form.	For example,

	$(document).ready(function() {
			$('#myForm').bind('submit', function() {
				$(this).ajaxSubmit({
					target: '#output'
				});
				return false; // <-- important!
			});
	});

	Use ajaxForm when you want the plugin to manage all the event binding
	for you.	For example,

	$(document).ready(function() {
			$('#myForm').ajaxForm({
				target: '#output'
			});
	});

	When using ajaxForm, the ajaxSubmit function will be invoked for you
	at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
	// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
	if (!this.length) {
			log('ajaxSubmit: skipping submit process - no element selected');
			return this;
	}

	if (typeof options == 'function')
			options = { success: options };

	// clean url (don't include hash vaue)
	var url = this.attr('action') || window.location.href;
	url = (url.match(/^([^#]+)/)||[])[1];
	url = url || '';

	options = $.extend({
			url:	url,
			type: this.attr('method') || 'GET'
	}, options || {});

	// hook for manipulating the form data before it is extracted;
	// convenient for use with rich editors like tinyMCE or FCKEditor
	var veto = {};
	this.trigger('form-pre-serialize', [this, options, veto]);
	if (veto.veto) {
			log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
			return this;
	}

	// provide opportunity to alter form data before it is serialized
	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
			log('ajaxSubmit: submit aborted via beforeSerialize callback');
			return this;
	}

	var a = this.formToArray(options.semantic);
	if (options.data) {
			options.extraData = options.data;
			for (var n in options.data) {
			if(options.data[n] instanceof Array) {
				for (var k in options.data[n])
					a.push( { name: n, value: options.data[n][k] } );
			}
			else
				a.push( { name: n, value: options.data[n] } );
			}
	}

	// give pre-submit callback an opportunity to abort the submit
	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
			log('ajaxSubmit: submit aborted via beforeSubmit callback');
			return this;
	}

	// fire vetoable 'validate' event
	this.trigger('form-submit-validate', [a, this, options, veto]);
	if (veto.veto) {
			log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
			return this;
	}

	var q = $.param(a);

	if (options.type.toUpperCase() == 'GET') {
			options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
			options.data = null;	// data is null for 'get'
	}
	else
			options.data = q; // data is the query string for 'post'

	var $form = this, callbacks = [];
	if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
	if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

	// perform a load on the target only if dataType is not provided
	if (!options.dataType && options.target) {
			var oldSuccess = options.success || function(){};
			callbacks.push(function(data) {
				$(options.target).html(data).each(oldSuccess, arguments);
			});
	}
	else if (options.success)
			callbacks.push(options.success);

	options.success = function(data, status) {
			for (var i=0, max=callbacks.length; i < max; i++)
				callbacks[i].apply(options, [data, status, $form]);
	};

	// are there files to upload?
	var files = $('input:file', this).fieldValue();
	var found = false;
	for (var j=0; j < files.length; j++)
			if (files[j])
				found = true;

	// options.iframe allows user to force iframe mode
	if (options.iframe || found) {
		// hack to fix Safari hang (thanks to Tim Molendijk for this)
		// see:	http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
		if (options.closeKeepAlive)
				$.get(options.closeKeepAlive, fileUpload);
		else
				fileUpload();
		}
	else
		$.ajax(options);

	// fire 'notify' event
	this.trigger('form-submit-notify', [this, options]);
	return this;


	// private function for handling file uploads (hat tip to YAHOO!)
	function fileUpload() {
			var form = $form[0];

			if ($(':input[name=submit]', form).length) {
				alert('Error: Form elements must not be named "submit".');
				return;
			}

			var opts = $.extend({}, $.ajaxSettings, options);
		var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

			var id = 'jqFormIO' + (new Date().getTime());
			var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
			var io = $io[0];

			$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

			var xhr = { // mock object
				aborted: 0,
				responseText: null,
				responseXML: null,
				status: 0,
				statusText: 'n/a',
				getAllResponseHeaders: function() {},
				getResponseHeader: function() {},
				setRequestHeader: function() {},
				abort: function() {
					this.aborted = 1;
					$io.attr('src','about:blank'); // abort op in progress
				}
			};

			var g = opts.global;
			// trigger ajax global events so that activity/block indicators work like normal
			if (g && ! $.active++) $.event.trigger("ajaxStart");
			if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && jQuery.active--;
			return;
			}
			if (xhr.aborted)
				return;

			var cbInvoked = 0;
			var timedOut = 0;

			// add submitting element to data if we know it
			var sub = form.clk;
			if (sub) {
				var n = sub.name;
				if (n && !sub.disabled) {
					options.extraData = options.extraData || {};
					options.extraData[n] = sub.value;
					if (sub.type == "image") {
							options.extraData[name+'.x'] = form.clk_x;
							options.extraData[name+'.y'] = form.clk_y;
					}
				}
			}

			// take a breath so that pending repaints get some cpu time before the upload starts
			setTimeout(function() {
				// make sure form attrs are set
				var t = $form.attr('target'), a = $form.attr('action');

			// update form attrs in IE friendly way
			form.setAttribute('target',id);
			if (form.getAttribute('method') != 'POST')
				form.setAttribute('method', 'POST');
			if (form.getAttribute('action') != opts.url)
				form.setAttribute('action', opts.url);

				// ie borks in some cases when setting encoding
				if (! options.skipEncodingOverride) {
					$form.attr({
							encoding: 'multipart/form-data',
							enctype:	'multipart/form-data'
					});
				}

				// support timout
				if (opts.timeout)
					setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

				// add "extra" data to form if provided in options
				var extraInputs = [];
				try {
					if (options.extraData)
							for (var n in options.extraData)
								extraInputs.push(
									$('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
											.appendTo(form)[0]);

					// add iframe to doc and submit the form
					$io.appendTo('body');
					io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
					form.submit();
				}
				finally {
					// reset attrs and remove "extra" input elements
				form.setAttribute('action',a);
					t ? form.setAttribute('target', t) : $form.removeAttr('target');
					$(extraInputs).remove();
				}
			}, 10);

			var nullCheckFlag = 0;

			function cb() {
				if (cbInvoked++) return;

				io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

				var ok = true;
				try {
					if (timedOut) throw 'timeout';
					// extract the server response from the iframe
					var data, doc;

					doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;

					if ((doc.body == null || doc.body.innerHTML == '') && !nullCheckFlag) {
							// in some browsers (cough, Opera 9.2.x) the iframe DOM is not always traversable when
							// the onload callback fires, so we give them a 2nd chance
							nullCheckFlag = 1;
							cbInvoked--;
							setTimeout(cb, 100);
							return;
					}

					xhr.responseText = doc.body ? doc.body.innerHTML : null;
					xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
					xhr.getResponseHeader = function(header){
							var headers = {'content-type': opts.dataType};
							return headers[header];
					};

					if (opts.dataType == 'json' || opts.dataType == 'script') {
							var ta = doc.getElementsByTagName('textarea')[0];
							xhr.responseText = ta ? ta.value : xhr.responseText;
					}
					else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
							xhr.responseXML = toXml(xhr.responseText);
					}
					data = $.httpData(xhr, opts.dataType);
				}
				catch(e){
					ok = false;
					$.handleError(opts, xhr, 'error', e);
				}

				// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
				if (ok) {
					opts.success(data, 'success');
					if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
				}
				if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
				if (g && ! --$.active) $.event.trigger("ajaxStop");
				if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

				// clean up
				setTimeout(function() {
					$io.remove();
					xhr.responseXML = null;
				}, 100);
			};

			function toXml(s, doc) {
				if (window.ActiveXObject) {
					doc = new ActiveXObject('Microsoft.XMLDOM');
					doc.async = 'false';
					doc.loadXML(s);
				}
				else
					doc = (new DOMParser()).parseFromString(s, 'text/xml');
				return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
			};
	};
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *	is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *	used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.	ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
	return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
			$(this).ajaxSubmit(options);
			return false;
	}).each(function() {
			// store options in hash
			$(":submit,input:image", this).bind('click.form-plugin',function(e) {
				var form = this.form;
				form.clk = this;
				if (this.type == 'image') {
					if (e.offsetX != undefined) {
							form.clk_x = e.offsetX;
							form.clk_y = e.offsetY;
					} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
							var offset = $(this).offset();
							form.clk_x = e.pageX - offset.left;
							form.clk_y = e.pageY - offset.top;
					} else {
							form.clk_x = e.pageX - this.offsetLeft;
							form.clk_y = e.pageY - this.offsetTop;
					}
				}
				// clear form vars
				setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
			});
	});
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
	this.unbind('submit.form-plugin');
	return this.each(function() {
			$(":submit,input:image", this).unbind('click.form-plugin');
	});

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.	An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
	var a = [];
	if (this.length == 0) return a;

	var form = this[0];
	var els = semantic ? form.getElementsByTagName('*') : form.elements;
	if (!els) return a;
	for(var i=0, max=els.length; i < max; i++) {
			var el = els[i];
			var n = el.name;
			if (!n) continue;

			if (semantic && form.clk && el.type == "image") {
				// handle image inputs on the fly when semantic == true
				if(!el.disabled && form.clk == el)
					a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
				continue;
			}

			var v = $.fieldValue(el, true);
			if (v && v.constructor == Array) {
				for(var j=0, jmax=v.length; j < jmax; j++)
					a.push({name: n, value: v[j]});
			}
			else if (v !== null && typeof v != 'undefined')
				a.push({name: n, value: v});
	}

	if (!semantic && form.clk) {
			// input type=='image' are not found in elements array! handle them here
			var inputs = form.getElementsByTagName("input");
			for(var i=0, max=inputs.length; i < max; i++) {
				var input = inputs[i];
				var n = input.name;
				if(n && !input.disabled && input.type == "image" && form.clk == input)
					a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
			}
	}
	return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
	//hand off to jQuery.param for proper encoding
	return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
	var a = [];
	this.each(function() {
			var n = this.name;
			if (!n) return;
			var v = $.fieldValue(this, successful);
			if (v && v.constructor == Array) {
				for (var i=0,max=v.length; i < max; i++)
					a.push({name: n, value: v[i]});
			}
			else if (v !== null && typeof v != 'undefined')
				a.push({name: this.name, value: v});
	});
	//hand off to jQuery.param for proper encoding
	return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.	For example, consider the following form:
 *
 *	<form><fieldset>
 *		<input name="A" type="text" />
 *		<input name="A" type="text" />
 *		<input name="B" type="checkbox" value="B1" />
 *		<input name="B" type="checkbox" value="B2"/>
 *		<input name="C" type="radio" value="C1" />
 *		<input name="C" type="radio" value="C2" />
 *	</fieldset></form>
 *
 *	var v = $(':text').fieldValue();
 *	// if no values are entered into the text inputs
 *	v == ['','']
 *	// if values entered into the text inputs are 'foo' and 'bar'
 *	v == ['foo','bar']
 *
 *	var v = $(':checkbox').fieldValue();
 *	// if neither checkbox is checked
 *	v === undefined
 *	// if both checkboxes are checked
 *	v == ['B1', 'B2']
 *
 *	var v = $(':radio').fieldValue();
 *	// if neither radio is checked
 *	v === undefined
 *	// if first radio is checked
 *	v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.	If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.	If no valid value can be determined the
 *		array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
	for (var val=[], i=0, max=this.length; i < max; i++) {
			var el = this[i];
			var v = $.fieldValue(el, successful);
			if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
				continue;
			v.constructor == Array ? $.merge(val, v) : val.push(v);
	}
	return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
	if (typeof successful == 'undefined') successful = true;

	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
			(t == 'checkbox' || t == 'radio') && !el.checked ||
			(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
			tag == 'select' && el.selectedIndex == -1))
				return null;

	if (tag == 'select') {
			var index = el.selectedIndex;
			if (index < 0) return null;
			var a = [], ops = el.options;
			var one = (t == 'select-one');
			var max = (one ? index+1 : ops.length);
			for(var i=(one ? index : 0); i < max; i++) {
				var op = ops[i];
				if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
						v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
					if (one) return v;
					a.push(v);
				}
			}
			return a;
	}
	return el.value;
};

/**
 * Clears the form data.	Takes the following actions on the form's input fields:
 *	- input text fields will have their 'value' property set to the empty string
 *	- select elements will have their 'selectedIndex' property set to -1
 *	- checkbox and radio inputs will have their 'checked' property set to false
 *	- inputs of type submit, button, reset, and hidden will *not* be effected
 *	- button elements will *not* be effected
 */
$.fn.clearForm = function() {
	return this.each(function() {
			$('input,select,textarea', this).clearFields();
	});
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
	return this.each(function() {
			var t = this.type, tag = this.tagName.toLowerCase();
			if (t == 'text' || t == 'password' || tag == 'textarea')
				this.value = '';
			else if (t == 'checkbox' || t == 'radio')
				this.checked = false;
			else if (tag == 'select')
				this.selectedIndex = -1;
	});
};

/**
 * Resets the form data.	Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
	return this.each(function() {
			// guard against an input with the name of 'reset'
			// note that IE reports the reset function as an 'object'
			if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
				this.reset();
	});
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
	if (b == undefined) b = true;
	return this.each(function() {
			this.disabled = !b;
	});
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
	if (select == undefined) select = true;
	return this.each(function() {
			var t = this.type;
			if (t == 'checkbox' || t == 'radio')
				this.checked = select;
			else if (this.tagName.toLowerCase() == 'option') {
				var $sel = $(this).parent('select');
				if (select && $sel[0] && $sel[0].type == 'select-one') {
					// deselect all other options
					$sel.find('option').selected(false);
				}
				this.selected = select;
			}
	});
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
	if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
			window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);

/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
*
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
*
* hoverIntent is currently available for use in all personal or commercial
* projects under both MIT and GPL licenses. This means that you can choose
* the license that best suits your project, and use it accordingly.
*
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
*
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*	sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
*	interval: 100,	// number = milliseconds of polling interval
*	over: showNav,	// function = onMouseOver callback (required)
*	timeout: 0,	// number = milliseconds delay before onMouseOut function call
*	out: hideNav	// function = onMouseOut callback (required)
* });
*
* @param	f	onMouseOver function || An object with configuration options
* @param	g	onMouseOut function	|| Nothing (use configuration options object)
* @author	Brian Cherne <brian@cherne.net>
*/
(function($) {
	$.fn.hoverIntent = function(f,g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? { over: f, out: g } : f );

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).unbind("mousemove",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

			// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	};
})(jQuery);
/*
 ### jQuery Star Rating Plugin v1.1 - 2008-02-21 ###
 By Diego A., http://www.fyneworks.com, diego@fyneworks.com

 Project: http://plugins.jquery.com/project/MultipleFriendlyStarRating
 Website: http://www.fyneworks.com/jquery/star-rating/

	This is a modified version of the star rating plugin from:
 http://www.phpletter.com/Demo/Jquery-Star-Rating-Plugin/
*/
// ORIGINAL COMMENTS:
/*************************************************
 This is hacked version of star rating created by <a href="http://php.scripts.psu.edu/rja171/widgets/rating.php">Ritesh Agrawal</a>
 It thansform a set of radio type input elements to star rating type and remain the radio element name and value,
 so could be integrated with your form. It acts as a normal radio button.
 modified by : Logan Cai (cailongqun[at]yahoo.com.cn)
 website:www.phpletter.com
************************************************/


/*# AVOID COLLISIONS #*/
;if(jQuery) (function($){
/*# AVOID COLLISIONS #*/

$.fn.rating = function(settings) {
	settings = jQuery.extend({},	settings || {});

	// multiple star ratings on one page
	var ratingwords = settings.ratingwords;
	var groups = {};

	var prevElem = null;
	var valueElem = null;
	var CancelElem = null;

	var event = {
		fill: function(n, el, style){ // fill to the current mouse position.
			var stars = $(groups[n].valueElem).siblings('.star');
			var index = stars.index(el) + 1;
			$(stars)
				.children('a').css('width', '100%').end()
				.removeClass('star_hover').removeClass('star_on')
				.slice(0,index).addClass( style || 'star_hover' ).end();
		},
		drain: function(n) { // drain all the stars.
			var stars = $(groups[n].valueElem).siblings('.star');
			$(stars)
				.filter('.star_on').removeClass('star_on').end()
				.filter('.star_hover').removeClass('star_hover').end();
		},
		reset: function(n){ // Reset the stars to the default index.
			var stars = $(groups[n].valueElem).siblings('.star');
			$(stars).slice(0,groups[n].currentValue).addClass('star_on').end();
		}
	};

	this.each(function (i) {
		var n = this.name;
		if(!groups[n]) groups[n] = {count:0, currentValue: 0};
		groups[n].count += 1;
		i = groups[n].count - 1;

		if(i == 0) {
			groups[n].valueElem = $('<input type="hidden" name="' + this.name + '" value="" >');
			$(this).before(groups[n].valueElem);

			var CancelElem = $('<div></div>');
			prevElem = CancelElem;
			$(this).before(prevElem);

		};

		//insert rating option right after preview element

		preElemTemp	= $('<div class="star"><a href="javascript:;" title="' + ratingwords[this.value] + '">' + this.value + '</a></div>');
		$(prevElem).after(preElemTemp);
		$(preElemTemp)
		.mouseover(function(){
			event.drain(n);
			event.fill(n, this);
				$(settings.rating_word).html($(this).children('a').attr('title'));

		})
		.mouseout(function(){
			event.drain(n);
			event.reset(n);
				$(settings.rating_word).html('');
		})
		.click(function(){
			groups[n].currentValue = $(this).children('a').html();
			$(groups[n].valueElem).val(groups[n].currentValue);
			event.drain(n);

			// post
			if(settings.rating_url){
				$.getJSON(settings.rating_url,
					{ form_rating : groups[n].currentValue, nbr: $('#hidden_nbr').val()},
					function(data){
						afterRating(data);
					});
			}

			//event.reset();
			event.fill(n, this);
		});

		if(this.checked) groups[n].initial = preElemTemp;

		prevElem = preElemTemp;
		preElemTemp = null;

		//remove this checkbox
		$(this).remove();
		if(i + 1 == this.length) event.reset(n);
	} );

	// initialize groups...
	for(n in groups){
		if(groups[n].initial){
			$(groups[n].initial).each(function(){
				event.fill(n, this, 'star_on');
				groups[n].currentValue = $(this).children('a').html();
				$(groups[n].valueElem).val(groups[n].currentValue);
			});
		}
	};

	return this;

	// view the image after del or set
	function afterRating(data){

		$('.form-msg').hide();
		if(data.status=='success'){
			ratingpercent = data.rating * 20;
			ret = '<span><span style="width:;width:'+ratingpercent+'%;" title="'+settings.ratingwords[data.rating]+'"></span></span>';
			$('span#rating_stars').html(ret).show();
			$('span#login_to_rate').hide();
			$('span#thanks_rating').show();
			$(settings.rating_result).show();
			$(settings.rating_input).hide();
		}
		else{
			$(settings.rating_result).html(data.message).show();
		}
	}

};


})(jQuery);
/*
 * Tabs 3 - New Wave Tabs
 *
 * Copyright (c) 2007 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Tabs
 */

(function($) {

	// if the UI scope is not availalable, add it
	$.ui = $.ui || {};

	// tabs API methods
	$.fn.tabs = function() {
		var method = typeof arguments[0] == 'string' && arguments[0];
		var args = method && Array.prototype.slice.call(arguments, 1) || arguments;

		return this.each(function() {
			if (method) {
				var tabs = $.data(this, 'ui-tabs');
				tabs[method].apply(tabs, args);
			} else
				new $.ui.tabs(this, args[0] || {});
		});
	};

	// tabs class
	$.ui.tabs = function(el, options) {
		var self = this;

		this.element = el;

		this.options = $.extend({

			// basic setup
			selected: 0,
			unselect: options.selected === null,
			event: 'click',
			disabled: [],
			cookie: null, // pass options object as expected by cookie plugin: { expires: 7, path: '/', domain: 'jquery.com', secure: true }
			// TODO bookmarkable: $.ajaxHistory ? true : false,

			// Ajax
			spinner: 'Loading&#8230;',
			cache: false,
			idPrefix: 'ui-tabs-',
			ajaxOptions: {},

			// animations
			fx: null, /* e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } */

			// templates
			tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>',
			panelTemplate: '<div></div>',

			// CSS classes
			navClass: 'ui-tabs-nav',
			selectedClass: 'ui-tabs-selected',
			unselectClass: 'ui-tabs-unselect',
			disabledClass: 'ui-tabs-disabled',
			panelClass: 'ui-tabs-panel',
			hideClass: 'ui-tabs-hide',
			loadingClass: 'ui-tabs-loading'

		}, options);

		this.options.event += '.ui-tabs'; // namespace event
		this.options.cookie = $.cookie && $.cookie.constructor == Function && this.options.cookie;

		$(el).bind('setData.ui-tabs', function(event, key, value) {
			self.options[key] = value;
			this.tabify();
		}).bind('getData.ui-tabs', function(event, key) {
			return self.options[key];
		});

		// save instance for later
		$.data(el, 'ui-tabs', this);

		// create tabs
		this.tabify(true);
	};

	// instance methods
	$.extend($.ui.tabs.prototype, {
		tabId: function(a) {
			return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
				|| this.options.idPrefix + $.data(a);
		},
		ui: function(tab, panel) {
			return {
				instance: this,
				options: this.options,
				tab: tab,
				panel: panel
			};
		},
		tabify: function(init) {

			this.$lis = $('li:has(a[href])', this.element);
			this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
			this.$panels = $([]);

			var self = this, o = this.options;

			this.$tabs.each(function(i, a) {
				// inline tab
				if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
					self.$panels = self.$panels.add(a.hash);
				// remote tab
				else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
					$.data(a, 'href.ui-tabs', a.href); // required for restore on destroy
					$.data(a, 'load.ui-tabs', a.href); // mutable
					var id = self.tabId(a);
					a.href = '#' + id;
					var $panel = $('#' + id);
					if (!$panel.length) {
						$panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
							.insertAfter( self.$panels[i - 1] || self.element );
						$panel.data('destroy.ui-tabs', true);
					}
					self.$panels = self.$panels.add( $panel );
				}
				// invalid tab href
				else
					o.disabled.push(i + 1);
			});

			if (init) {

				// attach necessary classes for styling if not present
				$(this.element).hasClass(o.navClass) || $(this.element).addClass(o.navClass);
				this.$panels.each(function() {
					var $this = $(this);
					$this.hasClass(o.panelClass) || $this.addClass(o.panelClass);
				});

				// disabled tabs
				for (var i = 0, index; index = o.disabled[i]; i++)
					this.disable(index);

				// Try to retrieve selected tab:
				// 1. from fragment identifier in url if present
				// 2. from cookie
				// 3. from selected class attribute on <li>
				// 4. otherwise use given "selected" option
				// 5. check if tab is disabled
				this.$tabs.each(function(i, a) {
					if (location.hash) {
						if (a.hash == location.hash) {
							o.selected = i;
							// prevent page scroll to fragment
							//if (($.browser.msie || $.browser.opera) && !o.remote) {
							if ($.browser.msie || $.browser.opera) {
								var $toShow = $(location.hash), toShowId = $toShow.attr('id');
								$toShow.attr('id', '');
								setTimeout(function() {
									$toShow.attr('id', toShowId); // restore id
								}, 500);
							}
							scrollTo(0, 0);
							return false; // break
						}
					} else if (o.cookie) {
						var index = parseInt($.cookie('ui-tabs' + $.data(self.element)),10);
						if (index && self.$tabs[index]) {
							o.selected = index;
							return false; // break
						}
					} else if ( self.$lis.eq(i).hasClass(o.selectedClass) ) {
						o.selected = i;
						return false; // break
					}
				});
				var n = this.$lis.length;
				while (this.$lis.eq(o.selected).hasClass(o.disabledClass) && n) {
					o.selected = ++o.selected < this.$lis.length ? o.selected : 0;
					n--;
				}
				if (!n) // all tabs disabled, set option unselect to true
					o.unselect = true;

				// highlight selected tab
				this.$panels.addClass(o.hideClass);
				this.$lis.removeClass(o.selectedClass);
				if (!o.unselect) {
					this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
					this.$lis.eq(o.selected).addClass(o.selectedClass);
				}

				// load if remote tab
				var href = !o.unselect && $.data(this.$tabs[o.selected], 'load.ui-tabs');
				if (href)
					this.load(o.selected, href);

				// disable click if event is configured to something else
				if (!(/^click/).test(o.event))
					this.$tabs.bind('click', function(e) { e.preventDefault(); });

			}

			var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
			if (o.fx && o.fx.constructor == Array)
				hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
			else
				hideFx = showFx = o.fx || baseFx;

			// reset some styles to maintain print style sheets etc.
			var resetCSS = { display: '', overflow: '', height: '' };
			if (!$.browser.msie) // not in IE to prevent ClearType font issue
				resetCSS.opacity = '';

			// Hide a tab, animation prevents browser scrolling to fragment,
			// $show is optional.
			function hideTab(clicked, $hide, $show) {
				$hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
					$hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
					if ($.browser.msie && hideFx.opacity)
						$hide[0].style.filter = '';
					if ($show)
						showTab(clicked, $show, $hide);
				});
			}

			// Show a tab, animation prevents browser scrolling to fragment,
			// $hide is optional.
			function showTab(clicked, $show, $hide) {
				if (showFx === baseFx)
					$show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
				$show.animate(showFx, showFx.duration || baseDuration, function() {
					$show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
					if ($.browser.msie && showFx.opacity)
						$show[0].style.filter = '';

					// callback
					$(self.element).triggerHandler("show.ui-tabs", [self.ui(clicked, $show[0])]);

				});
			}

			// switch a tab
			function switchTab(clicked, $li, $hide, $show) {
				/*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
					$.ajaxHistory.update(clicked.hash);
				}*/
				$li.addClass(o.selectedClass)
					.siblings().removeClass(o.selectedClass);
				hideTab(clicked, $hide, $show);
			}

			// attach tab event handler, unbind to avoid duplicates from former tabifying...
			this.$tabs.unbind(o.event).bind(o.event, function() {

				//var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
				var $li = $(this).parents('li:eq(0)'),
					$hide = self.$panels.filter(':visible'),
					$show = $(this.hash);

				// If tab is already selected and not unselectable or tab disabled or click callback returns false stop here.
				// Check if click handler returns false last so that it is not executed for a disabled tab!
				if (($li.hasClass(o.selectedClass) && !o.unselect) || $li.hasClass(o.disabledClass)
					|| $(self.element).triggerHandler("select.ui-tabs", [self.ui(this, $show[0])]) === false) {
					this.blur();
					return false;
				}

				self.options.selected = self.$tabs.index(this);

				// if tab may be closed
				if (o.unselect) {
					if ($li.hasClass(o.selectedClass)) {
						self.options.selected = null;
						$li.removeClass(o.selectedClass);
						self.$panels.stop();
						hideTab(this, $hide);
						this.blur();
						return false;
					} else if (!$hide.length) {
						self.$panels.stop();
						var a = this;
						self.load(self.$tabs.index(this), function() {
							$li.addClass(o.selectedClass).addClass(o.unselectClass);
							showTab(a, $show);
						});
						this.blur();
						return false;
					}
				}

				if (o.cookie)
					$.cookie('ui-tabs' + $.data(self.element), self.options.selected, o.cookie);

				// stop possibly running animations
				self.$panels.stop();

				// show new tab
				if ($show.length) {

					// prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
					/*if ($.browser.msie && o.bookmarkable) {
						var showId = this.hash.replace('#', '');
						$show.attr('id', '');
						setTimeout(function() {
							$show.attr('id', showId); // restore id
						}, 0);
					}*/

					var a = this;
					self.load(self.$tabs.index(this), function() {
						switchTab(a, $li, $hide, $show);
					});

					// Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
					/*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
					var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
					setTimeout(function() {
						scrollTo(scrollX, scrollY);
					}, 0);*/

				} else
					throw 'jQuery UI Tabs: Mismatching fragment identifier.';

				// Prevent IE from keeping other link focussed when using the back button
				// and remove dotted border from clicked link. This is controlled in modern
				// browsers via CSS, also blur removes focus from address bar in Firefox
				// which can become a usability and annoying problem with tabsRotate.
				if ($.browser.msie)
					this.blur();

				//return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
				return false;

			});

		},
		add: function(url, label, index) {
			if (url && label) {
				index = index || this.$tabs.length; // append by default

				var o = this.options;
				var $li = $(o.tabTemplate.replace(/#\{href\}/, url).replace(/#\{label\}/, label));
				$li.data('destroy.ui-tabs', true);

				var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId( $('a:first-child', $li)[0] );

				// try to find an existing element before creating a new one
				var $panel = $('#' + id);
				if (!$panel.length) {
					$panel = $(o.panelTemplate).attr('id', id)
						.addClass(o.panelClass).addClass(o.hideClass);
					$panel.data('destroy.ui-tabs', true);
				}
				if (index >= this.$lis.length) {
					$li.appendTo(this.element);
					$panel.appendTo(this.element.parentNode);
				} else {
					$li.insertBefore(this.$lis[index]);
					$panel.insertBefore(this.$panels[index]);
				}

				this.tabify();

				if (this.$tabs.length == 1) {
					$li.addClass(o.selectedClass);
					$panel.removeClass(o.hideClass);
					var href = $.data(this.$tabs[0], 'load.ui-tabs');
					if (href)
						this.load(index, href);
				}

				// callback
				$(this.element).triggerHandler("add.ui-tabs",
					[this.ui(this.$tabs[index], this.$panels[index])]
				);

			} else
				throw 'jQuery UI Tabs: Not enough arguments to add tab.';
		},
		remove: function(index) {
			if (index && index.constructor == Number) {
				var o = this.options, $li = this.$lis.eq(index).remove(),
					$panel = this.$panels.eq(index).remove();

				// If selected tab was removed focus tab to the right or
				// tab to the left if last tab was removed.
				if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
					this.click(index + (index < this.$tabs.length ? 1 : -1));
				this.tabify();

				// callback
				$(this.element).triggerHandler("remove.ui-tabs",
					[this.ui($li.find('a')[0], $panel[0])]
				);

			}
		},
		enable: function(index) {
			var self = this, o = this.options, $li = this.$lis.eq(index);
			$li.removeClass(o.disabledClass);
			if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
				$li.css('display', 'inline-block');
				setTimeout(function() {
					$li.css('display', 'block');
				}, 0);
			}

			o.disabled = $.map(this.$lis.filter('.' + o.disabledClass),
				function(n, i) { return self.$lis.index(n); } );

			// callback
			$(this.element).triggerHandler("enable.ui-tabs",
				[this.ui(this.$tabs[index], this.$panels[index])]
			);

		},
		disable: function(index) {
			var self = this, o = this.options;
			this.$lis.eq(index).addClass(o.disabledClass);

			o.disabled = $.map(this.$lis.filter('.' + o.disabledClass),
				function(n, i) { return self.$lis.index(n); } );

			// callback
			$(this.element).triggerHandler("disable.ui-tabs",
				[this.ui(this.$tabs[index], this.$panels[index])]
			);

		},
		select: function(index) {
			if (typeof index == 'string')
				index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] );
			this.$tabs.eq(index).trigger(this.options.event);
		},
		load: function(index, callback) { // callback is for internal usage only
			var self = this, o = this.options,
				$a = this.$tabs.eq(index), a = $a[0];

			var url = $a.data('load.ui-tabs');

			// no remote - just finish with callback
			if (!url) {
				typeof callback == 'function' && callback();
				return;
			}

			// load remote from here on
			if (o.spinner) {
				var $span = $('span', a), label = $span.html();
				$span.html('<em>' + o.spinner + '</em>');
			}
			var finish = function() {
				self.$tabs.filter('.' + o.loadingClass).each(function() {
					$(this).removeClass(o.loadingClass);
					if (o.spinner)
						$('span', this).html(label);
				});
				self.xhr = null;
			};
			var ajaxOptions = $.extend({}, o.ajaxOptions, {
				url: url,
				success: function(r, s) {
					$(a.hash).html(r);
					finish();
					// This callback is required because the switch has to take
					// place after loading has completed.
					typeof callback == 'function' && callback();

					if (o.cache)
						$.removeData(a, 'load.ui-tabs'); // if loaded once do not load them again

					// callback
					$(self.element).triggerHandler("load.ui-tabs",
						[self.ui(self.$tabs[index], self.$panels[index])]
					);

					o.ajaxOptions.success && o.ajaxOptions.success(r, s);
				}
			});
			if (this.xhr) {
				// terminate pending requests from other tabs and restore tab label
				this.xhr.abort();
				finish();
			}
			$a.addClass(o.loadingClass);
			setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
				self.xhr = $.ajax(ajaxOptions);
			}, 0);

		},
		url: function(index, url) {
			this.$tabs.eq(index).data('load.ui-tabs', url);
		},
		destroy: function() {
			var o = this.options;
			$(this.element).unbind('.ui-tabs')
				.removeClass(o.navClass).removeData('ui-tabs');
			this.$tabs.each(function() {
				var href = $.data(this, 'href.ui-tabs');
				if (href)
					this.href = href;
				$(this).unbind('.ui-tabs')
					.removeData('href.ui-tabs').removeData('load.ui-tabs');
			});
			this.$lis.add(this.$panels).each(function() {
				if ($.data(this, 'destroy.ui-tabs'))
					$(this).remove();
				else
					$(this).removeClass([o.selectedClass, o.unselectClass,
						o.disabledClass, o.panelClass, o.hideClass].join(' '));
			});
		}
	});

})(jQuery);
/*
 * Thickbox 3.1 - One Box To Rule Them All.
 * By Cody Lindley (http://www.codylindley.com)
 * Copyright (c) 2007 cody lindley
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/
/*
 * 1) loading image
 * 2) add "class='TB_Close'" for the close button
 * 3) <div id="TB_close_advance" smart="false" /> // no smart close
 */


var tb_pathToImage = "images/loading.gif";

/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/

//on page load call tb_init
$(document).ready(function(){
	tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
	imgLoader = new Image();// preload image
	imgLoader.src = tb_pathToImage;
});

//add thickbox to href & area elements that have a class of .thickbox
function tb_init(domChunk){
	$(domChunk).click(function(){
	var t = this.title || this.name || null;
	var a = this.href || this.alt;
	var g = this.rel || false;
	tb_show(t,a,g);
	this.blur();
	return false;
	});
}

function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link
	var close_smart = ( $('#TB_close_advance').attr('smart') == 'false' ? false: true);

	try {
		if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
			$("body","html").css({height: "100%", width: "100%"});
			$("html").css("overflow","hidden");
			if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
				$("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
				if(close_smart) $("#TB_overlay").click(tb_remove);
			}
		}else{//all others
			if(document.getElementById("TB_overlay") === null){
				$("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");
				if(close_smart) $("#TB_overlay").click(tb_remove);
			}
		}

		if(tb_detectMacXFF()){
			$("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
		}else{
			$("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
		}

		if(caption===null){caption="";}
		$("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page
		$('#TB_load').show();//show loader

		var baseURL;
		if(url.indexOf("?")!==-1){ //ff there is a query string involved
			baseURL = url.substr(0, url.indexOf("?"));
		}else{
				baseURL = url;
		}

		var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
		var urlType = baseURL.toLowerCase().match(urlString);

		if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images

			TB_PrevCaption = "";
			TB_PrevURL = "";
			TB_PrevHTML = "";
			TB_NextCaption = "";
			TB_NextURL = "";
			TB_NextHTML = "";
			TB_imageCount = "";
			TB_FoundURL = false;
			if(imageGroup){
				TB_TempArray = $("a[@rel="+imageGroup+"]").get();
				for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) {
					var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
						if (!(TB_TempArray[TB_Counter].href == url)) {
							if (TB_FoundURL) {
								TB_NextCaption = TB_TempArray[TB_Counter].title;
								TB_NextURL = TB_TempArray[TB_Counter].href;
								TB_NextHTML = "<span id='TB_next'>&nbsp;&nbsp;<a href='#'>Next &gt;</a></span>";
							} else {
								TB_PrevCaption = TB_TempArray[TB_Counter].title;
								TB_PrevURL = TB_TempArray[TB_Counter].href;
								TB_PrevHTML = "<span id='TB_prev'>&nbsp;&nbsp;<a href='#'>&lt; Prev</a></span>";
							}
						} else {
							TB_FoundURL = true;
							TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length);
						}
				}
			}

			imgPreloader = new Image();
			imgPreloader.onload = function(){
			imgPreloader.onload = null;

			// Resizing large images - orginal by Christian Montoya edited by me.
			var pagesize = tb_getPageSize();
			var x = pagesize[0] - 150;
			var y = pagesize[1] - 150;
			var imageWidth = imgPreloader.width;
			var imageHeight = imgPreloader.height;
			if (imageWidth > x) {
				imageHeight = imageHeight * (x / imageWidth);
				imageWidth = x;
				if (imageHeight > y) {
					imageWidth = imageWidth * (y / imageHeight);
					imageHeight = y;
				}
			} else if (imageHeight > y) {
				imageWidth = imageWidth * (y / imageHeight);
				imageHeight = y;
				if (imageWidth > x) {
					imageHeight = imageHeight * (x / imageWidth);
					imageWidth = x;
				}
			}
			// End Resizing

			TB_WIDTH = imageWidth + 30;
			TB_HEIGHT = imageHeight + 60;
			$("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' class='TB_Close' title='Close'><span>close</span></a></div>"); 

			$("#TB_closeWindowButton").click(tb_remove);

			if (!(TB_PrevHTML === "")) {
				function goPrev(){
					if($(document).unbind("click",goPrev)){$(document).unbind("click",goPrev);}
					$("#TB_window").remove();
					$("body").append("<div id='TB_window'></div>");
					tb_show(TB_PrevCaption, TB_PrevURL, imageGroup);
					return false;
				}
				$("#TB_prev").click(goPrev);
			}

			if (!(TB_NextHTML === "")) {
				function goNext(){
					$("#TB_window").remove();
					$("body").append("<div id='TB_window'></div>");
					tb_show(TB_NextCaption, TB_NextURL, imageGroup);
					return false;
				}
				$("#TB_next").click(goNext);

			}

			document.onkeydown = function(e){
				if (e == null) { // ie
					keycode = event.keyCode;
				} else { // mozilla
					keycode = e.which;
				}
				if(close_smart && keycode == 27){ // close
					tb_remove();
				} else if(keycode == 190){ // display previous image
					if(!(TB_NextHTML == "")){
						document.onkeydown = "";
						goNext();
					}
				} else if(keycode == 188){ // display next image
					if(!(TB_PrevHTML == "")){
						document.onkeydown = "";
						goPrev();
					}
				}
			};

			tb_position();
			$("#TB_load").remove();
			$("#TB_ImageOff").click(tb_remove);
			$("#TB_window").css({display:"block"}); //for safari using css instead of show
			};

			imgPreloader.src = url;
		}else{//code to show html

			var queryString = url.replace(/^[^\?]+\??/,'');
			var params = tb_parseQuery( queryString );

			TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
			TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
			ajaxContentW = TB_WIDTH - 30;
			ajaxContentH = TB_HEIGHT - 45;

			if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window
					urlNoQuery = url.split('TB_');
					$("#TB_iframeContent").remove();
					if(params['modal'] != "true"){//iframe no modal
						$("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close' class='TB_Close'><span>close</span></a></div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>");
					}else{//iframe modal
					$("#TB_overlay").unbind();
						$("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>");
					}
			}else{// not an iframe, ajax
					if($("#TB_window").css("display") != "block"){
						if(params['modal'] != "true"){//ajax no modal
						$("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' class='TB_Close'><span>close</span></a> </div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>");
						}else{//ajax modal
						$("#TB_overlay").unbind();
						$("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>");
						}
					}else{//this means the window is already up, we are just loading new content via ajax
						$("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
						$("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
						$("#TB_ajaxContent")[0].scrollTop = 0;
						$("#TB_ajaxWindowTitle").html(caption);
					}
			}

			$("#TB_closeWindowButton").click(tb_remove);

				if(url.indexOf('TB_inline') != -1){
					$("#TB_ajaxContent").append($('#' + params['inlineId']).children());
					$("#TB_window").unload(function () {
						$('#' + params['inlineId']).append( $("#TB_ajaxContent").children() ); // move elements back when you're finished
					});
					tb_position();
					$("#TB_load").remove();
					$("#TB_window").css({display:"block"});
				}else if(url.indexOf('TB_iframe') != -1){
					tb_position();
					if($.browser.safari){//safari needs help because it will not fire iframe onload
						$("#TB_load").remove();
						$("#TB_window").css({display:"block"});
					}
				}else{
					$("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method
						tb_position();
						$("#TB_load").remove();
						tb_init("#TB_ajaxContent a.thickbox");
						$("#TB_window").css({display:"block"});
					});
				}

		}

		if(!params['modal']){
			document.onkeyup = function(e){
				if (e == null) { // ie
					keycode = event.keyCode;
				} else { // mozilla
					keycode = e.which;
				}
				if(close_smart && keycode == 27){ // close
					tb_remove();
				}
			};
		}

	} catch(e) {
		//nothing here
	}
}

//helper functions below
function tb_showIframe(){
	$("#TB_load").remove();
	$("#TB_window").css({display:"block"});
}

function tb_remove() {
	var more_close_op = $('#TB_close_advance').attr('onbeforeclose');
	if($.trim(more_close_op) != ''){
		eval(more_close_op);
	}
 	$("#TB_imageOff").unbind("click");
	$("#TB_closeWindowButton").unbind("click");
	$("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();});
	$("#TB_load").remove();
	if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
		$("body","html").css({height: "auto", width: "auto"});
		$("html").css("overflow","");
	}
	document.onkeydown = "";
	document.onkeyup = "";
	return false;
}

function tb_position() {
	$("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
	pagesize = tb_getPageSize();
	h= Math.min(TB_HEIGHT , pagesize[1]);
	if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
		$("#TB_window").css({marginTop: '-' + parseInt((h / 2),10) + 'px'});
	}


}

function tb_parseQuery ( query ) {
	var Params = {};
	if ( ! query ) {return Params;}// return empty object
	var Pairs = query.split(/[;&]/);
	for ( var i = 0; i < Pairs.length; i++ ) {
		var KeyVal = Pairs[i].split('=');
		if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
		var key = unescape( KeyVal[0] );
		var val = unescape( KeyVal[1] );
		val = val.replace(/\+/g, ' ');
		Params[key] = val;
	}
	return Params;
}

function tb_getPageSize(){
	var de = document.documentElement;
	var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
	var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
	arrayPageSize = [w,h];
	return arrayPageSize;
}

function tb_detectMacXFF() {
	var userAgent = navigator.userAgent.toLowerCase();
	if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
	return true;
	}
}


/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *		used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *										If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *										If set to null or omitted, the cookie will be a session cookie and will not be retained
 *										when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *								require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
	if (typeof value != 'undefined') { // name and value given, set cookie
		options = options || {};
		if (value === null) {
			value = '';
			options.expires = -1;
		}
		var expires = '';
		if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
			var date;
			if (typeof options.expires == 'number') {
				date = new Date();
				date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
			} else {
				date = options.expires;
			}
			expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
		}
		// CAUTION: Needed to parenthesize options.path and options.domain
		// in the following expressions, otherwise they evaluate to undefined
		// in the packed version for some reason...
		var path = options.path ? '; path=' + (options.path) : '';
		var domain = options.domain ? '; domain=' + (options.domain) : '';
		var secure = options.secure ? '; secure' : '';
		document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
	} else { // only name given, get cookie
		var cookieValue = null;
		if (document.cookie && document.cookie != '') {
			var cookies = document.cookie.split(';');
			for (var i = 0; i < cookies.length; i++) {
				var cookie = jQuery.trim(cookies[i]);
				// Does this cookie string begin with the name we want?
				if (cookie.substring(0, name.length + 1) == (name + '=')) {
						cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
						break;
				}
			}
		}
		return cookieValue;
	}
};


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.extend({
	timer: {
		guid: 1,
		global: {},
		regex: /^([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 = parseInt(result[1], 10);
				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;

			if (!element.$timers)
				element.$timers = {};

			if (!element.$timers[label])
				element.$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 (!element.$timers[label][fn.$timerID])
				element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);

			if ( !this.global[label] )
				this.global[label] = [];
			this.global[label].push( element );

		},
		remove: function(element, label, fn) {
			var timers = element.$timers, 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 )
					element.$timers = null;
			}
		}
	}
});

if (jQuery.browser.msie)
	jQuery(window).one("unload", function() {
		var global = jQuery.timer.global;
		for ( var label in global ) {
			var els = global[label], i = els.length;
			while ( --i )
				jQuery.timer.remove(els[i], label);
		}
	});



/**
 * jQuery.ScrollTo
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 3/9/2009
 *
 * @projectDescription Easy element scrolling using jQuery.
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 * Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
 *
 * @author Ariel Flesler
 * @version 1.4.1
 *
 * @id jQuery.scrollTo
 * @id jQuery.fn.scrollTo
 * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
 *		The different options for target are:
 *		- A number position (will be applied to all axes).
 *		- A string position ('44', '100px', '+=90', etc ) will be applied to all axes
 *		- A jQuery/DOM element ( logically, child of the element to scroll )
 *		- A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
 *		- A hash { top:x, left:y }, x and y can be any kind of number/string like above.
 * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
 * @param {Object,Function} settings Optional set of settings or the onAfter callback.
 *	 @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
 *	 @option {Number} duration The OVERALL length of the animation.
 *	 @option {String} easing The easing method for the animation.
 *	 @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
 *	 @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
 *	 @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
 *	 @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
 *	 @option {Function} onAfter Function to be called after the scrolling ends. 
 *	 @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
 * @return {jQuery} Returns the same jQuery object, for chaining.
 *
 * @desc Scroll to a fixed position
 * @example $('div').scrollTo( 340 );
 *
 * @desc Scroll relatively to the actual position
 * @example $('div').scrollTo( '+=340px', { axis:'y' } );
 *
 * @dec Scroll using a selector (relative to the scrolled element)
 * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
 *
 * @ Scroll to a DOM element (same for jQuery object)
 * @example var second_child = document.getElementById('container').firstChild.nextSibling;
 *			$('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
 *				alert('scrolled!!');
 *			}});
 *
 * @desc Scroll on both axes, to different values
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
 */
;(function( $ ){

	var $scrollTo = $.scrollTo = function( target, duration, settings ){
		$(window).scrollTo( target, duration, settings );
	};

	$scrollTo.defaults = {
		axis:'xy',
		duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1
	};

	// Returns the element that needs to be animated to scroll the window.
	// Kept for backwards compatibility (specially for localScroll & serialScroll)
	$scrollTo.window = function( scope ){
		return $(window).scrollable();
	};

	// Hack, hack, hack... stay away!
	// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
	$.fn.scrollable = function(){
		return this.map(function(){
			var elem = this,
				isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;

				if( !isWin )
					return elem;

			var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;

			return $.browser.safari || doc.compatMode == 'BackCompat' ?
				doc.body : 
				doc.documentElement;
		});
	};

	$.fn.scrollTo = function( target, duration, settings ){
		if( typeof duration == 'object' ){
			settings = duration;
			duration = 0;
		}
		if( typeof settings == 'function' )
			settings = { onAfter:settings };

		if( target == 'max' )
			target = 9e9;

		settings = $.extend( {}, $scrollTo.defaults, settings );
		// Speed is still recognized for backwards compatibility
		duration = duration || settings.speed || settings.duration;
		// Make sure the settings are given right
		settings.queue = settings.queue && settings.axis.length > 1;

		if( settings.queue )
			// Let's keep the overall duration
			duration /= 2;
		settings.offset = both( settings.offset );
		settings.over = both( settings.over );

		return this.scrollable().each(function(){
			var elem = this,
				$elem = $(elem),
				targ = target, toff, attr = {},
				win = $elem.is('html,body');

			switch( typeof targ ){
				// A number will pass the regex
				case 'number':
				case 'string':
					if( /^([+-]=)?\d+(\.\d+)?(px)?$/.test(targ) ){
						targ = both( targ );
						// We are done
						break;
					}
					// Relative selector, no break!
					targ = $(targ,this);
				case 'object':
					// DOMElement / jQuery
					if( targ.is || targ.style )
						// Get the real position of the target 
						toff = (targ = $(targ)).offset();
			}
			$.each( settings.axis.split(''), function( i, axis ){
				var Pos	= axis == 'x' ? 'Left' : 'Top',
					pos = Pos.toLowerCase(),
					key = 'scroll' + Pos,
					old = elem[key],
					Dim = axis == 'x' ? 'Width' : 'Height';

				if( toff ){// jQuery / DOMElement
					attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );

					// If it's a dom element, reduce the margin
					if( settings.margin ){
						attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
						attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
					}

					attr[key] += settings.offset[pos] || 0;

					if( settings.over[pos] )
						// Scroll to a fraction of its width/height
						attr[key] += targ[Dim.toLowerCase()]() * settings.over[pos];
				}else
					attr[key] = targ[pos];

				// Number or 'number'
				if( /^\d+$/.test(attr[key]) )
					// Check the limits
					attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );

				// Queueing axes
				if( !i && settings.queue ){
					// Don't waste time animating, if there's no need.
					if( old != attr[key] )
						// Intermediate animation
						animate( settings.onAfterFirst );
					// Don't animate this axis again in the next iteration.
					delete attr[key];
				}
			});

			animate( settings.onAfter );

			function animate( callback ){
				$elem.animate( attr, duration, settings.easing, callback && function(){
					callback.call(this, target, settings);
				});
			};

			// Max scrolling position, works on quirks mode
			// It only fails (not too badly) on IE, quirks mode.
			function max( Dim ){
				var scroll = 'scroll'+Dim;

				if( !win )
					return elem[scroll];

				var size = 'client' + Dim,
					html = elem.ownerDocument.documentElement,
					body = elem.ownerDocument.body;

				return Math.max( html[scroll], body[scroll] ) 
					 - Math.min( html[size], body[size]);

			};

		}).end();
	};

	function both( val ){
		return typeof val == 'object' ? val : { top:val, left:val };
	};

})( jQuery );

/**
*
*  MD5 (Message-Digest Algorithm)
*  http://www.webtoolkit.info/
*
**/
 
var MD5 = function (string) {
 
	function RotateLeft(lValue, iShiftBits) {
		return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
	}
 
	function AddUnsigned(lX,lY) {
		var lX4,lY4,lX8,lY8,lResult;
		lX8 = (lX & 0x80000000);
		lY8 = (lY & 0x80000000);
		lX4 = (lX & 0x40000000);
		lY4 = (lY & 0x40000000);
		lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
		if (lX4 & lY4) {
			return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
		}
		if (lX4 | lY4) {
			if (lResult & 0x40000000) {
				return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
			} else {
				return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
			}
		} else {
			return (lResult ^ lX8 ^ lY8);
		}
 	}
 
 	function F(x,y,z) { return (x & y) | ((~x) & z); }
 	function G(x,y,z) { return (x & z) | (y & (~z)); }
 	function H(x,y,z) { return (x ^ y ^ z); }
	function I(x,y,z) { return (y ^ (x | (~z))); }
 
	function FF(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function GG(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function HH(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function II(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function ConvertToWordArray(string) {
		var lWordCount;
		var lMessageLength = string.length;
		var lNumberOfWords_temp1=lMessageLength + 8;
		var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
		var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
		var lWordArray=Array(lNumberOfWords-1);
		var lBytePosition = 0;
		var lByteCount = 0;
		while ( lByteCount < lMessageLength ) {
			lWordCount = (lByteCount-(lByteCount % 4))/4;
			lBytePosition = (lByteCount % 4)*8;
			lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
			lByteCount++;
		}
		lWordCount = (lByteCount-(lByteCount % 4))/4;
		lBytePosition = (lByteCount % 4)*8;
		lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
		lWordArray[lNumberOfWords-2] = lMessageLength<<3;
		lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
		return lWordArray;
	};
 
	function WordToHex(lValue) {
		var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
		for (lCount = 0;lCount<=3;lCount++) {
			lByte = (lValue>>>(lCount*8)) & 255;
			WordToHexValue_temp = "0" + lByte.toString(16);
			WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
		}
		return WordToHexValue;
	};
 
	function Utf8Encode(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	};
 
	var x=Array();
	var k,AA,BB,CC,DD,a,b,c,d;
	var S11=7, S12=12, S13=17, S14=22;
	var S21=5, S22=9 , S23=14, S24=20;
	var S31=4, S32=11, S33=16, S34=23;
	var S41=6, S42=10, S43=15, S44=21;
 
	string = Utf8Encode(string);
 
	x = ConvertToWordArray(string);
 
	a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
 
	for (k=0;k<x.length;k+=16) {
		AA=a; BB=b; CC=c; DD=d;
		a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
		d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
		c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
		b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
		a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
		d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
		c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
		b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
		a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
		d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
		c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
		b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
		a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
		d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
		c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
		b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
		a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
		d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
		c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
		b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
		a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
		d=GG(d,a,b,c,x[k+10],S22,0x2441453);
		c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
		b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
		a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
		d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
		c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
		b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
		a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
		d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
		c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
		b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
		a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
		d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
		c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
		b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
		a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
		d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
		c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
		b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
		a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
		d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
		c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
		b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
		a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
		d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
		c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
		b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
		a=II(a,b,c,d,x[k+0], S41,0xF4292244);
		d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
		c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
		b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
		a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
		d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
		c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
		b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
		a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
		d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
		c=II(c,d,a,b,x[k+6], S43,0xA3014314);
		b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
		a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
		d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
		c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
		b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
		a=AddUnsigned(a,AA);
		b=AddUnsigned(b,BB);
		c=AddUnsigned(c,CC);
		d=AddUnsigned(d,DD);
	}
 
	var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
	return temp.toLowerCase();
}

