/**
 * @license
 * jQuery Tools 1.2.5 / Tooltip Slide Effect
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/tooltip/slide.html
 *
 * Since: September 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// version number
	var t = $.tools.tooltip;

	// extend global configuragion with effect specific defaults
	$.extend(t.conf, {
		direction: 'up', // down, left, right
		bounce: false,
		slideOffset: 10,
		slideInSpeed: 200,
		slideOutSpeed: 200,
		slideFade: !$.browser.msie
	});

	// directions for slide effect
	var dirs = {
		up: ['-', 'top'],
		down: ['+', 'top'],
		left: ['-', 'left'],
		right: ['+', 'left']
	};

	/* default effect: "slide"  */
	t.addEffect("slide",

		// show effect
		function(done) {

			// variables
			var conf = this.getConf(),
				 tip = this.getTip(),
				 params = conf.slideFade ? {opacity: conf.opacity} : {},
				 dir = dirs[conf.direction] || dirs.up;

			// direction
			params[dir[1]] = dir[0] +'='+ conf.slideOffset;

			// perform animation
			if (conf.slideFade) { tip.css({opacity:0}); }
			tip.show().animate(params, conf.slideInSpeed, done);
		},

		// hide effect
		function(done) {

			// variables
			var conf = this.getConf(),
				 offset = conf.slideOffset,
				 params = conf.slideFade ? {opacity: 0} : {},
				 dir = dirs[conf.direction] || dirs.up;

			// direction
			var sign = "" + dir[0];
			if (conf.bounce) { sign = sign == '+' ? '-' : '+'; }
			params[dir[1]] = sign +'='+ offset;

			// perform animation
			this.getTip().animate(params, conf.slideOutSpeed, function()  {
				$(this).hide();
				done.call();
			});
		}
	);

})(jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 Tooltip - UI essentials
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/tooltip/
 *
 * Since: November 2008
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {
	// static constructs
	$.tools = $.tools || {version: '1.2.5'};

	$.tools.tooltip = {

		conf: {

			// default effect variables
			effect: 'toggle',
			fadeOutSpeed: "fast",
			predelay: 0,
			delay: 30,
			opacity: 1,
			tip: 0,

			// 'top', 'bottom', 'right', 'left', 'center'
			position: ['top', 'center'],
			offset: [0, 0],
			relative: false,
			cancelDefault: true,

			// type to event mapping
			events: {
				def: 			"mouseenter,mouseleave",
				input: 		"focus,blur",
				widget:		"focus mouseenter,blur mouseleave",
				tooltip:		"mouseenter,mouseleave"
			},

			// 1.2
			layout: '<div/>',
			tipClass: 'tooltip'
		},

		addEffect: function(name, loadFn, hideFn) {
			effects[name] = [loadFn, hideFn];
		}
	};


	var effects = {
		toggle: [
			function(done) {
				var conf = this.getConf(), tip = this.getTip(), o = conf.opacity;
				if (o < 1) { tip.css({opacity: o}); }
				tip.show();
				done.call();
			},

			function(done) {
				this.getTip().hide();
				done.call();
			}
		],

		fade: [
			function(done) {
				var conf = this.getConf();
				this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done);
			},
			function(done) {
				this.getTip().fadeOut(this.getConf().fadeOutSpeed, done);
			}
		]
	};


	/* calculate tip position relative to the trigger */
	function getPosition(trigger, tip, conf) {


		// get origin top/left position
		var top = conf.relative ? trigger.position().top : trigger.offset().top,
			 left = conf.relative ? trigger.position().left : trigger.offset().left,
			 pos = conf.position[0];

		top  -= tip.outerHeight() - conf.offset[0];
		left += trigger.outerWidth() + conf.offset[1];

		// iPad position fix
		if (/iPad/i.test(navigator.userAgent)) {
			top -= $(window).scrollTop();
		}

		// adjust Y
		var height = tip.outerHeight() + trigger.outerHeight();
		if (pos == 'center') 	{ top += height / 2; }
		if (pos == 'bottom') 	{ top += height; }


		// adjust X
		pos = conf.position[1];
		var width = tip.outerWidth() + trigger.outerWidth();
		if (pos == 'center') 	{ left -= width / 2; }
		if (pos == 'left')   	{ left -= width; }

		return {top: top, left: left};
	}



	function Tooltip(trigger, conf) {

		var self = this,
			 fire = trigger.add(self),
			 tip,
			 timer = 0,
			 pretimer = 0,
			 title = trigger.attr("title"),
			 tipAttr = trigger.attr("data-tooltip"),
			 effect = effects[conf.effect],
			 shown,

			 // get show/hide configuration
			 isInput = trigger.is(":input"),
			 isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"),
			 type = trigger.attr("type"),
			 evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def'];


		// check that configuration is sane
		if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; }

		evt = evt.split(/,\s*/);
		if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; }


		// trigger --> show
		trigger.bind(evt[0], function(e) {

			clearTimeout(timer);
			if (conf.predelay) {
				pretimer = setTimeout(function() { self.show(e); }, conf.predelay);

			} else {
				self.show(e);
			}

		// trigger --> hide
		}).bind(evt[1], function(e)  {
			clearTimeout(pretimer);
			if (conf.delay)  {
				timer = setTimeout(function() { self.hide(e); }, conf.delay);

			} else {
				self.hide(e);
			}

		});


		// remove default title
		if (title && conf.cancelDefault) {
			trigger.removeAttr("title");
			trigger.data("title", title);
		}

		$.extend(self, {

			show: function(e) {

				// tip not initialized yet
				if (!tip) {

					// data-tooltip
					if (tipAttr) {
						tip = $(tipAttr);

					// single tip element for all
					} else if (conf.tip) {
						tip = $(conf.tip).eq(0);

					// autogenerated tooltip
					} else if (title) {
						tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body)
							.hide().append(title);

					// manual tooltip
					} else {
						tip = trigger.next();
						if (!tip.length) { tip = trigger.parent().next(); }
					}

					if (!tip.length) { throw "Cannot find tooltip for " + trigger;	}
				}

			 	if (self.isShown()) { return self; }

			 	// stop previous animation
			 	tip.stop(true, true);

				// get position
				var pos = getPosition(trigger, tip, conf);

				// restore title for single tooltip element
				if (conf.tip) {
					tip.html(trigger.data("title"));
				}

				// onBeforeShow
				e = e || $.Event();
				e.type = "onBeforeShow";
				fire.trigger(e, [pos]);
				if (e.isDefaultPrevented()) { return self; }


				// onBeforeShow may have altered the configuration
				pos = getPosition(trigger, tip, conf);

				// set position
				tip.css({position:'absolute', top: pos.top, left: pos.left});

				shown = true;

				// invoke effect
				effect[0].call(self, function() {
					e.type = "onShow";
					shown = 'full';
					fire.trigger(e);
				});


				// tooltip events
				var event = conf.events.tooltip.split(/,\s*/);

				if (!tip.data("__set")) {

					tip.bind(event[0], function() {
						clearTimeout(timer);
						clearTimeout(pretimer);
					});

					if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) {
						tip.bind(event[1], function(e) {

							// being moved to the trigger element
							if (e.relatedTarget != trigger[0]) {
								trigger.trigger(evt[1].split(" ")[0]);
							}
						});
					}

					tip.data("__set", true);
				}

				return self;
			},

			hide: function(e) {

				if (!tip || !self.isShown()) { return self; }

				// onBeforeHide
				e = e || $.Event();
				e.type = "onBeforeHide";
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return; }

				shown = false;

				effects[conf.effect][1].call(self, function() {
					e.type = "onHide";
					fire.trigger(e);
				});

				return self;
			},

			isShown: function(fully) {
				return fully ? shown == 'full' : shown;
			},

			getConf: function() {
				return conf;
			},

			getTip: function() {
				return tip;
			},

			getTrigger: function() {
				return trigger;
			}

		});

		// callbacks
		$.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) {

			// configuration
			if ($.isFunction(conf[name])) {
				$(self).bind(name, conf[name]);
			}

			// API
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});

	}


	// jQuery plugin implementation
	$.fn.tooltip = function(conf) {

		// return existing instance
		var api = this.data("tooltip");
		if (api) { return api; }

		conf = $.extend(true, {}, $.tools.tooltip.conf, conf);

		// position can also be given as string
		if (typeof conf.position == 'string') {
			conf.position = conf.position.split(/,?\s/);
		}

		// install tooltip for each entry in jQuery object
		this.each(function() {
			api = new Tooltip($(this), conf);
			$(this).data("tooltip", api);
		});

		return conf.api ? api: this;
	};

}) (jQuery);



/**
 * @license
 * jQuery Tools 1.2.5 / Tooltip Dynamic Positioning
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/tooltip/dynamic.html
 *
 * Since: July 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// version number
	var t = $.tools.tooltip;

	t.dynamic = {
		conf: {
			classNames: "top right bottom left"
		}
	};

	/*
	 * See if element is on the viewport. Returns an boolean array specifying which
	 * edges are hidden. Edges are in following order:
	 *
	 * [top, right, bottom, left]
	 *
	 * For example following return value means that top and right edges are hidden
	 *
	 * [true, true, false, false]
	 *
	 */
	function getCropping(el) {

		var w = $(window);
		var right = w.width() + w.scrollLeft();
		var bottom = w.height() + w.scrollTop();

		return [
			el.offset().top <= w.scrollTop(), 						// top
			right <= el.offset().left + el.width(),				// right
			bottom <= el.offset().top + el.height(),			// bottom
			w.scrollLeft() >= el.offset().left 					// left
		];
	}

	/*
		Returns true if all edges of an element are on viewport. false if not

		@param crop the cropping array returned by getCropping function
	 */
	function isVisible(crop) {
		var i = crop.length;
		while (i--) {
			if (crop[i]) { return false; }
		}
		return true;
	}

	// dynamic plugin
	$.fn.dynamic = function(conf) {

		if (typeof conf == 'number') { conf = {speed: conf}; }

		conf = $.extend({}, t.dynamic.conf, conf);

		var cls = conf.classNames.split(/\s/), orig;

		this.each(function() {

			var api = $(this).tooltip().onBeforeShow(function(e, pos) {

				// get nessessary variables
				var tip = this.getTip(), tipConf = this.getConf();

				/*
					We store the original configuration and use it to restore back to the original state.
				*/
				if (!orig) {
					orig = [
						tipConf.position[0],
						tipConf.position[1],
						tipConf.offset[0],
						tipConf.offset[1],
						$.extend({}, tipConf)
					];
				}

				/*
					display tip in it's default position and by setting visibility to hidden.
					this way we can check whether it will be on the viewport
				*/
				$.extend(tipConf, orig[4]);
				tipConf.position = [orig[0], orig[1]];
				tipConf.offset = [orig[2], orig[3]];

				tip.css({
					visibility: 'hidden',
					position: 'absolute',
					top: pos.top,
					left: pos.left
				}).show();

				// now let's see for hidden edges
				var crop = getCropping(tip);

				// possibly alter the configuration
				if (!isVisible(crop)) {

					// change the position and add class
					if (crop[2]) { $.extend(tipConf, conf.top);		tipConf.position[0] = 'top'; 		tip.addClass(cls[0]); }
					if (crop[3]) { $.extend(tipConf, conf.right);	tipConf.position[1] = 'right'; 	tip.addClass(cls[1]); }
					if (crop[0]) { $.extend(tipConf, conf.bottom); 	tipConf.position[0] = 'bottom';	tip.addClass(cls[2]); }
					if (crop[1]) { $.extend(tipConf, conf.left);		tipConf.position[1] = 'left'; 	tip.addClass(cls[3]); }

					// vertical offset
					if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; }

					// horizontal offset
					if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; }
				}

				tip.css({visibility: 'visible'}).hide();

			});

			// restore positioning as soon as possible
			api.onBeforeShow(function() {
				var c = this.getConf(), tip = this.getTip();
				setTimeout(function() {
					c.position = [orig[0], orig[1]];
					c.offset = [orig[2], orig[3]];
				}, 0);
			});

			// remove custom class names and restore original effect
			api.onHide(function() {
				var tip = this.getTip();
				tip.removeClass(conf.classNames);
			});

			ret = api;

		});

		return conf.api ? ret : this;
	};

}) (jQuery);
/**
 * @license
 * jQuery Tools 1.2.5 Rangeinput - HTML5 <input type="range" /> for humans
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/rangeinput/
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	$.tools = $.tools || {version: '1.2.5'};

	var tool;

	tool = $.tools.rangeinput = {

		conf: {
			min: 0,
			max: 100,		// as defined in the standard
			step: 'any', 	// granularity of the value. a non-zero float or int (or "any")
			steps: 0,
			value: 0,
			precision: undefined,
			vertical: 0,
			keyboard: true,
			progress: false,
			speed: 100,

			// set to null if not needed
			css: {
				input:		'range',
				slider: 		'slider',
				progress: 	'progress',
				handle: 		'handle'
			}

		}
	};

//{{{ fn.drag

	/*
		FULL featured drag and drop. 0.7 kb minified, 0.3 gzipped. done.
		Who told d'n'd is rocket science? Usage:

		$(".myelement").drag({y: false}).bind("drag", function(event, x, y) {
			// do your custom thing
		});

		Configuration:
			x: true, 		// enable horizontal drag
			y: true, 		// enable vertical drag
			drag: true 		// true = perform drag, false = only fire events

		Events: dragStart, drag, dragEnd.
	*/
	var doc, draggable;

	$.fn.drag = function(conf) {

		// disable IE specialities
		document.ondragstart = function () { return false; };

		conf = $.extend({x: true, y: true, drag: true}, conf);

		doc = doc || $(document).bind("mousedown mouseup", function(e) {

			var el = $(e.target);

			// start
			if (e.type == "mousedown" && el.data("drag")) {

				var offset = el.position(),
					 x0 = e.pageX - offset.left,
					 y0 = e.pageY - offset.top,
					 start = true;

				doc.bind("mousemove.drag", function(e) {
					var x = e.pageX -x0,
						 y = e.pageY -y0,
						 props = {};

					if (conf.x) { props.left = x; }
					if (conf.y) { props.top = y; }

					if (start) {
						el.trigger("dragStart");
						start = false;
					}
					if (conf.drag) { el.css(props); }
					el.trigger("drag", [y, x]);
					draggable = el;
				});

				e.preventDefault();

			} else {

				try {
					if (draggable) {
						draggable.trigger("dragEnd");
					}
				} finally {
					doc.unbind("mousemove.drag");
					draggable = null;
				}
			}

		});

		return this.data("drag", true);
	};

