$(document).ready(function () {

	// COLLAPSABLE WIDGETS (on Dashboard & Profile pages)
	// toggle widget box contents
	$('a.toggle_box_contents').bind('click', toggleContent);

	// toggle widget box edit panel
	$('a.toggle_box_edit_panel').click(function () {
		$(this.parentNode.parentNode).children(".collapsable_box_editpanel").slideToggle("fast");
		return false;
	});

	// toggle customise edit panel
	$('a.toggle_customise_edit_panel').click(function () {
		$('div#customise_editpanel').slideToggle("fast");
		return false;
	});

	// toggle plugin's settings nad more info on admin tools admin
	$('a.pluginsettings_link').click(function () {
		$(this.parentNode.parentNode).children(".pluginsettings").slideToggle("fast");
		return false;
	});
	$('a.manifest_details').click(function () {
		$(this.parentNode.parentNode).children(".manifest_file").slideToggle("fast");
		return false;
	});
	// reusable generic hidden panel
	$('a.collapsibleboxlink').click(function () {
		$(this.parentNode.parentNode).children(".collapsible_box").slideToggle("fast");
		return false;
	});

	// WIDGET GALLERY EDIT PANEL
	// Sortable widgets
	var els = ['#leftcolumn_widgets', '#middlecolumn_widgets', '#rightcolumn_widgets', '#widget_picker_gallery' ];
	var $els = $(els.toString());

	$els.sortable({
		items: '.draggable_widget',
		handle: '.drag_handle',
		forcePlaceholderSize: true,
		placeholder: 'ui-state-highlight',
		cursor: 'move',
		opacity: 0.9,
		appendTo: 'body',
		connectWith: els,
		start:function(e,ui) {

		},
		stop: function(e,ui) {
			// refresh list before updating hidden fields with new widget order
			$(this).sortable( "refresh" );

			var widgetNamesLeft = outputWidgetList('#leftcolumn_widgets');
			var widgetNamesMiddle = outputWidgetList('#middlecolumn_widgets');
			var widgetNamesRight = outputWidgetList('#rightcolumn_widgets');

			document.getElementById('debugField1').value = widgetNamesLeft;
			document.getElementById('debugField2').value = widgetNamesMiddle;
			document.getElementById('debugField3').value = widgetNamesRight;
		}
	});

	// bind more info buttons - called when new widgets are created
	widget_moreinfo();

	// set-up hover class for dragged widgets
	$("#rightcolumn_widgets").droppable({
		accept: ".draggable_widget",
		hoverClass: 'droppable-hover'
	});
	$("#middlecolumn_widgets").droppable({
		accept: ".draggable_widget",
		hoverClass: 'droppable-hover'
	});
	$("#leftcolumn_widgets").droppable({
		accept: ".draggable_widget",
		hoverClass: 'droppable-hover'
	});

}); /* end document ready function */


// List active widgets for each page column
function outputWidgetList(forElement) {
	return( $("input[name='handler'], input[name='guid']", forElement ).makeDelimitedList("value") );
}

// Make delimited list
jQuery.fn.makeDelimitedList = function(elementAttribute) {

	var delimitedListArray = new Array();
	var listDelimiter = "::";

	// Loop over each element in the stack and add the elementAttribute to the array
	this.each(function(e) {
			var listElement = $(this);
			// Add the attribute value to our values array
			delimitedListArray[delimitedListArray.length] = listElement.attr(elementAttribute);
		}
	);

	// Return value list by joining the array
	return(delimitedListArray.join(listDelimiter));
}


// Read each widgets collapsed/expanded state from cookie and apply
function widget_state(forWidget) {

	var thisWidgetState = $.cookie(forWidget);

	if (thisWidgetState == 'collapsed') {
		forWidget = "#" + forWidget;
		$(forWidget).find("div.collapsable_box_content").hide();
		$(forWidget).find("a.toggle_box_contents").html('+');
		$(forWidget).find("a.toggle_box_edit_panel").fadeOut('medium');
	};
}


// Toggle widgets contents and save to a cookie
var toggleContent = function(e) {
var targetContent = $('div.collapsable_box_content', this.parentNode.parentNode);
	if (targetContent.css('display') == 'none') {
		targetContent.slideDown(400);
		$(this).html('-');
		$(this.parentNode).children(".toggle_box_edit_panel").fadeIn('medium');

		// set cookie for widget panel open-state
		var thisWidgetName = $(this.parentNode.parentNode.parentNode).attr('id');
		$.cookie(thisWidgetName, 'expanded', { expires: 365 });

	} else {
		targetContent.slideUp(400);
		$(this).html('+');
		$(this.parentNode).children(".toggle_box_edit_panel").fadeOut('medium');
		// make sure edit pane is closed
		$(this.parentNode.parentNode).children(".collapsable_box_editpanel").hide();

		// set cookie for widget panel closed-state
		var thisWidgetName = $(this.parentNode.parentNode.parentNode).attr('id');
		$.cookie(thisWidgetName, 'collapsed', { expires: 365 });
	}
	return false;
};

// More info tooltip in widget gallery edit panel
function widget_moreinfo() {

	$("img.more_info").hover(function(e) {
	var widgetdescription = $("input[name='description']", this.parentNode.parentNode.parentNode ).attr('value');
	$("body").append("<p id='widget_moreinfo'><b>"+ widgetdescription +" </b></p>");

		if (e.pageX < 900) {
			$("#widget_moreinfo")
				.css("top",(e.pageY + 10) + "px")
				.css("left",(e.pageX + 10) + "px")
				.fadeIn("medium");
		}
		else {
			$("#widget_moreinfo")
				.css("top",(e.pageY + 10) + "px")
				.css("left",(e.pageX - 210) + "px")
				.fadeIn("medium");
		}
	},
	function() {
		$("#widget_moreinfo").remove();
	});

	$("img.more_info").mousemove(function(e) {
		// action on mousemove
	});
};

// COOKIES
jQuery.cookie = function(name, value, options) {
	if (typeof value != 'undefined') { // name and value given, set cookie
	options = options || {};
		if (value === null) {
			value = '';
			options.expires = -1;
		}
	var expires = '';
	if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
		var date;
		if (typeof options.expires == 'number') {
			date = new Date();
			date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
		} else {
			date = options.expires;
		}
		expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
	}
	// CAUTION: Needed to parenthesize options.path and options.domain
	// in the following expressions, otherwise they evaluate to undefined
	// in the packed version for some reason.
	var path = options.path ? '; path=' + (options.path) : '';
	var domain = options.domain ? '; domain=' + (options.domain) : '';
	var secure = options.secure ? '; secure' : '';
	document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');

	} else { // only name given, get cookie
		var cookieValue = null;
		if (document.cookie && document.cookie != '') {
			var cookies = document.cookie.split(';');
			for (var i = 0; i < cookies.length; i++) {
				var cookie = jQuery.trim(cookies[i]);
				// Does this cookie string begin with the name we want?
				if (cookie.substring(0, name.length + 1) == (name + '=')) {
					cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
					break;
				}
			}
		}
		return cookieValue;
	}
};

// ELGG TOOLBAR MENU
$.fn.elgg_topbardropdownmenu = function(options) {

options = $.extend({speed: 350}, options || {});

this.each(function() {

	var root = this, zIndex = 5000;

	function getSubnav(ele) {
	  if (ele.nodeName.toLowerCase() == 'li') {
		var subnav = $('> ul', ele);
		return subnav.length ? subnav[0] : null;
	  } else {

		return ele;
	  }
	}

	function getActuator(ele) {
	  if (ele.nodeName.toLowerCase() == 'ul') {
		return $(ele).parents('li')[0];
	  } else {
		return ele;
	  }
	}

	function hide() {
	  var subnav = getSubnav(this);
	  if (!subnav) return;
	  $.data(subnav, 'cancelHide', false);
	  setTimeout(function() {
		if (!$.data(subnav, 'cancelHide')) {
		  $(subnav).slideUp(100);
		}
	  }, 250);
	}

	function show() {
	  var subnav = getSubnav(this);
	  if (!subnav) return;
	  $.data(subnav, 'cancelHide', true);
	  $(subnav).css({zIndex: zIndex++}).slideDown(options.speed);
	  if (this.nodeName.toLowerCase() == 'ul') {
		var li = getActuator(this);
		$(li).addClass('hover');
		$('> a', li).addClass('hover');
	  }
	}

	$('ul, li', this).hover(show, hide);
	$('li', this).hover(
	  function() { $(this).addClass('hover'); $('> a', this).addClass('hover'); },
	  function() { $(this).removeClass('hover'); $('> a', this).removeClass('hover'); }
	);

});

};

var submenuLayer = 1000;

function setup_avatar_menu() {

	// avatar image menu link
	$("div.usericon img").mouseover(function() {
		// find nested avatar_menu_button and show
		$(this.parentNode.parentNode).children(".avatar_menu_button").show();
		$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow");
		//$(this.parentNode.parentNode).css("z-index", submenuLayer);
	})
	.mouseout(function() { 
		if($(this).parent().parent().find("div.sub_menu").css('display')!="block") {
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_on");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_hover");
			$(this.parentNode.parentNode).children(".avatar_menu_button").hide();
		}
		else {
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_on");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_hover");
			$(this.parentNode.parentNode).children(".avatar_menu_button").show();
			$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow");
		}
	});


	// avatar contextual menu
	$(".avatar_menu_button img").click(function(e) { 
		
		var submenu = $(this).parent().parent().find("div.sub_menu");
		
		// close submenu if arrow is clicked & menu already open
		if(submenu.css('display') == "block") {
			//submenu.hide(); 		
		}
		else {
			// get avatar dimensions
			var avatar = $(this).parent().parent().parent().find("div.usericon");
			//alert( "avatarWidth: " + avatar.width() + ", avatarHeight: " + avatar.height() );
			
			// move submenu position so it aligns with arrow graphic
			if (e.pageX < 840) { // popup menu to left of arrow if we're at edge of page
			submenu.css("top",(avatar.height()) + "px")
					.css("left",(avatar.width()-15) + "px")
					.fadeIn('normal');	
			}	
			else {
			submenu.css("top",(avatar.height()) + "px")
					.css("left",(avatar.width()-166) + "px")
					.fadeIn('normal');		
			}	
			
			// force z-index - workaround for IE z-index bug			
			avatar.css("z-index",  submenuLayer);
			avatar.find("a.icon img").css("z-index",  submenuLayer);
			submenu.css("z-index", submenuLayer+1);
						
			submenuLayer++;
			
			// change arrow to 'on' state
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_hover");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow_on");
		}
		
		// hide any other open submenus and reset arrows
		$("div.sub_menu:visible").not(submenu).hide();
		$(".avatar_menu_button").removeClass("avatar_menu_arrow");
		$(".avatar_menu_button").removeClass("avatar_menu_arrow_on");
		$(".avatar_menu_button").removeClass("avatar_menu_arrow_hover");
		$(".avatar_menu_button").hide();
		$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow_on");
		$(this.parentNode.parentNode).children("div.avatar_menu_button").show();
		//alert("submenuLayer = " +submenu.css("z-index"));
	})
	// hover arrow each time mouseover enters arrow graphic (eg. when menu is already shown)
	.mouseover(function() {
		$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_on");
		$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
		$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow_hover");
	})
	// if menu not shown revert arrow, else show 'menu open' arrow
	.mouseout(function() { 
		if($(this).parent().parent().find("div.sub_menu").css('display')!="block"){
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_hover");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow");
		}
		else {
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow_hover");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").removeClass("avatar_menu_arrow");
			$(this.parentNode.parentNode).children("div.avatar_menu_button").addClass("avatar_menu_arrow_on");
		}
	});
	
	// hide avatar menu if click occurs outside of menu	
	// and hide arrow button						
	$(document).click(function(event) { 		
			var target = $(event.target);
			if (target.parents(".usericon").length == 0) {				
				$(".usericon div.sub_menu").fadeOut();
				$(".avatar_menu_button").removeClass("avatar_menu_arrow");
				$(".avatar_menu_button").removeClass("avatar_menu_arrow_on");
				$(".avatar_menu_button").removeClass("avatar_menu_arrow_hover");
				$(".avatar_menu_button").hide();
			}
	});			   
	

}

$(document).ready(function() {

	setup_avatar_menu();						   
								   
});
function usergallery_count_selected(id) {
          var total = 0;
          total = $('#' + id + ' ul li input[type=checkbox]:checked').length;
           $('#' + id + ' #beelibsel_count').html(total);
}
    
