/** core class (c) trendMe.net **/
var coreAjaxClass =  {
	_AjaxDispatcher: function(method,dataType,data,action,elID,showLoading,callScript,clientCallBack,floatInfo){
		 method   = (typeof(method) != 'undefined'?method:"GET");
		 dataType = (typeof(dataType) != 'undefined'?dataType:"html");
		 data 	  = (typeof(data) != 'undefined'?data:"");
		 showLoading = (typeof(showLoading) != 'undefined'?showLoading:false);
		 callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollectorHTMLP.php");
		 floatInfo = (typeof(floatInfo) != 'undefined'?floatInfo:true);
		
		 this.showLoading(elID,showLoading);
		 //return false;
		 $.ajax({
		   type: method,
		   dataType:dataType,
		   url: SITEURLPATH+callScript,
		   data: data+"&"+Math.random()*11,
		   success: function(data, textStatus, XMLHttpRequest){
				coreAjaxClass.hideLoading(elID); // hide loading
				if (typeof(action) != 'undefined'){
					switch (action)
					{
						case 0: //update
							$('#'+elID).html(data);
						break;
						case 1: //replace
							$('#'+elID).replaceWith(data);
						break;
						case 2: //append
							$('#'+elID).append(data);
						break;	
						case 3: //before
							$('#'+elID).before(data);
						break;
						case 4: //after
							$('#'+elID).after(data);
						break;							
					}
				}
				
				if (dataType=="json" && undefined!=data && undefined!=data[0].success){
					if (data[0].success==true){
					 	if (undefined!=data[0].info && data[0].info!=''){ 
					 		if (floatInfo==true) 
					 			effectsClass.ShowInfoBoxFloat(elID,data[0].info);
					 		else
					 			$('#'+elID).html(data[0].info);						 		
					 		//console.log("effectsClass.ShowInfoBoxFloat(elID,data[0].info);");
					 	}
						
						if (undefined!=data.returnVal){ //DEPENDS ON JQUERY JSON PLUGIN
						 		if ($.isFunction($.toJSON)){
						 			if (undefined!=clientCallBack){
						 				var evalString = clientCallBack+"'"+$.toJSON(data.returnVal)+"')";
						 				eval(evalString);
						 			}	
						 		}	
						}else if (undefined!=clientCallBack){
				 			//console.log(clientCallBack);
				 			eval(clientCallBack);
						}
					}else{
                        
                        if (undefined!=data[0].error && data[0].error!='' && (undefined==data[0].callback || data[0].callback=="")){ 
						 		if (floatInfo==true) 
						 			effectsClass.ShowInfoBoxFloat(elID,data[0].error);
						 		else
						 			$('#'+elID).html(data[0].error);	
                        		//console.log("effectsClass.ShowInfoBoxFloat(elID,data[0].error);");
                        }
                    }
					if (data[0].callback){
                        eval(Base64.decode(data[0].callback));
                    }
					
				}else{
					 	if (undefined!=clientCallBack){
				 			//console.log(clientCallBack);
				 			eval(clientCallBack);
						}				
				}
				

				
		   }
		});
	},
	/** THIS FUNCTION DEPENDS ON JQUERY FORMS **/
	_AjaxFormSubmit: function(method,dataType,elID,showLoading,callScript,clientCallBack,isForm, loadingElID, floatInfo){
		method   = (typeof(method) != 'undefined'?method:"POST");
		dataType = (typeof(dataType) != 'undefined'?dataType:"json");
		data 	  = (typeof(data) != 'undefined'?data:"");
		showLoading = (typeof(showLoading) != 'undefined'?showLoading:false);
		callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollector.php");
		isForm = (typeof(isForm) != 'undefined'?isForm:false);
		loadingElID = (typeof(loadingElID) != 'undefined'?loadingElID:elID);
	  	floatInfo = (typeof(floatInfo) != 'undefined'?floatInfo:true); 
	   
	    $("#"+elID+" input:text[dValue]").each(function(n, el){
	     	if ($(el).attr("value")!="" && $(el).attr("value")==$(el).attr("dValue")){
	     		$(this).attr("value","");
	     	}
	    });
	    
		var edit_form_ajax_options = {
		     url: SITEURLPATH+callScript,
		     dataType: dataType,
		     semantic:true,
		     type: method,
		     success: function(data) {
					$('#loadingMask_'+elID).remove();
					if (dataType=="json" && undefined!=data && undefined!=data[0].success){
						if (data[0].success==true){
						 	if (undefined!=data[0].info && data[0].info!=''){ 
						 		if (floatInfo==true) 
						 			effectsClass.ShowInfoBoxFloat(loadingElID,data[0].info);
						 		else
						 			$('#'+loadingElID).html(data[0].info);
						 		
						 	}
						 	if (undefined!=data.returnVal){ //DEPENDS ON JQUERY JSON PLUGIN
						 		if ($('#'+elID+"-returnValue").size()>0){
							 		if ($.isFunction($.toJSON))
							 			$('#'+elID+"-returnValue").attr('value',$.toJSON(data.returnVal));
						 		}else{
						 			if (undefined!==clientCallBack){
						 				if ($.isFunction($.toJSON)){
						 					var evalString = clientCallBack+"'"+$.toJSON(data.returnVal)+"')";
						 					eval(evalString);
						 				}
						 			}
						 		}
						 	}
						 	if (undefined!=clientCallBack){
					 			eval(clientCallBack);
							}
						}else{
	                        if (undefined!=data[0].error && data[0].error!='' && (undefined==data[0].callback || data[0].callback=="")){ 
						 		if (floatInfo==true) 
						 			effectsClass.ShowInfoBoxFloat(loadingElID,data[0].error);
						 		else
						 			$('#'+loadingElID).html(data[0].error);	                        	
	                        }
	                    }
						if (data[0].callback){
	                        eval(Base64.decode(data[0].callback));
	                    }
					}	        
		     },
		     beforeSubmit: function(formArray, jqForm,option){
			     coreAjaxClass.showLoading(elID,showLoading);
		     }
		};
		if (isForm==true)
			$('#'+elID).ajaxForm(edit_form_ajax_options);
		else
			$('#'+elID).ajaxSubmit(edit_form_ajax_options);
	},
	updateEl: function(elID, data, callScript,clientCallBack, showLoading){
		callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollectorHTMLP.php");
		showLoading = (typeof(showLoading) != 'undefined'?showLoading:true);
		coreAjaxClass._AjaxDispatcher("GET","html",data,0,elID,showLoading,callScript,clientCallBack);
	},
	replaceEl: function(elID, data, callScript,clientCallBack, showLoading){
		callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollectorHTMLP.php");
		showLoading = (typeof(showLoading) != 'undefined'?showLoading:true);		
		coreAjaxClass._AjaxDispatcher("GET","html",data,1,elID,showLoading,callScript,clientCallBack);
	},
	appendEl: function(elID, data){
		coreAjaxClass._AjaxDispatcher("GET","html",data,2,elID,true);
	},
	addEl: function(elID, data, callScript,clientCallBack, showLoading,addType){
		callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollectorHTMLP.php");
		showLoading = (typeof(showLoading) != 'undefined'?showLoading:true);		
		addType = (typeof(addType) != 'undefined'?addType:0);
		coreAjaxClass._AjaxDispatcher("GET","html",data,addType,elID,showLoading,callScript,clientCallBack);
	},	
	callJSON: function(elID, data, clientCallBack, callScript, floatInfo){
		callScript = (typeof(callScript) != 'undefined'?callScript:"ajaxCollector.php");
		floatInfo   = (typeof(floatInfo) != 'undefined'?floatInfo:true);
		coreAjaxClass._AjaxDispatcher("POST","json",data,null,elID,true,callScript,clientCallBack,floatInfo);
	},
	callFormJSON: function(elID, clientCallBack, showLoading, loadingElID, floatInfo){
		showLoading = (typeof(showLoading) != 'undefined'?showLoading:true);
		loadingElID = (typeof(loadingElID) != 'undefined'?loadingElID:elID);
		floatInfo   = (typeof(floatInfo) != 'undefined'?floatInfo:true);
		coreAjaxClass._AjaxFormSubmit("POST","json",elID,showLoading,"ajaxCollector.php",clientCallBack,false,loadingElID,floatInfo);
	},
	showLoading: function(elID,showLoading){
			 
		if ((showLoading==true) && (typeof(elID) != 'undefined')){
		 	var width = $('#'+elID).width();
		 	var height = $('#'+elID).height();
		 	var posY=parseInt($('#'+elID).offset().top);
			var posX=parseInt($('#'+elID).offset().left);
			
			
			var loading_mask = $('#'+elID).attr('loading_mask');
			if (typeof(loading_mask) == 'undefined' || loading_mask=="") loading_mask = 'loading_gif.gif';
			
			$('#loadingMask_'+elID).remove(); //ukloni isti takav od prije
		 	var html = "";
		 	//html = "<div class='loadingMask' style='width:"+width+";height:"+height+";'>"; 
		 	html = "<div class='loadingMask' id='loadingMask_"+elID+"' style='width:"+width+"px;height:"+height+"px;top:"+posY+"px;left:"+posX+"px;'>";
		 	html=html+"<img src='"+SITEURLPATH+"images/"+loading_mask+"' class='loading'/>";
		 	html=html+"</div>";

		 	//if ($('#loadingMask_'+elID).size()>0) 
		 	$("body").append(html); 
		 }
	
	},
	hideLoading: function(elID){
		$('#loadingMask_'+elID).remove();
	},
	postForm: function (elID){
	    var elDOM = $('#'+elID);
		var callback = $(':hidden[name=callback]',elDOM).fieldValue()[0]; 
    	coreAjaxClass.callFormJSON(elID,callback);
	}
	
	
};