//}}}



	function round(value, precision) {
		var n = Math.pow(10, precision);
		return Math.round(value * n) / n;
	}

	// get hidden element's width or height even though it's hidden
	function dim(el, key) {
		var v = parseInt(el.css(key), 10);
		if (v) { return v; }
		var s = el[0].currentStyle;
		return s && s.width && parseInt(s.width, 10);
	}

	function hasEvent(el) {
		var e = el.data("events");
		return e && e.onSlide;
	}

	function RangeInput(input, conf) {

		// private variables
		var self = this,
			 css = conf.css,
			 root = $("<div><div/><a href='#'/></div>").data("rangeinput", self),
			 vertical,
			 value,			// current value
			 origo,			// handle's start point
			 len,				// length of the range
			 pos;				// current position of the handle

		// create range
		input.before(root);

		var handle = root.addClass(css.slider).find("a").addClass(css.handle),
			 progress = root.find("div").addClass(css.progress);

		// get (HTML5) attributes into configuration
		$.each("min,max,step,value".split(","), function(i, key) {
			var val = input.attr(key);
			if (parseFloat(val)) {
				conf[key] = parseFloat(val, 10);
			}
		});

		var range = conf.max - conf.min,
			 step = conf.step == 'any' ? 0 : conf.step,
			 precision = conf.precision;

		if (precision === undefined) {
			try {
				precision = step.toString().split(".")[1].length;
			} catch (err) {
				precision = 0;
			}
		}

		// Replace built-in range input (type attribute cannot be changed)
		if (input.attr("type") == 'range') {
			var tmp = $("<input/>");
			$.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr)  {
				tmp.attr(attr, input.attr(attr));
			});
			tmp.val(conf.value);
			input.replaceWith(tmp);
			input = tmp;
		}

		input.addClass(css.input);

		var fire = $(self).add(input), fireOnSlide = true;


		/**
		 	The flesh and bone of this tool. All sliding is routed trough this.

			@param evt types include: click, keydown, blur and api (setValue call)
			@param isSetValue when called trough setValue() call (keydown, blur, api)

			vertical configuration gives additional complexity.
		 */
		function slide(evt, x, val, isSetValue) {

			// calculate value based on slide position
			if (val === undefined) {
				val = x / len * range;

			// x is calculated based on val. we need to strip off min during calculation
			} else if (isSetValue) {
				val -= conf.min;
			}

			// increment in steps
			if (step) {
				val = Math.round(val / step) * step;
			}

			// count x based on value or tweak x if stepping is done
			if (x === undefined || step) {
				x = val * len / range;
			}

			// crazy value?
			if (isNaN(val)) { return self; }

			// stay within range
			x = Math.max(0, Math.min(x, len));
			val = x / len * range;

			if (isSetValue || !vertical) {
				val += conf.min;
			}

			// in vertical ranges value rises upwards
			if (vertical) {
				if (isSetValue) {
					x = len -x;
				} else {
					val = conf.max - val;
				}
			}

			// precision
			val = round(val, precision);

			// onSlide
			var isClick = evt.type == "click";
			if (fireOnSlide && value !== undefined && !isClick) {
				evt.type = "onSlide";
				fire.trigger(evt, [val, x]);
				if (evt.isDefaultPrevented()) { return self; }
			}

			// speed & callback
			var speed = isClick ? conf.speed : 0,
				 callback = isClick ? function()  {
					evt.type = "change";
					fire.trigger(evt, [val]);
				 } : null;

			if (vertical) {
				handle.animate({top: x}, speed, callback);
				if (conf.progress) {
					progress.animate({height: len - x + handle.width() / 2}, speed);
				}

			} else {
				handle.animate({left: x}, speed, callback);
				if (conf.progress) {
					progress.animate({width: x + handle.width() / 2}, speed);
				}
			}

			// store current value
			value = val;
			pos = x;

			// se input field's value
			input.val(val);

			return self;
		}


		$.extend(self, {

			getValue: function() {
				return value;
			},

			setValue: function(val, e) {
				init();
				return slide(e || $.Event("api"), undefined, val, true);
			},

			getConf: function() {
				return conf;
			},

			getProgress: function() {
				return progress;
			},

			getHandle: function() {
				return handle;
			},

			getInput: function() {
				return input;
			},

			step: function(am, e) {
				e = e || $.Event();
				var step = conf.step == 'any' ? 1 : conf.step;
				self.setValue(value + step * (am || 1), e);
			},

			// HTML5 compatible name
			stepUp: function(am) {
				return self.step(am || 1);
			},

			// HTML5 compatible name
			stepDown: function(am) {
				return self.step(-am || -1);
			}

		});

		// callbacks
		$.each("onSlide,change".split(","), function(i, name) {

			// from configuration
			if ($.isFunction(conf[name]))  {
				$(self).bind(name, conf[name]);
			}

			// API methods
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});


		// dragging
		handle.drag({drag: false}).bind("dragStart", function() {

			/* do some pre- calculations for seek() function. improves performance */
			init();

			// avoid redundant event triggering (= heavy stuff)
			fireOnSlide = hasEvent($(self)) || hasEvent(input);


		}).bind("drag", function(e, y, x) {

			if (input.is(":disabled")) { return false; }
			slide(e, vertical ? y : x);

		}).bind("dragEnd", function(e) {
			if (!e.isDefaultPrevented()) {
				e.type = "change";
				fire.trigger(e, [value]);
			}

		}).click(function(e) {
			return e.preventDefault();
		});

		// clicking
		root.click(function(e) {
			if (input.is(":disabled") || e.target == handle[0]) {
				return e.preventDefault();
			}
			init();
			var fix = handle.width() / 2;
			slide(e, vertical ? len-origo-fix + e.pageY  : e.pageX -origo -fix);
		});

		if (conf.keyboard) {

			input.keydown(function(e) {

				if (input.attr("readonly")) { return; }

				var key = e.keyCode,
					 up = $([75, 76, 38, 33, 39]).index(key) != -1,
					 down = $([74, 72, 40, 34, 37]).index(key) != -1;

				if ((up || down) && !(e.shiftKey || e.altKey || e.ctrlKey)) {

					// UP: 	k=75, l=76, up=38, pageup=33, right=39
					if (up) {
						self.step(key == 33 ? 10 : 1, e);

					// DOWN:	j=74, h=72, down=40, pagedown=34, left=37
					} else if (down) {
						self.step(key == 34 ? -10 : -1, e);
					}
					return e.preventDefault();
				}
			});
		}


		input.blur(function(e) {
			var val = $(this).val();
			if (val !== value) {
				self.setValue(val, e);
			}
		});


		// HTML5 DOM methods
		$.extend(input[0], { stepUp: self.stepUp, stepDown: self.stepDown});


		// calculate all dimension related stuff
		function init() {
		 	vertical = conf.vertical || dim(root, "height") > dim(root, "width");

			if (vertical) {
				len = dim(root, "height") - dim(handle, "height");
				origo = root.offset().top + len;

			} else {
				len = dim(root, "width") - dim(handle, "width");
				origo = root.offset().left;
			}
		}

		function begin() {
			init();
			self.setValue(conf.value !== undefined ? conf.value : conf.min);
		}
		begin();

		// some browsers cannot get dimensions upon initialization
		if (!len) {
			$(window).load(begin);
		}
	}

	$.expr[':'].range = function(el) {
		var type = el.getAttribute("type");
		return type && type == 'range' || !!$(el).filter("input").data("rangeinput");
	};


	// jQuery plugin implementation
	$.fn.rangeinput = function(conf) {

		// already installed
		if (this.data("rangeinput")) { return this; }

		// extend configuration with globals
		conf = $.extend(true, {}, tool.conf, conf);

		var els;

		this.each(function() {
			var el = new RangeInput($(this), $.extend(true, {}, conf));
			var input = el.getInput().data("rangeinput", el);
			els = els ? els.add(input) : input;
		});

		return els ? els : this;
	};


}) (jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 History "Back button for AJAX apps"
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/toolbox/history.html
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	var hash, iframe, links, inited;

	$.tools = $.tools || {version: '1.2.5'};

	$.tools.history = {

		init: function(els) {

			if (inited) { return; }

			// IE
			if ($.browser.msie && $.browser.version < '8') {

				// create iframe that is constantly checked for hash changes
				if (!iframe) {
					iframe = $("<iframe/>").attr("src", "javascript:false;").hide().get(0);
					$("body").append(iframe);

					setInterval(function() {
						var idoc = iframe.contentWindow.document,
							 h = idoc.location.hash;

						if (hash !== h) {
							$.event.trigger("hash", h);
						}
					}, 100);

					setIframeLocation(location.hash || '#');
				}


			// other browsers scans for location.hash changes directly without iframe hack
			} else {
				setInterval(function() {
					var h = location.hash;
					if (h !== hash) {
						$.event.trigger("hash", h);
					}
				}, 100);
			}

			links = !links ? els : links.add(els);

			els.click(function(e) {
				var href = $(this).attr("href");
				if (iframe) { setIframeLocation(href); }

				// handle non-anchor links
				if (href.slice(0, 1) != "#") {
					location.href = "#" + href;
					return e.preventDefault();
				}

			});

			inited = true;
		}
	};


	function setIframeLocation(h) {
		if (h) {
			var doc = iframe.contentWindow.document;
			doc.open().close();
			doc.location.hash = h;
		}
	}

	// global histroy change listener
	$(window).bind("hash", function(e, h)  {
		if (h) {
			links.filter(function() {
			  var href = $(this).attr("href");
			  return href == h || href == h.replace("#", "");
			}).trigger("history", [h]);
		} else {
			links.eq(0).trigger("history", [h]);
		}

		hash = h;

	});


	// jQuery plugin implementation
	$.fn.history = function(fn) {

		$.tools.history.init(this);

		// return jQuery
		return this.bind("history", fn);
	};

})(jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 Mousewheel
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/toolbox/mousewheel.html
 *
 * based on jquery.event.wheel.js ~ rev 1 ~
 * Copyright (c) 2008, Three Dub Media
 * http://threedubmedia.com
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	$.fn.mousewheel = function( fn ){
		return this[ fn ? "bind" : "trigger" ]( "wheel", fn );
	};

	// special event config
	$.event.special.wheel = {
		setup: function() {
			$.event.add( this, wheelEvents, wheelHandler, {} );
		},
		teardown: function(){
			$.event.remove( this, wheelEvents, wheelHandler );
		}
	};

	// events to bind ( browser sniffed... )
	var wheelEvents = !$.browser.mozilla ? "mousewheel" : // IE, opera, safari
		"DOMMouseScroll"+( $.browser.version<"1.9" ? " mousemove" : "" ); // firefox

	// shared event handler
	function wheelHandler( event ) {

		switch ( event.type ) {

			// FF2 has incorrect event positions
			case "mousemove":
				return $.extend( event.data, { // store the correct properties
					clientX: event.clientX, clientY: event.clientY,
					pageX: event.pageX, pageY: event.pageY
				});

			// firefox
			case "DOMMouseScroll":
				$.extend( event, event.data ); // fix event properties in FF2
				event.delta = -event.detail / 3; // normalize delta
				break;

			// IE, opera, safari
			case "mousewheel":
				event.delta = event.wheelDelta / 120;
				break;
		}

		event.type = "wheel"; // hijack the event
		return $.event.handle.call( this, event, event.delta );
	}

})(jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 / Flashembed - New wave Flash embedding
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/toolbox/flashembed.html
 *
 * Since : March 2008
 * Date  : Thu May 15 10:43:37 CEST 2014
 */
(function() {

	var IE = document.all,
		 URL = 'http://www.adobe.com/go/getflashplayer',
		 JQUERY = typeof jQuery == 'function',
		 RE = /(\d+)[^\d]+(\d+)[^\d]*(\d*)/,
		 GLOBAL_OPTS = {
			// very common opts
			width: '100%',
			height: '100%',
			id: "_" + ("" + Math.random()).slice(9),

			// flashembed defaults
			allowfullscreen: true,
			allowscriptaccess: 'always',
			quality: 'high',

			// flashembed specific options
			version: [3, 0],
			onFail: null,
			expressInstall: null,
			w3c: false,
			cachebusting: false
	};

	// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
	if (window.attachEvent) {
		window.attachEvent("onbeforeunload", function() {
			__flash_unloadHandler = function() {};
			__flash_savedUnloadHandler = function() {};
		});
	}

	// simple extend
	function extend(to, from) {
		if (from) {
			for (var key in from) {
				if (from.hasOwnProperty(key)) {
					to[key] = from[key];
				}
			}
		}
		return to;
	}

	// used by asString method
	function map(arr, func) {
		var newArr = [];
		for (var i in arr) {
			if (arr.hasOwnProperty(i)) {
				newArr[i] = func(arr[i]);
			}
		}
		return newArr;
	}

	window.flashembed = function(root, opts, conf) {

		// root must be found / loaded
		if (typeof root == 'string') {
			root = document.getElementById(root.replace("#", ""));
		}

		// not found
		if (!root) { return; }

		if (typeof opts == 'string') {
			opts = {src: opts};
		}

		return new Flash(root, extend(extend({}, GLOBAL_OPTS), opts), conf);
	};

	// flashembed "static" API
	var f = extend(window.flashembed, {

		conf: GLOBAL_OPTS,

		getVersion: function()  {
			var fo, ver;

			try {
				ver = navigator.plugins["Shockwave Flash"].description.slice(16);
			} catch(e) {

				try  {
					fo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
					ver = fo && fo.GetVariable("$version");

				} catch(err) {
                try  {
                    fo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                    ver = fo && fo.GetVariable("$version");
                } catch(err2) { }
				}
			}

			ver = RE.exec(ver);
			return ver ? [ver[1], ver[3]] : [0, 0];
		},

		asString: function(obj) {

			if (obj === null || obj === undefined) { return null; }
			var type = typeof obj;
			if (type == 'object' && obj.push) { type = 'array'; }

			switch (type){

				case 'string':
					obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');

					// flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
					obj = obj.replace(/^\s?(\d+\.?\d+)%/, "$1pct");
					return '"' +obj+ '"';

				case 'array':
					return '['+ map(obj, function(el) {
						return f.asString(el);
					}).join(',') +']';

				case 'function':
					return '"function()"';

				case 'object':
					var str = [];
					for (var prop in obj) {
						if (obj.hasOwnProperty(prop)) {
							str.push('"'+prop+'":'+ f.asString(obj[prop]));
						}
					}
					return '{'+str.join(',')+'}';
			}

			// replace ' --> "  and remove spaces
			return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
		},

		getHTML: function(opts, conf) {

			opts = extend({}, opts);

			/******* OBJECT tag and it's attributes *******/
			var html = '<object width="' + opts.width +
				'" height="' + opts.height +
				'" id="' + opts.id +
				'" name="' + opts.id + '"';

			if (opts.cachebusting) {
				opts.src += ((opts.src.indexOf("?") != -1 ? "&" : "?") + Math.random());
			}

			if (opts.w3c || !IE) {
				html += ' data="' +opts.src+ '" type="application/x-shockwave-flash"';
			} else {
				html += ' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
			}

			html += '>';

			/******* nested PARAM tags *******/
			if (opts.w3c || IE) {
				html += '<param name="movie" value="' +opts.src+ '" />';
			}

			// not allowed params
			opts.width = opts.height = opts.id = opts.w3c = opts.src = null;
			opts.onFail = opts.version = opts.expressInstall = null;

			for (var key in opts) {
				if (opts[key]) {
					html += '<param name="'+ key +'" value="'+ opts[key] +'" />';
				}
			}

			/******* FLASHVARS *******/
			var vars = "";

			if (conf) {
				for (var k in conf) {
					if (conf[k]) {
						var val = conf[k];
						vars += k +'='+ (/function|object/.test(typeof val) ? f.asString(val) : val) + '&';
					}
				}
				vars = vars.slice(0, -1);
				html += '<param name="flashvars" value=\'' + vars + '\' />';
			}

			html += "</object>";

			return html;
		},

		isSupported: function(ver) {
			return VERSION[0] > ver[0] || VERSION[0] == ver[0] && VERSION[1] >= ver[1];
		}

	});

	var VERSION = f.getVersion();

	function Flash(root, opts, conf) {

		// version is ok
		if (f.isSupported(opts.version)) {
			root.innerHTML = f.getHTML(opts, conf);

		// express install
		} else if (opts.expressInstall && f.isSupported([6, 65])) {
			root.innerHTML = f.getHTML(extend(opts, {src: opts.expressInstall}), {
				MMredirectURL: location.href,
				MMplayerType: 'PlugIn',
				MMdoctitle: document.title
			});

		} else {

			// fail #2.1 custom content inside container
			if (!root.innerHTML.replace(/\s/g, '')) {
				root.innerHTML =
					"<h2>Flash version " + opts.version + " or greater is required</h2>" +
					"<h3>" +
						(VERSION[0] > 0 ? "Your version is " + VERSION : "You have no flash plugin installed") +
					"</h3>" +

					(root.tagName == 'A' ? "<p>Click here to download latest version</p>" :
						"<p>Download latest version from <a href='" + URL + "'>here</a></p>");

				if (root.tagName == 'A') {
					root.onclick = function() {
						location.href = URL;
					};
				}
			}

			// onFail
			if (opts.onFail) {
				var ret = opts.onFail.call(this);
				if (typeof ret == 'string') { root.innerHTML = ret; }
			}
		}

		// http://flowplayer.org/forum/8/18186#post-18593
		if (IE) {
			window[opts.id] = document.getElementById(opts.id);
		}

		// API methods for callback
		extend(this, {

			getRoot: function() {
				return root;
			},

			getOptions: function() {
				return opts;
			},


			getConf: function() {
				return conf;
			},

			getApi: function() {
				return root.firstChild;
			}

		});
	}

	// setup jquery support
	if (JQUERY) {

		// tools version number
		jQuery.tools = jQuery.tools || {version: '1.2.5'};

		jQuery.tools.flashembed = {
			conf: GLOBAL_OPTS
		};

		jQuery.fn.flashembed = function(opts, conf) {
			return this.each(function() {
				$(this).data("flashembed", flashembed(this, opts, conf));
			});
		};
	}

})();

/**
 * @license
 * jQuery Tools 1.2.5 / Expose - Dim the lights
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/toolbox/expose.html
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// static constructs
	$.tools = $.tools || {version: '1.2.5'};

	var tool;

	tool = $.tools.expose = {

		conf: {
			maskId: 'exposeMask',
			loadSpeed: 'slow',
			closeSpeed: 'fast',
			closeOnClick: true,
			closeOnEsc: true,

			// css settings
			zIndex: 9998,
			opacity: 0.8,
			startOpacity: 0,
			color: '#fff',

			// callbacks
			onLoad: null,
			onClose: null
		}
	};

	/* one of the greatest headaches in the tool. finally made it */
	function viewport() {

		// the horror case
		if ($.browser.msie) {

			// if there are no scrollbars then use window.height
			var d = $(document).height(), w = $(window).height();

			return [
				window.innerWidth || 							// ie7+
				document.documentElement.clientWidth || 	// ie6
				document.body.clientWidth, 					// ie6 quirks mode
				d - w < 20 ? w : d
			];
		}

		// other well behaving browsers
		return [$(document).width(), $(document).height()];
	}

	function call(fn) {
		if (fn) { return fn.call($.mask); }
	}

	var mask, exposed, loaded, config, overlayIndex;


	$.mask = {

		load: function(conf, els) {

			// already loaded ?
			if (loaded) { return this; }

			// configuration
			if (typeof conf == 'string') {
				conf = {color: conf};
			}

			// use latest config
			conf = conf || config;

			config = conf = $.extend($.extend({}, tool.conf), conf);

			// get the mask
			mask = $("#" + conf.maskId);

			// or create it
			if (!mask.length) {
				mask = $('<div/>').attr("id", conf.maskId);
				$("body").append(mask);
			}

			// set position and dimensions
			var size = viewport();

			mask.css({
				position:'absolute',
				top: 0,
				left: 0,
				width: size[0],
				height: size[1],
				display: 'none',
				opacity: conf.startOpacity,
				zIndex: conf.zIndex
			});

			if (conf.color) {
				mask.css("backgroundColor", conf.color);
			}

			// onBeforeLoad
			if (call(conf.onBeforeLoad) === false) {
				return this;
			}

			// esc button
			if (conf.closeOnEsc) {
				$(document).bind("keydown.mask", function(e) {
					if (e.keyCode == 27) {
						$.mask.close(e);
					}
				});
			}

			// mask click closes
			if (conf.closeOnClick) {
				mask.bind("click.mask", function(e)  {
					$.mask.close(e);
				});
			}

			// resize mask when window is resized
			$(window).bind("resize.mask", function() {
				$.mask.fit();
			});

			// exposed elements
			if (els && els.length) {

				overlayIndex = els.eq(0).css("zIndex");

				// make sure element is positioned absolutely or relatively
				$.each(els, function() {
					var el = $(this);
					if (!/relative|absolute|fixed/i.test(el.css("position"))) {
						el.css("position", "relative");
					}
				});

				// make elements sit on top of the mask
				exposed = els.css({ zIndex: Math.max(conf.zIndex + 1, overlayIndex == 'auto' ? 0 : overlayIndex)});
			}

			// reveal mask
			mask.css({display: 'block'}).fadeTo(conf.loadSpeed, conf.opacity, function() {
				$.mask.fit();
				call(conf.onLoad);
				loaded = "full";
			});

			loaded = true;
			return this;
		},

		close: function() {
			if (loaded) {

				// onBeforeClose
				if (call(config.onBeforeClose) === false) { return this; }

				mask.fadeOut(config.closeSpeed, function()  {
					call(config.onClose);
					if (exposed) {
						exposed.css({zIndex: overlayIndex});
					}
					loaded = false;
				});

				// unbind various event listeners
				$(document).unbind("keydown.mask");
				mask.unbind("click.mask");
				$(window).unbind("resize.mask");
			}

			return this;
		},

		fit: function() {
			if (loaded) {
				var size = viewport();
				mask.css({width: size[0], height: size[1]});
			}
		},

		getMask: function() {
			return mask;
		},

		isLoaded: function(fully) {
			return fully ? loaded == 'full' : loaded;
		},

		getConf: function() {
			return config;
		},

		getExposed: function() {
			return exposed;
		}
	};

	$.fn.mask = function(conf) {
		$.mask.load(conf);
		return this;
	};

	$.fn.expose = function(conf) {
		$.mask.load(conf, this);
		return this;
	};


})(jQuery);
/**
 * @license
 * jQuery Tools 1.2.5 Dateinput - <input type="date" /> for humans
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/form/dateinput/
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	/* TODO:
		 preserve today highlighted
	*/

	$.tools = $.tools || {version: '1.2.5'};

	var instances = [],
		 tool,

		 // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39
		 KEYS = [75, 76, 38, 39, 74, 72, 40, 37],
		 LABELS = {};

	tool = $.tools.dateinput = {

		conf: {
			format: 'mm/dd/yy',
			selectors: false,
			yearRange: [-5, 5],
			lang: 'en',
			offset: [0, 0],
			speed: 0,
			firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
			min: undefined,
			max: undefined,
			trigger: false,

			css: {

				prefix: 'cal',
				input: 'date',

				// ids
				root: 0,
				head: 0,
				title: 0,
				prev: 0,
				next: 0,
				month: 0,
				year: 0,
				days: 0,

				body: 0,
				weeks: 0,
				today: 0,
				current: 0,

				// classnames
				week: 0,
				off: 0,
				sunday: 0,
				focus: 0,
				disabled: 0,
				trigger: 0
			}
		},

		localize: function(language, labels) {
			$.each(labels, function(key, val) {
				labels[key] = val.split(",");
			});
			LABELS[language] = labels;
		}

	};

	tool.localize("en", {
		months: 		 'January,February,March,April,May,June,July,August,September,October,November,December',
		shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
		days: 		 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
		shortDays: 	 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'
	});