$(window).load(function(){
     var comments = $('textarea.comment');
     if (comments.length)
          comments.elastic();
     $('body').append("<div id=\"atooltip\"></div>");
     $("a.activetooltip").tooltip({
          // each trashcan image works as a trigger
        tipClass: 'atooltip',
 
        // custom positioning
        position: 'center right',
 
        // move tooltip a little bit to the right
        offset: [0, 15],
 
        // do not initialize tooltips until they are used
        lazy: true,
 
        // there is no delay when the mouse is moved away from the trigger
        delay: 0
     });
    
    
     var lightbox = $("div.lightbox").overlay({oneInstance: false, api: true, top: '20%'});
     var lightboxcontent = $("div.lightbox div.inside");
    
     $('div.lightbox a.close').live('click', function () {
          lightbox.close();
          if (!$(this).hasClass('noautoload'))
	          lightboxcontent.html('<span class="loading">Chargement</span>');
          return false;
    
     });
     
     if ($('textarea.explaininput').length)
     {
	     $('textarea.explaininput').bind('click', function () {
			if ($(this).hasClass('explaininput'))
			{
				$(this).val('');
				$(this).removeClass('explaininput');
			}
		});
	 }
	 
	 if ($('input.explaininput').length)
     {
	     $('input.explaininput').bind('click', function () {
			if ($(this).hasClass('explaininput'))
			{
				$(this).val('');
				$(this).removeClass('explaininput');
			}
		});
	 }
	 
	 $('a:not([href^="http://www.beebac.com/"]):not([href^="#"]):not([href^="/"])').attr("target", "_blank");
    
     	$('a.addfriendaction').bind('click', function () {
		lightboxcontent.load('http://www.beebac.com/mod/friend_request/addfriendmodal.php?guid=' + $(this).attr('rel'));
		lightbox.load();
		return false;
	});
	
	$('a.removefriendaction').bind('click', function () {
		lightboxcontent.load('http://www.beebac.com/mod/friend_request/removefriendmodal.php?guid=' + $(this).attr('rel'));
		lightbox.load();
		return false;
	});	//grab all the anchor tag with rel set to shareit
	$('a[rel=shareit]').bind('click', function() {		
		
		//get the height, top and calculate the left value for the sharebox
		var height = $(this).height();
		var top = $(this).offset().top;
		
		//get the left and find the center value
		var left = $(this).offset().left + ($(this).width() /2) - ($('#shareit-box').width() / 2);		
		
		//grab the href value and explode the bar symbol to grab the url and title
		//the content should be in this format url|title
		var value = $(this).attr('href').split('|');
		
		//assign the value to variables and encode it to url friendly
		var field = value[0];
		var url = encodeURIComponent(value[0]);
		var title = encodeURIComponent(value[1]);
		
		//assign the height for the header, so that the link is cover
		$('#shareit-header').height(height);
		
		//display the box
		$('#shareit-box').show();
		
		//set the position, the box should appear under the link and centered
		$('#shareit-box').css({'top':top, 'left':left});
		
		//assign the url to the textfield
		$('#shareit-field').val(field);
		
		//make the bookmark media open in new tab/window
		$('a.shareit-sm').attr('target','_blank');
	      
	    //Setup the bookmark media url and title  
	    $('a[rel=shareit-mail]').attr('href', 'http://mailto:?subject=' + title);  
	    $('a[rel=shareit-delicious]').attr('href', 'http://del.icio.us/post?v=4&noui&jump=close&url=' + url + '&title=' + title);  
	    $('a[rel=shareit-twitter]').attr('href', 'http://twitter.com/home?status=' + title + '%20-%20' + url); 
	    $('a[rel=shareit-facebook]').attr('href', 'http://www.facebook.com/share.php?u='+ url +'&t='+ title); 
	    $('a[rel=shareit-linkedin]').attr('href', 'http://www.linkedin.com/shareArticle?mini=true&url='+ url +'&title='+ title +'&source=Beebac.com'); 
	    $('a[rel=shareit-google]').attr('href', 'http://www.google.com/bookmarks/mark?op=edit&bkmk='+ url +'&title='+ title +'&annotation=Beebac.com');  
	    return false;  
	});  
  
	//onmouse out hide the shareit box  
	$('#shareit-box').mouseleave(function () {  
	    $('#shareit-field').val('');  
	    $(this).hide();  
	});
  
	//hightlight the textfield on click event  
	$('#shareit-field').click(function () {  
	    $(this).select();  
	});$("#input_select_grp_catego").change(function() {
	if (this.value == 'groups:catego0')
	{
		$("#groups_add_new_category_input").fadeIn();
	}
	else
	{
		$("#groups_add_new_category_input").fadeOut();
	}
});

$('a.group_addfriendaction').bind('click', function () {
	if ($("#group_userselector_hidden_div").length)
	{
		var content = $("#group_userselector_hidden_div").clone();
		$("#group_userselector_hidden_div").remove();
		$("div.lightbox").html(content.html());
		$("div.lightbox").css({'background' : 'white', 'width' : '580px', 'padding' : '20px'});	
	}	
	lightbox.load();
	return false;
});

if(typeof window.grp_update_invite_list == 'function') {
window.grp_update_invite_list();
}
if ($('a.sendnewmessage').length)
{
	$('a.sendnewmessage').bind('click', function () {
	
		var guid = $(this).attr('rel');
	
		lightboxcontent.load('http://www.beebac.com/mod/messages/newmessages.php?send_to=' + guid);
		lightboxcontent.parent().css('width', '540px');
		lightbox.load();
		
		return false;
	});
}if ($('div.media_controls a').length)
{
	$('div.media_controls a.addembed').bind('click', function () {
		$('#embeditem').slideToggle();
		return false;
	});
	$("#publication ul.sortable").sortable();
	
	var medialist = $("#publication ul.sortable");
	
	medialist.bind('sortupdate', function (event, ui) {
		var elems = $('#publication ul.sortable li input[type=hidden].count');
		elems.each(function (i) {
			this.value = i;
		});
	});
	
	$("#publication ul.sortable li div.hd span").live('click', function () {
		var mediaticket = $(this).parent().parent();
		mediaticket.find('div.bd').slideToggle();
	});
	
	$("#publication ul.sortable li div.hd a.delete").live('click', function () {
		var mediaticket = $(this).parent().parent().parent();
		mediaticket.remove();
		return false;
	});
		
	$('#addembedbutton').bind('click', function() {
		var embed = $('#embeditem textarea[name=embedarea]');
		if (embed.val())
		{
			addToMediaList(medialist, 'Code embed', embed.val(), 'embed');
			embed.attr('value', '');
			$.jGrowl("Le code embed a été ajouté à votre publication", { theme: 'success' });
			$('#embeditem').fadeOut();
		}	
		return false;
	});
}

if ($('div.contentnav select[name=pagefilter]').length)
{
	$('div.contentnav select[name=pagefilter]').bind('change', function () {

		var url = $(this).val();
		window.location.replace(url);
	});
}

if ($('div.desk_filter select[name=pagefilter]').length)
{
	$('div.desk_filter select[name=pagefilter]').bind('change', function () {

		var url = $(this).val();
		window.location.replace(url);
	});
}if ($('#connexionlink').length)
{
	$('#connexionlink').bind('click', function () {

		lightboxcontent.css('padding', 0);
		lightboxcontent.parent().css('width', '580px');
		lightbox.load();
	
		return false;
	});
}});     
;(function($){$.fn.ajaxSubmit=function(options){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){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||{});var veto={};this.trigger('form-pre-serialize',[this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');return this;}
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]});}}
if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false){log('ajaxSubmit: submit aborted via beforeSubmit callback');return this;}
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;}
else
options.data=q;var $form=this,callbacks=[];if(options.resetForm)callbacks.push(function(){$form.resetForm();});if(options.clearForm)callbacks.push(function(){$form.clearForm();});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){for(var i=0,max=callbacks.length;i<max;i++)
callbacks[i].apply(options,[data,status,xhr||$form,$form]);};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;if((files.length&&options.iframe!==false)||options.iframe||found||multipart){if(options.closeKeepAlive)
$.get(options.closeKeepAlive,fileUpload);else
fileUpload();}
else
$.ajax(options);this.trigger('form-submit-notify',[this,options]);return this;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={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);}};var g=opts.global;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;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;}}}
function doSubmit(){var t=$form.attr('target'),a=$form.attr('action');form.setAttribute('target',id);if(form.getAttribute('method')!='POST')
form.setAttribute('method','POST');if(form.getAttribute('action')!=opts.url)
form.setAttribute('action',opts.url);if(!opts.skipEncodingOverride){$form.attr({encoding:'multipart/form-data',enctype:'multipart/form-data'});}
if(opts.timeout)
setTimeout(function(){timedOut=true;cb();},opts.timeout);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]);$io.appendTo('body');$io.data('form-plugin-onload',cb);form.submit();}
finally{form.setAttribute('action',a);t?form.setAttribute('target',t):$form.removeAttr('target');$(extraInputs).remove();}};if(opts.forceSync)
doSubmit();else
setTimeout(doSubmit,10);var domCheckCount=100;function cb(){if(cbInvoked)
return;var ok=true;try{if(timedOut)throw'timeout';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){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'){var ta=doc.getElementsByTagName('textarea')[0];if(ta)
xhr.responseText=ta.value;else{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);}
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');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);}
else
doc=(new DOMParser()).parseFromString(s,'text/xml');return(doc&&doc.documentElement&&doc.documentElement.tagName!='parsererror')?doc:null;};};};$.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"))){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'){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;}}
setTimeout(function(){form.clk=form.clk_x=form.clk_y=null;},100);});};$.fn.ajaxFormUnbind=function(){return this.unbind('submit.form-plugin click.form-plugin');};$.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"){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){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;};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic));};$.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});});return $.param(a);};$.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;};$.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)
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;};$.fn.clearForm=function(){return this.each(function(){$('input,select,textarea',this).clearFields();});};$.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;});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType))
this.reset();});};$.fn.enable=function(b){if(b==undefined)b=true;return this.each(function(){this.disabled=!b;});};$.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'){$sel.find('option').selected(false);}
this.selected=select;}});};function log(){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);/*
	Masked Input plugin for jQuery
	Copyright (c) 2007-2009 Josh Bush (digitalbush.com)
	Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) 
	Version: 1.2.2 (03/09/2009 22:39:06)
*/
(function(a){var c=(a.browser.msie?"paste":"input")+".mask";var b=(window.orientation!=undefined);a.mask={definitions:{"9":"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"}};a.fn.extend({caret:function(e,f){if(this.length==0){return}if(typeof e=="number"){f=(typeof f=="number")?f:e;return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,f)}else{if(this.createTextRange){var g=this.createTextRange();g.collapse(true);g.moveEnd("character",f);g.moveStart("character",e);g.select()}}})}else{if(this[0].setSelectionRange){e=this[0].selectionStart;f=this[0].selectionEnd}else{if(document.selection&&document.selection.createRange){var d=document.selection.createRange();e=0-d.duplicate().moveStart("character",-100000);f=e+d.text.length}}return{begin:e,end:f}}},unmask:function(){return this.trigger("unmask")},mask:function(j,d){if(!j&&this.length>0){var f=a(this[0]);var g=f.data("tests");return a.map(f.data("buffer"),function(l,m){return g[m]?l:null}).join("")}d=a.extend({placeholder:"_",completed:null},d);var k=a.mask.definitions;var g=[];var e=j.length;var i=null;var h=j.length;a.each(j.split(""),function(m,l){if(l=="?"){h--;e=m}else{if(k[l]){g.push(new RegExp(k[l]));if(i==null){i=g.length-1}}else{g.push(null)}}});return this.each(function(){var r=a(this);var m=a.map(j.split(""),function(x,y){if(x!="?"){return k[x]?d.placeholder:x}});var n=false;var q=r.val();r.data("buffer",m).data("tests",g);function v(x){while(++x<=h&&!g[x]){}return x}function t(x){while(!g[x]&&--x>=0){}for(var y=x;y<h;y++){if(g[y]){m[y]=d.placeholder;var z=v(y);if(z<h&&g[y].test(m[z])){m[y]=m[z]}else{break}}}s();r.caret(Math.max(i,x))}function u(y){for(var A=y,z=d.placeholder;A<h;A++){if(g[A]){var B=v(A);var x=m[A];m[A]=z;if(B<h&&g[B].test(x)){z=x}else{break}}}}function l(y){var x=a(this).caret();var z=y.keyCode;n=(z<16||(z>16&&z<32)||(z>32&&z<41));if((x.begin-x.end)!=0&&(!n||z==8||z==46)){w(x.begin,x.end)}if(z==8||z==46||(b&&z==127)){t(x.begin+(z==46?0:-1));return false}else{if(z==27){r.val(q);r.caret(0,p());return false}}}function o(B){if(n){n=false;return(B.keyCode==8)?false:null}B=B||window.event;var C=B.charCode||B.keyCode||B.which;var z=a(this).caret();if(B.ctrlKey||B.altKey||B.metaKey){return true}else{if((C>=32&&C<=125)||C>186){var x=v(z.begin-1);if(x<h){var A=String.fromCharCode(C);if(g[x].test(A)){u(x);m[x]=A;s();var y=v(x);a(this).caret(y);if(d.completed&&y==h){d.completed.call(r)}}}}}return false}function w(x,y){for(var z=x;z<y&&z<h;z++){if(g[z]){m[z]=d.placeholder}}}function s(){return r.val(m.join("")).val()}function p(y){var z=r.val();var C=-1;for(var B=0,x=0;B<h;B++){if(g[B]){m[B]=d.placeholder;while(x++<z.length){var A=z.charAt(x-1);if(g[B].test(A)){m[B]=A;C=B;break}}if(x>z.length){break}}else{if(m[B]==z[x]&&B!=e){x++;C=B}}}if(!y&&C+1<e){r.val("");w(0,h)}else{if(y||C+1>=e){s();if(!y){r.val(r.val().substring(0,C+1))}}}return(e?B:i)}if(!r.attr("readonly")){r.one("unmask",function(){r.unbind(".mask").removeData("buffer").removeData("tests")}).bind("focus.mask",function(){q=r.val();var x=p();s();setTimeout(function(){if(x==j.length){r.caret(0,x)}else{r.caret(x)}},0)}).bind("blur.mask",function(){p();if(r.val()!=q){r.change()}}).bind("keydown.mask",l).bind("keypress.mask",o).bind(c,function(){setTimeout(function(){r.caret(p(true))},0)})}p()})}})})(jQuery);(function(jQuery){jQuery.fn.extend({elastic:function(){var mimics=['paddingTop','paddingRight','paddingBottom','paddingLeft','fontSize','lineHeight','fontFamily','width','fontWeight'];return this.each(function(){if(this.type!='textarea'){return false}var $textarea=jQuery(this),$twin=jQuery('<div />').css({'position':'absolute','display':'none','word-wrap':'break-word'}),lineHeight=parseInt($textarea.css('line-height'),10)||parseInt($textarea.css('font-size'),'10'),minheight=parseInt($textarea.css('height'),10)||lineHeight*3,maxheight=parseInt($textarea.css('max-height'),10)||Number.MAX_VALUE,goalheight=0,i=0;if(maxheight<0){maxheight=Number.MAX_VALUE}$twin.appendTo($textarea.parent());var i=mimics.length;while(i--){$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()))}function setHeightAndOverflow(height,overflow){curratedHeight=Math.floor(parseInt(height,10));if($textarea.height()!=curratedHeight){$textarea.css({'height':curratedHeight+'px','overflow':overflow})}}function update(){var textareaContent=$textarea.val().replace(/&/g,'&amp;').replace(/  /g,'&nbsp;').replace(/<|>/g,'&gt;').replace(/\n/g,'<br />');var twinContent=$twin.html();if(textareaContent+'&nbsp;'!=twinContent){$twin.html(textareaContent+'&nbsp;');if(Math.abs($twin.height()+lineHeight-$textarea.height())>3){var goalheight=$twin.height()+lineHeight;if(goalheight>=maxheight){setHeightAndOverflow(maxheight,'auto')}else if(goalheight<=minheight){setHeightAndOverflow(minheight,'hidden')}else{setHeightAndOverflow(goalheight,'hidden')}}}}$textarea.css({'overflow':'hidden'});$textarea.keyup(function(){update()});$textarea.live('input paste',function(e){setTimeout(update,250)});update()})}})})(jQuery);/* FCBKcomplete 2.7.2 - Jquery version required: 1.2.x, 1.3.x, 1.4.x  Changelog: - 2.00	new version of fcbkcomplete  - 2.01 fixed bugs & added features 		fixed filter bug for preadded items		focus on the input after selecting tag		the element removed pressing backspace when the element is selected		input tag in the control has a border in IE7		added iterate over each match and apply the plugin separately		set focus on the input after selecting tag  - 2.02 fixed fist element selected bug		fixed defaultfilter error bug  - 2.5 	removed selected="selected" attribute due ie bug		element search algorithm changed		better performance fix added		fixed many small bugs		onselect event added		onremove event added  - 2.6 	ie6/7 support fix added		added new public method addItem due request		added new options "firstselected" that you can set true/false to select first element on dropdown list		autoexpand input element added		removeItem bug fixed		and many more bug fixed 		fixed public method to use it $("elem").trigger("addItem",[{"title": "test", "value": "test"}]);		- 2.7 	jquery 1.4 compability 		item lock possability added by adding locked class to preadded option <option value="value" class="selected locked">text</option> 		maximum item that can be added- 2.7.1 bug fixed		ajax delay added thanks to http://github.com/dolorian- 2.7.2 some minor bug fixed		minified version recompacted due some problems *//* Coded by: emposha <admin@emposha.com> *//* Copyright: Emposha.com <http://www.emposha.com/> - Distributed under MIT - Keep this message! *//* * json_url         - url to fetch json object * cache       		- use cache * height           - maximum number of element shown before scroll will apear * newel            - show typed text like a element * firstselected	- automaticly select first element from dropdown * filter_case      - case sensitive filter * filter_selected  - filter selected items from list * complete_text    - text for complete page * maxshownitems	- maximum numbers that will be shown at dropdown list (less better performance) * onselect			- fire event on item select * onremove			- fire event on item remove * maxitimes		- maximum items that can be added * delay			- delay between ajax request (bigger delay, lower server time request) */jQuery(function($){$.fn.fcbkcomplete=function(opt){return this.each(function(){function init(){createFCBK();preSet();addInput(0);}function createFCBK(){element.hide();element.attr("multiple","multiple");if(element.attr("name").indexOf("[]")==-1){element.attr("name",element.attr("name")+"[]");}holder=$(document.createElement("ul"));holder.attr("class","holder");element.after(holder);complete=$(document.createElement("div"));complete.addClass("facebook-auto");complete.append('<div class="default">'+options.complete_text+"</div>");if(browser_msie){complete.append('<iframe class="ie6fix" scrolling="no" frameborder="0"></iframe>');browser_msie_frame=complete.children('.ie6fix');}feed=$(document.createElement("ul"));feed.attr("id",elemid+"_feed");complete.prepend(feed);holder.after(complete);feed.css("width",complete.width());}function preSet(){element.children("option").each(function(i,option){option=$(option);if(option.hasClass("selected")){addItem(option.text(),option.val(),true,option.hasClass("locked"));option.attr("selected","selected");}else{option.removeAttr("selected");}cache.push({caption:option.text(),value:option.val()});search_string+=""+(cache.length-1)+":"+option.text()+";";});}$(this).bind("addItem",function(event,data){addItem(data.title,data.value);});function addItem(title,value,preadded,locked){if(!maxItems()){return false;}var li=document.createElement("li");var txt=document.createTextNode(title);var aclose=document.createElement("a");var liclass="bit-box"+(locked?" locked":"");$(li).attr({"class":liclass,"rel":value});$(li).prepend(txt);$(aclose).attr({"class":"closebutton","href":"#"});li.appendChild(aclose);holder.append(li);$(aclose).click(function(){removeItem($(this).parent("li"));return false;});if(!preadded){$("#"+elemid+"_annoninput").remove();var _item;addInput(1);if(element.children("option[value="+value+"]").length){_item=element.children("option[value="+value+"]");_item.get(0).setAttribute("selected","selected");if(!_item.hasClass("selected")){_item.addClass("selected");}}else{var _item=$(document.createElement("option"));_item.attr("value",value).get(0).setAttribute("selected","selected");_item.attr("value",value).addClass("selected");_item.text(title);element.append(_item);}if(options.onselect.length){funCall(options.onselect,_item)}}holder.children("li.bit-box.deleted").removeClass("deleted");feed.hide();browser_msie?browser_msie_frame.hide():'';}function removeItem(item){if(!item.hasClass('locked')){item.fadeOut("fast");if(options.onremove.length){var _item=element.children("option[value="+item.attr("rel")+"]");funCall(options.onremove,_item)}element.children('option[value="'+item.attr("rel")+'"]').removeAttr("selected").removeClass("selected");item.remove();deleting=0;}}function addInput(focusme){var li=$(document.createElement("li"));var input=$(document.createElement("input"));var getBoxTimeout=0;li.attr({"class":"bit-input","id":elemid+"_annoninput"});input.attr({"type":"text","class":"maininput","size":"1"});holder.append(li.append(input));input.focus(function(){complete.fadeIn("fast");});input.blur(function(){complete.fadeOut("fast");});holder.click(function(){input.focus();if(feed.length&&input.val().length){feed.show();}else{feed.hide();browser_msie?browser_msie_frame.hide():'';complete.children(".default").show();}});input.keypress(function(event){if(event.keyCode==13){return false;}input.attr("size",input.val().length+1);});input.keydown(function(event){if(event.keyCode==191){event.preventDefault();return false;}});input.keyup(function(event){var etext=xssPrevent(input.val());if(event.keyCode==8&&etext.length==0){feed.hide();browser_msie?browser_msie_frame.hide():'';if(!holder.children("li.bit-box:last").hasClass('locked')){if(holder.children("li.bit-box.deleted").length==0){holder.children("li.bit-box:last").addClass("deleted");return false;}else{if(deleting){return;}deleting=1;holder.children("li.bit-box.deleted").fadeOut("fast",function(){removeItem($(this));return false;});}}}if(event.keyCode!=40&&event.keyCode!=38&&etext.length!=0){counter=0;if(options.json_url){if(options.cache&&json_cache){addMembers(etext);bindEvents();}else{getBoxTimeout++;var getBoxTimeoutValue=getBoxTimeout;setTimeout(function(){if(getBoxTimeoutValue!=getBoxTimeout)return;$.getJSON(options.json_url+(options.json_url.indexOf("?")>-1?"&":"?")+"tag="+etext,null,function(data){addMembers(etext,data);json_cache=true;bindEvents();});},options.delay);}}else{addMembers(etext);bindEvents();}complete.children(".default").hide();feed.show();}});if(focusme){setTimeout(function(){input.focus();complete.children(".default").show();},1);}}function addMembers(etext,data){feed.html('');if(!options.cache&&data!=null){cache=new Array();search_string="";}addTextItem(etext);if(data!=null&&data.length){$.each(data,function(i,val){cache.push({caption:val.caption,value:val.value});search_string+=""+(cache.length-1)+":"+val.caption+";";});}var maximum=options.maxshownitems<cache.length?options.maxshownitems:cache.length;var filter="i";if(options.filter_case){filter="";}var myregexp,match;try{myregexp=eval('/(?:^|;)\\s*(\\d+)\\s*:[^;]*?'+etext+'[^;]*/g'+filter);match=myregexp.exec(search_string);}catch(ex){};var content='';while(match!=null&&maximum>0){var id=match[1];var object=cache[id];if(options.filter_selected&&element.children("option[value="+object.value+"]").hasClass("selected")){}else{content+='<li rel="'+object.value+'">'+itemIllumination(object.caption,etext)+'</li>';counter++;maximum--;}match=myregexp.exec(search_string);}feed.append(content);if(options.firstselected){focuson=feed.children("li:visible:first");focuson.addClass("auto-focus");}if(counter>options.height){feed.css({"height":(options.height*24)+"px","overflow":"auto"});if(browser_msie){browser_msie_frame.css({"height":(options.height*24)+"px","width":feed.width()+"px"}).show();}}else{feed.css("height","auto");if(browser_msie){browser_msie_frame.css({"height":feed.height()+"px","width":feed.width()+"px"}).show();}}}function itemIllumination(text,etext){if(options.filter_case){try{eval("var text = text.replace(/(.*)("+etext+")(.*)/gi,'$1<em>$2</em>$3');");}catch(ex){};}else{try{eval("var text = text.replace(/(.*)("+etext.toLowerCase()+")(.*)/gi,'$1<em>$2</em>$3');");}catch(ex){};}return text;}function bindFeedEvent(){feed.children("li").mouseover(function(){feed.children("li").removeClass("auto-focus");$(this).addClass("auto-focus");focuson=$(this);});feed.children("li").mouseout(function(){$(this).removeClass("auto-focus");focuson=null;});}function removeFeedEvent(){feed.children("li").unbind("mouseover");feed.children("li").unbind("mouseout");feed.mousemove(function(){bindFeedEvent();feed.unbind("mousemove");});}function bindEvents(){var maininput=$("#"+elemid+"_annoninput").children(".maininput");bindFeedEvent();feed.children("li").unbind("mousedown");feed.children("li").mousedown(function(){var option=$(this);addItem(option.text(),option.attr("rel"));feed.hide();browser_msie?browser_msie_frame.hide():'';complete.hide();});maininput.unbind("keydown");maininput.keydown(function(event){if(event.keyCode==191){event.preventDefault();return false;}if(event.keyCode!=8){holder.children("li.bit-box.deleted").removeClass("deleted");}if(event.keyCode==13&&checkFocusOn()){var option=focuson;addItem(option.text(),option.attr("rel"));complete.hide();event.preventDefault();focuson=null;return false;}if(event.keyCode==13&&!checkFocusOn()){if(options.newel){var value=xssPrevent($(this).val());addItem(value,value);complete.hide();event.preventDefault();focuson=null;}return false;}if(event.keyCode==40){removeFeedEvent();if(focuson==null||focuson.length==0){focuson=feed.children("li:visible:first");feed.get(0).scrollTop=0;}else{focuson.removeClass("auto-focus");focuson=focuson.nextAll("li:visible:first");var prev=parseInt(focuson.prevAll("li:visible").length,10);var next=parseInt(focuson.nextAll("li:visible").length,10);if((prev>Math.round(options.height/2)||next<=Math.round(options.height/2))&&typeof(focuson.get(0))!="undefined"){feed.get(0).scrollTop=parseInt(focuson.get(0).scrollHeight,10)*(prev-Math.round(options.height/2));}}feed.children("li").removeClass("auto-focus");focuson.addClass("auto-focus");}if(event.keyCode==38){removeFeedEvent();if(focuson==null||focuson.length==0){focuson=feed.children("li:visible:last");feed.get(0).scrollTop=parseInt(focuson.get(0).scrollHeight,10)*(parseInt(feed.children("li:visible").length,10)-Math.round(options.height/2));}else{focuson.removeClass("auto-focus");focuson=focuson.prevAll("li:visible:first");var prev=parseInt(focuson.prevAll("li:visible").length,10);var next=parseInt(focuson.nextAll("li:visible").length,10);if((next>Math.round(options.height/2)||prev<=Math.round(options.height/2))&&typeof(focuson.get(0))!="undefined"){feed.get(0).scrollTop=parseInt(focuson.get(0).scrollHeight,10)*(prev-Math.round(options.height/2));}}feed.children("li").removeClass("auto-focus");focuson.addClass("auto-focus");}});}function maxItems(){if(options.maxitems!=0){if(holder.children("li.bit-box").length<options.maxitems){return true;}else{return false;}}}function addTextItem(value){if(options.newel&&maxItems()){feed.children("li[fckb=1]").remove();if(value.length==0){return;}var li=$(document.createElement("li"));li.attr({"rel":value,"fckb":"1"}).html(value);feed.prepend(li);counter++;}else{return;}}function funCall(func,item){var _object="";for(i=0;i<item.get(0).attributes.length;i++){if(item.get(0).attributes[i].nodeValue!=null){_object+="\"_"+item.get(0).attributes[i].nodeName+"\": \""+item.get(0).attributes[i].nodeValue+"\",";}}_object="{"+_object+" notinuse: 0}";try{eval(func+"("+_object+")");}catch(ex){};}function checkFocusOn(){if(focuson==null){return false;}if(focuson.length==0){return false;}return true;}function xssPrevent(string){string=string.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g,"\"\"");string=string.replace(/script(.*)/g,"");string=string.replace(/eval\((.*)\)/g,"");string=string.replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/','');return string;}var options=$.extend({json_url:null,cache:false,height:"10",newel:false,firstselected:false,filter_case:false,filter_hide:false,complete_text:"Start to type...",maxshownitems:30,maxitems:10,onselect:"",onremove:"",delay:350},opt);var holder=null;var feed=null;var complete=null;var counter=0;var cache=new Array();var json_cache=false;var search_string="";var focuson=null;var deleting=0;var browser_msie="\v"=="v";var browser_msie_frame;var element=$(this);var elemid=element.attr("id");init();return this;});};});(function(jQuery){jQuery.fn.extend({elastic:function(){var mimics=['paddingTop','paddingRight','paddingBottom','paddingLeft','fontSize','lineHeight','fontFamily','width','fontWeight'];return this.each(function(){if(this.type!='textarea'){return false}var $textarea=jQuery(this),$twin=jQuery('<div />').css({'position':'absolute','display':'none','word-wrap':'break-word'}),lineHeight=parseInt($textarea.css('line-height'),10)||parseInt($textarea.css('font-size'),'10'),minheight=parseInt($textarea.css('height'),10)||lineHeight*3,maxheight=parseInt($textarea.css('max-height'),10)||Number.MAX_VALUE,goalheight=0,i=0;if(maxheight<0){maxheight=Number.MAX_VALUE}$twin.appendTo($textarea.parent());var i=mimics.length;while(i--){$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()))}function setHeightAndOverflow(height,overflow){curratedHeight=Math.floor(parseInt(height,10));if($textarea.height()!=curratedHeight){$textarea.css({'height':curratedHeight+'px','overflow':overflow})}}function update(){var textareaContent=$textarea.val().replace(/&/g,'&amp;').replace(/  /g,'&nbsp;').replace(/<|>/g,'&gt;').replace(/\n/g,'<br />');var twinContent=$twin.html();if(textareaContent+'&nbsp;'!=twinContent){$twin.html(textareaContent+'&nbsp;');if(Math.abs($twin.height()+lineHeight-$textarea.height())>3){var goalheight=$twin.height()+lineHeight;if(goalheight>=maxheight){setHeightAndOverflow(maxheight,'auto')}else if(goalheight<=minheight){setHeightAndOverflow(minheight,'hidden')}else{setHeightAndOverflow(goalheight,'hidden')}}}}$textarea.css({'overflow':'hidden'});$textarea.keyup(function(){update()});$textarea.live('input paste',function(e){setTimeout(update,250)});update()})}})})(jQuery);/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();/*
Uploadify v2.1.0
Release Date: August 24, 2009

Copyright (c) 2009 Ronnie Garcia, Travis Nickels

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

if(jQuery){(function(a){a.extend(a.fn,{uploadify:function(b){a(this).each(function(){settings=a.extend({id:a(this).attr("id"),uploader:"uploadify.swf",script:"uploadify.php",expressInstall:null,folder:"",height:30,width:110,cancelImg:"cancel.png",wmode:"opaque",scriptAccess:"sameDomain",fileDataName:"Filedata",method:"POST",queueSizeLimit:999,simUploadLimit:1,queueID:false,displayData:"percentage",onInit:function(){},onSelect:function(){},onQueueFull:function(){},onCheck:function(){},onCancel:function(){},onError:function(){},onProgress:function(){},onComplete:function(){},onAllComplete:function(){}},b);var e=location.pathname;e=e.split("/");e.pop();e=e.join("/")+"/";var f={};f.uploadifyID=settings.id;f.pagepath=e;if(settings.buttonImg){f.buttonImg=escape(settings.buttonImg)}if(settings.buttonText){f.buttonText=escape(settings.buttonText)}if(settings.rollover){f.rollover=true}f.script=settings.script;f.folder=escape(settings.folder);if(settings.scriptData){var g="";for(var d in settings.scriptData){g+="&"+d+"="+settings.scriptData[d]}f.scriptData=escape(g.substr(1))}f.width=settings.width;f.height=settings.height;f.wmode=settings.wmode;f.method=settings.method;f.queueSizeLimit=settings.queueSizeLimit;f.simUploadLimit=settings.simUploadLimit;if(settings.hideButton){f.hideButton=true}if(settings.fileDesc){f.fileDesc=settings.fileDesc}if(settings.fileExt){f.fileExt=settings.fileExt}if(settings.multi){f.multi=true}if(settings.auto){f.auto=true}if(settings.sizeLimit){f.sizeLimit=settings.sizeLimit}if(settings.checkScript){f.checkScript=settings.checkScript}if(settings.fileDataName){f.fileDataName=settings.fileDataName}if(settings.queueID){f.queueID=settings.queueID}if(settings.onInit()!==false){a(this).css("display","none");a(this).after('<div id="'+a(this).attr("id")+'Uploader"></div>');swfobject.embedSWF(settings.uploader,settings.id+"Uploader",settings.width,settings.height,"9.0.24",settings.expressInstall,f,{quality:"high",wmode:settings.wmode,allowScriptAccess:settings.scriptAccess});if(settings.queueID==false){a("#"+a(this).attr("id")+"Uploader").after('<div id="'+a(this).attr("id")+'Queue" class="uploadifyQueue"></div>')}}if(typeof(settings.onOpen)=="function"){a(this).bind("uploadifyOpen",settings.onOpen)}a(this).bind("uploadifySelect",{action:settings.onSelect,queueID:settings.queueID},function(j,h,i){if(j.data.action(j,h,i)!==false){var k=Math.round(i.size/1024*100)*0.01;var l="KB";if(k>1000){k=Math.round(k*0.001*100)*0.01;l="MB"}var m=k.toString().split(".");if(m.length>1){k=m[0]+"."+m[1].substr(0,2)}else{k=m[0]}if(i.name.length>20){fileName=i.name.substr(0,20)+"..."}else{fileName=i.name}queue="#"+a(this).attr("id")+"Queue";if(j.data.queueID){queue="#"+j.data.queueID}a(queue).append('<div id="'+a(this).attr("id")+h+'" class="uploadifyQueueItem"><div class="cancel"><a href="javascript:jQuery(\'#'+a(this).attr("id")+"').uploadifyCancel('"+h+'\')"><img src="'+settings.cancelImg+'" border="0" /></a></div><span class="fileName">'+fileName+" ("+k+l+')</span><span class="percentage"></span><div class="uploadifyProgress"><div id="'+a(this).attr("id")+h+'ProgressBar" class="uploadifyProgressBar"><!--Progress Bar--></div></div></div>')}});if(typeof(settings.onSelectOnce)=="function"){a(this).bind("uploadifySelectOnce",settings.onSelectOnce)}a(this).bind("uploadifyQueueFull",{action:settings.onQueueFull},function(h,i){if(h.data.action(h,i)!==false){alert("The queue is full.  The max size is "+i+".")}});a(this).bind("uploadifyCheckExist",{action:settings.onCheck},function(m,l,k,j,o){var i=new Object();i=k;i.folder=e+j;if(o){for(var h in k){var n=h}}a.post(l,i,function(r){for(var p in r){if(m.data.action(m,l,k,j,o)!==false){var q=confirm("Do you want to replace the file "+r[p]+"?");if(!q){document.getElementById(a(m.target).attr("id")+"Uploader").cancelFileUpload(p,true,true)}}}if(o){document.getElementById(a(m.target).attr("id")+"Uploader").startFileUpload(n,true)}else{document.getElementById(a(m.target).attr("id")+"Uploader").startFileUpload(null,true)}},"json")});a(this).bind("uploadifyCancel",{action:settings.onCancel},function(l,h,k,m,j){if(l.data.action(l,h,k,m,j)!==false){var i=(j==true)?0:250;a("#"+a(this).attr("id")+h).fadeOut(i,function(){a(this).remove()})}});if(typeof(settings.onClearQueue)=="function"){a(this).bind("uploadifyClearQueue",settings.onClearQueue)}var c=[];a(this).bind("uploadifyError",{action:settings.onError},function(l,h,k,j){if(l.data.action(l,h,k,j)!==false){var i=new Array(h,k,j);c.push(i);a("#"+a(this).attr("id")+h+" .percentage").text(" - "+j.type+" Error");a("#"+a(this).attr("id")+h).addClass("uploadifyError")}});a(this).bind("uploadifyProgress",{action:settings.onProgress,toDisplay:settings.displayData},function(j,h,i,k){if(j.data.action(j,h,i,k)!==false){a("#"+a(this).attr("id")+h+"ProgressBar").css("width",k.percentage+"%");if(j.data.toDisplay=="percentage"){displayData=" - "+k.percentage+"%"}if(j.data.toDisplay=="speed"){displayData=" - "+k.speed+"KB/s"}if(j.data.toDisplay==null){displayData=" "}a("#"+a(this).attr("id")+h+" .percentage").text(displayData)}});a(this).bind("uploadifyComplete",{action:settings.onComplete},function(k,h,j,i,l){if(k.data.action(k,h,j,unescape(i),l)!==false){a("#"+a(this).attr("id")+h+" .percentage").text(" - Completed");a("#"+a(this).attr("id")+h).fadeOut(250,function(){a(this).remove()})}});if(typeof(settings.onAllComplete)=="function"){a(this).bind("uploadifyAllComplete",{action:settings.onAllComplete},function(h,i){if(h.data.action(h,i)!==false){c=[]}})}})},uploadifySettings:function(f,j,c){var g=false;a(this).each(function(){if(f=="scriptData"&&j!=null){if(c){var i=j}else{var i=a.extend(settings.scriptData,j)}var l="";for(var k in i){l+="&"+k+"="+escape(i[k])}j=l.substr(1)}g=document.getElementById(a(this).attr("id")+"Uploader").updateSettings(f,j)});if(j==null){if(f=="scriptData"){var b=unescape(g).split("&");var e=new Object();for(var d=0;d<b.length;d++){var h=b[d].split("=");e[h[0]]=h[1]}g=e}return g}},uploadifyUpload:function(b){a(this).each(function(){document.getElementById(a(this).attr("id")+"Uploader").startFileUpload(b,false)})},uploadifyCancel:function(b){a(this).each(function(){document.getElementById(a(this).attr("id")+"Uploader").cancelFileUpload(b,true,false)})},uploadifyClearQueue:function(){a(this).each(function(){document.getElementById(a(this).attr("id")+"Uploader").clearFileUploadQueue(false)})}})})(jQuery)};$(window).load(function () {
	var approved = $("a.approved");
	
	$(approved).bind('click', function () {
		var elem = $(this);
		var url = elem.attr('href');
		$.getJSON(url + '&ajax=1',
				function(data){
			    	if (data['success'] == true)
			    	{
			    		if (data['action'] == 'approved')
			    		{
			    			var reg=new RegExp("(approve)", "g");
			    			url = url.replace(reg, 'unapprove');
			    			elem.addClass('on');
			    			
			    		}	
			    		else
			    		{
			    			var reg=new RegExp("(unapprove)", "g");
			    			url = url.replace(reg, 'approve');
			    			elem.removeClass('on');
			    		}
			    		elem.attr('href', url);
			    		//$.jGrowl(data['message'], { theme: 'success' });
			    	} 
//					else
						//$.jGrowl(data['message'], { life: 50000, theme: 'error' });
    	
    			}
    	);
        return false;	
	});
});

function commentlikecallback(guid)
{
	var val = parseInt($('#likecount' + guid + ' quote').html()) + 1;
	$('#likecount' + guid + ' quote').html(val);
}

function commentunlikecallback(guid)
{
	var val = parseInt($('#likecount' + guid + ' quote').html()) - 1;
	$('#likecount' + guid + ' quote').html(val);
}/*
    http://www.JSON.org/json2.js
    2009-06-29

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html

    This file creates a global JSON object containing two methods: stringify
    and parse.

        JSON.stringify(value, replacer, space)
            value       any JavaScript value, usually an object or array.

            replacer    an optional parameter that determines how object
                        values are stringified for objects. It can be a
                        function or an array of strings.

            space       an optional parameter that specifies the indentation
                        of nested structures. If it is omitted, the text will
                        be packed without extra whitespace. If it is a number,
                        it will specify the number of spaces to indent at each
                        level. If it is a string (such as '\t' or '&nbsp;'),
                        it contains the characters used to indent at each level.

            This method produces a JSON text from a JavaScript value.

            When an object value is found, if the object contains a toJSON
            method, its toJSON method will be called and the result will be
            stringified. A toJSON method does not serialize: it returns the
            value represented by the name/value pair that should be serialized,
            or undefined if nothing should be serialized. The toJSON method
            will be passed the key associated with the value, and this will be
            bound to the object holding the key.

            For example, this would serialize Dates as ISO strings.

                Date.prototype.toJSON = function (key) {
                    function f(n) {
                        // Format integers to have at least two digits.
                        return n < 10 ? '0' + n : n;
                    }

                    return this.getUTCFullYear()   + '-' +
                         f(this.getUTCMonth() + 1) + '-' +
                         f(this.getUTCDate())      + 'T' +
                         f(this.getUTCHours())     + ':' +
                         f(this.getUTCMinutes())   + ':' +
                         f(this.getUTCSeconds())   + 'Z';
                };

            You can provide an optional replacer method. It will be passed the
            key and value of each member, with this bound to the containing
            object. The value that is returned from your method will be
            serialized. If your method returns undefined, then the member will
            be excluded from the serialization.

            If the replacer parameter is an array of strings, then it will be
            used to select the members to be serialized. It filters the results
            such that only members with keys listed in the replacer array are
            stringified.

            Values that do not have JSON representations, such as undefined or
            functions, will not be serialized. Such values in objects will be
            dropped; in arrays they will be replaced with null. You can use
            a replacer function to replace those with JSON values.
            JSON.stringify(undefined) returns undefined.

            The optional space parameter produces a stringification of the
            value that is filled with line breaks and indentation to make it
            easier to read.

            If the space parameter is a non-empty string, then that string will
            be used for indentation. If the space parameter is a number, then
            the indentation will be that many spaces.

            Example:

            text = JSON.stringify(['e', {pluribus: 'unum'}]);
            // text is '["e",{"pluribus":"unum"}]'


            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

            text = JSON.stringify([new Date()], function (key, value) {
                return this[key] instanceof Date ?
                    'Date(' + this[key] + ')' : value;
            });
            // text is '["Date(---current time---)"]'


        JSON.parse(text, reviver)
            This method parses a JSON text to produce an object or array.
            It can throw a SyntaxError exception.

            The optional reviver parameter is a function that can filter and
            transform the results. It receives each of the keys and values,
            and its return value is used instead of the original value.
            If it returns what it received, then the structure is not modified.
            If it returns undefined then the member is deleted.

            Example:

            // Parse the text. Values that look like ISO date strings will
            // be converted to Date objects.

            myData = JSON.parse(text, function (key, value) {
                var a;
                if (typeof value === 'string') {
                    a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                    if (a) {
                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
                    }
                }
                return value;
            });

            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
                var d;
                if (typeof value === 'string' &&
                        value.slice(0, 5) === 'Date(' &&
                        value.slice(-1) === ')') {
                    d = new Date(value.slice(5, -1));
                    if (d) {
                        return d;
                    }
                }
                return value;
            });


    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
    NOT CONTROL.
*/

/*jslint evil: true */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/

// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

var JSON = JSON || {};

(function () {

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                   this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }


    function str(key, holder) {

// Produce a string from holder[key].

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

        case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

            if (!value) {
                return 'null';
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = '';
            indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === 'string') {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

            return str('', {'': value});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('JSON.parse');
        };
    }
}());
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options=$.extend({},options);options.expires=-1;}var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;}expires='; expires='+date.toUTCString();}var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+'=')){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break;}}}return cookieValue;}};/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 5/25/2009
 * @author Ariel Flesler
 * @version 1.4.2
 *
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 */
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);/*
 * jQuery.SerialScroll - Animated scrolling of series
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 06/14/2009
 * @author Ariel Flesler
 * @version 1.2.2
 * http://flesler.blogspot.com/2008/02/jqueryserialscroll.html
 */
