function MM_preloadImages() {
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

var debug = {
	
	value : null,

	ShowDebugVars : function()
	{
		$("#js_debug").html(this.value);
		setTimeout("debug.ShowDebugVars()",500);
	}
}

// timer ################################################################
var timer = {
	
	pageLoadTime : 0,
	time : 0,
	delta : 0,
	idle : 0,

	tick : function()
	{
		var d = new Date();
		var t = d.getTime();
		this.delta = t - this.time;
		this.time = t;

		this.popupRefresh();
		this.calcIdle();

		setTimeout("timer.tick()",250);
	},

	resetIdle : function()
	{
		this.idle = 0;
	},

	calcIdle : function()
	{
		this.idle += this.delta;

		if (mouse.button != null)
			this.idle = 0;
	},

	popupRefresh : function()
	{
		if (mouse.x == null || mouse.y == null)
			return;

		if (this.idle > 200)
			popup.show();
	}
}

// lib ##################################################################
var lib = {

	onLoad : function()
	{
		jQuery.fn.extend({
			check: function() { return this.each(function() { this.checked = true; }); },
			uncheck: function() { return this.each(function() { this.checked = false; }); }
		 });

		var d = new Date();
		timer.pageLoadTime = d.getTime();

		timer.tick();

		//extendThumbs();
	},

	swapTabs : function(tabList,tab_selected,tab_prefix,content_prefix)
	{
		var tabOn =   "tabOn";
		var tabOff =  "tabOff";
		var visible = "visible";
		var hidden =  "hidden";

		if (typeof content_prefix == "string")
			var contents = new Array(content_prefix);
		else
			var contents = content_prefix;

		for (var i=0; i<tabList.length; i++)
		{
			var tab_node = null;
			if (tab_prefix)
				tab_node = tab_prefix + "_" + tabList[i];

			if (tab_node)
			{
				tab_node.removeClass(tabOn);
				tab_node.removeClass(tabOff);
			}
			
			for (var c = 0; c < contents.length; c++)
			{
				(contents[c] + "_" + tabList[i]).removeClass(visible);
				(contents[c] + "_" + tabList[i]).removeClass(hidden);
			}

			if (tabList[i] == tab_selected)
			{
				if (tab_node)
					tab_node.addClass(tabOn);
				
				for (var c = 0; c < contents.length; c++)
					(contents[c] + "_" + tabList[i]).addClass(visible);
			}
			else
			{
				if (tab_node)
					tab_node.addClass(tabOff);

				for (var c = 0; c < contents.length; c++)
					(contents[c] + "_" + tabList[i]).addClass(hidden);
			}
		}
	},
	
	/**
	* Converts the given data structure to a JSON string.
	* Argument: arr - The data structure that must be converted to JSON
	* Example: var json_string = array2json(['e', {pluribus: 'unum'}]);
	* 			var json = array2json({"success":"Sweet","failure":false,"empty_array":[],"numbers":[1,2,3],"info":{"name":"Binny","site":"http:\/\/www.openjs.com\/"}});
	* http://www.openjs.com/scripts/data/json_encode.php
	*/
	array2json : function(arr)
	{
		var parts = [];
		var is_list = (Object.prototype.toString.apply(arr) === '[object Array]');

		for(var key in arr) {
			var value = arr[key];
			if(typeof value == "object") { //Custom handling for arrays
				if(is_list) parts.push(this.array2json(value)); /* :RECURSION: */
				else parts[key] = this.array2json(value); /* :RECURSION: */
			} else {
				var str = "";
				if(!is_list) str = '"' + key + '":';

				//Custom handling for multiple data types
				if(typeof value == "number") str += value; //Numbers
				else if(value === false) str += 'false'; //The booleans
				else if(value === true) str += 'true';
				else str += '"' + value + '"'; //All other things
				// :TODO: Is there any more datatype we should be in the lookout for? (Functions?)

				parts.push(str);
			}
		}
		var json = parts.join(",");
		
		if(is_list) return '[' + json + ']';//Return numerical JSON
		return '{' + json + '}';//Return associative JSON
	},

	readDataFromPHP : function(node)
	{
		return str.unSerialize($(node).html());
	}
}

// mouse ################################################################
var mouse = {

	x : null,
	y : null,
	button : null,

	onMove : function(e)
	{
		e = e ? e : window.event;
		this.x = e.clientX;
		this.y = e.clientY;

		timer.resetIdle();
		popup.hide();
	},

	onDown : function(e)
	{
		this.button = 1;

		timer.resetIdle();
		popup.hide();
	},

	onUp : function(e)
	{
		this.button = null;

		timer.resetIdle();
		popup.hide();
	}
}

// keyboard ##################################################################
var keyboard = {

	key : null,

	onDown : function(e)
	{
		e = e ? e : window.event;
		if ($.browser.msie)
			this.key = e.keyCode;
		else
			this.key = e.which;

		timer.resetIdle();
		popup.hide();
	},

	onUp : function(e)
	{
		key = null;

		timer.resetIdle();
		popup.hide();
	}
}

// str ########################################################################
var str = {

	clean : function(str, chars)
	{
		return str.replace(new RegExp("[^a-zA-Z0-9" + chars + "]","g"),"");
	},

	trim : function(str, chars)
	{
		return this.ltrim(this.rtrim(str, chars), chars);
	},

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

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

	splitLines : function(str)
	{
		var result = "";
		var lines = str.split("\n");

		for (var i=0; i<lines.length; i++)
		{
			result += lines[i];
			if (i < lines.length-1)
				result += "<br/>";
		}
		
		return result;
	},

	zeroPad : function(num, len)
	{
		var str = num.toString();

		while (str.length < len)
			str = "0" + str;

		return str;
	},

	sys60toInt : function(str)
	{
		var sign = 1;
		if (typeof str != "string")
			return false;
		if (!str.length)
			return false;
		if (str.charAt(0) == "-")
		{
			str = str.substr(1);
			sign = -1;
		}
		else if (str.charAt(0) == "+")
		{
			str = str.substr(1);
		}
		if (!str.length || str.length > 16)
			return false;

		var mul = 1;
		var value = 0;
		for (var i=str.length-1; i>=0; i--)
		{
			var ch = str.charCodeAt(i);
			var digit;
			if (ch >= 48 && ch <= 57) digit = ch - 48;
			else if (ch >= 65 && ch <= 90) digit = 10 + ch - 65;
			else if (ch >= 97 && ch <= 120) digit = 36 + ch - 97;
			else return false;
			value += digit * mul;
			mul *= 60;
		}
		if (value > 0x7fffffff)
			return false;

		return (value * sign);
	},

	_getNum : function(stream,offs)
	{
		var n = 0;
		while (stream.charAt(offs.idx+n) != "z") n++;
		var num = 0;
		if (n != 0)
			num = this.sys60toInt(stream.substr(offs.idx,n));
		
		offs.idx += (n + 1);
		return num;
	},

	unSerialize : function(stream)
	{
		var root = new Array;
		var arg = new Array;
		var offs = new Object;
		var keys = new Array;
		arg.idx = 0;
		offs.idx = 0;

		var id = stream.substr(offs.idx,3);
		offs.idx += 3;
		if (id != "SD1")
		{
			alert("lib.unSerialize error");
			return null;
		}

		this._parseKeys(stream,offs,keys);
		this._unSerialize(stream,root,arg,offs,keys);

		return root[0];
	},

	_parseKeys : function(stream,offs,keys)
	{
		if (stream.charAt(offs.idx) != "y")
			return;
		offs.idx++;

		var numKeys = this.sys60toInt(stream.substr(offs.idx,1));
		offs.idx++;
		for (var i=0; i<numKeys; i++)
		{
			var keylen = this.sys60toInt(stream.substr(offs.idx,1));
			offs.idx++;
			keys[i] = stream.substr(offs.idx,keylen);
			offs.idx += keylen;
		}
	},

	_unSerialize : function(stream,parent,arg,offs,keys)
	{
		var obj;
		if (stream.charAt(offs.idx) == "y")
		{
			offs.idx++;
			if (stream.charAt(offs.idx) == "y")
			{
				offs.idx++;
				var strlen = this.sys60toInt(stream.substr(offs.idx,1));
				offs.idx++;
				obj = stream.substr(offs.idx,strlen);
				offs.idx += strlen;
			}
			else
			{
				var keyIdx = this.sys60toInt(stream.substr(offs.idx,1));
				offs.idx++;
				obj = keys[keyIdx];
			}
			if (!isNaN(obj))
				arg.idx = parseInt(obj) + 1;
		}
		else
		{
			obj = arg.idx++;
		}

		var thisChar = stream.charAt(offs.idx);
		if (thisChar == "i" || thisChar == "m")
		{
			offs.idx++;
			if (thisChar == "z")
				parent[obj] = 0;
			else
				parent[obj] = ((thisChar == "i") ? 1 : -1) * this._getNum(stream,offs);
		}
		else if (thisChar == "s")
		{
			offs.idx++;
			var strlen = this._getNum(stream,offs);
			if (strlen)
			{
				parent[obj] = base64.decode(stream.substr(offs.idx,strlen));
				offs.idx += strlen;
			}
			else
			{
				parent[obj] = "";
			}
		}
		else if (thisChar == "c")
		{
			offs.idx++;
			parent[obj] = base64.decode(stream.substr(offs.idx,1));
			offs.idx++;
		}
		else if (thisChar == "a")
		{
			offs.idx++;
			var arrlen = this._getNum(stream,offs);
			parent[obj] = new Array;
			arg[obj] = new Array;
			arg[obj].idx = 0;
			for (var i=0; i<arrlen; i++)
				this._unSerialize(stream,parent[obj],arg[obj],offs,keys);
		}
		else
		{
			parent[obj] = this._getNum(stream,offs);
		}
	}
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
 
// base64 ################################################################
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;
	}
 
}

