function parse_response(elem, address, parent_elem, custom_action){
		$.getJSON(address, {},
				function(msg){
					var list = $("#modal_window").find("div");
					list.empty();
					
					var ranks = msg['ranks'];
					
					for(var i=0; i < ranks.length; i++)
					{
						var item = $("<p style='margin:5px;'></p>");
						var rank = ranks[i];
						rank = rank.replace(/(\(\d+\))/g, '<span class="rank_chooser_count">$1</span>');
						item.html(rank);
						list.append(item);
					}
					
				}

			);
	}

(function($) {
	
	jQuery.fn.resize = function(maxSize)
	{
		var ratio = $(this).width()/$(this).height();
		if(ratio >= 1)	// szerokość >= wysokości
		{
			$(this).css('width', maxSize+'px');
			$(this).css('heiht', maxSize/ratio+'px');
		}
		else	// wysokośc > szerokości
		{
			$(this).css('height', maxSize+'px');
			$(this).css('width', maxSize*ratio+'px');
		}
	}
	
	jQuery.fn.myCorners = function(settings){
		
		settings = jQuery.extend({
			extension: '.gif',
			lastpart: '-ship',
			folder: '/images/corners/',
			lt: false,
			rt: false,
			lb: false,
			rb: false,
			all: false,
			top: false,
			bottom: false,
			left: false,
			right: false,
			zeropos: false
		}, settings);
		$(this).each(function(){
			if($.browser.msie){
				if(parseInt(jQuery.browser.version) <7)
					return;
			}
			if(settings.lt || settings.top || settings.left || settings.all){
				var element = $('<div class="corner corner-LT"></div>');
				var path = settings.folder+settings.ident+'-LT'+settings.lastpart+settings.extension;
				element.css('background-image', 'url("'+path+'")');
				
				if(settings.zeropos){
					element.css('left', '0');
					element.css('top', '0');
				}
				
				$(this).append(element);
				
			}
			
			if(settings.rt || settings.top || settings.right || settings.all){
				var element = $('<div class="corner corner-RT"></div>');
				var path = settings.folder+settings.ident+'-RT'+settings.lastpart+settings.extension;
				element.css('background-image', 'url("'+path+'")');
				
				if(settings.zeropos){
					element.css('right', '0');
					element.css('top', '0');
				}
				
				$(this).append(element);
			}
			
			if(settings.lb || settings.bottom || settings.left || settings.all){
				var element = $('<div class="corner corner-LB"></div>');
				var path = settings.folder+settings.ident+'-LB'+settings.lastpart+settings.extension;
				element.css('background-image', 'url("'+path+'")');
				
				if(settings.zeropos){
					element.css('left', '0');
					element.css('bottom', '0');
				}
				
				$(this).append(element);
			}
			
			if(settings.rb || settings.bottom || settings.right || settings.all){
				var element = $('<div class="corner corner-RB"></div>');
				var path = settings.folder+settings.ident+'-RB'+settings.lastpart+settings.extension;
				element.css('background-image', 'url("'+path+'")');
				
				if(settings.zeropos){
					element.css('right', '0');
					element.css('bottom', '0');
				}
				
				$(this).append(element);
			}
		});
	};
	
	jQuery.fn.validate = function()
	{
		var element = $(this);
		var name = $(element).val();
		$.post('/validation/register', {
			field : $(element).attr('name'),
			val : $(element).val(),
			pass : $("#password").val(),
			type : $('#reg_type').length > 0 ? $('#reg_type').val() : 'user'
		}, function(data) {
			//var nast = element.next();
			$(element).siblings('div').remove();
			var nast = $('<div class="registration-notification"></div>');
			element.after(nast);
			//nast.html(data.icon);
			$(nast).css('font-weight', 'bold');
			$(nast).css('color', '#FFFFFF');
			var img1; var img2;
			if (data.answer == false) {
				$(nast).html(data.errors);
				$(nast).css('background-color', 'red');
				img1 = $('<img src="/images/corners/registration-error-tr-ship.gif" style="position:absolute; right:-1px !important; right:-2px; top:-1px" />');
				img2 = $('<img src="/images/corners/registration-error-br-ship.gif" style="position:absolute; right:-1px !important; right:-2px; bottom:-1px!important; bottom:-2px" />');
			}
			else
			{
				$(nast).text("OK");
				$(nast).css('background-color', '#80c330');
				img1 = $('<img src="/images/corners/registration-ok-tr-ship.gif" style="position:absolute; right:-1px !important; right:-2px; top:-1px" />');
				img2 = $('<img src="/images/corners/registration-ok-br-ship.gif" style="position:absolute; right:-1px !important; right:-2px; bottom:-1px!important; bottom:-2px" />');
			}
			
			$(nast).append(img1);
			$(nast).append(img2);
		}, "json");
	}

	jQuery.fn.ajaxValidate = function(settings) {
		settings = jQuery.extend( {
			min_length : 3,
			base : '/validation/',
			method : ''
		}, settings);
		var timer = new Array();
		$(this).keyup(function() {
			var addr = settings.base + settings.method;
			var element = $(this);
			var n = $(this).attr('name');
			clearTimeout(timer[n]);
			timer[n] = setTimeout("$(\"input[name='"+n+"']\").validate()", 500);
			//validate(element);
		});
	};
	
	
	
	
	jQuery.fn.singleRankChooser = function(settings) {
		var element_name = $(this).attr('name');
		var parent_elem = $(this).parent().attr("id");
		var new_element = $('<input type="text" />');
		var hidden_element = $('<input type="hidden" name="'+element_name+'"/>');
		
		settings = jQuery.extend(
				{
					elements_name : element_name, // nazwa elementu
					back_element : hidden_element, // element zwrotny
					back_pres : new_element, // element "prezentacyjny"
												// wyświetlajacy nazwe
					back_pres_val : '', // wartosc domyslna elementu
										// prezentacyjnego
					href : '/main/select_new_rank',
					dialogClass : 'top_dialog',
					position : 'top',
					hide : 'slide',
					modal : true,
					resizable : false,
					draggable : false,
					element_id : "modal_window",
					width : 900,
					custom_action : null,
					title : $("#select_rank_title").val(),
					select_rank_cancel_src : $("#select_rank_cancel_src").val()
				}, settings);
		
		
		$(this).after(new_element).after(hidden_element);
		if($(this).val()){
			hidden_element.val($(this).val());
			new_element.val($(this).children("option[value='" + $(this).val() + "']").html());
		}
		
		var timer = 0;
		
		$(this).remove();
		$("#modal_window a.rank_pos").live("click", function(){
			$("#"+parent_elem+" > input[type=text]").val($(this).text()).focus();
			$("#"+parent_elem+" > input[name=ship_rank_id]").val($(this).attr('rank_id'));
			//var lock =  $('#submit_lock').length!=0 && $('#submit_lock').val()=="1";
			var lock = false;
			if(settings.custom_action && !lock)
			{
				settings.custom_action($(this).attr('rank_id'), $(this).text());
				$("body").append($('<input type="hidden" id="submit_lock" value="1" />'));
			}
			$("#"+parent_elem+" > input[type=hidden]").change();
			$("#modal_window").dialog('close');
			$(".ui-dialog").empty();
			$(".ui-dialog").remove();
			$(".ui-effects-wrapper").remove();
		});
		new_element.click(function() {
			
			var elem = $('<div id="' + settings.element_id + '"></div>');
			var textbox = $("<table style='width:780px; margin-left:0; margin-bottom: 15px;'></table>");
			textbox.append($("<tr><td></td><td style='text-align:left'><span style='font-size:12px; color:#898989;'>"+$("#select_rank_examples").val()+"</span></td></tr>"));
			textbox.append($("<tr><td style='font-size: 22px; width:230px; color:#2c2c2c; padding-right:20px; text-align:right'>"+$("#select_rank_search").val()+"<br />"+$("#select_rank_click").val()+"</td><td style='text-align:left'><input type='text' id='rank_name_part' /></td></tr>"));
			elem.append(textbox);
			textbox.append($("<tr><td></td><td><div style='height:300px; overflow:auto; margin:0px; margin-right:125px; text-align:left;'></div></td>"));
			elem.append($("<p><a href='#' id='select_rank_cancel'><img alt='cancel' src='/"+settings.select_rank_cancel_src+"' /></a></p>"));
			elem.dialog(settings);
			parse_response(elem, settings.href, parent_elem);
			if($.browser.msie){
				$(".ui-widget-overlay").width(document.body.clientWidth);	
			}
			
			
			elem.find('#select_rank_cancel').click(function(){
				$("#"+parent_elem).find("input[name='ship_rank_id']").keypress();
				elem.dialog('close');
				$(".ui-dialog").empty();
				$(".ui-dialog").remove();
				$(".ui-effects-wrapper").remove();
				return false;
			});
		
		$("#rank_name_part").live("keyup", function(){
			clearTimeout(timer);
			var link = settings.href.split('?');
			link[0] += "/"+escape($(this).val().replace("/", "*"));
			link = link.join('?');
			timer = setTimeout("parse_response($(this).parent().parent(), '" + link + "','" + parent_elem + "', null)", 500);
		});

			return jQuery;
		});

	};
	

	jQuery.fn.singleDialogDropdown = function(settings) {
		var element_name = $(this).attr('name');
		var new_element = $('<input type="text" />');
		var hidden_element = $('<input type="hidden" name="'+element_name+'"/>');
		
		settings = jQuery.extend(
				{
					remove_button : false, //ustawia, czy dostępny ma być przycisk "czyszczenia"
					elements_name : element_name, // nazwa elementu
					back_element : hidden_element, // element zwrotny
					back_pres : new_element, // element "prezentacyjny"
												// wyświetlajacy nazwe
					back_pres_val : '', // wartosc domyslna elementu
										// prezentacyjnego
					/*buttons : {
						"" : function() {
							var selected = $(this).find(
									"input[name='" + settings.elements_name
											+ "']:checked");
							var id_elem = selected.attr('element_id');
							settings.back_element.val(id_elem);
							settings.back_pres.val($(this).find(
									"label[for='" + selected.attr('id') + "']")
									.html());
							$(this).dialog("close");
						}
					},*/
					style : null,
					actions : function(){}
				}, settings);
		
		
		//settings.back_pres.val(settings.back_pres_val);
		if(settings.style != null)
			$(new_element).css(settings.style);
		$(this).after(new_element).after(hidden_element);
		if($(this).val()){
			hidden_element.val($(this).val());
			new_element.val($(this).children("option[value='" + $(this).val() + "']").html());
		}
		if(settings.remove_button != false){
			var remove_btn = $('<a href="#">Delete</a>');
			remove_btn.click(function(){
				
				settings.back_element.val('');
				settings.back_element.change();
				settings.back_pres.val('-');
				settings.back_pres.change();
			});
			
			settings.back_pres.after(remove_btn);
		}
		
		$(this).remove();
		new_element.click(function() {
			$.ajaxShow(settings, settings.href);
			settings.actions();
		});

	};


	jQuery.fn.dialogDropdown = function(settings) {
		return this.each(function(){
			$(this).singleDialogDropdown(settings);
		});
	};

	jQuery.fn.ajaxDialog = function(settings) {

		$(this).click(function() {

			var address = $(this).attr('href');
			$.ajaxShow(settings, address)

			return false;
		});

		return jQuery;

	};

	jQuery.ajaxShow = function(settings, address) {
		// Settings
		settings = jQuery.extend( {
			dialogClass : 'top_dialog',
			position : 'top',
			hide : 'slide',
			modal : true,
			resizable : false,
			draggable : false,
			element_id : "modal_window",
			load : function(){}
		}, settings);
		elem = $('<div id="' + settings.element_id + '"></div>');
		elem.dialog(settings);

		$.ajax( {
			url : address,
			success : function(msg) {

				elem.empty().append($(msg));
				if (settings.callback != null) {
					settings.callback(elem);
				}
				settings.load();
			}

		});

		return jQuery;

	};

	jQuery.fn.ajaxReload = function(settings) {
		settings = jQuery.extend( {
			callback : null
		}, settings);
		$(this).click(function() {

			var address = $(this).attr('href');

			$.post(address, {}, function(data) {
				for (d in data) {
					$('#' + d).html(data[d]);
				}
				if (settings.callback != null) {
					settings.callback();
				}
				myship_basics();
			}, "json");

			return false;
		});

		return jQuery;
	}
	
	jQuery.fn.propertyChanger = function(settings) {
		settings = jQuery.extend( {
			callback : null,
			url : null,
			title : "",
			cities_url: null,
			callback_notify: null,
			width : 800,
			height : 500
		}, settings);
		var elem = this;
		
		$.ajax({
			url : settings.url, 
			complete : function(response){
				if(response.readyState != 4) return;
				var newelem = $("<div id='property-changer'></div>");
				elem.after(newelem);
				newelem.html(response.responseText);
				newelem.find(".cancel-btn").click(function(){
					newelem.find(".cancel-btn").unbind('click');
					newelem.find(".ok-btn").unbind();
					$('#property-changer').dialog("destroy");
					$('#property-changer').remove();
				});
				newelem.find(".input_text").keyup();
				newelem.find('textarea').autoResize({
				    animateDuration : 300
				});
				newelem.find("input[type=checkbox]").change(function(){
					var name = $(this).attr('id');
					var new_name;
					if(name.search('_popular_') > 0)
						new_name = name.replace('_popular_', '_all_');
					else if(name.search('_all_') > 0)
						new_name = name.replace('_all_', '_popular_');
					else
						return;
					$("#"+new_name).click();
				});
				newelem.find("#country_id").change(function(){
					var select = $(this);
					$.ajax({
						url: settings.cities_url,
						type: "POST",
						
						data: {cid:select.val()},
						complete: function(data){
							if(data.readyState == 4)
							{
								$('#city_id').find("option").remove();
								var response = eval('('+data.responseText+')');
								response = eval('('+response.content+')');
								for(var i in response)
								{
									var option = $('<option></option>');
									$(option).text(response[i]);
									option.attr('value', i);
									$('#city_id').append(option);
								}
							}
						}
					});
				});
				newelem.find('input[type=button]').css('cursor','pointer');
				newelem.find(".ok-btn").click(function(){
					if(settings.callback != null)
						settings.callback(newelem);
					else {
						var data = new Array();
						var elems = newelem.find('.input_text');
						var null_checkbox = false;
						var counter = 0;
						for(var i=0; i<elems.length; i++)
						{
							if($(elems[i]).attr('name').length == 0) continue;
							if($(elems[i]).attr('type') == 'checkbox' && !($(elems[i]).is(':checked'))) {
								if(!null_checkbox){
									var d = new Object();
									d.name = $(elems[i]).attr('name');
									d.val = null;
									data[counter] = d;
									null_checkbox = true;
									counter++;
								}
								continue;
							}
							var d = new Object();
							d.name = $(elems[i]).attr('name');
							d.val = $(elems[i]).val() != null ? encodeURIComponent($(elems[i]).val().replace(/"/g, '\\"')) : 0;
							data[counter] = d;
							counter++;
						}
						var data_str = JSON.stringify(data);
						var url2 = settings.url.replace("/edit", "/view");
						var hider = $('<div></div>');
						hider.addClass('hider');
						hider.width(elem.width());
						hider.height(elem.height());
						hider.html('<img src="/images/wait30.gif" alt="Wait please..." style="margin-top:'+(elem.height()/2-15)+'px" />');
						elem.append(hider);
						$.ajax({
							url: url2,
							type : "POST",
							data : "data="+data_str,
							complete: function(data){
								if(data.readyState != 4) return;
								var responseElem = $(data.responseText);
								elem.replaceWith(responseElem);
								responseElem.find('a').css('cursor','pointer');
								if(settings.callback_notify && $('#'+settings.callback_notify).length > 0)
									$('#'+settings.callback_notify).change();
							}
						});
					}
					newelem.find(".ok-btn").unbind();
					newelem.find(".cancel-btn").unbind();
					newelem.dialog("destroy");
					$('#property-changer').remove();
				});
				newelem.dialog({
					modal: true,
					width: settings.width,
					height : settings.height,
					resizable: false,
					title: settings.title
				});
			}
		});
	}
	
	jQuery.fn.avatarChanger = function(settings) {
		settings = jQuery.extend( {
			callback : null,
			url : null,
			avatar: null,
			okclick: null,
			cancelclick: null,
			avatara: '',
			width: 800,
			height: 500
		}, settings);
		var dialog = $(this);
		var file_url = null;
		
		$("#avatar-change").attr('src', settings.avatar);
		
		$('.cancel-btn').click(function(){
			settings.cancelclick();
			dialog.dialog('destroy');
		});
		
		$('.ok-btn').click(function(){
			settings.okclick();
			dialog.dialog('destroy');
		});
		
		$(this).dialog({
			width: settings.width,
			minHeight: settings.height,
			title: "Edit logo",
			modal: true
		});
		
		$("#avatar-upload").change(function(){
			$(".avatar-change-error").remove();
			if($(this).val().length == 0)
				return false;
			var valid_extensions = /(.jpg|.jpeg|.gif)$/i;
			if (!valid_extensions.test($(this).val()))
			{
				var error = $('<div class="avatar-change-error"></div>');
				error.text('Wrong file extension');
				$(this).after(error);
				return false;
			}
			$("#avatar-uploader > img").css('visibility', 'visible');
			var upload_pool = $(this);
			$.ajaxFileUpload({
	                url:settings.url,
	                secureuri:false,
	                fileElementId:'avatar-upload',
	                dataType: 'json',
	                success: function (data, status)
	                {
	                    var response = eval('(' + data.content + ')');
	                    if(response.status == 0)
	                    	$('#avatar-change').attr('src', response.filename+'?date='+(new Date()).getTime());
	                    else
	                    {
	                    	var error = $('<div class="avatar-change-error"></div>');
		    				error.text(response.response);
		    				$("#avatar-upload").after(error);
	                    }
	                    $("#avatar-uploader > img").css('visibility', 'hidden');
	                }
			});
		});
		
	}
	
	jQuery.fn.photoAdder = function(settings) {
		settings = jQuery.extend( {
			before : function(){},
			success: function(){},
			title : '',
			show_btn: null,
			autoOpen: false,
			width: 800,
			height: 'auto'
		}, settings);
		
		var container = $(this);
		
		$(this).find('input[type=file]').change(function(){
			$("#photo-add-error").hide();
			if($(this).val().length == 0)
				return;
			var valid_extensions = /(.jpg)$/i;
			if (!valid_extensions.test($(this).val()))
			{
				$("#photo-add-error").text('Wrong file extension');
				$("#photo-add-error").show();
				return;
			}
		});
		
		$(this).find('.okbtn').click(function(){
			$("#photo-add-error").hide();
			var file = $(container).find("input[type=file]").val();
			if(file.length == 0)
				return false;
			var valid_extensions = /(.jpg)$/i;
			if (!valid_extensions.test(file))
			{
				$("#photo-add-error").text('Wrong file extension');
				$("#photo-add-error").show();
				return false;
			}
			
			var hash = $.sha1(file);
			
			$(container).find("input[name=name_hash]").val(hash);
			$(container).dialog("close");

			$(container).find("form").ajaxSubmit({
				success : settings.success,
				beforeSubmit: settings.before,
				clearForm : false,
				target: '#loader_'+hash,
				replaceTarget: true,
				dataType : 'html'
			});
			
		});
		
		$(this).find('.cancelbtn').click(function(){
			$("#photo-add-error").hide();
			$(container).find("form").clearForm();
			$(container).dialog("close");
		});
		
		$(container).dialog({
			modal: true,
			width: settings.width,
			height: settings.height,
			title: settings.title,
			resizable: false,
			autoOpen: settings.autoOpen
		});
		
		$(settings.show_btn).click(function(){
			$(container).dialog('open');
		});
	}

})(jQuery);

/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix" Version: 1.2, 09.03.2009 by Andreas Eberhard,
 * andreas.eberhard@gmail.com http://jquery.andreaseberhard.de/
 * 
 * Copyright (c) 2007 Andreas Eberhard Licensed under GPL
 * (http://www.opensource.org/licenses/gpl-license.php)
 * 
 * Changelog: 09.03.2009 Version 1.2 - Update for jQuery 1.3.x, removed @ from
 * selectors 11.09.2007 Version 1.1 - removed noConflict - added png-support for
 * input type=image - 01.08.2007 CSS background-image support extension added by
 * Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com 31.05.2007
 * initial Version 1.0
 * --------------------------------------------------------------------
 * @example $(function(){$(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready
 * 
 * jQuery(function(){jQuery(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready when using noConflict
 * 
 * @example $(function(){$('div.examples').pngFix();});
 * @desc Fixes all PNG's within div with class examples
 * 
 * @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
 * @desc Fixes all PNG's within div with class examples, provides blank gif for
 *       input with png
 *       --------------------------------------------------------------------
 */

(function($) {

	jQuery.fn.pngFix = function(settings) {

		// Settings
		settings = jQuery.extend( {
			blankgif : 'blank.gif'
		}, settings);

		var ie55 = (navigator.appName == "Microsoft Internet Explorer"
				&& parseInt(navigator.appVersion) == 4 && navigator.appVersion
				.indexOf("MSIE 5.5") != -1);
		var ie6 = (navigator.appName == "Microsoft Internet Explorer"
				&& parseInt(navigator.appVersion) == 4 && navigator.appVersion
				.indexOf("MSIE 6.0") != -1);

		if (jQuery.browser.msie && (ie55 || ie6)) {

			// fix images with png-source
			jQuery(this)
					.find("img[src$=.png]")
					.each(
							function() {
								jQuery(this)
										.attr('width', jQuery(this).width());
								jQuery(this).attr('height',
										jQuery(this).height());

								var prevStyle = '';
								var strNewHTML = '';
								var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(
										this).attr('id') + '" '
										: '';
								var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(
										this).attr('class') + '" '
										: '';
								var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(
										this).attr('title') + '" '
										: '';
								var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(
										this).attr('alt') + '" '
										: '';
								var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(
										this).attr('align') + ';'
										: '';
								var imgHand = (jQuery(this).parent()
										.attr('href')) ? 'cursor:hand;' : '';
								if (this.style.border) {
									prevStyle += 'border:' + this.style.border + ';';
									this.style.border = '';
								}
								if (this.style.padding) {
									prevStyle += 'padding:' + this.style.padding + ';';
									this.style.padding = '';
								}
								if (this.style.margin) {
									prevStyle += 'margin:' + this.style.margin + ';';
									this.style.margin = '';
								}
								var imgStyle = (this.style.cssText);

								strNewHTML += '<span ' + imgId + imgClass
										+ imgTitle + imgAlt;
								strNewHTML += 'style="position:relative;white-space:pre-line;display:inline-block;background:transparent;'
										+ imgAlign + imgHand;
								strNewHTML += 'width:' + jQuery(this).width()
										+ 'px;' + 'height:'
										+ jQuery(this).height() + 'px;';
								strNewHTML += 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + jQuery(
										this).attr('src') + '\', sizingMethod=\'scale\');';
								strNewHTML += imgStyle + '"></span>';
								if (prevStyle != '') {
									strNewHTML = '<span style="position:relative;display:inline-block;'
											+ prevStyle
											+ imgHand
											+ 'width:'
											+ jQuery(this).width()
											+ 'px;'
											+ 'height:'
											+ jQuery(this).height()
											+ 'px;'
											+ '">'
											+ strNewHTML
											+ '</span>';
								}

								jQuery(this).hide();
								jQuery(this).after(strNewHTML);

							});

			// fix css background pngs
			jQuery(this)
					.find("*")
					.each(
							function() {
								var bgIMG = jQuery(this)
										.css('background-image');
								if (bgIMG.indexOf(".png") != -1) {
									var iebg = bgIMG.split('url("')[1]
											.split('")')[0];
									jQuery(this)
											.css('background-image', 'none');
									jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"
											+ iebg + "',sizingMethod='scale')";
								}
							});

			// fix input with png-source
			jQuery(this)
					.find("input[src$=.png]")
					.each(
							function() {
								var bgIMG = jQuery(this).attr('src');
								jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
								jQuery(this).attr('src', settings.blankgif)
							});

		}

		return jQuery;

	};

})(jQuery);

/*
 * jQuery EasIng v1.1.2 - http://gsgd.co.uk/sandbox/jquery.easIng.php
 * 
 * Uses the built In easIng capabilities added In jQuery 1.1 to offer multiple
 * easIng options
 * 
 * Copyright (c) 2007 George Smith Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 */

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.extend(jQuery.easing, {
	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;
	}
});

/*
 * 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 Coda-Slider v1.1 - http://www.ndoherty.com/coda-slider
 * 
 * Copyright (c) 2007 Niall Doherty
 * 
 * Inspired by the clever folks at http://www.panic.com/coda Many thanks to Gian
 * Carlo Mingati. Coda-Slider is a heavily modified version of his slideViewer,
 * which can be found at
 * http://www.gcmingati.net/wordpress/wp-content/lab/jquery/imagestrip/imageslide-plugin.html
 * 
 * Requirements: - jQuery 1.2 ... available via http://www.jquery.com - jQuery
 * easing plugin (1.2) ... available via
 * http://gsgd.co.uk/sandbox/jquery/easing/ - jQuery easing compatability plugin
 * ... available via http://gsgd.co.uk/sandbox/jquery/easing/ - CSS included in
 * index.html
 */

jQuery(function() {
	jQuery("div.csw")
			.prepend(
					"<p class='loading'>Loading...<br /><img src='images/ajax-loader.gif' alt='loading...'/ ></p>");
});

jQuery.fn.codaSlider = function(settings) {
	var j = 0;
	settings = jQuery.extend( {
		easeFunc : "expoinout",
		easeTime : 750,
		toolTip : false
	}, settings);

	return this.each(function(i, el) {
		
			var container = jQuery(this);
		// Remove the preloader gif...
			container.find("p.loading").remove();
			// Self-explanatory...
			container.removeClass("csw").addClass("stripViewer");
			// Get the width of a panel, set from CSS...
			var panelWidth = container.find("div.panel").width();
			// panelCount gives us a count of the panels in the container...
			var panelCount = container.find("div.panel").size();

			// Calculate the width of all the panels when lined up end-to-end...
			var stripViewerWidth = panelWidth * panelCount;
			// Use the above width to specify the CSS width for the
			// panelContainer element...
			container.find("div.panelContainer").css("width", stripViewerWidth);
			// Set the navWidth as a multiple of panelCount to account for
			// margin-right on each li
			var navWidth = panelCount * 2;

			// Specify the current panel.
			// If the loaded URL has a hash (cross-linking), we're going to use
			// that hash to give the slider a specific starting position...
			if (location.hash && parseInt(location.hash.slice(1)) <= panelCount) {
				var cPanel = parseInt(location.hash.slice(1));
				var cnt = -(panelWidth * (cPanel - 1));
				jQuery(this).find("div.panelContainer").css( {
					left : cnt
				});
				// Otherwise, we'll just set the current panel to 1...
			} else {
				var cPanel = 1;
			}
			;
			// Create appropriate nav
			container.each(function(i) {
				// Create the Left and Right arrows
					if (settings.navs) {
						element = jQuery("<div class='stripNavL' id='stripNavL"
								+ j + "'><a href='#'></a><\/div>");
						element.find('a').append(settings.navs.left);
						jQuery(this).before(element);
						element = jQuery("<div class='stripNavR' id='stripNavR"
								+ j + "'><a href='#'></a><\/div>");
						element.find('a').append(settings.navs.right);
						jQuery(this).after(element);

					} else {
						jQuery(this).before(
								"<div class='stripNavL' id='stripNavL" + j
										+ "'><a href='#'>Left</a><\/div>");
						jQuery(this).after(
								"<div class='stripNavR' id='stripNavR" + j
										+ "'><a href='#'>Right</a><\/div>");
					}
					// Create the Tabs
					/*
					 * jQuery(this).before("<div class='stripNav' id='stripNav" +
					 * j + "'><ul><\/ul><\/div>");
					 * jQuery(this).find("div.panel").each(function(n) {
					 * jQuery("div#stripNav" + j + " ul").append("<li class='tab" + (n+1) + "'><a
					 * href='#" + (n+1) + "'>" + jQuery(this).attr("title") + "<\/a><\/li>");
					 * });
					 */
	
					// Tab nav
					jQuery("div#stripNav" + j + " a").each(function(z) {
						// Figure out the navWidth by adding up the width of
						// each li
							navWidth += jQuery(this).parent().width();
							// What happens when a nav link is clicked
							jQuery(this).bind(
									"click",
									function() {
										jQuery(this).addClass("current")
												.parent().parent().find("a")
												.not(jQuery(this)).removeClass(
														"current"); // wow!
										var cnt = -(panelWidth * z);
										cPanel = z + 1;
										jQuery(this).parent().parent().parent()
												.next().find(
														"div.panelContainer")
												.animate( {
													left : cnt
												}, settings.easeTime,
														settings.easeFunc);
									});
						});

					// Left nav
					jQuery("div#stripNavL" + j + " a").click(
							function() {
								if (cPanel == 1) {
									var cnt = -(panelWidth * (panelCount - 1));
									cPanel = panelCount;
									jQuery(this).parent().parent().find(
											"div.stripNav a.current")
											.removeClass("current").parent()
											.parent().find("li:last a")
											.addClass("current");
								} else {
									cPanel -= 1;
									var cnt = -(panelWidth * (cPanel - 1));
									jQuery(this).parent().parent().find(
											"div.stripNav a.current")
											.removeClass("current").parent()
											.prev().find("a").addClass(
													"current");
								}
								;
								jQuery(this).parent().parent().find(
										"div.panelContainer").animate( {
									left : cnt
								}, settings.easeTime, settings.easeFunc);
								// Change the URL hash (cross-linking)...
								location.hash = cPanel;
								return false;
							});

					// Right nav
					jQuery("div#stripNavR" + j + " a").click(
							function() {
								if (cPanel == panelCount) {
									var cnt = 0;
									cPanel = 1;
									jQuery(this).parent().parent().find(
											"div.stripNav a.current")
											.removeClass("current").parent()
											.parent().find("a:eq(0)").addClass(
													"current");
								} else {
									var cnt = -(panelWidth * cPanel);
									cPanel += 1;
									jQuery(this).parent().parent().find(
											"div.stripNav a.current")
											.removeClass("current").parent()
											.next().find("a").addClass(
													"current");
								}
								;
								jQuery(this).parent().parent().find(
										"div.panelContainer").animate( {
									left : cnt
								}, settings.easeTime, settings.easeFunc);
								// Change the URL hash (cross-linking)...
								location.hash = cPanel;
								return false;
							});

					// Same-page cross-linking
					jQuery("a.cross-link").click(
							function() {
								jQuery(this).parents().find(
										".stripNav ul li a:eq("
												+ (parseInt(jQuery(this).attr(
														"href").slice(1)) - 1)
												+ ")").trigger('click');
							});

					// Set the width of the nav using the navWidth figure we
					// calculated earlier. This is so the nav can be centred
					// above the slider
					jQuery("div#stripNav" + j).css("width", navWidth);

					// Specify which tab is initially set to "current". Depends
					// on if the loaded URL had a hash or not (cross-linking).
					if (location.hash
							&& parseInt(location.hash.slice(1)) <= panelCount) {
						jQuery(
								"div#stripNav" + j + " a:eq("
										+ (location.hash.slice(1) - 1) + ")")
								.addClass("current");
					} else {
						jQuery("div#stripNav" + j + " a:eq(0)").addClass(
								"current");
					}

				});

			j++;
		});
};

(function($){ 
    $.fn.extend({  
        limit: function(limit,element) {
			
			var interval, f;
			var self = $(this);
					
			$(this).focus(function(){
				interval = window.setInterval(substring,100);
			});
			
			$(this).blur(function(){
				clearInterval(interval);
				substring();
			});
			
			substringFunction = "function substring(){ var val = $(self).val();var length = val.length;if(length > limit){$(self).val($(self).val().substring(0,limit));}";
			if(typeof element != 'undefined')
				substringFunction += "if($(element).html() != limit-length){$(element).html((limit-length<=0)?'0':limit-length);}"
				
			substringFunction += "}";
			
			eval(substringFunction);
			
			
			
			substring();
			
       } 
   }); 
})(jQuery);


/*
 * jQuery autoResize (textarea auto-resizer)
 * @copyright James Padolsey http://james.padolsey.com
 * @version 1.04
 */

(function($){
    
    $.fn.autoResize = function(options) {
        // Just some abstracted details,
        // to make plugin users happy:
        var settings = $.extend({
            onResize : function(){},
            animate : true,
            animateDuration : 150,
            animateCallback : function(){},
            extraSpace : 20,
            limit: 1000
        }, options);
        // Only textarea's auto-resize:
        this.filter('textarea').each(function(){
                // Get rid of scrollbars and disable WebKit resizing:
            var textarea = $(this).css({resize:'none','overflow-y':'hidden'}),

                // Cache original height, for use later:
                origHeight = parseInt(textarea.css('height').substr(0, textarea.css('height').length-2))-settings.extraSpace,
                
                // Need clone of textarea, hidden off screen:
                clone = (function(){
                    
                    // Properties which may effect space taken up by chracters:
                    var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
                        propOb = {};
                        
                    // Create object of styles to apply:
                    $.each(props, function(i, prop){
                        propOb[prop] = textarea.css(prop);
                    });
                    
                    // Clone the actual textarea removing unique properties
                    // and insert before original textarea:
                    return textarea.clone().removeAttr('id').removeAttr('name').css({
                        position: 'absolute',
                        top: 0,
                        left: -9999
                    }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
					
                })(),
                lastScrollTop = null,
                updateSize = function() {
                    // Prepare the clone:
                    clone.height(0).val($(this).val()).scrollTop(10000);
                    // Find the height of text:
                    var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
                        toChange = $(this).add(clone);
						
                    // Don't do anything if scrollTip hasen't changed:
                    if (lastScrollTop === scrollTop) { return; }
                    lastScrollTop = scrollTop;
					
                    // Check for limit:
                    if ( scrollTop >= settings.limit ) {
                        $(this).css('overflow-y','');
                        return;
                    }
                    // Fire off callback:
                    settings.onResize.call(this);
					
                    // Either animate or directly apply height:
                    settings.animate && textarea.css('display') === 'block' ?
                        toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
                        : toChange.height(scrollTop);
                        
                };
                
           
            // Bind namespaced handlers to appropriate events:
            textarea
                .unbind('.dynSiz')
                .bind('keyup.dynSiz', updateSize)
                .bind('keydown.dynSiz', updateSize)
                .bind('change.dynSiz', updateSize)
                .bind('focus.dynSiz', updateSize);
            
        });
        
        // Chain:
        return this;
        
    };
    
    
    
})(jQuery);




/*
 * jQuery Autocomplete plugin 1.1
 *
 * Copyright (c) 2009 JĂ¶rn Zaefferer
 *
 * 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.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
 */

;(function($) {
	
$.fn.extend({
	autocomplete: function(urlOrData, options) {
		var isUrl = typeof urlOrData == "string";
		options = $.extend({}, $.Autocompleter.defaults, {
			url: isUrl ? urlOrData : null,
			data: isUrl ? null : urlOrData,
			delay: isUrl ? $.Autocompleter.defaults.delay : 10,
			max: options && !options.scroll ? 10 : 150
		}, options);
		
		// if highlight is set to false, replace it with a do-nothing function
		options.highlight = options.highlight || function(value) { return value; };
		
		// if the formatMatch option is not specified, then use formatItem for backwards compatibility
		options.formatMatch = options.formatMatch || options.formatItem;
		
		return this.each(function() {
			new $.Autocompleter(this, options);
		});
	},
	result: function(handler) {
		return this.bind("result", handler);
	},
	search: function(handler) {
		return this.trigger("search", [handler]);
	},
	flushCache: function() {
		return this.trigger("flushCache");
	},
	setOptions: function(options){
		return this.trigger("setOptions", [options]);
	},
	unautocomplete: function() {
		return this.trigger("unautocomplete");
	}
});

$.Autocompleter = function(input, options) {

	var KEY = {
		UP: 38,
		DOWN: 40,
		DEL: 46,
		TAB: 9,
		RETURN: 13,
		ESC: 27,
		COMMA: 188,
		PAGEUP: 33,
		PAGEDOWN: 34,
		BACKSPACE: 8
	};

	// Create $ object for input element
	var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);

	var timeout;
	var previousValue = "";
	var cache = $.Autocompleter.Cache(options);
	var hasFocus = 0;
	var lastKeyPressCode;
	var config = {
		mouseDownOnSelect: false
	};
	var select = $.Autocompleter.Select(options, input, selectCurrent, config);
	
	var blockSubmit;
	
	// prevent form submit in opera when selecting with return key
	$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
		if (blockSubmit) {
			blockSubmit = false;
			return false;
		}
	});

	
	// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
	$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
		// a keypress means the input has focus
		// avoids issue where input had focus before the autocomplete was applied
		hasFocus = 1;
		// track last key pressed
		lastKeyPressCode = event.keyCode;
		switch(event.keyCode) {
		
			case KEY.UP:
				event.preventDefault();
				if ( select.visible() ) {
					select.prev();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.DOWN:
				event.preventDefault();
				if ( select.visible() ) {
					select.next();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.PAGEUP:
				event.preventDefault();
				if ( select.visible() ) {
					select.pageUp();
				} else {
					onChange(0, true);
				}
				break;
				
			case KEY.PAGEDOWN:
				event.preventDefault();
				if ( select.visible() ) {
					select.pageDown();
				} else {
					onChange(0, true);
				}
				break;
			
			// matches also semicolon
			case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
			case KEY.TAB:
			case KEY.RETURN:
				if( selectCurrent() ) {
					// stop default to prevent a form submit, Opera needs special handling
					event.preventDefault();
					blockSubmit = true;
					return false;
				}
				break;
				
			case KEY.ESC:
				select.hide();
				break;
				
			default:
				clearTimeout(timeout);
				timeout = setTimeout(onChange, options.delay);
				break;
		}
	}).focus(function(){
		// track whether the field has focus, we shouldn't process any
		// results if the field no longer has focus
		hasFocus++;
	}).blur(function() {
		hasFocus = 0;
		if (!config.mouseDownOnSelect) {
			hideResults();
		}
	}).click(function() {
		// show select when clicking in a focused field
		if ( hasFocus++ > 1 && !select.visible() ) {
			onChange(0, false);
		}
		else if ( !select.visible() ) {
			onChange(0, true);
		}
	}).bind("search", function() {
		// TODO why not just specifying both arguments?
		var fn = (arguments.length > 1) ? arguments[1] : null;
		function findValueCallback(q, data) {
			var result;
			if( data && data.length ) {
				for (var i=0; i < data.length; i++) {
					if( data[i].result.toLowerCase() == q.toLowerCase() ) {
						result = data[i];
						break;
					}
				}
			}
			if( typeof fn == "function" ) fn(result);
			else $input.trigger("result", result && [result.data, result.value]);
		}
		$.each(trimWords($input.val()), function(i, value) {
			request(value, findValueCallback, findValueCallback);
		});
	}).bind("flushCache", function() {
		cache.flush();
	}).bind("setOptions", function() {
		$.extend(options, arguments[1]);
		// if we've updated the data, repopulate
		if ( "data" in arguments[1] )
			cache.populate();
	}).bind("unautocomplete", function() {
		select.unbind();
		$input.unbind();
		$(input.form).unbind(".autocomplete");
	});
	
	
	function selectCurrent() {
		var selected = select.selected();
		if( !selected )
			return false;
		
		var v = selected.result;
		previousValue = v;
		
		if ( options.multiple ) {
			var words = trimWords($input.val());
			if ( words.length > 1 ) {
				var seperator = options.multipleSeparator.length;
				var cursorAt = $(input).selection().start;
				var wordAt, progress = 0;
				$.each(words, function(i, word) {
					progress += word.length;
					if (cursorAt <= progress) {
						wordAt = i;
						return false;
					}
					progress += seperator;
				});
				words[wordAt] = v;
				// TODO this should set the cursor to the right position, but it gets overriden somewhere
				//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
				v = words.join( options.multipleSeparator );
			}
			v += options.multipleSeparator;
		}
		
		$input.val(v);
		if(options.resultId)
			$('#'+options.resultId).val(selected.data[3]);
		$input.change();
		hideResultsNow();
		$input.trigger("result", [selected.data, selected.value]);
		return true;
	}
	
	function onChange(crap, skipPrevCheck) {
		if( lastKeyPressCode == KEY.DEL ) {
			select.hide();
			return;
		}
		
		var currentValue = $input.val();
		
		if ( !skipPrevCheck && currentValue == previousValue )
			return;
		if(options.resultId && currentValue != previousValue)
			$('#'+options.resultId).val('');
		
		previousValue = currentValue;
		
		currentValue = lastWord(currentValue);
		if ( currentValue.length >= options.minChars) {
			$input.addClass(options.loadingClass);
			if (!options.matchCase)
				currentValue = currentValue.toLowerCase();
			request(currentValue, receiveData, hideResultsNow);
		} else {
			stopLoading();
			select.hide();
		}
	};
	
	function trimWords(value) {
		if (!value)
			return [""];
		if (!options.multiple)
			return [$.trim(value)];
		return $.map(value.split(options.multipleSeparator), function(word) {
			return $.trim(value).length ? $.trim(word) : null;
		});
	}
	
	function lastWord(value) {
		if ( !options.multiple )
			return value;
		var words = trimWords(value);
		if (words.length == 1) 
			return words[0];
		var cursorAt = $(input).selection().start;
		if (cursorAt == value.length) {
			words = trimWords(value)
		} else {
			words = trimWords(value.replace(value.substring(cursorAt), ""));
		}
		return words[words.length - 1];
	}
	
	// fills in the input box w/the first match (assumed to be the best match)
	// q: the term entered
	// sValue: the first matching result
	function autoFill(q, sValue){
		// autofill in the complete box w/the first match as long as the user hasn't entered in more data
		// if the last user key pressed was backspace, don't autofill
		if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
			// fill in the value (keep the case the user has typed)
			$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
			// select the portion of the value not typed by the user (so the next character will erase)
			$(input).selection(previousValue.length, previousValue.length + sValue.length);
		}
	};

	function hideResults() {
		clearTimeout(timeout);
		timeout = setTimeout(hideResultsNow, 200);
	};

	function hideResultsNow() {
		var wasVisible = select.visible();
		select.hide();
		clearTimeout(timeout);
		stopLoading();
		if (options.mustMatch) {
			// call search and run callback
			$input.search(
				function (result){
					// if no value found, clear the input box
					if( !result ) {
						if (options.multiple) {
							var words = trimWords($input.val()).slice(0, -1);
							$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
						}
						else {
							$input.val( "" );
							$input.trigger("result", null);
						}
					}
				}
			);
		}
	};

	function receiveData(q, data) {
		if ( data && data.length && hasFocus ) {
			stopLoading();
			select.display(data, q);
			autoFill(q, data[0].value);
			select.show();
		} else {
			hideResultsNow();
		}
	};

	function request(term, success, failure) {
		if (!options.matchCase)
			term = term.toLowerCase();
		var data = cache.load(term);
		// recieve the cached data
		if (data && data.length) {
			success(term, data);
		// if an AJAX url has been supplied, try loading the data now
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			
			var extraParams = {
				timestamp: +new Date()
			};
			$.each(options.extraParams, function(key, param) {
				extraParams[key] = typeof param == "function" ? param() : param;
			});
			
			$.ajax({
				// try to leverage ajaxQueue plugin to abort previous requests
				mode: "abort",
				// limit abortion to this input
				port: "autocomplete" + input.name,
				dataType: options.dataType,
				url: options.url,
				data: $.extend({
					q: lastWord(term),
					limit: options.max
				}, extraParams),
				success: function(data) {
					var parsed = options.parse && options.parse(data) || parse(data);
					cache.add(term, parsed);
					success(term, parsed);
				}
			});
		} else {
			// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
			select.emptyList();
			failure(term);
		}
	};
	
	function parse(data) {
		var parsed = [];
		var rows = data.split("\n");
		for (var i=0; i < rows.length; i++) {
			var row = $.trim(rows[i]);
			if (row) {
				row = row.split("|");
				parsed[parsed.length] = {
					data: row,
					value: row[0],
					result: options.formatResult && options.formatResult(row, row[0]) || row[0]
				};
			}
		}
		return parsed;
	};

	function stopLoading() {
		$input.removeClass(options.loadingClass);
	};

};

$.Autocompleter.defaults = {
	inputClass: "ac_input",
	resultsClass: "ac_results",
	loadingClass: "ac_loading",
	resultId: null,
	minChars: 1,
	delay: 400,
	matchCase: false,
	matchSubset: true,
	matchContains: false,
	cacheLength: 10,
	max: 100,
	mustMatch: false,
	extraParams: {},
	selectFirst: false,
	formatItem: function(row) { return row[0]; },
	formatMatch: null,
	autoFill: false,
	width: 0,
	multiple: false,
	multipleSeparator: ", ",
	highlight: function(value, term) {
		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
	},
    scroll: true,
    scrollHeight: 180
};

$.Autocompleter.Cache = function(options) {

	var data = {};
	var length = 0;
	
	function matchSubset(s, sub) {
		if (!options.matchCase) 
			s = s.toLowerCase();
		var i = s.indexOf(sub);
		if (options.matchContains == "word"){
			i = s.toLowerCase().search("\\b" + sub.toLowerCase());
		}
		if (i == -1) return false;
		return i == 0 || options.matchContains;
	};
	
	function add(q, value) {
		if (length > options.cacheLength){
			flush();
		}
		if (!data[q]){ 
			length++;
		}
		data[q] = value;
	}
	
	function populate(){
		if( !options.data ) return false;
		// track the matches
		var stMatchSets = {},
			nullData = 0;

		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
		if( !options.url ) options.cacheLength = 1;
		
		// track all options for minChars = 0
		stMatchSets[""] = [];
		
		// loop through the array and create a lookup structure
		for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
			var rawValue = options.data[i];
			// if rawValue is a string, make an array otherwise just reference the array
			rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
			
			var value = options.formatMatch(rawValue, i+1, options.data.length);
			if ( value === false )
				continue;
				
			var firstChar = value.charAt(0).toLowerCase();
			// if no lookup array for this character exists, look it up now
			if( !stMatchSets[firstChar] ) 
				stMatchSets[firstChar] = [];

			// if the match is a string
			var row = {
				value: value,
				data: rawValue,
				result: options.formatResult && options.formatResult(rawValue) || value
			};
			
			// push the current match into the set list
			stMatchSets[firstChar].push(row);

			// keep track of minChars zero items
			if ( nullData++ < options.max ) {
				stMatchSets[""].push(row);
			}
		};

		// add the data items to the cache
		$.each(stMatchSets, function(i, value) {
			// increase the cache size
			options.cacheLength++;
			// add to the cache
			add(i, value);
		});
	}
	
	// populate any existing data
	setTimeout(populate, 25);
	
	function flush(){
		data = {};
		length = 0;
	}
	
	return {
		flush: flush,
		add: add,
		populate: populate,
		load: function(q) {
			if (!options.cacheLength || !length)
				return null;
			/* 
			 * if dealing w/local data and matchContains than we must make sure
			 * to loop through all the data collections looking for matches
			 */
			if( !options.url && options.matchContains ){
				// track all matches
				var csub = [];
				// loop through all the data grids for matches
				for( var k in data ){
					// don't search through the stMatchSets[""] (minChars: 0) cache
					// this prevents duplicates
					if( k.length > 0 ){
						var c = data[k];
						$.each(c, function(i, x) {
							// if we've got a match, add it to the array
							if (matchSubset(x.value, q)) {
								csub.push(x);
							}
						});
					}
				}				
				return csub;
			} else 
			// if the exact item exists, use it
			if (data[q]){
				return data[q];
			} else
			if (options.matchSubset) {
				for (var i = q.length - 1; i >= options.minChars; i--) {
					var c = data[q.substr(0, i)];
					if (c) {
						var csub = [];
						$.each(c, function(i, x) {
							if (matchSubset(x.value, q)) {
								csub[csub.length] = x;
							}
						});
						return csub;
					}
				}
			}
			return null;
		}
	};
};

$.Autocompleter.Select = function (options, input, select, config) {
	var CLASSES = {
		ACTIVE: "ac_over"
	};
	
	var listItems,
		active = -1,
		data,
		term = "",
		needsInit = true,
		element,
		list;
	
	// Create results
	function init() {
		if (!needsInit)
			return;
		element = $("<div/>")
		.hide()
		.addClass(options.resultsClass)
		.css("position", "absolute")
		.appendTo(document.body);
	
		list = $("<ul/>").appendTo(element).mouseover( function(event) {
			if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
	            active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
			    $(target(event)).addClass(CLASSES.ACTIVE);            
	        }
		}).click(function(event) {
			$(target(event)).addClass(CLASSES.ACTIVE);
			select();
			// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
			input.focus();
			return false;
		}).mousedown(function() {
			config.mouseDownOnSelect = true;
		}).mouseup(function() {
			config.mouseDownOnSelect = false;
		});
		
		if( options.width > 0 )
			element.css("width", options.width);
			
		needsInit = false;
	} 
	
	function target(event) {
		var element = event.target;
		while(element && element.tagName != "LI")
			element = element.parentNode;
		// more fun with IE, sometimes event.target is empty, just ignore it then
		if(!element)
			return [];
		return element;
	}

	function moveSelect(step) {
		listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
		movePosition(step);
        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
        if(options.scroll) {
            var offset = 0;
            listItems.slice(0, active).each(function() {
				offset += this.offsetHeight;
			});
            if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
            } else if(offset < list.scrollTop()) {
                list.scrollTop(offset);
            }
        }
	};
	
	function movePosition(step) {
		active += step;
		if (active < 0) {
			active = listItems.size() - 1;
		} else if (active >= listItems.size()) {
			active = 0;
		}
	}
	
	function limitNumberOfItems(available) {
		return options.max && options.max < available
			? options.max
			: available;
	}
	
	function fillList() {
		list.empty();
		var max = limitNumberOfItems(data.length);
		for (var i=0; i < max; i++) {
			if (!data[i])
				continue;
			var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
			if ( formatted === false )
				continue;
			var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
			$.data(li, "ac_data", data[i]);
		}
		listItems = list.find("li");
		if ( options.selectFirst ) {
			listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
			active = 0;
		}
		// apply bgiframe if available
		if ( $.fn.bgiframe )
			list.bgiframe();
	}
	
	return {
		display: function(d, q) {
			init();
			data = d;
			term = q;
			fillList();
		},
		next: function() {
			moveSelect(1);
		},
		prev: function() {
			moveSelect(-1);
		},
		pageUp: function() {
			if (active != 0 && active - 8 < 0) {
				moveSelect( -active );
			} else {
				moveSelect(-8);
			}
		},
		pageDown: function() {
			if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
				moveSelect( listItems.size() - 1 - active );
			} else {
				moveSelect(8);
			}
		},
		hide: function() {
			element && element.hide();
			listItems && listItems.removeClass(CLASSES.ACTIVE);
			active = -1;
		},
		visible : function() {
			return element && element.is(":visible");
		},
		current: function() {
			return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
		},
		show: function() {
			var offset = $(input).offset();
			element.css({
				width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
				top: offset.top + input.offsetHeight,
				left: offset.left
			}).show();
            if(options.scroll) {
                list.scrollTop(0);
                list.css({
					maxHeight: options.scrollHeight,
					overflow: 'auto'
				});
				
                if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
					var listHeight = 0;
					listItems.each(function() {
						listHeight += this.offsetHeight;
					});
					var scrollbarsVisible = listHeight > options.scrollHeight;
                    list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
					if (!scrollbarsVisible) {
						// IE doesn't recalculate width when scrollbar disappears
						listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
					}
                }
                
            }
		},
		selected: function() {
			var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
			return selected && selected.length && $.data(selected[0], "ac_data");
		},
		emptyList: function (){
			list && list.empty();
		},
		unbind: function() {
			element && element.remove();
		}
	};
};

$.fn.selection = function(start, end) {
	if (start !== undefined) {
		return this.each(function() {
			if( this.createTextRange ){
				var selRange = this.createTextRange();
				if (end === undefined || start == end) {
					selRange.move("character", start);
					selRange.select();
				} else {
					selRange.collapse(true);
					selRange.moveStart("character", start);
					selRange.moveEnd("character", end);
					selRange.select();
				}
			} else if( this.setSelectionRange ){
				this.setSelectionRange(start, end);
			} else if( this.selectionStart ){
				this.selectionStart = start;
				this.selectionEnd = end;
			}
		});
	}
	var field = this[0];
	if ( field.createTextRange ) {
		var range = document.selection.createRange(),
			orig = field.value,
			teststring = "<->",
			textLength = range.text.length;
		range.text = teststring;
		var caretAt = field.value.indexOf(teststring);
		field.value = orig;
		this.selection(caretAt, caretAt + textLength);
		return {
			start: caretAt,
			end: caretAt + textLength
		}
	} else if( field.selectionStart !== undefined ){
		return {
			start: field.selectionStart,
			end: field.selectionEnd
		}
	}
};

})(jQuery);