/** misc animate, and aux (c) trendMe.net **/
var GLOBAL_NOTE_PING_INT = null;

function setNotificationInterval(){
	GLOBAL_NOTE_PING_INT = setInterval ( "refreshNotification()", 180000 );
}

function refreshNotification(){
	//coreAjaxClass.showLoading("notificationHolder",true);
	clearInterval(GLOBAL_NOTE_PING_INT);
	coreAjaxClass.updateEl("notificationHolder",
			   "ajaxcall=getUP_Content_HTML::13&userId="+GLOBAL_UID, 
			   "ajaxCollectorHTMLP.php",
			   "$('#notificationHolder').show();setNotificationInterval();",
			   false); 	
}

function initDefaultInputValues(elID,parentEl){
	var parentElDOM = document;
	var elID2=elID;
	if (typeof(elID) == 'undefined' || elID=="") elID="input:text[dValue]";
	if (typeof(elID2) == 'undefined' || elID2=="") elID2="textarea[dValue]";
	if (typeof(parentEl) == 'undefined' || parentEl=="") 
		parentElDOM = document;
	else
		parentElDOM = $('#'+parentEl);

	$(elID,parentElDOM).blur(function(){
		var defaultValue = $(this).attr("dValue");
		
		var currentValue = $(this).attr("value");
		if (currentValue=="") $(this).attr("value",defaultValue);
	});
	
	$(elID,parentElDOM).focus(function(){
		var defaultValue = $(this).attr("dValue");
		var currentValue = $(this).attr("value");
		if (currentValue==defaultValue) $(this).attr("value","");
	});
	
	$(elID2,parentElDOM).blur(function(){
		var defaultValue = $(this).attr("dValue");
		
		var currentValue = $(this).val();
		if (currentValue=="") $(this).val(defaultValue);
		
	});
	
	$(elID2,parentElDOM).focus(function(){
		var defaultValue = $(this).attr("dValue");
		var currentValue = $(this).val();
		if (currentValue==defaultValue) $(this).val("");
		
	});
	
}

