;

;(function ($) {

// Change global settings
$.ewyseGallery = {
	set: function(settings) {
		$.ewyseGallery.settings = $.extend(true, $.ewyseGallery.settings, settings);
	},
	
	$: {},
	
	// The global settings
	settings: {
		imgPath: 'images/gallery/',
		img: {
			close: 'close.png',
			overview: 'overview.gif',
			info: 'info.gif',
			loader: 'loader.gif',
			prev: 'previous.gif',
			next: 'next.gif',
			play: 'play.gif',
			pause: 'pause.gif',
			sep: 'sep.gif'
		},
		slideshowInterval: 3500,
		minWidth: 300,
		minHeight: 0,
		maxWidth: 900,
		maxHeight: 600,
		borderSpace: 0,
		autoMaxDimension: false, // If true, the max width and height will be calculated through the screen size on gallery show.
		fitImage: true,
		overlayBgColor: '#000',
		overlayOpacity:	0.5,
		cacheAjaxRequests: false,
		cache: {},
		flashparams: {
			version: [9,45], /* JW player needs at least this Flash version */
			width: 400, 
			height: 320
		},
		flashvars: {autostart: true}, 
		plugins: {
			flv: 'flash',
			swf: 'flash',
			youtube: 'flash'
		}
	},
	
	data: {},
	
	current: 0,
	
	show: false, // store whether we are showing ourselves.. good for async checks
	
	timer: false, // The timer is used for the slideshow
	
	_initInterface: function(options) {
		if (!this.$['gallery']) {
			function _img(name) {
				return $.ewyseGallery.settings.imgPath + $.ewyseGallery.settings.img[name];
			};
			this.options = $.extend({appendTo: 'body', showInContent: false}, options || {});
			
			$(this.options.appendTo).append(
				(this.options.showInContent ? '' : '<div id="egallery-overlay" title="close" style="display: none;"></div>') +
				'<div id="egallery" style="display: none;">' +
					'<div id="egallery-container">' +
						(this.options.showInContent ? '' : '<a id="egallery-close-link" href="javascript:void(0)"><img id="egallery-close" src="' + _img('close') + '" alt="Close"></a>') +
						'<div id="egallery-info"><span></span></div>' +
						'<div id="egallery-loading"><img src="' + _img('loader') + '"></div>' +
						'<div id="egallery-imageContainer"><img style="display: none;" id="egallery-image" alt="image"></div>' +
						'<div id="egallery-controls">' +
							'<table><tr><td>' +
								'<img class="egallery-sep" src="' + _img('sep') + '" alt="&nbsp;">' +
								'<img id="egallery-button-prev" src="' + _img('prev') + '" alt="Previous Image" title="Previous Image">' +
								'<img id="egallery-button-play" src="' + _img('play') + '" alt="Play Slideshow" title="Play Slideshow">' +
								'<img id="egallery-button-pause" style=\"display: none;\" src="' + _img('pause') + '" alt="Pause Slideshow" title="Pause Slideshow">' +
								'<img id="egallery-button-next" src="' + _img('next') + '" alt="Next Image" title="Next Image">' +
								'<img class="egallery-sep" src="' + _img('sep') + '" alt="&nbsp;">' +
								'<img id="egallery-button-overview" src="' + _img('overview') + '" alt="View thumbnails" title="View thumbnails">' +
								'<img class="egallery-sep" src="' + _img('sep') + '" alt="&nbsp;">' +
								'<img id="egallery-button-info" src="' + _img('info') + '" alt="Toggle Info" title="Toggle Info">' +
								'<img class="egallery-sep" src="' + _img('sep') + '" alt="&nbsp;">' +
							'</td></tr></table>' +
							'<div id="egallery-index"></div>' +
						'</div>' +
					'</div>' +
				'</div>'
			);
			
			if ($.ifixpng) $('#egallery *').ifixpng();

			this.$ = {
				overlay: $('#egallery-overlay').css({
					backgroundColor:	this.settings.overlayBgColor,
					opacity:			this.settings.overlayOpacity
				}),
				info: $('#egallery-info').css({zIndex: 1002}),
				'close-link': $('#egallery-close-link').bind('click', this.actions.close),
				'b': {
					'info': $('#egallery-button-info'),
					'play': $('#egallery-button-play'),
					'pause': $('#egallery-button-pause'),
					'prev': $('#egallery-button-prev'),
					'next': $('#egallery-button-next'),
					'overview': $('#egallery-button-overview').hide()
				},
				gallery: $('#egallery'),
				loading: $('#egallery-loading').css('z-index', 2000),
				controls: $('#egallery-controls'),
				image: $('#egallery-image'),
				'image-container': $('#egallery-imageContainer').css({position: 'relative', opacity: 1}),
				container: $('#egallery-container'), // Opacity = 1 are IE hacks to let images with opacity > 0 and < 1 not 'see through' the background
				index: $('#egallery-index')
			};

			if (this.options.hideInfo) this.$['b']['info'].remove();
			this.$['controls'].find('td').css({position: 'relative', opacity: 1});
			this._setButton('overview', true);
		}

		return this.$['gallery'];
	},
	
	plugins: {
		flash: {
			create: function(img) {
				var params = {};
				
				/* l=263 requests an other YouTube encoding which is compatible with Flash version 9.0.45 (TODO: Tell them to upgrade!) */
				if (/youtube.com/.test(img.src))
					params = {l: "263"};
					
				params = $.extend(params, $.ewyseGallery.settings.flashparams, {type: img.type, src: img.src});
				
				$(img.obj).appendTo('body').flashembed(params, $.ewyseGallery.settings.flashvars);
				var elem = $('body > div:last');
				img.obj = {html: elem.html()};
				elem.remove();
			}
		}
	},
	
	actions: {
		next: function() {
			$.ewyseGallery._setButton('next',false);
			$.ewyseGallery._setButton('prev',false);
			$.ewyseGallery._setButton('play',false);
			$.ewyseGallery._setCurrentImage('next');
		},
		prev: function() {
			$.ewyseGallery._setButton('next',false);
			$.ewyseGallery._setButton('prev',false);
			$.ewyseGallery._setButton('play',false);
			$.ewyseGallery._setCurrentImage('prev');
		},
		close: function() {
			with ($.ewyseGallery) {
				show = false;
				slideshow.stop();
				window.$(window).add(document).unbind('.gallery');
				$['image'].remove();
				$['info'].slideUp('fast');
				$['close-link'].hide();
				$['gallery'].hide();
				$['overlay'].fadeOut();
				window.$('embed, object, select').css({ 'visibility' : 'visible'});
			}
		},
		info: function() {
			$.ewyseGallery.$['info'].slideToggle();
		},
		play: function() {
			$.ewyseGallery.slideshow.start();
		},
		pause: function() {
			$.ewyseGallery.slideshow.stop();
		},
		overview: function() {
			
		}
	},
	
	slideshow: {
		start: function() {
			$.ewyseGallery.$['b']['play'].hide();
			$.ewyseGallery.$['b']['pause'].show();
			$.ewyseGallery._setButton('next',false);
			$.ewyseGallery._setButton('prev',false);
			this.setTimeout();
		},
		setTimeout: function() {
			clearTimeout(this.timer);
			this.timer = setTimeout(this.next, $.ewyseGallery.settings.slideshowInterval);
		},
		next: function() {
			$.ewyseGallery._setCurrentImage('next');
		},
		toggle: function() {
			if (!this.timer) this.start();
			else this.stop();
		},
		stop: function() {
			clearTimeout(this.timer);
			this.timer = false;
			$.ewyseGallery.$['b']['pause'].hide();
			$.ewyseGallery.$['b']['play'].show();
			$.ewyseGallery._setButton('prev', true);
			$.ewyseGallery._setButton('next', true);
		}
	},
	
	_setCurrentImage: function(which) { // show the loading
		// Show the loading
		if (this.loading) return;
		var img = this._getImage(which, true);
		if (img !== false) {
			this.loading = true;
			this.$['info'].slideUp('fast');
			this._preload(img, this._setImage);
		}
	},
	
	_preload: function(img, callback) {
		// get the image object, if not yet supplied
		if (!((typeof img == 'object') || (img = this._getImage(img)))) return;
		
		if (!img.type) {
			//if (/youtube.com/.test(img.src)) {
				
			//}
			img.type = /youtube.com/.test(img.src) ? 'youtube' : img.src.split('.').pop();
		}
		if (img.type && !img.plugin) img.plugin = this.settings.plugins[img.type];
		
		// Store the context, because THIS won't be available in callback functions
		var context = this;
		var newHeight = Math.max(this.settings.maxHeight, this.settings.minHeight) - this.settings.borderSpace * 2;
		var newWidth = Math.max(this.settings.maxWidth, this.settings.minWidth) - this.settings.borderSpace * 2;
		// If we already have an image object, see if we have a callback
		if (img.obj) {
			if (callback) {
				if (img.plugin) {
					callback.call(context, img.obj);
					context = null;
					return;
				} else if (!this.data.rewriteFunction || img.width == newWidth && img.height == newHeight) {
					// If the image is already loaded we apply the callback already, unless the max image size has changed, so we have to reload the image
					if (img.obj.complete) {
						callback.call(context, img.obj);
						context = null;
						return;
					} else {
						$(img.obj).one('load', function(e) {
							callback.call(context, this);
							context = null;
						});
						this.$['loading'].show();
						return;
					}
				}
			}
		} else {
			img.obj = new Image();
			if (img.plugin) this.plugins[img.plugin].create(img);
		}

		if (callback) {
			this.$['loading'].show();
			if (img.plugin) {
				callback.call(context, img.obj);
				context = null;
			} else 
				$(img.obj).one('load', function(e) {
					callback.call(context, this);
					context = null;
				});
		}
		
		// Store the currently used width and height, so we know when to reload the images
		if (!img.plugin) {
			img.width = newWidth;
			img.height = newHeight;
			img.obj.src = this.data.rewriteFunction ? this.data.rewriteFunction.apply(context, [img.src, img.width, img.height]) : img.src;
		}
		img.obj.title = img.obj.alt = $.trim(img.title) || '';
	},
	
	_setImage: function(img) {
		var newHeight, newWidth, h, w, $img = $(img.html || img), imgHeight = parseInt(img.height || $img.attr('height')), imgWidth = parseInt(img.width || $img.attr('width'));
		if (this.settings.fitImage) {
			newHeight = imgHeight + (this.settings.borderSpace * 2);
			newWidth = imgWidth + (this.settings.borderSpace * 2);
		} else {
			newHeight = Math.max(Math.min(imgHeight + this.settings.borderSpace * 2, this.settings.maxHeight), this.settings.minHeight);
			newWidth = Math.max(Math.min(imgWidth + this.settings.borderSpace * 2, this.settings.maxWidth), this.settings.minWidth);
		}

		/* If the user has no plugin installed, these are set to NaN, so use default */
		if (!parseInt(newHeight))
			newHeight = 200;
		if (!parseInt(newWidth))
			newWidth = 400;
			
		h = this.$['image-container'].height() != newHeight;
		w = this.$['container'].width() != newWidth;

		// Helper function
		function temp() {
			$.ewyseGallery.$['image'] = $img.css('display', 'none').appendTo($.ewyseGallery.$['image-container']);
			$.ewyseGallery._loadingDone(img);
			if (h && $.ewyseGallery.options.showInContent !== true) $.ewyseGallery._setPosition();
		}
		
		this.$['image'].fadeOut(300, function() {
			if ($.ewyseGallery.slideshow.timer) $.ewyseGallery.slideshow.setTimeout();
			else {
				var enabled = $.ewyseGallery.data.images.length > 1;
				$.ewyseGallery._setButton('play', enabled);
				$.ewyseGallery._setButton('prev', enabled);
				$.ewyseGallery._setButton('next', enabled);
			}
			$(this).remove();
			if (h || w) {
				// hide the close link on resize.. otherwise it's cropped
				$.ewyseGallery.$['close-link'].hide();
				$.ewyseGallery.$['image-container'].animate({height: newHeight, width: newWidth}, 400, 'easeInOutCubic');
				$.ewyseGallery.$['container'].animate({width: newWidth}, 400, 'easeInOutCubic', temp);
			} else temp();
		});
	},

	_loadingDone: function(img) {
		this._setButton('info', img.title);
		if (!!$.trim(img.title)) this.$['info'].slideDown().children().html(img.title);
		this.$['close-link'].show();
		this.$['loading'].hide();
		this.$['index'].html((this.current + 1) + ' / ' + this.data.images.length);
		this.$['image'].center().fadeIn(300);
		this.loading = false;
		this._preload('next');
	},

	_getImage: function(which, setCurrent) {
		var index = which;
		if (typeof index == 'undefined') index = this.current;
		else switch(which) {
			case 'current':
			case 'active': index = this.current; break;
			case 'prev': index = this.__testIndex(this.current - 1) !== false ? this.current - 1 : this.data.images.length - 1; break;
			case 'next': index = this.__testIndex(this.current + 1) || 0; break;
			case 'last': index = this.data.images.length - 1; break;
			case 'first': index = 0; break;
		}
		index = this.__testIndex(index);
		if (index !== false && setCurrent) this.current = index;
		return $.ewyseGallery.data.images[index];
	},
	
	__testIndex: function(index) {
		return (index >= 0 && index < this.data.images.length) ? index : false;
	},
	
	_setButton: function(which, enabled) {
		this.$['b'][which].unbind().css({opacity: enabled ? 1 : 0.4, cursor: enabled ? 'pointer' : 'auto'});
		if (enabled) this.$['b'][which].bind('click', this.actions[which]);
	},
	
	_show: function(args, index) {
		this._initInterface();
		var self = this;
		this.show = true;
		// Set the collection we are currently viewing.
		$('embed, object, select').css({ 'visibility' : 'hidden'});

		if (!this._settings) this._settings = $.extend({}, this.settings);
		
		if (this.options.showInContent !== true) {
			this._setPosition();
			this.$['gallery'].css({
				position: 'absolute',
				left: 0,
				top: 0
			});
			var windowTimeout = false;
			$(window).bind('scroll.gallery resize.gallery', function(e) {
				clearTimeout(windowTimeout);
				windowTimeout = setTimeout(function() {self._setPosition(e);}, 50);
			});
		}

		this.data = args;
		
		if (typeof index != 'undefined') this.current = index;
		
		if (this.data.images.length > 1) {
			this._setButton('play', true);
			this._setButton('pause', true);
			this.$['controls'].show();
		} else {
			this.$['controls'].hide();
		}
		
		this.$['gallery'].fadeIn(function () {
			$.ewyseGallery._setCurrentImage();
			if (args.autoplay) $.ewyseGallery.slideshow.start();
		});
		
		this._bindKeys();
	},
	
	_bindKeys: function() {
		var self = this;
		$(document).bind('keydown.gallery', function(e) {
			var prevent = true;
			if (e.which == 32) self.slideshow.toggle();
			else if (e.keyCode == 39) self.actions.next();
			else if (e.keyCode == 37) self.actions.prev();
			else if (e.keyCode == 27 && self.options.showInContent !== true) self.actions.close();
			else prevent = false;
			// If we don't do this, we stop the animated GIF as well
			if (prevent) {
				e.stopPropagation();
				e.preventDefault();
			}
		}).click();
	},
	
	_setPosition: function(y) {
		if (!$.ewyseGallery.show) return;
		var $win = $(window), $doc = $(document), scrollTop = $win.scrollTop(), winHeight = $win.height();
		var location = $win.scrollTop() + (winHeight / 2) - ($.ewyseGallery.$['gallery'].height() / 2);
		if (!isNaN(y)) height = Math.max(y, $doc.height());
		if ($.ewyseGallery.settings.autoMaxDimension) {
			$.ewyseGallery.settings.maxWidth = Math.min($win.width() - 50, $.ewyseGallery._settings.maxWidth);
			$.ewyseGallery.settings.maxHeight = Math.min(winHeight - 150, $.ewyseGallery._settings.maxHeight);
		}
		if (location > scrollTop) {
			$.ewyseGallery.$['gallery'].stop().animate({top: location, opacity: 1}, 'fast', 'easeOutCubic', function() {
				if ($.browser.msie) $.ewyseGallery.$['gallery'].css('filter', '');
				$.ewyseGallery.$['overlay'].css('height', $doc.height()).not(':visible').fadeIn('fast');
			});
		} else {
			$.ewyseGallery.$['overlay'].css('height', $doc.height()).not(':visible').fadeIn('fast');
			if (!y || !isNaN(y)) $.ewyseGallery.$['gallery'].animate({top: scrollTop + 30}, 'fast', 'easeOutCubic');
		}
	}
};

$.fn.center = function() {
	return this.each(function() {
		var $$ = $(this);
		$parent = $$.parent().css({position: 'relative'});
		$$.css({
			position: 'absolute',
			left: ($parent.width() - $$.width()) / 2,
			top: ($parent.height() - $$.height()) / 2
		});
	});
}

$.fn.ewyseGallery = function(arg, arg2) {
	// If $arg is a string, then $this is a grouping and $arg are the items per group.
	if (typeof arg == 'string') {
		// Make a gallery of each of the selected items
		return this.each(function() {
			var $$ = $(this);
			arg2 = arg2 || {};
			// If a thumbnail jquery path is given (as a string), get it for each item
			if (arg2.thumbnails && typeof arg2.thumbnails == 'string') arg2.thumbnails = $$.find(arg2.thumbnails).get();
			$$.find(arg).ewyseGallery($.extend({}, arg2));
		});
	} // Else, $this is the path to all the gallery items
	var options = arg || {};
	options.images = options.images || [];
	options.thumbnails = options.thumbnails ? (typeof options.thumbnails == 'string' ? $(options.thumbnails).get() : options.thumbnails) : [];
	var jsonLoaded = false;
	
	function _initialize(e) {
		e.preventDefault();
		e.stopPropagation();
		
		var obj = this;
		if (!jsonLoaded && options.mode && options.mode.toLowerCase() == 'json') {
			if ($.ewyseGallery.settings.cacheAjaxRequests && (options.images = $.ewyseGallery.settings.cache[options.url])) {
				jsonLoaded = true;
				_start(obj, options);
			} else {
				$.getJSON(options.url, function(json) {
					jsonLoaded = true;
					options.images = json.images || json;
					if (options.jsonCallback) options.images = options.jsonCallback.call(this, options.images);
					// cache the request? Good for catching identical requests
					if ($.ewyseGallery.settings.cacheAjaxRequests) {
						$.ewyseGallery.settings.cache[options.url] = options.images;
					}
					_start(obj, options);
				});
			}
		} else _start(obj, options);
		
		return false;
	};
	
	function _start(obj, data) {
		var img = obj.href || obj.src;
		var index = 0;
		for (i = 0; i < data.images.length; i++) {
			if (data.images[i].src.indexOf(img) > -1) {
				index = i; break;
			}
		};
		$.ewyseGallery._show(data, index);
	}
	
	if (!options.images.length) this.each(function () {
		var img = {
			src: this.href || this.src,
			title: this.title || this.alt
		};
		img.type = ($.metadata ? $(this).metadata().type : false) || $(this).data('type') || false;
		options.images.push(img);
	});
	return this.unbind('.gallery').bind('click.gallery', _initialize);
};

})(jQuery);;