;(function(a){var b=a.serialScroll=function(c){return a(window).serialScroll(c)};b.defaults={duration:1e3,axis:"x",event:"click",start:0,step:1,lock:!0,cycle:!0,constant:!0};a.fn.serialScroll=function(c){return this.each(function(){var t=a.extend({},b.defaults,c),s=t.event,i=t.step,r=t.lazy,e=t.target?this:document,u=a(t.target||this,e),p=u[0],m=t.items,h=t.start,g=t.interval,k=t.navigation,l;if(!r){m=d()}if(t.force){f({},h)}a(t.prev||[],e).bind(s,-i,q);a(t.next||[],e).bind(s,i,q);if(!p.ssbound){u.bind("prev.serialScroll",-i,q).bind("next.serialScroll",i,q).bind("goto.serialScroll",f)}if(g){u.bind("start.serialScroll",function(v){if(!g){o();g=!0;n()}}).bind("stop.serialScroll",function(){o();g=!1})}u.bind("notify.serialScroll",function(x,w){var v=j(w);if(v>-1){h=v}});p.ssbound=!0;if(t.jump){(r?u:d()).bind(s,function(v){f(v,j(v.target))})}if(k){k=a(k,e).bind(s,function(v){v.data=Math.round(d().length/k.length)*k.index(this);f(v,this)})}function q(v){v.data+=h;f(v,this)}function f(B,z){if(!isNaN(z)){B.data=z;z=p}var C=B.data,v,D=B.type,A=t.exclude?d().slice(0,-t.exclude):d(),y=A.length,w=A[C],x=t.duration;if(D){B.preventDefault()}if(g){o();l=setTimeout(n,t.interval)}if(!w){v=C<0?0:y-1;if(h!=v){C=v}else{if(!t.cycle){return}else{C=y-v-1}}w=A[C]}if(!w||t.lock&&u.is(":animated")||D&&t.onBefore&&t.onBefore(B,w,u,d(),C)===!1){return}if(t.stop){u.queue("fx",[]).stop()}if(t.constant){x=Math.abs(x/i*(h-C))}u.scrollTo(w,x,t).trigger("notify.serialScroll",[C])}function n(){u.trigger("next.serialScroll")}function o(){clearTimeout(l)}function d(){return a(m,p)}function j(w){if(!isNaN(w)){return w}var x=d(),v;while((v=x.index(w))==-1&&w!=p){w=w.parentNode}return v}})}})(jQuery);// This code was written by Tyler Akins and has been placed in the
// public domain.  It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com

var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

/**
 * Encodes a string in base64
 * @param {String} input The string to encode in base64.
 */
function encode64(input) {
   var output = "";
   var chr1, chr2, chr3;
   var enc1, enc2, enc3, enc4;
   var i = 0;

   do {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
         enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
         enc4 = 64;
      }

      output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
         keyStr.charAt(enc3) + keyStr.charAt(enc4);
   } while (i < input.length);

   return output;
}

/**
 * Decodes a base64 string.
 * @param {String} input The string to decode.
 */