//{{{ private functions


	// @return amount of days in certain month
	function dayAm(year, month) {
		return 32 - new Date(year, month, 32).getDate();
	}

	function zeropad(val, len) {
		val = '' + val;
		len = len || 2;
		while (val.length < len) { val = "0" + val; }
		return val;
	}

	// thanks: http://stevenlevithan.com/assets/misc/date.format.js
	var Re = /d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>");

	function format(date, fmt, lang) {

	  var d = date.getDate(),
			D = date.getDay(),
			m = date.getMonth(),
			y = date.getFullYear(),

			flags = {
				d:    d,
				dd:   zeropad(d),
				ddd:  LABELS[lang].shortDays[D],
				dddd: LABELS[lang].days[D],
				m:    m + 1,
				mm:   zeropad(m + 1),
				mmm:  LABELS[lang].shortMonths[m],
				mmmm: LABELS[lang].months[m],
				yy:   String(y).slice(2),
				yyyy: y
			};

		var ret = fmt.replace(Re, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});

		// a small trick to handle special characters
		return tmpTag.html(ret).html();

	}

	function integer(val) {
		return parseInt(val, 10);
	}

	function isSameDay(d1, d2)  {
		return d1.getFullYear() === d2.getFullYear() &&
			d1.getMonth() == d2.getMonth() &&
			d1.getDate() == d2.getDate();
	}

	function parseDate(val) {

		if (!val) { return; }
		if (val.constructor == Date) { return val; }

		if (typeof val == 'string') {

			// rfc3339?
			var els = val.split("-");
			if (els.length == 3) {
				return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2]));
			}

			// invalid offset
			if (!/^-?\d+$/.test(val)) { return; }

			// convert to integer
			val = integer(val);
		}

		var date = new Date();
		date.setDate(date.getDate() + val);
		return date;
	}

