/* Zotonic basic Javascript library
----------------------------------------------------------

@package:	Zotonic 2009	
@Author:	Tim Benniks <tim@timbenniks.nl>
@Author:	Marc Worrell <marc@worrell.nl>

Copyright 2009-2010 Tim Benniks, Marc Worrell

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Based on nitrogen.js which is copyright 2008-2009 Rusty Klophaus

---------------------------------------------------------- */

var z_ws                    = false;
var z_ws_opened             = false;
var z_comet_is_running		= false;
var z_doing_postback		= false;
var z_spinner_show_ct		= 0;
var z_postbacks				= [];
var z_default_form_postback = false;
var z_input_updater			= false;
var z_drag_tag              = [];

/* 
We need to set the domain of the session cookie to 'test'
Then we can try to make an xhr request to 0.test, 1.test etc.
document.domain  = 'test';
var z_xhr_domain = 'test';
*/

function z_dialog_open(title, text)
{
	$('.dialog').remove();
	$.dialogAdd({title: title, text: text});
}

function z_dialog_close()
{
	$('.dialog-close').click();
}

/* Growl messages
---------------------------------------------------------- */

function z_growl_add(message, stay, type)
{
	stay = stay || false;
	type = type || 'notice';
	
	$.noticeAdd(
	{
		text: message,
		stay: stay,
		type: type
	});
	
	if(type == 'error' && window.console)
	{
		console.error(message);
	}
}

function z_growl_close()
{
	jQuery. jQuery.noticeRemove($('.notice-item-wrapper'), 400);
}


/* Postback loop
---------------------------------------------------------- */

function z_postback_check() 
{
    if (!z_postbacks.length)
    {
        z_doing_postback = false;
    }
	if (z_postbacks.length > 0)
	{
		// Send only a single postback at a time.
		z_doing_postback = true;

		var o = z_postbacks.shift();
		z_do_postback(o.triggerID, o.postback, o.extraParams);
	}
}

function z_opt_cancel(obj)
{
	var nodeName = obj.nodeName.toLowerCase();
	var nodeType = $(obj).attr("type");

	if (nodeName == 'input' &&	(nodeType == 'checkbox' || nodeType == 'radio'))
	{
		return true;
	}
	else
	{
		return false;
	}
}

function z_queue_postback(triggerID, postback, extraParams, noTriggerValue) 
{
	var triggerValue = '';

	if (triggerID != '' && !noTriggerValue)
	{
		var trigger = $('#'+triggerID).get(0);
		var nodeName = trigger.nodeName.toLowerCase();
		
		if (nodeName == 'input' || nodeName == 'button' || nodeName == 'textarea' || nodeName == 'select')
			triggerValue = $('#'+triggerID).val() || '';
	}

	extraParams = extraParams || new Array(); 
	extraParams.push({name: 'triggervalue', value: triggerValue})
	
	var o			= new Object();
	o.triggerID		= triggerID;
	o.postback		= postback;
	o.extraParams	= extraParams;
	
	z_postbacks.push(o);
    z_postback_check();
}

function z_do_postback(triggerID, postback, extraParams) 
{
	// Get params...
	var params = 
		"postback=" + urlencode(postback) + 
		"&z_trigger_id=" + urlencode(triggerID) +
		"&z_pageid=" + urlencode(z_pageid) + 
		"&" + $.param(extraParams);
	
	// logon_form and .ajax forms are always posted, as they will set cookies.
	if (z_ws && triggerID != "logon_form" && !$('#'+triggerID).hasClass("setcookie"))
	{
	    z_ws.send(params);
	}
	else
	{
    	z_ajax(triggerID, params);
	}
}

function z_ajax(triggerID, params)
{
	z_start_spinner();

	$.ajax({ 
		url:		'/postback',
		type:		'post',
		data:		params,
		dataType:	'text',
		success: function(data, textStatus) 
		{
			z_stop_spinner();
			
			try 
			{
				eval(data);
				z_init_postback_forms();
			} 
			catch(e)
			{
				$.misc.error("Error evaluating ajax return value: " + data);
				$.misc.warn(e);
			}
            setTimeout("z_postback_check()", 0);
		},
		error: function(xmlHttpRequest, textStatus, errorThrown) 
		{
			z_stop_spinner();
			
			$.misc.error("FAIL: " + textStatus);
			z_unmask_error(triggerID);
		}
	});
}

function z_unmask(id)
{
    if (id)
    {
    	var trigger = $('#'+id).get(0);
	
    	if (trigger && trigger.nodeName.toLowerCase() == 'form') 
    	{
        	try { $(trigger).unmask(); } catch (e) {};
    	}
        $(trigger).removeClass("z_error_upload");
    }
}


function z_unmask_error(id)
{
    if (id)
    {
        z_unmask(id);
        $('#'+id).addClass("z_error_upload");
    }
}


function z_progress(id, value)
{
	if (id)
	{
    	var trigger = $('#'+id).get(0);
	
    	if (trigger.nodeName.toLowerCase() == 'form') 
    	{
        	try { $(trigger).maskProgress(value); } catch (e) {};
    	}
		
	}
}

/* Comet long poll or WebSockets connection
---------------------------------------------------------- */

function z_stream_start(hostname)
{
    if (!z_ws && !z_comet_is_running)
    {
    	if ("WebSocket" in window) 
    	{
    	    z_websocket_start(hostname);
    	}
        else
    	{
    		setTimeout("z_comet();", 2000);
    		z_comet_is_running = true;
    	}
    }
}

function z_comet() 
{
	$.ajax({ 
		url: '/comet',
		type:'post',
		data: "z_pageid=" + urlencode(z_pageid),
		dataType: 'text',
		success: function(data, textStatus) 
		{
			try 
			{
				eval(data);
				z_init_postback_forms();
			} 
			catch (e)
			{
				$.misc.error("Error evaluating ajax return value: " + data);
				$.misc.warn(e);
			}
			setTimeout("z_comet();", 1000);
		},
		error: function(xmlHttpRequest, textStatus, errorThrown) 
		{
			setTimeout("z_comet();", 1000);
		}
	});
	return;
}