/**
* @author Remy Sharp
* @url http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/
*/

(function ($) {

$.fn.hint = function (blurClass) {
  if (!blurClass) { 
    blurClass = 'blur';
  }
    
  return this.each(function () {
    // get jQuery version of 'this'
    var $input = $(this);
    
    // capture the rest of the variable to allow for reuse
      var title = $input.attr('title');
      var $form = $(this.form);
      var $win = $(window);

    function remove() {
      if ($input.val() === title && $input.hasClass(blurClass)) {
        $input.val('').removeClass(blurClass);
      }
    }

    // only apply logic if the element has the attribute
    if (title) { 
      // on blur, set value to title attr if text is blank
      $input.blur(function () {
        if (this.value === '' || $(this).hasClass(blurClass)) {
          $input.val(title).addClass(blurClass);
        }
      }).focus(remove).blur(); // now change all inputs to title
      
      // clear the pre-defined text when form is submitted
      $form.submit(remove);
      $win.unload(remove); // handles Firefox's autocomplete
    }
  });
};

})(jQuery);






/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version: 1.0.3
 * Requires jQuery 1.1.3+
 * Docs: http://docs.jquery.com/Plugins/livequery
 */

(function($) {
	
$.extend($.fn, {
	livequery: function(type, fn, fn2) {
		var self = this, q;
		
		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;
			
		// See if Live Query already exists
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context &&
				type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
					// Found the query, exit the each loop
					return (q = query) && false;
		});
		
		// Create new Live Query if it wasn't found
		q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
		
		// Make sure it is running
		q.stopped = false;
		
		// Run it immediately for the first time
		q.run();
		
		// Contnue the chain
		return this;
	},
	
	expire: function(type, fn, fn2) {
		var self = this;
		
		// Handle different call patterns
		if ($.isFunction(type))
			fn2 = fn, fn = type, type = undefined;
			
		// Find the Live Query based on arguments and stop it
		$.each( $.livequery.queries, function(i, query) {
			if ( self.selector == query.selector && self.context == query.context && 
				(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
					$.livequery.stop(query.id);
		});
		
		// Continue the chain
		return this;
	}
});

$.livequery = function(selector, context, type, fn, fn2) {
	this.selector = selector;
	this.context  = context || document;
	this.type     = type;
	this.fn       = fn;
	this.fn2      = fn2;
	this.elements = [];
	this.stopped  = false;
	
	// The id is the index of the Live Query in $.livequery.queries
	this.id = $.livequery.queries.push(this)-1;
	
	// Mark the functions for matching later on
	fn.$lqguid = fn.$lqguid || $.livequery.guid++;
	if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
	
	// Return the Live Query
	return this;
};

$.livequery.prototype = {
	stop: function() {
		var query = this;
		
		if ( this.type )
			// Unbind all bound events
			this.elements.unbind(this.type, this.fn);
		else if (this.fn2)
			// Call the second function for all matched elements
			this.elements.each(function(i, el) {
				query.fn2.apply(el);
			});
			
		// Clear out matched elements
		this.elements = [];
		
		// Stop the Live Query from running until restarted
		this.stopped = true;
	},
	
	run: function() {
		// Short-circuit if stopped
		if ( this.stopped ) return;
		var query = this;
		
		var oEls = this.elements,
			els  = $(this.selector, this.context),
			nEls = els.not(oEls);
		
		// Set elements to the latest set of matched elements
		this.elements = els;
		
		if (this.type) {
			// Bind events to newly matched elements
			nEls.bind(this.type, this.fn);
			
			// Unbind events to elements no longer matched
			if (oEls.length > 0)
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						$.event.remove(el, query.type, query.fn);
				});
		}
		else {
			// Call the first function for newly matched elements
			nEls.each(function() {
				query.fn.apply(this);
			});
			
			// Call the second function for elements no longer matched
			if ( this.fn2 && oEls.length > 0 )
				$.each(oEls, function(i, el) {
					if ( $.inArray(el, els) < 0 )
						query.fn2.apply(el);
				});
		}
	}
};