// listGen ##################################################################
var listGen = {

	getPageIndexList : function(base, node, curr_page, num_page)
	{
		var blockFirstPage = curr_page - 3;
		var blockLastPage = curr_page + 3;
		if (blockFirstPage < 2) blockFirstPage = 2;
		if (blockLastPage > num_page-1) blockLastPage = num_page-1;

		var prevPage = (curr_page == 1) ? "" : "<a href='" + base + (curr_page-1) + "'><</a> ";
		var nextPage = (curr_page == num_page) ? "" : "<a href='" + base + (curr_page+1) + "'>></a>";
		var preDots = (blockFirstPage > 2) ? " ... " : "";
		var postDots = (blockLastPage < num_page-1) ? " ... " : "";

		var block = "";
		for (var i=blockFirstPage; i<=blockLastPage; i++)
		{
			var p = (i == curr_page) ? (i + " ") : ("<a href='" + base + i + "'>" + i + "</a> ");
			block = block + p;
		}

		var firstPage = (curr_page == 1) ? "1 " : "<a href='" + base + "1'>1</a> ";
		if (num_page > 1)
			var lastPage = (curr_page == num_page) ? (num_page + " ") : "<a href='" + base + num_page + "'>" + num_page + "</a> ";
		else
			var lastPage = "";

		node.html("Page: " + prevPage + firstPage + preDots + block + postDots + lastPage + nextPage);
	}
}

