/*
	AJAX Suggestions is developed by Robert Nyman, http://www.robertnyman.com, and it is released according to the
	Creative Commons Deed license (http://creativecommons.org/licenses/GPL/2.0/)
	For more information, please see http://www.robertnyman.com/ajax-suggestions
*/


// ---
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}
var ajaxSuggestions = {
	// Settings
	elmIdToPresentResultsIn : "search-results",
	elmIdResultsContainer : "search-result-suggestions",
	charactersBeforeSearch : 1,
	timeBeforeSuggest : 200, // In milliseconds
	sameWidthAsInputElm : true,
	doNotSubmitInsertOnly : false,
	insertCallback : null,
	offsetLeft: 0,
	offsetTop : 0,
	urlExt : "term=",
	addSearchTermToQueryString : true,
	addKeyNavigationEvents : true,
	hideResultsOnDocumentClick : true,
	enabled : true,
	itemClassName : "item",
	itemSelectedClassName : "selected",
	itemInsertValueIntoInputClassName : "choose-value",
	itemInsertValueSetFocusToInput : true,
	hideResultsWhenInsertValueIsSelected : true,
	itemSeparator : ";",
	turnAutoCompleteOff : true,
	// Object properties
	xmlHttp : null,
	elements : [],
	timer : null,
	currentElm : null,
	currentKeyEvent : null,
	suggestionsForElm : null,
	elmToPresentResultsIn : null,
	elmResultsContainer : null,
	suggestions : [],
	resultIndex : 0,
	selectedItem : -1,
	resultsAreVisible : false,
	valueAddedFromResultsListToInput : true,

	init : function () {
		this.xmlHttp = this.createXmlHttp();
		if (this.xmlHttp) {
			if (typeof document.getElementsByClassName != "function") {
				document.getElementsByClassName = this.elmByClass;
			}
			var elements1=(document.getElementsByClassName("ajax-suggestion", "input"));
			var  elements2=document.getElementsByClassName("ajax-suggestion-insert-only", "input");
			for (var i = 0; i<elements1.length; i++) {
				this.elements[this.elements.length]=elements1[i];
			}
			for (var i = 0; i<elements2.length; i++) {
				this.elements[this.elements.length]=elements2[i];
			}
			this.applyEvents();
			this.elmToPresentResultsIn = document.getElementById(this.elmIdToPresentResultsIn);
			this.elmResultsContainer = document.getElementById(this.elmIdResultsContainer);
			if (this.addKeyNavigationEvents) {
				this.addEvent(document, "keydown", this.navigateResults);
				this.addEvent(document, "keypress", this.preventDefaultForArrowKeys);
				this.addEvent(document, "keyup", this.preventDefaultForArrowKeys);
			}
			if (this.hideResultsOnDocumentClick) {
				this.addEvent(document, "click", this.clearResultsElement);
			}
		}
	},

	createXmlHttp : function () {
		this.xmlHttp = null;
		if (typeof XMLHttpRequest != "undefined") {
			this.xmlHttp = new XMLHttpRequest();
		}
		else if (typeof window.ActiveXObject != "undefined") {
			try {
				this.xmlHttp = new ActiveXObject("Msxml2.XMLHTTP.4.0");
			}
			catch(e) {
				try {
					this.xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
				}
				catch(e) {
					try {
						this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
					}
					catch(e) {
						this.xmlHttp = null;
					}
				}
			}
		}
		return this.xmlHttp;
	},

	applyEvents : function () {
		var element;
		for (var i = 0; i < this.elements.length; i++) {
			element = this.elements[i];
			if (this.turnAutoCompleteOff) {
				element.setAttribute("autocomplete", "off");
			}
			this.addEvent(element, "keyup", this.startSuggestionsTimer);
			if (this.hideResultsOnDocumentClick) {
				this.addEvent(element, "click", this.preventInputClickBubbling);
			}
		}
	},

	startSuggestionsTimer : function (evt) {
		if (!ajaxSuggestions.enabled) return;
//    alert(evt.keyCode);
		if (!/13|27|40|37|38/.test(evt.keyCode)) {
			clearTimeout(ajaxSuggestions.timer);
			ajaxSuggestions.currentElm = (/input/i.test(this.nodeName)) ? this : evt.srcElement;
			if(evt.type=='focus' && ajaxSuggestions.currentElm.value.length>0){
				return;
			}
			ajaxSuggestions.currentKeyEvent = evt.keyCode;
			ajaxSuggestions.timer = setTimeout("ajaxSuggestions.getSuggestions()", ajaxSuggestions.timeBeforeSuggest);
		}
	},

	getSuggestions : function () {
		var value = this.currentElm.value;
		if (!/13|27|38|37|40/.test(this.currentKeyEvent)) {
			var url = '';
//			var url = this.currentElm.className.replace(/.*url-([\w\/\?\.-]+).*/, "$1");
			if (!this.valueAddedFromResultsListToInput) {
				ajaxSuggestions.clearResults(true);
			}
			if (value.length > this.charactersBeforeSearch /*&& url.length > 0*/) {
				this.makeSuggestionCall(value, url);
			}
			else if (value.length < this.charactersBeforeSearch || !this.valueAddedFromResultsListToInput) {
				ajaxSuggestions.clearResults();
			}
		}
	},

	makeSuggestionCall : function (value, url) {
//		var regExpValue = new RegExp(("^" + value + "$"), "i");
		var exists = false;
		var suggestionItem;
		var url = url + ((/\?/.test(url)) ? "&" : "?") + this.urlExt + ((this.addSearchTermToQueryString) ? Base64.encode(value) : "");
		for (var i = 0; i < this.suggestions.length; i++) {
			suggestionItem = this.suggestions[i];
//			if (regExpValue.test(suggestionItem[0]) && url == suggestionItem[2]) {
			if (trim(value).toLowerCase()==suggestionItem[0] && url == suggestionItem[2]) {
				exists = true;
				this.resultIndex = i;
				this.presentResult(this.suggestions[i][1]);
				break;
			}
		}
		;
		if (!exists) {
			/*this.xmlHttp.onreadystatechange = function (){};
			this.xmlHttp.abort();
			this.currentValue = value;
			this.currentURL = url;
			this.xmlHttp.open("GET", url, true);
			this.xmlHttp.onreadystatechange = this.getResults;
			this.xmlHttp.send(null);*/
			this.createTag(url);
		}
	},
	scriptCounter : 0,
	searchBase : "",
	createTag: function (url) {
		this.headLoc = document.getElementsByTagName("head").item(0);
		this.scriptId = 'JscriptId' + ajaxSuggestions.scriptCounter++;
		this.scriptObj = document.createElement("script");
		this.scriptObj.setAttribute("type", "text/javascript");
		this.scriptObj.setAttribute("charset", "utf-8");
		this.scriptObj.setAttribute("src", this.searchBase + url + "&format=jsonp");
		this.scriptObj.setAttribute("id", this.scriptId);

		this.headLoc.appendChild(this.scriptObj);
	},

	jsonpCallback: function(jsonData) {
		//alert(jsonData.suggestions.length);
		this.resultIndex = this.suggestions.length;
		this.suggestions.push([this.currentValue, this.buildText(jsonData.suggestions), this.currentURL]);
        ///this.suggestions = jsonData.suggestions;
        try {
            var childNodes = this.headLoc.childNodes;
            for(i=0;i<childNodes.length;i++){
                if(childNodes[i]==this.scriptObj) {
                    this.headLoc.removeChild(this.scriptObj);
                    break;
                }
            }
        } catch(e) {
        }
		if (jsonData.suggestions.length > 0) {
			this.presentResult();
		} else {
			this.clearResults();
		}
	},

	buildText : function(suggest) {
		var res = "<ul>";
		for (var i = 0; i < suggest.length; i++) {
			if(this.doNotSubmitInsertOnly){
				res += '<li><a href="#" onclick="ajaxSuggestions.insertTermIntoField(' + i + ')"';
			}else {
				res += '<li><a href="#" onclick="ajaxSuggestions.submitForm(' + i + ')"';
			}
			res += 'class="item" onmouseover="ajaxSuggestions.selectByMouseOver(' + i + ')" id="suggestion' + i + '">';

			res += suggest[i];
			res += "</a></li>";
		}
		res += "</ul>";
		return res;
	},

	getResults : function () {
		if (ajaxSuggestions.xmlHttp.readyState == 4 && trim(ajaxSuggestions.xmlHttp.responseText).length > 0) {
			ajaxSuggestions.loadResults();
		} else {
			ajaxSuggestions.clearResults();
		}
	},

	loadResults : function () {
		this.resultIndex = this.suggestions.length;
		this.suggestions.push([this.currentValue, this.xmlHttp.responseText, this.currentURL]);
		this.presentResult();
	},

	presentResult : function () {
		this.elmToPresentResultsIn.innerHTML = this.suggestions[this.resultIndex][1];
		var coordinates = this.getCoordinates();
		var elm = this.elmResultsContainer.style;
		elm.left = (coordinates[0] + this.offsetLeft) + "px";
		elm.top = (coordinates[1] + this.currentElm.offsetHeight + this.offsetTop) + "px";
		if (this.sameWidthAsInputElm) {
			elm.width = this.currentElm.offsetWidth + "px";
		}
		this.applyResultEvents();
		elm.display = "block";
		this.resultsAreVisible = true;
		if (this.addKeyNavigationEvents && /38|40/.test(this.currentKeyEvent)) {
			if (!this.valueAddedFromResultsListToInput) {
				this.selectedItem = -1;
			}
			this.navigateResults(null, this.currentKeyEvent);
		}
	},

	clearResults : function (justClear) {
		if (this.elmResultsContainer && this.elmToPresentResultsIn) {
			if (!justClear) {
				this.elmResultsContainer.style.display = "none";
				this.resultsAreVisible = false;
			}
			this.elmToPresentResultsIn.innerHTML = "";
			this.selectedItem = -1;
		}
	},

	clearResultsElement : function () {
		ajaxSuggestions.clearResults();
	},

	navigateResults : function (evt, keyCode) {
		if (ajaxSuggestions.currentElm && ajaxSuggestions.elmToPresentResultsIn) {
			var event = (typeof evt != "undefined") ? evt : event;
			if (typeof ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName != "function") {
				ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName = ajaxSuggestions.elmByClass;
			}
			var results = ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName(ajaxSuggestions.itemClassName);
			var selectedItem = (!evt && keyCode == 38) ? results.length : ajaxSuggestions.selectedItem;
			var keyCode = keyCode || event.keyCode;
			var navigateUp = keyCode == 38;
			var navigateDown = keyCode == 40;
			if (results.length > 0 && (navigateUp || navigateDown)) {
				if (navigateUp) {
					if ((selectedItem - 1) >= 0) {
						selectedItem--;
					}
					else {
						selectedItem = results.length - 1;
					}
				}
				else if (navigateDown) {
					if ((selectedItem + 1) < results.length) {
						selectedItem++;
					}
					else {
						selectedItem = 0;
					}
				}
				var item;
				var classToRemove;
				for (var i = 0; i < results.length; i++) {
					item = results[i];
					classToRemove = new RegExp((ajaxSuggestions.itemSelectedClassName + "\s?"), "i");
					item.className = item.className.replace(classToRemove, "").replace(/^\s?|\s?$/g, "");
				}
				;
				ajaxSuggestions.selectedItem = selectedItem;
				var elmToFocus = ajaxSuggestions.currentElm;
				if (selectedItem > -1) {
					var currentItem = results[selectedItem];
					var currentClass = item.className;
					if (!new RegExp(ajaxSuggestions.itemSelectedClassName, "i").test(currentClass)) {
						currentItem.className = currentClass + ((currentClass.length > 0) ? " " : "") + ajaxSuggestions.itemSelectedClassName;
					}
					elmToFocus = results[selectedItem];
					for (var i = 0; i < ajaxSuggestions.elements.length; i++) {
						//            alert(isHiddenByParent(ajaxSuggestions.elements[i])+":"+ajaxSuggestions.elements[i].class);
						if (!isHiddenByParent(ajaxSuggestions.elements[i])) {
							ajaxSuggestions.elements[i].value = currentItem.innerHTML;
							try {
								ajaxSuggestions.elements[i].focus();
								break;
							}
							catch(e) {
								//              					 Just in case... :-)
							}
						}
					}
				}
//				try{
				//					elmToFocus.focus();
				//				}
				//				catch(e){
				//					 Just in case... :-)
				//				}
				if (event) {
					if (event.preventDefault) {
						event.preventDefault();
					}
					else {
						event.returnValue = false;
					}
					if (event.stopPropagation) {
						event.stopPropagation();
					}
					else {
						event.cancelBubble = true;
					}
				}
				return false;
			}
			else if (keyCode == 27) {
				ajaxSuggestions.clearResults();
				try {
					ajaxSuggestions.currentElm.focus();
				}
				catch(e) {
					// Just in case... :-)
				}
			}
		}
	},

	insertTermIntoField : function (selectedIndex) {
		var results = ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName(ajaxSuggestions.itemClassName);
		if(this.insertCallback!=null){//let the callback do the insert job and etc.
			this.insertCallback(results[selectedIndex].innerHTML,this.currentElm);
		}else {
			this.currentElm.value = results[selectedIndex].innerHTML;
			this.currentElm.focus();
		}

/*
		for (var i = 0; i < ajaxSuggestions.elements.length; i++) {
			ajaxSuggestions.elements[i].value = results[selectedIndex].innerHTML;
			try {
				ajaxSuggestions.elements[i].focus();
			}
			catch(e) {
				// Just in case... :-)
			}
		}
*/
	},

	selectByMouseOver : function (selectedIndex) {
		if (ajaxSuggestions.currentElm && ajaxSuggestions.elmToPresentResultsIn) {
			var event = (typeof evt != "undefined") ? evt : event;
			if (typeof ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName != "function") {
				ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName = ajaxSuggestions.elmByClass;
			}
			var results = ajaxSuggestions.elmToPresentResultsIn.getElementsByClassName(ajaxSuggestions.itemClassName);
			var selectedItem = selectedIndex;
			if (results.length > 0) {
				var item;
				var classToRemove;
				for (var i = 0; i < results.length; i++) {
					item = results[i];
					classToRemove = new RegExp((ajaxSuggestions.itemSelectedClassName + "\s?"), "i");
					item.className = item.className.replace(classToRemove, "").replace(/^\s?|\s?$/g, "");
				}
				;
				ajaxSuggestions.selectedItem = selectedItem;
				var elmToFocus = ajaxSuggestions.currentElm;
				if (selectedItem > -1) {
					var currentItem = results[selectedItem];
					var currentClass = item.className;
					if (!new RegExp(ajaxSuggestions.itemSelectedClassName, "i").test(currentClass)) {
						currentItem.className = currentClass + ((currentClass.length > 0) ? " " : "") + ajaxSuggestions.itemSelectedClassName;
					}
					elmToFocus = results[selectedItem];
//          for(var i=0; i<ajaxSuggestions.elements.length; i++){
					//            ajaxSuggestions.elements[i].value=currentItem.innerHTML;
					//            ajaxSuggestions.elements[i].focus();
					//            break;
					//          }
				}
//				try{
				//					elmToFocus.focus();
				//				}
				//				catch(e){
				//					 Just in case... :-)
				//				}
				if (event) {
					if (event.preventDefault) {
						event.preventDefault();
					}
					else {
						event.returnValue = false;
					}
					if (event.stopPropagation) {
						event.stopPropagation();
					}
					else {
						event.cancelBubble = true;
					}
				}
				return false;
			}
			else if (keyCode == 27) {
				ajaxSuggestions.clearResults();
				try {
					ajaxSuggestions.currentElm.focus();
				}
				catch(e) {
					// Just in case... :-)
				}
			}
		}
	},

	applyResultEvents : function () {
		if (typeof this.elmToPresentResultsIn.getElementsByClassName != "function") {
			this.elmToPresentResultsIn.getElementsByClassName = this.elmByClass;
		}
		var insertValueItems = this.elmToPresentResultsIn.getElementsByClassName(this.itemInsertValueIntoInputClassName, "a");
		var item;
		for (var i = 0; i < insertValueItems.length; i++) {
			item = insertValueItems[i];
			item.inputRef = this.currentElm;
			this.addEvent(item, "click", this.insertValueIntoField);
		}
		;
	},

	insertValueIntoField : function (evt) {
		var elm = (/a/i.test(this.nodeName)) ? this : evt.srcElement;
		var input = elm.inputRef;
		var value = elm.getAttribute("href");
		if (!new RegExp(value).test(input.value)) {
			input.value = ((input.value.length > 0 && /;/i.test(input.value)) ? (input.value + value) : value) + ajaxSuggestions.itemSeparator;
		}
		if (evt.preventDefault) {
			evt.preventDefault();
		}
		else {
			evt.returnValue = false;
		}
		if (evt.stopPropagation) {
			evt.stopPropagation();
		}
		else {
			evt.cancelBubble = true;
		}
		if (ajaxSuggestions.itemInsertValueSetFocusToInput) {
			try {
				input.focus();
			}
			catch(e) {
				// Just in case... :-)
			}
		}
		if (ajaxSuggestions.hideResultsWhenInsertValueIsSelected) {
			ajaxSuggestions.clearResults();
		}
		ajaxSuggestions.valueAddedFromResultsListToInput = true;
	},

	preventInputClickBubbling : function (evt) {
		if (evt.preventDefault) {
			evt.preventDefault();
		}
		else {
			evt.returnValue = false;
		}
		if (evt.stopPropagation) {
			evt.stopPropagation();
		}
		else {
			evt.cancelBubble = true;
		}
		return false;
	},

	preventDefaultForArrowKeys : function (evt) {
		var keyCode = evt.keyCode;
		var navigateUp = keyCode == 38;
		var navigateDown = keyCode == 40;
		if ((!evt.ctrlKey && !evt.metaKey && !evt.shiftKey) && ajaxSuggestions.resultsAreVisible && (navigateUp || navigateDown)) {
			if (evt.preventDefault) {
				evt.preventDefault();
			}
			else {
				evt.returnValue = false;
			}
			if (evt.stopPropagation) {
				evt.stopPropagation();
			}
			else {
				evt.cancelBubble = true;
			}
			return false;
		}
	},

	getCoordinates : function () {
		var d = $(this.currentElm).offset();
		return [d.left, d.top];
		/*
      var elm = this.currentElm;
		  var offsetLeft = 0;
		  var offsetTop = 0;
		  while(elm.offsetParent){
			  offsetLeft += elm.offsetLeft;
			  offsetTop += elm.offsetTop;
			  if(elm.scrollTop > 0){
				  offsetTop -= elm.scrollTop;
			  }
			  elm = elm.offsetParent;
		  }
		  return [offsetLeft, offsetTop];
  */
	},

	closeSession : function () {
		delete ajaxSuggestions;
		ajaxSuggestions = null;
	},

	elmByClass : function (className, tag) {
		return ajaxSuggestions.getElementsByClassName.call(this, className, tag);
	},

	getElementsByClassName : function (className, tag) {
		var elms = ((!tag || tag == "*") && this.all) ? this.all : this.getElementsByTagName(tag || "*");
		var returnElms = [];
		var className = className.replace(/\-/g, "\\-");
		var regExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
		var elm;
		for (var i = 0; i < elms.length; i++) {
			elm = elms[i];
			if (regExp.test(elm.className)) {
				returnElms.push(elm);
			}
		}
		return (returnElms);
	},



	submitForm : function (counter) {

		ajaxSuggestions.insertTermIntoField(counter);

		var anElement = this.currentElm;
		if (!isHiddenByParent(anElement)) {
			if($(anElement).hasClass("ajax-suggestion-insert-only"))return;
			var callSubmit = true;
			if (anElement.form.onsubmit != '' && anElement.form.onsubmit != null) {
				try {
					callSubmit = anElement.form.onsubmit();
				}
				catch(e) {
				}
			}
//			if (callSubmit) anElement.form.submit();
		}

	},
	addEvent : function (elm, evt, func) {
		if (elm) {
			if (elm.addEventListener) {
				elm.addEventListener(evt, func, false);
			}
			else if (window.attachEvent) {
				elm.attachEvent(("on" + evt), func)
			}
		}
	}
};
// ---
ajaxSuggestions.addEvent(window, "load", function() {
	ajaxSuggestions.init();
});
ajaxSuggestions.addEvent(window, "unload", function() {
	ajaxSuggestions.closeSession();
});
// ---


function isHiddenByParent(element) {
	if (element != null && element.style != null && element.style.display == 'none') {
		return true;
	}
	var element = element.parentNode;
	while (element != null) {
		if (element != null && element.style != null && element.style.display == 'none') {
			return true;
		}
		element = element.parentNode;
	}
	return false;
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

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

	// public method for encoding
	encode : function (input) {
		var output = "";
		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);

		}

		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;
	}

}