$.extend($.livequery, {
	guid: 0,
	queries: [],
	queue: [],
	running: false,
	timeout: null,
	
	checkQueue: function() {
		if ( $.livequery.running && $.livequery.queue.length ) {
			var length = $.livequery.queue.length;
			// Run each Live Query currently in the queue
			while ( length-- )
				$.livequery.queries[ $.livequery.queue.shift() ].run();
		}
	},
	
	pause: function() {
		// Don't run anymore Live Queries until restarted
		$.livequery.running = false;
	},
	
	play: function() {
		// Restart Live Queries
		$.livequery.running = true;
		// Request a run of the Live Queries
		$.livequery.run();
	},
	
	registerPlugin: function() {
		$.each( arguments, function(i,n) {
			// Short-circuit if the method doesn't exist
			if (!$.fn[n]) return;
			
			// Save a reference to the original method
			var old = $.fn[n];
			
			// Create a new method
			$.fn[n] = function() {
				// Call the original method
				var r = old.apply(this, arguments);
				
				// Request a run of the Live Queries
				$.livequery.run();
				
				// Return the original methods result
				return r;
			}
		});
	},
	
	run: function(id) {
		if (id != undefined) {
			// Put the particular Live Query in the queue if it doesn't already exist
			if ( $.inArray(id, $.livequery.queue) < 0 )
				$.livequery.queue.push( id );
		}
		else
			// Put each Live Query in the queue if it doesn't already exist
			$.each( $.livequery.queries, function(id) {
				if ( $.inArray(id, $.livequery.queue) < 0 )
					$.livequery.queue.push( id );
			});
		
		// Clear timeout if it already exists
		if ($.livequery.timeout) clearTimeout($.livequery.timeout);
		// Create a timeout to check the queue and actually run the Live Queries
		$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
	},
	
	stop: function(id) {
		if (id != undefined)
			// Stop are particular Live Query
			$.livequery.queries[ id ].stop();
		else
			// Stop all Live Queries
			$.each( $.livequery.queries, function(id) {
				$.livequery.queries[ id ].stop();
			});
	}
});

// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');

// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });


// Save a reference to the original init method
var init = $.prototype.init;

// Create a new init method that exposes two new properties: selector and context
$.prototype.init = function(a,c) {
	// Call the original init and save the result
	var r = init.apply(this, arguments);
	
	// Copy over properties if they exist already
	if (a && a.selector)
		r.context = a.context, r.selector = a.selector;
		
	// Set properties
	if ( typeof a == 'string' )
		r.context = c || document, r.selector = a;
	
	// Return the result
	return r;
};

// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
$.prototype.init.prototype = $.prototype;
	
})(jQuery);



/*
 * jQuery corner plugin
 *
 * version 1.7 (1/26/2007)
 * Plus modifications by Bennett McElwee - http://www.thunderguy.com/semicolon/2007/07/19/optimised-jquery-corners-plugin/
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

/**
 * The corner() method provides a simple way of styling DOM elements.  
 *
 * corner() takes a single string argument:  $().corner("effect corners width")
 *
 *   effect:  The name of the effect to apply, such as round or bevel. 
 *            If you don't specify an effect, rounding is used.
 *
 *   corners: The corners can be one or more of top, bottom, tr, tl, br, or bl. 
 *            By default, all four corners are adorned. 
 *
 *   width:   The width specifies the width of the effect; in the case of rounded corners this 
 *            will be the radius of the width. 
 *            Specify this value using the px suffix such as 10px, and yes it must be pixels.
 *
 * For more details see: http://methvin.com/jquery/jq-corner.html
 * For a full demo see:  http://malsup.com/jquery/corner/
 *
 *
 * @example $('.adorn').corner();
 * @desc Create round, 10px corners 
 *
 * @example $('.adorn').corner("25px");
 * @desc Create round, 25px corners 
 *
 * @example $('.adorn').corner("notch bottom");
 * @desc Create notched, 10px corners on bottom only
 *
 * @example $('.adorn').corner("tr dog 25px");
 * @desc Create dogeared, 25px corner on the top-right corner only
 *
 * @example $('.adorn').corner("round 8px").parent().css('padding', '4px').corner("round 10px");
 * @desc Create a rounded border effect by styling both the element and its parent
 * 
 * @name corner
 * @type jQuery
 * @param String options Options which control the corner style
 * @cat Plugins/Corner
 * @return jQuery
 * @author Dave Methvin (dave.methvin@gmail.com)
 * @author Mike Alsup (malsup@gmail.com)
 */