function initShareIcons(parentEl){
	if (typeof(parentEl) == 'undefined'||parentEl=="") 
		parentElDOM = document;
	else
		parentElDOM = $('#'+parentEl);
	
	$(".shareIcons",parentElDOM).hover(
		function(){
			$(this).attr("src",$(this).attr("over"));
		},
		function(){
			$(this).attr("src",$(this).attr("off"));;
		}
	);

}

var effectsClass = {
	initFlowInfoBox: function(){
		if (undefined==$('#floatInfoBox') || $('#floatInfoBox').size()<1){
			var floatInfoBoxHMTL="";
			floatInfoBoxHMTL = "<div id='floatInfoBox'></div>";
			$("body").append(floatInfoBoxHMTL);
		}
	},
	initTopInfoBox: function(){
		if (undefined==$('#topInfoBox') || $('#topInfoBox').size()<1){
			var topInfoBoxHMTL="";
			topInfoBoxHMTL = "<div id='topInfoBox'></div>";
			$("body").append(topInfoBoxHMTL);
		}
	},
	ShowInfoBoxFloat: function(elID,text,sec){
				sec   = (typeof(sec) != 'undefined'?sec:4000);
				
				effectsClass.initFlowInfoBox(); //init box
				
				$('#floatInfoBox').fadeTo(1,0);
				if ($(elID).size()>0){
					var pos=parseInt($(elID).offset().top)-20;
					var posX=parseInt($(elID).offset().left);
				}else{//try with id
					var pos=parseInt($('#'+elID).offset().top)-20;
					var posX=parseInt($('#'+elID).offset().left);			
				}
				$('#floatInfoBox').queue([]).stop().animate({ top:(pos+"px"),left:(posX+"px") },1);
				$('#floatInfoBox').css({ width:"auto",height:"auto"});
				$('#floatInfoBox').html(text);
				$('#floatInfoBox').fadeTo(1,1).show();
				if (sec!='undefined' && sec!=null)
				     $('#floatInfoBox').animate({ opacity:1 }, parseInt(sec/2)).animate({ top:"-=45px",opacity:0 }, parseInt(sec/2)).animate({ top:"0px",left:"0px"}, 1).animate({ width:"0px",height:"0px"}, 1);
				else
				     $('#floatInfoBox').animate({ opacity:1 }, 1).animate({ top:"0px",left:"0px"}, 1).animate({ width:"0px",height:"0px"}, 1);
	},
	ShowInfoBoxTop: function(title,text,duration){
		effectsClass.initTopInfoBox(); //init box
		
		if (typeof(duration)=='undefined') duration=4000;
		
		var insertHTML = "<h1 class='topInfoBoxH1'>"+title+"</h1><br />"+text;
		
		$("#topInfoBox").css("top",$(window).scrollTop()+"px").css("left",parseInt($(window).scrollLeft()-150)+parseInt(parseInt($(window).width())/2)+"px").html(insertHTML).animate( { opacity: 1 },  { queue:false, duration:1 } )
	         .fadeIn( "fast")
	         .animate( { opacity: 1  }, {queue:true, duration:duration } )
	         .fadeOut( "fast").animate({ top:"0px",left:"0px"}, 1);
	},
	/*** FANCY FLOAT **/
	initFancyFloat: function(){
		if (undefined==$('#fancyFloatBox') || $('#fancyFloatBox').size()<1){
			var floatInfoBoxHMTL="";
			floatInfoBoxHMTL = "<div id='fancyFloatBox'><div id='fancyFloatBoxInner'></div></div>";
			if (undefined==$('#contentHolder') || $('#contentHolder').size()<1)
				$("body").append(floatInfoBoxHMTL);
			else
				$("#contentHolder").append(floatInfoBoxHMTL);
		}
	},
	ShowFancyFloat: function(insertHTML, dontHideEmbeded){
		dontHideEmbeded = (typeof(dontHideEmbeded) != 'undefined'?dontHideEmbeded:false);
		if (dontHideEmbeded==false) $('object,embed').css('visibility','hidden');
		effectsClass.initFancyFloat(); //init box
		if (insertHTML!='undefined') $("#fancyFloatBox").html(insertHTML); //something is there already
		var height = $("#fancyFloatBox").height()+40; //padding
		var width = $("#fancyFloatBox").width()+40; //padding
		$("#fancyFloatBox").css("top",($(window).scrollTop()-parseInt(height/2)+parseInt(parseInt($(window).height())/2))+"px").
						 css("left",parseInt($(window).scrollLeft()-parseInt(width/2))+parseInt(parseInt($(window).width())/2)+"px").
						 animate( { opacity: 1 },  { queue:false, duration:1 } );
	},
	hideFancyFloat: function(){
		$('#fancyFloatBoxInner').empty();
		$('#fancyFloatBox').animate( { opacity: 0},  { queue:false, duration:1 } ).
							animate({ top:"0px",left:"0px"}, 1);
		$('object,embed').css('visibility','visible');
		
	},
	zoomMeInit: function(parentEl){
		
		
		if (typeof(parentEl) == 'undefined'||parentEl=="") 
			parentElDOM = document;
		else
			parentElDOM = $('#'+parentEl);
		
		$(".zoomMe",parentElDOM).hover(
				function(){
			        $(this).parent().find("img.magnify").remove();
			        var zoomMeImg = '<img src="'+SITEURLPATH+'images/share/zoom-in-icon-24.png" class="magnify" id="magnify_remove"/>';
			        $(this).after(zoomMeImg);
				    var THIS = $(this);
			        $(this).click(function(event){
				    	effectsClass.zoomMe(THIS,event);
				    	event.stopPropagation();  
				    	return false;
				    	
				    });
			        
				    $(this).parent().find("img.magnify").animate({opacity: 1}, 3000).fadeOut("fast");
				},
				function(){
					//$('#magnify_remove').remove();
				}
		);
	},
	zoomMe: function(elDOM,event){
			var elThis = $(elDOM);
			var elThisFull = $(elDOM).attr("image_full");
			var elThisThumb = $(elDOM).attr("image_thumb");
			var elThisCurr = $(elDOM).attr("src");
			var nextImgSrc=null;

			if (elThisFull == elThisCurr) 
				nextImgSrc=elThisThumb;
			else
				nextImgSrc=elThisFull;
			
			console.log(elDOM);
            var imgPreloader = new Image;
            $(imgPreloader).unbind('load').bind('load', function() {
                $(elThis).attr("src",imgPreloader.src);
            }).attr('src', nextImgSrc);
            
			event.stopPropagation(); 
			alert(nextImgSrc);
	}
};