// Some adjustments to jquery by Yereth Jansen; www.yereth.nl, www.wharf.nl
(function($){
	$.trim = function(t){
		return typeof t != 'string' ? t : (t||"").replace(/^\s+|\s+$/g, "");
	};
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	// We add the clean arg, so we can remove values which are not set
	$.param = function( a, clean ) {
		var s = [ ];

		function add( key, value, array ){
			if (!clean || $.trim(value)) s[ s.length ] = encodeURIComponent(key) + (array ? '[]=' : '=') + encodeURIComponent(value);
		};

		// If an array was passed in, assume that it is an array
		// of form elements
		if ( jQuery.isArray(a) || a.jquery )
			// Serialize the form elements
			jQuery.each( a, function(){
				add( this.name, this.value );
			});

		// Otherwise, assume that it's an object of key/value pairs
		else
			// Serialize the key/values
			for ( var j in a )
				// If the value is an array then the key names need to be repeated
				if ( jQuery.isArray(a[j]) )
					jQuery.each( a[j], function(){
						add( j, this, true );
					});
				else
					add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );

		// Return the resulting serialization
		return s.join("&").replace(/%20/g, "+");
	};
})(jQuery);;


/**
 * flashembed 0.28. Adobe Flash embedding script
 * 
 * http://flowplayer.org/tools/flash-embed.html
 *
 * Copyright (c) 2008 Tero Piirainen (tero@flowplayer.org)
 *
 * Released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * >> Basically you can do anything you want but leave this header as is <<
 *
 * Since: 				03/11/2008 
 * Version: 0.28 		05/26/2008
 */
function flashembed(root, userParams, flashvars) {
	
	if (typeof root == 'string') root = document.getElementById(root);
	
	// setup params
	var params = {
		
		// very common params
		src: '#',
		width: '100%',
		height: '100%',		
		
		// flashembed specific options
		version:null,  
		loadEvent:null,
		onFail:null,
		expressInstall: window.pb_path + 'js/expressInstall.swf',
		
		// flashembed defaults
		allowfullscreen: true,
		allowscriptaccess: 'always',
		quality: 'high',
		bgcolor: '#ffffff',
		wmode: 'opaque',
		type: 'application/x-shockwave-flash',
		pluginspage: 'http://www.adobe.com/go/getflashplayer'
	};
	
	extend(params, userParams);	

	var evt = params.loadEvent;
	params.loadEvent = null;
		
	// setup "lazy loading"
	if (evt) {
		if (!root) return;
		root['on' + evt] = function() {
			return load();
		}; 
		
	// normal loading upon startup. handle to the generated flash object is returned
	} else {
		return load();		
	}
	
	// override extend params function 
	function extend(to, from) {
		if (from) {
			for (key in from) {
				to[key] = from[key];	
			}
		}
	};	
 	
	function setContent(html) {
		if (/img|a/.test(root.nodeName.toLowerCase())) {
			var newRoot = $("<div/>").html(html).insertAfter(root);
			$(root).remove();
			root = newRoot[0];
		} else {
			root.innerHTML = html;
			// return our API			
		}
	};
	
	function load() {
		
		var version = getVersion(); 
		var required = params.version; 
		var express = params.expressInstall;		 

		if (!root) return;
		
		// is supported 
		if (parseInt(version) > 0 && (!required || isSupported(required))) {
			params.onFail = params.version = params.expressInstall = null; 
			setContent(getHTML());
			return root.firstChild;
		// custom fail event
		} else if (params.onFail) {
			var ret = params.onFail.call(params, getVersion(), flashvars);
			if (ret) setContent(ret);
		// express install
		} else if (required && express && isSupported([6,65])) {
			extend(params, {src: express});
			
			flashvars =   {
				MMredirectURL: location.href,
				MMplayerType: 'PlugIn',
				MMdoctitle: document.title
			};
			
			setContent(getHTML());
			
		// not supported
		} else {
			// minor bug fixed here 08.04.2008 (thanks JRodman)
			
			if (root.innerHTML.replace(/\s/g, '') != '') {
				// custom content was supplied
			
			} else {
				setContent(
					"<div class=\"noFlash\">" +
					"<h2>Flash version " + (required || "6.65") + " or greater is required</h2>" + 
					"<h3>" + (version[0] > 0 ? 
						"Your version is " + version : "You have no flash plugin installed") +
					"</h3>" + 
					"<p>Download the latest version <a href='" + params.pluginspage + "'>here</a></p>" +
					"</div>"
				);
			}
		} 
		root['on' + evt] = null; 
		
	}
	
	
	function isSupported(version) {
		var now = getVersion();
		var ret = 
			(now[0] > version[0]) || 
		 	(now[0] == version[0] && now[1] >= version[1])
		;			
		return ret;
	}
	
	
	function getHTML() {
		
		var html = "";
		if (typeof flashvars == 'function') flashvars = flashvars();
		
		
		// mozilla
		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {  

			html = '<embed type="application/x-shockwave-flash" ';

			extend(params, {name:params.id});
			for(var key in params) { 
				if (params[key] != null) 
					html += [key] + '="' +params[key]+ '"\n\t'; 
			}  
			
			if (flashvars) {
				html += 'flashvars=\'';
				for(var key in flashvars) { 
					html += [key] + '=' + encodeURIComponent(flashvars[key]) + '&';
				}			
				html += '\'';
			}
			
			html += '/>';
			
		// ie
		} else { 

			html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
			html += 'width="' + params.width + '" height="' + params.height + '"'; 
			
			// IE Hack: setup pseudo id for IE 6. otherwise we cannot return our embedded Flash object
			if (document.all && parseInt(navigator.appVersion) <= 6) {
				params.id = "_" + ("" + Math.random()).substring(5);
			} 
			if (params.id) html += ' id="' + params.id + '"'; 
			
			html += '>';  
			html += '\n\t<param name="movie" value="'+ params.src +'" />';
			
			// We need the width and height also in the flashvars, for certain players
			$.extend(flashvars, {width: params.width, height: params.height});
			
			params.id = params.src = params.width = params.height = null;
			
			for (var key in params) {
				if (params[key] != null) 
					html += '\n\t<param name="'+ key +'" value="'+ params[key] +'" />';
			}
			
			if (flashvars) {
				html += '\n\t<param name="flashvars" value=\'';
				for(var key in flashvars) { 
					html += [key] + '=' + encodeURIComponent(flashvars[key]) + '&'; 
				}			
				html += '\' />';
			}
			 
			html += "</object>"; 
		}

		return html;
	}
	

	// arr[major, minor, fix]
	function getVersion() {

		var version = [0, 0];
		
		if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
			var _d = navigator.plugins["Shockwave Flash"].description;
			if (typeof _d != "undefined") {
				_d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
				var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
				version = [_m, _r];
			}
			
		} else if (window.ActiveXObject) {
			
			try { // avoid fp 6 crashes
				var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
				
			} catch(e) {
				try { 
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
					version = [6, 0];
					_a.AllowScriptAccess = "always"; // throws if fp < 6.47 
					
				} catch(e) {
					if (version[0] == 6) return;
				}
				try {
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				} catch(e) {
				
				}
				
			}
			
			if (typeof _a == "object") {
				var _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
				if (typeof _d != "undefined") {
					_d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
					version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
				}
			}
		} 
		
		return version;
	}
	
	
	// JSON.asString() function
	function asString(obj) {
		
		switch (typeOf(obj)){
			case 'string':
				return '"'+obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1')+'"';
			case 'array':
				
				return '['+ map(obj, function(el) {
					return asString(el);
				}).join(',') +']';
				
				
			case 'object':
				var str = [];
				for (var property in obj) {
					
					str.push('"'+property+'":'+ asString(obj[property])); 
				}
				return '{'+str.join(',')+'}';
		}
		
		// replace ' --> "  and remove spaces
		return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
	}
	
	
	// private functions
	function typeOf(obj){
		if (obj === null || obj === undefined) return false;
		var type = typeof obj;
		return (type == 'object' && obj.push) ? 'array' : type;
	}
	
	
	// 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() {};
		});
	}
	
	function map(arr, func) {
	  var newArr = []; 
	  for (var i in arr) {
		 newArr[i] = func(arr[i]);
	  }
	  return newArr;
	}
	
	// expose as static method
	flashembed.getVersion = getVersion;
	flashembed.isSupported = isSupported; 

	return root;
}