// popup window #################################################################
var popup = {
	
	visible : false,
	popupNode : null,
	popupContent : null,

	getInventory : function()
	{
		if (Element.hasClassName(this.popupNode,"invItem"))			// gear
			var slices = this.popupNode.id.split("_");
		else
			var slices = this.popupNode.firstChild.id.split("_");	// pack

		var itemInfo = inventory.getItemInfo(slices[0],slices[1],slices[2]);

		var side;
		if (itemInfo["side"] == "c")
			side = "common";
		else if (itemInfo["side"] == "p")
			side = "pirate";
		else if (itemInfo["side"] == "n")
			side = "ninja";

		this.popupContent =
			"<div style='color: #ff0; font-size: 14px; font-weight: bold;'>" + itemInfo["name"] + "</div>" +
			"<div>" + "side: " + side + "</div>" +
			"<div>" + "power: " + itemInfo["power"] + "</div>" +
			"<div>" + "cost: " + itemInfo["cost"] + "</div>";
	},

	getBuild : function()
	{
		this.popupContent = this.popupNode.firstChild.html();
	},

	show : function()
	{
		if (this.visible)
			return;
		this.visible = true;

		var width = 180;
		var height = 210;
		var top = mouse.y;
		var left = mouse.x + 12;

		if ((left + width) > $("body").outerWidth())
			left -= width + 28;
		if ((top + height) > $("body").outerHeight())
			top -= height + 20;
		else
			top += 10;

		var scrollOffsetTop = $("body").scrollTop();
		var scrollOffsetLeft = $("body").scrollLeft();

		top += scrollOffsetTop;
		left += scrollOffsetLeft;

		var popupNodes = $(".p");
		this.popupNode = null;
		for (var i=0; i<popupNodes.length; i++)
		{
			if (Position.within(popupNodes[i],mouse.x + scrollOffsetLeft,mouse.y + scrollOffsetTop))
			{
				this.popupNode = popupNodes[i];
				break;
			}
		}

		if (this.popupNode)
		{
			var path = $("#path").html().split("/");
			if (path[0] == "profile")
			{
				if (path[1] == "inventory")
					this.getInventory();
			}
			else if (path[0] == "admin" && path[1] == "multi_fight")
			{
				this.getBuild();
			}

			var node = $("#popup");
			node.css({"width" : String(width)+"px" , "height" : String(height)+"px" , "top" : String(top)+"px" , "left" : String(left)+"px"});
			node.removeClass("hidden");
			node.html(this.popupContent);
			node.addClass("visible");
		}
	},

	hide : function()
	{
		if (!this.visible)
			return;
		this.visible = false;

		$("#popup").removeClass("visible");
		$("#popup").addClass("hidden");
	}
}