jQuery.fn.corner = function(o) {
    function hex2(s) {
        var s = parseInt(s).toString(16);
        return ( s.length < 2 ) ? '0'+s : s;
    };
    function gpc(node) {
        for ( ; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode  ) {
            var v = jQuery.css(node,'backgroundColor');
            if ( v.indexOf('rgb') >= 0 ) { 
                rgb = v.match(/\d+/g); 
                return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            if ( v && v != 'transparent' )
                return v;
        }
        return '#ffffff';
    };
    function getW(i) {
        switch(fx) {
        case 'round':  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
        case 'cool':   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
        case 'sharp':  return Math.round(width*(1-Math.cos(Math.acos(i/width))));
        case 'bite':   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
        case 'slide':  return Math.round(width*(Math.atan2(i,width/i)));
        case 'jut':    return Math.round(width*(Math.atan2(width,(width-i-1))));
        case 'curl':   return Math.round(width*(Math.atan(i)));
        case 'tear':   return Math.round(width*(Math.cos(i)));
        case 'wicked': return Math.round(width*(Math.tan(i)));
        case 'long':   return Math.round(width*(Math.sqrt(i)));
        case 'sculpt': return Math.round(width*(Math.log((width-i-1),width)));
        case 'dog':    return (i&1) ? (i+1) : width;
        case 'dog2':   return (i&2) ? (i+1) : width;
        case 'dog3':   return (i&3) ? (i+1) : width;
        case 'fray':   return (i%2)*width;
        case 'notch':  return width; 
        case 'bevel':  return i+1;
        }
    };
    o = (o||"").toLowerCase();
    var keep = /keep/.test(o);                       // keep borders?
    var cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]);  // corner color
    var sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]);  // strip color
    var width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10; // corner width
    var re = /round|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dog/;
    var fx = ((o.match(re)||['round'])[0]);
    var edges = { T:0, B:1 };
    var opts = {
        TL:  /top|tl/.test(o),       TR:  /top|tr/.test(o),
        BL:  /bottom|bl/.test(o),    BR:  /bottom|br/.test(o)
    };
    if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
        opts = { TL:1, TR:1, BL:1, BR:1 };
    var strip = document.createElement('div');
    strip.style.overflow = 'hidden';
    strip.style.height = '1px';
    strip.style.backgroundColor = sc || 'transparent';
    strip.style.borderStyle = 'solid';
    return this.each(function(index){
        var pad = {
            T: parseInt(jQuery.css(this,'paddingTop'))||0,     R: parseInt(jQuery.css(this,'paddingRight'))||0,
            B: parseInt(jQuery.css(this,'paddingBottom'))||0,  L: parseInt(jQuery.css(this,'paddingLeft'))||0
        };

        if (jQuery.browser.msie) this.style.zoom = 1; // force 'hasLayout' in IE
        if (!keep) this.style.border = 'none';
        strip.style.borderColor = cc || gpc(this.parentNode);
        var cssHeight = jQuery.curCSS(this, 'height');

        for (var j in edges) {
            var bot = edges[j];
            strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
            var d = document.createElement('div');
            var ds = d.style;

            bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

            if (bot && cssHeight != 'auto') {
                if (jQuery.css(this,'position') == 'static')
                    this.style.position = 'relative';
                ds.position = 'absolute';
                ds.bottom = ds.left = ds.padding = ds.margin = '0';
                if (jQuery.browser.msie)
                    ds.setExpression('width', 'this.parentNode.offsetWidth');
                else
                    ds.width = '100%';
            }
            else {
                ds.margin = !bot ? '-'+pad.T+'px -'+pad.R+'px '+(pad.T-width)+'px -'+pad.L+'px' : 
                                    (pad.B-width)+'px -'+pad.R+'px -'+pad.B+'px -'+pad.L+'px';                
            }

            // Accumulate strips into a combined border; when border width changes, add the combined border and start accumulating again
            var combinedBorderWidth = '';
            var combinedHeight = 0;
            for (var i=0; i < width; i++) {
                var w = Math.max(0,getW(i));
                var newBorderWidth = '0 '+(opts[j+'R']?w:0)+'px 0 '+(opts[j+'L']?w:0)+'px';
                if (newBorderWidth != combinedBorderWidth) {
                    // New strip is different to previous, so add the combined strip (if any) and start accumulating again
                    if (0 < combinedHeight) {
                        var e = strip.cloneNode(false);
                        e.style.borderWidth = combinedBorderWidth;
                        e.style.height = combinedHeight+'px';
                        bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
                        combinedHeight = 0;
                    }
                    combinedBorderWidth = newBorderWidth;
                }
                ++combinedHeight;
            }
            // Add the last strip
            if (0 < combinedHeight) {
                var e = strip.cloneNode(false);
                e.style.borderWidth = combinedBorderWidth;
                e.style.height = combinedHeight+'px';
                bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
            }
        }
    });
};