// setup jquery support
if (typeof jQuery == 'function') {
	(function($) {
		var $$ = $.flashembed = {
			// The players
			players: {
				flv: window.pb_path + 'js/mediaplayer.swf',
				mp3: window.pb_path + 'js/mediaplayer.swf'
			},
			
			types: {
				flv: function(src, params, flashvars) {
					flashvars.file = src;
					return $$.players.flv + '?' + $.param(flashvars);
				},
				mp3: function(src, params, flashvars) {
					flashvars.file = src;
					return $$.players.mp3 + '?file=' + encodeURIComponent(src);
				},
				swf: function(src, params, flashvars) {
					return src;
				}
			}
		};
		
		$.fn.flashembed = function(params, flashvars) {
			flashvars = flashvars || {};
			return this.each(function() {
				$(this).css('display', 'block'); // So we can calculate the right dimensions
				params = $.extend($.metadata ? $(this).metadata() : {}, params);
				params.height = params.height || this.height || $(this).height();
				params.width = params.width || this.width || $(this).width();
				params.type = params.type || 'swf';
				// Temporary youtube hack.. this will work fine for the player
				if (params.type == 'youtube') params.type = 'flv';
				params.src = $$.types[params.type] ? $$.types[params.type](params.src || this.href || this.src, params, flashvars) : params.src;
				new flashembed(this, params, flashvars);
			});
		};		
	})(jQuery);
}


;

/*
 * jQuery Example Plugin 1.3.3
 * Populate form inputs with example text that disappears on focus.
 *
 * e.g.
 *  $('input#name').example('Bob Smith');
 *  $('input[@title]').example(function() {
 *    return $(this).attr('title');
 *  });
 *  $('textarea#message').example('Type your message here', {
 *    class_name: 'example_text',
 *    hide_label: true
 *  });
 *
 * Copyright (c) Paul Mucur (http://mucur.name), 2007-2008.
 * Dual-licensed under the BSD (BSD-LICENSE.txt) and GPL (GPL-LICENSE.txt)
 * licenses.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
(function($) {
      
  $.fn.example = function(text, args) {
    
    /* Merge the default options with the given arguments. */
    var options = $.extend({}, $.fn.example.defaults, args);
    
    /* Only calculate once whether a callback has been used. */
    var callback = $.isFunction(text);
    
	$.fn.example.bound_class_names[options.class_name] = true;      
    
	// add submit bindings to empty the example fields (we don't want example texts to be submitted)
	$('form:not(.jq_example_form)').addClass('jq_example_form').bind('submit.jq_example', $.fn.example.empty_bound_inputs);
    
	return this.each(function() {
      
      /* Reduce method calls by saving the current jQuery object. */
      var $this = $(this);
      var val = callback ? text.call(this) : text;
	  
	  if (!val) return this;
	  
      /* Internet Explorer will cache form values even if they are cleared
       * on unload, so this will clear any value that matches the example
       * text and hasn't been specified in the value attribute.
       *
       * The trick is to see whether a value has been set that is
       * different to the defaultValue attribute. As I do not want
       * to recklessly clear form inputs that are not examples on
       * document ready, only those with values that match the example
       * text will be cleared.
       *
       * If a callback is used, it is not possible to predict
       * what the example text is going to be so all non-default values
       * are cleared. This means that caching is effectively disabled for
       * that field.
       *
       * Many thanks to Klaus Hartl for this technique.
       */
      if ($.browser.msie && !$this.attr('defaultValue') &&
          (callback ? $this.val() != '' : $this.val() == text)) {
        $this.val('');
      }

      /* Initially place the example text in the field if it is empty. */
      if ($this.val() == '') {
        $this.addClass(options.class_name);
        
        /* The text argument can now be a function; if this is the case,
         * call it, passing the current element as `this`.
         */
        $this.val(callback ? text.call(this) : text);
      }
    
      /* DEPRECATION WARNING: I am considering removing this option.
       *
       * If the option is set, hide the associated label (and its line-break
       * if it has one).
       */
      if (options.hide_label) {
        var label = $('label[@for=' + $this.attr('id') + ']');
        
        /* The label and its line break must be hidden separately as
         * jQuery 1.1 does not support andSelf().
         */
        label.next('br').hide();
        label.hide();
      }
    
      /* Make the example text disappear when someone focuses.
       *
       * To determine whether the value of the field is an example or not,
       * check for the example class name only; comparing the actual value
       * seems wasteful and can stop people from using example values as real 
       * input.
       */
      $this.focus(function() {
        
        /* jQuery 1.1 has no hasClass(), so is() must be used instead. */
        if ($(this).is('.' + options.class_name)) {
          $(this).val('');
          $(this).removeClass(options.class_name);
        }
      });
    	
      /* Make the example text reappear if the input is blank on blurring. */
      $this.blur(function(e) {
		if ($(this).val() == '') {
		  $(this).addClass(options.class_name);
		  
		  /* Re-evaluate the callback function every time the user
		   * blurs the field without entering anything. While this
		   * is not as efficient as caching the value, it allows for
		   * more dynamic applications of the plugin.
		   */
		  $(this).val(callback ? text.call(this) : text);
		}
      });
    });
};
  
  /* Users can override the defaults for the plugin like so:
   *
   *   $.fn.example.defaults.class_name = 'not_example';
   *   $.fn.example.defaults.hide_label = true;
   */
  $.fn.example.defaults = {
    class_name: 'example',
    
    /* DEPRECATION WARNING: I am considering removing this option. */    
    hide_label: false
  };
  
	/* All the class names used are stored as keys in the following array. */
	$.fn.example.bound_class_names = {};
  
	$.fn.example.empty_bound_inputs = function() {
		var self = $(this);
		$.each($.fn.example.bound_class_names, function(key, b) {
			self.find('.' + key).val('');
		});
	}
	
	// empty the processed forms because of FF caching issue
	$(window).unload(function() {
		$.fn.example.empty_bound_inputs.apply($('form.jq_example_form'));
	});

})(jQuery);
;

/*
 *	2008, 25th of August
 *	
 *	Author:		Yereth Jansen (http://www.yereth.nl)
 *	Copyright:	Wharf (http://www.wharf.nl)
 *	Version:	0.91
 *	
 *	Usage:
 *	$('#myMenu a').ajaxNav(options);
 *	
 *	Server side script which delivers content items similar to the 'target' option.
 *
 *	Either the 'target' or the 'workspace' should be explicitly set. If the 'target' is not set
 *	the 'target' will be the direct first child of the 'workspace'. If the 'workspace' is not set,
 *	the parent of the 'target' will be used, unless one enables 'createWorkspace'. It's recommended
 *	to either pre-create a workspace or enable 'createWorkspace', so the direct parent can be used
 *	as a viewport.
 */