//}}}


	function Dateinput(input, conf)  {

		// variables
		var self = this,
			 now = new Date(),
			 css = conf.css,
			 labels = LABELS[conf.lang],
			 root = $("#" + css.root),
			 title = root.find("#" + css.title),
			 trigger,
			 pm, nm,
			 currYear, currMonth, currDay,
			 value = input.attr("data-value") || conf.value || input.val(),
			 min = input.attr("min") || conf.min,
			 max = input.attr("max") || conf.max,
			 opened;

		// zero min is not undefined
		if (min === 0) { min = "0"; }

		// use sane values for value, min & max
		value = parseDate(value) || now;
		min   = parseDate(min || conf.yearRange[0] * 365);
		max   = parseDate(max || conf.yearRange[1] * 365);


		// check that language exists
		if (!labels) { throw "Dateinput: invalid language: " + conf.lang; }

		// Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser
		if (input.attr("type") == 'date') {
			var tmp = $("<input/>");

			$.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr)  {
				tmp.attr(attr, input.attr(attr));
			});
			input.replaceWith(tmp);
			input = tmp;
		}
		input.addClass(css.input);

		var fire = input.add(self);

		// construct layout
		if (!root.length) {

			// root
			root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>')
				.hide().css({position: 'absolute'}).attr("id", css.root);

			// elements
			root.children()
				.eq(0).attr("id", css.head).end()
				.eq(1).attr("id", css.body).children()
					.eq(0).attr("id", css.days).end()
					.eq(1).attr("id", css.weeks).end().end().end()
				.find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next);

			// title
			title = root.find("#" + css.head).find("div").attr("id", css.title);

			// year & month selectors
			if (conf.selectors) {
				var monthSelector = $("<select/>").attr("id", css.month),
					 yearSelector = $("<select/>").attr("id", css.year);
				title.html(monthSelector.add(yearSelector));
			}

			// day titles
			var days = root.find("#" + css.days);

			// days of the week
			for (var d = 0; d < 7; d++) {
				days.append($("<span/>").text(labels.shortDays[(d + conf.firstDay) % 7]));
			}

			$("body").append(root);
		}


		// trigger icon
		if (conf.trigger) {
			trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e)  {
				self.show();
				return e.preventDefault();
			}).insertAfter(input);
		}


		// layout elements
		var weeks = root.find("#" + css.weeks);
		yearSelector = root.find("#" + css.year);
		monthSelector = root.find("#" + css.month);


//{{{ pick

		function select(date, conf, e) {

			// current value
			value 	 = date;
			currYear  = date.getFullYear();
			currMonth = date.getMonth();
			currDay	 = date.getDate();


			// change
			e = e || $.Event("api");
			e.type = "change";

			fire.trigger(e, [date]);
			if (e.isDefaultPrevented()) { return; }

			// formatting
			input.val(format(date, conf.format, conf.lang));

			// store value into input
			input.data("date", date);

			self.hide(e);
		}
//}}}


//{{{ onShow

		function onShow(ev) {

			ev.type = "onShow";
			fire.trigger(ev);

			$(document).bind("keydown.d", function(e) {

				if (e.ctrlKey) { return true; }
				var key = e.keyCode;

				// backspace clears the value
				if (key == 8) {
					input.val("");
					return self.hide(e);
				}

				// esc key
				if (key == 27) { return self.hide(e); }

				if ($(KEYS).index(key) >= 0) {

					if (!opened) {
						self.show(e);
						return e.preventDefault();
					}

					var days = $("#" + css.weeks + " a"),
						 el = $("." + css.focus),
						 index = days.index(el);

					el.removeClass(css.focus);

					if (key == 74 || key == 40) { index += 7; }
					else if (key == 75 || key == 38) { index -= 7; }
					else if (key == 76 || key == 39) { index += 1; }
					else if (key == 72 || key == 37) { index -= 1; }


					if (index > 41) {
						 self.addMonth();
						 el = $("#" + css.weeks + " a:eq(" + (index-42) + ")");
					} else if (index < 0) {
						 self.addMonth(-1);
						 el = $("#" + css.weeks + " a:eq(" + (index+42) + ")");
					} else {
						 el = days.eq(index);
					}

					el.addClass(css.focus);
					return e.preventDefault();

				}

				// pageUp / pageDown
				if (key == 34) { return self.addMonth(); }
				if (key == 33) { return self.addMonth(-1); }

				// home
				if (key == 36) { return self.today(); }

				// enter
				if (key == 13) {
					if (!$(e.target).is("select")) {
						$("." + css.focus).click();
					}
				}

				return $([16, 17, 18, 9]).index(key) >= 0;
			});


			// click outside dateinput
			$(document).bind("click.d", function(e) {
				var el = e.target;

				if (!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
					self.hide(e);
				}

			});
		}