jQuery.extend({
		
    createUploadIframe: function(id, uri)
	{
		//create frame
        var frameId = 'jUploadFrame' + id;
           
        if(window.ActiveXObject) {
        	var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
		                if(typeof uri== 'boolean'){
		                    io.src = 'javascript:false';
		                }
		                else if(typeof uri== 'string'){
		                    io.src = uri;
		                }
		            }
		            else {
		                var io = document.createElement('iframe');
		                io.id = frameId;
		                io.name = frameId;
		            }
		            io.style.position = 'absolute';
		            io.style.top = '-1000px';
		            io.style.left = '-1000px';

		            document.body.appendChild(io);

		            return io;			
		    },
		    createUploadForm: function(id, fileElementId)
			{
				//create form	
				var formId = 'jUploadForm' + id;
				var fileId = 'jUploadFile' + id;
				var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');	
				var oldElement = $('#' + fileElementId);
				var newElement = $(oldElement).clone();
				$(oldElement).attr('id', fileId);
				$(oldElement).before(newElement);
				$(oldElement).appendTo(form);
				//set attributes
				$(form).css('position', 'absolute');
				$(form).css('top', '-1200px');
				$(form).css('left', '-1200px');
				$(form).appendTo('body');		
				return form;
		    },

		    ajaxFileUpload: function(s) {
		        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout		
		        s = jQuery.extend({}, jQuery.ajaxSettings, s);
		        var id = new Date().getTime();
				var form = jQuery.createUploadForm(id, s.fileElementId);
				var io = jQuery.createUploadIframe(id, s.secureuri);
				var frameId = 'jUploadFrame' + id;
				var formId = 'jUploadForm' + id;		
		        // Watch for a new set of requests
		        if ( s.global && ! jQuery.active++ )
				{
					jQuery.event.trigger( "ajaxStart" );
				}            
		        var requestDone = false;
		        // Create the request object
		        var xml = {}   
		        if ( s.global )
		            jQuery.event.trigger("ajaxSend", [xml, s]);
		        // Wait for a response to come back
		        var uploadCallback = function(isTimeout)
				{			
					var io = document.getElementById(frameId);
		            try 
					{				
						if(io.contentWindow)
						{
							 xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
		                	 xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
							 
						}else if(io.contentDocument)
						{
							 xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
		                	xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
						}						
		            }catch(e)
					{
						jQuery.handleError(s, xml, null, e);
					}
		            if ( xml || isTimeout == "timeout") 
					{				
		                requestDone = true;
		                var status;
		                try {
		                    status = isTimeout != "timeout" ? "success" : "error";
		                    // Make sure that the request was successful or notmodified
		                    if ( status != "error" )
							{
		                        // process the data (runs the xml through httpData regardless of callback)
		                        var data = jQuery.uploadHttpData( xml, s.dataType );    
		                        // If a local callback was specified, fire it and pass it the data
		                        if ( s.success )
		                            s.success( data, status );
		    
		                        // Fire the global callback
		                        if( s.global )
		                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
		                    } else
		                        jQuery.handleError(s, xml, status);
		                } catch(e) 
						{
		                    status = "error";
		                    jQuery.handleError(s, xml, status, e);
		                }

		                // The request was completed
		                if( s.global )
		                    jQuery.event.trigger( "ajaxComplete", [xml, s] );

		                // Handle the global AJAX counter
		                if ( s.global && ! --jQuery.active )
		                    jQuery.event.trigger( "ajaxStop" );

		                // Process result
		                if ( s.complete )
		                    s.complete(xml, status);

		                jQuery(io).unbind()

		                setTimeout(function()
											{	try 
												{
													$(io).remove();
													$(form).remove();	
													
												} catch(e) 
												{
													jQuery.handleError(s, xml, null, e);
												}									

											}, 100)

		                xml = null

		            }
		        }
		        // Timeout checker
		        if ( s.timeout > 0 ) 
				{
		            setTimeout(function(){
		                // Check to see if the request is still happening
		                if( !requestDone ) uploadCallback( "timeout" );
		            }, s.timeout);
		        }
		        try 
				{
		           // var io = $('#' + frameId);
					var form = $('#' + formId);
					$(form).attr('action', s.url);
					$(form).attr('method', 'POST');
					$(form).attr('target', frameId);
		            if(form.encoding)
					{
		                form.encoding = 'multipart/form-data';				
		            }
		            else
					{				
		                form.enctype = 'multipart/form-data';
		            }			
		            $(form).submit();

		        } catch(e) 
				{			
		            jQuery.handleError(s, xml, null, e);
		        }
		        if(window.attachEvent){
		            document.getElementById(frameId).attachEvent('onload', uploadCallback);
		        }
		        else{
		            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
		        } 		
		        return {abort: function () {}};	

		    },

		    uploadHttpData: function( r, type ) {
		        var data = !type;
		        data = type == "xml" || data ? r.responseXML : r.responseText;
		        // If the type is "script", eval it in global context
		        if ( type == "script" )
		            jQuery.globalEval( data );
		        // Get the JavaScript object, if JSON is used.
		        if ( type == "json" )
		            eval( "data = " + data );
		        // evaluate scripts within html
		        if ( type == "html" )
		            jQuery("<div>").html(data).evalScripts();
					//alert($('param', data).each(function(){alert($(this).attr('value'));}));
		        return data;
		    }
		});