function z_websocket_start(hostname)
{
	z_ws = new WebSocket("ws://"+hostname+"/websocket?z_pageid="+z_pageid);

	z_ws.onopen = function() { z_ws_opened = true; };
	z_ws.onerror = function() {};

	z_ws.onclose = function (evt) 
	{
	    if (z_ws_opened)
	    {
	        // Try to reopen, might be closed to error upstream
	        setTimeout(function() { z_websocket_start(hostname); }, 10);
	    }
	    else
	    {
	        // Failed opening websocket connection - try to start comet
	        z_ws = undefined;
    		setTimeout("z_comet();", 2000);
    		z_comet_is_running = true;
	    }
	};

	z_ws.onmessage = function (evt)
	{
		try
		{
		    eval(evt.data);
			z_init_postback_forms();
		}
		catch (e)
		{
			$.misc.error("Error evaluating ajax return value: " + data);
			$.misc.warn(e);
		}
        setTimeout("z_postback_check()", 0);
	};
}


/* Utility functions
---------------------------------------------------------- */

function z_is_enter_key(event) 
{
	return (event && event.keyCode == 13);
}


/* Spinner, show when waiting for a postback
---------------------------------------------------------- */

function z_start_spinner()
{
	if (z_spinner_show_ct++ == 0)
	{
		$(document.body).addClass('wait');
		$('#spinner').fadeIn(100);
	}
}

function z_stop_spinner() 
{
	if (--z_spinner_show_ct == 0)
	{
		$('#spinner').fadeOut(100);
		$(document.body).removeClass('wait');
	}
}


/* Drag & drop interface to the postback
---------------------------------------------------------- */

function z_draggable(dragObj, dragOptions, dragTag) 
{
	dragObj.draggable(dragOptions).data("z_drag_tag", dragTag);
	z_drag_tag[dragObj.attr('id')] = dragTag;
}

function z_droppable(dropObj, dropOptions, dropPostbackInfo) 
{
	dropOptions.greedy = true;
	dropOptions.drop = function(ev, ui) 
	{
		var dragTag = $(ui.draggable[0]).data("z_drag_tag");
		var dragItem = new Array({name: 'drag_item', value: dragTag});
		z_queue_postback(this.id, dropPostbackInfo, dragItem, true);
	};

	$(dropObj).droppable(dropOptions);
}


/* Sorter and sortables interface to the postback
---------------------------------------------------------- */

function z_sortable(sortableObj, sortTag) 
{
	sortableObj.data("z_sort_tag", sortTag);
}

function z_sorter(sortBlock, sortOptions, sortPostbackInfo) 
{
	sortOptions.update = function() 
	{
		var sortItems = "";

		for (var i = 0; i < this.childNodes.length; i++) 
		{
			var sortTag = $(this.childNodes[i]).data("z_sort_tag") 
			if (!sortTag && this.childNodes[i].id)
			{
			    sortTag = z_drag_tag[this.childNodes[i].id];
			}
			if (sortTag)
			{
				if (sortItems != "") 
				{
					sortItems += ",";
				}
				
				sortItems += sortTag
			}
		}
		
		var sortItem = new Array({name: 'sort_items', value: sortItems});
		
		z_queue_postback(this.id, sortPostbackInfo, sortItem, true);
	};

	$(sortBlock).sortable(sortOptions);
}


/* typeselect input field
---------------------------------------------------------- */

function z_typeselect(ElementId, postbackInfo)
{
	if (z_input_updater)
	{
		clearTimeout(z_input_updater);
		z_input_updater = false;
	}
	
	z_input_updater = setTimeout(function()
	{
		var obj = $('#'+ElementId);

		if(obj.val().length >= 2)
		{
			obj.addClass('loading');
			z_queue_postback(ElementId, postbackInfo)
		}
	}, 400);
}


/* Form element validations
----------------------------------------------------------

Grab all "postback" forms, let them be handled by Ajax postback calls.
This function can be run multiple times.

---------------------------------------------------------- */

function z_init_postback_forms()
{
	$("form[action*='postback']").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;
				}
			}
		});
	})
	.submit(function(event)
	{
	    try { $(this).mask("", 100); } catch (e) {};
	    
		if ($('.tinymce', this).length > 0 && tinyMCE)
		{
			tinyMCE.triggerSave(true,true);
		}

		var arguments = $(this).formToArray();

		this.clk = this.clk_x = this.clk_y = null;

		var postback	= $(this).data("z_submit_postback");
		var action		= $(this).data("z_submit_action");
		var form_id		= $(this).attr('id');
		var validations = $(this).formValidationPostback();
		
		if(!postback) 
		{
			postback = z_default_form_postback;
		}
		
		if(action) 
		{
			setTimeout(action, 10);
		}

		var files = $('input:file', this).fieldValue();
		var found = false;

        if (typeof(z_only_post_forms) != "undefined" && z_only_post_forms)
        {
            found = true;
        }
        else
        {
    		for (var j=0; j < files.length && !found; j++)
    		{
    			if (files[j])
    			{
    				found = true;
    			}
    		}
        }
        
		if(found) 
		{
			$(this).postbackFileForm(form_id, postback, validations);
		}
		else
		{
			z_queue_postback(form_id, postback, arguments.concat(validations)); 
		}

		event.stopPropagation();
		return false;
	})
	.attr('action', 'pb:installed');
}

$.fn.postbackFileForm = function(trigger_id, postback, validations)
{
	var a = validations;

	a.push({name: "postback", value: postback});
	a.push({name: "z_trigger_id", value: trigger_id});
	a.push({name: "z_pageid", value: z_pageid});
	a.push({name: "z_comet", value: z_comet_is_running || z_ws});
	
	var $form = this;
	var options = {
		url:  '/postback?' + $.param(a),
		type: 'POST',
		dataType: 'text/javascript'
	};

	// hack to fix Safari hang (thanks to Tim Molendijk for this)
	// see:	 http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
	if ($.browser.safari)
		$.get('/close-connection', fileUpload);
	else
		fileUpload();
	
	// 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 = $.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 && $.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');
			var 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 domCheckCount = 3;

		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 == '') {
                    if (--domCheckCount) {
                        // in some browsers (Opera) the iframe DOM is not always traversable when
                        // the onload callback fires, so we loop a bit to accommodate

                        // MW: looks like this is not a timing issue but Opera triggering a
                        //     load event on the 100 continue.
                        cbInvoked = 0;
                        io.addEventListener('load', cb, false);
                        return;
                    }
                    log('Could not access iframe DOM after 50 tries.');
                    return;
                }

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

				var ta = doc.getElementsByTagName('textarea')[0];
				xhr.responseText = ta ? ta.value : 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) {
			    try {
    				eval(data);
			    } catch (e) {
			        z_unmask_error(form.id);
			    }
				if (g) 
				{
					$.event.trigger("ajaxSuccess", [xhr, opts]);
				}
			} else {
			    z_unmask_error(form.id);
			}
			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);
		};
	};
}