function checkPaginationInput(el){
	var numericExpression = /^[0-9]+$/;
	var ret = true;
	var totalPageCount = parseInt($(el).attr("totalPageCount"));
	var currentPage = parseInt($(el).attr("currentPage"));
	var currentValue = $(el).attr("value")+"";

	if (currentValue.match(numericExpression)==null){ 
		$(el).attr("value",currentPage); 
		ret = false;
	}else if (parseInt($(el).attr("value"))>totalPageCount){ 
		$(el).attr("value",totalPageCount); 
		ret = false;
	}else if (parseInt($(el).attr("value"))<1){ 
		$(el).attr("value",1); 
		ret = false;
	}
	return ret;
}

CurrencyFactory = function(hasSpace, dp, dSeparator, tSeparator, symbol, rightPosition) {
    return function(n) {
		var spaceText = hasSpace?" ":"";
        dp = Math.abs(dp) + 1 ? dp : 2;
        dSeparator = dSeparator || ",";
        tSeparator = tSeparator || ".";
        symbol = symbol || "kn";
        rightPosition = rightPosition || true;
		
		if (n == 'undefined' || undefined===n || n=="" || isNaN(n)) return rightPosition?"0"+dSeparator+"00"+spaceText+symbol:symbol+spaceText+"0"+dSeparator+"00";
        var m = (/(\d+)(?:(\.\d+)|)/.exec(n + "")), x = m[1].length > 3 ? m[1].length % 3 : 0;
        var v = (n < 0? '-' : '') // preserve minus sign
        + (x ? m[1].substr(0, x) + tSeparator : "")
        + m[1].substr(x).replace(/(\d{3})(?=\d)/g, "$1" + tSeparator)
        + (dp? dSeparator + (+m[2] || 0).toFixed(dp).substr(2) : "");
        return rightPosition?v+spaceText+symbol:symbol+spaceText+v;
    };
};