function decode64(input) {
   var output = "";
   var chr1, chr2, chr3;
   var enc1, enc2, enc3, enc4;
   var i = 0;

   // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
   input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

   do {
      enc1 = keyStr.indexOf(input.charAt(i++));
      enc2 = keyStr.indexOf(input.charAt(i++));
      enc3 = keyStr.indexOf(input.charAt(i++));
      enc4 = keyStr.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
         output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
         output = output + String.fromCharCode(chr3);
      }
   } while (i < input.length);

   return output;
}
/*
 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
 * in FIPS PUB 180-1
 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for details.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = new Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  var i, j, t, olda, oldb, oldc, oldd, olde;
  for (i = 0; i < x.length; i += 16)
  {
    olda = a;
    oldb = b;
    oldc = c;
    oldd = d;
    olde = e;

    for (j = 0; j < 80; j++)
    {
      if (j < 16) { w[j] = x[i + j]; }
      else { w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); }
      t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return [a, b, c, d, e];
}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if (t < 20) { return (b & c) | ((~b) & d); }
  if (t < 40) { return b ^ c ^ d; }
  if (t < 60) { return (b & c) | (b & d) | (c & d); }
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if (bkey.length > 16) { bkey = core_sha1(bkey, key.length * chrsz); }

  var ipad = new Array(16), opad = new Array(16);
  for (var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = [];
  var mask = (1 << chrsz) - 1;
  for (var i = 0; i < str.length * chrsz; i += chrsz)
  {
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  }
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for (var i = 0; i < bin.length * 32; i += chrsz)
  {
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for (var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  var triplet, j;
  for (var i = 0; i < binarray.length * 4; i += 3)
  {
    triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16) |
              (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |
               ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for (j = 0; j < 4; j++)
    {
      if (i * 8 + j * 6 > binarray.length * 32) { str += b64pad; }
      else { str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); }
    }
  }
  return str;
}
/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  var olda, oldb, oldc, oldd;
  for(var i = 0; i < x.length; i += 16)
  {
    olda = a;
    oldb = b;
    oldc = c;
    oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return [a, b, c, d];
}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) { bkey = core_md5(bkey, key.length * chrsz); }

  var ipad = new Array(16), opad = new Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = [];
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
  {
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  }
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
  {
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  var triplet, j;
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16) |
              (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) |
              ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) { str += b64pad; }
      else { str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); }
    }
  }
  return str;
}
var Base64=(function(){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var obj={encode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;do{chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else{if(isNaN(chr3)){enc4=64}}output=output+keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4)}while(i<input.length);return output},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=(enc1<<2)|(enc2>>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2)}if(enc4!=64){output=output+String.fromCharCode(chr3)}}while(i<input.length);return output}};return obj})();var MD5=(function(){var hexcase=0;var b64pad="";var chrsz=8;var safe_add=function(x,y){var lsw=(x&65535)+(y&65535);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&65535)};var bit_rol=function(num,cnt){return(num<<cnt)|(num>>>(32-cnt))};var str2binl=function(str){var bin=[];var mask=(1<<chrsz)-1;for(var i=0;i<str.length*chrsz;i+=chrsz){bin[i>>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32)}return bin};var binl2str=function(bin){var str="";var mask=(1<<chrsz)-1;for(var i=0;i<bin.length*32;i+=chrsz){str+=String.fromCharCode((bin[i>>5]>>>(i%32))&mask)}return str};var binl2hex=function(binarray){var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef";var str="";for(var i=0;i<binarray.length*4;i++){str+=hex_tab.charAt((binarray[i>>2]>>((i%4)*8+4))&15)+hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&15)}return str};var binl2b64=function(binarray){var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var str="";var triplet,j;for(var i=0;i<binarray.length*4;i+=3){triplet=(((binarray[i>>2]>>8*(i%4))&255)<<16)|(((binarray[i+1>>2]>>8*((i+1)%4))&255)<<8)|((binarray[i+2>>2]>>8*((i+2)%4))&255);for(j=0;j<4;j++){if(i*8+j*6>binarray.length*32){str+=b64pad}else{str+=tab.charAt((triplet>>6*(3-j))&63)}}}return str};var md5_cmn=function(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)};var md5_ff=function(a,b,c,d,x,s,t){return md5_cmn((b&c)|((~b)&d),a,b,x,s,t)};var md5_gg=function(a,b,c,d,x,s,t){return md5_cmn((b&d)|(c&(~d)),a,b,x,s,t)};var md5_hh=function(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)};var md5_ii=function(a,b,c,d,x,s,t){return md5_cmn(c^(b|(~d)),a,b,x,s,t)};var core_md5=function(x,len){x[len>>5]|=128<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;var olda,oldb,oldc,oldd;for(var i=0;i<x.length;i+=16){olda=a;oldb=b;oldc=c;oldd=d;a=md5_ff(a,b,c,d,x[i+0],7,-680876936);d=md5_ff(d,a,b,c,x[i+1],12,-389564586);c=md5_ff(c,d,a,b,x[i+2],17,606105819);b=md5_ff(b,c,d,a,x[i+3],22,-1044525330);a=md5_ff(a,b,c,d,x[i+4],7,-176418897);d=md5_ff(d,a,b,c,x[i+5],12,1200080426);c=md5_ff(c,d,a,b,x[i+6],17,-1473231341);b=md5_ff(b,c,d,a,x[i+7],22,-45705983);a=md5_ff(a,b,c,d,x[i+8],7,1770035416);d=md5_ff(d,a,b,c,x[i+9],12,-1958414417);c=md5_ff(c,d,a,b,x[i+10],17,-42063);b=md5_ff(b,c,d,a,x[i+11],22,-1990404162);a=md5_ff(a,b,c,d,x[i+12],7,1804603682);d=md5_ff(d,a,b,c,x[i+13],12,-40341101);c=md5_ff(c,d,a,b,x[i+14],17,-1502002290);b=md5_ff(b,c,d,a,x[i+15],22,1236535329);a=md5_gg(a,b,c,d,x[i+1],5,-165796510);d=md5_gg(d,a,b,c,x[i+6],9,-1069501632);c=md5_gg(c,d,a,b,x[i+11],14,643717713);b=md5_gg(b,c,d,a,x[i+0],20,-373897302);a=md5_gg(a,b,c,d,x[i+5],5,-701558691);d=md5_gg(d,a,b,c,x[i+10],9,38016083);c=md5_gg(c,d,a,b,x[i+15],14,-660478335);b=md5_gg(b,c,d,a,x[i+4],20,-405537848);a=md5_gg(a,b,c,d,x[i+9],5,568446438);d=md5_gg(d,a,b,c,x[i+14],9,-1019803690);c=md5_gg(c,d,a,b,x[i+3],14,-187363961);b=md5_gg(b,c,d,a,x[i+8],20,1163531501);a=md5_gg(a,b,c,d,x[i+13],5,-1444681467);d=md5_gg(d,a,b,c,x[i+2],9,-51403784);c=md5_gg(c,d,a,b,x[i+7],14,1735328473);b=md5_gg(b,c,d,a,x[i+12],20,-1926607734);a=md5_hh(a,b,c,d,x[i+5],4,-378558);d=md5_hh(d,a,b,c,x[i+8],11,-2022574463);c=md5_hh(c,d,a,b,x[i+11],16,1839030562);b=md5_hh(b,c,d,a,x[i+14],23,-35309556);a=md5_hh(a,b,c,d,x[i+1],4,-1530992060);d=md5_hh(d,a,b,c,x[i+4],11,1272893353);c=md5_hh(c,d,a,b,x[i+7],16,-155497632);b=md5_hh(b,c,d,a,x[i+10],23,-1094730640);a=md5_hh(a,b,c,d,x[i+13],4,681279174);d=md5_hh(d,a,b,c,x[i+0],11,-358537222);c=md5_hh(c,d,a,b,x[i+3],16,-722521979);b=md5_hh(b,c,d,a,x[i+6],23,76029189);a=md5_hh(a,b,c,d,x[i+9],4,-640364487);d=md5_hh(d,a,b,c,x[i+12],11,-421815835);c=md5_hh(c,d,a,b,x[i+15],16,530742520);b=md5_hh(b,c,d,a,x[i+2],23,-995338651);a=md5_ii(a,b,c,d,x[i+0],6,-198630844);d=md5_ii(d,a,b,c,x[i+7],10,1126891415);c=md5_ii(c,d,a,b,x[i+14],15,-1416354905);b=md5_ii(b,c,d,a,x[i+5],21,-57434055);a=md5_ii(a,b,c,d,x[i+12],6,1700485571);d=md5_ii(d,a,b,c,x[i+3],10,-1894986606);c=md5_ii(c,d,a,b,x[i+10],15,-1051523);b=md5_ii(b,c,d,a,x[i+1],21,-2054922799);a=md5_ii(a,b,c,d,x[i+8],6,1873313359);d=md5_ii(d,a,b,c,x[i+15],10,-30611744);c=md5_ii(c,d,a,b,x[i+6],15,-1560198380);b=md5_ii(b,c,d,a,x[i+13],21,1309151649);a=md5_ii(a,b,c,d,x[i+4],6,-145523070);d=md5_ii(d,a,b,c,x[i+11],10,-1120210379);c=md5_ii(c,d,a,b,x[i+2],15,718787259);b=md5_ii(b,c,d,a,x[i+9],21,-343485551);a=safe_add(a,olda);b=safe_add(b,oldb);c=safe_add(c,oldc);d=safe_add(d,oldd)}return[a,b,c,d]};var core_hmac_md5=function(key,data){var bkey=str2binl(key);if(bkey.length>16){bkey=core_md5(bkey,key.length*chrsz)}var ipad=new Array(16),opad=new Array(16);for(var i=0;i<16;i++){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}var hash=core_md5(ipad.concat(str2binl(data)),512+data.length*chrsz);return core_md5(opad.concat(hash),512+128)};var obj={hexdigest:function(s){return binl2hex(core_md5(str2binl(s),s.length*chrsz))},b64digest:function(s){return binl2b64(core_md5(str2binl(s),s.length*chrsz))},hash:function(s){return binl2str(core_md5(str2binl(s),s.length*chrsz))},hmac_hexdigest:function(key,data){return binl2hex(core_hmac_md5(key,data))},hmac_b64digest:function(key,data){return binl2b64(core_hmac_md5(key,data))},hmac_hash:function(key,data){return binl2str(core_hmac_md5(key,data))},test:function(){return MD5.hexdigest("abc")==="900150983cd24fb0d6963f7d28e17f72"}};return obj})();if(!Function.prototype.bind){Function.prototype.bind=function(obj){var func=this;return function(){return func.apply(obj,arguments)}}}if(!Function.prototype.prependArg){Function.prototype.prependArg=function(arg){var func=this;return function(){var newargs=[arg];for(var i=0;i<arguments.length;i++){newargs.push(arguments[i])}return func.apply(this,newargs)}}}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(elt){var len=this.length;var from=Number(arguments[1])||0;from=(from<0)?Math.ceil(from):Math.floor(from);if(from<0){from+=len}for(;from<len;from++){if(from in this&&this[from]===elt){return from}}return -1}}(function(callback){var Strophe;function $build(name,attrs){return new Strophe.Builder(name,attrs)}function $msg(attrs){return new Strophe.Builder("message",attrs)}function $iq(attrs){return new Strophe.Builder("iq",attrs)}function $pres(attrs){return new Strophe.Builder("presence",attrs)}Strophe={VERSION:"1.0.1",NS:{HTTPBIND:"http://jabber.org/protocol/httpbind",BOSH:"urn:xmpp:xbosh",CLIENT:"jabber:client",AUTH:"jabber:iq:auth",ROSTER:"jabber:iq:roster",PROFILE:"jabber:iq:profile",DISCO_INFO:"http://jabber.org/protocol/disco#info",DISCO_ITEMS:"http://jabber.org/protocol/disco#items",MUC:"http://jabber.org/protocol/muc",SASL:"urn:ietf:params:xml:ns:xmpp-sasl",STREAM:"http://etherx.jabber.org/streams",BIND:"urn:ietf:params:xml:ns:xmpp-bind",SESSION:"urn:ietf:params:xml:ns:xmpp-session",VERSION:"jabber:iq:version",STANZAS:"urn:ietf:params:xml:ns:xmpp-stanzas"},addNamespace:function(name,value){Strophe.NS[name]=value},Status:{ERROR:0,CONNECTING:1,CONNFAIL:2,AUTHENTICATING:3,AUTHFAIL:4,CONNECTED:5,DISCONNECTED:6,DISCONNECTING:7,ATTACHED:8},LogLevel:{DEBUG:0,INFO:1,WARN:2,ERROR:3,FATAL:4},ElementType:{NORMAL:1,TEXT:3},TIMEOUT:1.1,SECONDARY_TIMEOUT:0.1,forEachChild:function(elem,elemName,func){var i,childNode;for(i=0;i<elem.childNodes.length;i++){childNode=elem.childNodes[i];if(childNode.nodeType==Strophe.ElementType.NORMAL&&(!elemName||this.isTagEqual(childNode,elemName))){func(childNode)}}},isTagEqual:function(el,name){return el.tagName.toLowerCase()==name.toLowerCase()},_xmlGenerator:null,_makeGenerator:function(){var doc;if(window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.appendChild(doc.createElement("strophe"))}else{doc=document.implementation.createDocument("jabber:client","strophe",null)}return doc},xmlElement:function(name){if(!name){return null}var node=null;if(!Strophe._xmlGenerator){Strophe._xmlGenerator=Strophe._makeGenerator()}node=Strophe._xmlGenerator.createElement(name);var a,i,k;for(a=1;a<arguments.length;a++){if(!arguments[a]){continue}if(typeof(arguments[a])=="string"||typeof(arguments[a])=="number"){node.appendChild(Strophe.xmlTextNode(arguments[a]))}else{if(typeof(arguments[a])=="object"&&typeof(arguments[a].sort)=="function"){for(i=0;i<arguments[a].length;i++){if(typeof(arguments[a][i])=="object"&&typeof(arguments[a][i].sort)=="function"){node.setAttribute(arguments[a][i][0],arguments[a][i][1])}}}else{if(typeof(arguments[a])=="object"){for(k in arguments[a]){if(arguments[a].hasOwnProperty(k)){node.setAttribute(k,arguments[a][k])}}}}}}return node},xmlescape:function(text){text=text.replace(/\&/g,"&amp;");text=text.replace(/</g,"&lt;");text=text.replace(/>/g,"&gt;");return text},xmlTextNode:function(text){text=Strophe.xmlescape(text);if(!Strophe._xmlGenerator){Strophe._xmlGenerator=Strophe._makeGenerator()}return Strophe._xmlGenerator.createTextNode(text)},getText:function(elem){if(!elem){return null}var str="";if(elem.childNodes.length===0&&elem.nodeType==Strophe.ElementType.TEXT){str+=elem.nodeValue}for(var i=0;i<elem.childNodes.length;i++){if(elem.childNodes[i].nodeType==Strophe.ElementType.TEXT){str+=elem.childNodes[i].nodeValue}}return str},copyElement:function(elem){var i,el;if(elem.nodeType==Strophe.ElementType.NORMAL){el=Strophe.xmlElement(elem.tagName);for(i=0;i<elem.attributes.length;i++){el.setAttribute(elem.attributes[i].nodeName.toLowerCase(),elem.attributes[i].value)}for(i=0;i<elem.childNodes.length;i++){el.appendChild(Strophe.copyElement(elem.childNodes[i]))}}else{if(elem.nodeType==Strophe.ElementType.TEXT){el=Strophe.xmlTextNode(elem.nodeValue)}}return el},escapeNode:function(node){return node.replace(/^\s+|\s+$/g,"").replace(/\\/g,"\\5c").replace(/ /g,"\\20").replace(/\"/g,"\\22").replace(/\&/g,"\\26").replace(/\'/g,"\\27").replace(/\//g,"\\2f").replace(/:/g,"\\3a").replace(/</g,"\\3c").replace(/>/g,"\\3e").replace(/@/g,"\\40")},unescapeNode:function(node){return node.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\")},getNodeFromJid:function(jid){if(jid.indexOf("@")<0){return null}return jid.split("@")[0]},getDomainFromJid:function(jid){var bare=Strophe.getBareJidFromJid(jid);if(bare.indexOf("@")<0){return bare}else{var parts=bare.split("@");parts.splice(0,1);return parts.join("@")}},getResourceFromJid:function(jid){var s=jid.split("/");if(s.length<2){return null}s.splice(0,1);return s.join("/")},getBareJidFromJid:function(jid){return jid.split("/")[0]},log:function(level,msg){return},debug:function(msg){this.log(this.LogLevel.DEBUG,msg)},info:function(msg){this.log(this.LogLevel.INFO,msg)},warn:function(msg){this.log(this.LogLevel.WARN,msg)},error:function(msg){this.log(this.LogLevel.ERROR,msg)},fatal:function(msg){this.log(this.LogLevel.FATAL,msg)},serialize:function(elem){var result;if(!elem){return null}if(typeof(elem.tree)==="function"){elem=elem.tree()}var nodeName=elem.nodeName;var i,child;if(elem.getAttribute("_realname")){nodeName=elem.getAttribute("_realname")}result="<"+nodeName;for(i=0;i<elem.attributes.length;i++){if(elem.attributes[i].nodeName!="_realname"){result+=" "+elem.attributes[i].nodeName.toLowerCase()+"='"+elem.attributes[i].value.replace("&","&amp;").replace("'","&apos;").replace("<","&lt;")+"'"}}if(elem.childNodes.length>0){result+=">";for(i=0;i<elem.childNodes.length;i++){child=elem.childNodes[i];if(child.nodeType==Strophe.ElementType.NORMAL){result+=Strophe.serialize(child)}else{if(child.nodeType==Strophe.ElementType.TEXT){result+=child.nodeValue}}}result+="</"+nodeName+">"}else{result+="/>"}return result},_requestId:0,_connectionPlugins:{},addConnectionPlugin:function(name,ptype){Strophe._connectionPlugins[name]=ptype}};Strophe.Builder=function(name,attrs){if(name=="presence"||name=="message"||name=="iq"){if(attrs&&!attrs.xmlns){attrs.xmlns=Strophe.NS.CLIENT}else{if(!attrs){attrs={xmlns:Strophe.NS.CLIENT}}}}this.nodeTree=Strophe.xmlElement(name,attrs);this.node=this.nodeTree};Strophe.Builder.prototype={tree:function(){return this.nodeTree},toString:function(){return Strophe.serialize(this.nodeTree)},up:function(){this.node=this.node.parentNode;return this},attrs:function(moreattrs){for(var k in moreattrs){if(moreattrs.hasOwnProperty(k)){this.node.setAttribute(k,moreattrs[k])}}return this},c:function(name,attrs){var child=Strophe.xmlElement(name,attrs);this.node.appendChild(child);this.node=child;return this},cnode:function(elem){this.node.appendChild(elem);this.node=elem;return this},t:function(text){var child=Strophe.xmlTextNode(text);this.node.appendChild(child);return this}};Strophe.Handler=function(handler,ns,name,type,id,from,options){this.handler=handler;this.ns=ns;this.name=name;this.type=type;this.id=id;this.options=options||{matchbare:false};if(!this.options.matchBare){this.options.matchBare=false}if(this.options.matchBare){this.from=Strophe.getBareJidFromJid(from)}else{this.from=from}this.user=true};Strophe.Handler.prototype={isMatch:function(elem){var nsMatch;var from=null;if(this.options.matchBare){from=Strophe.getBareJidFromJid(elem.getAttribute("from"))}else{from=elem.getAttribute("from")}nsMatch=false;if(!this.ns){nsMatch=true}else{var self=this;Strophe.forEachChild(elem,null,function(elem){if(elem.getAttribute("xmlns")==self.ns){nsMatch=true}});nsMatch=nsMatch||elem.getAttribute("xmlns")==this.ns}if(nsMatch&&(!this.name||Strophe.isTagEqual(elem,this.name))&&(!this.type||elem.getAttribute("type")===this.type)&&(!this.id||elem.getAttribute("id")===this.id)&&(!this.from||from===this.from)){return true}return false},run:function(elem){var result=null;try{result=this.handler(elem)}catch(e){if(e.sourceURL){Strophe.fatal("error: "+this.handler+" "+e.sourceURL+":"+e.line+" - "+e.name+": "+e.message)}else{if(e.fileName){if(typeof(console)!="undefined"){console.trace();console.error(this.handler," - error - ",e,e.message)}Strophe.fatal("error: "+this.handler+" "+e.fileName+":"+e.lineNumber+" - "+e.name+": "+e.message)}else{Strophe.fatal("error: "+this.handler)}}throw e}return result},toString:function(){return"{Handler: "+this.handler+"("+this.name+","+this.id+","+this.ns+")}"}};Strophe.TimedHandler=function(period,handler){this.period=period;this.handler=handler;this.lastCalled=new Date().getTime();this.user=true};Strophe.TimedHandler.prototype={run:function(){this.lastCalled=new Date().getTime();return this.handler()},reset:function(){this.lastCalled=new Date().getTime()},toString:function(){return"{TimedHandler: "+this.handler+"("+this.period+")}"}};Strophe.Request=function(elem,func,rid,sends){this.id=++Strophe._requestId;this.xmlData=elem;this.data=Strophe.serialize(elem);this.origFunc=func;this.func=func;this.rid=rid;this.date=NaN;this.sends=sends||0;this.abort=false;this.dead=null;this.age=function(){if(!this.date){return 0}var now=new Date();return(now-this.date)/1000};this.timeDead=function(){if(!this.dead){return 0}var now=new Date();return(now-this.dead)/1000};this.xhr=this._newXHR()};Strophe.Request.prototype={getResponse:function(){var node=null;if(this.xhr.responseXML&&this.xhr.responseXML.documentElement){node=this.xhr.responseXML.documentElement;if(node.tagName=="parsererror"){Strophe.error("invalid response received");Strophe.error("responseText: "+this.xhr.responseText);Strophe.error("responseXML: "+Strophe.serialize(this.xhr.responseXML));throw"parsererror"}}else{if(this.xhr.responseText){Strophe.error("invalid response received");Strophe.error("responseText: "+this.xhr.responseText);Strophe.error("responseXML: "+Strophe.serialize(this.xhr.responseXML))}}return node},_newXHR:function(){var xhr=null;if(window.XMLHttpRequest){xhr=new XMLHttpRequest();if(xhr.overrideMimeType){xhr.overrideMimeType("text/xml")}}else{if(window.ActiveXObject){xhr=new ActiveXObject("Microsoft.XMLHTTP")}}xhr.onreadystatechange=this.func.prependArg(this);return xhr}};Strophe.Connection=function(service){this.service=service;this.jid="";this.rid=Math.floor(Math.random()*4294967295);this.sid=null;this.streamId=null;this.do_session=false;this.do_bind=false;this.timedHandlers=[];this.handlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[];this._idleTimeout=null;this._disconnectTimeout=null;this.authenticated=false;this.disconnecting=false;this.connected=false;this.errors=0;this.paused=false;this.hold=1;this.wait=60;this.window=5;this._data=[];this._requests=[];this._uniqueId=Math.round(Math.random()*10000);this._sasl_success_handler=null;this._sasl_failure_handler=null;this._sasl_challenge_handler=null;this._idleTimeout=setTimeout(this._onIdle.bind(this),100);for(var k in Strophe._connectionPlugins){if(Strophe._connectionPlugins.hasOwnProperty(k)){var ptype=Strophe._connectionPlugins[k];var F=function(){};F.prototype=ptype;this[k]=new F();this[k].init(this)}}};Strophe.Connection.prototype={reset:function(){this.rid=Math.floor(Math.random()*4294967295);this.sid=null;this.streamId=null;this.do_session=false;this.do_bind=false;this.timedHandlers=[];this.handlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[];this.authenticated=false;this.disconnecting=false;this.connected=false;this.errors=0;this._requests=[];this._uniqueId=Math.round(Math.random()*10000)},pause:function(){this.paused=true},resume:function(){this.paused=false},getUniqueId:function(suffix){if(typeof(suffix)=="string"||typeof(suffix)=="number"){return ++this._uniqueId+":"+suffix}else{return ++this._uniqueId+""}},connect:function(jid,pass,callback,wait,hold){this.jid=jid;this.pass=pass;this.connect_callback=callback;this.disconnecting=false;this.connected=false;this.authenticated=false;this.errors=0;this.wait=wait||this.wait;this.hold=hold||this.hold;this.domain=Strophe.getDomainFromJid(this.jid);var body=this._buildBody().attrs({to:this.domain,"xml:lang":"en",wait:this.wait,hold:this.hold,content:"text/xml; charset=utf-8",ver:"1.6","xmpp:version":"1.0","xmlns:xmpp":Strophe.NS.BOSH});this._changeConnectStatus(Strophe.Status.CONNECTING,null);this._requests.push(new Strophe.Request(body.tree(),this._onRequestStateChange.bind(this).prependArg(this._connect_cb.bind(this)),body.tree().getAttribute("rid")));this._throttledRequestHandler()},attach:function(jid,sid,rid,callback,wait,hold,wind){this.jid=jid;this.sid=sid;this.rid=rid;this.connect_callback=callback;this.domain=Strophe.getDomainFromJid(this.jid);this.authenticated=true;this.connected=true;this.wait=wait||this.wait;this.hold=hold||this.hold;this.window=wind||this.window;this._changeConnectStatus(Strophe.Status.ATTACHED,null)},xmlInput:function(elem){return},xmlOutput:function(elem){return},rawInput:function(data){return},rawOutput:function(data){return},send:function(elem){if(elem===null){return}if(typeof(elem.sort)==="function"){for(var i=0;i<elem.length;i++){this._queueData(elem[i])}}else{if(typeof(elem.tree)==="function"){this._queueData(elem.tree())}else{this._queueData(elem)}}this._throttledRequestHandler();clearTimeout(this._idleTimeout);this._idleTimeout=setTimeout(this._onIdle.bind(this),100)},flush:function(){clearTimeout(this._idleTimeout);this._onIdle()},sendIQ:function(elem,callback,errback,timeout){var timeoutHandler=null;var that=this;if(typeof(elem.tree)==="function"){elem=elem.tree()}var id=elem.getAttribute("id");if(!id){id=this.getUniqueId("sendIQ");elem.setAttribute("id",id)}var handler=this.addHandler(function(stanza){if(timeoutHandler){that.deleteTimedHandler(timeoutHandler)}var iqtype=stanza.getAttribute("type");if(iqtype==="result"){if(callback){callback(stanza)}}else{if(iqtype==="error"){if(errback){errback(stanza)}}else{throw {name:"StropheError",message:"Got bad IQ type of "+iqtype}}}},null,"iq",null,id);if(timeout){timeoutHandler=this.addTimedHandler(timeout,function(){that.deleteHandler(handler);if(errback){errback(null)}return false})}this.send(elem);return id},_queueData:function(element){if(element===null||!element.tagName||!element.childNodes){throw {name:"StropheError",message:"Cannot queue non-DOMElement."}}this._data.push(element)},_sendRestart:function(){this._data.push("restart");this._throttledRequestHandler();clearTimeout(this._idleTimeout);this._idleTimeout=setTimeout(this._onIdle.bind(this),100)},addTimedHandler:function(period,handler){var thand=new Strophe.TimedHandler(period,handler);this.addTimeds.push(thand);return thand},deleteTimedHandler:function(handRef){this.removeTimeds.push(handRef)},addHandler:function(handler,ns,name,type,id,from,options){var hand=new Strophe.Handler(handler,ns,name,type,id,from,options);this.addHandlers.push(hand);return hand},deleteHandler:function(handRef){this.removeHandlers.push(handRef)},disconnect:function(reason){this._changeConnectStatus(Strophe.Status.DISCONNECTING,reason);Strophe.info("Disconnect was called because: "+reason);if(this.connected){this._disconnectTimeout=this._addSysTimedHandler(3000,this._onDisconnectTimeout.bind(this));this._sendTerminate()}},_changeConnectStatus:function(status,condition){for(var k in Strophe._connectionPlugins){if(Strophe._connectionPlugins.hasOwnProperty(k)){var plugin=this[k];if(plugin.statusChanged){try{plugin.statusChanged(status,condition)}catch(err){Strophe.error(""+k+" plugin caused an exception changing status: "+err)}}}}if(this.connect_callback){try{this.connect_callback(status,condition)}catch(e){Strophe.error("User connection callback caused an exception: "+e)}}},_buildBody:function(){var bodyWrap=$build("body",{rid:this.rid++,xmlns:Strophe.NS.HTTPBIND});if(this.sid!==null){bodyWrap.attrs({sid:this.sid})}return bodyWrap},_removeRequest:function(req){Strophe.debug("removing request");var i;for(i=this._requests.length-1;i>=0;i--){if(req==this._requests[i]){this._requests.splice(i,1)}}req.xhr.onreadystatechange=function(){};this._throttledRequestHandler()},_restartRequest:function(i){var req=this._requests[i];if(req.dead===null){req.dead=new Date()}this._processRequest(i)},_processRequest:function(i){var req=this._requests[i];var reqStatus=-1;try{if(req.xhr.readyState==4){reqStatus=req.xhr.status}}catch(e){Strophe.error("caught an error in _requests["+i+"], reqStatus: "+reqStatus)}if(typeof(reqStatus)=="undefined"){reqStatus=-1}var time_elapsed=req.age();var primaryTimeout=(!isNaN(time_elapsed)&&time_elapsed>Math.floor(Strophe.TIMEOUT*this.wait));var secondaryTimeout=(req.dead!==null&&req.timeDead()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait));var requestCompletedWithServerError=(req.xhr.readyState==4&&(reqStatus<1||reqStatus>=500));if(primaryTimeout||secondaryTimeout||requestCompletedWithServerError){if(secondaryTimeout){Strophe.error("Request "+this._requests[i].id+" timed out (secondary), restarting")}req.abort=true;req.xhr.abort();req.xhr.onreadystatechange=function(){};this._requests[i]=new Strophe.Request(req.xmlData,req.origFunc,req.rid,req.sends);req=this._requests[i]}if(req.xhr.readyState===0){Strophe.debug("request id "+req.id+"."+req.sends+" posting");req.date=new Date();try{req.xhr.open("POST",this.service,true)}catch(e2){Strophe.error("XHR open failed.");if(!this.connected){this._changeConnectStatus(Strophe.Status.CONNFAIL,"bad-service")}this.disconnect();return}var sendFunc=function(){req.xhr.send(req.data)};if(req.sends>1){var backoff=Math.pow(req.sends,3)*1000;setTimeout(sendFunc,backoff)}else{sendFunc()}req.sends++;this.xmlOutput(req.xmlData);this.rawOutput(req.data)}else{Strophe.debug("_processRequest: "+(i===0?"first":"second")+" request has readyState of "+req.xhr.readyState)}},_throttledRequestHandler:function(){if(!this._requests){Strophe.debug("_throttledRequestHandler called with undefined requests")}else{Strophe.debug("_throttledRequestHandler called with "+this._requests.length+" requests")}if(!this._requests||this._requests.length===0){return}if(this._requests.length>0){this._processRequest(0)}if(this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)<this.window-1){this._processRequest(1)}},_onRequestStateChange:function(func,req){Strophe.debug("request id "+req.id+"."+req.sends+" state changed to "+req.xhr.readyState);if(req.abort){req.abort=false;return}var reqStatus;if(req.xhr.readyState==4){reqStatus=0;try{reqStatus=req.xhr.status}catch(e){}if(typeof(reqStatus)=="undefined"){reqStatus=0}if(this.disconnecting){if(reqStatus>=400){this._hitError(reqStatus);return}}var reqIs0=(this._requests[0]==req);var reqIs1=(this._requests[1]==req);if((reqStatus>0&&reqStatus<500)||req.sends>5){this._removeRequest(req);Strophe.debug("request id "+req.id+" should now be removed")}if(reqStatus==200){if(reqIs1||(reqIs0&&this._requests.length>0&&this._requests[0].age()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait))){this._restartRequest(0)}Strophe.debug("request id "+req.id+"."+req.sends+" got 200");func(req);this.errors=0}else{Strophe.error("request id "+req.id+"."+req.sends+" error "+reqStatus+" happened");if(reqStatus===0||(reqStatus>=400&&reqStatus<600)||reqStatus>=12000){this._hitError(reqStatus);if(reqStatus>=400&&reqStatus<500){this._changeConnectStatus(Strophe.Status.DISCONNECTING,null);this._doDisconnect()}}}if(!((reqStatus>0&&reqStatus<10000)||req.sends>5)){this._throttledRequestHandler()}}},_hitError:function(reqStatus){this.errors++;Strophe.warn("request errored, status: "+reqStatus+", number of errors: "+this.errors);if(this.errors>4){this._onDisconnectTimeout()}},_doDisconnect:function(){Strophe.info("_doDisconnect was called");this.authenticated=false;this.disconnecting=false;this.sid=null;this.streamId=null;this.rid=Math.floor(Math.random()*4294967295);if(this.connected){this._changeConnectStatus(Strophe.Status.DISCONNECTED,null);this.connected=false}this.handlers=[];this.timedHandlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[]},_dataRecv:function(req){try{var elem=req.getResponse()}catch(e){if(e!="parsererror"){throw e}this.disconnect("strophe-parsererror")}if(elem===null){return}this.xmlInput(elem);this.rawInput(Strophe.serialize(elem));var i,hand;while(this.removeHandlers.length>0){hand=this.removeHandlers.pop();i=this.handlers.indexOf(hand);if(i>=0){this.handlers.splice(i,1)}}while(this.addHandlers.length>0){this.handlers.push(this.addHandlers.pop())}if(this.disconnecting&&this._requests.length===0){this.deleteTimedHandler(this._disconnectTimeout);this._disconnectTimeout=null;this._doDisconnect();return}var typ=elem.getAttribute("type");var cond,conflict;if(typ!==null&&typ=="terminate"){cond=elem.getAttribute("condition");conflict=elem.getElementsByTagName("conflict");if(cond!==null){if(cond=="remote-stream-error"&&conflict.length>0){cond="conflict"}this._changeConnectStatus(Strophe.Status.CONNFAIL,cond)}else{this._changeConnectStatus(Strophe.Status.CONNFAIL,"unknown")}this.disconnect();return}var self=this;Strophe.forEachChild(elem,null,function(child){var i,newList;newList=self.handlers;self.handlers=[];for(i=0;i<newList.length;i++){var hand=newList[i];if(hand.isMatch(child)&&(self.authenticated||!hand.user)){if(hand.run(child)){self.handlers.push(hand)}}else{self.handlers.push(hand)}}})},_sendTerminate:function(){Strophe.info("_sendTerminate was called");var body=this._buildBody().attrs({type:"terminate"});if(this.authenticated){body.c("presence",{xmlns:Strophe.NS.CLIENT,type:"unavailable"})}this.disconnecting=true;var req=new Strophe.Request(body.tree(),this._onRequestStateChange.bind(this).prependArg(this._dataRecv.bind(this)),body.tree().getAttribute("rid"));this._requests.push(req);this._throttledRequestHandler()},_connect_cb:function(req){Strophe.info("_connect_cb was called");this.connected=true;var bodyWrap=req.getResponse();if(!bodyWrap){return}this.xmlInput(bodyWrap);this.rawInput(Strophe.serialize(bodyWrap));var typ=bodyWrap.getAttribute("type");var cond,conflict;if(typ!==null&&typ=="terminate"){cond=bodyWrap.getAttribute("condition");conflict=bodyWrap.getElementsByTagName("conflict");if(cond!==null){if(cond=="remote-stream-error"&&conflict.length>0){cond="conflict"}this._changeConnectStatus(Strophe.Status.CONNFAIL,cond)}else{this._changeConnectStatus(Strophe.Status.CONNFAIL,"unknown")}return}if(!this.sid){this.sid=bodyWrap.getAttribute("sid")}if(!this.stream_id){this.stream_id=bodyWrap.getAttribute("authid")}var wind=bodyWrap.getAttribute("requests");if(wind){this.window=parseInt(wind,10)}var hold=bodyWrap.getAttribute("hold");if(hold){this.hold=parseInt(hold,10)}var wait=bodyWrap.getAttribute("wait");if(wait){this.wait=parseInt(wait,10)}var do_sasl_plain=false;var do_sasl_digest_md5=false;var do_sasl_anonymous=false;var mechanisms=bodyWrap.getElementsByTagName("mechanism");var i,mech,auth_str,hashed_auth_str;if(mechanisms.length>0){for(i=0;i<mechanisms.length;i++){mech=Strophe.getText(mechanisms[i]);if(mech=="DIGEST-MD5"){do_sasl_digest_md5=true}else{if(mech=="PLAIN"){do_sasl_plain=true}else{if(mech=="ANONYMOUS"){do_sasl_anonymous=true}}}}}else{var body=this._buildBody();this._requests.push(new Strophe.Request(body.tree(),this._onRequestStateChange.bind(this).prependArg(this._connect_cb.bind(this)),body.tree().getAttribute("rid")));this._throttledRequestHandler();return}if(Strophe.getNodeFromJid(this.jid)===null&&do_sasl_anonymous){this._changeConnectStatus(Strophe.Status.AUTHENTICATING,null);this._sasl_success_handler=this._addSysHandler(this._sasl_success_cb.bind(this),null,"success",null,null);this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null);this.send($build("auth",{xmlns:Strophe.NS.SASL,mechanism:"ANONYMOUS"}).tree())}else{if(Strophe.getNodeFromJid(this.jid)===null){this._changeConnectStatus(Strophe.Status.CONNFAIL,"x-strophe-bad-non-anon-jid");this.disconnect()}else{if(do_sasl_digest_md5){this._changeConnectStatus(Strophe.Status.AUTHENTICATING,null);this._sasl_challenge_handler=this._addSysHandler(this._sasl_challenge1_cb.bind(this),null,"challenge",null,null);this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null);this.send($build("auth",{xmlns:Strophe.NS.SASL,mechanism:"DIGEST-MD5"}).tree())}else{if(do_sasl_plain){auth_str=Strophe.getBareJidFromJid(this.jid);auth_str=auth_str+"\u0000";auth_str=auth_str+Strophe.getNodeFromJid(this.jid);auth_str=auth_str+"\u0000";auth_str=auth_str+this.pass;this._changeConnectStatus(Strophe.Status.AUTHENTICATING,null);this._sasl_success_handler=this._addSysHandler(this._sasl_success_cb.bind(this),null,"success",null,null);this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null);hashed_auth_str=Base64.encode(auth_str);this.send($build("auth",{xmlns:Strophe.NS.SASL,mechanism:"PLAIN"}).t(hashed_auth_str).tree())}else{this._changeConnectStatus(Strophe.Status.AUTHENTICATING,null);this._addSysHandler(this._auth1_cb.bind(this),null,null,null,"_auth_1");this.send($iq({type:"get",to:this.domain,id:"_auth_1"}).c("query",{xmlns:Strophe.NS.AUTH}).c("username",{}).t(Strophe.getNodeFromJid(this.jid)).tree())}}}}},_sasl_challenge1_cb:function(elem){var attribMatch=/([a-z]+)=("[^"]+"|[^,"]+)(?:,|$)/;var challenge=Base64.decode(Strophe.getText(elem));var cnonce=MD5.hexdigest(Math.random()*1234567890);var realm="";var host=null;var nonce="";var qop="";var matches;this.deleteHandler(this._sasl_failure_handler);while(challenge.match(attribMatch)){matches=challenge.match(attribMatch);challenge=challenge.replace(matches[0],"");matches[2]=matches[2].replace(/^"(.+)"$/,"$1");switch(matches[1]){case"realm":realm=matches[2];break;case"nonce":nonce=matches[2];break;case"qop":qop=matches[2];break;case"host":host=matches[2];break}}var digest_uri="xmpp/"+this.domain;if(host!==null){digest_uri=digest_uri+"/"+host}var A1=MD5.hash(Strophe.getNodeFromJid(this.jid)+":"+realm+":"+this.pass)+":"+nonce+":"+cnonce;var A2="AUTHENTICATE:"+digest_uri;var responseText="";responseText+="username="+this._quote(Strophe.getNodeFromJid(this.jid))+",";responseText+="realm="+this._quote(realm)+",";responseText+="nonce="+this._quote(nonce)+",";responseText+="cnonce="+this._quote(cnonce)+",";responseText+='nc="00000001",';responseText+='qop="auth",';responseText+="digest-uri="+this._quote(digest_uri)+",";responseText+="response="+this._quote(MD5.hexdigest(MD5.hexdigest(A1)+":"+nonce+":00000001:"+cnonce+":auth:"+MD5.hexdigest(A2)))+",";responseText+='charset="utf-8"';this._sasl_challenge_handler=this._addSysHandler(this._sasl_challenge2_cb.bind(this),null,"challenge",null,null);this._sasl_success_handler=this._addSysHandler(this._sasl_success_cb.bind(this),null,"success",null,null);this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null);this.send($build("response",{xmlns:Strophe.NS.SASL}).t(Base64.encode(responseText)).tree());return false},_quote:function(str){return'"'+str.replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"'},_sasl_challenge2_cb:function(elem){this.deleteHandler(this._sasl_success_handler);this.deleteHandler(this._sasl_failure_handler);this._sasl_success_handler=this._addSysHandler(this._sasl_success_cb.bind(this),null,"success",null,null);this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null);this.send($build("response",{xmlns:Strophe.NS.SASL}).tree());return false},_auth1_cb:function(elem){var iq=$iq({type:"set",id:"_auth_2"}).c("query",{xmlns:Strophe.NS.AUTH}).c("username",{}).t(Strophe.getNodeFromJid(this.jid)).up().c("password").t(this.pass);if(!Strophe.getResourceFromJid(this.jid)){this.jid=Strophe.getBareJidFromJid(this.jid)+"/strophe"}iq.up().c("resource",{}).t(Strophe.getResourceFromJid(this.jid));this._addSysHandler(this._auth2_cb.bind(this),null,null,null,"_auth_2");this.send(iq.tree());return false},_sasl_success_cb:function(elem){Strophe.info("SASL authentication succeeded.");this.deleteHandler(this._sasl_failure_handler);this._sasl_failure_handler=null;if(this._sasl_challenge_handler){this.deleteHandler(this._sasl_challenge_handler);this._sasl_challenge_handler=null}this._addSysHandler(this._sasl_auth1_cb.bind(this),null,"stream:features",null,null);this._sendRestart();return false},_sasl_auth1_cb:function(elem){var i,child;for(i=0;i<elem.childNodes.length;i++){child=elem.childNodes[i];if(child.nodeName=="bind"){this.do_bind=true}if(child.nodeName=="session"){this.do_session=true}}if(!this.do_bind){this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}else{this._addSysHandler(this._sasl_bind_cb.bind(this),null,null,null,"_bind_auth_2");var resource=Strophe.getResourceFromJid(this.jid);if(resource){this.send($iq({type:"set",id:"_bind_auth_2"}).c("bind",{xmlns:Strophe.NS.BIND}).c("resource",{}).t(resource).tree())}else{this.send($iq({type:"set",id:"_bind_auth_2"}).c("bind",{xmlns:Strophe.NS.BIND}).tree())}}return false},_sasl_bind_cb:function(elem){if(elem.getAttribute("type")=="error"){Strophe.info("SASL binding failed.");this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}var bind=elem.getElementsByTagName("bind");var jidNode;if(bind.length>0){jidNode=bind[0].getElementsByTagName("jid");if(jidNode.length>0){this.jid=Strophe.getText(jidNode[0]);if(this.do_session){this._addSysHandler(this._sasl_session_cb.bind(this),null,null,null,"_session_auth_2");this.send($iq({type:"set",id:"_session_auth_2"}).c("session",{xmlns:Strophe.NS.SESSION}).tree())}else{this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}}}else{Strophe.info("SASL binding failed.");this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}},_sasl_session_cb:function(elem){if(elem.getAttribute("type")=="result"){this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}else{if(elem.getAttribute("type")=="error"){Strophe.info("Session creation failed.");this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}}return false},_sasl_failure_cb:function(elem){if(this._sasl_success_handler){this.deleteHandler(this._sasl_success_handler);this._sasl_success_handler=null}if(this._sasl_challenge_handler){this.deleteHandler(this._sasl_challenge_handler);this._sasl_challenge_handler=null}this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false},_auth2_cb:function(elem){if(elem.getAttribute("type")=="result"){this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}else{if(elem.getAttribute("type")=="error"){this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);this.disconnect()}}return false},_addSysTimedHandler:function(period,handler){var thand=new Strophe.TimedHandler(period,handler);thand.user=false;this.addTimeds.push(thand);return thand},_addSysHandler:function(handler,ns,name,type,id){var hand=new Strophe.Handler(handler,ns,name,type,id);hand.user=false;this.addHandlers.push(hand);return hand},_onDisconnectTimeout:function(){Strophe.info("_onDisconnectTimeout was called");var req;while(this._requests.length>0){req=this._requests.pop();req.abort=true;req.xhr.abort();req.xhr.onreadystatechange=function(){}}this._doDisconnect();return false},_onIdle:function(){var i,thand,since,newList;while(this.removeTimeds.length>0){thand=this.removeTimeds.pop();i=this.timedHandlers.indexOf(thand);if(i>=0){this.timedHandlers.splice(i,1)}}while(this.addTimeds.length>0){this.timedHandlers.push(this.addTimeds.pop())}var now=new Date().getTime();newList=[];for(i=0;i<this.timedHandlers.length;i++){thand=this.timedHandlers[i];if(this.authenticated||!thand.user){since=thand.lastCalled+thand.period;if(since-now<=0){if(thand.run()){newList.push(thand)}}else{newList.push(thand)}}}this.timedHandlers=newList;var body,time_elapsed;if(this.authenticated&&this._requests.length===0&&this._data.length===0&&!this.disconnecting){Strophe.info("no requests during idle cycle, sending blank request");this._data.push(null)}if(this._requests.length<2&&this._data.length>0&&!this.paused){body=this._buildBody();for(i=0;i<this._data.length;i++){if(this._data[i]!==null){if(this._data[i]==="restart"){body.attrs({to:this.domain,"xml:lang":"en","xmpp:restart":"true","xmlns:xmpp":Strophe.NS.BOSH})}else{body.cnode(this._data[i]).up()}}}delete this._data;this._data=[];this._requests.push(new Strophe.Request(body.tree(),this._onRequestStateChange.bind(this).prependArg(this._dataRecv.bind(this)),body.tree().getAttribute("rid")));this._processRequest(this._requests.length-1)}if(this._requests.length>0){time_elapsed=this._requests[0].age();if(this._requests[0].dead!==null){if(this._requests[0].timeDead()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait)){this._throttledRequestHandler()}}if(time_elapsed>Math.floor(Strophe.TIMEOUT*this.wait)){Strophe.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(Strophe.TIMEOUT*this.wait)+" seconds since last activity");this._throttledRequestHandler()}}clearTimeout(this._idleTimeout);this._idleTimeout=setTimeout(this._onIdle.bind(this),100)}};if(callback){callback(Strophe,$build,$msg,$iq,$pres)}})(function(){window.Strophe=arguments[0];window.$build=arguments[1];window.$msg=arguments[2];window.$iq=arguments[3];window.$pres=arguments[4]});/**
 * Beechat
 * 
 * @package beechat
 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
 * @author Beechannels <contact@beechannels.com>
 * @copyright Beechannels 2007-2010
 * @link http://beechannels.com/
 */ 