(function($){

$.ajaxNav = {
	version: 0.91,
	
	// The last hash is for the hash poll, so it won't check if the hash is the same as the last time
	lastHash: false,
	
	defaults: {
		ajaxFile:		window.location.protocol + '//' + window.location.host + window.location.pathname,	// The location of the file which handles the ajax requests
		ajaxParams:		{},					// Parameters passed along with the ajax call
		hash:			true,				// Disable the hashing function? Could be wise, with complex sites, as it won't work gracefully together with other ajax content.
		preload:		true,				// Preload content?
		target:			false,				// The current content item, which will be the base for the dimensions of all other items
		dimensional:	true,				// Should the content move around in 1 or 2 dimensions?
		workspace:		false,				// The workspace, if already available, wherein the content items will be layed out
		createWorkspace:false,				// Create the workspace wherein content is layed out
		createViewport:	false,				// Create the viewport wherein the workspace exists
		fixViewport:	false,				// If true, the viewport will get fixed dimensions, as it is when we find it
		onShow:			function() {},		// Function called whenever content is shown (element dimensions will be available)
		callback:		false,				// Function called when content is added (content might be hidden)
		subMenu:		false,				// Query which points to the submenu in the content items, which will be used for vertical navigation
		classActive:	'activeItem',		// The classname marking the currently active navigation item
		trackGA:		false,				// Track navigation with google analytics, when available (works with ua, not with urchin)
		useOverlay:		false,				// Use a clickable overlay on inactive content
		keyNav:			false,				// Use the arrow keys to navigate through this navigation
		windowResize:	false,				// Center the content on window resize event
		fade:			true,				// Fade the incoming menu? Might be heavy on the cpu and doesn't look nice in IE with transparent PNGs
		find:			false,				// In the AJAX result, find a specific element to use (jquery style), instead of the complete content result
		offset:			[50, 50],			// Distance between content items [x, y]
		buttons:		false,				// Add buttons for navigation. Usage: {left: image, right: image, down: image, up: image, index: /horizontal|vertical|both/}
		dragDrop:		false,				// BETA!!!!!!!
		easing:			'easeInOutCubic'	// Default easing option
	},
	
	parseGetParameters: function(url) {
		var array = {}, index, args, arg, i, key;
		if ((url || (!noEnv && (url = window.location.search))) && (index = url.indexOf('?')) !== -1) {
			args = url.substring(index + 1).split(/&amp;|&/);
			for (i = 0; i < args.length; i++) {
				arg = args[i].split('=');
				// Remove the first entry; it's our key in this pair
				key = arg.shift();
				// If the value also contains unencoded '=' signs, we save the value by rejoining the remainings
				arg = arg.join('=');
				array[key] = (typeof(arg) != 'undefined') ? decodeURIComponent(arg) : '';
			}
		}
		return array;
	},
	
	// Storage for all the instances of ajax navigation
	cache: [],
	
	init: function(settings) {
		if (settings.mainNav.is('.ajaxNav')) return;
		settings.cacheIndex = this.cache.length;
		this.cache[settings.cacheIndex] = settings;
		settings.hashRegExp = new RegExp(settings.cacheIndex + ":(\\-?\\d+),(\\-?\\d+)");
		
		settings.root = window.location.protocol + '//' + window.location.hostname + window.location.pathname;
		// Create the back link log, to process links in the page which refer to ajaxNav processed links..
		settings.backLinkLog = {};
		// Create the backlog for hashes, so we can map the current hash to content items
		settings.backHashLog = {};
		// Assume the rootURL (no window.location.search) refers to the [0,0] item..
		if (settings.options.keyNav) settings.backLinkLog[settings.root] = [0,0];
		
		var o = settings.options;
		if (!o.workspace && !o.target) return;
		
		var target = o.target ? $(o.target) : $(':first-child', o.workspace);
		
		settings.mainNav.each(function(i) {
			if ($(this).is('.' + o.classActive)) settings.activeItem = [i,0];
		});
		
		if (o.subMenu) $(o.subMenu, target).each(function(i) {
			if ($(this).is('.' + o.classActive)) settings.activeItem[1] = i;
		});
		
		// Create the nav buttons before processing backlinks!
		if (o.buttons) {
			this.initButtons(settings);
		}
		
		this.createNav(settings, settings, settings.mainNav);
		
		this.setHash(settings, settings.activeItem, true);
		
		// Exception for non-navigation items... if no active item is detected, the activeItem is [-1,-1]
		if (settings.activeItem[0] == -1) {
			settings.nav[-1] = {nav: []};
			settings.nav[-1].nav[settings.activeItem[1]] = {};
		}
		
		if (o.subMenu) this.createSubMenu(settings, settings.activeItem, true);
		settings.currentTarget = settings.activeItem;
	
		// Get the current content target, the workspace and the viewport
		var target = this.getNav(settings, settings.activeItem)['target'] = o.target ? $(o.target) : $(':first-child', o.workspace);
		settings.workspace = o.workspace ? $(o.workspace) : o.createWorkspace ? target.wrap("<div/>").parent() : $(target).parent();
		settings.viewport = o.createViewport ? settings.workspace.wrap("<div/>").parent() : settings.workspace.parent();
		
		settings.workspace.addClass('ajaxNav_workspace');
		settings.viewport.addClass('ajaxNav_viewport');
		// Rediculous IE fix to make sure the viewport is rendered correctly and returns the right height
		if ($.browser.msie) settings.viewport.add(settings.workspace).css('zoom', 1);
		
		settings.contentWidth = target.width();

		if (o.dimensional) {
			// Set some dimension and location values
			settings.contentHeight = target.height() || target.append('<div style="clear: both" />').height();
			settings.contentOuterWidth = target.outerWidth();
			settings.contentOuterHeight = target.outerHeight();
			settings.windowWidth = $(window).width();
			settings.left = settings.viewport.width() / 2 - 5000;
			settings.top = 0;

			if (o.fixViewport) {
				settings.viewport.css({
					overflow: 'hidden',
					width: settings.viewport.outerWidth(),
					height: settings.viewport.outerHeight(),
					position: settings.viewport.css('position') == 'absolute' ? 'absolute' : 'relative'
				});
			}

			settings.workspace.css({
				width: 10000,
				height: 10000,
				position: 'absolute',
				left: settings.left,
				top: settings.top,
				textAlign: 'center'
			});

			target.css({
				cursor: 'auto',
				textAlign: 'left',
				position: 'absolute',
				top: target.position().top,
				left: 5000 - settings.contentOuterWidth / 2,
				width: settings.contentWidth, 
				height: settings.contentHeight
			});
		} else {
			settings.workspace.css({position: settings.workspace.css('position') == 'absolute' ? 'absolute' : 'relative'});
			target.css({width: settings.contentWidth});
		}
		
		if (o.dragDrop) settings.workspace.css({
			cursor: 'move'
		}).bind('mousedown.ajaxNav', function(e) {
			$.ajaxNav.drag.start(e, settings);
		});
		
		
		if (o.windowResize) $(window).bind('resize.ajaxNav', $.ajaxNav.setPosition);
		if (o.useOverlay && !this.compare(settings.activeItem,[-1,-1])) this.addOverlay(settings, settings.activeItem);
		if (o.keyNav) this.initKeyNav(settings);
		
		if (settings.options.preload) setTimeout(function() { $.ajaxNav.preloadNeighbors(settings); }, 500);
		
		if (o.hash && !this.hashEnabled) {
			this.hashEnabled = true;
			this.hashPoll();
		}

		if (o.buttons) {
			this.setButtons(settings);
		}
	},
	
	initButtons: function(settings) {
		settings.buttons = {};
		var action;
		for (action in settings.options.buttons) {
			if (this.nav[action]) {
				var button = settings.options.buttons[action];
				settings.buttons[action] = (button.constructor == String) 
					? $('<img/>').css('cursor', 'pointer')
						.attr({
						  src: settings.options.buttons[action],
						  alt: action
						}).addClass(action)
						.appendTo(settings.viewport.parent())
					: button;
				settings.buttons[action].addClass('ajaxNav').bind('click.ajaxNav', function(e) {
					e.preventDefault();
					this.blur();
					$.ajaxNav.nav[$(this).data('action')](settings);
				});
				settings.buttons[action].data('action', action);
			}
		}
	},
	
	initKeyNav: function(settings) {
		$(document).bind('keydown.ajaxNav', function(e) {
			if ($(e.target).is(':input')) return true;
			var action = false, cancel = false;
			if (37 == e.keyCode) action = 'left';
			else if (39 == e.keyCode) action = 'right';
			else if (38 == e.keyCode) action = 'up';
			else if (40 == e.keyCode) action = 'down';
			if (action) cancel = $.ajaxNav.nav[action](settings);		
			if (cancel) {
				e.preventDefault();
				e.stopPropagation();
			}
			return !cancel;
		});
	},
	
	setButtons: function(settings) {
		var b = settings.buttons;
		if (!b) return;
		if (b.left) b.left[this.getNav(settings, settings.activeItem[0] - 1) ? 'show' : 'hide']();
		if (b.right) b.right[this.getNav(settings, settings.activeItem[0] + 1) ? 'show' : 'hide']();
		if (b.up) b.up[this.getNav(settings, [settings.activeItem[0], settings.activeItem[1] - 1]) ? 'show' : 'hide']();
		if (b.down) b.down[this.getNav(settings, [settings.activeItem[0], settings.activeItem[1] + 1]) ? 'show' : 'hide']();
	},
	
	nav: {
		left: function(settings) {
			return $.ajaxNav.navigate(settings, [settings.activeItem[0] - 1, settings.activeItem[1]]);
		},
		right: function(settings) {
			return $.ajaxNav.navigate(settings, [settings.activeItem[0] + 1, settings.activeItem[1]]);
		},
		up: function(settings) {
			return $.ajaxNav.navigate(settings, [settings.activeItem[0], settings.activeItem[1] - 1]);
		},
		down: function(settings) {
			return $.ajaxNav.navigate(settings, [settings.activeItem[0], settings.activeItem[1] + 1]);
		}
	},

	drag: {
		start: function(e, settings) {
			if (e.target != settings.workspace[0]) return true;
			settings.drag = {
				x: -e.clientX + settings.left,
				y: -e.clientY + settings.top + settings.topOffset,
				startX: e.clientX,
				startY: e.clientY
			}
			$(window).bind('mousemove.ajaxNav', function(e) {
				$.ajaxNav.drag.drag(e, settings);
			});
			$(window).one('mouseup.ajaxNav', function(e) {
				$.ajaxNav.drag.stop(e, settings);
			});
		},
		drag: function(e, settings) {
			settings.workspace[0].style.left = (settings.drag.x + e.clientX) + 'px';
			settings.workspace[0].style.top = (settings.drag.y + e.clientY) + 'px';
			return false;
		},
		stop: function (e, settings) {
			$(window).unbind('mousemove.ajaxNav');
			$.ajaxNav.setPosition();
		}
	},
	
	createSubMenu: function(settings, which) {
		var nav = this.getNav(settings, which[0]);
		var subMenu = $(settings.options.subMenu, this.getNav(settings, which, 'target'));
		
		this.createNav(settings, nav, subMenu, which[0]);
	},

	createNav: function(settings, addTo, urls, primary) {
		if (!addTo.nav) addTo.nav = [];
		
		urls.each(function(i) {
			var self = $(this);
			if ($(this).is('.ajaxNav')) return;
			var which = typeof primary !== 'undefined' ? [primary, i] : [i, 0];
			if (!addTo.nav[i]) {
				// Create new nav item
				addTo.nav[i] = {
					url: this.href,
					el: this,
					backLinks: [this],
					target: false,
					ajaxParams: $.metadata ? (self.metadata().ajaxParams || {}) : {},
					hash: '#' + decodeURIComponent(this.search.substr(1))
				};
				// Create backlogs to track back items
				settings.backHashLog[addTo.nav[i].hash] = which;
				settings.backLinkLog[addTo.nav[i].url] = which;
			}
			$.ajaxNav.processLink(settings, this, which);
		});
		this.processBackLinks(settings);
	},
	
	processLink: function(settings, el, which) {
		$(el).not('.ajaxNav').addClass('ajaxNav').bind('click.ajaxNav', function(e) {
			this.blur();
			e.preventDefault();
			$.ajaxNav.navigate(settings, which);
		});
	},
	
	processBackLinks: function(settings, context) {
		var which;
		setTimeout(function() {
			$('a', context || document).each(function() {
				var a = $(this), nav;
				// Only handle non processed links
				if (!/ajaxNav/.test(this.className)) {
					if (which = settings.backLinkLog[this.href]) {
						// Add the currently found element to the backlinks so we can add an active class to it when activated
						$.ajaxNav.getNav(settings, which).backLinks.push(this);
						// Process the current link to also work with ajax, instead of its normal way
						$.ajaxNav.processLink(settings, this, which);
					}
				}
			});
		}, 0);
	},
	
	setHash: function(settings, which, ifNotSet) {
		if (settings.options.hash) window.location.hash = this.getNav(settings, which, 'hash') || '#';
	},
	
	hashPoll: function() {
		var i, settings, browserHash, hash = window.location.hash ? decodeURIComponent(window.location.hash) : false;
		if (hash && hash != this.lastHash) {
			for (i = 0; i < this.cache.length; i++) {
				var settings = this.cache[i];
				// check which element should be selected depending on the current hash
				var which = settings.backHashLog[hash] || false;
				if (which && !this.compare(settings.activeItem, which)) $.ajaxNav.navigate(settings, which);
			}
		}
		this.lastHash = hash;
		setTimeout(function() {
			$.ajaxNav.hashPoll();
		}, 100);
	},
	
	compare: function(which1, which2) {
		return (which1[0] == which2[0]) && ((which1[1] || 0) == (which2[1] || 0));
	},
	
	// See if a corresponding navigation item exists
	getNav: function(settings, which, property) {
		var result = false;
		// If only given a number, we're looking for a primary nav. item.
		if (which.constructor == Number) {
			result = settings.nav[which];
		// Otherwise, we wish to get a submenu nav. item.
		} else if (which.constructor == Array) {
			// If the submenu item is set, see if it exists.
			if (which[1] != 0) result = settings.nav[which[0]] && settings.nav[which[0]].nav ? settings.nav[which[0]].nav[which[1]] : (settings.options.subMenu ? false : undefined);
			// If not, just return a primary nav. item.s
			else result = settings.nav[which[0]];
		}
		// If a property was set, return that property of the result.
		if (result && property) return result[property];
		else return result;
	},
	
	setPosition: function(e, animationTime) {
		var width = $(window).width();
		$.each($.ajaxNav.cache, function() {
			if (!e || this.options.windowResize) {
				this.topOffset = (this.options.useOverlay && this.activeItem[1] != 0) ? (this.viewport.height() - this.contentHeight) / 2 : 0;
				if (this.options.windowResize) this.left = this.left - (this.windowWidth - width) / 2;
				this.windowWidth = width;
				this.workspace.stop().animate({left: this.left, top: this.top + this.topOffset}, animationTime || 200, this.options.easing);
			}
		});
	},
	
	preloadNeighbors: function(settings) {
		var a = settings.activeItem;
		
		if (a.constructor == Array) {
			this.load(settings, [a[0] - 1, a[1]]);
			this.load(settings, [a[0] + 1, a[1]]);
			this.load(settings, [a[0], a[1] - 1]);
			this.load(settings, [a[0], a[1] + 1]);
		} else {
			this.load(settings, [a - 1, 0]);
			this.load(settings, [a + 1, 0]);
		}
	},
	
	load: function(settings, which) {
		var url, nav;
		if ((nav = this.getNav(settings, which)) && (url = nav.url)) {
			if (!nav.target && !nav.loading) {
				nav.loading = true;
				var params = $.extend(this.parseGetParameters(url), settings.options.ajaxParams, nav.ajaxParams);
				var base = url.split('?').shift();
				$.getJSON(encodeURI(base), params, function(json) {
					nav.ready = true;
					nav.title = json.title || json.name || '';
					$.ajaxNav.addContent(settings, which, json);
					// Use set timeout, so we don't get stack errors
					setTimeout(function() { $(nav).trigger('ajaxload'); }, 0);
				});
			// Use set timeout, so we don't get stack errors
			} else if (nav.ready) setTimeout(function() { $(nav).trigger('ajaxload'); }, 0);
		}
	},
	
	addContent: function(settings, which, json) {
		var el, active, left, top, target, css, content;
		target = this.getNav(settings, which[0]);
		content = $(json.content);
		if (settings.options.find) content = content.find(settings.options.find);
		
		if (settings.options.dimensional) {
			active = this.getNav(settings, settings.activeItem, 'target');
			css = {
				height: settings.contentHeight,
				display: settings.options.fade ? 'none' : 'block',
				left: parseInt(active.css('left')) + (which[0] - settings.activeItem[0]) * (settings.contentOuterWidth + settings.options.offset[0]),
				top: parseInt(active.css('top')) + ((which[1] || 0) - (settings.activeItem[1] || 0)) * (settings.contentHeight + settings.options.offset[1])
			}
		} else {
			css = {
				visibility: 'hidden',
				top: 0,
				left: 0,
				opacity: 0
			}	
		}
		
		el = (content).css($.extend(css,
			{
				width: settings.contentWidth,
				position: 'absolute',
				textAlign: 'left',
				cursor: 'auto'
			}))
			.appendTo(settings.workspace);
		if (which[1] > 0) {
			target.nav[which[1]]['target'] = el;
		} else {
			target['target'] = el;
		}
		
		if (settings.options.useOverlay) {
			$.ajaxNav.addOverlay(settings, which);
			el.fadeIn(500);
		}
		if (settings.options.subMenu) this.createSubMenu(settings, which);
		if (settings.options.callback) settings.options.callback.apply(el.parent());
	},
	
	addOverlay: function(settings, which) {
		var target = this.getNav(settings, which);
		var overlay = $('<a href="' + target.url + '" class="contentOverlay" style="background-color: black; cursor: pointer; position: absolute; z-index: 10;"/>');
		
		overlay.css('opacity', 0.4);
		
		var el = target.target;
		overlay.prependTo(el)
			.css({width: el.width(), height: el.height()})
			.hover(
				function() {
					$(this).stop().fadeTo(200, 0);
				},
				function() {
					$(this).stop().fadeTo(200, 0.4);
				}
			);
		this.processLink(settings, el, which);
		if (this.compare(which, settings.activeItem)) overlay.hide();
	},
	
	navigate: function(settings, which, force) {
		if (!force && this.compare(settings.currentTarget, which)) return false;
		settings.currentTarget = which;
		
		var current = this.getNav(settings, settings.activeItem, 'target');
		var target = this.getNav(settings, which);
		
		// When the target is undefined (instead of false), the user tried to navigate to an illegal target
		if (typeof target == 'undefined') return false;
		else this.setHash(settings, which);
		
		// If we our target is not available yet AND we are in a secondary Navigation level,
		// obviously we first need to get the primary content item, before we can descend into
		// the sub-navigation content item.
		if (!target) {
			if (which[1] > 0) {
				$(this.getNav(settings, which[0])).unbind('ajaxload').one('ajaxload', function() {
					$.ajaxNav.navigate(settings, which, true);
				});
				this.load(settings, [which[0], 0]);
			}
			return true;
		}
		var navTo = target.target || false;
		if (!navTo) {
			$(target).unbind('ajaxload').one('ajaxload', function() {
				$.ajaxNav.navigate(settings, which, true);
			});
			this.load(settings, which);
			return true;
		}
		
		// Add active class to element we navigate to and remove from the old active link
		$(this.getNav(settings, settings.activeItem[0]).backLinks).removeClass(settings.options.classActive);
		$(this.getNav(settings, which[0]).backLinks).addClass(settings.options.classActive);

		// Now we have a new active item. Set it.
		settings.activeItem = which;
		
		if (settings.options.dimensional) {
			var leftDiff = parseInt(current.css('left')) - parseInt(navTo.css('left'));
			settings.left += leftDiff;
			
			var topDiff = parseInt(current.css('top')) - parseInt(navTo.css('top'));
			settings.top += topDiff;
	
			var time = topDiff && leftDiff ? 600 : 450;
		}
		
		// See if you have calculated new ajaxNav links which are also referred to in the content page we navigate to.
		this.processBackLinks(settings, navTo);

		// Track Google Analytics
		if (settings.options.trackGA && window.pageTracker && target.title) {
			try { pageTracker._trackPageview(target.title); } catch (e) { if (window.console) console.log("Tracking error in ajaxNav: " + e); }
		}
		
		if (settings.options.useOverlay) {
			current.children('.contentOverlay').show();
			navTo.children('.contentOverlay').hide();
			if (settings.options.dimensional && (topDiff || leftDiff)) $.ajaxNav.setPosition(false, time);
			if ($.isFunction(settings.options.onShow)) settings.options.onShow.apply(navTo.parent());
		} else if (settings.options.fade) {
			current.stop(false, true).fadeOut(time);
			if (settings.options.dimensional && (topDiff || leftDiff)) $.ajaxNav.setPosition(false, time);
			navTo.stop(false, true).fadeIn(time, settings.options.onShow || false);
		} else {
			if (settings.options.dimensional) {
				if (topDiff || leftDiff) $.ajaxNav.setPosition(false, time);
				if ($.isFunction(settings.options.onShow)) settings.options.onShow.apply(navTo.parent());
			} else {
				function goRightAhead() {
					settings.workspace.stop().animate({height: navTo.outerHeight()}, 'normal', 'easeOutCubic', function () {
						settings.workspace.css('height', 'auto');
					});
					current.css({position: 'absolute', visibility: 'hidden', left: -1000000});
					navTo.css({position: 'relative', visibility: 'visible', left: 0});
					current.animate({opacity: 0});
					navTo.animate({opacity: 1}, function() {
						// necessary for strange rendering if opacity is not removed
						if ($.isFunction(settings.options.onShow)) settings.options.onShow.apply(navTo.parent());
						if ($.browser.msie) $(this).css('filter', '');
					});
				}
				
				// If the plugin imageReady is available, use it to wait for images to be loaded. Otherwise we may calculate the height incorrectly, which
				// will of course cause a glitch in the matrix
				if ($.fn.imageReady) $('img', navTo).imageReady(goRightAhead);
				else goRightAhead();
			}
		}
		
		this.setButtons(settings);
		
		// after a delay, load the neighbors. Give the workspace some time to fluently move towards the active element
		if (settings.options.preload) setTimeout(function() { $.ajaxNav.preloadNeighbors(settings); }, 500);
		return true;
	}
}

$.fn.ajaxNav = function(options) {
	var settings = {
		mainNav: this,
		activeItem: [-1,-1],
		options: $.extend({}, $.ajaxNav.defaults, options)
	};
	
	$.ajaxNav.init(settings);
};

})(jQuery);;