// cookie ################################################################
var cookie = {

	_toCookie : function(value)
	{
		if (value === 0)
			return "__null__";

		return value;
	},

	_fromCookie : function(value)
	{
		if (value == "__null__")
			return 0;

		return value;
	},

	set : function(name, value, path)
	{
		var pathstr = "/";
		if (path)
			pathstr = path;

		document.cookie = escape(name) + "=" + escape(this._toCookie(value)) + "; path=" + pathstr;
	},

	setArray : function(name, arr)
	{
		var value = "";
		for (var i=0; i<arr.length; i++)
		{
			value += arr[i];
			if (i != arr.length-1)
				value += "\x80";
		}

		this.set(name, value);
	},

	get : function(name)
	{
		var exp = new RegExp(escape(name) + "=([^;]+)");
		if (exp.test(document.cookie + ";"))
		{
			exp.exec(document.cookie + ";");
			return unescape(this._fromCookie(RegExp.$1));
		}
		
		return false;
	},

	getArray : function(name)
	{
		var value = this.get(name);
		if (value === false)
			return false;

		return value.split("\x80");
	},

	testSession : function()
	{
		document.cookie = "testSessionCookie=Enabled";
		if (this.get("testSessionCookie") == "Enabled")
			return true;
		
		return false;
	},

	testPersistent : function()
	{
		this.setPersistent("testPersistentCookie", "Enabled", "days", 1);
		if (this.get("testPersistentCookie") == "Enabled")
			return true;
		
		return false;
	},

	setPersistent : function(name, value, periodType, offset)
	{
		var expireDate = new Date();
		offset = offset / 1;
	  
		var myPeriodType = periodType;
		switch (myPeriodType.toLowerCase())
		{
			case "years": 
				var year = expireDate.getYear();     
				// Note some browsers give only the years since 1900, and some since 0.
				if (year < 1000) year = year + 1900;     
					expireDate.setYear(year + offset);
				break;
			case "months":
				expireDate.setMonth(expireDate.getMonth() + offset);
				break;
			case "days":
				expireDate.setDate(expireDate.getDate() + offset);
				break;
			case "hours":
				expireDate.setHours(expireDate.getHours() + offset);
				break;
			case "minutes":
				expireDate.setMinutes(expireDate.getMinutes() + offset);
				break;
			default:
				alert("Invalid periodType parameter for setPersistent()");
				break;
		} 
	  
		document.cookie = escape(name) + "=" + escape(value) + "; expires=" + expireDate.toGMTString() + "; path=/";
	},

	deleteCookie : function(name)
	{
		if (this.get(name))
			this.setPersistent(name,"Pending delete","years", -1);
	}
}

// utf8 ################################################################
function utf8_encode ( string )
{
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: sowberry
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // *     example 1: utf8_encode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
 
    string = (string+'').replace(/\r\n/g,"\n");
    var utftext = "";
    var start, end;
    var stringl = 0;
 
    start = end = 0;
    stringl = string.length;
    for (var n = 0; n < stringl; n++) {
        var c1 = string.charCodeAt(n);
        var enc = null;
 
        if (c1 < 128) {
            end++;
        } else if((c1 > 127) && (c1 < 2048)) {
            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
        } else {
            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
        }
        if (enc != null) {
            if (end > start) {
                utftext += string.substring(start, end);
            }
            utftext += enc;
            start = end = n+1;
        }
    }
 
    if (end > start) {
        utftext += string.substring(start, string.length);
    }
 
    return utftext;
}