/** Globals
 *
 */
g_beechat_user = null;
g_beechat_roster_items = null;

/** Class: BeeChat
 *  An object container for all BeeChat mod functions
 *
 */
BeeChat = {
    BOSH_SERVICE: '/http-bind/',
    DOMAIN: 'jabber.beechannels.com',
    RESOURCE: 'beebac',
    INACTIVITY_PERIOD_LENGTH: 60,

    NS: {
	CHAT_STATES: 'http://jabber.org/protocol/chatstates'
    },

    Message: {
	Types: {
	    NORMAL: 'normal',
	    CHAT: 'chat',
	    GROUPCHAT: 'groupchat',
	    HEADLINE: 'headline',
	    ERROR: 'error'
	},

	ChatStates: {
	    COMPOSING: 'composing',
	    PAUSED: 'paused',
	    ACTIVE: 'active',
	    INACTIVE: 'inactive',
	    GONE: 'gone'
	}
    },

    IQ: {
	Types: {
	    GET: 'get',
	    RESULT: 'result',
	    SET: 'set',
	    ERROR: 'error'
	}
    },

    Presence: {
	Types: {
	    UNAVAILABLE: 'unavailable',
	    SUBSCRIBE: 'subscribe',
	    SUBSCRIBED: 'subscribed',
	    UNSUBSCRIBE: 'unsubscribe',
	    UNSUBSCRIBED: 'unsubscribed',
	    PROBE: 'probe',
	    ERROR: 'error'
	},

	ChildElements: {
	    SHOW: 'show',
	    STATUS: 'status',
	    PRIORITY: 'priority'
	},

	ShowElements: {
	    CHAT: 'chat',
	    DND: 'dnd',
	    AWAY: 'away',
	    XA: 'xa'
	}
    },

    Roster: {
	DEFAULT_GROUP: 'Contacts'
    },


    Events: {
	Identifiers: {
	    UPDATE_CONNECTION_STATE: 0,
	    UPDATE_ROSTER: 1,
	    RECV_PRESENCE: 2,
	    RECV_CHAT_MESSAGE: 3
	},
	Messages: {
	    ConnectionStates: {
		CONNECTING: "Connexion...",
		AUTHENTICATING: "Authentification...",
		FAILED: "Échec",
		DISCONNECTING: "Déconnexion...",
		OFFLINE: "Hors ligne",
		ONLINE: "En ligne"
	    }
	}
    }
};


/** Class: BeeChat.Core
 *  An object container for all BeeChat Core functions
 *
 */
BeeChat.Core = {
    ReferenceTables: {
	AvailabilityRates: {
	    AVAILABLE: 0,
	    ONLINE: 0,
	    CHAT: 0,
	    DND: 1,
	    AWAY: 2,
	    XA: 3,
	    UNAVAILABLE: 10,
	    OFFLINE: 10
	}
    }
};


/** Class: BeeChat.Core.User
 *  Create a BeeChat.Core.User object
 *
 *  Parameters:
 *    (String) jid - The user's jabber id
 *
 *  Returns:
 *    A new BeeChat.Core.User.
 */
BeeChat.Core.User = function(jid)
{
    if (!(this instanceof arguments.callee))
	return new BeeChat.Core.User(jid);

    /** Private members
     *
     */
    var _connection = null;
    var _attached = false;
    var _initialized = false;
    var _jid = null;
    var _roster = null;
    var _msgTemp = [];
    var _funcs = [];

    /** Constructor
     *
     */
    this.init = function(jid)
    {
	_jid = jid;
	_roster = new BeeChat.Core.Roster();
    }

    /** Accessors
     *
     */
    this.getConnection = function()
    {
	return _connection;
    }

    this.getJid = function()
    {
	return _jid;
    }

    this.getRoster = function()
    {
	return _roster;
    }

    this.isAttached = function()
    {
	return _attached;
    }

    this.isInitialized = function()
    {
	return _initialized;
    }

    /** Mutators
     *
     */
    this.setInitialized = function(isInitialized)
    {
	_initialized = isInitialized;
    }

    /** Function: addObserver
     *  Add an observer for a specified type of event
     *
     *  Parameters:
     *    (BeeChat.Events.Identifiers) eventType - The type of event to observer
     *    (Object) pFunc - A function to call when the event will be triggered
     */
    this.addObserver = function(eventType, pFunc)
    {
	if (jQuery.inArray(pFunc, _funcs) == -1) {
	    if (!_funcs[eventType])
		_funcs[eventType] = [];
	    _funcs[eventType].push(pFunc);
	}
    }

    /** Function: removeObserver
     *  Remove an observer
     *
     *  Parameters:
     *    (Object) pFunc - The registered function
     */
    this.removeObserver = function(pFunc)
    {
	var index = null;

	for (var key in _funcs) {
	    if (typeof _funcs[key] != 'object')
		continue;
	    if ((index = jQuery.inArray(pFunc, _funcs[key])) != -1)
		_funcs.splice(index, 1);
	}
    }

    /** Function: connect
     *  Connect the user to the BOSH service
     *
     *  Parameters:
     *    (String) password - The user's password
     *
     */
    this.connect = function(password)
    {
	if (_connection == null)
	    _connection = new Strophe.Connection(BeeChat.BOSH_SERVICE);
	_connection.connect(_jid, password, _onConnect);
    }

    /** Function: attach
     *  Attach user's connection to an existing XMPP session
     *
     *  Parameters:
     *    (String) sid - The SID of the existing XMPP session
     *    (String) rid - The RID of the existing XMPP session
     */
    this.attach = function(sid, rid)
    {
	if (_connection == null) {
	    _connection = new Strophe.Connection(BeeChat.BOSH_SERVICE);
	}
	_connection.attach(_jid, sid, rid, _onConnect);
	_attached = true;
	_onConnect(Strophe.Status.CONNECTED);
    }

    /** Function: disconnect
     *  Disconnect the user from the BOSH service
     *
     */
    this.disconnect = function()
    {
	if (_connection != null) {
	    _connection.disconnect();
	    _connection = null;
	}
    }

    /** Function: requestSessionPause
     *  Request a session pause to the server connection manager
     *
     */
    this.requestSessionPause = function()
    {
	var req = $build('body', {
		rid: _connection.rid,
		sid: _connection.sid,
		pause: BeeChat.INACTIVITY_PERIOD_LENGTH,
		xmlns: Strophe.NS.HTTPBIND
	    });

	_attached = false;
	_connection.send(req.tree());
    }

    /** Function: requestRoster
     *  Request a new roster to the server
     *
     */
    this.requestRoster = function()
    {
	var req = $iq({from: _jid, type: BeeChat.IQ.Types.GET})
	.c('query', {xmlns: Strophe.NS.ROSTER});

	_connection.send(req.tree());
    }

    /** Function: sendInitialPresence
     *  Send initial presence to the server in order to signal availability for communications
     *
     */
    this.sendInitialPresence = function()
    {
	_connection.send($pres().tree());
	_initialized = true;
    }

    /** Function: sendChatMessage
     *  Send a chat message to the server
     *
     *  Parameters:
     *    (String) addressee - The addressee of the chat message
     *    (String) msg - The chat message
     *
     */
    this.sendChatMessage = function(addressee, msg)
    {
	var req = $msg({
		type: BeeChat.Message.Types.CHAT,
		to: addressee,
		from: _connection.jid
	    }).c('body').t(msg).up().c(BeeChat.Message.ChatStates.ACTIVE, {xmlns: BeeChat.NS.CHAT_STATES});

	_connection.send(req.tree());
    }

    /** Function: sendChatStateMessage
     *  Send a chat state message to the server
     *
     *  Parameters:
     *    (String) addressee - The addressee of the chat state message
     *    (BeeChat.Message.ChatsState) state - The chat state that will be send
     *
     */
    this.sendChatStateMessage = function(addressee, state)
    {
	var req = $msg({
		type: BeeChat.Message.Types.CHAT,
		to: addressee,
		from: _connection.jid
	    }).c(state, {xmlns: BeeChat.NS.CHAT_STATES});

	_connection.send(req.tree());
    }

    /** Function: sendPresenceAvailabiliy
     *  Send a detailed presence stanza to the server
     *
     *  Parameters:
     *    (BeeChat.Presence.ShowElements) availability - The availability status
     *    (String) details - Detailed status information
     *
     */
    this.sendPresenceAvailability = function(availability, details)
    {
	var req = $pres()
	.c(BeeChat.Presence.ChildElements.SHOW).t(availability).up()
	.c(BeeChat.Presence.ChildElements.STATUS).t(details).up()
	.c(BeeChat.Presence.ChildElements.PRIORITY).t('1');

	_connection.send(req.tree());
    }

    /** PrivateFunction: _fire
     *  Triggers registered funcs of registered observers for a specified type of event
     *
     */
    function _fire(eventType, data, scope)
    {
	if (_funcs[eventType] != undefined) {
	    for (var i = 0; i < _funcs[eventType].length; i++)
		_funcs[eventType][i].call((scope || window), data);
	}
    }

    /** PrivateFunction: _onConnect
     *  Connection state manager
     *
     *  Parameters:
     *    (Strophe.Status) status - A Strophe connection status constant
     *
     */
    function _onConnect(status)
    {
	var msg = null;

	if (status == Strophe.Status.CONNECTING) 
{
	    msg = BeeChat.Events.Messages.ConnectionStates.CONNECTING;
	}
	else if (status == Strophe.Status.AUTHENTICATING) {
	    msg = BeeChat.Events.Messages.ConnectionStates.AUTHENTICATING;
	}
	else if (status == Strophe.Status.AUTHFAIL)
	    msg = BeeChat.Events.Messages.ConnectionStates.FAILED;
 	else if (status == Strophe.Status.CONNFAIL)
	    msg = BeeChat.Events.Messages.ConnectionStates.FAILED;
 	else if (status == Strophe.Status.DISCONNECTING)
	    msg = BeeChat.Events.Messages.ConnectionStates.DISCONNECTING;
 	else if (status == Strophe.Status.DISCONNECTED)
	    msg = BeeChat.Events.Messages.ConnectionStates.OFFLINE;
 	else if (status == Strophe.Status.CONNECTED) {
	    msg = BeeChat.Events.Messages.ConnectionStates.ONLINE;
	    _connection.addHandler(_onIQResult, null, 'iq', BeeChat.IQ.Types.RESULT, null, null);
	    _connection.addHandler(_onPresence, null, 'presence', null, null, null);
	    _connection.addHandler(_onMessageChat, null, 'message', BeeChat.Message.Types.CHAT, null, null);

	}

	_fire(BeeChat.Events.Identifiers.UPDATE_CONNECTION_STATE, msg);
    }

    /** PrivateFunction: _onIQResult
     *  Manage received IQ stanza of 'result' type
     *
     *  Parameters:
     *    (XMLElement) iq - The iq stanza received
     *
     */
    function _onIQResult(iq)
    {
	_roster.updateFromIQResult(iq);
	_fire(BeeChat.Events.Identifiers.UPDATE_ROSTER, _roster.getItems());

	return true;
    }

    /** PrivateFunction: _onPresence
     *  Manage received presence stanza
     *
     *  Parameters:
     *    (XMLElement) presence - The presence stanza received
     *
     */
    function _onPresence(presence)
    {
	if (Strophe.getBareJidFromJid($(presence).attr('from')).toLowerCase() != Strophe.getBareJidFromJid(_jid).toLowerCase()) {
	    _roster.updateFromPresence(presence);
	}
	_fire(BeeChat.Events.Identifiers.RECV_PRESENCE, _roster.getOnlineItems());
	return true;
    }

    /** PrivateFunction: _onMessageChat
     *  Manage received message stanza of 'chat' type
     *
     *  Parameters:
     *    (XMLElement) message - The message stanza received
     *
     */
    function _onMessageChat(message)
    {
	var data = {
	    contactBareJid: Strophe.getBareJidFromJid($(message).attr('from')),
	    msg: message
	};
	_msgTemp.push(data);

	if (_initialized == true) {
	    for (var key in _msgTemp) {
		if (typeof _msgTemp[key] != 'object')
		    continue;
		_fire(BeeChat.Events.Identifiers.RECV_CHAT_MESSAGE, _msgTemp[key]);
		_msgTemp.shift();
	    }
	}

	return true;
    }

    this.init(jid);
};


/** Constructor: BeeChat.Core.Roster
 *  Create a BeeChat.Core.Roster object
 *
 *  Parameters:
 *    (Object) items - The roster's items in object notation
 *
 *  Returns:
 *    A new BeeChat.Core.Roster.
 */
BeeChat.Core.Roster = function()
{
    if (!(this instanceof arguments.callee))
	return new BeeChat.Core.Roster();

    /** Private members
     *
     */
    _items = null;


    /** Constructor
     *
     */
    this.init = function()
    {
	_items = (arguments.length > 0) ? arguments[0] : {};
    }

    /** Accessors
     *
     */
    this.getItems = function()
    {
	return _items;
    }

    /** Mutators
     *
     */
    this.setItems = function(items)
    {
	for (var key in items) {
	    _items[key] = new BeeChat.Core.RosterItem(items[key]);
	}
    }

    this.setIcons = function(icons)
    {
	for (var key in icons) {
	    _items[key + '@' + BeeChat.DOMAIN].icon_small = icons[key].small;
	    _items[key + '@' + BeeChat.DOMAIN].icon_tiny = icons[key].tiny;
	}
    }

    this.setStatuses = function(statuses)
    {
	for (var key in statuses)  {
	    _items[key + '@' + BeeChat.DOMAIN].status = statuses[key];
	}
    }

    /** Function: updateFromIQResult
     *  Update the roster items from an IQ result stanza
     *
     *  Parameters:
     *    (XMLElement) iq - The IQ result stanza
     */
    this.updateFromIQResult = function(iq)
    {
	$(iq).find('item').each(function() {
		var attr = {
		    bareJid: Strophe.getBareJidFromJid($(this).attr('jid')).toLowerCase(),
		    name: $(this).attr('name'),
		    subscription: $(this).attr('subscription'),
		    groups: [],
		    presences: {}
		};

		$(this).find('group').each(function() {
			attr['groups'].push($(this).text());
		    });

		if (attr['groups'].length == 0)
		    attr['groups'].push(BeeChat.Roster.DEFAULT_GROUP);

		if (!_items[attr.bareJid])
		    _items[attr.bareJid] = new BeeChat.Core.RosterItem(attr);
		else {
		    _items[attr.bareJid].bareJid = attr.bareJid;
		    _items[attr.bareJid].name = attr.name;
		    _items[attr.bareJid].subscription = attr.subscription;
		    _items[attr.bareJid].groups = attr.groups;
		}
	    });
    }

    /** Function: updateFromPresence
     *  Update the roster items from a presence stanza
     *
     *  Parameters:
     *    (XMLElement) presence - The presence stanza
     *
     *  Returns:
     *    (String) The bare jid of the roster item who updated his presence
     */
    this.updateFromPresence = function(presence)
    {
	var jid = $(presence).attr('from').toLowerCase();
	var attr = {
	    bareJid: Strophe.getBareJidFromJid(jid),
	    name: null,
	    subscription: null,
	    groups: null,
	    presences: {}
	};

	attr.presences[jid] = {};
	attr.presences[jid].type = (!$(presence).attr('type')) ? 'available' : $(presence).attr('type');

	if (attr.presences[jid].type == 'available') {
	    $(presence).children().each(function() {
		    if (this.tagName == BeeChat.Presence.ChildElements.SHOW)
			attr.presences[jid].show = $(this).text();
		    if (this.tagName == BeeChat.Presence.ChildElements.STATUS)
			attr.presences[jid].status = $(this).text();
		});

	    if (!attr.presences[jid].show)
		attr.presences[jid].show = 'chat';
	} else {
	    attr.presences[jid].show = 'offline';
	}

	if (!_items[attr.bareJid])
	    _items[attr.bareJid] = new BeeChat.Core.RosterItem(attr);
	else
	    _items[attr.bareJid].presences[jid] = attr.presences[jid];
    }

    /** Function: getOnlineItems
     *
     *
     */
    this.getOnlineItems = function()
    {
	var sortedOnlineBareJid = [];
	var sortedOnlineItems = {};

	for (var key in _items) {
	    if (typeof _items[key] != 'object')
		continue;

	    var pres = _items[key].getStrongestPresence();

	    if (pres != null && pres.type == 'available') {
		sortedOnlineBareJid.push(key);
	    }
	}

	if (sortedOnlineBareJid.length > 1) {
	    sortedOnlineBareJid.sort();
	    sortedOnlineBareJid.sort(statusSort);
	}

	for (var key in sortedOnlineBareJid) {
	    sortedOnlineItems[sortedOnlineBareJid[key]] = _items[sortedOnlineBareJid[key]];
	}

	return (sortedOnlineItems);
    }

    /** Function: getSizeOnlineItems
     *  Return the number of available items
     *
     *  Returns:
     *    (int) The number of available items
     */
    this.getSizeOnlineItems = function()
    {
	var n = 0;

	for (var key in _items) {
	    if (typeof _items[key] != 'object')
		continue;

	    var pres = _items[key].getStrongestPresence();

	    if (pres != null && pres.type == 'available')
		++n;
	}
	return (n);
    }

    /** Function: getItemsUsernamesAsList
     *
     */
    this.getItemsUsernamesAsList = function()
    {
	var data = '';

	for (var key in _items) {
	    if (typeof _items[key] != 'object')
		continue;
	    data = data + Strophe.getNodeFromJid(key) + ',';
	}

	return (data);
    }

    /** PrivateFunction: statusSort
     *
     */
    function statusSort(x, y)
    {
	var xPres = _items[x].getStrongestPresence();
	var yPres = _items[y].getStrongestPresence();

	if (xPres != null && yPres != null)
	    return (BeeChat.Core.Roster.Utils.comparePresences(xPres, yPres));
	return (0);
    }

    this.init();
};

BeeChat.Core.Roster.Utils = {

    /** Function: comparePresences
     *  Compare the two presences x and y
     *
     *  Parameters:
     *    (Object) xPres - The x presence in object notation
     *    (Object) yPres - The y presence in object notation
     *
     *  Returns:
     *    0 if presence are equal, 1 if x > y, -1 if y > x
     *
     *  Note:
     *    Presences are tagged in the following order:
     *      ONLINE < DND < AWAY < XA < OFFLINE
     *
     */
    comparePresences: function(xPres, yPres)
    {
	var xRate = 0;
	var yRate = 0;

	if (xPres.type == 'unavailable')
	    xRate += BeeChat.Core.ReferenceTables.AvailabilityRates[xPres.type.toUpperCase()];
	if (yPres.type == 'unavailable')
	    yRate += BeeChat.Core.ReferenceTables.AvailabilityRates[yPres.type.toUpperCase()];

	if (xPres.show != null)
	    xRate += BeeChat.Core.ReferenceTables.AvailabilityRates[xPres.show.toUpperCase()];
	if (yPres.show != null)
	    yRate =+ BeeChat.Core.ReferenceTables.AvailabilityRates[yPres.show.toUpperCase()];

	if (xRate > yRate)
	    return (1);
	else if (xRate == yRate)
	    return (0);
	return (-1);
    }
};


/** Constructor: BeeChat.Core.RosterItem
 *  Create a BeeChat.Core.RosterItem object
 *
 *  Parameters:
 *    (Object) attr - The RosterItem's attributes in object notation
 *
 *  Returns:
 *    A new BeeChat.Core.RosterItem.
 */
BeeChat.Core.RosterItem = function()
{
    this.bareJid = (arguments.length > 0) ? arguments[0].bareJid : null;
    this.name = (arguments.length > 0) ? arguments[0].name : null;
    this.subscription = (arguments.length > 0) ? arguments[0].subscription : null;
    this.groups = (arguments.length > 0) ? arguments[0].groups : null;
    this.presences = (arguments.length > 0) ? arguments[0].presences : null;
    this.icon_small = (arguments.length > 0) ? arguments[0].icon_small : null;
    this.icon_tiny = (arguments.length > 0) ? arguments[0].icon_tiny : null;
    this.status = (arguments.length > 0) ? arguments[0].status : null;
};
BeeChat.Core.RosterItem.prototype = {
    /** Function: getStrongestPresence
     *  Return the strongest presence of the RosterItem
     *
     */
    getStrongestPresence: function()
    {
	var res = null;

	for (var key in this.presences) {
	    if (typeof this.presences[key] != 'object')
		continue;
	    if (res == null)
		res = this.presences[key];
	    else
		if (BeeChat.Core.Roster.Utils.comparePresences(this.presences[key], res) == -1)
		    res = this.presences[key];
	}
	return (res);
    }
};


/** Class: BeeChat.UI
 *  An object container for all BeeChat UI functions
 *
 */