// Collect all postback validations from the form elements
$.fn.formValidationPostback = function() 
{
	var a = [];
	if(this.length == 0) return a;

	var form = this[0];
	var els	 = 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)
		{
			var v = $(el).data("z_postback_validation");
			if (v)
			{
				a.push({name: "z_v", value: n+":"+v})
			}
		}
	}
	return a;
}

// Initialize a validator for the element #id
function z_init_validator(id, args)
{
	var elt = $('#'+id);
	if (elt)
	{
		if (elt.attr('type') == 'radio')
		{
			$('input[name='+elt.attr('name')+']').each(function() {
				if (!$(this).data("z_live_validation"))
					$(this).data("z_live_validation", new LiveValidation($(this).attr('id'), args));
			});
		}
		else if (!$(elt).data("z_live_validation"))
		{
			$(elt).data("z_live_validation", new LiveValidation(id, args));
		}
	}
	else
	{
		$.misc.error('Validator error: no element with id #'+id, $(id));
	}
}

// Add a validator to the input field
function z_add_validator(id, type, args)
{
	var elt = $('#'+id);
	
	if (elt.attr('type') == 'radio')
		elt = $('input[name='+elt.attr('name')+']');

	elt.each(function() {
		var v = $(this).data("z_live_validation");

		if (v)
		{
		    if (args['pattern'])
		    {
		        args['pattern'] = new RegExp(args['pattern']);
		    }
			switch (type)
			{
				case 'email':			v.add(Validate.Email, args);		break;
				case 'presence':		v.add(Validate.Presence, args);		break;
				case 'confirmation':	v.add(Validate.Confirmation, args); break;
				case 'acceptance':		v.add(Validate.Acceptance, args);	break;
				case 'length':			v.add(Validate.Length, args);		break;
				case 'format':          v.add(Validate.Format, args);       break;
				case 'numericality':	v.add(Validate.Numericality, args); break;
				case 'postback':        
				    args['z_id'] = id;
				    v.add(Validate.Postback, args);
				    break;
				default:
				    $.misc.error("unknown validation: "+type);
				    break;
			}
		}
	});
}

function z_set_validator_postback(id, postback)
{
	if (postback)
	{
		var pb = $('#'+id).data("z_postback_validation");
		
		if (pb)
		{
			$.misc.error("Element #"+id+" had already a validation postback, add all validations as one batch.", $('#' +id));
		}

		$('#'+id).data("z_postback_validation", postback);
	}
}


function z_async_validation_result(id, isValid, testedValue)
{
	var v = $('#'+id).data("z_live_validation");

	if (v && $('#'+id).val() == testedValue)
	{
	    v.asyncValidationResult(isValid, testedValue);
    }
}

// Called by the server on validation errors
function z_validation_error(id, error)
{
	var v = $('#'+id).data("z_live_validation");
	if (v)
	{
    	if (error == 'invalid')
    	{
    		// Generic error - handle it ourselves
    		error = "please correct";
    	}
	    v.showErrorMessage(error);
    }
}