﻿/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);;

// JavaScript Document
;(function ($) {
$.shadow = {
	defaults: {
		imagePath: 'assets/images/shadow/',
		imageType: 'png',
		corners: 'tl tr bl br',
		sides: 'top right bottom left',
		dimensions: {
			width: 5,
			height: 5
		},
		wrap: 'inside',
		noPadding: false,
		margin: false, // defaults to 'sides' defined above.. it will compensate on margins defined here, to try to maintain the layout
		callback: false,
		fixWidth: false,
		innerOverlap: false // When the added images overlap with the inner content, instead of just closing the gap
	},
	remove: function() {
		$('.jq_shadow').shadow('remove');
	}
};

$.fn.shadow = $.browser.msie && $.browser.version < 7 ? function() { return this; } : function(options) {
	// Want to remove the shadow?
	if (options && options.constructor == String && options == 'remove') {
		return this.each(function() {
			var $$ = $(this);
			if (!$$.is('.jq_shadow')) return;
			if ($$.is(':has(> .jq_shadow_inner)')) {
				$$.css({border: '', background: '', margin: '', padding: '', width: ''}).children('.jq_shadow_inner').css({padding: 0, width: 'auto'});
			}
			$$.removeClass('jq_shadow').children('.jq_shadow_element').remove();
		});
	}
	
	options = $.extend(true, {}, $.shadow.defaults, options || {});
	if (!options.margin) options.margin = options.sides;
	var $$ = this;
	
	function num(elem, prop) {
		// Ok, this may look weird, why not use parseInt? Because FF sometimes gives me 0.98333px instead of 1px o.O
		return elem[0] && Math.round(parseFloat( jQuery.curCSS(elem[0], prop, true), 10 )) || 0;
	}
	
	function img(which) {
		return options.imagePath + which +  '.' + options.imageType;
	}
	
	var tmp = options.corners.split(' ')[0], src;
	if (tmp && (src = img(tmp))) {
		var testImg = new Image();
		$(testImg).one('load', function() {
			options.dimensions = {
				width: this.width,
				height: this.height
			}
			process($$, options);
		});
		testImg.src = src;
	} else {
		setTimeout(function() {
			process($$, options);
		},0);	
	}
	
	function process(elems, opts) {
		elems.each(function() {
			var self = $(this), elements, css = {}, src, padding = {};
			if (self.is('.jq_shadow')) return;
			self.addClass('jq_shadow');
			
			if (!opts.noPadding) {
				// first reset padding
				css.padding = '0px';
				if (/t/.test(opts.corners) || /top/.test(opts.sides)) padding.top = opts.dimensions.height;
				if (/r/.test(opts.corners) || /right/.test(opts.sides)) padding.right = opts.dimensions.width;
				if (/b/.test(opts.corners) || /bottom/.test(opts.sides)) padding.bottom = opts.dimensions.height;
				if (/l/.test(opts.corners) || /left/.test(opts.sides)) padding.left = opts.dimensions.width;
				$.each(padding, function(key, value) {
					css['padding-' + key] = value;
					if (opts.margin && opts.margin.indexOf(key) > -1) css['margin-' + key] = -(value - num(self, 'padding-' + key)) + num(self, 'margin-' + key);
				});
			}
			
			if (opts.wrap == 'inside') {
				var cssInner = {};
				if (!self.is(':has(> .jq_shadow_inner)')) {
					var tempVal;
					$.each('backgroundColor backgroundScroll backgroundPosition backgroundImage backgroundRepeat'.split(' '), function() {
						if (tempVal = self.css(this.toString())) cssInner[this] = tempVal;
					});
					css.background = 'transparent';
					self.wrapInner('<div class="jq_shadow_inner"></div>');
				}
				
				// Inherit the padding and margin settings
				var borderWidth, tempPadding, tempSide;
				$.each('left right top bottom'.split(' '), function() {
					tempSide = this.toString();
					tempPadding = num(self, 'padding-' + tempSide);
					borderWidth = num(self, 'border-' + tempSide + '-width');
					if (opts.innerOverlap) {
						cssInner['margin-' + tempSide] =  tempPadding - (padding[tempSide] || 0) + borderWidth;
						cssInner['padding-' + tempSide] = Math.max(tempPadding, 0);
					} else {
						cssInner['padding-' + tempSide] = Math.max(tempPadding - (padding[tempSide] || 0), 0) + borderWidth;
					}
				});
				// Should we set the width if the inner element? If it is defined and requested, yes please.
				if (opts.fixWidth) {
					var tempWidth = num(self, 'width');
					if (tempWidth > 0) cssInner.width = tempWidth;
				}
				
				// MS IE? Let's zoom to 1!!!11oneone
				if ($.browser.msie) {
					cssInner.zoom = 1;
					css.zoom = 1;
				}
				
				self.children('.jq_shadow_inner').css(cssInner);
				css.border = 'none';
				css.background = 'transparent';
			}
			
			if (self.css('position') != 'absolute') css.position = 'relative';
			
			self.css(css);
			
			// Re-use the CSS object to use for the elements we will add.
			css = {
				position: 'absolute'
			};
			
			if ($.browser.msie) {
				css.lineHeight = 0,
				css.fontSize = 0
			}
			
			$.each(opts.sides.split(' '), function() {
				var $$ = $('<span>&nbsp;</span>').css(css).addClass(this + ' jq_shadow_element');
				var temp = {
					backgroundImage: 'url(' + img(this) + ')'
				};
				if (/left|right/.test(this)) {
					temp[this] = 0;
					temp.backgroundRepeat = 'repeat-y';
					temp.width = opts.dimensions.width;
					temp.top = opts.corners.indexOf('t' + this.charAt(0)) > -1 ? opts.dimensions.height : 0;
					temp.bottom = opts.corners.indexOf('b' + this.charAt(0)) > -1 ? opts.dimensions.height : 0;
				}
				else if (/top|bottom/.test(this)) {
					temp[this] = 0;
					temp.backgroundRepeat = 'repeat-x';
					temp.height = opts.dimensions.height;
					temp.left = opts.corners.indexOf(this.charAt(0) + 'l') > -1 ? opts.dimensions.width : 0;
					temp.right = opts.corners.indexOf(this.charAt(0) + 'r') > -1 ? opts.dimensions.width : 0;
				}
				$$.appendTo(self).css(temp);
			});
			
			$.extend(css, opts.dimensions);
			css.backgroundRepeat = 'no-repeat';
			$.each(opts.corners.split(' '), function() {
				var $$ = $('<span>&nbsp;</span>').css(css).addClass(this + ' jq_shadow_element');
				var temp = {
					backgroundImage: 'url(' + img(this) + ')'
				};
				if (/b/.test(this)) temp.bottom = 0;
				if (/t/.test(this)) temp.top = 0;
				if (/l/.test(this)) temp.left = 0;
				if (/r/.test(this)) temp.right = 0;
				$$.appendTo(self).css(temp);
			});
			
			if (options.callback) options.callback.apply(self);
		});
	}
	
	return this;
};

})(jQuery);;

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

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

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

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