BeeChat.UI = {
    HAS_FOCUS: true,

    Resources: {
	Paths: {
	    ICONS: 'http://static.beebac.com/mod/beechat/graphics/icons/',
	    MEMBER_PROFILE: 'http://www.beebac.com/pg/profile/'
	},

	Sounds: {
	    NEW_MESSAGE: 'beechat_sounds_new_message'
	},

	/*
	Cookies: {
	    DOMAIN: 'beechannels.com',
	    FILENAME_CONN: 'beechat_conn'
	},
	*/

	Emoticons: {
    	    FILENAME_SMILE: 'emoticon_smile.png',
	    FILENAME_UNHAPPY: 'emoticon_unhappy.png',
	    FILENAME_GRIN: 'emoticon_grin.png',
	    FILENAME_EVILGRIN: 'emoticon_evilgrin.png',
	    FILENAME_SURPRISED: 'emoticon_surprised.png',
	    FILENAME_TONGUE: 'emoticon_tongue.png',
	    FILENAME_WINK: 'emoticon_wink.png'
	},

	Strings: {
	    Availability: {
		AVAILABLE: "Disponible",
		CHAT: "Disponible",
		ONLINE: "Disponible",
		DND: "Ne pas déranger",
		AWAY: "Absent",
		XA:"Absence prolongée",
		OFFLINE: "Hors ligne"
	    },

	    Contacts: {
		BUTTON: "Chat"
	    },

	    ChatMessages: {
		SELF: "",
		COMPOSING: " est en train d'écrire."
	    },

	    Box: {
		MINIMIZE: "Diminuer",
		CLOSE: "Fermer",
		SHOWHIDE: "Montrer/Cacher cette fenêtre de chat"
	    }
	},

	StyleClasses: {
	    Availability: {
		Left: {
		    ONLINE: 'beechat_left_availability_chat',
		    DND: 'beechat_left_availability_dnd',
		    AWAY: 'beechat_left_availability_away',
		    XA: 'beechat_left_availability_xa',
		    OFFLINE: 'beechat_left_availability_offline'
		},

		Right: {
		    ONLINE: 'beechat_right_availability_chat',
		    DND: 'beechat_right_availability_dnd',
		    AWAY: 'beechat_right_availability_away',
		    XA: 'beechat_right_availability_xa',
		    OFFLINE: 'beechat_right_availability_offline'
		},

		Control: {
		    UP: 'beechat_availability_switcher_control_up',
		    DOWN: 'beechat_availability_switcher_control_down'
		}
	    },

	    ChatBox: {
		MAIN: 'beechat_chatbox',
		TOP: 'beechat_chatbox_top',
		SUBTOP: 'beechat_chatbox_subtop',
		TOP_ICON: 'beechat_chatbox_top_icon',
		TOP_CONTROLS: 'beechat_chatbox_top_controls',
		CONTENT: 'beechat_chatbox_content',
		INPUT: 'beechat_chatbox_input',
		BOTTOM: 'beechat_chatbox_bottom',
		CONTROL: 'beechat_chatbox_control',
		STATE: 'beechat_chatbox_state',
		MESSAGE: 'beechat_chatbox_message',
		MESSAGE_SENDER: 'beechat_chatbox_message_sender',
		MESSAGE_DATE: 'beechat_chatbox_message_date'
	    },

	    ScrollBox: {
		SELECTED: 'beechat_scrollbox_selected'
	    },

	    BOX_CONTROL: 'beechat_box_control',
	    LABEL: 'beechat_label',
	    UNREAD_COUNT: 'beechat_unread_count'
	},

	Elements: {
	    ID_DIV_BAR: 'beechat',
	    ID_DIV_BAR_CENTER: 'beechat_center',
	    ID_DIV_BAR_RIGHT: 'beechat_right',

	    ID_TOOLTIP_TRIGGER: 'beechat_tooltip_trigger',

	    ID_SPAN_CONTACTS_BUTTON: 'beechat_contacts_button',
	    ID_SPAN_CLOSE_BOX: 'beechat_box_control_close',

	    ID_DIV_CONTACTS: 'beechat_contacts',
	    ID_DIV_CONTACTS_CONTROLS: 'beechat_contacts_controls',
	    ID_SPAN_CONTACTS_CONTROL_MINIMIZE: 'beechat_contacts_control_minimize',
	    ID_DIV_CONTACTS_CONTENT: 'beechat_contacts_content',
	    ID_UL_CONTACTS_LIST: 'beechat_contacts_list',

	    ID_DIV_AVAILABILITY_SWITCHER: 'beechat_availability_switcher',
	    ID_SPAN_AVAILABILITY_SWITCHER_CONTROL: 'beechat_availability_switcher_control',
	    ID_SPAN_CURRENT_AVAILABILITY: 'beechat_current_availability',
	    ID_UL_AVAILABILITY_SWITCHER_LIST: 'beechat_availability_switcher_list',

	    ID_DIV_CHATBOXES: 'beechat_chatboxes',

	    ID_DIV_SCROLLBOXES: 'beechat_scrollboxes'
	}
    },


    /** Function: initialize
     *  Initialize the BeeChat UI
     *
     */
    initialize: function(ts, token)
    {
	this.ts = ts;
	this.token = token;
	$('#' + BeeChat.UI.Resources.Elements.ID_TOOLTIP_TRIGGER).tooltip({
		offset: [-3, 8],
		effect: 'fade'
	    });

	$('#accountlinks').find('li').filter('[class=last]').bind('click', function() {
		if (g_beechat_user != null)
		    g_beechat_user.disconnect();
	    });

	BeeChat.UI.AvailabilitySwitcher.initialize(BeeChat.Presence.ShowElements.CHAT);
	BeeChat.UI.ContactsList.initialize();
	BeeChat.UI.ScrollBoxes.initialize();
	BeeChat.UI.loadConnection();
    },

    /** Function: getUserDetails
     *  Retrieve user details
     *
     *  Returns:
     *    User details in object notation.
     *
     */
    addActionTokens: function(url_string)
    {
	return url_string + "?__elgg_ts="+this.ts + "&__elgg_token=" + this.token;
    },

    getUserDetails: function(cb_func)
    {
	var json = null;
	var self = this;

	$.ajax({
		url: self.addActionTokens('http://www.beebac.com/action/beechat/get_details'),
		async: true,
		dataType: 'json',
		success: function(data) {
			cb_func(data);
		}
	    });

	return (json);
    },

    /** Function: connect
     *  Create the user and connect him to the BOSH service
     *
     *  Parameters:
     *    (Object) conn - Running connection informations in object notation
     */
    connect: function()
    {
	var conn = (arguments.length > 0) ? arguments[0] : null;
	var userDetails = {
	    jid: (conn != null) ? conn.jid : null,
	    password: null
	}
	var self = this;
	if (conn == null || (conn != null && conn.attached)) {
	    BeeChat.UI.getUserDetails(function(retrievedUserDetails) {
	    	userDetails.jid = retrievedUserDetails.username + '@' + BeeChat.DOMAIN + '/' + BeeChat.RESOURCE;
	    	userDetails.password = retrievedUserDetails.password;
		self.connect_end(conn, userDetails)
	    });
	}
	else
	        this.connect_end(conn, userDetails)
    },

    connect_end: function(conn, userDetails)
    {
	g_beechat_user = new BeeChat.Core.User(userDetails.jid);
	g_beechat_user.addObserver(BeeChat.Events.Identifiers.UPDATE_CONNECTION_STATE, BeeChat.UI.updateConnectionStatus);
	g_beechat_user.addObserver(BeeChat.Events.Identifiers.UPDATE_ROSTER, BeeChat.UI.onRosterUpdate);
	g_beechat_user.addObserver(BeeChat.Events.Identifiers.RECV_PRESENCE, BeeChat.UI.ContactsList.update);
	g_beechat_user.addObserver(BeeChat.Events.Identifiers.RECV_CHAT_MESSAGE, BeeChat.UI.onChatMessage);

	if (conn == null || (conn != null && conn.attached))
	    g_beechat_user.connect(userDetails.password);
	else
	    g_beechat_user.attach(conn.sid, conn.rid);
    },
 
    /** Function: disconnect
     *  Terminate the user's XMPP session
     *
     */
    disconnect: function()
    {
	g_beechat_user.disconnect();
    },

    /** Function: updateConnectionStatus
     *
     */
    updateConnectionStatus: function(connStatusMsg)
    {
	BeeChat.UI.ContactsList.updateButtonText(connStatusMsg);
	if (connStatusMsg == BeeChat.Events.Messages.ConnectionStates.ONLINE) {
	    if (!g_beechat_user.isAttached()) {
		g_beechat_user.requestRoster();
		//BeeChat.UI.ContactsList.toggleDisplay();
		$('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).show();
		$('.' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + '>textarea').removeAttr('disabled');
	    }
	    if (g_beechat_user.isAttached()) {
		BeeChat.UI.loadState();
	    }

	    $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'online');
	    BeeChat.UI.saveConnection();
	}
	else if (connStatusMsg == BeeChat.Events.Messages.ConnectionStates.OFFLINE) {
	    var contactsBoxElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS);

	    if (!contactsBoxElm.is(':hidden'))
		BeeChat.UI.ContactsList.toggleDisplay();

	    $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).empty();
	    BeeChat.UI.AvailabilitySwitcher.initialize(BeeChat.Presence.ShowElements.CHAT);
	    BeeChat.UI.ContactsList.updateButtonText(BeeChat.UI.Resources.Strings.Contacts.BUTTON);
	    $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'offline');
	    $('.' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + '>textarea').attr('disabled', 'true');
	    $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().hide();
	    $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children()
	    .attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()]);
	    g_beechat_user = null;
	    BeeChat.UI.saveConnection();
	}
    },

    /** Function: saveConnection
     *  Save connection informations (non sensible data) in $_SESSION.
     *
     */
    saveConnection: function()
    {
	var conn = null;

	if (g_beechat_user != null) {
	    var userConn = g_beechat_user.getConnection();

	    conn = {
		'jid': userConn.jid,
		'sid': userConn.sid,
		'rid': userConn.rid,
		'attached': g_beechat_user.isAttached()
	    };
	}
	var self = this;
	
	$.ajax({
		type: 'POST',
		async: false,
		url: self.addActionTokens('http://www.beebac.com/action/beechat/save_state'),
		data: { beechat_conn: JSON.stringify(conn) },
		async:false
	    });

	/*
	$.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN, null);
	$.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN, JSON.stringify(conn), {path: '/', domain: BeeChat.UI.Resources.Cookies.DOMAIN});
	*/
    },

    /** Function: loadConnection
     *  Check if a connection already exists. In the case that a connection exists,
     *  this function triggers the connection process.
     *
     */
    loadConnection: function()
    {
	var self = this;
	$.ajax({
		type: 'GET',
		async: false,
		cache: false,
		dataType: 'json',
		url: self.addActionTokens('http://www.beebac.com/action/beechat/get_connection'),
		success: function(conn) {
		    if (conn != null) {
			if (conn.attached)
			    BeeChat.UI.connect();
			else
			    BeeChat.UI.connect(conn);
			}
		},
		error: function() {
		    BeeChat.UI.connect();
		}
	    });

	/*
	var conn = JSON.parse($.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN));

	if (conn != null) {
	    if (conn.attached)
		BeeChat.UI.connect();
	    else
		BeeChat.UI.connect(conn);
	} else
	    BeeChat.UI.connect();
	*/
    },

    /** Function: saveState
     *  Save app state in $_SESSION
     *
     */
    saveState: function()
    {
	var self = this;
	var currentAvailabilityClass = $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY).attr('class');
	var currentAvailability = currentAvailabilityClass.substr(currentAvailabilityClass.lastIndexOf('_') + 1);

	var data = {
	    availability: currentAvailability,
	    contacts: g_beechat_roster_items,
	    chats: {},
	    contacts_list: {
		minimized: $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS).is(':hidden')
	    }
	};

	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().each(function() {
		var contactBareJid = $(this).attr('bareJid');
		//var contactBareJid = $(this).data('bareJid');

		data.chats[contactBareJid] = {
		    'html_content': $(this).children().filter('[bareJid=' + contactBareJid + ']').html(),
		    'minimized': $(this).is(':hidden'),
		    'unread': BeeChat.UI.UnreadCountBox.getElm(contactBareJid).text()
		};
	    });

	$.ajax({
		type: 'POST',
		async: false,
		url: self.addActionTokens('http://www.beebac.com/action/beechat/save_state'),
		data: { beechat_state: JSON.stringify(data) },
		async:false 
	    });
    },

    /** Function: loadState
     *  Load app state from $_SESSION
     *
     */
    loadState: function()
    {
	var self = this;
	$.ajax({
		type: 'GET',
		async: true,
		cache: false,
		dataType: 'json',
		url: self.addActionTokens('http://www.beebac.com/action/beechat/get_state'),
		success: function(json) {
		    BeeChat.UI.AvailabilitySwitcher.initialize(json.availability);

		    if (!json.contacts_list.minimized) {
				$('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS).show();
				BeeChat.UI.ContactsList.showedStyle();
		    }

		    g_beechat_user.getRoster().setItems(json.contacts);
		    g_beechat_roster_items = g_beechat_user.getRoster().getItems();
		    BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems())
		    g_beechat_user.setInitialized(true);

		    var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES);
		    var scrollBoxElmToShow = null;

		    // Load save chats
		    for (var key in json.chats) {
			BeeChat.UI.ScrollBoxes.add(key);

			var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(key);

			if (!json.chats[key].minimized) {
			    scrollBoxElmToShow = BeeChat.UI.ScrollBoxes.getScrollBoxElm(key);
			}

			var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + key + ']');

			chatBoxContentElm.append(json.chats[key].html_content);
			chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')});

			BeeChat.UI.UnreadCountBox.update(key, json.chats[key].unread);
		    }
		    if (scrollBoxElmToShow != null)
			scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElmToShow));
		    else
			scrollBoxesElm.trigger('goto', 0);

		    g_beechat_user.sendPresenceAvailability(json.availability, '');
		    BeeChat.UI.ScrollBoxes.isInitialized = true;

			  for (var key in json.chats) {
					if (json.chats[key].minimized) {
						BeeChat.UI.ChatBoxes.getChatBoxElm(key).hide();
						BeeChat.UI.ScrollBoxes.unselect(key);
					}
				}

		},
		error: function() {
		    BeeChat.UI.ContactsList.initialize();
		}
	    });
    },

    /** Function: loadRosterItemsIcons
     *
     */
    loadRosterItemsIcons: function()
    {
	var data = g_beechat_user.getRoster().getItemsUsernamesAsList();
	var self = this;

	$.ajax({
		type: 'POST',
		url: self.addActionTokens('http://www.beebac.com/action/beechat/get_icons'),
		async: true,
		cache: false,
		data: {'beechat_roster_items_usernames': data},
		dataType: 'json',
		success: function(json) {
		    g_beechat_user.getRoster().setIcons(json);
		    g_beechat_roster_items = g_beechat_user.getRoster().getItems();
		}
	    });
    },

    /** Function: loadRosterItemsStatuses
     *
     */
    loadRosterItemsStatuses: function()
    {
	var data = g_beechat_user.getRoster().getItemsUsernamesAsList();

	var self = this;
	$.ajax({
		type: 'POST',
		url: self.addActionTokens('http://www.beebac.com/action/beechat/get_statuses'),
		async: true,
		cache: false,
		data: {'beechat_roster_items_usernames': data},
		dataType: 'json',
		success: function(json) {
		    g_beechat_user.getRoster().setStatuses(json);
		    g_beechat_roster_items = g_beechat_user.getRoster().getItems();
		}
	    });
    },

    /** Function: onRosterUpdate
     *  Notified by core on a roster update
     *
     */
    onRosterUpdate: function(rosterItems)
    {
	g_beechat_roster_items = rosterItems;

	if (!g_beechat_user.isInitialized()) {

	    BeeChat.UI.loadRosterItemsIcons();
	    BeeChat.UI.loadRosterItemsStatuses();
	    g_beechat_user.sendInitialPresence();
	}
    },

    /** Function: onChatMessage
     *
     */
    onChatMessage: function(data)
    {
	if ($(data.msg).find('body').length == 0) {
	    BeeChat.UI.ChatBoxes.updateChatState(data.contactBareJid, data.msg);
	}
	else {
	    BeeChat.UI.ChatBoxes.update(data.contactBareJid, BeeChat.UI.Utils.getContactName(data.contactBareJid), Strophe.getText($(data.msg).find('body')[0]));
	}
    }
};


/** Class: BeeChat.UI.Resources.ReferenceTables
 *  An object container for all reference tables
 *
 */
BeeChat.UI.Resources.ReferenceTables = {
    Styles: {
	Availability: {
	    Left: {
		AVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Left.ONLINE,
		CHAT: BeeChat.UI.Resources.StyleClasses.Availability.Left.ONLINE,
		DND: BeeChat.UI.Resources.StyleClasses.Availability.Left.DND,
		AWAY: BeeChat.UI.Resources.StyleClasses.Availability.Left.AWAY,
		XA: BeeChat.UI.Resources.StyleClasses.Availability.Left.XA,
		UNAVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Left.OFFLINE,
		OFFLINE: BeeChat.UI.Resources.StyleClasses.Availability.Left.OFFLINE
	    },

	    Right: {
		AVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Right.ONLINE,
		CHAT: BeeChat.UI.Resources.StyleClasses.Availability.Right.ONLINE,
		DND: BeeChat.UI.Resources.StyleClasses.Availability.Right.DND,
		AWAY: BeeChat.UI.Resources.StyleClasses.Availability.Right.AWAY,
		XA: BeeChat.UI.Resources.StyleClasses.Availability.Right.XA,
		UNAVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Right.OFFLINE,
		OFFLINE: BeeChat.UI.Resources.StyleClasses.Availability.Right.OFFLINE
	    }
	}
    }
};


/** Class: BeeChat.UI.ContactsList
 *  An object container for all ContactsList functions
 *
 */
BeeChat.UI.ContactsList = {
    /** Function: initialize
     *  Initialize the contacts list by binding elements
     *
     */
    initialize: function()
    {
		$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_CONTROL_MINIMIZE).unbind('click').bind('click', BeeChat.UI.ContactsList.toggleDisplay);
	$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).unbind('click').bind('click', function() {
		if (g_beechat_user == null)
		    BeeChat.UI.connect();
		else
		    BeeChat.UI.ContactsList.toggleDisplay();
	    });
    },

    /** Function: update
     *  Update the contacts list content
     *
     *  Parameters:
     *    (Object)(BeeChat.Core.RosterItem) onlineRosterItems - A hash of RosterItems in object notation
     *
     */
    update: function(onlineRosterItems)
    {
	var contactsListElm = $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST);

	contactsListElm.children().each(function() {
		var contactBareJid = $(this).attr('bareJid');

		if (g_beechat_roster_items != null) {
		    if ($.inArray(contactBareJid, onlineRosterItems) == -1) {
			BeeChat.UI.ScrollBoxes.updateAvailability(contactBareJid);
			$(this).remove();
		    }
		}
	    });

	for (var key in onlineRosterItems) {
	    if (typeof onlineRosterItems[key] != 'object')
		continue;

	    var contactElm = contactsListElm.find('li').filter('[bareJid=' + key + ']');

	    if (contactElm.length == 0) {
		contactElm = $('<li></li>')
		    .attr('bareJid', key)
		    .append($('<img />')
			    .attr('src', g_beechat_roster_items[key].icon_tiny))
		    .append(BeeChat.UI.Utils.getTruncatedContactName(key, 25))
		    .appendTo(contactsListElm)
		    .bind('click', function() {
					if (!BeeChat.UI.ChatBoxes.getChatBoxElm($(this).attr('bareJid')).is(':visible')) {
						BeeChat.UI.ContactsList.toggleDisplay();
					}

			    BeeChat.UI.ScrollBoxes.add($(this).attr('bareJid'), true);
			});
	    }

	    BeeChat.UI.ContactsList.updateContactAvailability(contactElm, key);
	}

	BeeChat.UI.ContactsList.updateButtonText(BeeChat.UI.Resources.Strings.Contacts.BUTTON + ' (<strong>' + g_beechat_user.getRoster().getSizeOnlineItems() + '</strong>)');
    },

    /** Function: updateContactAvailability
     *
     */
    updateContactAvailability: function(contactElm, contactBareJid)
    {
	// Update from contactsList
	contactElm.attr('class', BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Right[g_beechat_roster_items[contactBareJid].getStrongestPresence().show.toUpperCase()]);

	// Update from scrollBoxes
	BeeChat.UI.ScrollBoxes.updateAvailability(contactBareJid);
    },

    /** Function: updateButtonText
     *
     *
     */
    updateButtonText: function(msg)
    {
	$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).html(msg);
    },

    /** Function: toggleDisplay
     *  Toggle the contacts box display (hide | show)
     *
     */
    toggleDisplay: function()
    {
	var contactsBoxElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS);

	contactsBoxElm.toggle();
	if (contactsBoxElm.is(':hidden')) {
	    BeeChat.UI.ContactsList.hiddenStyle();
	} else {
	    BeeChat.UI.ContactsList.showedStyle();
	}
	$('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).hide();
    },

    /** Function: hiddenStyle
     *
     */
    hiddenStyle: function()
    {
	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_RIGHT).css({'border-left': '1px solid #BBBBBB', 'border-right': '1px solid #BBBBBB', 'background-color': '#DDDDDD'});
    },

    /** Function: showedStyle
     *
     */
    showedStyle: function()
    {
	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_RIGHT).css({'border-left': '1px solid #666666', 'border-right': '1px solid #666666', 'background-color': 'white'});
    }
};


/** Class: BeeChat.UI.AvailabilitySwitcher
 *  An object container for all AvailabilitySwitcher functions
 *
 */
BeeChat.UI.AvailabilitySwitcher = {
    /** Function: initialize
     *  Initialize the availability switcher by setting the current user's availability
     *  and binding actions
     *
     */
    initialize: function(availability)
    {
		$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY).unbind('click').bind('click', BeeChat.UI.AvailabilitySwitcher.toggleListDisplay);
		
		$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_AVAILABILITY_SWITCHER_CONTROL).unbind('click').bind('click', BeeChat.UI.AvailabilitySwitcher.toggleListDisplay);
		
		$('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).find('li').each(function() {
		$(this).unbind('click').bind('click', function() {
			var availabilityClass = $(this).attr('class');
			var availability = availabilityClass.substr(availabilityClass.lastIndexOf('_') + 1);

			if (availability == 'offline')
			    BeeChat.UI.disconnect();
			else {
			    g_beechat_user.sendPresenceAvailability(availability, '');
			    BeeChat.UI.AvailabilitySwitcher.update(availability);
			    $('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).hide('slow');
			    $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).show('slow');
			}
		    });
	    });
	BeeChat.UI.AvailabilitySwitcher.update(availability);
    },

    /** Function: update
     *  Update the current user's availability
     *
     *  Parameters:
     *    (BeeChat.Presence.ShowElements) availability - The current user's availability
     */
    update: function(availability)
    {
	var upperCasedAvailability = availability.toUpperCase();

	$('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY)
	.attr('class', BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[upperCasedAvailability])
	.text(BeeChat.UI.Resources.Strings.Availability[upperCasedAvailability]);

	if (availability == 'chat')
	    $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'online');
	else if (availability == 'xa' || availability == 'away')
	    $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'away');
	else if (availability == 'dnd')
	    $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'dnd');
    },

    /** Function: switchControlClass
     *
     */
    switchControlClass: function()
    {
	var switcherControlElm = $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_AVAILABILITY_SWITCHER_CONTROL);

	if (switcherControlElm.attr('class') == BeeChat.UI.Resources.StyleClasses.Availability.Control.UP)
	    switcherControlElm.attr('class', BeeChat.UI.Resources.StyleClasses.Availability.Control.DOWN);
	else
	    switcherControlElm.attr('class', BeeChat.UI.Resources.StyleClasses.Availability.Control.UP);
    },

    /** Function: toggleListDisplay
     *
     */
    toggleListDisplay: function()
    {
		BeeChat.UI.AvailabilitySwitcher.switchControlClass();
		$('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).toggle('slow');
		$('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).toggle('slow');
    }
};


/** Class: BeeChat.UI.ScrollBoxes
 *  An object container for all ScrollBoxes related functions
 *
 */
BeeChat.UI.ScrollBoxes = {
    isInitialized: false,

    /** Function: initialize
     *
     */
    initialize: function() {
	var $prev = $('#beechat_center_prev'),
	$next = $('#beechat_center_next');

	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_CENTER).serialScroll({
		    target: '#beechat_scrollboxes',
		    items: 'li',
		    prev: '#beechat_center_prev',
		    next: '#beechat_center_next',
		    axys: 'x',
		    start: 2,
		    step: -1,
		    interval: 0,
		    duration: 0,
		    cycle: false,
		    force: true,
		    jump: true,
		    lock: true,
		    lazy: true,
		    constant: true,

		    onBefore: function(e, elem, $pane, $items, pos) {
		      $next.add($prev).hide();
		      $prev.add($next).hide();
		      if (pos != 0) {
			  $next.show();
		      }
		      if (pos != $items.length - 1)
			  $prev.show();
		    },

		    onAfter: function(elem) {
		    	BeeChat.UI.ChatBoxes.takeStand($(elem).attr('bareJid'));
			BeeChat.UI.ScrollBoxes.isInitialized = true;
		    }
	    });
    },

    /** Function: add
     *  Add a scrollbox to the scrollboxes bar
     *
     */
    add: function(contactBareJid)
    {
	var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES);
	var scrollBoxElm = scrollBoxesElm.find('ul').children().filter('[bareJid=' + contactBareJid + ']');

	if (scrollBoxElm.length == 0) {
	    var availClass = null;
	    var pres = g_beechat_roster_items[contactBareJid] != null ? g_beechat_roster_items[contactBareJid].getStrongestPresence() : null;

	    if (pres != null)
		availClass = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[pres.show.toUpperCase()];
	    else
		availClass = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()];

	    scrollBoxElm = $('<li></li>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + availClass)
		.attr('bareJid', contactBareJid)
		.attr('title', BeeChat.UI.Resources.Strings.Box.SHOWHIDE)
		.text(BeeChat.UI.Utils.getTruncatedContactName(contactBareJid, 11))
		.append($('<span></span>')
			.attr('class', BeeChat.UI.Resources.StyleClasses.BOX_CONTROL)
			.attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX)
			.text('X')
			.attr('title', BeeChat.UI.Resources.Strings.Box.CLOSE)
			.bind('click', function() {
				var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES);

				BeeChat.UI.ChatBoxes.remove($(this).parent().attr('bareJid'));
				scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(BeeChat.UI.ScrollBoxes.getSelectedScrollBoxElm()));
			    }));

	    scrollBoxesElm.find('ul').append(scrollBoxElm);
	    BeeChat.UI.ChatBoxes.add(contactBareJid);
	    if (arguments.length == 2 && arguments[1])
		scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm));
	    BeeChat.UI.loadRosterItemsIcons();
	    BeeChat.UI.loadRosterItemsStatuses();
	} else {
	    scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm));
	}
    },

    /** Function: remove
     *
     */
    remove: function(contactBareJid)
    {
	BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).remove();
    },

    /** Function: unselect
     *
     */
    unselect: function(contactBareJid)
    {
	var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid);
	scrollBoxElm.attr('class', (scrollBoxElm.attr('class')).replace(/beechat_scrollbox_selected/, ''));
    },

    /** Function: select
     *
     */
    select: function(contactBareJid)
    {
	var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid);
	var scrollBoxElmClasses = scrollBoxElm.attr('class');

	if (scrollBoxElmClasses.search(/beechat_scrollbox_selected/) == -1)
	    scrollBoxElm.attr('class', scrollBoxElmClasses + ' ' + BeeChat.UI.Resources.StyleClasses.ScrollBox.SELECTED);
    },

    /** Function: updateAvailability
     *
     */
    updateAvailability: function(contactBareJid)
    {
	var pres = g_beechat_roster_items[contactBareJid].getStrongestPresence();
	var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid);
	var scrollBoxElmClasses = scrollBoxElm.attr('class');
	var updatedAvailability = null;

	if (pres != null)
	    updatedAvailability = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[pres.show.toUpperCase()];
	else
	    updatedAvailability = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()];

	if (scrollBoxElmClasses == undefined || scrollBoxElmClasses.search(/(beechat_left_availability_)/g) == -1) {
	    scrollBoxElm.attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + updatedAvailability);
	} else {
	    updatedAvailability = updatedAvailability.replace(/(beechat_left_availability)/g, '');

	    scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_chat)/g, updatedAvailability);
	    scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_dnd)/g, updatedAvailability);
	    scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_away)/g, updatedAvailability);
	    scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_xa)/g, updatedAvailability);
	    scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_offline)/g, updatedAvailability);

	    scrollBoxElm.attr('class', scrollBoxElmClasses);
	}
    },

    /** Function: getSelectedScrollBoxElm
     *
     */
    getSelectedScrollBoxElm: function(contactBareJid)
    {
	var elm = undefined;

	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().each(function() {
		if ($(this).attr('class').search(/beechat_scrollbox_selected/) != -1)
		    elm = $(this);
	    });

	return (elm);
    },

    /** Function: getScrollBoxElm
     *
     */
    getScrollBoxElm: function(contactBareJid)
    {
	return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().filter('[bareJid=' + contactBareJid + ']');
    }
};