//}}}


		$.extend(self, {

//{{{  show

			show: function(e) {

				if (input.attr("readonly") || input.attr("disabled") || opened) { return; }

				// onBeforeShow
				e = e || $.Event();
				e.type = "onBeforeShow";
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return; }

				$.each(instances, function() {
					this.hide();
				});

				opened = true;

				// month selector
				monthSelector.unbind("change").change(function() {
					self.setValue(yearSelector.val(), $(this).val());
				});

				// year selector
				yearSelector.unbind("change").change(function() {
					self.setValue($(this).val(), monthSelector.val());
				});

				// prev / next month
				pm = root.find("#" + css.prev).unbind("click").click(function(e) {
					if (!pm.hasClass(css.disabled)) {
						self.addMonth(-1);
					}
					return false;
				});

				nm = root.find("#" + css.next).unbind("click").click(function(e) {
					if (!nm.hasClass(css.disabled)) {
						self.addMonth();
					}
					return false;
				});

				// set date
				self.setValue(value);

				// show calendar
				var pos = input.offset();

				// iPad position fix
				if (/iPad/i.test(navigator.userAgent)) {
					pos.top -= $(window).scrollTop();
				}

				root.css({
					top: pos.top + input.outerHeight({margins: true}) + conf.offset[0],
					left: pos.left + conf.offset[1]
				});

				if (conf.speed) {
					root.show(conf.speed, function() {
						onShow(e);
					});
				} else {
					root.show();
					onShow(e);
				}

				return self;
			},
//}}}


//{{{  setValue

			setValue: function(year, month, day)  {

				var date = integer(month) >= -1 ?
					new Date(integer(year), integer(month), integer(day || 1)) : year || value
				;

				if (date < min) { date = min; }
				else if (date > max) { date = max; }

				year = date.getFullYear();
				month = date.getMonth();
				day = date.getDate();


				// roll year & month
				if (month == -1) {
					month = 11;
					year--;
				} else if (month == 12) {
					month = 0;
					year++;
				}

				if (!opened) {
					select(date, conf);
					return self;
				}

				currMonth = month;
				currYear = year;

				// variables
				var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(),
					 days = dayAm(year, month),
					 prevDays = dayAm(year, month - 1),
					 week;

				// selectors
				if (conf.selectors) {

					// month selector
					monthSelector.empty();
					$.each(labels.months, function(i, m) {
						if (min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) {
							monthSelector.append($("<option/>").html(m).attr("value", i));
						}
					});

					// year selector
					yearSelector.empty();
					var yearNow = now.getFullYear();

					for (var i = yearNow + conf.yearRange[0];  i < yearNow + conf.yearRange[1]; i++) {
						if (min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) {
							yearSelector.append($("<option/>").text(i));
						}
					}

					monthSelector.val(month);
					yearSelector.val(year);

				// title
				} else {
					title.html(labels.months[month] + " " + year);
				}

				// populate weeks
				weeks.empty();
				pm.add(nm).removeClass(css.disabled);

				// !begin === "sunday"
				for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {

					a = $("<a/>");

					if (j % 7 === 0) {
						week = $("<div/>").addClass(css.week);
						weeks.append(week);
					}

					if (j < begin)  {
						a.addClass(css.off);
						num = prevDays - begin + j + 1;
						date = new Date(year, month-1, num);

					} else if (j >= begin + days)  {
						a.addClass(css.off);
						num = j - days - begin + 1;
						date = new Date(year, month+1, num);

					} else  {
						num = j - begin + 1;
						date = new Date(year, month, num);

						// current date
						if (isSameDay(value, date)) {
							a.attr("id", css.current).addClass(css.focus);

						// today
						} else if (isSameDay(now, date)) {
							a.attr("id", css.today);
						}
					}

					// disabled
					if (min && date < min) {
						a.add(pm).addClass(css.disabled);
					}

					if (max && date > max) {
						a.add(nm).addClass(css.disabled);
					}

					a.attr("href", "#" + num).text(num).data("date", date);

					week.append(a);
				}

				// date picking
				weeks.find("a").click(function(e) {
					var el = $(this);
					if (!el.hasClass(css.disabled)) {
						$("#" + css.current).removeAttr("id");
						el.attr("id", css.current);
						select(el.data("date"), conf, e);
					}
					return false;
				});

				// sunday
				if (css.sunday) {
					weeks.find(css.week).each(function() {
						var beg = conf.firstDay ? 7 - conf.firstDay : 0;
						$(this).children().slice(beg, beg + 1).addClass(css.sunday);
					});
				}

				return self;
			},
	//}}}

			setMin: function(val, fit) {
				min = parseDate(val);
				if (fit && value < min) { self.setValue(min); }
				return self;
			},

			setMax: function(val, fit) {
				max = parseDate(val);
				if (fit && value > max) { self.setValue(max); }
				return self;
			},

			today: function() {
				return self.setValue(now);
			},

			addDay: function(amount) {
				return this.setValue(currYear, currMonth, currDay + (amount || 1));
			},

			addMonth: function(amount) {
				return this.setValue(currYear, currMonth + (amount || 1), currDay);
			},

			addYear: function(amount) {
				return this.setValue(currYear + (amount || 1), currMonth, currDay);
			},

			hide: function(e) {

				if (opened) {

					// onHide
					e = $.Event();
					e.type = "onHide";
					fire.trigger(e);

					$(document).unbind("click.d").unbind("keydown.d");

					// cancelled ?
					if (e.isDefaultPrevented()) { return; }

					// do the hide
					root.hide();
					opened = false;
				}

				return self;
			},

			getConf: function() {
				return conf;
			},

			getInput: function() {
				return input;
			},

			getCalendar: function() {
				return root;
			},

			getValue: function(dateFormat) {
				return dateFormat ? format(value, dateFormat, conf.lang) : value;
			},

			isOpen: function() {
				return opened;
			}

		});

		// callbacks
		$.each(['onBeforeShow','onShow','change','onHide'], function(i, name) {

			// configuration
			if ($.isFunction(conf[name]))  {
				$(self).bind(name, conf[name]);
			}

			// API methods
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});


		// show dateinput & assign keyboard shortcuts
		input.bind("focus click", self.show).keydown(function(e) {

			var key = e.keyCode;

			// open dateinput with navigation keyw
			if (!opened &&  $(KEYS).index(key) >= 0) {
				self.show(e);
				return e.preventDefault();
			}

			// allow tab
			return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();

		});

		// initial value
		if (parseDate(input.val())) {
			select(value, conf);
		}

	}

	$.expr[':'].date = function(el) {
		var type = el.getAttribute("type");
		return type && type == 'date' || !!$(el).data("dateinput");
	};


	$.fn.dateinput = function(conf) {

		// already instantiated
		if (this.data("dateinput")) { return this; }

		// configuration
		conf = $.extend(true, {}, tool.conf, conf);

		// CSS prefix
		$.each(conf.css, function(key, val) {
			if (!val && key != 'prefix') {
				conf.css[key] = (conf.css.prefix || '') + (val || key);
			}
		});

		var els;

		this.each(function() {
			var el = new Dateinput($(this), conf);
			instances.push(el);
			var input = el.getInput().data("dateinput", el);
			els = els ? els.add(input) : input;
		});

		return els ? els : this;
	};


}) (jQuery);


/**
 * @license
 * jQuery Tools 1.2.5 Tabs- The basics of UI design.
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/tabs/
 *
 * Since: November 2008
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// static constructs
	$.tools = $.tools || {version: '1.2.5'};

	$.tools.tabs = {

		conf: {
			tabs: 'a',
			current: 'current',
			onBeforeClick: null,
			onClick: null,
			effect: 'default',
			initialIndex: 0,
			event: 'click',
			rotate: false,

			// 1.2
			history: false
		},

		addEffect: function(name, fn) {
			effects[name] = fn;
		}

	};

	var effects = {

		// simple "toggle" effect
		'default': function(i, done) {
			this.getPanes().hide().eq(i).show();
			done.call();
		},

		/*
			configuration:
				- fadeOutSpeed (positive value does "crossfading")
				- fadeInSpeed
		*/
		fade: function(i, done) {

			var conf = this.getConf(),
				 speed = conf.fadeOutSpeed,
				 panes = this.getPanes();

			if (speed) {
				panes.fadeOut(speed);
			} else {
				panes.hide();
			}

			panes.eq(i).fadeIn(conf.fadeInSpeed, done);
		},

		// for basic accordions
		slide: function(i, done) {
			this.getPanes().slideUp(200);
			this.getPanes().eq(i).slideDown(400, done);
		},

		/**
		 * AJAX effect
		 */
		ajax: function(i, done)  {
			this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);
		}
	};

	var w;

	/**
	 * Horizontal accordion
	 *
	 * @deprecated will be replaced with a more robust implementation
	 */
	$.tools.tabs.addEffect("horizontal", function(i, done) {

		// store original width of a pane into memory
		if (!w) { w = this.getPanes().eq(0).width(); }

		// set current pane's width to zero
		this.getCurrentPane().animate({width: 0}, function() { $(this).hide(); });

		// grow opened pane to it's original width
		this.getPanes().eq(i).animate({width: w}, function() {
			$(this).show();
			done.call();
		});

	});


	function Tabs(root, paneSelector, conf) {

		var self = this,
			 trigger = root.add(this),
			 tabs = root.find(conf.tabs),
			 panes = paneSelector.jquery ? paneSelector : root.children(paneSelector),
			 current;


		// make sure tabs and panes are found
		if (!tabs.length)  { tabs = root.children(); }
		if (!panes.length) { panes = root.parent().find(paneSelector); }
		if (!panes.length) { panes = $(paneSelector); }


		// public methods
		$.extend(this, {
			click: function(i, e) {

				var tab = tabs.eq(i);

				if (typeof i == 'string' && i.replace("#", "")) {
					tab = tabs.filter("[href*=" + i.replace("#", "") + "]");
					i = Math.max(tabs.index(tab), 0);
				}

				if (conf.rotate) {
					var last = tabs.length -1;
					if (i < 0) { return self.click(last, e); }
					if (i > last) { return self.click(0, e); }
				}

				if (!tab.length) {
					if (current >= 0) { return self; }
					i = conf.initialIndex;
					tab = tabs.eq(i);
				}

				// current tab is being clicked
				if (i === current) { return self; }

				// possibility to cancel click action
				e = e || $.Event();
				e.type = "onBeforeClick";
				trigger.trigger(e, [i]);
				if (e.isDefaultPrevented()) { return; }

				// call the effect
				effects[conf.effect].call(self, i, function() {

					// onClick callback
					e.type = "onClick";
					trigger.trigger(e, [i]);
				});

				// default behaviour
				current = i;
				tabs.removeClass(conf.current);
				tab.addClass(conf.current);

				return self;
			},

			getConf: function() {
				return conf;
			},

			getTabs: function() {
				return tabs;
			},

			getPanes: function() {
				return panes;
			},

			getCurrentPane: function() {
				return panes.eq(current);
			},

			getCurrentTab: function() {
				return tabs.eq(current);
			},

			getIndex: function() {
				return current;
			},

			next: function() {
				return self.click(current + 1);
			},

			prev: function() {
				return self.click(current - 1);
			},

			destroy: function() {
				tabs.unbind(conf.event).removeClass(conf.current);
				panes.find("a[href^=#]").unbind("click.T");
				return self;
			}

		});

		// callbacks
		$.each("onBeforeClick,onClick".split(","), function(i, name) {

			// configuration
			if ($.isFunction(conf[name])) {
				$(self).bind(name, conf[name]);
			}

			// API
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});


		if (conf.history && $.fn.history) {
			$.tools.history.init(tabs);
			conf.event = 'history';
		}

		// setup click actions for each tab
		tabs.each(function(i) {
			$(this).bind(conf.event, function(e) {
				self.click(i, e);
				return e.preventDefault();
			});
		});

		// cross tab anchor link
		panes.find("a[href^=#]").bind("click.T", function(e) {
			self.click($(this).attr("href"), e);
		});

		// open initial tab
		if (location.hash && conf.tabs == "a" && root.find("[href=" +location.hash+ "]").length) {
			self.click(location.hash);

		} else {
			if (conf.initialIndex === 0 || conf.initialIndex > 0) {
				self.click(conf.initialIndex);
			}
		}

	}


	// jQuery plugin implementation
	$.fn.tabs = function(paneSelector, conf) {

		// return existing instance
		var el = this.data("tabs");
		if (el) {
			el.destroy();
			this.removeData("tabs");
		}

		if ($.isFunction(conf)) {
			conf = {onBeforeClick: conf};
		}

		// setup conf
		conf = $.extend({}, $.tools.tabs.conf, conf);


		this.each(function() {
			el = new Tabs($(this), paneSelector, conf);
			$(this).data("tabs", el);
		});

		return conf.api ? el: this;
	};

}) (jQuery);