PercentFormater = function(v)
{
	if (v=='') v='0';
	v = (v + '');
	v = v.replace(/\,/, '.');
	
	v = parseFloat(v);
	v = (Math.round((v-0)*100))/100;
	v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
	v = new String(v);
	return v;
	//return v.replace(/\./, ',');
};

$.fn.image = function(src, f){ 
  return this.each(function(){ 
    var i = new Image(); 
    i.src = src; 
    i.onload = f; 
    this.appendChild(i);
  }); 
};


function translateThis(cssSelector,currentLang){$(cssSelector).each(function(){var contentDOM=$(this);var content=$(this).html();google.language.translate(content,"",currentLang,function(result){if(!result.error){$(contentDOM).html(result.translation);}});});};

this.tooltip = function(parentEl, delayHide){    
    /* CONFIG */        
        xOffset = 10;
        yOffset = 20;        
    /* END CONFIG */  
        if (typeof(delayHide) == 'undefined' || delayHide=="") delayHide=false;
        	
		if (typeof(parentEl) == 'undefined' || parentEl=="") 
			parentElDOM = document;
		else
			parentElDOM = $('#'+parentEl); 
		$("#tm_tooltip").remove();
    $(".tm_tooltip",parentElDOM).hover(function(e){                                              
    	$("#tm_tooltip").remove();
    	var tooltip_title = $(this).attr("tooltip_title");
    	var tooltip_target = $(this).attr("tooltip_target");
    	this.title = ( tooltip_title!= ''?this.tooltip_title:this.title);
    	
    	if (tooltip_target != '') 
    		this.t = $('#'+tooltip_target).html();
    	else
    		this.t = this.title;

    	if (this.t=="") return false;
        
    	this.title = ""; 
        $("body").append("<div id='tm_tooltip'><div id='tm_tooltip_inner'><p>"+ this.t +"</p></div></div>");
        
        if( (e.pageX + yOffset) > (screen.width - 220) )
        {
            //console.log("ss")
            yOffset = - $("#tm_tooltip").width() - 25;
        }
        else
        {
            yOffset = 20;
        }
        
        $("#tm_tooltip")
            .css("top",(e.pageY - xOffset) + "px")
            .css("left",(e.pageX + yOffset) + "px")
            .fadeIn("fast");        
    },
    function(){
        this.title = this.t;        
        if (delayHide)
        	$("#tm_tooltip").delay(2000).fadeOut("fast");
        else
        	$("#tm_tooltip").remove();
    });
    
    $(".tm_tooltip",parentElDOM).mousemove(function(e){
        $("#tm_tooltip")
            .css("top",(e.pageY - xOffset) + "px")
            .css("left",(e.pageX + yOffset) + "px");
           //console.log(screen.width);
    });            
};