/** Class: BeeChat.UI.ChatBoxes
 *  An object container for all ChatBoxes related functions
 *
 */
BeeChat.UI.ChatBoxes = {
    dateLastComposing: {},
    lastTimedPauses: {},

    /** Function: add
     *
     */
    add: function(contactBareJid)
    {
	var chatBoxes = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES);

	if ($(chatBoxes).children().filter('[bareJid=' + contactBareJid + ']').length == 0) {
	    var chatBox = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN)
		.attr('bareJid', contactBareJid)
		.hide();

	    var chatBoxTop = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP)
		.append($('<a></a>')
			.attr('href', BeeChat.UI.Resources.Paths.MEMBER_PROFILE + Strophe.getNodeFromJid(contactBareJid))
			.append($('<img />')
				.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP_ICON)
				.attr('src', g_beechat_roster_items[contactBareJid].icon_small)))
		.append($('<span></span>')
			.attr('class', BeeChat.UI.Resources.StyleClasses.LABEL)
			.html('<a href="' + BeeChat.UI.Resources.Paths.MEMBER_PROFILE + Strophe.getNodeFromJid(contactBareJid) + '">' + BeeChat.UI.Utils.getTruncatedContactName(contactBareJid) + '</a>'))
		.append($('<div></div>')
			.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP_CONTROLS)
			.append($('<span></span>')
				.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTROL)
				.attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX)
				.text('X')
				.attr('title', BeeChat.UI.Resources.Strings.Box.CLOSE)
				.bind('click', function() {
					BeeChat.UI.ChatBoxes.remove($(this).parent().parent().parent().attr('bareJid'));
				    }))
			.append($('<span></span>')
				.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTROL)
				.attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX)
				.text('_')
				.attr('title', BeeChat.UI.Resources.Strings.Box.MINIMIZE)
				.css({'font-size': '1.6em', 'position': 'relative', 'line-height': '4px'})
				.bind('click', function() {
					BeeChat.UI.ScrollBoxes.unselect($(this).parent().parent().parent().attr('bareJid'));
					$(this).parent().parent().parent().fadeOut('slow');
				    })));

	    var chatBoxSubTop = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.SUBTOP)
		.append(BeeChat.UI.Utils.getTruncatedContactStatus(g_beechat_roster_items[contactBareJid].status != undefined ? g_beechat_roster_items[contactBareJid].status : ''));

	    var chatBoxContent = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTENT)
		.attr('bareJid', contactBareJid);

	    var chatBoxInput = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT)
		.append($('<textarea></textarea>')
			.attr('bareJid', contactBareJid)
			.bind('keypress', BeeChat.UI.ChatBoxes.onTypingMessage)
			.bind('keyup', function(e) {
				if ((e.keyCode ? e.keyCode : e.which) == 13)
				    $(this).val('');
			    }));

	    var chatBoxBottom = $('<div></div>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.BOTTOM)
		.append($('<span></span>')
			.append($('<span></span>')));

	    chatBox.append(chatBoxTop).append(chatBoxSubTop).append(chatBoxContent).append(chatBoxInput).append(chatBoxBottom).appendTo(chatBoxes);
	}
    },

    /** Function: takeStand
     *
     */
    takeStand: function(contactBareJid)
    {
	var chatBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children();
	var chatBoxElm = chatBoxesElm.filter('[bareJid=' + contactBareJid + ']');
	var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']');
	var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES);
	var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid);

	if (!chatBoxElm.is(':hidden')) {
	    BeeChat.UI.ScrollBoxes.unselect(contactBareJid);
	    chatBoxElm.hide();
	} else {
	    // Hide all other chatboxes
	    $.each(chatBoxesElm.filter('[bareJid!=' + contactBareJid + ']'), function() {
		    BeeChat.UI.ScrollBoxes.unselect($(this).attr('bareJid'));
		    $(this).hide();
		});
	    // Add selected scrollbox style
	    BeeChat.UI.ScrollBoxes.select(contactBareJid);
	    // Remove UnreadCountBox
	    BeeChat.UI.UnreadCountBox.remove(contactBareJid);
	    // Position the chatbox
	    var pos = scrollBoxElm.position().left - (chatBoxElm.width() - scrollBoxElm.width()) + 24;
	    chatBoxElm.show().css({'left': pos});
	    // Scroll down the content of the chatbox
	    chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')});
	    // Focus textarea
	    chatBoxElm.children().filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + ']').find('textarea').focus();
	}
    },

    /** Function: onTypingMessage
     *
     */
    onTypingMessage: function(e)
    {
	var keyCode = (e.keyCode) ? e.keyCode : e.which;
	var contactBareJid = $(this).attr('bareJid');

	if (keyCode == 13 && $(this).val() != '') {
	    g_beechat_user.sendChatMessage(contactBareJid, jQuery.trim($(this).val()));
	    BeeChat.UI.ChatBoxes.update(contactBareJid, BeeChat.UI.Utils.truncateString(BeeChat.UI.Resources.Strings.ChatMessages.SELF, 24), $(this).val());
	    clearTimeout(BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid]);
	    BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid] = null;
	} else {
	    var nowTime = new Date().getTime();

	    if (BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] == null || BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] + 2000 < nowTime) {
		BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] = nowTime;
		g_beechat_user.sendChatStateMessage(contactBareJid, BeeChat.Message.ChatStates.COMPOSING);
	    }

	    clearTimeout(BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid]);
	    BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid] = setTimeout('g_beechat_user.sendChatStateMessage(\'' + contactBareJid + '\', BeeChat.Message.ChatStates.PAUSED)', 2000);

	    var chatBoxTextAreaElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + ']').find('textarea');
	    chatBoxTextAreaElm.attr({scrollTop: chatBoxTextAreaElm.attr('scrollHeight')});
	}
    },

    /** Function: update
     *
     */
    update: function(contactBareJid, fromName, msg)
    {
	var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid);

	if (chatBoxElm.length == 0) {
	    BeeChat.UI.ScrollBoxes.add(contactBareJid);
	    chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid);
	}

	var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']');

	chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').remove();

	var chatBoxLastMessageElm = $(chatBoxContentElm).find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE + ']').filter(':last');

	if (chatBoxLastMessageElm && chatBoxLastMessageElm.find('span').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_SENDER + ']').text() == fromName) {
	    chatBoxLastMessageElm.append('<p>' + BeeChat.UI.Utils.getPrintableChatMessage(msg) + '</p>');
	} else {
	    chatBoxContentElm.append($('<div></div>')
				     .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE)
				     .append($('<span></span>')
					     .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_SENDER)
					     .text(fromName))
				     .append($('<span></span>')
					     .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_DATE)
					     .text(BeeChat.UI.Utils.getNowFormattedTime()))
				     .append('<p>' + BeeChat.UI.Utils.getPrintableChatMessage(msg) + '</p>'));
	}

	chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')});

	var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES);
	var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid);

	if (BeeChat.UI.ScrollBoxes.isInitialized == false) {
	    scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm));
	}

	if (chatBoxElm.is(':hidden')) {
	    BeeChat.UI.UnreadCountBox.update(contactBareJid);
//	    if (BeeChat.UI.HAS_FOCUS)
//		document.getElementById(BeeChat.UI.Resources.Sounds.NEW_MESSAGE).Play();
	}

//	if (!BeeChat.UI.HAS_FOCUS)
//	    document.getElementById(BeeChat.UI.Resources.Sounds.NEW_MESSAGE).Play();
    },

    /** Function: updateChatState
     *
     */
    updateChatState: function(contactBareJid, msg)
    {
	var chatBoxContentElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[bareJid=' + contactBareJid + ']');

	$(msg).children().each(function() {
		if (this.tagName == BeeChat.Message.ChatStates.COMPOSING) {
		    if (chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').length == 0) {
			$('<p></p>')
			    .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.STATE)
			    .html(BeeChat.UI.Utils.getContactName(contactBareJid) + BeeChat.UI.Resources.Strings.ChatMessages.COMPOSING + "</br />")
			    .appendTo(chatBoxContentElm);
		    }
		} else if (this.tagName == BeeChat.Message.ChatStates.PAUSED) {
		    chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').remove();
		}
	    });
	chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')});
    },

    /** Function: remove
     *
     */
    remove: function(contactBareJid)
    {
	BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).remove();
	BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).remove();
    },

    /** Function: show
     *
     */
    show: function(contactBareJid)
    {
	BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).show();
    },

    /** Function: hide
     *
     */
    hide: function(contactBareJid)
    {
	BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).hide();
    },

    /** Function: getChatBoxElm
     *
     */
    getChatBoxElm: function(contactBareJid)
    {
	return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().filter('[bareJid=' + contactBareJid + ']');
    }
};

BeeChat.UI.UnreadCountBox = {
    /** Function: add
     *
     */
    add: function(contactBareJid)
    {
	BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid)
	.append($('<span></span>')
		.attr('class', BeeChat.UI.Resources.StyleClasses.UNREAD_COUNT));
    },

    /** Function: remove
     *
     */
    remove: function(contactBareJid)
    {
	BeeChat.UI.UnreadCountBox.getElm(contactBareJid).remove();
    },

    /** Function: update
     *
     */
    update: function(contactBareJid)
    {
	if (arguments.length > 1 && !arguments[1])
	    return;

	var unreadCountBoxElm = BeeChat.UI.UnreadCountBox.getElm(contactBareJid);
	if (unreadCountBoxElm.length == 0) {
	    BeeChat.UI.UnreadCountBox.add(contactBareJid);
	    unreadCountBoxElm = BeeChat.UI.UnreadCountBox.getElm(contactBareJid);
	}
	if (arguments.length == 1) {
	    var unreadCount = unreadCountBoxElm.text();
	    unreadCountBoxElm.text(++unreadCount);
	} else
	    unreadCountBoxElm.text(arguments[1]);
    },

    /** Function: getElm
     *
     */
    getElm: function(contactBareJid)
    {
	return BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).find('span').filter('[class=' + BeeChat.UI.Resources.StyleClasses.UNREAD_COUNT +' ]');
    }
};

/** Class: BeeChat.UI.Utils
 *  An object container for all UI utilities functions
 *
 */
BeeChat.UI.Utils = {
    /** Function: getTruncatedContactName
     *
     */
    getTruncatedContactName: function(bareJid)
    {
	return (BeeChat.UI.Utils.truncateString(BeeChat.UI.Utils.getContactName(bareJid), (arguments.length == 2) ? arguments[1] : 21));
    },

    /** Function: getTruncatedContactStatus
     *
     */
    getTruncatedContactStatus: function(contactStatus)
    {
	return (BeeChat.UI.Utils.truncateString(contactStatus, (arguments.length == 2 ? arguments[1] : 50)));
    },

    /** Function: getContactName
     *
     */
    getContactName: function(bareJid)
    {
	var contactName = bareJid;

	if (g_beechat_roster_items != null && g_beechat_roster_items[bareJid])
	    contactName = g_beechat_roster_items[bareJid].name;
	// no contact name so we show bareJid
	if (!contactName || contactName == '')
		contactName = bareJid;

	return (contactName);
    },

    /** Function: getPrintableChatMessage
     *
     */
    getPrintableChatMessage: function(msg)
    {
    	var val = new String;
		val = $('<div>' + msg + '</div>');
		msg = val.text();
		
		msg = jQuery.trim(msg);
		msg = BeeChat.UI.Utils.replaceLinks(msg);
		msg = BeeChat.UI.Utils.replaceSmileys(msg);

		return msg;
    },

    /** Function: getNowFormattedTime
     *
     */
    getNowFormattedTime: function()
    {
	var date = new Date();

	var hours = date.getHours();
	var minutes = date.getMinutes();
	var seconds = date.getSeconds();

	if (hours < 10)
	    hours = '0' + hours;
	if (minutes < 10)
	    minutes = '0' + minutes;
	if (seconds < 10)
	    seconds = '0' + seconds;
	return (hours + ':' + minutes + ':' + seconds);
    },


    /** Function: replaceSmileys
     *  Replace smileys founded in a string to beautiful icons :)
     *
     *  Parameters:
     *    (String) str - The string containing smileys
     *
     */
    replaceSmileys: function(str)
    {
	str = str.replace(/(;\))/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_WINK + '" />');
	str = str.replace(/(:\))/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_SMILE + '" />');
	str = str.replace(/(:\()/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_UNHAPPY + '" />');
	str = str.replace(/(:D)/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_GRIN + '" />');
	str = str.replace(/(:o)/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_SURPRISED + '" />');
	str = str.replace(/(xD)/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_EVILGRIN + '" />');
	str = str.replace(/(:p)/gi, '<img src="' + BeeChat.UI.Resources.Paths.ICONS + BeeChat.UI.Resources.Emoticons.FILENAME_TONGUE + '" />');

	return (str);
    },

    /** Function: replaceLinks
     *  Transform links founded in a string to clickable links
     *
     *  Parameters:
     *    (String) str - The string where will be replaced links
     */
    replaceLinks: function(str)
    {
	var xpr =
	/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;

	return (str.replace(xpr, '<a href="$1" target="_blank">$1</a>'));
    },

    /** Function: truncateString
     *  Truncate a string at a specified length
     *
     *  Parameters:
     *    (String) str - The string to truncate
     *    (int) len - The maximum length of str
     */
    truncateString: function(str, len)
    {
	if (str != null && str.length > len)
	    return ((str.substr(0, len) + '...'));
	return (str);
    }
};


/** Executed when the DOM is ready
 *
 */
function init_beechat(ts, token) {
	if (typeof document.body.style.maxHeight === "undefined") { // IE6
	    return;
	}

	BeeChat.UI.initialize(ts, token);
}

/** Window resizing
 *
 */
$(window).resize(function() {
	if (typeof document.body.style.maxHeight === "undefined") { // IE6
	    return;
	}

	$('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().each(function() {
		var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm($(this).attr('bareJid'));
		var pos = scrollBoxElm.position().left - ($(this).width() - scrollBoxElm.width()) + 24;

		$(this).css({'left': pos});
	    });
});


/** Executed when the page is unloaded
 *
 */
$(window).unload(function() {
	if (typeof document.body.style.maxHeight === "undefined") { // IE6
	    return;
	}

	if (!$('#beechat').length)
		return;

	if (g_beechat_user != null) {
	    g_beechat_user.requestSessionPause();
	    BeeChat.UI.saveState();
	}
	BeeChat.UI.saveConnection();
    });


/** Check whether the BeeChat tab is active or not
 *
 */
$(window).bind('blur', function() {
	BeeChat.UI.HAS_FOCUS = false;
    });

$(window).bind('focus', function() {
	BeeChat.UI.HAS_FOCUS = true;
    });	function addToMediaList(medialist, title, code, type)
	{
		var mediacount = parseInt(mediacountinput.val());
		var formatedcode = '<li class="ui-state-default">';
		formatedcode += '<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>'
		formatedcode += '<div class="mod"><div class="hd"><span>' + title + '</span><a class="delete" href="#">Supprimer</a></div>';
		formatedcode += '<div class="bd">' + code;
		formatedcode += '<textarea name="embed_' + mediacount + '">' + code + '</textarea>';
		formatedcode += '<input type="hidden" class="count" name="count_' + mediacount + '" value="' + mediacount + '" />';
		formatedcode += '<input type="hidden" name="type_' + mediacount + '" value="' + type + '" />';
		formatedcode += '</div></div></li>';
		medialist.append(formatedcode);
		mediacountinput.val(mediacount + 1);
	}
	
	function ajax_file_upload_complete(evt, queueID, fileObj, response, data, ts, token)
	{
		var res = eval('(' + response + ')');
		if (res['success'])
		{
			$.post('http://www.beebac.com/action/file/move', {
					filename: fileObj.name,
					access_id: 2,
					__elgg_token:token,
					__elgg_ts:ts,
					ajax:1
				},
				function (data) {
					if (data['success'])
					{
						$.jGrowl(data['message'], { theme: 'success' });
						insert_file(data['filetitle'], data['fileurl'], data['mime'], data['embed'])
					}	
					else
						$.jGrowl(data['message'], { life: 50000, theme: 'error' }); 
				}, 'json');
		}	
		else
			$.jGrowl(res['message'], { life: 50000, theme: 'error' });
		return true;	
	}
	
	function insert_file(filetitle, fileurl, mime, embed)
	{
		var medialist = $("#publication ul.sortable");
		
		if (embed)
			addToMediaList(medialist, 'Document', embed, 'doc');
		else
		{
			if (mime && mime.substr(0, 5) == 'image')
			{
				var html = '<img title="' + filetitle + '" src="' + fileurl + '" />';
			}
			else
			{
				var html = '<a href="' + fileurl + '">' +  filetitle + '</a>';
			}
			if(window.tinyMCE)
				window.tinyMCE.execCommand("mceInsertContent",true,html);
		}
	}$(window).load(function () {
	
	$('form.featuredform a.featuredaction').bind('click', function () {
	
		var form = $(this).parent();
		
		$.post(form.attr('action'), {
		
			__elgg_token:form.find('input[name=__elgg_token]').val(),
			__elgg_ts:form.find('input[name=__elgg_ts]').val(),
			guid:form.find('input[name=guid]').val(),
			ajax:1
	
		}, function (data) {
		
			if (data['success'] == true)
			{
				if (data['type'] == 'featured')
				{
					form.attr('action', 'http://www.beebac.com/action/featuredcontent/unfeatured');
					form.find('a.featuredaction').html('Ne plus mettre en avant');
				}
				else
				{
					form.attr('action', 'http://www.beebac.com/action/featuredcontent/featured');
					form.find('a.featuredaction').html('Mettre en avant');
				}
				$.jGrowl(data['message'], { theme: 'success' });
			}
			else
	    		$.jGrowl(data['message'], { life: 50000, theme: 'error' }); 
		
		}, 'json');
		return false;
	});
});	(function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0)
$('<div id="jGrowl"></div>').addClass($.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',$.extend(new $.fn.jGrowl(),{notifications:[],element:null,interval:null}));$(this).data('jGrowl.instance').startup(this);}
if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',corners:'10px',check:250,life:3000,speed:'normal',easing:'swing',closer:true,closeTemplate:'&times;',closerTemplate:'<div>[ Tout fermer ]</div>',log:function(e,m,o){},beforeOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);this.notifications.push({message:message,options:o});o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('<div class="jGrowl-notification ui-state-highlight ui-corner-all'+
((o.group!=undefined&&o.group!='')?' '+o.group:'')+'">'+'<div class="close">'+o.closeTemplate+'</div>'+'<div class="header">'+o.header+'</div>'+'<div class="message">'+message+'</div></div>').data("jGrowl",o).addClass(o.theme).children('div.close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();$(notification).bind("mouseover.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",true);}).bind("mouseout.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",false);}).bind('jGrowl.beforeOpen',function(){if(o.beforeOpen.apply(notification,[notification,message,o,self.element])!=false){$(this).trigger('jGrowl.open');}}).bind('jGrowl.open',function(){if(o.open.apply(notification,[notification,message,o,self.element])!=false){if(o.glue=='after'){$('div.jGrowl-notification:last',self.element).after(notification);}else{$('div.jGrowl-notification:first',self.element).before(notification);}
$(this).animate(o.animateOpen,o.speed,o.easing,function(){if($.browser.msie&&(parseInt($(this).css('opacity'),10)===1||parseInt($(this).css('opacity'),10)===0))
this.style.removeAttribute('filter');$(this).data("jGrowl").created=new Date();});}}).bind('jGrowl.beforeClose',function(){if(o.beforeClose.apply(notification,[notification,message,o,self.element])!=false)
$(this).trigger('jGrowl.close');}).bind('jGrowl.close',function(){$(this).data('jGrowl.pause',true);$(this).animate(o.animateClose,o.speed,o.easing,function(){$(this).remove();var close=o.close.apply(notification,[notification,message,o,self.element]);if($.isFunction(close))
close.apply(notification,[notification,message,o,self.element]);});}).trigger('jGrowl.beforeOpen');if($.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',self.element).size()>1&&$('div.jGrowl-closer',self.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer ui-state-highlight ui-corner-all').addClass(this.defaults.theme).appendTo(self.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().children('div.close').trigger("click.jGrowl");if($.isFunction(self.defaults.closer)){self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);}});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+$(this).data("jGrowl").life)<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl.pause")==undefined||$(this).data("jGrowl.pause")!=true)){$(this).trigger('jGrowl.beforeClose');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()<this.defaults.pool))
this.render(this.notifications.shift());if($(this.element).find('div.jGrowl-notification:parent').size()<2){$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){$(this).remove();});}},startup:function(e){this.element=$(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');this.interval=setInterval(function(){$(e).data('jGrowl.instance').update();},this.defaults.check);if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"]){$(this.element).addClass('ie6');}},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);},close:function(){$(this.element).find('div.jGrowl-notification').each(function(){$(this).trigger('jGrowl.beforeClose');});}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery);$(window).load(function () {
	
	$('form.likeform a.likeaction').live('click', function () {
	
		var form = $(this).parent();
		var guid = form.find('input[name=guid]').val();
		
		$.post(form.attr('action'), {
		
			__elgg_token:form.find('input[name=__elgg_token]').val(),
			__elgg_ts:form.find('input[name=__elgg_ts]').val(),
			guid:guid,
			text:form.find('input[name=text]').val(),
			ajax:1
	
		}, function (data) {
		
			if (data['success'] == true)
			{
				if (data['type'] == 'like')
				{
					form.attr('action', 'http://www.beebac.com/action/likecontent/unlike');
					form.find('a.likeaction').html(data['textUnlike']);
					form.addClass('selected');
					form.trigger('likesuccess', [guid]);
				}
				else
				{
					form.attr('action', 'http://www.beebac.com/action/likecontent/like');
					form.find('a.likeaction').html(data['textLike']);
					form.removeClass('selected');
					form.trigger('unlikesuccess', [guid]);
				}
				form.parent().parent().find('div.river_comments_likecount').html(data['likecount']);
				form.parent().parent().find('div.river_comments').fadeIn().removeClass('hide');
				//$.jGrowl(data['message'], { theme: 'success' });
			}
			else
				$.jGrowl(data['message'], { life: 50000, theme: 'error' }); 
		
		}, 'json');
		return false;
	});
});

function likecallback(guid) {
	$('#likestat div.bd').load('http://www.beebac.com/mod/likecontent/likestat.php?guid=' + guid);
}var river_offset = 20;
var river_contentype = "all";
var river_subject = 'mine';
var river_subjectfriend = true;
var river_container = 0;

$(window).load(function () {

	$('div.river_item_list a.river_item_comment_action').live('click',
	function () {
		var comment = $(this).parent().parent().find('.river_comments');
		comment.fadeIn();
		return false;
	});
	
	$('div.river_item_list a.river_item_comment_seemore').live('click',
	function () {
		var comment = $(this).parent().find('span.seemore');
		var shortdesc = $(this).parent().find('span.shortdescription');
		$(this).hide();
		shortdesc.hide();
		comment.fadeIn();
		return false;
	});
	
	$('div.river_item_list a.river_item_comment_showall').live('click',
	function () {
		var comment = $(this).parent().parent().find('ul li');
		$(this).hide();
		comment.fadeIn();
		return false;
	});	
	
	$('.river_comments form textarea.comment').live('click', function () {
		$(this).parent().find('input[type=submit]').show();
	});
	
	$('.river_comments form').live('submit', function () {
		var form = $(this);
		var rand = Math.floor(Math.random()*101);
		commenttxt = form.find('textarea[name=generic_comment]');
		if (commenttxt.val())
		{
			form.find('input[type=submit]').hide();
			form.find('div.content').append('<span id="submit_loader' + rand + '" class="submit_loader">Chargement</span>')
			$.post(form.attr('action'), {
				__elgg_token: form.find('input[name=__elgg_token]').val(),
				__elgg_ts: form.find('input[name=__elgg_ts]').val(),
				generic_comment: commenttxt.val(),
				entity_guid:form.find('input[name=entity_guid]').val(),
				ajax:1
			}, function (data) {
				if (data['success'])
				{
					var comment = '<li id="comment' + data['comment_id'] + '">'
					comment += data['owner_icon'];
					comment += '<div class="content">';
					comment += '<a href="' + data['owner_url'] + '">' + data['owner_name'] + '</a> ';
					comment += data['comment_text'];
					comment += '<span class="river_item_comment_time">' + data['comment_time_created'] + '</span>';
					comment += '</div></li>';
					$('#submit_loader' + rand).remove();
					form.parent().find('ul').append(comment);
					commenttxt.attr('value', '');
					$.jGrowl(data['message'], { theme: 'success' });
				}
				else
					$.jGrowl(data['message'], { life: 50000, theme: 'error' }); 
				form.find('input[type=submit]').show();
			}, 'json');
		}				
		return false;	
	});
	
	set_dynamique_pagination();
});	