/**
 * @license
 * jQuery Tools 1.2.5 Slideshow - Extend it.
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/tabs/slideshow.html
 *
 * Since: September 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	var tool;

	tool = $.tools.tabs.slideshow = {

		conf: {
			next: '.forward',
			prev: '.backward',
			disabledClass: 'disabled',
			autoplay: false,
			autopause: true,
			interval: 3000,
			clickable: true,
			api: false
		}
	};

	function Slideshow(root, conf) {

		var self = this,
			 fire = root.add(this),
			 tabs = root.data("tabs"),
			 timer,
			 stopped = true;


		// next / prev buttons
		function find(query) {
			var el = $(query);
			return el.length < 2 ? el : root.parent().find(query);
		}

		var nextButton = find(conf.next).click(function() {
			tabs.next();
		});

		var prevButton = find(conf.prev).click(function() {
			tabs.prev();
		});


		// extend the Tabs API with slideshow methods
		$.extend(self, {

			// return tabs API
			getTabs: function() {
				return tabs;
			},

			getConf: function() {
				return conf;
			},

			play: function() {

				// do not start additional timer if already exists
				if (timer) { return self; }

				// onBeforePlay
				var e = $.Event("onBeforePlay");
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return self; }


				// construct new timer
				timer = setInterval(tabs.next, conf.interval);
				stopped = false;

				// onPlay
				fire.trigger("onPlay");

				return self;
			},

			pause: function() {

				if (!timer) { return self; }

				// onBeforePause
				var e = $.Event("onBeforePause");
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return self; }

				timer = clearInterval(timer);

				// onPause
				fire.trigger("onPause");

				return self;
			},

			// when stopped - mouseover won't restart
			stop: function() {
				self.pause();
				stopped = true;
			}

		});

		// callbacks
		$.each("onBeforePlay,onPlay,onBeforePause,onPause".split(","), function(i, name) {

			// configuration
			if ($.isFunction(conf[name]))  {
				$(self).bind(name, conf[name]);
			}

			// API methods
			self[name] = function(fn) {
				return $(self).bind(name, fn);
			};
		});


		/* when mouse enters, slideshow stops */
		if (conf.autopause) {
			tabs.getTabs().add(nextButton).add(prevButton).add(tabs.getPanes()).hover(self.pause, function() {
				if (!stopped) { self.play(); }
			});
		}

		if (conf.autoplay) {
			self.play();
		}

		if (conf.clickable) {
			tabs.getPanes().click(function()  {
				tabs.next();
			});
		}

		// manage disabling of next/prev buttons
		if (!tabs.getConf().rotate) {

			var disabled = conf.disabledClass;

			if (!tabs.getIndex()) {
				prevButton.addClass(disabled);
			}

			tabs.onBeforeClick(function(e, i)  {
				prevButton.toggleClass(disabled, !i);
				nextButton.toggleClass(disabled, i == tabs.getTabs().length -1);
			});
		}
	}

	// jQuery plugin implementation
	$.fn.slideshow = function(conf) {

		// return existing instance
		var el = this.data("slideshow");
		if (el) { return el; }

		conf = $.extend({}, tool.conf, conf);

		this.each(function() {
			el = new Slideshow($(this), conf);
			$(this).data("slideshow", el);
		});

		return conf.api ? el : this;
	};

})(jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 / Scrollable Navigator
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/scrollable/navigator.html
 *
 * Since: September 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	var t = $.tools.scrollable;

	t.navigator = {

		conf: {
			navi: '.navi',
			naviItem: null,
			activeClass: 'active',
			indexed: false,
			idPrefix: null,

			// 1.2
			history: false
		}
	};

	function find(root, query) {
		var el = $(query);
		return el.length < 2 ? el : root.parent().find(query);
	}

	// jQuery plugin implementation
	$.fn.navigator = function(conf) {

		// configuration
		if (typeof conf == 'string') { conf = {navi: conf}; }
		conf = $.extend({}, t.navigator.conf, conf);

		var ret;

		this.each(function() {

			var api = $(this).data("scrollable"),
				 navi = conf.navi.jquery ? conf.navi : find(api.getRoot(), conf.navi),
				 buttons = api.getNaviButtons(),
				 cls = conf.activeClass,
				 history = conf.history && $.fn.history;

			// @deprecated stuff
			if (api) { ret = api; }

			api.getNaviButtons = function() {
				return buttons.add(navi);
			};


			function doClick(el, i, e) {
				api.seekTo(i);
				if (history) {
					if (location.hash) {
						location.hash = el.attr("href").replace("#", "");
					}
				} else  {
					return e.preventDefault();
				}
			}

			function els() {
				return navi.find(conf.naviItem || '> *');
			}

			function addItem(i) {

				var item = $("<" + (conf.naviItem || 'a') + "/>").click(function(e)  {
					doClick($(this), i, e);

				}).attr("href", "#" + i);

				// index number / id attribute
				if (i === 0) {  item.addClass(cls); }
				if (conf.indexed)  { item.text(i + 1); }
				if (conf.idPrefix) { item.attr("id", conf.idPrefix + i); }

				return item.appendTo(navi);
			}


			// generate navigator
			if (els().length) {
				els().each(function(i) {
					$(this).click(function(e)  {
						doClick($(this), i, e);
					});
				});

			} else {
				$.each(api.getItems(), function(i) {
					addItem(i);
				});
			}

			// activate correct entry
			api.onBeforeSeek(function(e, index) {
				setTimeout(function() {
					if (!e.isDefaultPrevented()) {
						var el = els().eq(index);
						if (!e.isDefaultPrevented() && el.length) {
							els().removeClass(cls).eq(index).addClass(cls);
						}
					}
				}, 1);
			});

			function doHistory(evt, hash) {
				var el = els().eq(hash.replace("#", ""));
				if (!el.length) {
					el = els().filter("[href=" + hash + "]");
				}
				el.click();
			}

			// new item being added
			api.onAddItem(function(e, item) {
				item = addItem(api.getItems().index(item));
				if (history)  { item.history(doHistory); }
			});

			if (history) { els().history(doHistory); }

		});

		return conf.api ? ret : this;

	};

})(jQuery);
/**
 * @license
 * jQuery Tools 1.2.5 Scrollable - New wave UI design
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/scrollable.html
 *
 * Since: March 2008
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// static constructs
	$.tools = $.tools || {version: '1.2.5'};

	$.tools.scrollable = {

		conf: {
			activeClass: 'active',
			circular: false,
			clonedClass: 'cloned',
			disabledClass: 'disabled',
			easing: 'swing',
			initialIndex: 0,
			item: null,
			items: '.items',
			keyboard: true,
			mousewheel: false,
			next: '.next',
			prev: '.prev',
			speed: 400,
			vertical: false,
			touch: true,
			wheelSpeed: 0
		}
	};

	// get hidden element's width or height even though it's hidden
	function dim(el, key) {
		var v = parseInt(el.css(key), 10);
		if (v) { return v; }
		var s = el[0].currentStyle;
		return s && s.width && parseInt(s.width, 10);
	}

	function find(root, query) {
		var el = $(query);
		return el.length < 2 ? el : root.parent().find(query);
	}

	var current;

	// constructor
	function Scrollable(root, conf) {

		// current instance
		var self = this,
			 fire = root.add(self),
			 itemWrap = root.children(),
			 index = 0,
			 vertical = conf.vertical;

		if (!current) { current = self; }
		if (itemWrap.length > 1) { itemWrap = $(conf.items, root); }

		// methods
		$.extend(self, {

			getConf: function() {
				return conf;
			},

			getIndex: function() {
				return index;
			},

			getSize: function() {
				return self.getItems().size();
			},

			getNaviButtons: function() {
				return prev.add(next);
			},

			getRoot: function() {
				return root;
			},

			getItemWrap: function() {
				return itemWrap;
			},

			getItems: function() {
				return itemWrap.children(conf.item).not("." + conf.clonedClass);
			},

			move: function(offset, time) {
				return self.seekTo(index + offset, time);
			},

			next: function(time) {
				return self.move(1, time);
			},

			prev: function(time) {
				return self.move(-1, time);
			},

			begin: function(time) {
				return self.seekTo(0, time);
			},

			end: function(time) {
				return self.seekTo(self.getSize() -1, time);
			},

			focus: function() {
				current = self;
				return self;
			},

			addItem: function(item) {
				item = $(item);

				if (!conf.circular)  {
					itemWrap.append(item);
				} else {
					itemWrap.children("." + conf.clonedClass + ":last").before(item);
					itemWrap.children("." + conf.clonedClass + ":first").replaceWith(item.clone().addClass(conf.clonedClass));
				}

				fire.trigger("onAddItem", [item]);
				return self;
			},


			/* all seeking functions depend on this */
			seekTo: function(i, time, fn) {

				// ensure numeric index
				if (!i.jquery) { i *= 1; }

				// avoid seeking from end clone to the beginning
				if (conf.circular && i === 0 && index == -1 && time !== 0) { return self; }

				// check that index is sane
				if (!conf.circular && i < 0 || i > self.getSize() || i < -1) { return self; }

				var item = i;

				if (i.jquery) {
					i = self.getItems().index(i);

				} else {
					item = self.getItems().eq(i);
				}

				// onBeforeSeek
				var e = $.Event("onBeforeSeek");
				if (!fn) {
					fire.trigger(e, [i, time]);
					if (e.isDefaultPrevented() || !item.length) { return self; }
				}

				var props = vertical ? {top: -item.position().top} : {left: -item.position().left};

				index = i;
				current = self;
				if (time === undefined) { time = conf.speed; }

				itemWrap.animate(props, time, conf.easing, fn || function() {
					fire.trigger("onSeek", [i]);
				});

				return self;
			}

		});

		// callbacks
		$.each(['onBeforeSeek', 'onSeek', 'onAddItem'], function(i, name) {

			// configuration
			if ($.isFunction(conf[name])) {
				$(self).bind(name, conf[name]);
			}

			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});

		// circular loop
		if (conf.circular) {

			var cloned1 = self.getItems().slice(-1).clone().prependTo(itemWrap),
				 cloned2 = self.getItems().eq(1).clone().appendTo(itemWrap);

			cloned1.add(cloned2).addClass(conf.clonedClass);

			self.onBeforeSeek(function(e, i, time) {


				if (e.isDefaultPrevented()) { return; }

				/*
					1. animate to the clone without event triggering
					2. seek to correct position with 0 speed
				*/
				if (i == -1) {
					self.seekTo(cloned1, time, function()  {
						self.end(0);
					});
					return e.preventDefault();

				} else if (i == self.getSize()) {
					self.seekTo(cloned2, time, function()  {
						self.begin(0);
					});
				}

			});

			// seek over the cloned item
			self.seekTo(0, 0, function() {});
		}

		// next/prev buttons
		var prev = find(root, conf.prev).click(function() { self.prev(); }),
			 next = find(root, conf.next).click(function() { self.next(); });

		if (!conf.circular && self.getSize() > 1) {

			self.onBeforeSeek(function(e, i) {
				setTimeout(function() {
					if (!e.isDefaultPrevented()) {
						prev.toggleClass(conf.disabledClass, i <= 0);
						next.toggleClass(conf.disabledClass, i >= self.getSize() -1);
					}
				}, 1);
			});

			if (!conf.initialIndex) {
				prev.addClass(conf.disabledClass);
			}
		}

		// mousewheel support
		if (conf.mousewheel && $.fn.mousewheel) {
			root.mousewheel(function(e, delta)  {
				if (conf.mousewheel) {
					self.move(delta < 0 ? 1 : -1, conf.wheelSpeed || 50);
					return false;
				}
			});
		}

		// touch event
		if (conf.touch) {
			var touch = {};

			itemWrap[0].ontouchstart = function(e) {
				var t = e.touches[0];
				touch.x = t.clientX;
				touch.y = t.clientY;
			};

			itemWrap[0].ontouchmove = function(e) {

				// only deal with one finger
				if (e.touches.length == 1 && !itemWrap.is(":animated")) {
					var t = e.touches[0],
						 deltaX = touch.x - t.clientX,
						 deltaY = touch.y - t.clientY;

					self[vertical && deltaY > 0 || !vertical && deltaX > 0 ? 'next' : 'prev']();
					e.preventDefault();
				}
			};
		}

		if (conf.keyboard)  {

			$(document).bind("keydown.scrollable", function(evt) {

				// skip certain conditions
				if (!conf.keyboard || evt.altKey || evt.ctrlKey || $(evt.target).is(":input")) { return; }

				// does this instance have focus?
				if (conf.keyboard != 'static' && current != self) { return; }

				var key = evt.keyCode;

				if (vertical && (key == 38 || key == 40)) {
					self.move(key == 38 ? -1 : 1);
					return evt.preventDefault();
				}

				if (!vertical && (key == 37 || key == 39)) {
					self.move(key == 37 ? -1 : 1);
					return evt.preventDefault();
				}

			});
		}

		// initial index
		if (conf.initialIndex) {
			self.seekTo(conf.initialIndex, 0, function() {});
		}
	}


	// jQuery plugin implementation
	$.fn.scrollable = function(conf) {

		// already constructed --> return API
		var el = this.data("scrollable");
		if (el) { return el; }

		conf = $.extend({}, $.tools.scrollable.conf, conf);

		this.each(function() {
			el = new Scrollable($(this), conf);
			$(this).data("scrollable", el);
		});

		return conf.api ? el: this;

	};


})(jQuery);
/**
 * @license
 * jQuery Tools 1.2.5 / Scrollable Autoscroll
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/scrollable/autoscroll.html
 *
 * Since: September 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	var t = $.tools.scrollable;

	t.autoscroll = {

		conf: {
			autoplay: true,
			interval: 3000,
			autopause: true
		}
	};

	// jQuery plugin implementation
	$.fn.autoscroll = function(conf) {

		if (typeof conf == 'number') {
			conf = {interval: conf};
		}

		var opts = $.extend({}, t.autoscroll.conf, conf), ret;

		this.each(function() {

			var api = $(this).data("scrollable");
			if (api) { ret = api; }

			// interval stuff
			var timer, stopped = true;

			api.play = function() {

				// do not start additional timer if already exists
				if (timer) { return; }

				stopped = false;

				// construct new timer
				timer = setInterval(function() {
					api.next();
				}, opts.interval);

			};

			api.pause = function() {
				timer = clearInterval(timer);
			};

			// when stopped - mouseover won't restart
			api.stop = function() {
				api.pause();
				stopped = true;
			};

			/* when mouse enters, autoscroll stops */
			if (opts.autopause) {
				api.getRoot().add(api.getNaviButtons()).hover(api.pause, api.play);
			}

			if (opts.autoplay) {
				api.play();
			}

		});

		return opts.api ? ret : this;

	};

})(jQuery);
/**
 * @license
 * jQuery Tools Validator 1.2.5 - HTML5 is here. Now use it.
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/form/validator/
 *
 * Since: Mar 2010
 * Date: Thu May 15 10:43:37 CEST 2014
 */