// URL encode function that is more RFC compatible.	 Also encodes +, *, / and @.
function urlencode(s)
{
	s = escape(s);
	s = s.replace(/\+/g, '%2B');
	s = s.replace(/\*/g, '%2A');
	s = s.replace(/\//g, '%2F');
	s = s.replace(/@/g, '%40');
	return s;
}

// HTML escape a string so it is safe to concatenate when making tags.
function html_escape(s)
{
	s.replace(/&/, "&amp;").replace(/</, "&lt;").replace(/>/, "&gt;").replace(/"/, "&quot;");
}


// From: http://malsup.com/jquery/form/jquery.form.js

/*
 * jQuery Form Plugin
 * version: 2.28 (10-MAY-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
 */

/**
 * 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 ($(el).hasClass("nosubmit")) 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});
	}

	// add submitting element to data if we know it
	var sub = form.clk;
	if (sub) {
		var n = sub.name;
		if (n && !sub.disabled) {
			a.push({name: n, value: ''});
		}
	}


	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 == 'radio' && !el.checked ||
		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
		tag == 'select' && el.selectedIndex == -1))
			return null;
	
	// Return empty value for non-checked checkboxes
	if (successful && t == 'checkbox' && !el.checked)
		return '';

	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 (window.console && window.console.log)
		window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
}
;
/* Admin widgetManager class
----------------------------------------------------------

@package:	Zotonic 2009	
@Author: 	Tim Benniks <tim@timbenniks.nl>

Copyright 2009 Tim Benniks

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

---------------------------------------------------------- */

;(function($)
{
	$.extend(
	{
		widgetManager: function(context)
		{
			context 	= context || document.body;
			var stack 	= [context];

			while(stack.length > 0)
			{
				var objectClass, objectOptions, functionName, defaults, element = stack.pop();
				
				if(element.className && (objectClass = new RegExp("do_([\\w_]+)", "g").exec(element.className)))
				{
					functionName = objectClass[1];
					
					if(typeof $(element)[functionName] == "function")
					{
						if($.ui && $.ui[functionName] && $.ui[functionName].defaults)
						{
							defaults = $.ui[functionName].defaults;
						}
						else
						{
							defaults = {}
						}
						
						objectOptions = $.extend({}, defaults, $(element).metadata());
						$(element)[functionName](objectOptions);
					}
				}

				if(element.childNodes) 
				{
				    for(var i = 0; i< element.childNodes.length; i++)
					{
						if(element.childNodes[i].nodeType != 3)
						{
							stack.unshift(element.childNodes[i]);
						}
					}
				}
			}
		},
		
		misc: 
		{
			log: function(obj)
			{
				if(window.console) 
				{
					console.log(obj);
	
					if($.noticeAdd)
					{
						$.noticeAdd({
							text: 'Logging, check firebug: '+obj, 
							type: 'notice', 
							stay: 0
						});
					}
				} 
				else 
				{
					if($.noticeAdd)
					{
						$.noticeAdd({
							text: 'logged: '+obj, 
							type: 'notice', 
							stay: 0
						});
					}
					else
					{
						alert(obj.toSource());
					}
				}
			},
			
			warn: function(text, obj)
			{
				obj = obj || '';
				
				if(window.console) 
				{
					console.warn(text, obj);
				}
				
				if($.noticeAdd)
				{
					$.noticeAdd({
						text: text, 
						type: 'notice', 
						stay: 1
					});
				}
			},
			
			error: function(text, obj)
			{
				obj = obj || '';

				if(window.console) 
				{
					console.error(text, obj);
				}
				
				if($.noticeAdd)
				{
					$.noticeAdd({
						text: text, 
						type: 'error', 
						stay: 1
					});
				}
			}
		},
		
		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);
				
				// check for empty string in single property
				if(!settings.single.length)
				{
					settings.single = 'metadata';
				}
				
				var data = $.data(elem, settings.single);
				
				// returned cached data if it already exists
				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 );
	};
    
	$.fn.widgetManager = function(opts)
	{
	    $.widgetManager(this[0]);
	};

})(jQuery);;
/*
 * jQuery Cycle Plugin (with Transition Definitions)
 * Examples and documentation at: http://jquery.malsup.com/cycle/
 * Copyright (c) 2007-2009 M. Alsup
 * Version: 2.73 (04-NOV-2009)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Requires: jQuery v1.2.6 or later
 *
 * Originally based on the work of:
 *	1) Matt Oakes
 *	2) Torsten Baldes (http://medienfreunde.com/lab/innerfade/)
 *	3) Benjamin Sterling (http://www.benjaminsterling.com/experiments/jqShuffle/)
 */
(function(i){var l="2.73";if(i.support==undefined){i.support={opacity:!(i.browser.msie)}}function a(q){if(i.fn.cycle.debug){f(q)}}function f(){if(window.console&&window.console.log){window.console.log("[cycle] "+Array.prototype.join.call(arguments," "))}}i.fn.cycle=function(r,q){var s={s:this.selector,c:this.context};if(this.length===0&&r!="stop"){if(!i.isReady&&s.s){f("DOM not ready, queuing slideshow");i(function(){i(s.s,s.c).cycle(r,q)});return this}f("terminating; zero elements found by selector"+(i.isReady?"":" (DOM not ready)"));return this}return this.each(function(){var w=m(this,r,q);if(w===false){return}if(this.cycleTimeout){clearTimeout(this.cycleTimeout)}this.cycleTimeout=this.cyclePause=0;var x=i(this);var y=w.slideExpr?i(w.slideExpr,this):x.children();var u=y.get();if(u.length<2){f("terminating; too few slides: "+u.length);return}var t=k(x,y,u,w,s);if(t===false){return}var v=t.continuous?10:h(t.currSlide,t.nextSlide,t,!t.rev);if(v){v+=(t.delay||0);if(v<10){v=10}a("first timeout: "+v);this.cycleTimeout=setTimeout(function(){e(u,t,0,!t.rev)},v)}})};function m(q,t,r){if(q.cycleStop==undefined){q.cycleStop=0}if(t===undefined||t===null){t={}}if(t.constructor==String){switch(t){case"stop":q.cycleStop++;if(q.cycleTimeout){clearTimeout(q.cycleTimeout)}q.cycleTimeout=0;i(q).removeData("cycle.opts");return false;case"pause":q.cyclePause=1;return false;case"resume":q.cyclePause=0;if(r===true){t=i(q).data("cycle.opts");if(!t){f("options not found, can not resume");return false}if(q.cycleTimeout){clearTimeout(q.cycleTimeout);q.cycleTimeout=0}e(t.elements,t,1,1)}return false;case"prev":case"next":var u=i(q).data("cycle.opts");if(!u){f('options not found, "prev/next" ignored');return false}i.fn.cycle[t](u);return false;default:t={fx:t}}return t}else{if(t.constructor==Number){var s=t;t=i(q).data("cycle.opts");if(!t){f("options not found, can not advance slide");return false}if(s<0||s>=t.elements.length){f("invalid slide index: "+s);return false}t.nextSlide=s;if(q.cycleTimeout){clearTimeout(q.cycleTimeout);q.cycleTimeout=0}if(typeof r=="string"){t.oneTimeFx=r}e(t.elements,t,1,s>=t.currSlide);return false}}return t}function b(q,r){if(!i.support.opacity&&r.cleartype&&q.style.filter){try{q.style.removeAttribute("filter")}catch(s){}}}function k(y,J,u,t,E){var C=i.extend({},i.fn.cycle.defaults,t||{},i.metadata?y.metadata():i.meta?y.data():{});if(C.autostop){C.countdown=C.autostopCount||u.length}var r=y[0];y.data("cycle.opts",C);C.$cont=y;C.stopCount=r.cycleStop;C.elements=u;C.before=C.before?[C.before]:[];C.after=C.after?[C.after]:[];C.after.unshift(function(){C.busy=0});if(!i.support.opacity&&C.cleartype){C.after.push(function(){b(this,C)})}if(C.continuous){C.after.push(function(){e(u,C,0,!C.rev)})}n(C);if(!i.support.opacity&&C.cleartype&&!C.cleartypeNoBg){g(J)}if(y.css("position")=="static"){y.css("position","relative")}if(C.width){y.width(C.width)}if(C.height&&C.height!="auto"){y.height(C.height)}if(C.startingSlide){C.startingSlide=parseInt(C.startingSlide)}if(C.random){C.randomMap=[];for(var H=0;H<u.length;H++){C.randomMap.push(H)}C.randomMap.sort(function(L,w){return Math.random()-0.5});C.randomIndex=0;C.startingSlide=C.randomMap[0]}else{if(C.startingSlide>=u.length){C.startingSlide=0}}C.currSlide=C.startingSlide=C.startingSlide||0;var x=C.startingSlide;J.css({position:"absolute",top:0,left:0}).hide().each(function(w){var L=x?w>=x?u.length-(w-x):x-w:u.length-w;i(this).css("z-index",L)});i(u[x]).css("opacity",1).show();b(u[x],C);if(C.fit&&C.width){J.width(C.width)}if(C.fit&&C.height&&C.height!="auto"){J.height(C.height)}var D=C.containerResize&&!y.innerHeight();if(D){var v=0,B=0;for(var F=0;F<u.length;F++){var q=i(u[F]),K=q[0],A=q.outerWidth(),I=q.outerHeight();if(!A){A=K.offsetWidth}if(!I){I=K.offsetHeight}v=A>v?A:v;B=I>B?I:B}if(v>0&&B>0){y.css({width:v+"px",height:B+"px"})}}if(C.pause){y.hover(function(){this.cyclePause++},function(){this.cyclePause--})}if(c(C)===false){return false}var s=false;t.requeueAttempts=t.requeueAttempts||0;J.each(function(){var N=i(this);this.cycleH=(C.fit&&C.height)?C.height:N.height();this.cycleW=(C.fit&&C.width)?C.width:N.width();if(N.is("img")){var L=(i.browser.msie&&this.cycleW==28&&this.cycleH==30&&!this.complete);var O=(i.browser.mozilla&&this.cycleW==34&&this.cycleH==19&&!this.complete);var M=(i.browser.opera&&((this.cycleW==42&&this.cycleH==19)||(this.cycleW==37&&this.cycleH==17))&&!this.complete);var w=(this.cycleH==0&&this.cycleW==0&&!this.complete);if(L||O||M||w){if(E.s&&C.requeueOnImageNotLoaded&&++t.requeueAttempts<100){f(t.requeueAttempts," - img slide not loaded, requeuing slideshow: ",this.src,this.cycleW,this.cycleH);setTimeout(function(){i(E.s,E.c).cycle(t)},C.requeueTimeout);s=true;return false}else{f("could not determine size of image: "+this.src,this.cycleW,this.cycleH)}}}return true});if(s){return false}C.cssBefore=C.cssBefore||{};C.animIn=C.animIn||{};C.animOut=C.animOut||{};J.not(":eq("+x+")").css(C.cssBefore);if(C.cssFirst){i(J[x]).css(C.cssFirst)}if(C.timeout){C.timeout=parseInt(C.timeout);if(C.speed.constructor==String){C.speed=i.fx.speeds[C.speed]||parseInt(C.speed)}if(!C.sync){C.speed=C.speed/2}while((C.timeout-C.speed)<250){C.timeout+=C.speed}}if(C.easing){C.easeIn=C.easeOut=C.easing}if(!C.speedIn){C.speedIn=C.speed}if(!C.speedOut){C.speedOut=C.speed}C.slideCount=u.length;C.currSlide=C.lastSlide=x;if(C.random){C.nextSlide=C.currSlide;if(++C.randomIndex==u.length){C.randomIndex=0}C.nextSlide=C.randomMap[C.randomIndex]}else{C.nextSlide=C.startingSlide>=(u.length-1)?0:C.startingSlide+1}if(!C.multiFx){var G=i.fn.cycle.transitions[C.fx];if(i.isFunction(G)){G(y,J,C)}else{if(C.fx!="custom"&&!C.multiFx){f("unknown transition: "+C.fx,"; slideshow terminating");return false}}}var z=J[x];if(C.before.length){C.before[0].apply(z,[z,z,C,true])}if(C.after.length>1){C.after[1].apply(z,[z,z,C,true])}if(C.next){i(C.next).bind(C.prevNextEvent,function(){return o(C,C.rev?-1:1)})}if(C.prev){i(C.prev).bind(C.prevNextEvent,function(){return o(C,C.rev?1:-1)})}if(C.pager){d(u,C)}j(C,u);return C}function n(q){q.original={before:[],after:[]};q.original.cssBefore=i.extend({},q.cssBefore);q.original.cssAfter=i.extend({},q.cssAfter);q.original.animIn=i.extend({},q.animIn);q.original.animOut=i.extend({},q.animOut);i.each(q.before,function(){q.original.before.push(this)});i.each(q.after,function(){q.original.after.push(this)})}function c(w){var u,s,r=i.fn.cycle.transitions;if(w.fx.indexOf(",")>0){w.multiFx=true;w.fxs=w.fx.replace(/\s*/g,"").split(",");for(u=0;u<w.fxs.length;u++){var v=w.fxs[u];s=r[v];if(!s||!r.hasOwnProperty(v)||!i.isFunction(s)){f("discarding unknown transition: ",v);w.fxs.splice(u,1);u--}}if(!w.fxs.length){f("No valid transitions named; slideshow terminating.");return false}}else{if(w.fx=="all"){w.multiFx=true;w.fxs=[];for(p in r){s=r[p];if(r.hasOwnProperty(p)&&i.isFunction(s)){w.fxs.push(p)}}}}if(w.multiFx&&w.randomizeEffects){var t=Math.floor(Math.random()*20)+30;for(u=0;u<t;u++){var q=Math.floor(Math.random()*w.fxs.length);w.fxs.push(w.fxs.splice(q,1)[0])}a("randomized fx sequence: ",w.fxs)}return true}function j(r,q){r.addSlide=function(u,v){var t=i(u),w=t[0];if(!r.autostopCount){r.countdown++}q[v?"unshift":"push"](w);if(r.els){r.els[v?"unshift":"push"](w)}r.slideCount=q.length;t.css("position","absolute");t[v?"prependTo":"appendTo"](r.$cont);if(v){r.currSlide++;r.nextSlide++}if(!i.support.opacity&&r.cleartype&&!r.cleartypeNoBg){g(t)}if(r.fit&&r.width){t.width(r.width)}if(r.fit&&r.height&&r.height!="auto"){$slides.height(r.height)}w.cycleH=(r.fit&&r.height)?r.height:t.height();w.cycleW=(r.fit&&r.width)?r.width:t.width();t.css(r.cssBefore);if(r.pager){i.fn.cycle.createPagerAnchor(q.length-1,w,i(r.pager),q,r)}if(i.isFunction(r.onAddSlide)){r.onAddSlide(t)}else{t.hide()}}}i.fn.cycle.resetState=function(r,q){q=q||r.fx;r.before=[];r.after=[];r.cssBefore=i.extend({},r.original.cssBefore);r.cssAfter=i.extend({},r.original.cssAfter);r.animIn=i.extend({},r.original.animIn);r.animOut=i.extend({},r.original.animOut);r.fxFn=null;i.each(r.original.before,function(){r.before.push(this)});i.each(r.original.after,function(){r.after.push(this)});var s=i.fn.cycle.transitions[q];if(i.isFunction(s)){s(r.$cont,i(r.elements),r)}};function e(x,q,w,y){if(w&&q.busy&&q.manualTrump){i(x).stop(true,true);q.busy=false}if(q.busy){return}var u=q.$cont[0],A=x[q.currSlide],z=x[q.nextSlide];if(u.cycleStop!=q.stopCount||u.cycleTimeout===0&&!w){return}if(!w&&!u.cyclePause&&((q.autostop&&(--q.countdown<=0))||(q.nowrap&&!q.random&&q.nextSlide<q.currSlide))){if(q.end){q.end(q)}return}if(w||!u.cyclePause){var v=q.fx;A.cycleH=A.cycleH||i(A).height();A.cycleW=A.cycleW||i(A).width();z.cycleH=z.cycleH||i(z).height();z.cycleW=z.cycleW||i(z).width();if(q.multiFx){if(q.lastFx==undefined||++q.lastFx>=q.fxs.length){q.lastFx=0}v=q.fxs[q.lastFx];q.currFx=v}if(q.oneTimeFx){v=q.oneTimeFx;q.oneTimeFx=null}i.fn.cycle.resetState(q,v);if(q.before.length){i.each(q.before,function(B,C){if(u.cycleStop!=q.stopCount){return}C.apply(z,[A,z,q,y])})}var s=function(){i.each(q.after,function(B,C){if(u.cycleStop!=q.stopCount){return}C.apply(z,[A,z,q,y])})};if(q.nextSlide!=q.currSlide){q.busy=1;if(q.fxFn){q.fxFn(A,z,q,s,y)}else{if(i.isFunction(i.fn.cycle[q.fx])){i.fn.cycle[q.fx](A,z,q,s)}else{i.fn.cycle.custom(A,z,q,s,w&&q.fastOnEvent)}}}q.lastSlide=q.currSlide;if(q.random){q.currSlide=q.nextSlide;if(++q.randomIndex==x.length){q.randomIndex=0}q.nextSlide=q.randomMap[q.randomIndex]}else{var t=(q.nextSlide+1)==x.length;q.nextSlide=t?0:q.nextSlide+1;q.currSlide=t?x.length-1:q.nextSlide-1}if(q.pager){i.fn.cycle.updateActivePagerLink(q.pager,q.currSlide)}}var r=0;if(q.timeout&&!q.continuous){r=h(A,z,q,y)}else{if(q.continuous&&u.cyclePause){r=10}}if(r>0){u.cycleTimeout=setTimeout(function(){e(x,q,0,!q.rev)},r)}}i.fn.cycle.updateActivePagerLink=function(q,r){i(q).each(function(){i(this).find("a").removeClass("activeSlide").filter("a:eq("+r+")").addClass("activeSlide")})};function h(v,s,u,r){if(u.timeoutFn){var q=u.timeoutFn(v,s,u,r);while((q-u.speed)<250){q+=u.speed}a("calculated timeout: "+q+"; speed: "+u.speed);if(q!==false){return q}}return u.timeout}i.fn.cycle.next=function(q){o(q,q.rev?-1:1)};i.fn.cycle.prev=function(q){o(q,q.rev?1:-1)};function o(r,u){var q=r.elements;var t=r.$cont[0],s=t.cycleTimeout;if(s){clearTimeout(s);t.cycleTimeout=0}if(r.random&&u<0){r.randomIndex--;if(--r.randomIndex==-2){r.randomIndex=q.length-2}else{if(r.randomIndex==-1){r.randomIndex=q.length-1}}r.nextSlide=r.randomMap[r.randomIndex]}else{if(r.random){if(++r.randomIndex==q.length){r.randomIndex=0}r.nextSlide=r.randomMap[r.randomIndex]}else{r.nextSlide=r.currSlide+u;if(r.nextSlide<0){if(r.nowrap){return false}r.nextSlide=q.length-1}else{if(r.nextSlide>=q.length){if(r.nowrap){return false}r.nextSlide=0}}}}if(i.isFunction(r.prevNextClick)){r.prevNextClick(u>0,r.nextSlide,q[r.nextSlide])}e(q,r,1,u>=0);return false}function d(r,s){var q=i(s.pager);i.each(r,function(t,u){i.fn.cycle.createPagerAnchor(t,u,q,r,s)});i.fn.cycle.updateActivePagerLink(s.pager,s.startingSlide)}i.fn.cycle.createPagerAnchor=function(u,v,s,t,w){var r;if(i.isFunction(w.pagerAnchorBuilder)){r=w.pagerAnchorBuilder(u,v)}else{r='<a href="#">'+(u+1)+"</a>"}if(!r){return}var x=i(r);if(x.parents("body").length===0){var q=[];if(s.length>1){s.each(function(){var y=x.clone(true);i(this).append(y);q.push(y[0])});x=i(q)}else{x.appendTo(s)}}x.bind(w.pagerEvent,function(A){A.preventDefault();w.nextSlide=u;var z=w.$cont[0],y=z.cycleTimeout;if(y){clearTimeout(y);z.cycleTimeout=0}if(i.isFunction(w.pagerClick)){w.pagerClick(w.nextSlide,t[w.nextSlide])}e(t,w,1,w.currSlide<u);return false});if(w.pagerEvent!="click"){x.click(function(){return false})}if(w.pauseOnPagerHover){x.hover(function(){w.$cont[0].cyclePause++},function(){w.$cont[0].cyclePause--})}};i.fn.cycle.hopsFromLast=function(t,s){var r,q=t.lastSlide,u=t.currSlide;if(s){r=u>q?u-q:t.slideCount-q}else{r=u<q?q-u:q+t.slideCount-u}return r};function g(s){function r(t){t=parseInt(t).toString(16);return t.length<2?"0"+t:t}function q(w){for(;w&&w.nodeName.toLowerCase()!="html";w=w.parentNode){var t=i.css(w,"background-color");if(t.indexOf("rgb")>=0){var u=t.match(/\d+/g);return"#"+r(u[0])+r(u[1])+r(u[2])}if(t&&t!="transparent"){return t}}return"#ffffff"}s.each(function(){i(this).css("background-color",q(this))})}i.fn.cycle.commonReset=function(v,t,u,r,s,q){i(u.elements).not(v).hide();u.cssBefore.opacity=1;u.cssBefore.display="block";if(r!==false&&t.cycleW>0){u.cssBefore.width=t.cycleW}if(s!==false&&t.cycleH>0){u.cssBefore.height=t.cycleH}u.cssAfter=u.cssAfter||{};u.cssAfter.display="none";i(v).css("zIndex",u.slideCount+(q===true?1:0));i(t).css("zIndex",u.slideCount+(q===true?0:1))};i.fn.cycle.custom=function(B,v,q,s,r){var A=i(B),w=i(v);var t=q.speedIn,z=q.speedOut,u=q.easeIn,y=q.easeOut;w.css(q.cssBefore);if(r){if(typeof r=="number"){t=z=r}else{t=z=1}u=y=null}var x=function(){w.animate(q.animIn,t,u,s)};A.animate(q.animOut,z,y,function(){if(q.cssAfter){A.css(q.cssAfter)}if(!q.sync){x()}});if(q.sync){x()}};i.fn.cycle.transitions={fade:function(r,s,q){s.not(":eq("+q.currSlide+")").css("opacity",0);q.before.push(function(v,t,u){i.fn.cycle.commonReset(v,t,u);u.cssBefore.opacity=0});q.animIn={opacity:1};q.animOut={opacity:0};q.cssBefore={top:0,left:0}}};i.fn.cycle.ver=function(){return l};i.fn.cycle.defaults={fx:"fade",timeout:4000,timeoutFn:null,continuous:0,speed:1000,speedIn:null,speedOut:null,next:null,prev:null,prevNextClick:null,prevNextEvent:"click",pager:null,pagerClick:null,pagerEvent:"click",pagerAnchorBuilder:null,before:null,after:null,end:null,easing:null,easeIn:null,easeOut:null,shuffle:null,animIn:null,animOut:null,cssBefore:null,cssAfter:null,fxFn:null,height:"auto",startingSlide:0,sync:1,random:0,fit:0,containerResize:1,pause:0,pauseOnPagerHover:0,autostop:0,autostopCount:0,delay:0,slideExpr:null,cleartype:!i.support.opacity,cleartypeNoBg:false,nowrap:0,fastOnEvent:0,randomizeEffects:1,rev:0,manualTrump:true,requeueOnImageNotLoaded:true,requeueTimeout:250}})(jQuery);
/*
 * jQuery Cycle Plugin Transition Definitions
 * This script is a plugin for the jQuery Cycle Plugin
 * Examples and documentation at: http://malsup.com/jquery/cycle/
 * Copyright (c) 2007-2008 M. Alsup
 * Version:	 2.72
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
(function(a){a.fn.cycle.transitions.none=function(c,d,b){b.fxFn=function(g,e,f,h){a(e).show();a(g).hide();h()}};a.fn.cycle.transitions.scrollUp=function(d,e,c){d.css("overflow","hidden");c.before.push(a.fn.cycle.commonReset);var b=d.height();c.cssBefore={top:b,left:0};c.cssFirst={top:0};c.animIn={top:0};c.animOut={top:-b}};a.fn.cycle.transitions.scrollDown=function(d,e,c){d.css("overflow","hidden");c.before.push(a.fn.cycle.commonReset);var b=d.height();c.cssFirst={top:0};c.cssBefore={top:-b,left:0};c.animIn={top:0};c.animOut={top:b}};a.fn.cycle.transitions.scrollLeft=function(d,e,c){d.css("overflow","hidden");c.before.push(a.fn.cycle.commonReset);var b=d.width();c.cssFirst={left:0};c.cssBefore={left:b,top:0};c.animIn={left:0};c.animOut={left:0-b}};a.fn.cycle.transitions.scrollRight=function(d,e,c){d.css("overflow","hidden");c.before.push(a.fn.cycle.commonReset);var b=d.width();c.cssFirst={left:0};c.cssBefore={left:-b,top:0};c.animIn={left:0};c.animOut={left:b}};a.fn.cycle.transitions.scrollHorz=function(c,d,b){c.css("overflow","hidden").width();b.before.push(function(h,f,g,e){a.fn.cycle.commonReset(h,f,g);g.cssBefore.left=e?(f.cycleW-1):(1-f.cycleW);g.animOut.left=e?-h.cycleW:h.cycleW});b.cssFirst={left:0};b.cssBefore={top:0};b.animIn={left:0};b.animOut={top:0}};a.fn.cycle.transitions.scrollVert=function(c,d,b){c.css("overflow","hidden");b.before.push(function(h,f,g,e){a.fn.cycle.commonReset(h,f,g);g.cssBefore.top=e?(1-f.cycleH):(f.cycleH-1);g.animOut.top=e?h.cycleH:-h.cycleH});b.cssFirst={top:0};b.cssBefore={left:0};b.animIn={top:0};b.animOut={left:0}};a.fn.cycle.transitions.slideX=function(c,d,b){b.before.push(function(g,e,f){a(f.elements).not(g).hide();a.fn.cycle.commonReset(g,e,f,false,true);f.animIn.width=e.cycleW});b.cssBefore={left:0,top:0,width:0};b.animIn={width:"show"};b.animOut={width:0}};a.fn.cycle.transitions.slideY=function(c,d,b){b.before.push(function(g,e,f){a(f.elements).not(g).hide();a.fn.cycle.commonReset(g,e,f,true,false);f.animIn.height=e.cycleH});b.cssBefore={left:0,top:0,height:0};b.animIn={height:"show"};b.animOut={height:0}};a.fn.cycle.transitions.shuffle=function(e,f,d){var c,b=e.css("overflow","visible").width();f.css({left:0,top:0});d.before.push(function(i,g,h){a.fn.cycle.commonReset(i,g,h,true,true,true)});if(!d.speedAdjusted){d.speed=d.speed/2;d.speedAdjusted=true}d.random=0;d.shuffle=d.shuffle||{left:-b,top:15};d.els=[];for(c=0;c<f.length;c++){d.els.push(f[c])}for(c=0;c<d.currSlide;c++){d.els.push(d.els.shift())}d.fxFn=function(m,j,l,g,i){var h=i?a(m):a(j);a(j).css(l.cssBefore);var k=l.slideCount;h.animate(l.shuffle,l.speedIn,l.easeIn,function(){var o=a.fn.cycle.hopsFromLast(l,i);for(var q=0;q<o;q++){i?l.els.push(l.els.shift()):l.els.unshift(l.els.pop())}if(i){for(var r=0,n=l.els.length;r<n;r++){a(l.els[r]).css("z-index",n-r+k)}}else{var s=a(m).css("z-index");h.css("z-index",parseInt(s)+1+k)}h.animate({left:0,top:0},l.speedOut,l.easeOut,function(){a(i?this:m).hide();if(g){g()}})})};d.cssBefore={display:"block",opacity:1,top:0,left:0}};a.fn.cycle.transitions.turnUp=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,true,false);f.cssBefore.top=e.cycleH;f.animIn.height=e.cycleH});b.cssFirst={top:0};b.cssBefore={left:0,height:0};b.animIn={top:0};b.animOut={height:0}};a.fn.cycle.transitions.turnDown=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,true,false);f.animIn.height=e.cycleH;f.animOut.top=g.cycleH});b.cssFirst={top:0};b.cssBefore={left:0,top:0,height:0};b.animOut={height:0}};a.fn.cycle.transitions.turnLeft=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,true);f.cssBefore.left=e.cycleW;f.animIn.width=e.cycleW});b.cssBefore={top:0,width:0};b.animIn={left:0};b.animOut={width:0}};a.fn.cycle.transitions.turnRight=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,true);f.animIn.width=e.cycleW;f.animOut.left=g.cycleW});b.cssBefore={top:0,left:0,width:0};b.animIn={left:0};b.animOut={width:0}};a.fn.cycle.transitions.zoom=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,false,true);f.cssBefore.top=e.cycleH/2;f.cssBefore.left=e.cycleW/2;f.animIn={top:0,left:0,width:e.cycleW,height:e.cycleH};f.animOut={width:0,height:0,top:g.cycleH/2,left:g.cycleW/2}});b.cssFirst={top:0,left:0};b.cssBefore={width:0,height:0}};a.fn.cycle.transitions.fadeZoom=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,false);f.cssBefore.left=e.cycleW/2;f.cssBefore.top=e.cycleH/2;f.animIn={top:0,left:0,width:e.cycleW,height:e.cycleH}});b.cssBefore={width:0,height:0};b.animOut={opacity:0}};a.fn.cycle.transitions.blindX=function(d,e,c){var b=d.css("overflow","hidden").width();c.before.push(function(h,f,g){a.fn.cycle.commonReset(h,f,g);g.animIn.width=f.cycleW;g.animOut.left=h.cycleW});c.cssBefore={left:b,top:0};c.animIn={left:0};c.animOut={left:b}};a.fn.cycle.transitions.blindY=function(d,e,c){var b=d.css("overflow","hidden").height();c.before.push(function(h,f,g){a.fn.cycle.commonReset(h,f,g);g.animIn.height=f.cycleH;g.animOut.top=h.cycleH});c.cssBefore={top:b,left:0};c.animIn={top:0};c.animOut={top:b}};a.fn.cycle.transitions.blindZ=function(e,f,d){var c=e.css("overflow","hidden").height();var b=e.width();d.before.push(function(i,g,h){a.fn.cycle.commonReset(i,g,h);h.animIn.height=g.cycleH;h.animOut.top=i.cycleH});d.cssBefore={top:c,left:b};d.animIn={top:0,left:0};d.animOut={top:c,left:b}};a.fn.cycle.transitions.growX=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,true);f.cssBefore.left=this.cycleW/2;f.animIn={left:0,width:this.cycleW};f.animOut={left:0}});b.cssBefore={width:0,top:0}};a.fn.cycle.transitions.growY=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,true,false);f.cssBefore.top=this.cycleH/2;f.animIn={top:0,height:this.cycleH};f.animOut={top:0}});b.cssBefore={height:0,left:0}};a.fn.cycle.transitions.curtainX=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,false,true,true);f.cssBefore.left=e.cycleW/2;f.animIn={left:0,width:this.cycleW};f.animOut={left:g.cycleW/2,width:0}});b.cssBefore={top:0,width:0}};a.fn.cycle.transitions.curtainY=function(c,d,b){b.before.push(function(g,e,f){a.fn.cycle.commonReset(g,e,f,true,false,true);f.cssBefore.top=e.cycleH/2;f.animIn={top:0,height:e.cycleH};f.animOut={top:g.cycleH/2,height:0}});b.cssBefore={left:0,height:0}};a.fn.cycle.transitions.cover=function(f,g,e){var i=e.direction||"left";var b=f.css("overflow","hidden").width();var c=f.height();e.before.push(function(j,d,h){a.fn.cycle.commonReset(j,d,h);if(i=="right"){h.cssBefore.left=-b}else{if(i=="up"){h.cssBefore.top=c}else{if(i=="down"){h.cssBefore.top=-c}else{h.cssBefore.left=b}}}});e.animIn={left:0,top:0};e.animOut={opacity:1};e.cssBefore={top:0,left:0}};a.fn.cycle.transitions.uncover=function(f,g,e){var i=e.direction||"left";var b=f.css("overflow","hidden").width();var c=f.height();e.before.push(function(j,d,h){a.fn.cycle.commonReset(j,d,h,true,true,true);if(i=="right"){h.animOut.left=b}else{if(i=="up"){h.animOut.top=-c}else{if(i=="down"){h.animOut.top=c}else{h.animOut.left=-b}}}});e.animIn={left:0,top:0};e.animOut={opacity:1};e.cssBefore={top:0,left:0}};a.fn.cycle.transitions.toss=function(e,f,d){var b=e.css("overflow","visible").width();var c=e.height();d.before.push(function(i,g,h){a.fn.cycle.commonReset(i,g,h,true,true,true);if(!h.animOut.left&&!h.animOut.top){h.animOut={left:b*2,top:-c/2,opacity:0}}else{h.animOut.opacity=0}});d.cssBefore={left:0,top:0};d.animIn={left:0}};a.fn.cycle.transitions.wipe=function(s,m,e){var q=s.css("overflow","hidden").width();var j=s.height();e.cssBefore=e.cssBefore||{};var g;if(e.clip){if(/l2r/.test(e.clip)){g="rect(0px 0px "+j+"px 0px)"}else{if(/r2l/.test(e.clip)){g="rect(0px "+q+"px "+j+"px "+q+"px)"}else{if(/t2b/.test(e.clip)){g="rect(0px "+q+"px 0px 0px)"}else{if(/b2t/.test(e.clip)){g="rect("+j+"px "+q+"px "+j+"px 0px)"}else{if(/zoom/.test(e.clip)){var o=parseInt(j/2);var f=parseInt(q/2);g="rect("+o+"px "+f+"px "+o+"px "+f+"px)"}}}}}}e.cssBefore.clip=e.cssBefore.clip||g||"rect(0px 0px 0px 0px)";var k=e.cssBefore.clip.match(/(\d+)/g);var u=parseInt(k[0]),c=parseInt(k[1]),n=parseInt(k[2]),i=parseInt(k[3]);e.before.push(function(w,h,t){if(w==h){return}var d=a(w),b=a(h);a.fn.cycle.commonReset(w,h,t,true,true,false);t.cssAfter.display="block";var r=1,l=parseInt((t.speedIn/13))-1;(function v(){var y=u?u-parseInt(r*(u/l)):0;var z=i?i-parseInt(r*(i/l)):0;var A=n<j?n+parseInt(r*((j-n)/l||1)):j;var x=c<q?c+parseInt(r*((q-c)/l||1)):q;b.css({clip:"rect("+y+"px "+x+"px "+A+"px "+z+"px)"});(r++<=l)?setTimeout(v,13):d.css("display","none")})()});e.cssBefore={display:"block",opacity:1,top:0,left:0};e.animIn={left:0};e.animOut={left:0}}})(jQuery);