// md5 ################################################################
function md5 ( str )
{
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // + namespaced by: Michael White (http://getsprink.com)
    // +    tweaked by: Jack
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: utf8_encode
    // *     example 1: md5('Kevin van Zonneveld');
    // *     returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
 
    var RotateLeft = function(lValue, iShiftBits) {
        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
    };
 
    var AddUnsigned = function(lX,lY) {
        var lX4,lY4,lX8,lY8,lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
    };
 
    var F = function(x,y,z) { return (x & y) | ((~x) & z); };
    var G = function(x,y,z) { return (x & z) | (y & (~z)); };
    var H = function(x,y,z) { return (x ^ y ^ z); };
    var I = function(x,y,z) { return (y ^ (x | (~z))); };
 
    var FF = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var GG = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var HH = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var II = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var ConvertToWordArray = function(str) {
        var lWordCount;
        var lMessageLength = str.length;
        var lNumberOfWords_temp1=lMessageLength + 8;
        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
        var lWordArray=Array(lNumberOfWords-1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while ( lByteCount < lMessageLength ) {
            lWordCount = (lByteCount-(lByteCount % 4))/4;
            lBytePosition = (lByteCount % 4)*8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount)<<lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount-(lByteCount % 4))/4;
        lBytePosition = (lByteCount % 4)*8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
        return lWordArray;
    };
 
    var WordToHex = function(lValue) {
        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
        for (lCount = 0;lCount<=3;lCount++) {
            lByte = (lValue>>>(lCount*8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
        }
        return WordToHexValue;
    };
 
	var x=Array();
    var k,AA,BB,CC,DD,a,b,c,d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;
 
    str = utf8_encode(str);
    x = ConvertToWordArray(str);
    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
    
    xl = x.length;
    for (k=0;k<xl;k+=16) {
        AA=a; BB=b; CC=c; DD=d;
        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
        a=AddUnsigned(a,AA);
        b=AddUnsigned(b,BB);
        c=AddUnsigned(c,CC);
        d=AddUnsigned(d,DD);
    }
 
    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
    return temp.toLowerCase();
}

// font ################################################################
var font = {
	
	type : null,
	size : null,
	overlay : null,
	canMark : null,

	set : function(type,size,overlay,canMark)
	{
		this.type = type;
		this.size = size;
		this.overlay = overlay;
		this.canMark = canMark;
	},

	setType : function(type)
	{
		this.type = type;
	},

	setSize : function(size)
	{
		this.size = size;
	},

	setOverlay : function(overlay)
	{
		this.overlay = overlay;
	},

	setCanMark : function(canMark)
	{
		this.canMark = canMark;
	},

	write : function(node,str,margin)
	{
		var result = "";

		if (margin)
			result += "<div style='width: "+margin+"px; height: 1px; float: left;'></div>";

		var offs = 0;
		var marker = false;
		var markerID = "";
		var markFlag = false;
		for (var i=0; i<str.length; i++)
		{
			var ch = str.charCodeAt(i);
			if (this.canMark)
			{
				if (ch == 37)
				{
					marker = !marker;
					if (marker)
					{
						markerID = "";
						continue;
					}
					else if (markerID.length)
					{
						markFlag = true;
						continue;
					}
				}

				if (marker)
				{
					markerID += str.charAt(i);
					continue;
				}
			}

			var img = "/images/fonts/" + this.type + "/" + ch + ".png";

			var ID = markFlag ? ("id='"+markerID+"'") : "";
			var height = this.size ? "height='"+this.size+"'" : "";

			if (this.overlay)
			{
				result += "<img "+ID+" style='position: relative; left: "+offs+"px;' "+height+" src='"+img+"'/>";
				offs -= this.overlay;
			}
			else
			{
				result += "<img "+ID+" "+height+" src='"+img+"'/>";
			}

			markFlag = false;
		}

		node.html(result);
	}
}

var ui = {
	
	enableButton : function(node)
	{
		node.removeClass("buttonDisabled");
		node.addClass("button");
		node.removeAttr("disabled");
	},

	disableButton : function(node)
	{
		node.removeClass("button");
		node.addClass("buttonDisabled");
		node.attr("disabled","disabled");
	}
}

//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2008 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
function ControlVersion()
{
	var version;
	var axo;
	var e;
	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}
	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";
			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";
			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}
// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];
        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}
function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}
function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }
  document.write(str);
}
function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}
function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}
function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    
    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblclick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}