/*jslint evil: true */
(function($) {

	$.tools = $.tools || {version: '1.2.5'};

	// globals
	var typeRe = /\[type=([a-z]+)\]/,
		numRe = /^-?[0-9]*(\.[0-9]+)?$/,
		dateInput = $.tools.dateinput,

		// http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/
		emailRe = /^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i,
		urlRe = /^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i,
		v;

	v = $.tools.validator = {

		conf: {
			grouped: false, 				// show all error messages at once inside the container
			effect: 'default',			// show/hide effect for error message. only 'default' is built-in
			errorClass: 'invalid',		// input field class name in case of validation error

			// when to check for validity?
			inputEvent: null,				// change, blur, keyup, null
			errorInputEvent: 'keyup',  // change, blur, keyup, null
			formEvent: 'submit',       // submit, null

			lang: 'en',						// default language for error messages
			message: '<div/>',
			messageAttr: 'data-message', // name of the attribute for overridden error message
			messageClass: 'error',		// error message element's class name
			offset: [0, 0],
			position: 'center right',
			singleError: false, 			// validate all inputs at once
			speed: 'normal'				// message's fade-in speed
		},


		/* The Error Messages */
		messages: {
			"*": { en: "Please correct this value" }
		},

		localize: function(lang, messages) {
			$.each(messages, function(key, msg)  {
				v.messages[key] = v.messages[key] || {};
				v.messages[key][lang] = msg;
			});
		},

		localizeFn: function(key, messages) {
			v.messages[key] = v.messages[key] || {};
			$.extend(v.messages[key], messages);
		},

		/**
		 * Adds a new validator
		 */
		fn: function(matcher, msg, fn) {

			// no message supplied
			if ($.isFunction(msg)) {
				fn = msg;

			// message(s) on second argument
			} else {
				if (typeof msg == 'string') { msg = {en: msg}; }
				this.messages[matcher.key || matcher] = msg;
			}

			// check for "[type=xxx]" (not supported by jQuery)
			var test = typeRe.exec(matcher);
			if (test) { matcher = isType(test[1]); }

			// add validator to the arsenal
			fns.push([matcher, fn]);
		},

		/* Add new show/hide effect */
		addEffect: function(name, showFn, closeFn) {
			effects[name] = [showFn, closeFn];
		}

	};

	/* calculate error message position relative to the input */
	function getPosition(trigger, el, conf) {

		// get origin top/left position
		var top = trigger.offset().top,
			 left = trigger.offset().left,
			 pos = conf.position.split(/,?\s+/),
			 y = pos[0],
			 x = pos[1];

		top  -= el.outerHeight() - conf.offset[0];
		left += trigger.outerWidth() + conf.offset[1];


		// iPad position fix
		if (/iPad/i.test(navigator.userAgent)) {
			top -= $(window).scrollTop();
		}

		// adjust Y
		var height = el.outerHeight() + trigger.outerHeight();
		if (y == 'center') 	{ top += height / 2; }
		if (y == 'bottom') 	{ top += height; }

		// adjust X
		var width = trigger.outerWidth();
		if (x == 'center') 	{ left -= (width  + el.outerWidth()) / 2; }
		if (x == 'left')  	{ left -= width; }

		return {top: top, left: left};
	}



	// $.is("[type=xxx]") or $.filter("[type=xxx]") not working in jQuery 1.3.2 or 1.4.2
	function isType(type) {
		function fn() {
			return this.getAttribute("type") == type;
		}
		fn.key = "[type=" + type + "]";
		return fn;
	}


	var fns = [], effects = {

		'default' : [

			// show errors function
			function(errs) {

				var conf = this.getConf();

				// loop errors
				$.each(errs, function(i, err) {

					// add error class
					var input = err.input;
					input.addClass(conf.errorClass);

					// get handle to the error container
					var msg = input.data("msg.el");

					// create it if not present
					if (!msg) {
						msg = $(conf.message).addClass(conf.messageClass).appendTo(document.body);
						input.data("msg.el", msg);
					}

					// clear the container
					msg.css({visibility: 'hidden'}).find("p").remove();

					// populate messages
					$.each(err.messages, function(i, m) {
						$("<p/>").html(m).appendTo(msg);
					});

					// make sure the width is not full body width so it can be positioned correctly
					if (msg.outerWidth() == msg.parent().width()) {
						msg.add(msg.find("p")).css({display: 'inline'});
					}

					// insert into correct position (relative to the field)
					var pos = getPosition(input, msg, conf);

					msg.css({ visibility: 'visible', position: 'absolute', top: pos.top, left: pos.left })
						.fadeIn(conf.speed);
				});


			// hide errors function
			}, function(inputs) {

				var conf = this.getConf();
				inputs.removeClass(conf.errorClass).each(function() {
					var msg = $(this).data("msg.el");
					if (msg) { msg.css({visibility: 'hidden'}); }
				});
			}
		]
	};


	/* sperial selectors */
	$.each("email,url,number".split(","), function(i, key) {
		$.expr[':'][key] = function(el) {
			return el.getAttribute("type") === key;
		};
	});


	/*
		oninvalid() jQuery plugin.
		Usage: $("input:eq(2)").oninvalid(function() { ... });
	*/
	$.fn.oninvalid = function( fn ){
		return this[fn ? "bind" : "trigger"]("OI", fn);
	};


	/******* built-in HTML5 standard validators *********/

	v.fn(":email", "Please enter a valid email address", function(el, v) {
		return !v || emailRe.test(v);
	});

	v.fn(":url", "Please enter a valid URL", function(el, v) {
		return !v || urlRe.test(v);
	});

	v.fn(":number", "Please enter a numeric value.", function(el, v) {
		return numRe.test(v);
	});

	v.fn("[max]", "Please enter a value smaller than $1", function(el, v) {

		// skip empty values and dateinputs
		if (v === '' || dateInput && el.is(":date")) { return true; }

		var max = el.attr("max");
		return parseFloat(v) <= parseFloat(max) ? true : [max];
	});

	v.fn("[min]", "Please enter a value larger than $1", function(el, v) {

		// skip empty values and dateinputs
		if (v === '' || dateInput && el.is(":date")) { return true; }

		var min = el.attr("min");
		return parseFloat(v) >= parseFloat(min) ? true : [min];
	});

	v.fn("[required]", "Please complete this mandatory field.", function(el, v) {
		if (el.is(":checkbox")) { return el.is(":checked"); }
		return !!v;
	});

	v.fn("[pattern]", function(el) {
		var p = new RegExp("^" + el.attr("pattern") + "$");
		return p.test(el.val());
	});


	function Validator(inputs, form, conf) {

		// private variables
		var self = this,
			 fire = form.add(self);

		// make sure there are input fields available
		inputs = inputs.not(":button, :image, :reset, :submit");

		// utility function
		function pushMessage(to, matcher, returnValue) {

			// only one message allowed
			if (!conf.grouped && to.length) { return; }

			// the error message
			var msg;

			// substitutions are returned
			if (returnValue === false || $.isArray(returnValue)) {
				msg = v.messages[matcher.key || matcher] || v.messages["*"];
				msg = msg[conf.lang] || v.messages["*"].en;

				// substitution
				var matches = msg.match(/\$\d/g);

				if (matches && $.isArray(returnValue)) {
					$.each(matches, function(i) {
						msg = msg.replace(this, returnValue[i]);
					});
				}

			// error message is returned directly
			} else {
				msg = returnValue[conf.lang] || returnValue;
			}

			to.push(msg);
		}


		// API methods
		$.extend(self, {

			getConf: function() {
				return conf;
			},

			getForm: function() {
				return form;
			},

			getInputs: function() {
				return inputs;
			},

			reflow: function() {
				inputs.each(function()  {
					var input = $(this),
						 msg = input.data("msg.el");

					if (msg) {
						var pos = getPosition(input, msg, conf);
						msg.css({ top: pos.top, left: pos.left });
					}
				});
				return self;
			},

			/* @param e - for internal use only */
			invalidate: function(errs, e) {

				// errors are given manually: { fieldName1: 'message1', fieldName2: 'message2' }
				if (!e) {
					var errors = [];
					$.each(errs, function(key, val) {
						var input = inputs.filter("[name='" + key + "']");
						if (input.length) {

							// trigger HTML5 ininvalid event
							input.trigger("OI", [val]);

							errors.push({ input: input, messages: [val]});
						}
					});

				  	errs = errors;
					e = $.Event();
				}

				// onFail callback
				e.type = "onFail";
				fire.trigger(e, [errs]);

				// call the effect
				if (!e.isDefaultPrevented()) {
					effects[conf.effect][0].call(self, errs, e);
				}

				return self;
			},

			reset: function(els) {
				els = els || inputs;
				els.removeClass(conf.errorClass).each(function()  {
					var msg = $(this).data("msg.el");
					if (msg) {
						msg.remove();
						$(this).data("msg.el", null);
					}
				}).unbind(conf.errorInputEvent || '');
				return self;
			},

			destroy: function() {
				form.unbind(conf.formEvent + ".V").unbind("reset.V");
				inputs.unbind(conf.inputEvent + ".V").unbind("change.V");
				return self.reset();
			},


//{{{  checkValidity() - flesh and bone of this tool

			/* @returns boolean */
			checkValidity: function(els, e) {

				els = els || inputs;
				els = els.not(":disabled");
				if (!els.length) { return true; }

				e = e || $.Event();

				// onBeforeValidate
				e.type = "onBeforeValidate";
				fire.trigger(e, [els]);
				if (e.isDefaultPrevented()) { return e.result; }

				// container for errors
				var errs = [];

				// loop trough the inputs
				els.not(":radio:not(:checked)").each(function() {

					// field and it's error message container
					var msgs = [],
						 el = $(this).data("messages", msgs),
						 event = dateInput && el.is(":date") ? "onHide.v" : conf.errorInputEvent + ".v";

					// cleanup previous validation event
					el.unbind(event);


					// loop all validator functions
					$.each(fns, function() {
						var fn = this, match = fn[0];

						// match found
						if (el.filter(match).length)  {

							// execute a validator function
							var returnValue = fn[1].call(self, el, el.val());


							// validation failed. multiple substitutions can be returned with an array
							if (returnValue !== true) {

								// onBeforeFail
								e.type = "onBeforeFail";
								fire.trigger(e, [el, match]);
								if (e.isDefaultPrevented()) { return false; }

								// overridden custom message
								var msg = el.attr(conf.messageAttr);
								if (msg) {
									msgs = [msg];
									return false;
								} else {
									pushMessage(msgs, match, returnValue);
								}
							}
						}
					});

					if (msgs.length) {

						errs.push({input: el, messages: msgs});

						// trigger HTML5 ininvalid event
						el.trigger("OI", [msgs]);

						// begin validating upon error event type (such as keyup)
						if (conf.errorInputEvent) {
							el.bind(event, function(e) {
								self.checkValidity(el, e);
							});
						}
					}

					if (conf.singleError && errs.length) { return false; }

				});


				// validation done. now check that we have a proper effect at hand
				var eff = effects[conf.effect];
				if (!eff) { throw "Validator: cannot find effect \"" + conf.effect + "\""; }

				// errors found
				if (errs.length) {
					self.invalidate(errs, e);
					return false;

				// no errors
				} else {

					// call the effect
					eff[1].call(self, els, e);

					// onSuccess callback
					e.type = "onSuccess";
					fire.trigger(e, [els]);

					els.unbind(conf.errorInputEvent + ".v");
				}

				return true;
			}
//}}}

		});

		// callbacks
		$.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","), function(i, name) {

			// configuration
			if ($.isFunction(conf[name]))  {
				$(self).bind(name, conf[name]);
			}

			// API methods
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});


		// form validation
		if (conf.formEvent) {
			form.bind(conf.formEvent + ".V", function(e) {
				if (!self.checkValidity(null, e)) {
					return e.preventDefault();
				}
			});
		}

		// form reset
		form.bind("reset.V", function()  {
			self.reset();
		});

		// disable browser's default validation mechanism
		if (inputs[0] && inputs[0].validity) {
			inputs.each(function()  {
				this.oninvalid = function() {
					return false;
				};
			});
		}

		// Web Forms 2.0 compatibility
		if (form[0]) {
			form[0].checkValidity = self.checkValidity;
		}

		// input validation
		if (conf.inputEvent) {
			inputs.bind(conf.inputEvent + ".V", function(e) {
				self.checkValidity($(this), e);
			});
		}

		// checkboxes, selects and radios are checked separately
		inputs.filter(":checkbox, select").filter("[required]").bind("change.V", function(e) {
			var el = $(this);
			if (this.checked || (el.is("select") && $(this).val())) {
				effects[conf.effect][1].call(self, el, e);
			}
		});

		var radios = inputs.filter(":radio").change(function(e) {
			self.checkValidity(radios, e);
		});

		// reposition tooltips when window is resized
		$(window).resize(function() {
			self.reflow();
		});
	}


	// jQuery plugin initialization
	$.fn.validator = function(conf) {

		var instance = this.data("validator");

		// destroy existing instance
		if (instance) {
			instance.destroy();
			this.removeData("validator");
		}

		// configuration
		conf = $.extend(true, {}, v.conf, conf);

		// selector is a form
		if (this.is("form")) {
			return this.each(function() {
				var form = $(this);
				instance = new Validator(form.find(":input"), form, conf);
				form.data("validator", instance);
			});

		} else {
			instance = new Validator(this, this.eq(0).closest("form"), conf);
			return this.data("validator", instance);
		}

	};

})(jQuery);