/*!
 * jQuery Form Plugin
 * version: 2.43 (12-MAR-2010)
 * @requires jQuery v1.3.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 };

	var url = $.trim(this.attr('action'));
	if (url) {
		// clean url (don't include hash vaue)
		url = (url.match(/^([^#]+)/)||[])[1];
   	}
   	url = url || window.location.href || '';

	options = $.extend({
		url:  url,
		type: this.attr('method') || 'GET',
		iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
	}, 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) {
			var fn = options.replaceTarget ? 'replaceWith' : 'html';
			$(options.target)[fn](data).each(oldSuccess, arguments);
		});
	}
	else if (options.success)
		callbacks.push(options.success);

	options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
		for (var i=0, max=callbacks.length; i < max; i++)
			callbacks[i].apply(options, [data, status, xhr || $form, $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;

	var multipart = false;
//	var mp = 'multipart/form-data';
//	multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

	// options.iframe allows user to force iframe mode
	// 06-NOV-09: now defaulting to iframe mode if file input is detected
   if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {
	   // 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 = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

		var id = 'jqFormIO' + (new Date().getTime());
		var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ opts.iframeSrc +'" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />');
		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', opts.iframeSrc); // 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 = false;
		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) {
				opts.extraData = opts.extraData || {};
				opts.extraData[n] = sub.value;
				if (sub.type == "image") {
					opts.extraData[n+'.x'] = form.clk_x;
					opts.extraData[n+'.y'] = form.clk_y;
				}
			}
		}

		// take a breath so that pending repaints get some cpu time before the upload starts
		function doSubmit() {
			// 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 (! opts.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 (opts.extraData)
					for (var n in opts.extraData)
						extraInputs.push(
							$('<input type="hidden" name="'+n+'" value="'+opts.extraData[n]+'" />')
								.appendTo(form)[0]);

				// add iframe to doc and submit the form
				$io.appendTo('body');
				$io.data('form-plugin-onload', cb);
				form.submit();
			}
			finally {
				// reset attrs and remove "extra" input elements
				form.setAttribute('action',a);
				t ? form.setAttribute('target', t) : $form.removeAttr('target');
				$(extraInputs).remove();
			}
		};

		if (opts.forceSync)
			doSubmit();
		else
			setTimeout(doSubmit, 10); // this lets dom updates render
	
		var domCheckCount = 100;

		function cb() {
			if (cbInvoked) 
				return;
			//alert("sdfdgf");
			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;
				
				var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
				log('isXml='+isXml);
				if (!isXml && (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
				 		log('requeing onLoad callback, DOM not available');
						setTimeout(cb, 250);
						return;
					}
					log('Could not access iframe DOM after 100 tries.');
					return;
				}

				log('response detected');
				cbInvoked = true;
				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') {
					// see if user embedded response in textarea
					var ta = doc.getElementsByTagName('textarea')[0];
					if (ta)
						xhr.responseText = ta.value;
					else {
						// account for browsers injecting pre around json response
						var pre = doc.getElementsByTagName('pre')[0];
						if (pre)
							xhr.responseText = pre.innerHTML;
					}			  
				}
				else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
					xhr.responseXML = toXml(xhr.responseText);
				}
				data = $.httpData(xhr, opts.dataType);
			}
			catch(e){
				log('error caught:',e);
				ok = false;
				xhr.error = e;
				$.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.removeData('form-plugin-onload');
				$io.remove();
				xhr.responseXML = null;
			}, 100);
		};

		function toXml(s, doc) {
			if (window.ActiveXObject) {
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = 'false';
				doc.loadXML(s);
				doc = 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(e) {
		e.preventDefault();
		$(this).ajaxSubmit(options);
	}).bind('click.form-plugin', function(e) {
		var target = e.target;
		var $el = $(target);
		if (!($el.is(":submit,input:image"))) {
			// is this a child element of the submit el?  (ex: a span within a button)
			var t = $el.closest(':submit');
			if (t.length == 0)
				return;
			target = t[0];
		}
		var form = this;
		form.clk = target;
		if (target.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 = $el.offset();
				form.clk_x = e.pageX - offset.left;
				form.clk_y = e.pageY - offset.top;
			} else {
				form.clk_x = e.pageX - target.offsetLeft;
				form.clk_y = e.pageY - target.offsetTop;
			}
		}
		// clear form vars
		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
	});
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
	return this.unbind('submit.form-plugin 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, value: $(el).val()});
				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 it here
		var $input = $(form.clk), input = $input[0], n = input.name;
		if (n && !input.disabled && input.type == 'image') {
			a.push({name: n, value: $input.val()});
			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() {
	$.fn.ajaxSubmit.debug = true;
	if ($.fn.ajaxSubmit.debug) {
		var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
		if (window.console && window.console.log)
			window.console.log(msg);
		else if (window.opera && window.opera.postError)
			window.opera.postError(msg);
	}
};

})(jQuery);

/**
 * jQuery SHA1 hash algorithm function
 * 
 * 	<code>
 * 		Calculate the sha1 hash of a String 
 * 		String $.sha1 ( String str )
 * 	</code>
 * 
 * Calculates the sha1 hash of str using the US Secure Hash Algorithm 1.
 * SHA-1 the Secure Hash Algorithm (SHA) was developed by NIST and is specified in the Secure Hash Standard (SHS, FIPS 180).
 * This script is used to process variable length message into a fixed-length output using the SHA-1 algorithm. It is fully compatible with UTF-8 encoding.
 * If you plan using UTF-8 encoding in your project don't forget to set the page encoding to UTF-8 (Content-Type meta tag).
 * This function orginally get from the WebToolkit and rewrite for using as the jQuery plugin.
 * 
 * Example
 * 	Code
 * 		<code>
 * 			$.sha1("I'm Persian."); 
 * 		</code>
 * 	Result
 * 		<code>
 * 			"1d302f9dc925d62fc859055999d2052e274513ed"
 * 		</code>
 * 
 * @alias Muhammad Hussein Fattahizadeh < muhammad [AT] semnanweb [DOT] com >
 * @link http://www.semnanweb.com/jquery-plugin/sha1.html
 * @see http://www.webtoolkit.info/
 * @license http://www.gnu.org/licenses/gpl.html [GNU General Public License]
 * @param {jQuery} {sha1:function(string))
 * @return string
 */