function closeWelcomeScreen(elID){
	$('#'+elID).fadeOut();
	coreAjaxClass.callJSON('contentHolder', "ajaxcall=FPAction::0");
}
function iniACFiltering(cssSelector,filterSelector, hideParent){
	 if (typeof(hideParent) == 'undefined' || hideParent=="") hideParent=false;
	$(cssSelector).keyup(function(event) {
		if (event.which == '13') {
		     event.preventDefault();
		}
		var targetEl = $(this).attr("targetEl");
		var query = $(this).val();
		$('#'+targetEl+" "+filterSelector).each(function(){
			if ($(this).text().search(new RegExp(query, "i"))<0){
				if (hideParent)
					$(this).parent().hide();
				else
					$(this).hide();
			}else{
				if (hideParent)
					$(this).parent().show();
				else
					$(this).show();
			}
		});
	});
}

function _layzLoad(elID,callBack,threshold) {
	  if (typeof(threshold) == 'undefined' || threshold=="") threshold=0;
	  var position        = $("#"+elID).offset().top;            
	  var scrollWidth        = $(window).scrollTop() + $(window).height();
	  if ( (scrollWidth+threshold) > position) {
	       $("#"+elID).attr("targetEl","");
	       eval(callBack);
	  }
}
function _layLoadBinder(selector, threshold){
	$(selector).each(function(){
		var callBack = $(this).attr("callBack");
		var targetEl = $(this).attr("targetEl");
		if (targetEl!="" && callBack!="")
		_layzLoad(targetEl,callBack, threshold);
		
	})
}
function initLazyLoad(selector, threshold){
	$(window).scroll( 
		function() { 
		_layLoadBinder(selector,threshold); 
		}
	);
};/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		
		var output = "";
		try{
			var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
			var i = 0;
	
			input = Base64._utf8_encode(input);
	
			while (i < input.length) {
	
				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 +
				this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
				this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
	
			}
		}catch(e){}
		return output;
	},

	// public method for decoding
	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, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._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);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

};