/*
 * jQuery Easing Compatibility v1 - http://gsgd.co.uk/sandbox/jquery.easing.php
 *
 * Adds compatibility for applications that use the pre 1.2 easing names
 *
 * Copyright (c) 2007 George Smith
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */

jQuery.extend( jQuery.easing,
{
	easein: function (x, t, b, c, d) {
		return jQuery.easing.easeInQuad(x, t, b, c, d);
	},
	easeout: function (x, t, b, c, d) {
		return jQuery.easing.easeOutQuad(x, t, b, c, d);
	},
	easeinout: function (x, t, b, c, d) {
		return jQuery.easing.easeInOutQuad(x, t, b, c, d);
	},
	expoin: function(x, t, b, c, d) {
		return jQuery.easing.easeInExpo(x, t, b, c, d);
	},
	expoout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutExpo(x, t, b, c, d);
	},
	expoinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutExpo(x, t, b, c, d);
	},
	bouncein: function(x, t, b, c, d) {
		return jQuery.easing.easeInBounce(x, t, b, c, d);
	},
	bounceout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutBounce(x, t, b, c, d);
	},
	bounceinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutBounce(x, t, b, c, d);
	},
	elasin: function(x, t, b, c, d) {
		return jQuery.easing.easeInElastic(x, t, b, c, d);
	},
	elasout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutElastic(x, t, b, c, d);
	},
	elasinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutElastic(x, t, b, c, d);
	},
	backin: function(x, t, b, c, d) {
		return jQuery.easing.easeInBack(x, t, b, c, d);
	},
	backout: function(x, t, b, c, d) {
		return jQuery.easing.easeOutBack(x, t, b, c, d);
	},
	backinout: function(x, t, b, c, d) {
		return jQuery.easing.easeInOutBack(x, t, b, c, d);
	}
});;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    var q = $.param(a);

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

        var cbInvoked = 0;
        var timedOut = 0;

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

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

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

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

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

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

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

        var nullCheckFlag = 0;

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

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

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

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

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

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

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

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

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

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

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

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

};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

})(jQuery);
;

/*
 * Metadata - jQuery plugin for parsing metadata from elements
 *
 * Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.metadata.js 3620 2007-10-10 20:55:38Z pmclanahan $
 *
 */
(function($){$.extend({metadata:{defaults:{type:'class',name:'metadata',cre:/({.*})/,single:'metadata'},setType:function(type,name){this.defaults.type=type;this.defaults.name=name;},get:function(elem,opts){var settings=$.extend({},this.defaults,opts);if(!settings.single.length)settings.single='metadata';var data=$.data(elem,settings.single);if(data)return data;data="{}";if(settings.type=="class"){var m=settings.cre.exec(elem.className);if(m)data=m[1];}else if(settings.type=="elem"){if(!elem.getElementsByTagName)return;var e=elem.getElementsByTagName(settings.name);if(e.length)data=$.trim(e[0].innerHTML);}else if(elem.getAttribute!=undefined){var attr=elem.getAttribute(settings.name);if(attr)data=attr;}if(data.indexOf('{')<0)data="{"+data+"}";data=eval("("+data+")");$.data(elem,settings.single,data);return data;}}});$.fn.metadata=function(opts){return $.metadata.get(this[0],opts);};})(jQuery);;

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

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

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

})(jQuery);;

;(function($) {

if (!$.ewyseCustom) {

$.extend({
	ewyseCustom: true,
	load: function(jquery, url, args, callback) {
		return $(jquery).load(url, args, callback);
	},
	ie6: function() {
		return $.browser.msie && parseInt($.browser.version) < 7;
	},
	activeItem: function(jquery, options) {
		return $(jquery).activeItem(options);
	},
	makeURL: function(url, args) {
		if (args) url += (url.match(/\?/) ? "&" : "?") + (typeof args == 'string' ? args : $.param(args, true));
		return url;
	},

	postJSON: function(url, getParams, postParams, callback) {
		return $.ajax({
			type: "POST",
			url: $.makeURL(url, getParams),
			dataType: "json",
			data: postParams,
			success: callback
		});
	},
	createStyleSheet: function(url) {
		if (document.styleSheets) {
			for (var i=0; i<document.styleSheets.length; i++) {
				if (document.styleSheets[i].href.indexOf(url) >= 0) return document.styleSheets[i];
			} 
		}
		if ($.browser.msie) {
			return document.createStyleSheet(url);
		} else {
			return $('<link>').appendTo('head').attr({ href: url, rel: 'stylesheet', type: 'text/css' })[0];
		}
	}
});

if (!$.fn._load) $.fn._load = $.fn.load;

$.fn.extend({
	// Perform a function if a condition is fullfilled.. (to not break chaining and
	// to prevent queries to have to run again.
	doIf: function(bool, func) {
		return (bool && $.isFunction(func)) ? func.apply(this) : this;
	},
	absolutize: function() {
		return this.each(function() {
			var $this = $(this);
			var offset = $this.position();
			$this.css({
				position: 'absolute',
				top: offset.top,
				left: offset.left,
				width: $this.width(),
				height: $this.height()
			});
		});
	},
	load: function(url, args, callback) {
		// Backwards compatibility for the jquery load function
		if ($.isFunction(url)) return $(this)._load(url, args, callback);
		if (!this.length) return this;
		var url2 = url;
		if (args) url2 += (url2.match(/\?/) ? "&" : "?") + $.param(args);
		return this.each(function() {
			if (typeof this['location'] == 'object') this.location.href = url2;
			else if (typeof this['href'] != 'undefined') this.href = url2;
			else if (typeof this['src'] != 'undefined') this.src = url2;
			else $(this)._load(url, args, callback);
		});
	},
	hoverClass: function(className) {
		return this.hover( 
			function () { $(this).addClass(className); },
			function () { $(this).removeClass(className); }
		);
	},
	focusClass: function(className) {
		return this.each(function () {
			$(this)
				.focus(function() { $(this).addClass(className); })
    			.blur(function() { $(this).removeClass(className); });
		});
	},
	activeClass: function(className) {
		return this.each(function () {
			$(this)
				.mousedown(function() { $(this).addClass(className); })
    			.mouseup(function() { $(this).removeClass(className); });
		});
	},
	document: function(query) {
		if (this.length == 1 && (el = this[0]) && el.nodeName == 'IFRAME') {
			var result = $(el.contentWindow.document);
		} else {
			var result = $(document);
		}
		if (typeof query != 'undefined') return result.find(query);
		else return result;
	},
	window: function(query) {
		if (this.length == 1 && (el = this[0]) && el.nodeName == 'IFRAME') {
			var result = $(el.contentWindow);
		} else {
			var result = $(window);
		}
		if (typeof query != 'undefined') return result.find(query);
		else return result;
	},
	enable: function(setOpacity) {
		//alert('hi');
		if ($.browser.mozilla || setOpacity) { this.css('opacity', 1);};
		return this.removeAttr('disabled');
	},
	disable: function(setOpacity) {
		if ($.browser.mozilla || setOpacity) this.css("opacity", 0.4);
		return this.attr('disabled','disabled');
	},
	enabled: function(aBool, setOpacity) {
		return this[aBool === false ? 'disable' : 'enable'](setOpacity);
	},
	activeItem: function(options) {
		if (!options) options = {};
		
		var config = {
			classBase: ((options.classBase || this.className) || 'dummyClassForActiveItem'),
			classDown: options.classDown || '',
			classOver: options.classOver || '',
			classActive: options.classActive || '',
			navigation: options.navigation || false, // none, vertical, horizontal
			keyNext: options.navigation == 'horizontal' ? 39 : 40,
			keyPrev: options.navigation == 'horizontal' ? 37 : 38
		};
		
		return this.each(function (i) {
			var $this = $(this);
			// Make tab-selectable
			this.tabIndex = '0';
			
			this.className = config.classBase;
			
			if (config.classOver) $this.mouseover(function(event) {
				this.focus();
				$(this).addClass(config.classOver).siblings('.' + config.classBase).mouseout();
			});
			
			if (config.classOver || config.classDown) $this.mouseout(function (event) {
				if (!config.classActive || !$this.is('.' + config.classActive)) {
					$(this).removeClass([config.classDown, config.classOver].join(' '));
				}
			});
			
			$this.blur(function (event) {
				$(this).triggerHandler('mouseout');
			});

			$this.focus(function (event) {
				$(this).triggerHandler('mouseover');
			});

			if (config.classDown) {
				$this.mousedown(function (event) {
					$(this).addClass(config.classDown);
					return false;
				});
				$this.mouseup(function (event) {
					$(this).mouseout();
					return false;
				});
			}
			// Set general actions
			$this.keyup(function (event) {
				if (/13|32/.test(event.which)) {
					$(this).mouseup().click();
					return false;
				}
			});

			$this.keydown(function (event) {
				if (/13|32/.test(event.which)) {
					$(this).mousedown();
					return false;
				} else if (config.navigation) {
					if (event.which == config.keyNext && (nextItem = $(this).next().not(':disabled')) && nextItem.length) {
						$(this).mouseout();
						nextItem.mouseover().focus();
						return false;
					} else if (event.which == config.keyPrev && (prevItem = $(this).prev().not(':disabled')) && prevItem.length) {
						$(this).mouseout();
						prevItem.mouseover().focus();
						return false;
					}
				}
			});
			if (config.classOver) {
				$this.mouseover(function (event) {
				if (!config.classActive || !$this.is('.' + config.classActive)) {
						$this.addClass(config.classOver);
					}
				});
			}
		});
	}
});

/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-07-21 18:44:59 -0500 (Sat, 21 Jul 2007) $
 * $Rev: 2446 $
 *
 * Version 2.1.1
 */
$.fn.bgIframe = $.fn.bgiframe = function(s) {
	// This is only for IE6
	if ( $.browser.msie && $.browser.version == '6.0' ) {
		s = $.extend({
			top     : 'auto', // auto == .currentStyle.borderTopWidth
			left    : 'auto', // auto == .currentStyle.borderLeftWidth
			width   : 'auto', // auto == offsetWidth
			height  : 'auto', // auto == offsetHeight
			opacity : true,
			src     : 'javascript:false;'
		}, s || {});
		var prop = function(n){return n&&n.constructor==Number?n+'px':n;},
		    html = '<iframe class="bgiframe" frameborder="0" tabindex="-1" src="'+s.src+'" '+
		               'style="display:block;position:absolute;z-index:-1;'+
			               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
					       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
					       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
					       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
					       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
					'"/>';
		return this.not('.bgiframeProcessed').prepend(html).addClass('bgiframeProcessed');
	}
	return this;
};
}

})(jQuery);;

;var PopupMessage = function() {
	// If the context is global, return a new object, if we don't already have a views object. (1 views only)
	if ( window == this ) {
		return window.___popupMessage ? window.___popupMessage : new PopupMessage();
	}
	
	window.___popupMessage = this;

	$(function() {
		$("<div id=\"dimmer\" title=\"Click to close\" style=\"cursor: pointer; position: absolute; left: 0; top: 0; width: 100%; background: #000; z-index:100; display:none;\"></div>")
			.appendTo('body')
			.click(function() {
				PopupMessage().hide();
			});
	});
};