function set_dynamique_pagination()
{
	if ($('div.river_pagination a.back').length)
	{
		$('div.river_pagination a.back').html("Afficher plus d'actualités");
		$('div.river_pagination a.back').live('click', function () {
			var riverpagination = $(this).parent().parent();
			$.getJSON("http://www.beebac.com/action/river/getmorefeed?__elgg_ts=1283803131&__elgg_token=be6e7eb2a36b07a3284c7a25c55d3d9e",
						{ offset: river_offset,
						  content: river_contentype,
						  subject: river_subject,
						  subject_friend: river_subjectfriend,
						  container: river_container
						}, function (data) {
					
					if (data['html'])
					{
						riverpagination.before(data['html']);	
						river_offset = data['offset'];
					}
					else
						riverpagination.hide();
			});
			
			return false;
		});
	}
}/*
Script: TextboxList.js
	Displays a textbox as a combination of boxes an inputs (eg: facebook tokenizer)

	Authors:
		Guillermo Rauch
		
	Note:
		TextboxList is not priceless for commercial use. See <http://devthought.com/projects/jquery/textboxlist/>. 
		Purchase to remove this message.
*/

(function($){
	
$.TextboxList = function(element, _options){
	
	var original, container, list, current, focused = false, index = [], blurtimer, events = {};
	var options = $.extend(true, {
    prefix: 'textboxlist',
    max: null,
		unique: false,
		uniqueInsensitive: true,
    endEditableBit: true,
		startEditableBit: true,
		hideEditableBits: true,
    inBetweenEditableBits: true,
		keys: {previous: 37, next: 39},
		bitsOptions: {editable: {}, box: {}},
    plugins: {},
		// tip: you can change encode/decode with JSON.stringify and JSON.parse
		encode: function(o){ 
			return $.grep($.map(o, function(v){		
				v = (chk(v[0]) ? v[0] : v[1]);
				return chk(v) ? v.toString().replace(/,/, '') : null;
			}), function(o){ return o != undefined; }).join(','); 
		},
		decode: function(o){ return o.split(','); }
  }, _options);
	
	element = $(element);
	
	var self = this;
	var init = function(){		
		original = element.css('display', 'none').attr('autocomplete', 'off').focus(focusLast);
		container = $('<div class="'+options.prefix+'" />')
			.insertAfter(element)
			.click(function(e){ 
				if ((e.target == list.get(0) || e.target == container.get(0)) && (!focused || (current && current.toElement().get(0) != list.find(':last-child').get(0)))) focusLast(); 			
			});			
		list = $('<ul class="'+ options.prefix +'-bits" />').appendTo(container);
		for (var name in options.plugins) enablePlugin(name, options.plugins[name]);		
		afterInit();
	};
	
	var enablePlugin = function(name, options){
		self.plugins[name] = new $.TextboxList[camelCase(capitalize(name))](self, options);
	};
	
	var afterInit = function(){
		if (options.endEditableBit) create('editable', null, {tabIndex: original.tabIndex}).inject(list);
		addEvent('bitAdd', update, true);
		addEvent('bitRemove', update, true);
		$(document).click(function(e){
			if (!focused) return;
			if (e.target.className.indexOf(options.prefix) != -1){				
				if (e.target == $(container).get(0)) return;				
				var parent = $(e.target).parents('div.' + options.prefix);
				if (parent.get(0) == container.get(0)) return;
			}
			blur();
		}).keydown(function(ev){
			if (!focused || !current) return;
			var caret = current.is('editable') ? current.getCaret() : null;
			var value = current.getValue()[1];
			var special = !!$.map(['shift', 'alt', 'meta', 'ctrl'], function(e){ return ev[e]; }).length;
			var custom = special || (current.is('editable') && current.isSelected());
			var evStop = function(){ ev.stopPropagation(); ev.preventDefault(); };
			switch (ev.which){
				case 8:
					if (current.is('box')){ 
						evStop();
						return current.remove(); 
					}
				case options.keys.previous:
					if (current.is('box') || ((caret == 0 || !value.length) && !custom)){
						evStop();
						focusRelative('prev');
					}
					break;
				case 46:
					if (current.is('box')){ 
						evStop();
						return current.remove(); 
					}
				case options.keys.next: 
					if (current.is('box') || (caret == value.length && !custom)){
						evStop();
						focusRelative('next');
					}
			}
		});
		setValues(options.decode(original.val()));
	};
	
	var create = function(klass, value, opt){
		if (klass == 'box'){
			if (chk(options.max) && list.children('.' + options.prefix + '-bit-box').length + 1 > options.max) return false;
			if (options.unique && $.inArray(uniqueValue(value), index) != -1) return false;		
		}		
		return new $.TextboxListBit(klass, value, self, $.extend(true, options.bitsOptions[klass], opt));
	};
	
	var uniqueValue = function(value){
		return chk(value[0]) ? value[0] : (options.uniqueInsensitive ? value[1].toLowerCase() : value[1]);
	}
	
	var add = function(plain, id, html, afterEl){
		var b = create('box', [id, plain, html]);
		if (b){
			if (!afterEl || !afterEl.length) afterEl = list.find('.' + options.prefix + '-bit-box').filter(':last');
			b.inject(afterEl.length ? afterEl : list, afterEl.length ? 'after' : 'top');
		} 
		return self;
	};
	
	var focusRelative = function(dir, to){
		var el = getBit(to && $(to).length ? to : current).toElement();
		var b = getBit(el[dir]());
		if (b) b.focus();
		return self;
	};
	
	var focusLast = function(){
		var lastElement = list.children().filter(':last');
		if (lastElement) getBit(lastElement).focus();
		return self;
	};
	
	var blur = function(){	
		if (! focused) return self;
		if (current) current.blur();
		focused = false;
		return fireEvent('blur');
	};
	
	var getBit = function(obj){				
		return (obj.type && (obj.type == 'editable' || obj.type == 'box')) ? obj : $(obj).data('textboxlist:bit');
	};
	
	var getValues = function(){
		var values = [];
		list.children().each(function(){
			var bit = getBit(this);
			if (!bit.is('editable')) values.push(bit.getValue());
		});
		return values;
	};
	
	var setValues = function(values){
		if (!values) return;
		$.each(values, function(i, v){
			if (v) add.apply(self, $.isArray(v) ? [v[1], v[0], v[2]] : [v]);
		});		
	};
	
	var update = function(){
		original.val(options.encode(getValues()));
	};
	
	var addEvent = function(type, fn){
		if (events[type] == undefined) events[type] = [];
		var exists = false;
		$.each(events[type], function(f){
			if (f === fn){
				exists = true;
				return;
			};
		});
		if (!exists) events[type].push(fn);
		return self;
	};
	
	var fireEvent = function(type, args, delay){
		if (!events || !events[type]) return self;
		$.each(events[type], function(i, fn){		
			(function(){
				args = (args != undefined) ? splat(args) : Array.prototype.slice.call(arguments);
				var returns = function(){
					return fn.apply(self || null, args);
				};
				if (delay) return setTimeout(returns, delay);
				return returns();
			})();
		});
		return self;
	};
	
	var removeEvent = function(type, fn){
		if (events[type]){
			for (var i = events[type].length; i--; i){
				if (events[type][i] === fn) events[type].splice(i, 1);
			}
		} 
		return self;
	};
	
	var isDuplicate = function(v){
		return $.inArray(uniqueValue(v), index);
	};
	
	this.onFocus = function(bit){
		if (current) current.blur();
		clearTimeout(blurtimer);
		current = bit;
		container.addClass(options.prefix + '-focus');		
		if (!focused){
			focused = true;
			fireEvent('focus', bit);
		}
	};
	
	this.onAdd = function(bit){
		if (options.unique && bit.is('box')) index.push(uniqueValue(bit.getValue()));
		if (bit.is('box')){
			var prior = getBit(bit.toElement().prev());
			if ((prior && prior.is('box') && options.inBetweenEditableBits) || (!prior && options.startEditableBit)){				
				var priorEl = prior && prior.toElement().length ? prior.toElement() : false;
				var b = create('editable').inject(priorEl || list, priorEl ? 'after' : 'top');
				if (options.hideEditableBits) b.hide();
			}
		}
	};
	
	this.onRemove = function(bit){
		if (!focused) return;
		if (options.unique && bit.is('box')){
			var i = isDuplicate(bit.getValue());
			if (i != -1) index = index.splice(i + 1, 1);
		} 
		var prior = getBit(bit.toElement().prev());
		if (prior && prior.is('editable')) prior.remove();
		focusRelative('next', bit);
	};
	
	this.onBlur = function(bit, all){
		current = null;
		container.removeClass(options.prefix + '-focus');		
		blurtimer = setTimeout(blur, all ? 0 : 200);
	};
	
	this.setOptions = function(opt){
		options = $.extend(true, options, opt);
	};
	
	this.getOptions = function(){
		return options;
	};
	
	this.getContainer = function(){
		return container;
	};
	
	this.isDuplicate = isDuplicate;
	this.addEvent = addEvent;
	this.removeEvent = removeEvent;
	this.fireEvent = fireEvent;
	this.create = create;
	this.add = add;
	this.getValues = getValues;
	this.plugins = [];
	init();
};

$.TextboxListBit = function(type, value, textboxlist, _options){
	
	var element, bit, prefix, typeprefix, close, hidden, focused = false, name = capitalize(type); 
	var options = $.extend(true, type == 'box' ? {
		deleteButton: true
  } : {
		tabIndex: null,
		growing: true,
		growingOptions: {},
		stopEnter: true,
		addOnBlur: false,
		addKeys: [13]
	}, _options);
	
	this.type = type;
	this.value = value;
	
	var self = this;
	var init = function(){
		prefix = textboxlist.getOptions().prefix + '-bit';
		typeprefix = prefix + '-' + type;
		bit = $('<li />').addClass(prefix).addClass(typeprefix)
			.data('textboxlist:bit', self)
			.hover(function(){ 
				bit.addClass(prefix + '-hover').addClass(typeprefix + '-hover'); 
			}, function(){
				bit.removeClass(prefix + '-hover').removeClass(typeprefix + '-hover'); 
			});
		if (type == 'box'){
			bit.html(chk(self.value[2]) ? self.value[2] : self.value[1]).click(focus);
			if (options.deleteButton){
				bit.addClass(typeprefix + '-deletable');
				close = $('<a href="#" class="'+ typeprefix +'-deletebutton" />').click(remove).appendTo(bit);
			}
			bit.children().click(function(e){ e.stopPropagation(); e.preventDefault(); });
		} else {
			element = $('<input type="text" class="'+ typeprefix +'-input" autocomplete="off" />').val(self.value ? self.value[1] : '').appendTo(bit);
			if (chk(options.tabIndex)) element.tabIndex = options.tabIndex;
			if (options.growing) new $.GrowingInput(element, options.growingOptions);		
			element.focus(function(){ focus(true); }).blur(function(){
				blur(true);
				if (options.addOnBlur) toBox(); 
			});				
			if (options.addKeys || options.stopEnter){
				element.keydown(function(ev){
					if (!focused) return;
					var evStop = function(){ ev.stopPropagation(); ev.preventDefault(); };
					if (options.stopEnter && ev.which === 13) evStop();
					if ($.inArray(ev.which, splat(options.addKeys)) != -1){
						evStop();
						toBox();
					}
				});
			}
		}
	};
	
	var inject = function(el, where){
		switch(where || 'bottom'){
			case 'top': bit.prependTo(el); break;
			case 'bottom': bit.appendTo(el); break;
			case 'before': bit.insertBefore(el); break;			
			case 'after': bit.insertAfter(el); break;						
		}
		textboxlist.onAdd(self);	
		return fireBitEvent('add');
	};
	
	var focus = function(noReal){
		if (focused) return self;
		show();
		focused = true;
		textboxlist.onFocus(self);
		bit.addClass(prefix + '-focus').addClass(prefix + '-' + type + '-focus');
		fireBitEvent('focus');		
		if (type == 'editable' && !noReal) element.focus();
		return self;
	};
	
	var blur = function(noReal){
		if (!focused) return self;
		focused = false;
		textboxlist.onBlur(self);
		bit.removeClass(prefix + '-focus').removeClass(prefix + '-' + type + '-focus');
		fireBitEvent('blur');
		if (type == 'editable'){
			if (!noReal) element.blur();
			if (hidden && !element.val().length) hide();
		}
		return self;
	};
	
	var remove = function(){
		blur();		
		textboxlist.onRemove(self);
		bit.remove();
		return fireBitEvent('remove');
	};
	
	var show = function(){
		bit.css('display', 'block');
		return self;
	};
	
	var hide = function(){
		bit.css('display', 'none');		
		hidden = true;
		return self;
	};
	
	var fireBitEvent = function(type){
		type = capitalize(type);
		textboxlist.fireEvent('bit' + type, self).fireEvent('bit' + name + type, self);
		return self;
	};
	
  this.is = function(t){
    return type == t;
  };

	this.setValue = function(v){
		if (type == 'editable'){
			element.val(chk(v[0]) ? v[0] : v[1]);
			if (options.growing) element.data('growing').resize();
		} else value = v;
		return self;
	};

 	this.getValue = function(){
		return type == 'editable' ? [null, element.val(), null] : value;
	};
	
	if (type == 'editable'){
		this.getCaret = function(){
 			var el = element.get(0);
			if (el.createTextRange){
		    var r = document.selection.createRange().duplicate();		
		  	r.moveEnd('character', el.value.length);
		  	if (r.text === '') return el.value.length;
		  	return el.value.lastIndexOf(r.text);
		  } else return el.selectionStart;
		};

		this.getCaretEnd = function(){
 			var el = element.get(0);			
			if (el.createTextRange){
				var r = document.selection.createRange().duplicate();
				r.moveStart('character', -el.value.length);
				return r.text.length;
			} else return el.selectionEnd;
		};
		
		this.isSelected = function(){
			return focused && (self.getCaret() !== self.getCaretEnd());
		};
		
		var toBox = function(){
			var value = self.getValue();				
			var b = textboxlist.create('box', value);
			if (b){
				b.inject(bit, 'before');
				self.setValue([null, '', null]);
				return b;
			}
			return null;
		};
		
		this.toBox = toBox;
	}
	
	this.toElement = function(){
		return bit;
	};
	
	this.focus = focus;
	this.blur = blur;
	this.remove = remove;
	this.inject = inject;
	this.show = show;
	this.hide = hide;
	this.fireBitEvent = fireBitEvent;
	init();
};

var chk = function(v){ return !!(v || v === 0); };
var splat = function(a){ return $.isArray(a) ? a : [a]; };
var camelCase = function(str){ return str.replace(/-\D/g, function(match){ return match.charAt(1).toUpperCase(); }); };
var capitalize = function(str){ return str.replace(/\b[a-z]/g, function(A){ return A.toUpperCase(); }); };

$.fn.extend({
	
	textboxlist: function(options){
		return this.each(function(){
			new $.TextboxList(this, options);
		});
	}
	
});

})(jQuery);/*
Script: TextboxList.Autocomplete.js
	TextboxList Autocomplete plugin

	Authors:
		Guillermo Rauch
	
	Note:
		TextboxList is not priceless for commercial use. See <http://devthought.com/projects/jquery/textboxlist/>
		Purchase to remove this message.
*/

(function(){
	
$.TextboxList.Autocomplete = function(textboxlist, _options){
	
  var index, prefix, method, container, list, values = [], searchValues = [], results = [], placeholder = false, current, currentInput, hidetimer, doAdd, currentSearch, currentRequest;
	var options = $.extend(true, {
		minLength: 1,
		maxResults: 10,
		insensitive: true,
		highlight: true,
		highlightSelector: null,
		mouseInteraction: true,
		onlyFromValues: false,
		queryRemote: false,
    remote: {
			url: '',
			param: 'search',
			extraParams: {},
			loadPlaceholder: 'Please wait...'
    },
		method: 'standard',
		placeholder: 'Type to receive suggestions'
	}, _options);
	
	var init = function(){
		textboxlist.addEvent('bitEditableAdd', setupBit)
			.addEvent('bitEditableFocus', search)
			.addEvent('bitEditableBlur', hide)
			.setOptions({bitsOptions: {editable: {addKeys: false, stopEnter: false}}});
		if ($.browser.msie) textboxlist.setOptions({bitsOptions: {editable: {addOnBlur: false}}});
		prefix = textboxlist.getOptions().prefix + '-autocomplete';
		method = $.TextboxList.Autocomplete.Methods[options.method];
		container = $('<div class="'+ prefix +'" />').width(textboxlist.getContainer().width()).appendTo(textboxlist.getContainer());
		if (chk(options.placeholder)) placeholder = $('<div class="'+ prefix +'-placeholder" />').html(options.placeholder).appendTo(container);		
		list = $('<ul class="'+ prefix +'-results" />').appendTo(container).click(function(ev){
			ev.stopPropagation(); ev.preventDefault();
		});
	};
	
	var setupBit = function(bit){
		bit.toElement().keydown(navigate).keyup(function(){ search(); });
	};
	
	var search = function(bit){
		if (bit) currentInput = bit;
		if (!options.queryRemote && !values.length) return;
		var search = $.trim(currentInput.getValue()[1]);
		if (search.length < options.minLength) showPlaceholder();
		if (search == currentSearch) return;
		currentSearch = search;
		list.css('display', 'none');
		if (search.length < options.minLength) return;
		if (options.queryRemote){
			if (searchValues[search]){
				values = searchValues[search];
			} else {
				var data = options.remote.extraParams;
				data[options.remote.param] = search;
				if (currentRequest) currentRequest.abort();
				currentRequest = $.ajax({
					url: options.remote.url,
					data: data,
					dataType: 'json',
					success: function(r){
						searchValues[search] = r;
						values = r;
						showResults(search);
					}
				});
			}
		}
		showResults(search);
	};
	
	var showResults = function(search){
		var results = method.filter(values, search, options.insensitive, options.maxResults);
		if (textboxlist.getOptions().unique){
			results = $.grep(results, function(v){ return textboxlist.isDuplicate(v) == -1; });		
		}
		hidePlaceholder();
		if (!results.length) return;
		blur();
		list.empty().css('display', 'block');
		$.each(results, function(i, r){ addResult(r, search); });
		if (options.onlyFromValues) focusFirst();
		results = results;
	};
	
	var addResult = function(r, searched){
		var element = $('<li class="'+ prefix +'-result" />').html(r[3] ? r[3] : r[1]).data('textboxlist:auto:value', r);		
		element.appendTo(list);
		if (options.highlight) $(options.highlightSelector ? element.find(options.highlightSelector) : element).each(function(){
			if ($(this).html()) method.highlight($(this), searched, options.insensitive, prefix + '-highlight');
		});
		if (options.mouseInteraction){
			element.css('cursor', 'pointer').hover(function(){ focus(element); }).mousedown(function(ev){
				ev.stopPropagation(); 
				ev.preventDefault();
				clearTimeout(hidetimer);
				doAdd = true;
			}).mouseup(function(){
				if (doAdd){
					addCurrent();
					currentInput.focus();
					search();
					doAdd = false;
				}
			});
			if (!options.onlyFromValues) element.mouseleave(function(){ if (current && (current.get(0) == element.get(0))) blur(); });	
		}
	};
	
	var hide = function(){
		hidetimer = setTimeout(function(){
			hidePlaceholder();
			list.css('display', 'none');
			currentSearch = null;			
		}, $.browser.msie ? 150 : 0);
	};
	
	var showPlaceholder = function(){
		if (placeholder) placeholder.css('display', 'block');		
	};
	
	var hidePlaceholder = function(){
		if (placeholder) placeholder.css('display', 'none');
	};
	
	var focus = function(element){
		if (!element || !element.length) return;
		blur();
		current = element.addClass(prefix + '-result-focus');
	};
	
	var blur = function(){
		if (current && current.length){
			current.removeClass(prefix + '-result-focus');
			current = null;
		}
	};
	
	var focusFirst = function(){
		return focus(list.find(':first'));
	};
	
	var focusRelative = function(dir){
		if (!current || !current.length) return self;
		return focus(current[dir]());
	};
	
	var addCurrent = function(){
		var value = current.data('textboxlist:auto:value');
		var b = textboxlist.create('box', value.slice(0, 3));
		if (b){
			b.autoValue = value;
			if ($.isArray(index)) index.push(value);
			currentInput.setValue([null, '', null]);
			b.inject(currentInput.toElement(), 'before');
		}
		blur();
		return self;
	};
	
	var navigate = function(ev){
		var evStop = function(){ ev.stopPropagation(); ev.preventDefault(); };
		switch (ev.which){
			case 38:			
				evStop();
				(!options.onlyFromValues && current && current.get(0) === list.find(':first').get(0)) ? blur() : focusRelative('prev');
				break;
			case 40:			
				evStop();
				(current && current.length) ? focusRelative('next') : focusFirst();
				break;
			case 13:
				evStop();
				if (current && current.length) addCurrent();
				else if (!options.onlyFromValues){
					var value = currentInput.getValue();				
					var b = textboxlist.create('box', value);
					if (b){
						b.inject(currentInput.toElement(), 'before');
						currentInput.setValue([null, '', null]);
					}
				}
		}
	};
	
	this.setValues = function(v){
		values = v;
	};
	
	init();
};

$.TextboxList.Autocomplete.Methods = {
	
	standard: {
		filter: function(values, search, insensitive, max){
			var newvals = [], regexp = new RegExp('\\b' + escapeRegExp(search), insensitive ? 'i' : '');
			for (var i = 0; i < values.length; i++){
				if (newvals.length === max) break;
				if (regexp.test(values[i][1])) newvals.push(values[i]);
			}
			return newvals;
		},
		
		highlight: function(element, search, insensitive, klass){
			var regex = new RegExp('(<[^>]*>)|(\\b'+ escapeRegExp(search) +')', insensitive ? 'ig' : 'g');
			return element.html(element.html().replace(regex, function(a, b, c){
				return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + c + '</strong>'; 
			}));
		}
	}
	
};

var chk = function(v){ return !!(v || v === 0); };
var escapeRegExp = function(str){ return str.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); };

})();/*
Script: TextboxList.Autocomplete.Binary.js
	TextboxList Autocomplete binary search extension

	Authors:
		Guillermo Rauch
	
	Note:
		TextboxList is not priceless for commercial use. See <http://devthought.com/projects/jquery/textboxlist/>
		Purchase to remove this message.
*/

$.TextboxList.Autocomplete.Methods.binary = {
	filter: function(values, search, insensitive, max){
		var method = insensitive ? 'toLowerCase' : 'toString', low = 0, high = values.length - 1, lastTry;
		search = search[method]();
		while (high >= low){
			var mid = parseInt((low + high) / 2);
			var curr = values[mid][1].substr(0, search.length)[method]();			
			var result = ((search == curr) ? 0 : ((search > curr) ? 1 : -1));
			if (result < 0) { high = mid - 1; continue; }
			if (result > 0) { low = mid + 1; continue; }
			if (result === 0) break;
		}				
		if (high < low) return [];
		var newvalues = [values[mid]], checkNext = true, checkPrev = true, v1, v2;
		for (var i = 1; i <= values.length - mid; i++){			
			if (newvalues.length === max) break;
			if (checkNext) v1 = values[mid + i] ? values[mid + i][1].substr(0, search.length)[method]() : false;
			if (checkPrev) v2 = values[mid - i] ? values[mid - i][1].substr(0, search.length)[method]() : false;
			checkNext = checkPrev = false;
			if (v1 === search) { newvalues.push(values[mid + i]); checkNext = true; }
			if (v2 === search) { newvalues.unshift(values[mid - i]); checkPrev = true; }
			if (! (checkNext || checkPrev)) break;
		}
		return newvalues;
	},
	
	highlight: function(element, search, insensitive, klass){
		var regex = new RegExp('(<[^>]*>)|(\\b'+ search.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1") +')', insensitive ? 'ig' : 'g');
		return element.html(element.html().replace(regex, function(a, b, c, d){
			return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + c + '</strong>'; 
		}));
	}
};/*
Script: GrowingInput.js
	Alters the size of an input depending on its content

	License:
		MIT-style license.

	Authors:
		Guillermo Rauch
*/

(function($){

$.GrowingInput = function(element, options){
	
	var value, lastValue, calc;
	
	options = $.extend({
		min: 0,
		max: null,
		startWidth: 15,
		correction: 15
	}, options);
	
	element = $(element).data('growing', this);
	
	var self = this;
	var init = function(){
		calc = $('<span></span>').css({
			'float': 'left',
			'display': 'inline-block',
			'position': 'absolute',
			'left': -1000
		}).insertAfter(element);
		$.each(['font-size', 'font-family', 'padding-left', 'padding-top', 'padding-bottom', 
		 'padding-right', 'border-left', 'border-right', 'border-top', 'border-bottom', 
		 'word-spacing', 'letter-spacing', 'text-indent', 'text-transform'], function(i, p){				
				calc.css(p, element.css(p));
		});
		element.blur(resize).keyup(resize).keydown(resize).keypress(resize);
		resize();
	};
	
	var calculate = function(chars){
		calc.text(chars);
		var width = calc.width();
		return (width ? width : options.startWidth) + options.correction;
	};
	
	var resize = function(){
		lastValue = value;
		value = element.val();
		var retValue = value;		
		if(chk(options.min) && value.length < options.min){
			if(chk(lastValue) && (lastValue.length <= options.min)) return;
			retValue = str_pad(value, options.min, '-');
		} else if(chk(options.max) && value.length > options.max){
			if(chk(lastValue) && (lastValue.length >= options.max)) return;
			retValue = value.substr(0, options.max);
		}
		element.width(calculate(retValue));
		return self;
	};
	
	this.resize = resize;
	init();
};

var chk = function(v){ return !!(v || v === 0); };
var str_repeat = function(str, times){ return new Array(times + 1).join(str); };
var str_pad = function(self, length, str, dir){
	if (self.length >= length) return this;
	str = str || ' ';
	var pad = str_repeat(str, length - self.length).substr(0, length - self.length);
	if (!dir || dir == 'right') return self + pad;
	if (dir == 'left') return pad + self;
	return pad.substr(0, (pad.length / 2).floor()) + self + pad.substr(0, (pad.length / 2).ceil());
};

})(jQuery);