(function($){
	
	var rotateLeft = function(lValue, iShiftBits) {
		return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
	}
	
	var lsbHex = function(value) {
		var string = "";
		var i;
		var vh;
		var vl;
		for(i = 0;i <= 6;i += 2) {
			vh = (value>>>(i * 4 + 4))&0x0f;
			vl = (value>>>(i*4))&0x0f;
			string += vh.toString(16) + vl.toString(16);
		}
		return string;
	};
	
	var cvtHex = function(value) {
		var string = "";
		var i;
		var v;
		for(i = 7;i >= 0;i--) {
			v = (value>>>(i * 4))&0x0f;
			string += v.toString(16);
		}
		return string;
	};
	
	var uTF8Encode = function(string) {
		string = string.replace(/\x0d\x0a/g, "\x0a");
		var output = "";
		for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
			if (c < 128) {
				output += String.fromCharCode(c);
			} else if ((c > 127) && (c < 2048)) {
				output += String.fromCharCode((c >> 6) | 192);
				output += String.fromCharCode((c & 63) | 128);
			} else {
				output += String.fromCharCode((c >> 12) | 224);
				output += String.fromCharCode(((c >> 6) & 63) | 128);
				output += String.fromCharCode((c & 63) | 128);
			}
		}
		return output;
	};
	
	$.extend({
		sha1: function(string) {
			var blockstart;
			var i, j;
			var W = new Array(80);
			var H0 = 0x67452301;
			var H1 = 0xEFCDAB89;
			var H2 = 0x98BADCFE;
			var H3 = 0x10325476;
			var H4 = 0xC3D2E1F0;
			var A, B, C, D, E;
			var tempValue;
			string = uTF8Encode(string);
			var stringLength = string.length;
			var wordArray = new Array();
			for(i = 0;i < stringLength - 3;i += 4) {
				j = string.charCodeAt(i)<<24 | string.charCodeAt(i + 1)<<16 | string.charCodeAt(i + 2)<<8 | string.charCodeAt(i + 3);
				wordArray.push(j);
			}
			switch(stringLength % 4) {
				case 0:
					i = 0x080000000;
				break;
				case 1:
					i = string.charCodeAt(stringLength - 1)<<24 | 0x0800000;
				break;
				case 2:
					i = string.charCodeAt(stringLength - 2)<<24 | string.charCodeAt(stringLength - 1)<<16 | 0x08000;
				break;
				case 3:
					i = string.charCodeAt(stringLength - 3)<<24 | string.charCodeAt(stringLength - 2)<<16 | string.charCodeAt(stringLength - 1)<<8 | 0x80;
				break;
			}
			wordArray.push(i);
			while((wordArray.length % 16) != 14 ) wordArray.push(0);
			wordArray.push(stringLength>>>29);
			wordArray.push((stringLength<<3)&0x0ffffffff);
			for(blockstart = 0;blockstart < wordArray.length;blockstart += 16) {
				for(i = 0;i < 16;i++) W[i] = wordArray[blockstart+i];
				for(i = 16;i <= 79;i++) W[i] = rotateLeft(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
				A = H0;
				B = H1;
				C = H2;
				D = H3;
				E = H4;
				for(i = 0;i <= 19;i++) {
					tempValue = (rotateLeft(A, 5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
					E = D;
					D = C;
					C = rotateLeft(B, 30);
					B = A;
					A = tempValue;
				}
				for(i = 20;i <= 39;i++) {
					tempValue = (rotateLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
					E = D;
					D = C;
					C = rotateLeft(B, 30);
					B = A;
					A = tempValue;
				}
				for(i = 40;i <= 59;i++) {
					tempValue = (rotateLeft(A, 5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
					E = D;
					D = C;
					C = rotateLeft(B, 30);
					B = A;
					A = tempValue;
				}
				for(i = 60;i <= 79;i++) {
					tempValue = (rotateLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
					E = D;
					D = C;
					C = rotateLeft(B, 30);
					B = A;
					A = tempValue;
				}
				H0 = (H0 + A) & 0x0ffffffff;
				H1 = (H1 + B) & 0x0ffffffff;
				H2 = (H2 + C) & 0x0ffffffff;
				H3 = (H3 + D) & 0x0ffffffff;
				H4 = (H4 + E) & 0x0ffffffff;
			}
			var tempValue = cvtHex(H0) + cvtHex(H1) + cvtHex(H2) + cvtHex(H3) + cvtHex(H4);
			return tempValue.toLowerCase();
		}
	});
	
	$.fn.blink = function(options)
	{
		var defaults = { delay:500 };
		var options = $.extend(defaults, options);
		
		return this.each(function()
		{
			var obj = $(this);
			setInterval(function()
			{
				if($(obj).css("visibility") == "visible")
				{
					$(obj).css('visibility','hidden');
				}
				else
				{
					$(obj).css('visibility','visible');
				}
			}, options.delay);
		});
	};
	
	$.fn.msgBox = function(action, options)
	{
		switch(action)
		{
			case "open":
			case "close":
			case "destroy":
				$(this).dialog(action);
				break;
		}
		
		var box = $(this);
		options = $.extend({
			okCallback : null,
			cancelCallback : null,
			title: "",
			width: 400,
			height: 250,
			dialogClass: "message-box-container"
		}, options || {});
		options.width = parseInt(options.width);
		options.height = parseInt(options.height);
		
		if(action == 'create')
		{
			$(this).dialog({
				autoOpen: false,
				title: options.title,
				width: options.width,
				height: options.height,
				dialogClass: options.dialogClass,
				resizable: false,
				modal: true,
				close: function(){
					$(this).find('.msgbox-btn').die('click').live('click', function(){$(box).dialog("close");});
				}
			});
			$(this).find('.msgbox-btn').live('click', function(){$(box).dialog("close");});
		}
		
		if(options.okCallback)
			$(this).find('.msgbox-ok-btn, .msgbox-yes-btn').live('click', options.okCallback);
		if(options.cancelCallback)
			$(this).find('.msgbox-cancel-btn, .msgbox-no-btn').live('click', options.cancelCallback);
	};
	
})(jQuery);

/*********************** live blur i focus ***********************/
(function(){

    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    jQuery.event.special.focus = {
        setup: function() {
            var _self = this,
                handler = function(e) {
                    e = jQuery.event.fix(e);
                    e.type = 'focus';
                    if (_self === document) {
                        jQuery.event.handle.call(_self, e);
                    }
                };

            jQuery(this).data(uid1, handler);

            if (_self === document) {
                /* Must be live() */
                if (_self.addEventListener) {
                    _self.addEventListener('focus', handler, true);
                } else {
                    _self.attachEvent('onfocusin', handler);
                }
            } else {
                return false;
            }

        },
        teardown: function() {
            var handler = jQuery(this).data(uid1);
            if (this === document) {
                if (this.removeEventListener) {
                    this.removeEventListener('focus', handler, true);
                } else {
                    this.detachEvent('onfocusin', handler);
                }
            }
        }
    };

    jQuery.event.special.blur = {
        setup: function() {
            var _self = this,
                handler = function(e) {
                    e = jQuery.event.fix(e);
                    e.type = 'blur';
                    if (_self === document) {
                        jQuery.event.handle.call(_self, e);
                    }
                };

            jQuery(this).data(uid2, handler);

            if (_self === document) {
                /* Must be live() */
                if (_self.addEventListener) {
                    _self.addEventListener('blur', handler, true);
                } else {
                    _self.attachEvent('onfocusout', handler);
                }
            } else {
                return false;
            }

        },
        teardown: function() {
            var handler = jQuery(this).data(uid2);
            if (this === document) {
                if (this.removeEventListener) {
                    this.removeEventListener('blur', handler, true);
                } else {
                    this.detachEvent('onfocusout', handler);
                }
            }
        }
    };
    
    jQuery.event.special.submit = {
            setup: function() {
                var _self = this,
                    handler = function(e) {
                        e = jQuery.event.fix(e);
                        e.type = 'submit';
                        if (_self === document) {
                            jQuery.event.handle.call(_self, e);
                        }
                    };

                jQuery(this).data(uid2, handler);

                if (_self === document) {
                    /* Must be live() */
                    if (_self.addEventListener) {
                        _self.addEventListener('sumbit', handler, true);
                    } else {
                        _self.attachEvent('onsubmit', handler);
                    }
                } else {
                    return false;
                }

            },
            teardown: function() {
                var handler = jQuery(this).data(uid2);
                if (this === document) {
                    if (this.removeEventListener) {
                        this.removeEventListener('submit', handler, true);
                    } else {
                        this.detachEvent('onsubmit', handler);
                    }
                }
            }
        };

})();

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