PopupMessage.prototype = {
	settings: {
		emptyOnHide: false,
		width: 600,
		ifixpng: 'img',
		lightboxButton: "assets/images/buttons/close.png",
		addHelpers: false,
		easing: 'easeOutCubic'
	},
	
	set: function(settings) {
		$.extend(this.settings, settings);
	},
	
	lightbox: function(content, options) {
		options = options || {};
		var $$ = $('#lightbox'), self = this;
		if (!($$.length)) {
			$$ = '<div id="lightbox"><div id="lightboxInner">' +
				'<span id="lightboxCloseLink">' +
					'<img alt="sluiten" src="' + this.settings.lightboxButton + '" id="lightboxClose"/>' +
				'</span>';
			if (this.settings.addHelpers) $$ = $$ + '<span class="top">&nbsp;</span><span class="tl">&nbsp;</span><span class="tr">&nbsp;</span>';
			$$ = $$ + '<div id="lightboxContent"></div>';
			if (this.settings.addHelpers) $$ = $$ + '<span class="bottom">&nbsp;</span><span class="bl">&nbsp;</span><span class="br">&nbsp;</span></div></div>';
			$$ = $($$).css({textAlign: 'center', position: 'absolute', left: 0, display: 'none', width: '100%'}).appendTo('body');
			$('#lightboxClose', $$).css({cursor: 'pointer', zIndex: 1001}).click(function() { self.hide(); });
			if (this.settings.shadow && $.shadow && !($.browser.msie && $.browser.version < 7 )) {
				this.settings.emptyOnHide = '.jq_shadow_inner';
				var c = $('#lightboxContent').html('<div/>').shadow($.extend({callback: helper}, this.settings.shadow));
			} else helper();
		} else helper();
		
		function helper() {
			var css = {
				width: self.settings.width,
				margin: 'auto',
				textAlign: 'left',
				position: 'relative'
			};
			
			if ($.metadata) css.width = $(content).metadata().width || css.width;
			$('#lightboxInner', $$).css(css);
			
			if (!self.settings.emptyOnHide || self.settings.emptyOnHide === true) self.settings.emptyOnHide = '#lightboxContent';
			
			self.settings.contentEl = $$.find(self.settings.emptyOnHide).html(content);
			
			self.show($$, false, options);
		}
	},
	
	// helper function to show a message (html) inside a 'lightbox'
	showMessage: function(message, options) {
		options = options || {};
		var $$ = $('#myMessageBoxHelper');
		if (!($$.length)) {
			$$ = $('<div id="myMessageBoxHelper" style="position: absolute; width: 100%; display: none; text-align: center; left: 0;"><div id="myMessageBox" style="margin: auto; position: relative;"></div></div>').appendTo('body');
		};
		var d = {width: '', height: ''};
		if ($.metadata) {
			var data = $(message).metadata();
			d.width = data.width || d.width;
			d.height = data.height || d.height;
		}
		$$.find(':first-child').css(d).html(message);
		this.show('myMessageBoxHelper', options.onShow, options);
	},
	
	show: function(control, callback, options) {
		options = options || {};
		var self = this;
		var temp = typeof control == 'string' ? $('#' + control) : $(control);
		if (!temp.length) return;
		else this.control = temp;
		$('body').children().not(this.control).find('embed, object, select').css({ 'visibility' : 'hidden'});
		
		if (callback) options.onShow = callback;
		if ($('#dimmer').is(':hidden')) {
			$('#dimmer').css({opacity: 0.4, zIndex: 900}).animate({opacity: 'show'}, 200, function() {
				self._show(temp, options);
			});
		} else this._show(temp, options);
		return this;
	},
	
	_show: function(control, options) {
		var self = this;
		this._setHeight();
		if ($.ifixpng && this.settings.ifixpng) $(this.settings.ifixpng === true ? 'img' : this.settings.ifixpng, control).ifixpng();
		control.css({zIndex: 1000, position: 'absolute', opacity: 0, display: 'block'}).animate({opacity: 1}, 200, function() {
			// Remove the opacity property in IE, as it messes with the overflow
			if ($.browser.msie) control.css('opacity', '');
			$(window).bind('resize.popupmessage scroll.popupmessage', window.___popupMessage._setHeight);
			$(document).bind('keyup.popupmessage', function(e) {
				var prevent = true;
				if (e.keyCode == 27) self.hide();
				else prevent = false;
				// If we don't do this, we stop the animated GIF as well
				if (prevent) e.preventDefault();
			});
			if ($.isFunction(options.onShow)) options.onShow.apply(control);
		});
		if ($.isFunction(options.onHide)) control.one('hide.popupmessage', options.onHide);
	},
	
	hide: function(e) {
		var self = this;
		$(window).add(document).unbind('.popupmessage');
		var $$ = $(this.control).stop().animate({opacity: 0}, function() {
			$$.hide();
			if (self.settings.emptyOnHide) {
				if ($.browser.msie) $$.find('embed,object').remove();
				$$.find(self.settings.emptyOnHide.constructor != Boolean ? self.settings.emptyOnHide : ':first-child').empty();
			}
			
			$('#dimmer').animate({opacity: 'hide'}, 300, function() {
				$('embed, object, select').css({ 'visibility' : 'visible'});
			});
		}).trigger('hide');
		
		return this;
	},
	
	_setHeight: function(e) {
		var control = $(window.___popupMessage.control);
		var $win = $(window);
		var scrolltop = $win.scrollTop();
		var location = $win.scrollTop() + ($win.height() / 2) - (control.height() / 2);
		if (location > scrolltop) {
			if (e) control.stop(true);
			control.animate({top: location}, 'fast', window.___popupMessage.settings.easing);
		}
		else if (!e) control.animate({top: scrolltop + 25}, 'fast', window.___popupMessage.settings.easing);
		$('#dimmer').height($(document).height());
	}
};;

$(init);
var currentURL = window.location.protocol + '//' + window.location.host + window.location.pathname;
if (!window.console) {
	window.console = {
		log: function() {}
	};
}
function init() {
	$.ewyseGallery.set({
		imgPath: 'assets/images/gallery/',
		img: {close: 'close.png'},
		maxHeight: 540,
		minHeight: 540,
		minWidth: 720,
		maxWidth: 720,
		autoMaxDimension: true,
		flashparams: {height: 330}
	});
	
	if ($.ie6()) {
		$.ifixpng('assets/images/pixel.gif');
		$('.kruis, div.clearSelection, #header img, #archive-image').ifixpng();
	}
	
	// Set a global AJAX loader.
	var loader = $('<div class="ajaxLoader"/>').hide().appendTo('body'), loaderTimer;
	$('body').ajaxStart(function() {
		clearTimeout(loaderTimer);
		loader.fadeIn();
	}).ajaxComplete(function() {
		$.resultsTooltip.hide(false, 0);
		clearTimeout(loaderTimer);
		loaderTimer = setTimeout(function() { loader.fadeOut(); }, 1000);
	}).ajaxError(function() {
		clearTimeout(loaderTimer);
		loaderTimer = setTimeout(function() { loader.fadeOut(); }, 1000);
	});

	if ($.browser.msie){
		try {
			document.execCommand("BackgroundImageCache", false, true);
		}
		catch (err) {}
	}
	
	PopupMessage().set({lightboxButton: 'assets/images/close.png', width: 946, shadow: {}});
	
	$('#home').shadow();
	
	$('body').removeClass('nonJS').addClass('js');
	
	processPage(this);
	
	$('#homepage a[href$=zoeken]').click(function(e) {
		e.preventDefault();
		var footer = $('#footer');
		footer.animate({opacity: 0}, 'fast');
		$.getJSON(this.href, {output: 'json', retrieve: 'template'}, function(json) {
			var template = $('#template').css('position', 'absolute');
			template.animate({opacity: 0}, 400, 'easeOutCubic', function() { 
				try { pageTracker._trackPageview('Zoeken (ajax)'); } catch (e) { if (window.console) console.log("Tracking error in init.js: " + e); }
				$('body').removeAttr('id');
				var content = $(json.content).css('opacity', 0).insertAfter(template).attr('id', 'template').animate({opacity: 1}, 'slow', function() { if ($.browser.msie) $(this).css('filter', ''); processPage(this); footer.animate({opacity: 1}); });
				template.remove();
			});
		});
	});
}

function processPage(context) {
	context = context || this;
	var sel = $('select#type');

	$('div.tagsPanel :checkbox').tags();
	
	$('input.jq_example').example(function() {
		return $(this).metadata().example;
	});

	processResults(context);
	
	//console.log($('#searchResults'));
	
	$('form#resultsForm:not(.jq_ajaxForm)').addClass('jq_ajaxForm').each(function() {
		var form = $(this), results = $('#searchResults'), timer;
		form.args({retrieve: 'content', output: 'json'}).ajaxForm({
			dataType: 'json',
			type: 'POST',
			success: function(json) {
				$('input.searchInput', form).triggerHandler('blur');
				results.hide();
				processResults(results.html(json.content).show().parent()); /* If this is done on results, rather than results.parent(), the paginator stops working after a search. */
			}}
		)
		form.find(':checkbox').bind('click change', function() {
			clearTimeout(timer);
			timer = setTimeout(function() {
				$('form#resultsForm').submit();
			}, 500);
		});
	});
	
	$('div.panelWrapper:not(.jq_clearbutton)').filter('.themesPanel, .typesPanel, .tagsPanel').addClass('jq_clearbutton').addClearButton();	
}

function processResults(context) {
	context = context || this;
	$('div.beeldPanel div.panelContent a.collection_item_url', context).ewyseGallery();
	var video = $('div.documentsDetails div.beeldPanel div.panelContent a:first', context);
	// Make document image clickable if there's a download
	 if (video.length) {
		title = 'Bekijk "' + $.trim(video.text()) + '"';
		img.attr('title', title).css('cursor', 'pointer').click(function() {
			video.click();
		});
	}
	
	$('form#mailpageForm:not(.processed), form.generalForm:not(.processed)', context)
		.addClass('processed')
		.args({output: 'json', retrieve: 'data', data: ['missing', 'validated', 'error']})
		.ajaxForm({dataType: 'json', success: ajaxFormReply, beforeSubmit: beforeFormSubmit});

	$('table.results a, div.contactsPanel div.panelContent a.collection_item_url, a.lightbox:not(".bijdrage"), div.kennisPanel div.panelContent a', context).lightbox({onShow: processResults});
	
	$('th.sortable', context).sortableColumns({defaultActive: {which: '.name', order: 'desc'}, target: '#resultsForm'});
	
	var nav = $('div.collection_navigation:not(.processed)', context).addClass('processed');
	if (nav.length) {
		var buttons = {right: $('a.nextItem', nav), left: $('a.prevItem', nav)};
		if (!buttons.right.length) buttons.right = $('<a href="#nade"><span>&gt;&gt;</span></a>').appendTo(nav);
		if (!buttons.left.length) buttons.left = $('<a href="#nade"><span>&lt;&lt;</span></a>').prependTo(nav);
		// <flip vernooij>
		// The pager didn't worked correctly when a search selection was made.
		// I fixed it by parsing the formvalues as get values behind every pager url.
		// This should only happen when the results are NOT shown in the lightbox.
		// I don't know or this is the best way to do it,.. but it works!
		var params;
		if($(context).attr('id')=='template'){
			
			params=$('form#resultsForm').serialize();
			params=params.replace('Zoek+op+trefwoorden+en%2Fof+mensen', '');
			params=unescape(params);
			params=params.split('&');
			var types=[];
			var themes=[];
			var tags=[];
			var search='';
			for(var i=0;i<params.length;i++){
				var t=params[i];
				t=t.split('=');
				var tm=t[1];
				t[1]=tm.replace('+', ' ');
				switch(t[0]){
					case "types[]":
						types.push(t[1]);
					break;
					case 'themes[]':
						themes.push(t[1]);
					break;
					case 'tags[]':
						tags.push(t[1]);
					break;
					case 'zoeken':
						search=t[1];
					break;
				}
			}
			params={output: 'json', retrieve: 'content', types: types, themes: themes, tags: tags, zoeken: search};
		}else{
			params={output: 'json', retrieve: 'content'}
		}
		$('a.page', nav).ajaxNav({
			target: nav.parent().prev(),
			preload: false,
			dimensional: false,
			keyNav: true,
			fade: false,
			callback: processResults,
			createWorkspace: true,
			classActive: 'activePage',
			ajaxParams: params,
			find: 'table',
			buttons: buttons
		}
	);
	}
	
	$('table.results tbody tr', context).resultsTooltip();
	var currentHelpItems = $('a.helpIcon', context).helpTooltip(), status = false;
	$('a.uitleg:not(.processedHelpLink)', context).addClass('processedHelpLink').click(function(e) {
		e.stopPropagation();
		if (!status) {
			status = true;
			currentHelpItems.trigger('showTooltip');
			$('body').one('click.showTooltip', function() {
				status = false;
				currentHelpItems.trigger('hideTooltip');
			});
		} else {
			$('body').unbind('click.showTooltip');
			status = false;
			currentHelpItems.trigger('hideTooltip');
		}
	});
	
	/* the z-indexes of each panel need to be descendant, so the helpballoons will fall over them */
	addZindex($(".panelWrapper:not('.tagsPanel, #searchResults')"));
	
	/* Add some boundaries to the amount of results shown in the panels */
	var listWrap = $('.detailsWrapper .contactsPanel .panelContent');
	slider(5, listWrap);

	var listWrap2 = $('.detailsWrapper .downloadsPanel .panelContent');
	slider(5, listWrap2);
	
	/* TODO: Not the best way, but this prevents the clicks on the anchors to go to an other page */	
	$("a.theme", context).click(
		function(e) {
			e.preventDefault();
			
			/* Get the theme_id by using an ugly regexp */
			var theme_id = $(this).attr("href").replace(/.*themes\[\]=([0-9]+).*/, "$1");

			/* Deselect all other checkboxes */
			$("div.themesPanel input:checkbox").removeAttr("checked");
			
			/* Select the one with the corresponding ID and send the change event so the form gets submitted */
			$("#theme_" + theme_id).attr("checked", "true").change();
			
			PopupMessage().hide();
		}
	);
}