/**
 * @license
 * jQuery Tools 1.2.5 Overlay - Overlay base. Extend it.
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/overlay/
 *
 * Since: March 2008
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// static constructs
	$.tools = $.tools || {version: '1.2.5'};

	$.tools.overlay = {

		addEffect: function(name, loadFn, closeFn) {
			effects[name] = [loadFn, closeFn];
		},

		conf: {
			close: null,
			closeOnClick: true,
			closeOnEsc: true,
			closeSpeed: 'fast',
			effect: 'default',

			// since 1.2. fixed positioning not supported by IE6
			fixed: !$.browser.msie || $.browser.version > 6,

			left: 'center',
			load: false, // 1.2
			mask: null,
			oneInstance: true,
			speed: 'normal',
			target: null, // target element to be overlayed. by default taken from [rel]
			top: '10%'
		}
	};


	var instances = [], effects = {};

	// the default effect. nice and easy!
	$.tools.overlay.addEffect('default',

		/*
			onLoad/onClose functions must be called otherwise none of the
			user supplied callback methods won't be called
		*/
		function(pos, onLoad) {

			var conf = this.getConf(),
				 w = $(window);

			if (!conf.fixed)  {
				pos.top += w.scrollTop();
				pos.left += w.scrollLeft();
			}

			pos.position = conf.fixed ? 'fixed' : 'absolute';
			this.getOverlay().css(pos).fadeIn(conf.speed, onLoad);

		}, function(onClose) {
			this.getOverlay().fadeOut(this.getConf().closeSpeed, onClose);
		}
	);


	function Overlay(trigger, conf) {

		// private variables
		var self = this,
			 fire = trigger.add(self),
			 w = $(window),
			 closers,
			 overlay,
			 opened,
			 maskConf = $.tools.expose && (conf.mask || conf.expose),
			 uid = Math.random().toString().slice(10);


		// mask configuration
		if (maskConf) {
			if (typeof maskConf == 'string') { maskConf = {color: maskConf}; }
			maskConf.closeOnClick = maskConf.closeOnEsc = false;
		}

		// get overlay and triggerr
		var jq = conf.target || trigger.attr("rel");
		overlay = jq ? $(jq) : null || trigger;

		// overlay not found. cannot continue
		if (!overlay.length) { throw "Could not find Overlay: " + jq; }

		// trigger's click event
		if (trigger && trigger.index(overlay) == -1) {
			trigger.click(function(e) {
				self.load(e);
				return e.preventDefault();
			});
		}

		// API methods
		$.extend(self, {

			load: function(e) {

				// can be opened only once
				if (self.isOpened()) { return self; }

				// find the effect
		 		var eff = effects[conf.effect];
		 		if (!eff) { throw "Overlay: cannot find effect : \"" + conf.effect + "\""; }

				// close other instances?
				if (conf.oneInstance) {
					$.each(instances, function() {
						this.close(e);
					});
				}

				// onBeforeLoad
				e = e || $.Event();
				e.type = "onBeforeLoad";
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return self; }

				// opened
				opened = true;

				// possible mask effect
				if (maskConf) { $(overlay).expose(maskConf); }

				// position & dimensions
				var top = conf.top,
					 left = conf.left,
					 oWidth = overlay.outerWidth({margin:true}),
					 oHeight = overlay.outerHeight({margin:true});

				if (typeof top == 'string')  {
					top = top == 'center' ? Math.max((w.height() - oHeight) / 2, 0) :
						parseInt(top, 10) / 100 * w.height();
				}

				if (left == 'center') { left = Math.max((w.width() - oWidth) / 2, 0); }


		 		// load effect
				eff[0].call(self, {top: top, left: left}, function() {
					if (opened) {
						e.type = "onLoad";
						fire.trigger(e);
					}
				});

				// mask.click closes overlay
				if (maskConf && conf.closeOnClick) {
					$.mask.getMask().one("click", self.close);
				}

				// when window is clicked outside overlay, we close
				if (conf.closeOnClick) {
					$(document).bind("click." + uid, function(e) {
						if (!$(e.target).parents(overlay).length) {
							self.close(e);
						}
					});
				}

				// keyboard::escape
				if (conf.closeOnEsc) {

					// one callback is enough if multiple instances are loaded simultaneously
					$(document).bind("keydown." + uid, function(e) {
						if (e.keyCode == 27) {
							self.close(e);
						}
					});
				}


				return self;
			},

			close: function(e) {

				if (!self.isOpened()) { return self; }

				e = e || $.Event();
				e.type = "onBeforeClose";
				fire.trigger(e);
				if (e.isDefaultPrevented()) { return; }

				opened = false;

				// close effect
				effects[conf.effect][1].call(self, function() {
					e.type = "onClose";
					fire.trigger(e);
				});

				// unbind the keyboard / clicking actions
				$(document).unbind("click." + uid).unbind("keydown." + uid);

				if (maskConf) {
					$.mask.close();
				}

				return self;
			},

			getOverlay: function() {
				return overlay;
			},

			getTrigger: function() {
				return trigger;
			},

			getClosers: function() {
				return closers;
			},

			isOpened: function()  {
				return opened;
			},

			// manipulate start, finish and speeds
			getConf: function() {
				return conf;
			}

		});

		// callbacks
		$.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","), function(i, name) {

			// configuration
			if ($.isFunction(conf[name])) {
				$(self).bind(name, conf[name]);
			}

			// API
			self[name] = function(fn) {
				if (fn) { $(self).bind(name, fn); }
				return self;
			};
		});

		// close button
		closers = overlay.find(conf.close || ".close");

		if (!closers.length && !conf.close) {
			closers = $('<a class="close"></a>');
			overlay.prepend(closers);
		}

		closers.click(function(e) {
			self.close(e);
		});

		// autoload
		if (conf.load) { self.load(); }

	}

	// jQuery plugin initialization
	$.fn.overlay = function(conf) {

		// already constructed --> return API
		var el = this.data("overlay");
		if (el) { return el; }

		if ($.isFunction(conf)) {
			conf = {onBeforeLoad: conf};
		}

		conf = $.extend(true, {}, $.tools.overlay.conf, conf);

		this.each(function() {
			el = new Overlay($(this), conf);
			instances.push(el);
			$(this).data("overlay", el);
		});

		return conf.api ? el: this;
	};

})(jQuery);

/**
 * @license
 * jQuery Tools 1.2.5 / Overlay Apple effect.
 *
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 *
 * http://flowplayer.org/tools/overlay/apple.html
 *
 * Since: July 2009
 * Date: Thu May 15 10:43:37 CEST 2014
 */
(function($) {

	// version number
	var t = $.tools.overlay,
		 w = $(window);

	// extend global configuragion with effect specific defaults
	$.extend(t.conf, {
		start: {
			top: null,
			left: null
		},

		fadeInSpeed: 'fast',
		zIndex: 9999
	});

	// utility function
	function getPosition(el) {
		var p = el.offset();
		return {
			top: p.top + el.height() / 2,
			left: p.left + el.width() / 2
		};
	}

//{{{ load

	var loadEffect = function(pos, onLoad) {

		var overlay = this.getOverlay(),
			 conf = this.getConf(),
			 trigger = this.getTrigger(),
			 self = this,
			 oWidth = overlay.outerWidth({margin:true}),
			 img = overlay.data("img"),
			 position = conf.fixed ? 'fixed' : 'absolute';


		// growing image is required.
		if (!img) {
			var bg = overlay.css("backgroundImage");

			if (!bg) {
				throw "background-image CSS property not set for overlay";
			}

			// url("bg.jpg") --> bg.jpg
			bg = bg.slice(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, "");
			overlay.css("backgroundImage", "none");

			img = $('<img src="' + bg + '"/>');
			img.css({border:0, display:'none'}).width(oWidth);
			$('body').append(img);
			overlay.data("img", img);
		}

		// initial top & left
		var itop = conf.start.top || Math.round(w.height() / 2),
			 ileft = conf.start.left || Math.round(w.width() / 2);

		if (trigger) {
			var p = getPosition(trigger);
			itop = p.top;
			ileft = p.left;
		}

		// put overlay into final position
		if (conf.fixed) {
			itop -= w.scrollTop();
			ileft -= w.scrollLeft();
		} else {
			pos.top += w.scrollTop();
			pos.left += w.scrollLeft();
		}

		// initialize background image and make it visible
		img.css({
			position: 'absolute',
			top: itop,
			left: ileft,
			width: 0,
			zIndex: conf.zIndex
		}).show();

		pos.position = position;
		overlay.css(pos);

		// begin growing
		img.animate({
			top: overlay.css("top"),
			left: overlay.css("left"),
			width: oWidth}, conf.speed, function() {

			// set close button and content over the image
			overlay.css("zIndex", conf.zIndex + 1).fadeIn(conf.fadeInSpeed, function()  {

				if (self.isOpened() && !$(this).index(overlay)) {
					onLoad.call();
				} else {
					overlay.hide();
				}
			});

		}).css("position", position);

	};
//}}}


	var closeEffect = function(onClose) {

		// variables
		var overlay = this.getOverlay().hide(),
			 conf = this.getConf(),
			 trigger = this.getTrigger(),
			 img = overlay.data("img"),

			 css = {
			 	top: conf.start.top,
			 	left: conf.start.left,
			 	width: 0
			 };

		// trigger position
		if (trigger) { $.extend(css, getPosition(trigger)); }


		// change from fixed to absolute position
		if (conf.fixed) {
			img.css({position: 'absolute'})
				.animate({ top: "+=" + w.scrollTop(), left: "+=" + w.scrollLeft()}, 0);
		}

		// shrink image
		img.animate(css, conf.closeSpeed, onClose);
	};


	// add overlay effect
	t.addEffect("apple", loadEffect, closeEffect);

})(jQuery);