function slider(maxLength, listWrap) {
	var speed = 400;
	if ($.ie6()) {
		speed = '';	
	}
	var list = listWrap.find('ul').children();
	
	if (list.length > maxLength) {
		list.filter(function(index) {			 
			 return index > maxLength; 
		}).css("display","none");
		/* initieel gesloten */
		listWrap.find(".slider:not(.processed)").append("Bekijk volledige lijst").css("cursor", "pointer").addClass("slidedown");	
		
		listWrap.find(".slider:not(.processed)").bind("click", function() {
			if ($(this).hasClass("slidedown")) {
				list.show(speed);			
				$(this).empty().append("Verberg lijst").removeClass("slidedown").addClass("slideup");
			}
			else if ($(this).hasClass("slideup")) {
				list.filter(function(index) {
					return index > maxLength; 
				}).hide(speed);
				$(this).empty().append("Bekijk volledige lijst").removeClass("slideup").addClass("slidedown");
			}
		}).addClass('processed');
	}
}

function addZindex(e) {
	var zindex = 100;
	e.each(function() {
		$(this).css("cssText", "z-index: "+(zindex)+" !important;");	/* for IE z-index needs to set !important */
		zindex-=10;
	});
}

function beforeFormSubmit(a, form) {
	//$('<img class=\"ajaxLoader\" src="assets/images/ajax-loader.gif">').insertAfter($('input:submit', form)).fadeIn('fast');
	$(form).add($(':submit, :image', form)).attr('disabled','disabled');
}
function ajaxFormReply(json, a, form) {
	$form = $(form);
	$form.find('.ajaxLoader').fadeOut('slow', function() { $(this).remove(); } );
	if (!json.validated) {
		$form.add($(':submit, :image', form)).removeAttr('disabled');
		if (json.missing && json.missing.length > 0) {
			$.each(json.missing, function() {
				var el = $('[name="' + this + '"]:not(.error)', form);
				if (el.length) {
					var error = el.metadata().error;
					label = $(form).find('label[for="' + el.attr('id') + '"]');
					input = $(form).find('input#' + el.attr('id'));
					if (input.length != 0) {
						var css = input.position();
						css.left += input.outerWidth() + 5;
					} else {
						var css = label.position();
						css.left += label.outerWidth() + 5;
					}
					css.position = 'absolute';
					css.cursor = 'pointer';
					if (error) {
						var message = $('<span class="errorMessage"/>')
							.text(error)
							.appendTo(el.parent())
							.css(css)
							.click(function() {
								el.focus();
							});
					}
					el.addClass('error').one('focus click', function() {
						if (error) message.remove();
						$(this).removeClass('error');
					});
				}
			});
		} else $('div.replyMessage').css('color', json.reply ? 'green' : 'red').text(json.message);
	} else $('div.replyMessage').css('color', json.reply ? 'green' : 'red').text(json.message);
}

$.fn.addClearButton = function() {
	var $button = $('<div class="clearSelection">Selectie verwijderen</div>').hoverClass('hover').click(function() {
		var fields = $(this).parent().next().find('input:checked');
		if (fields.length) {
			fields.clearFields();
			fields.each(function() {
				$(this).triggerHandler('click');
			});
		}
	});
	
	this.each(function() {
		var self = $(this).find('.panelTitleBar').append($button.clone(true));
		
	});	
	$('.clearSelection').ifixpng();
}

$.fn.sortableColumns = function(settings) {
	var items = this.filter(':not(.processed)'), target = $(settings.target), active = items.filter('.desc, .asc');
	items.addClass('processed');
	if (!active.length && settings.defaultActive && settings.defaultActive.which) active = items.filter(settings.defaultActive.which).addClass((settings.defaultActive.order || 'asc').toLowerCase());
	items.click(function() {
		var self = $(this);
		var order = self.is('.asc') ? 'desc' : 'asc';
		//if (active) active.removeClass('desc asc');

		//active = self.addClass(order);
		target.args({order: order, orderby: self.metadata().row}).submit();
	});
}

$.resultsTooltip = {
	tooltip: false,
	timer: false,
	context: false,
	status: 'hidden',
	data: {},
	
	init: function() {
		var self = this;
		if (!this.tooltip) {
			this.tooltip = $('<div class="resultsTooltip" style="display: none;"><div class="resultsTooltipInner">&nbsp;</div></div>')
				.appendTo('body')
				.hover(function () {
					self.clearTimer();
				}, function() {
					self.hide();
				});
			this.tooltip.children().shadow({imagePath: 'assets/images/tooltip-shadow/'});
		}
	},
	
	clearTimer: function() {
		clearTimeout(this.timer);
		this.timer = false;
	},
	
	show: function(content, context, options) {
		var self = this;
		options = options || {};
		
		this.data = {
			css: $(context).offset(),
			animate: {height: 'show'},
			content: content,
			context: context
		};
		
		if (!$.browser.msie) this.data.animate.opacity = 1;
		if (options.width) this.data.css.width = options.width;
		
		this.clearTimer();
		
		time = !isNaN(options.time) ? options.time : (this.status == 'show' ? 500 : 800);
		this.timer = setTimeout(function() {
			if (self.status == 'show') {
				self.hide(function() {
					self._show();
				}, 0);
			} else {
				self._show();
			}
		}, time);
	},
	
	_show: function(callback) {
		// For IE6 we don't have the q_shadow_inner element, so we need the second defined element instead
		this.tooltip.css(this.data.css).find($.ie6() ? '.resultsTooltipInner' : '.jq_shadow_inner').empty().html(this.data.content);
		this.tooltip.find('a').removeClass('processedLink').lightbox({onShow: processResults});
		this.status = 'show';
		this.tooltip.animate(this.data.animate, 'normal', 'easeOutCubic');
	},
	
	hide: function(callback, time) {
		var self = this, animate = {height: 'hide'};
		if (!$.browser.msie) animate.opacity = 0;
		if (typeof time == 'undefined') time = 300;
		this.clearTimer();

		this.timer = setTimeout(function() { self.tooltip.animate(animate, 'normal', 'easeInCubic', function() {
			self.status = 'hidden';
			if (callback) callback.apply(this);
		}); }, time);
	}
};

$.fn.resultsTooltip = function() {
	$.resultsTooltip.init();
	
	function createContent(self) {
		var content = $('<div/>').append(self.find('td.door > div').clone().addClass('contacts')).append(self.find('td.naam > div').clone().addClass('body'));
		content.find('div.description').css('display', 'block');
		return content;
	}
	
	this.filter(':not(.jq_tooltip)').addClass('jq_tooltip').each(function() {
		var self = $(this), content = false;
		self.find('*').andSelf().removeAttr('title');
		self.hover(function () {
			if (!content) content = createContent(self);
			$.resultsTooltip.show(content, this, {width: self.width() - 21});
		}, function() {
			$.resultsTooltip.hide();
		});
	});
	return this;
};

$.fn.helpTooltip = function() {
	this.filter(':not(.jq_helpTooltip)').addClass('jq_helpTooltip').each(function() {
		var self = $(this), content = false, tooltip = $(this).children('span.helpContent'), animateShow = {height: 'show'}, animateHide = {height: 'hide'}, timer;
		if (!$.browser.msie) {
			animateHide.opacity = 0;
			animateShow.opacity = 1;
		} 
		self
			.data('status', 'hidden')
			.bind('hideTooltip', function() {
				tooltip.animate(animateHide, 'normal', 'easeInCubic', function() {
					self.data('status', 'hidden');
				}); 
			}).bind('showTooltip', function() {
				clearTimeout(timer);
				if (self.data('status') != 'show') {
					self.data('status', 'show');
					tooltip.css({visibility: 'visible', display: 'none'});
					tooltip.animate(animateShow, 'normal', 'easeOutCubic');
				}
			}).click(function () {
				self.trigger('showTooltip');
			}).hover(function() {
				clearTimeout(timer);
			}, function() {
				if (self.data('status') != 'hidden') {
					timer = setTimeout(function() { 
						self.trigger('hideTooltip');
					}, 500);
				}
			});
		}).children().shadow({imagePath: 'assets/images/tooltip-shadow/'});
	return this;
};

$.fn.tags = function() {
	return this.each(function() {
		var self = $(this);
		self.bind('click change', function (e) {
			self.parent().find('[for=' + this.id + ']')[self.is(':checked') ? 'addClass' : 'removeClass']('selected');
		}).triggerHandler('click');
	});
}

$.fn.args = function(args) {
	return this.each(function() {
		if (/FORM|A/.test(this.nodeName)) {
			var url = this.href || this.action, index;
			var oldArgs = parseGetParameters(url);
			if ((index = url.indexOf('?')) > -1) url = url.substring(0, index || url.length);
			args = $.extend({}, oldArgs, args);
			$(this).attr(this.nodeName == 'FORM' ? 'action' : 'href', $.makeURL(url, args));
		}
	});
}

// Show a link in a lightbox
$.fn.lightbox = function(options) {
	this.filter('a:not(.processedLink)').addClass('processedLink').each(function() {
		$(this).bind('click', function(e) {
			e.preventDefault();
			openLinkInLightbox(this.href, options);
		});
	});
	return this;
}

window.lastLightboxURL = false;
window.lightboxStack = [];
window.lightboxBackButton = false;
function openLinkInLightbox(href, options, doNotStack) {
	options = options || {};
	if (!doNotStack) {
		lightboxStack.push({href: href, options: options});
	}
	options.onHide = function() {
		// Get rid of the last added item; it is this current box
		window.lightboxStack.pop();
	}

	var base = href.split('?')[0], args = parseGetParameters(href);
	$.extend(args, {output: 'json', retrieve: 'content'});
	var url = $.makeURL(base, args);
	$.getJSON(url, function(json) {
		try { pageTracker._trackPageview(json.name); } catch (e) { if (window.console) console.log("Tracking error in AJAX page '" + json.name + "': " + e); }
		PopupMessage().lightbox(json.content, options);
		
		// Create back button
		if (!window.lightboxBackButton) {
			window.lightboxBackButton = $('<img class="vorigeButton"/>').attr({
				src: 'assets/images/vorige.png',
				alt: 'vorige'
			}).appendTo('#lightboxInner')
			.click(function() {
				// remove current element, which is the current page
				window.lightboxStack.pop();
				// get the next in the stack, which was the previous page
				var lastItem = window.lightboxStack.pop();
				openLinkInLightbox(lastItem.href, lastItem.options, doNotStack);
			});
		}
		
		window.lightboxBackButton[window.lightboxStack.length > 1 ? 'show' : 'hide']();
	});
}

// Returns an array with either the current get-arguments or the get-arguments of the given url.
function parseGetParameters(url, noEnv) {
	var array = {}, index, args, arg, i, key;
	if ((url || (!noEnv && (url = window.location.search))) && (index = url.indexOf('?')) !== -1) {
		args = url.substring(index + 1).split(/&amp;|&/);
		var arrNum=0;
		for (i = 0; i < args.length; i++) {
			arg = args[i].split('=');
			// Remove the first entry; it's our key in this pair
			key = arg.shift();
			// If the value also contains unencoded '=' signs, we save the value by rejoining the remainings
			arg = arg.join('=');
			array[key] = (typeof(arg) != 'undefined') ? decodeURIComponent(arg) : '';
		}
	}
	return array;
};
