/**** START: .svn ****/



/**** END:  .svn ****/

/**** START: lbox.js ****/

// bastardized version of Lightbox by Lokesh Dakar
// check him out at www.huddletogether.com

// Returns array with x,y page scroll values.
function getPageScroll(){

	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}

	arrayPageScroll = new Array('',yScroll)
	return arrayPageScroll;
}


// Returns array with page width, height and window width, height
function getPageSize(){

	var xScroll, yScroll;

	if (window.innerHeight && window.scrollMaxY) {
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}

	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}

	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else {
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}

	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
	return arrayPageSize;
}


function showLightbox(objLink,xy)
{
	var enh = document.getElementById(objLink);
	coord = xy.split(',');

	if (objLink == 'enh'){
		x = parseInt(coord[1]) - 10;
		y = parseInt(coord[0]) - 30;

		//if (y>700){ y = y-350; };
	    //if (x>500){ x = x-100; };
	}
	else if (objLink == 'details'){
		x = parseInt(coord[1]);
        y = parseInt(coord[0]);
        if (y>700){ y = y-350; };
	    if (x>500){ x = x-250; };
	}
	else if (objLink == 'regbox'){
		x = parseInt(coord[1]);
        y = parseInt(coord[0]);
        if (y>700){ y = y-250; };	
	}
	else {
		x = parseInt(coord[1]);
		y = parseInt(coord[0]);
		if (y>700){ y = y-150; };		
	}

	// prep objects
	var objLightbox = document.getElementById('lightbox');
	var objCaption = document.getElementById('lightboxCaption');
	var objImage = document.getElementById('lightboxImage');
	var objLoadingImage = document.getElementById('loadingImage');
	var objLightboxDetails = document.getElementById('lightboxDetails');

	var arrayPageSize = getPageSize();
	var arrayPageScroll = getPageScroll();

	// Hide select boxes as they will 'peek' through the image in IE
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}

	if (objLink == 'exportbox'){
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - 550) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - 600) / 2);
	} 
	else if (objLink == 'donate'){
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - 200) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - 300) / 2);
		
	}
	else if (objLink == 'loading' || objLink == 'saving' || objLink == 'saving_done'){
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - 150) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - 400) / 2);
	}
	else if (objLink == 'savecheck'){
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - 450) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - 400) / 2);
		
		document.check_save.save_origin.style.visibility = "visible";
		document.check_save.save_server.style.visibility = "visible";
		document.check_save.save_pvp.style.visibility = "visible";
		document.check_save.save_private.style.visibility = "visible";
	}
	else {
		var lightboxTop = x;
		var lightboxLeft = y
	}

	enh.style.top  = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
	enh.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";
	enh.style.zIndex = 100000;
	enh.style.display = 'block';	

}

function hideLightbox()
{
	// get objects
	objLightbox = document.getElementById('lightbox');

	// hide lightbox
	document.getElementById('enh').style.display = 'none';
	document.getElementById('exportbox').style.display = 'none';
	document.getElementById('details').style.display = 'none';
	document.getElementById('login').style.display = 'none';
	document.getElementById('regbox').style.display = 'none';
	document.getElementById('loading').style.display = 'none';
	document.getElementById('saving').style.display = 'none';
	document.getElementById('saving_done').style.display = 'none';
	document.getElementById('savecheck').style.display = 'none';
	document.getElementById('donate').style.display = 'none';

	// make select boxes visible
	selects = document.getElementsByTagName("select");
    for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}

	// disable keypress listener
	document.onkeypress = '';
}


/**** END:  lbox.js ****/

/**** START: register.js ****/

function checkReg2(){

	var user	= $('username').value;
	var global	= $('global').value;
	var email	= $('email').value;
	var pass	= $('rpass').value;
	var pass2	= $('rpass2').value;
	
	msg = '';
	
	if (trim(user).length == 0){
		msg += "=> Please select a Username!\n";
	}
		 
	if (pass.length < 5) {
		msg += "=> Password must be at least 5 characters long!\n";
	}
	else if (hex_md5(pass) != pass2){
		msg += "=> Passwords do no match!\n";	
	}
	
	if (trim(global).length == 0){
		msg += "=> Please enter your Global handle!\n";		
	}
	if (trim(email).length == 0){
		msg += "=> Please enter your Email address!\n";
	}
	
	if (msg != ''){	
		msg = "The following must be corrected before registering:\n\n" + msg;
		alert(msg);
		return false;	
	} else {
		return true;
	}
	
}

function checkLogin2(){

	var user = $('username').value;
	var pass = $('rpass').value;
	
	msg = '';
	
	if (trim(user).length == 0){
		msg += "=> Please enter your Username!\n";
	}
		 
	if (trim(pass).length == 0) {
		msg += "=> Password enter your Password!\n";
	}
	
	if (msg != ''){	
		msg = "The following must be corrected before logging in:\n\n" + msg;
		alert(msg);
		return false;	
	} else {
		return true;
	}
	
}

function checkAccChange(){

	var global = $('global').value;
	var email  = $('email').value;
	var pass   = $('password').value;
	
	msg = '';
	
	if (trim(global).length == 0 || trim(global) == '@'){
		msg += "=> Please enter your Global Handle!\n";
	}
		 
	if (trim(email).length == 0){
		msg += "=> Please enter your Email Address!\n";
	}
		 
	if (trim(pass).length == 0) {
		msg += "=> Please enter your Password!\n";
	}

	
	if (msg != ''){	
		msg = "The following must be corrected before submitting:\n\n" + msg;
		alert(msg);
		return false;	
	} else {
		return true;
	}
	
}


/**** END:  register.js ****/

/**** START: slots.js ****/

function makeSlotsAvailable(){
	
	form = document.planner;
	
	slots = parseInt(form.enh_level.value);
	atpower = parseInt(form.atpower.value);
	atslots = parseInt(form.atslots.value);
	
	form.slots.value = parseInt(slot_amounts[slot_array[atslots]]);
	
	if (slots > 0 && slots <= parseInt(form.level.value)){

		for ( x=1; x <= atpower; x++ ){
			tlevel = left($('selection'+x).innerHTML, 4);
			tlevel = tlevel.replace('(','');
			tlevel = tlevel.replace(')','');

			if (tlevel <= slots){
				$('selection'+x).className = 'choose';
				check = 0;
			}

			for (l=2; l <= 6; l++)	{
				li = $('li_'+x+'_'+l);

				if (li.innerHTML.match(/new.gif/)){ check = 1; };

				if ((li.innerHTML == '' || li.innerHTML == '&nbsp;') && check == 0){
					name = $('selection'+x).name;
					li.innerHTML = "<a href=\"javascript:placeEmptyEnh('li_"+x+"_"+l+"','"+name+"')\"><img src=\"/img/enh/new.gif\"></a>";
					check = 1;
				} 
				else if (check == 1){
					break;	
				}
			}
		}
		
		for ( x=25; x <= 40; x++ ){
			tlevel = left($('selection'+x).innerHTML, 4);
			tlevel = tlevel.replace('(','');
			tlevel = tlevel.replace(')','');

			if (tlevel <= slots){
				$('selection'+x).className = 'choose';
				check = 0;
			}

			for (l=2; l <= 6; l++)	{
				li = $('li_'+x+'_'+l);

				if (li.innerHTML.match(/new.gif/)){ check = 1; };

				if ((li.innerHTML == '' || li.innerHTML == '&nbsp;') && check == 0){
					if (x == 25 || x == 26 || x == 27){
						li.innerHTML = "<a href=\"javascript:placeEmptyEnh('li_"+x+"_"+l+"','"+inh_ids[x]+"')\"><img src=\"/img/enh/new.gif\"></a>";
					} else {
						name = $('selection'+x).name;
						li.innerHTML = "<a href=\"javascript:placeEmptyEnh('li_"+x+"_"+l+"','"+name+"')\"><img src=\"/img/enh/new.gif\"></a>";
					}
					check = 1;
				} 
				else if (check == 1){
					break;	
				}
			}
		}
	}
}

function makeSlotsAvailableSpecial(nextpow,powID){
	form = document.planner;
	
	level = parseInt(form.enh_level.value);
	slots = parseInt(form.slots.value);
	
	tlevel = left($('selection'+nextpow).innerHTML, 4);
	tlevel = tlevel.replace('(','');
	tlevel = tlevel.replace(')','');
	
	if (slots > 0 && tlevel < level){
		liID = 'li_'+nextpow+'_2';
		li = $(liID);
		li.innerHTML = "<a href=\"javascript:placeEmptyEnh('"+liID+"','"+powID+"')\"><img src=\"/img/enh/new.gif\"></a>";
	}
}

/* SELECTING SLOTS
*************************************************/

// place empty enhancement on power click
function placeEmptyEnh(tdID, tdName){

	var form = document.planner;

	level = parseInt(form.enh_level.value);
    slotted = parseInt(form.enh_count.value);
	slots = parseInt(form.slots.value);
	atslots = parseInt(form.atslots.value);
	
	td = tdID.split('_');
	html = 'seltext'+td[1];
	
	if ($(html).innerHTML == '' || $(html).innerHTML == '&nbsp;'){
		return;
	}
	
	if (slots == 1){
		
		for (x=1;x<=40;x++){
			for (l=1;l<=6;l++){
				if ($('li_'+x+'_'+l).innerHTML.match(/new.gif/)){
					$('li_'+x+'_'+l).innerHTML = '';
				}
			}
		}
		
		next_level = slot_array[atslots+1];

	/*
		if (next_level == 50){
			form.enh_level.value = 50;
			form.slots.value = slot_amounts[50];
			form.enh_tot.value = slot_amounts[50];
			form.enh_count.value = slot_amounts[50];
		}
	*/	
		setTimeout('upSlotsLevel();',150);
	} else if (slots == 0){		
		return;
	}

	slotted++;

	$(tdID).innerHTML = "<a href=\"javascript:showEnhDiv('"+tdName+"','"+tdID+"');\"><img id=\""+tdName+slotted+level+"\" alt=\""+level+"\" src=\"/img/enh/Empty.gif\" /></a>";
	form.enh_count.value = slotted;

	form.slots.value = form.slots.value - 1;
	
	li = tdID.split('_');
	if (li[2] != 6){
		li[2]++;
		newli = 'li_' + li[1] + '_' + li[2];
		if (!$(newli).innerHTML.match(/new.gif/) && slots != 1){
			$(newli).innerHTML = "<a href=\"javascript:placeEmptyEnh('"+newli+"', '"+tdName+"')\"><img src=\"/img/enh/new.gif\"></a>";
		}
	}
	
	form.enh_count.value = parseInt(form.enh_count.value) + 1;

}

// show the enh picker
function showEnhDiv(powID, liID){
	
	var form = document.planner;

	// only want to show the div if there's a power in it.
	if (powID){
		
		//if (powID == form.last_enh.value){		
		//	xy = form.x.value + ',' + form.y.value;
		//	showLightbox('enh',xy);
		//} else {
		
			// get power data
			hos =  (form.show_hos.checked) ? 1 : 0;
			ios =  (form.show_ios.checked) ? 1 : 0;
			
			form.last_enh.value = powID;
			
			var ao = new AjaxObject();
			ao.sndReq('get', '/ajax.php?op=power_enh&x='+powID+'&y='+liID+'&hos='+hos+'&ios='+ios);
		//}
	}
}

// replace empty with enhancement
function chooseEnh(liID, enh){

	hideLightbox();
	
	stuff = $(liID);
			
	for (z=0; z<stuff.childNodes.length; z++){					
		try{
			if (enh.match(/Exposure/)){
				dir = '/img/hos/';
				t = ho_list[enh];
				ext = 'gif';
			} else if (enh.match(/IO-/)){
				dir = '/img/ios/';
				balls = enh.split('-');
				t = balls[1] + ": " + balls[2];
				enh = balls[1];
				ext = 'png';
			} else {
				dir = '/img/enh/';
				t = enh;
				ext = 'gif';
			}
			
			(stuff.childNodes[z]).childNodes[0].src = dir + enh + '.' + ext;
			(stuff.childNodes[z]).childNodes[0].title = '(' + document.planner.enh_level.value + ') ' + t;
		}
		catch (e) {}
	}

}

function showIOSets(io){
	new Ajax.Request('/ajax.php',
		{
			method: 'post',
			parameters: {op: '',u: user, p: pass},
			onSuccess: function(transport){
				var response = transport.responseText || 'no response text';
				finishLogin(response);
			},
			onFailure: function(){ alert('failed'); }
		});
}


/**** END:  slots.js ****/

/**** START: md5.js ****/

/*
 * 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;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var 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 Array(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 = Array(16), opad = 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 = Array();
  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 = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var 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(var 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;
}

/**** END:  md5.js ****/

/**** START: prototype.js ****/

/*  Prototype JavaScript framework, version 1.5.0
 *  (c) 2005-2007 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.5.0',
  BrowserFeatures: {
    XPath: !!document.evaluate
  },

  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
  emptyFunction: function() {},
  K: function(x) { return x }
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

var Abstract = new Object();

Object.extend = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }
  return destination;
}

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (object === undefined) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : object.toString();
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({}, object);
  }
});

Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this, args = $A(arguments), object = args.shift();
  return function(event) {
    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
  }
}

Object.extend(Number.prototype, {
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }
});

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }

    return returnValue;
  }
}

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.callback(this);
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
}
String.interpret = function(value){
  return value == null ? '' : String(value);
}

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = count === undefined ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return this;
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : this;
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
  },

  unescapeHTML: function() {
    var div = document.createElement('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return {};

    return match[1].split(separator || '&').inject({}, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var name = decodeURIComponent(pair[0]);
        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;

        if (hash[name] !== undefined) {
          if (hash[name].constructor != Array)
            hash[name] = [hash[name]];
          if (value) hash[name].push(value);
        }
        else hash[name] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function(){
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.replace(/\\/g, '\\\\');
    if (useDoubleQuotes)
      return '"' + escapedString.replace(/"/g, '\\"') + '"';
    else
      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (typeof replacement == 'function') return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
}

String.prototype.parseQuery = String.prototype.toQueryParams;

var Template = Class.create();
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
Template.prototype = {
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern  = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    return this.template.gsub(this.pattern, function(match) {
      var before = match[1];
      if (before == '\\') return match[2];
      return before + String.interpret(object[match[3]]);
    });
  }
}

var $break    = new Object();
var $continue = new Object();

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        try {
          iterator(value, index++);
        } catch (e) {
          if (e != $continue) throw e;
        }
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator) {
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.map(iterator);
  },

  all: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      result = result && !!(iterator || Prototype.K)(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator) {
    var result = false;
    this.each(function(value, index) {
      if (result = !!(iterator || Prototype.K)(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      results.push((iterator || Prototype.K)(value, index));
    });
    return results;
  },

  detect: function(iterator) {
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern))
        results.push((iterator || Prototype.K)(value, index));
    })
    return results;
  },

  include: function(object) {
    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = fillWith === undefined ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator) {
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (result == undefined || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (result == undefined || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator) {
    var trues = [], falses = [];
    this.each(function(value, index) {
      ((iterator || Prototype.K)(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value, index) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator) {
    return this.map(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (typeof args.last() == 'function')
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
}

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse)
  Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(value && value.constructor == Array ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  indexOf: function(object) {
    for (var i = 0, length = this.length; i < length; i++)
      if (this[i] == object) return i;
    return -1;
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function() {
    return this.inject([], function(array, value) {
      return array.include(value) ? array : array.concat([value]);
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }
});

Array.prototype.toArray = Array.prototype.clone;

function $w(string){
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if(window.opera){
  Array.prototype.concat = function(){
    var array = [];
    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for(var i = 0, length = arguments.length; i < length; i++) {
      if(arguments[i].constructor == Array) {
        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  }
}
var Hash = function(obj) {
  Object.extend(this, obj || {});
};

Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];

	  this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;

      if (pair.value && pair.value.constructor == Array) {
        var values = pair.value.compact();
        if (values.length < 2) pair.value = values.reduce();
        else {
        	key = encodeURIComponent(pair.key);
          values.each(function(value) {
            value = value != undefined ? encodeURIComponent(value) : '';
            parts.push(key + '=' + encodeURIComponent(value));
          });
          return;
        }
      }
      if (pair.value == undefined) pair[1] = '';
      parts.push(pair.map(encodeURIComponent).join('='));
	  });

    return parts.join('&');
  }
});

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
  _each: function(iterator) {
    for (var key in this) {
      var value = this[key];
      if (value && value == Hash.prototype[key]) continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  merge: function(hash) {
    return $H(hash).inject(this, function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  remove: function() {
    var result;
    for(var i = 0, length = arguments.length; i < length; i++) {
      var value = this[arguments[i]];
      if (value !== undefined){
        if (result === undefined) result = value;
        else {
          if (result.constructor != Array) result = [result];
          result.push(value)
        }
      }
      delete this[arguments[i]];
    }
    return result;
  },

  toQueryString: function() {
    return Hash.toQueryString(this);
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }
});

function $H(object) {
  if (object && object.constructor == Hash) return object;
  return new Hash(object);
};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
}

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
}

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (typeof responder[callback] == 'function') {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) {}
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate: function() {
    Ajax.activeRequestCount++;
  },
  onComplete: function() {
    Ajax.activeRequestCount--;
  }
});

Ajax.Base = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   ''
    }
    Object.extend(this.options, options || {});

    this.options.method = this.options.method.toLowerCase();
    if (typeof this.options.parameters == 'string')
      this.options.parameters = this.options.parameters.toQueryParams();
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  _complete: false,

  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = this.options.parameters;

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    params = Hash.toQueryString(params);
    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='

    // when GET, append parameters to URL
    if (this.method == 'get' && params)
      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;

    try {
      Ajax.Responders.dispatch('onCreate', this, this.transport);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous)
        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      var body = this.method == 'post' ? (this.options.postBody || params) : null;

      this.transport.send(body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (typeof extras.push == 'function')
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    return !this.transport.status
        || (this.transport.status >= 200 && this.transport.status < 300);
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState];
    var transport = this.transport, json = this.evalJSON();

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport, json);
      } catch (e) {
        this.dispatchException(e);
      }

      if ((this.getHeader('Content-type') || 'text/javascript').strip().
        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
          this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' + state, this, transport, json);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) { return null }
  },

  evalJSON: function() {
    try {
      var json = this.getHeader('X-JSON');
      return json ? eval('(' + json + ')') : null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval(this.transport.responseText);
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, param) {
      this.updateContent();
      onComplete(transport, param);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.container[this.success() ? 'success' : 'failure'];
    var response = this.transport.responseText;

    if (!this.options.evalScripts) response = response.stripScripts();

    if (receiver = $(receiver)) {
      if (this.options.insertion)
        new this.options.insertion(receiver, response);
      else
        receiver.update(response);
    }

    if (this.success()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(container, url, options) {
    this.setOptions(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = {};
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(request) {
    if (this.options.decay) {
      this.decay = (request.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = request.responseText;
    }
    this.timer = setTimeout(this.onTimerEvent.bind(this),
      this.decay * this.frequency * 1000);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (typeof element == 'string')
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(query.snapshotItem(i));
    return results;
  };
}

document.getElementsByClassName = function(className, parentElement) {
  if (Prototype.BrowserFeatures.XPath) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
  } else {
    var children = ($(parentElement) || document.body).getElementsByTagName('*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
      child = children[i];
      if (Element.hasClassName(child, className))
        elements.push(Element.extend(child));
    }
    return elements;
  }
};

/*--------------------------------------------------------------------------*/

if (!window.Element)
  var Element = new Object();

Element.extend = function(element) {
  if (!element || _nativeExtensions || element.nodeType == 3) return element;

  if (!element._extended && element.tagName && element != window) {
    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;

    if (element.tagName == 'FORM')
      Object.extend(methods, Form.Methods);
    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
      Object.extend(methods, Form.Element.Methods);

    Object.extend(methods, Element.Methods.Simulated);

    for (var property in methods) {
      var value = methods[property];
      if (typeof value == 'function' && !(property in element))
        element[property] = cache.findOrStore(value);
    }
  }

  element._extended = true;
  return element;
};

Element.extend.cache = {
  findOrStore: function(value) {
    return this[value] = this[value] || function() {
      return value.apply(null, [this].concat($A(arguments)));
    }
  }
};

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    $(element).style.display = 'none';
    return element;
  },

  show: function(element) {
    $(element).style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, html) {
    html = typeof html == 'undefined' ? '' : html.toString();
    $(element).innerHTML = html.stripScripts();
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  },

  replace: function(element, html) {
    element = $(element);
    html = typeof html == 'undefined' ? '' : html.toString();
    if (element.outerHTML) {
      element.outerHTML = html.stripScripts();
    } else {
      var range = element.ownerDocument.createRange();
      range.selectNodeContents(element);
      element.parentNode.replaceChild(
        range.createContextualFragment(html.stripScripts()), element);
    }
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return $(element).recursivelyCollect('parentNode');
  },

  descendants: function(element) {
    return $A($(element).getElementsByTagName('*'));
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (typeof selector == 'string')
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    return Selector.findElement($(element).ancestors(), expression, index);
  },

  down: function(element, expression, index) {
    return Selector.findElement($(element).descendants(), expression, index);
  },

  previous: function(element, expression, index) {
    return Selector.findElement($(element).previousSiblings(), expression, index);
  },

  next: function(element, expression, index) {
    return Selector.findElement($(element).nextSiblings(), expression, index);
  },

  getElementsBySelector: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  getElementsByClassName: function(element, className) {
    return document.getElementsByClassName(className, element);
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (document.all && !window.opera) {
      var t = Element._attributeTranslations;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name])  name = t.names[name];
      var attribute = element.attributes[name];
      if(attribute) return attribute.nodeValue;
    }
    return element.getAttribute(name);
  },

  getHeight: function(element) {
    return $(element).getDimensions().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    if (elementClassName.length == 0) return false;
    if (elementClassName == className ||
        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
      return true;
    return false;
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element).add(className);
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element).remove(className);
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
    return element;
  },

  observe: function() {
    Event.observe.apply(Event, arguments);
    return $A(arguments).first();
  },

  stopObserving: function() {
    Event.stopObserving.apply(Event, arguments);
    return $A(arguments).first();
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.match(/^\s*$/);
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);
    while (element = element.parentNode)
      if (element == ancestor) return true;
    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = Position.cumulativeOffset(element);
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    if (['float','cssFloat'].include(style))
      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
    style = style.camelize();
    var value = element.style[style];
    if (!value) {
      if (document.defaultView && document.defaultView.getComputedStyle) {
        var css = document.defaultView.getComputedStyle(element, null);
        value = css ? css[style] : null;
      } else if (element.currentStyle) {
        value = element.currentStyle[style];
      }
    }

    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
      value = element['offset'+style.capitalize()] + 'px';

    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
    if(style == 'opacity') {
      if(value) return parseFloat(value);
      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if(value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }
    return value == 'auto' ? null : value;
  },

  setStyle: function(element, style) {
    element = $(element);
    for (var name in style) {
      var value = style[name];
      if(name == 'opacity') {
        if (value == 1) {
          value = (/Gecko/.test(navigator.userAgent) &&
            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
        } else if(value == '') {
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
        } else {
          if(value < 0.00001) value = 0;
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
              'alpha(opacity='+value*100+')';
        }
      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
      element.style[name.camelize()] = value;
    }
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = $(element).getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = element.style.overflow || 'auto';
    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  }
};

Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});

Element._attributeTranslations = {};

Element._attributeTranslations.names = {
  colspan:   "colSpan",
  rowspan:   "rowSpan",
  valign:    "vAlign",
  datetime:  "dateTime",
  accesskey: "accessKey",
  tabindex:  "tabIndex",
  enctype:   "encType",
  maxlength: "maxLength",
  readonly:  "readOnly",
  longdesc:  "longDesc"
};

Element._attributeTranslations.values = {
  _getAttr: function(element, attribute) {
    return element.getAttribute(attribute, 2);
  },

  _flag: function(element, attribute) {
    return $(element).hasAttribute(attribute) ? attribute : null;
  },

  style: function(element) {
    return element.style.cssText.toLowerCase();
  },

  title: function(element) {
    var node = element.getAttributeNode('title');
    return node.specified ? node.nodeValue : null;
  }
};

Object.extend(Element._attributeTranslations.values, {
  href: Element._attributeTranslations.values._getAttr,
  src:  Element._attributeTranslations.values._getAttr,
  disabled: Element._attributeTranslations.values._flag,
  checked:  Element._attributeTranslations.values._flag,
  readonly: Element._attributeTranslations.values._flag,
  multiple: Element._attributeTranslations.values._flag
});

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    var t = Element._attributeTranslations;
    attribute = t.names[attribute] || attribute;
    return $(element).getAttributeNode(attribute).specified;
  }
};

// IE is missing .innerHTML support for TABLE-related elements
if (document.all && !window.opera){
  Element.Methods.update = function(element, html) {
    element = $(element);
    html = typeof html == 'undefined' ? '' : html.toString();
    var tagName = element.tagName.toUpperCase();
    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
      var div = document.createElement('div');
      switch (tagName) {
        case 'THEAD':
        case 'TBODY':
          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
          depth = 2;
          break;
        case 'TR':
          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
          depth = 3;
          break;
        case 'TD':
          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
          depth = 4;
      }
      $A(element.childNodes).each(function(node){
        element.removeChild(node)
      });
      depth.times(function(){ div = div.firstChild });

      $A(div.childNodes).each(
        function(node){ element.appendChild(node) });
    } else {
      element.innerHTML = html.stripScripts();
    }
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  }
};

Object.extend(Element, Element.Methods);

var _nativeExtensions = false;

if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
    var className = 'HTML' + tag + 'Element';
    if(window[className]) return;
    var klass = window[className] = {};
    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
  });

Element.addMethods = function(methods) {
  Object.extend(Element.Methods, methods || {});

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    var cache = Element.extend.cache;
    for (var property in methods) {
      var value = methods[property];
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = cache.findOrStore(value);
    }
  }

  if (typeof HTMLElement != 'undefined') {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
    copy(Form.Methods, HTMLFormElement.prototype);
    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
      copy(Form.Element.Methods, klass.prototype);
    });
    _nativeExtensions = true;
  }
}

var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content.stripScripts();

    if (this.adjacency && this.element.insertAdjacentHTML) {
      try {
        this.element.insertAdjacentHTML(this.adjacency, this.content);
      } catch (e) {
        var tagName = this.element.tagName.toUpperCase();
        if (['TBODY', 'TR'].include(tagName)) {
          this.insertContent(this.contentFromAnonymousTable());
        } else {
          throw e;
        }
      }
    } else {
      this.range = this.element.ownerDocument.createRange();
      if (this.initializeRange) this.initializeRange();
      this.insertContent([this.range.createContextualFragment(this.content)]);
    }

    setTimeout(function() {content.evalScripts()}, 10);
  },

  contentFromAnonymousTable: function() {
    var div = document.createElement('div');
    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
    return $A(div.childNodes[0].childNodes[0].childNodes);
  }
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment, this.element);
    }).bind(this));
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },

  insertContent: function(fragments) {
    fragments.reverse(false).each((function(fragment) {
      this.element.insertBefore(fragment, this.element.firstChild);
    }).bind(this));
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.appendChild(fragment);
    }).bind(this));
  }
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment,
        this.element.nextSibling);
    }).bind(this));
  }
});

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);
var Selector = Class.create();
Selector.prototype = {
  initialize: function(expression) {
    this.params = {classNames: []};
    this.expression = expression.toString().strip();
    this.parseExpression();
    this.compileMatcher();
  },

  parseExpression: function() {
    function abort(message) { throw 'Parse error in selector: ' + message; }

    if (this.expression == '')  abort('empty expression');

    var params = this.params, expr = this.expression, match, modifier, clause, rest;
    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
      params.attributes = params.attributes || [];
      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
      expr = match[1];
    }

    if (expr == '*') return this.params.wildcard = true;

    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
      modifier = match[1], clause = match[2], rest = match[3];
      switch (modifier) {
        case '#':       params.id = clause; break;
        case '.':       params.classNames.push(clause); break;
        case '':
        case undefined: params.tagName = clause.toUpperCase(); break;
        default:        abort(expr.inspect());
      }
      expr = rest;
    }

    if (expr.length > 0) abort(expr.inspect());
  },

  buildMatchExpression: function() {
    var params = this.params, conditions = [], clause;

    if (params.wildcard)
      conditions.push('true');
    if (clause = params.id)
      conditions.push('element.readAttribute("id") == ' + clause.inspect());
    if (clause = params.tagName)
      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
    if ((clause = params.classNames).length > 0)
      for (var i = 0, length = clause.length; i < length; i++)
        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
    if (clause = params.attributes) {
      clause.each(function(attribute) {
        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
        var splitValueBy = function(delimiter) {
          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
        }

        switch (attribute.operator) {
          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
          case '|=':      conditions.push(
                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
                          ); break;
          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
          case '':
          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
        }
      });
    }

    return conditions.join(' && ');
  },

  compileMatcher: function() {
    this.match = new Function('element', 'if (!element.tagName) return false; \
      element = $(element); \
      return ' + this.buildMatchExpression());
  },

  findElements: function(scope) {
    var element;

    if (element = $(this.params.id))
      if (this.match(element))
        if (!scope || Element.childOf(element, scope))
          return [element];

    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');

    var results = [];
    for (var i = 0, length = scope.length; i < length; i++)
      if (this.match(element = scope[i]))
        results.push(Element.extend(element));

    return results;
  },

  toString: function() {
    return this.expression;
  }
}

Object.extend(Selector, {
  matchElements: function(elements, expression) {
    var selector = new Selector(expression);
    return elements.select(selector.match.bind(selector)).map(Element.extend);
  },

  findElement: function(elements, expression, index) {
    if (typeof expression == 'number') index = expression, expression = false;
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    return expressions.map(function(expression) {
      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
        var selector = new Selector(expr);
        return results.inject([], function(elements, result) {
          return elements.concat(selector.findElements(result || element));
        });
      });
    }).flatten();
  }
});

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, getHash) {
    var data = elements.inject({}, function(result, element) {
      if (!element.disabled && element.name) {
        var key = element.name, value = $(element).getValue();
        if (value != undefined) {
          if (result[key]) {
            if (result[key].constructor != Array) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return getHash ? data : Hash.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, getHash) {
    return Form.serializeElements(Form.getElements(form), getHash);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    form.getElements().each(function(element) {
      element.blur();
      element.disabled = 'true';
    });
    return form;
  },

  enable: function(form) {
    form = $(form);
    form.getElements().each(function(element) {
      element.disabled = '';
    });
    return form;
  },

  findFirstElement: function(form) {
    return $(form).getElements().find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  }
}

Object.extend(Form, Form.Methods);

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
}

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = {};
        pair[element.name] = value;
        return Hash.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    element.focus();
    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
      !['button', 'reset', 'submit'].include(element.type) ) )
      element.select();
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = false;
    return element;
  }
}

Object.extend(Form.Element, Form.Element.Methods);
var Field = Form.Element;
var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
      default:
        return Form.Element.Serializers.textarea(element);
    }
  },

  inputSelector: function(element) {
    return element.checked ? element.value : null;
  },

  textarea: function(element) {
    return element.value;
  },

  select: function(element) {
    return this[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
}

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;

    this.lastValue = this.getValue();
    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    var value = this.getValue();
    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
      ? this.lastValue != value : String(this.lastValue) != String(value));
    if (changed) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback.bind(this));
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
}

Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) {
  var Event = new Object();
}

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,

  element: function(event) {
    return event.target || event.srcElement;
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointerX: function(event) {
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

  pointerY: function(event) {
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

  stop: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // find the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  },

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0, length = Event.observers.length; i < length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    Event._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      try {
        element.detachEvent('on' + name, observer);
      } catch (e) {}
    }
  }
});

/* prevent memory leaks in IE */
if (navigator.appVersion.match(/\bMSIE\b/))
  Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  realOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return [valueL, valueT];
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return [valueL, valueT];
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if(element.tagName=='BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p == 'relative' || p == 'absolute') break;
      }
    } while (element);
    return [valueL, valueT];
  },

  offsetParent: function(element) {
    if (element.offsetParent) return element.offsetParent;
    if (element == document.body) return element;

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return element;

    return document.body;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = this.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = this.realOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = this.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  page: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent==document.body)
        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!window.opera || element.tagName=='BODY') {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return [valueL, valueT];
  },

  clone: function(source, target) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || {})

    // find page position of source
    source = $(source);
    var p = Position.page(source);

    // find coordinate system to use
    target = $(target);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(target,'position') == 'absolute') {
      parent = Position.offsetParent(target);
      delta = Position.page(parent);
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
  },

  absolutize: function(element) {
    element = $(element);
    if (element.style.position == 'absolute') return;
    Position.prepare();

    var offsets = Position.positionedOffset(element);
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
  },

  relativize: function(element) {
    element = $(element);
    if (element.style.position == 'relative') return;
    Position.prepare();

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
  }
}

// Safari returns margins on body which is incorrect if the child is absolutely
// positioned.  For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
  Position.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return [valueL, valueT];
  }
}

Element.addMethods();


/**** END:  prototype.js ****/

/**** START: level.js ****/

function upLevel(){

	var form = document.planner;

	// get the current level
	var current_level = parseInt(form.level.value);
	var atpower = parseInt(form.atpower.value);

	var at = parseInt(form.at.value);

	// if not at max level, add one
	if (atpower == 24){
		form.level.value = 50;
		upSlotsLevel();
		return;
	} else {
		var new_level = power_array[atpower];
		form.level.value = new_level;
	}

	makePowerAvailable(new_level, 'prim',   14);
	makePowerAvailable(new_level, 'sec',    12);
	makePowerAvailable(new_level, 'pool1_', 4);
	makePowerAvailable(new_level, 'pool2_', 4);
	makePowerAvailable(new_level, 'pool3_', 4);
	makePowerAvailable(new_level, 'pool4_', 4);
	makePowerAvailable(new_level, 'app', 4);

	if (new_level >= 4){
		upSlotsLevel();
	}

	if (at == 11 || at == 12){
		if (current_level == 1){
			var ao = new AjaxObject();
			ao.sndReq('get','/ajax.php?op=power_khelds&x=01&y='+at);
		}
		else if(new_level == 10){
			var ao = new AjaxObject();
			ao.sndReq('get','/ajax.php?op=power_khelds&x=10&y='+at);
		}
	}
}

function upSlotsLevel(){	
	var form = document.planner;
	
	var enh_level = parseInt(form.enh_level.value);
	var level = parseInt(form.level.value);
	var atslots = parseInt(form.atslots.value);
	
	if ((enh_level == 50 && level == 50) && form.slots.value == 0){
		return;
	}
	
	if (atslots == 0){
		form.enh_level.value = slot_array[1];
		form.atslots.value = 1;
	}
/*
	else if (atslots == 26){
		form.enh_level.value = 50;
		form.atslots.value = parseInt(form.atslots.value) + 1;			
	}
*/	
	else if (atslots > 27){
		return;
	}
	else {
		if (form.slots.value == 0){
			form.enh_level.value = slot_array[parseInt(form.atslots.value)+1];
			form.atslots.value = parseInt(form.atslots.value) + 1;			
		}
	}
	
	makeSlotsAvailable();
}


/* GO BACK
*************************************************/
// only handle going back for powers
function goBackPower(){

	var form = document.planner;
	
	// get the current data
	var at = parseInt(form.at.value);
	level = parseInt(form.level.value);
	slots = parseInt(form.enh_level.value);
	atpower = parseInt(form.atpower.value);
	// calculate new level
	new_level = power_array[atpower-1];
	
	// if it's level 1  we ain't gotta do jack
	if (level == 1){
		resetPowers();
		return;
	} 
	else if (level == 2) {
		// reset power selections
		for ( x=1; x <= 40; x++ ){
			if (x != 25 && x != 26 && x != 27){
				document.getElementById('seltext'+x).innerHTML = '';
			}
			for (i=1; i<=6;i++){
				li = 'li_' + x + '_' + i;
				document.getElementById(li).innerHTML = '';
			}
		}
		
		// reset selected power td's
		for ( x=1; x <= 9; x++ ){
			document.getElementById('prim'+x).className = 'none';
		}
		
		document.planner.level.value = 1;
		document.planner.atpower.value = 0;

		document.planner.pool1.disabled = false;
		document.planner.pool2.disabled = false;
		document.planner.pool3.disabled = false;
		document.planner.pool4.disabled = false;
		document.planner.app.disabled   = false;

		makePowerAvailable(1, 'prim',   14);
		makePowerAvailable(1, 'sec',    12);
		makePowerAvailable(1, 'pool1_', 4);
		makePowerAvailable(1, 'pool2_', 4);
		makePowerAvailable(1, 'pool3_', 4);
		makePowerAvailable(1, 'pool4_', 4);

		setTimeout("fillSpan('1',document.getElementById('sec1').name, 'sec1')",100);

		return;
	}
	
	pname = document.getElementById('seltext'+atpower).innerHTML;
	$('seltext'+atpower).innerHTML = '';
	
	for (i=1;i<=6;i++){
		li = 'li_' + atpower + '_' + i;
		$(li).innerHTML = '';
	}

	tds = getElementsByClassName(document, 'li', 'selected');	
	for (y=0; y<tds.length; y++){
		if (tds[y].innerHTML == pname){
			tds[y].className = 'available';
			break;
		}
	}
	
	if (at == 11 || at == 12){
		for (x=28; x<=40; x++){
			if ($('seltext'+x).innerHTML.match(pname)){
				$('seltext'+x).innerHTML = '';
				for (i=1;i<=6;i++){
					li = 'li_' + x + '_' + i;
					$(li).innerHTML = '';
				}
				$('selection'+x).innerHTML = $('selection'+x).innerHTML.replace(/\(\d+\)/,'');
			}
			
			if (new_level < 10){
				if ($('seltext'+x).innerHTML == 'Combat Flight' || $('seltext'+x).innerHTML == 'Shadow Recall'){
					$('seltext'+x).innerHTML = '';
					for (i=1;i<=6;i++){
						li = 'li_' + x + '_' + i;
						$(li).innerHTML = '';
					}
					$('selection'+x).innerHTML = $('selection'+x).innerHTML.replace(/\(\d+\)/,'');
				}
			}
		}
	}
	
	form.atpower.value = form.atpower.value-1;
	form.level.value = new_level;
	
	makePowerAvailable(new_level, 'prim',   14);
	makePowerAvailable(new_level, 'sec',    12);
	makePowerAvailable(new_level, 'pool1_', 4);
	makePowerAvailable(new_level, 'pool2_', 4);
	makePowerAvailable(new_level, 'pool3_', 4);
	makePowerAvailable(new_level, 'pool4_', 4);
	makePowerAvailable(new_level, 'app', 4);
	
	if (slots >= new_level){
		goBackSlots();
	}
}


function goBackSlots(){
	
	var form = document.planner;
	
	// get the current data
	level = parseInt(form.level.value);
	slots = parseInt(form.enh_level.value);
	atpower = parseInt(form.atpower.value);
	atslots = parseInt(form.atslots.value);
	
	if (slots <= 3){
		// go through "regular" powers
		for ( x=1; x<=3; x++)	{
			for (i=2; i<=3; i++){
				li = 'li_' + x + '_' + i;				
				document.getElementById(li).innerHTML = '';
			}
		}
	
		if (level >=3){
			form.enh_level.value = 3;
			setTimeout("makeSlotsAvailable();",500);
		}
		else {
			form.enh_level.value = 0;
		}		
		
		return;
	} 

	// get the new slot level
	new_slots = slot_array[parseInt(atslots)-1];

	// go through "regular" powers
	for ( x=1; x<=atpower; x++)	{
		for (i=2; i<=6; i++){
			li = 'li_' + x + '_' + i;
			stuff = document.getElementById(li);
			for (z=0; z<stuff.childNodes.length; z++){
				try	{
					if (parseInt((stuff.childNodes[z]).childNodes[0].alt) >= new_slots){
						document.getElementById(li).innerHTML = '';	
					}
					else if ((stuff.childNodes[z]).childNodes[0].src.match(/new.gif/)){
						document.getElementById(li).innerHTML = '';
					}
				}catch (e) {}
			}
		}
	}
	
	// go through inherent powers
	if (at == 11 || at == 12){
		next_x = 40;
	} 
	else {
		next_x = 27;
	}
	
	for ( x=25; x<=next_x; x++){
		for (i=6; i>=2; i--){
			li = 'li_' + x + '_' + i;
			stuff = document.getElementById(li);
			for (z=0; z<stuff.childNodes.length; z++){
				try{
					if (parseInt((stuff.childNodes[z]).childNodes[0].alt) >= new_slots){
						document.getElementById(li).innerHTML = '';	
					}
					else if ((stuff.childNodes[z]).childNodes[0].src.match(/new.gif/)){
						document.getElementById(li).innerHTML = '';
					}
				}
				catch (e) {}
			}
		}
		
	}
	
	form.enh_level.value = new_slots;
	form.atslots.value = parseInt(atslots)-1;
	setTimeout("makeSlotsAvailable();",500);	
}


/**** END:  level.js ****/

/**** START: static.js ****/

/* STATIC LEVEL AND POWER DATA
*************************************************/
// levels you select a power
power_levels = ",1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,35,38,41,44,47,49,";

var power_array = new Array();
power_array[0] = 1;
power_array[1] = 1;
power_array[2] = 2;
power_array[3] = 4;
power_array[4] = 6;
power_array[5] = 8;
power_array[6] = 10;
power_array[7] = 12;
power_array[8] = 14;
power_array[9] = 16;
power_array[10] = 18;
power_array[11] = 20;
power_array[12] = 22;
power_array[13] = 24;
power_array[14] = 26;
power_array[15] = 28;
power_array[16] = 30;
power_array[17] = 32;
power_array[18] = 35;
power_array[19] = 38;
power_array[20] = 41;
power_array[21] = 44;
power_array[22] = 47;
power_array[23] = 49;


// levels you get slots
slot_levels = ",3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,34,36,37,39,40,42,43,45,46,48,50,";

var slot_array = new Array();
slot_array[0] = 0;
slot_array[1] = 3;
slot_array[2] = 5;
slot_array[3] = 7;
slot_array[4] = 9;
slot_array[5] = 11;
slot_array[6] = 13;
slot_array[7] = 15;
slot_array[8] = 17;
slot_array[9] = 19;
slot_array[10] = 21;
slot_array[11] = 23;
slot_array[12] = 25;
slot_array[13] = 27;
slot_array[14] = 29;
slot_array[15] = 31;
slot_array[16] = 33;
slot_array[17] = 34;
slot_array[18] = 36;
slot_array[19] = 37;
slot_array[20] = 39;
slot_array[21] = 40;
slot_array[22] = 42;
slot_array[23] = 43;
slot_array[24] = 45;
slot_array[25] = 46;
slot_array[26] = 48;
slot_array[27] = 50;


// # of slots you get at each level
var slot_amounts = new Array();
slot_amounts[3]  = 2;
slot_amounts[5]  = 2;
slot_amounts[7]  = 2;
slot_amounts[9]  = 2;
slot_amounts[11] = 2;
slot_amounts[13] = 2;
slot_amounts[15] = 2;
slot_amounts[17] = 2;
slot_amounts[19] = 2;
slot_amounts[21] = 2;
slot_amounts[23] = 2;
slot_amounts[25] = 2;
slot_amounts[27] = 2;
slot_amounts[29] = 2;
slot_amounts[31] = 3;
slot_amounts[33] = 3;
slot_amounts[34] = 3;
slot_amounts[36] = 3;
slot_amounts[37] = 3;
slot_amounts[39] = 3;
slot_amounts[40] = 3;
slot_amounts[42] = 3;
slot_amounts[43] = 3;
slot_amounts[45] = 3;
slot_amounts[46] = 3;
slot_amounts[48] = 3;
slot_amounts[50] = 3;

// primary table vs level available
var pri_levs = new Array();
pri_levs[1] = 1;
pri_levs[2] = 1;
pri_levs[3] = 2;
pri_levs[4] = 6;
pri_levs[5] = 8;
pri_levs[6] = 12;
pri_levs[7] = 18;
pri_levs[8] = 26;
pri_levs[9] = 32;

var k_pri_levs = new Array();
k_pri_levs[1] = 1;
k_pri_levs[2] = 1;
k_pri_levs[3] = 2;
k_pri_levs[4] = 6;
k_pri_levs[5] = 6;
k_pri_levs[6] = 8;
k_pri_levs[7] = 12;
k_pri_levs[8] = 12;
k_pri_levs[9] = 18;
k_pri_levs[10] = 18;
k_pri_levs[11] = 26;
k_pri_levs[12] = 26;
k_pri_levs[13] = 32;
k_pri_levs[14] = 32;


// primary table vs level available
var sec_levs = new Array();
sec_levs[1] = 0;
sec_levs[2] = 2;
sec_levs[3] = 4;
sec_levs[4] = 10;
sec_levs[5] = 16;
sec_levs[6] = 20;
sec_levs[7] = 28;
sec_levs[8] = 35;
sec_levs[9] = 38;

var k_sec_levs = new Array();
k_sec_levs[1] = 0;
k_sec_levs[2] = 2;
k_sec_levs[3] = 4;
k_sec_levs[4] = 10;
k_sec_levs[5] = 14;
k_sec_levs[6] = 16;
k_sec_levs[7] = 20;
k_sec_levs[8] = 22;
k_sec_levs[9] = 24;
k_sec_levs[10] = 28;
k_sec_levs[11] = 35;
k_sec_levs[12] = 38;


var poo_levs = new Array();
poo_levs[1] = 6;
poo_levs[2] = 6;
poo_levs[3] = 14;
poo_levs[4] = 20;

var app_levs = new Array();
app_levs[1] = 41;
app_levs[2] = 41;
app_levs[3] = 44;
app_levs[4] = 47;


var inh_ids = new Array();
inh_ids[25] = 5831;
inh_ids[26] = 5832;
inh_ids[27] = 5833;


var ho_list = new Object();
ho_list['Nucleolus Exposure'] = 'Damage,Accuracy';
ho_list['Centriole Exposure'] = 'Damage,Range';
ho_list['Peroxisome Exposure'] = 'Accuracy,Hold Duration, Disorient Duration,Confusion Duration,Fear Duration,Intangibility,Immobilize';
ho_list['Endoplasm Exposure'] = 'Accuracy,Hold Duration, Disorient Duration,Confusion Duration,Fear Duration,Intangibility,Immobilize';
ho_list['Golgi Exposure'] = 'Heal,Endurance Cost';
ho_list['Ribosome Exposure'] = 'Damage Resistance,Endurance Cost';
ho_list['Microfilament Exposure'] = 'Flight Speed, Running Speed, Jump,Endurance Cost';
ho_list['Lysosome Exposure'] = 'ToHit Buff,ToHit Debuff,Defense Buff,Defense Debuffs,Accuracy';
ho_list['Enzyme Exposure'] = 'ToHit Buff,ToHit Debuff,Defense Buff,Defense Debuffs,Endurance Cost';
ho_list['Membrane Exposure'] = 'ToHit Buff,ToHit Debuff,Defence Debuffs,Defense Buffs,Attack Rate';
ho_list['Cytoskeleton Exposure'] = 'ToHit Buff,Defense Buffs,Endurance Cost';

var brute = new Array();var corruptor = new Array();var dominator = new Array();
var mastermind = new Array();var stalker = new Array();var blaster = new Array();
var controller = new Array();var defender = new Array();var scrapper = new Array();
var tanker = new Array();var peacebringer = new Array();var warshade = new Array();

brute[1] = "1|Dark Melee,2|Fiery Melee,4|Stone Melee,5|Super Strength,113|Energy Melee,123|Electric Melee,509|Dual Blades";
brute[2] = "6|Dark Armor,7|Fiery Aura,9|Invulnerability,10|Stone Armor,114|Energy Aura,124|Electric Armor,510|Willpower";
brute[4] = "489|Leviathan Mastery,490|Mace Mastery,491|Mu Mastery,492|Soul Mastery";
corruptor[1] = "11|Assault Rifle,12|Dark Blast,13|Energy Blast,14|Fire Blast,15|Ice Blast,16|Radiation Blast,17|Sonic Blast";
corruptor[2] = "18|Cold Domination,19|Dark Miasma,20|Kinetics,21|Thermal Radiation,22|Traps,23|Radiation Emission,116|Sonic Resonance";
corruptor[4] = "493|Leviathan Mastery,494|Mace Mastery,495|Mu Mastery,496|Soul Mastery";
dominator[1] = "24|Fire Control,25|Gravity Control,26|Ice Control,27|Mind Control,28|Plant Control";
dominator[2] = "29|Energy Assault,30|Fiery Assault,31|Icy Assault,32|Psionic Assault,117|Thorny Assault";
dominator[4] = "497|Leviathan Mastery,498|Mace Mastery,499|Mu Mastery,500|Soul Mastery";
mastermind[1] = "34|Mercenaries,35|Necromancy,36|Ninjas,37|Robotics,125|Thugs";
mastermind[2] = "38|Traps,39|Dark Miasma,40|Force Field,41|Poison,42|Trick Arrow";
mastermind[4] = "501|Leviathan Mastery,502|Mace Mastery,503|Mu Mastery,504|Soul Mastery";
stalker[1] = "43|Claws,44|Energy Melee,45|Ninja Blade,46|Martial Arts,47|Spines,126|Dark Melee,511|Dual Blades";
stalker[2] = "48|Energy Aura,50|Regeneration,51|Super Reflexes,118|Ninjitsu,127|Dark Armor,512|Willpower";
stalker[4] = "505|Leviathan Mastery,506|Mace Mastery,507|Mu Mastery,508|Soul Mastery";
blaster[1] = "52|Assault Rifle,53|Fire Blast,54|Energy Blast,55|Electrical Blast,56|Ice Blast,57|Sonic Blast,58|Archery";
blaster[2] = "59|Devices,60|Energy Manipulation,61|Electricity Manipulation,62|Fire Manipulation,63|Ice Manipulation";
blaster[4] = "467|Cold Mastery,468|Electrical Mastery,469|Flame Mastery,470|Force Mastery,471|Munitions Mastery";
controller[1] = "64|Earth Control,65|Fire Control,66|Gravity Control,67|Ice Control,68|Illusion Control,69|Mind Control";
controller[2] = "70|Empathy,71|Force Field,72|Kinetics,73|Radiation Emission,74|Storm Summoning,75|Trick Arrow,76|Sonic Resonance";
controller[4] = "472|Fire Mastery,473|Ice Mastery,474|Primal Forces Mastery,475|Psionic Mastery,476|Stone Mastery";
defender[1] = "77|Dark Miasma,78|Empathy,79|Force Field,80|Kinetics,81|Radiation Emission,82|Storm Summoning,83|Trick Arrow,84|Sonic Resonance";
defender[2] = "85|Electrical Blast,86|Energy Blast,87|Dark Blast,88|Psychic Blast,89|Radiation Blast,90|Archery,91|Sonic Blast";
defender[4] = "477|Dark Mastery,478|Electricity Mastery,479|Power Mastery,480|Psychic Mastery";
scrapper[1] = "92|Broad Sword,93|Claws,94|Dark Melee,95|Katana,96|Martial Arts,97|Spines,513|Dual Blades";
scrapper[2] = "98|Dark Armor,99|Invulnerability,100|Regeneration,101|Super Reflexes,514|Willpower";
scrapper[4] = "481|Body Mastery,482|Darkness Mastery,483|Weapon Mastery";
tanker[1] = "102|Invulnerability,103|Fiery Aura,104|Ice Armor,105|Stone Armor,515|Willpower";
tanker[2] = "106|Battle Axe,107|Fiery Melee,108|Ice Melee,109|Energy Melee,110|Stone Melee,111|Super Strength,112|War Mace,516|Dual Blades";
tanker[4] = "485|Arctic Mastery,486|Earth Mastery,487|Energy Mastery,488|Pyre Mastery";
peacebringer[1] = "119|Luminous Blast";
peacebringer[2] = "120|Luminous Aura";
peacebringer[4] = "";
warshade[1] = "121|Umbral Blast";
warshade[2] = "122|Umbral Aura";
warshade[4] = "";

var powers = new Array();

powers[1] = "5109|Shadow Punch,5110|Smite,5111|Shadow Maul,5112|Touch of Fear,5113|Siphon Life,5114|Taunt,5115|Dark Consumption,5116|Soul Drain,5117|Midnight Grasp";
powers[2] = "5118|Scorch,5120|Fire Sword,5122|Cremate,5126|Build Up,5131|Incinerate,5128|Taunt,5124|Breath of Fire,5129|Fire Sword Circle,5133|Greater Fire Sword";
powers[4] = "5135|Stone Fist,5136|Stone Mallet,5137|Heavy Mallet,5138|Build Up,5140|Fault,5141|Taunt,5142|Seismic Smash,5143|Hurl Boulder,5145|Tremor";
powers[5] = "5223|Jab,5224|Punch,5225|Haymaker,5226|Hand Clap,5227|Knockout Blow,5228|Taunt,5229|Rage,5230|Hurl,5231|Foot Stomp";
powers[6] = "5146|Dark Embrace,5148|Death Shroud,5150|Murky Cloud,5152|Obsidian Shield,5154|Dark Regeneration,5155|Cloak of Darkness,5157|Cloak of Fear,5159|Oppressive Gloom,5160|Soul Transfer";
powers[7] = "5161|Fire Shield,5163|Blazing Aura,5165|Healing Flames,5167|Temperature Protection,5169|Plasma Shield,5171|Consume,5173|Burn,5175|Fiery Embrace,5177|Rise of the Phoenix";
powers[9] = "5179|Resist Physical Damage,5181|Temp Invulnerability,5183|Dull Pain,5185|Resist Elements,5187|Unyielding,5189|Resist Energies,5191|Invincibility,5193|Tough Hide,5195|Unstoppable";
powers[10] = "5197|Rock Armor,5199|Stone Skin,5201|Earth's Embrace,5203|Mud Pots,5204|Rooted,5206|Brimstone Armor,5208|Crystal Armor,5210|Minerals,5212|Granite Armor";
powers[113] = "5214|Barrage,5215|Energy Punch,5216|Bone Smasher,5217|Build Up,5218|Whirling Hands,5219|Taunt,5220|Total Focus,5221|Stun,5222|Energy Transfer";
powers[114] = "5232|Kinetic Shield,5233|Dampening Field,5234|Power Shield,5235|Entropy Shield,5236|Energy Protection,5237|Energy Cloak,5238|Energy Drain,5239|Conserve Power,5240|Overload";
powers[123] = "2369|Charged Brawl,2370|Havoc Punch,2371|Jacobs Ladder,2372|Build Up,2373|Thunder Strike,2374|Taunt,2375|Chain Induction,2376|Lightning Clap,2377|Lightning Rod";
powers[124] = "2378|Charged Armor,2379|Lightning Field,2380|Conductive Shield,2381|Static Shield,2382|Grounded,2383|Lightning Reflexes,2384|Conserve Power,2385|Power Sink,2386|Power Surge";
powers[489] = "2498|Spirit Shark,2499|School of Sharks,2500|Bile Spray,2501|Summon Guardian";
powers[490] = "2502|Mace Blast,2503|Web Envelope,2504|Disruptor Blast,2505|Summon Blaster";
powers[491] = "2506|Mu Lightning,2507|Electrifying Fences,2508|Ball Lightning,2509|Summon Striker";
powers[492] = "2510|Gloom,2511|Soul Tentacles,2512|Dark Obliteration,2513|Summon Widow";
powers[11] = "5241|Burst,5242|Slug,5243|Buckshot,5244|M30 Grenade,5245|Beanbag,5247|Sniper Rifle,5249|Flamethrower,5251|Ignite,5253|Full Auto";
powers[12] = "5255|Dark Blast,5256|Gloom,5257|Moonbeam,5258|Dark Pit,5259|Tenebrous Tentacles,5260|Night Fall,5261|Torrent,5262|Life Drain,5263|Blackstar";
powers[13] = "5264|Power Bolt,5265|Power Blast,5266|Energy Torrent,5267|Power Burst,5268|Sniper Blast,5270|Aim,5272|Power Push,5273|Explosive Blast,5274|Nova";
powers[14] = "5275|Flares,5277|Fire Blast,5279|Fire Ball,5281|Rain of Fire,5283|Fire Breath,5285|Aim,5287|Blaze,5289|Blazing Bolt,5291|Inferno";
powers[15] = "5292|Ice Bolt,5293|Ice Blast,5294|Frost Breath,5296|Aim,5298|Freeze Ray,5299|Ice Storm,5300|Bitter Ice Blast,5301|Bitter Freeze Ray,5302|Blizzard";
powers[16] = "5303|Neutrino Bolt,5305|X-Ray Beam,5306|Irradiate,5307|Electron Haze,5308|Proton Volley,5309|Aim,5311|Cosmic Burst,5312|Neutron Bomb,5313|Atomic Blast";
powers[17] = "5314|Shriek,5316|Scream,5318|Howl,5320|Shockwave,5322|Shout,5324|Amplify,5326|Sirens Song,5328|Screech,5330|Dreadful Wail";
powers[18] = "5332|Infrigidate,5333|Ice Shield,5334|Snow Storm,5335|Glacial Shield,5336|Frostwork,5337|Arctic Fog,5338|Benumb,5339|Sleet,5340|Heat Loss";
powers[19] = "5341|Twilight Grasp,5342|Tar Patch,5343|Darkest Night,5344|Howling Twilight,5345|Shadow Fall,5346|Fearsome Stare,5347|Petrifying Gaze,5349|Black Hole,5350|Dark Servant";
powers[20] = "5352|Transfusion,5353|Siphon Power,5354|Repel,5356|Siphon Speed,5357|Increase Density,5358|Speed Boost,5359|Inertial Reduction,5360|Transference,5361|Fulcrum Shift";
powers[21] = "5362|Warmth,5363|Fire Shield,5365|Cauterize,5367|Plasma Shield,5369|Power of the Phoenix,5371|Thaw,5372|Forge,5374|Heat Exhaustion,5376|Melt Armor";
powers[22] = "5396|Web Grenade,5397|Caltrops,5398|Triage Beacon,5399|Acid Mortar,5400|Force Field Generator,5401|Poison Trap,5402|Seeker Drones,5403|Trip Mine,5405|Time Bomb";
powers[23] = "5377|Radiant Aura,5378|Radiation Infection,5379|Accelerate Metabolism,5380|Enervating Field,5381|Mutation,5382|Lingering Radiation,5383|Choking Cloud,5384|Fallout,5386|EM Pulse";
powers[116] = "5387|Sonic Siphon,5388|Sonic Barrier,5389|Sonic Haven,5390|Sonic Cage,5391|Disruption Field,5394|Sonic Dispersion,5393|Sonic Repulsion,5392|Clarity,5395|Liquefy";
powers[493] = "2514|School of Sharks,2515|Shark Skin,2516|Spirit Shark Jaws,2517|Summon Coralax";
powers[494] = "2518|Web Envelope,2519|Scorpion Shield,2520|Web Cocoon,2521|Summon Disruptor";
powers[495] = "2522|Power Sink,2523|Charged Armor,2524|Electric Shackles,2525|Summon Adept";
powers[496] = "2526|Soul Drain,2527|Dark Embrace,2528|Soul Storm,2529|Summon Mistress";
powers[24] = "5407|Ring of Fire,5408|Char,5409|Fire Cages,5410|Smoke,5411|Hot Feet,5412|Flashfire,5413|Cinders,5414|Bonfire,5415|Fire Imps";
powers[25] = "5417|Crush,5418|Lift,5420|Gravity Distortion,5421|Propel,5423|Crushing Field,5424|Dimension Shift,5426|Gravity Distortion Field,5428|Wormhole,5430|Singularity";
powers[26] = "5432|Chilblain,5434|Block of Ice,5435|Frostbite,5436|Arctic Air,5437|Shiver,5438|Ice Slick,5439|Flash Freeze,5440|Glacier,5441|Jack Frost";
powers[27] = "5442|Mesmerize,5443|Levitate,5445|Dominate,5446|Confuse,5447|Mass Hypnosis,5448|Telekinesis,5449|Total Domination,5450|Terrify,5451|Mass Confusion";
powers[28] = "5452|Entangle,5453|Strangler,5454|Roots,5455|Spore Burst,5457|Seeds of Confusion,5458|Spirit Tree,5460|Vines,5462|Carrion Creepers,5464|Fly Trap";
powers[29] = "5466|Power Bolt,5467|Bone Smasher,5468|Power Push,5469|Power Blast,5470|Power Boost,5472|Whirling Hands,5474|Total Focus,5476|Sniper Blast,5478|Power Burst";
powers[30] = "5479|Flares,5481|Incinerate,5483|Fire Breath,5485|Fire Blast,5487|Fiery Embrace,5489|Combustion,5491|Consume,5493|Blazing Bolt,5495|Blaze";
powers[31] = "5497|Ice Bolt,5498|Ice Sword,5499|Ice Sword Circle,5501|Ice Blast,5502|Power Boost,5504|Frost Breath,5506|Chilling Embrace,5507|Greater Ice Sword,5508|Bitter Ice Blast";
powers[32] = "5509|Psionic Dart,5510|Mind Probe,5511|Telekinetic Thrust,5513|Mental Blast,5514|Psychic Scream,5515|Drain Psyche,5516|Subdue,5517|Psionic Lance,5518|Psychic Shockwave";
powers[117] = "5519|Thorny Darts,5520|Skewer,5521|Fling Thorns,5522|Impale,5523|Aim,5524|Thorn Burst,5525|Thorntrops,5526|Ripper,5527|Thorn Barrage";
powers[497] = "2530|Water Spout,2531|Bile Spray,2532|Shark Skin,2533|Summon Coralax";
powers[498] = "2534|Poisonous Ray,2535|Scorpion Shield,2536|Disruptor Blast,2537|Summon Tarantula";
powers[499] = "2538|Power Sink,2539|Charged Armor,2540|Ball Lightning,2541|Summon Guardian";
powers[500] = "2542|Dark Consumption,2543|Dark Embrace,2544|Dark Obliteration,2545|Summon Seer";
powers[34] = "5528|Burst,5529|Soldiers,5531|Slug,5533|Equip Mercenary,5535|M30 Grenade,5537|Spec Ops,5539|Serum,5541|Commando,5543|Tactical Upgrade";
powers[35] = "5545|Dark Blast,5547|Zombie Horde,5549|Gloom,5551|Enchant Undead,5553|Life Drain,5555|Grave Knight,5557|Soul Extraction,5559|Lich,5561|Dark Empowerment";
powers[36] = "5563|Snap Shot,5565|Call Genin,5567|Aimed Shot,5569|Train Ninjas,5571|Fistful of Arrows,5573|Call Jounin,5575|Smoke Flash,5577|Oni,5579|Kuji In Zen";
powers[37] = "5581|Pulse Rifle Blast,5583|Battle Drones,5585|Pulse Rifle Burst,5587|Equip Robot,5589|Photon Grenade,5591|Protector Bots,5593|Repair,5595|Assault Bot,5597|Upgrade Robot";
powers[38] = "5599|Web Grenade,5601|Caltrops,5603|Triage Beacon,5605|Acid Mortar,5607|Force Field Generator,5609|Poison Trap,5611|Seeker Drones,5613|Trip Mine,5615|Detonator";
powers[39] = "5617|Twilight Grasp,5619|Tar Patch,5621|Darkest Night,5623|Howling Twilight,5625|Shadow Fall,5627|Fearsome Stare,5629|Petrifying Gaze,5631|Black Hole,5633|Dark Servant";
powers[40] = "5635|Force Bolt,5636|Deflection Shield,5637|Insulation Shield,5638|Detention Field,5639|Personal Force Field,5640|Dispersion Bubble,5641|Repulsion Field,5642|Repulsion Bomb,5643|Force Bubble";
powers[41] = "5644|Alkaloid,5646|Envenom,5648|Weaken,5650|Neurotoxic Breath,5652|Elixir of Life,5654|Antidote,5656|Paralytic Poison,5658|Poison Trap,5660|Noxious Gas";
powers[42] = "5662|Entangling Arrow,5664|Flash Arrow,5666|Glue Arrow,5668|Ice Arrow,5670|Poison Gas Arrow,5672|Acid Arrow,5674|Disruption Arrow,5676|Oil Slick Arrow,5678|EMP Arrow";
powers[125] = "2387|Pistols,2388|Call Thugs,2389|Dual Wield,2390|Equip Thugs,2391|Empty Clips,2392|Call Enforcer,2393|Gang War,2394|Call Bruiser,2395|Upgrade Equipment";
powers[501] = "2546|School of Sharks,2547|Bile Spray,2548|Shark Skin,2549|Spirit Shark Jaws";
powers[502] = "2550|Web Envelope,2551|Scorpion Shield,2552|Mace Beam Volley,2553|Web Cocoon";
powers[503] = "2554|Static Discharge,2555|Charged Armor,2556|Electrifying Fences,2557|Electric Shackles";
powers[504] = "2558|Night Fall,2559|Dark Embrace,2560|Soul Tentacles,2561|Soul Storm";
powers[43] = "5680|Swipe,5681|Strike,5683|Slash,5685|Assassin's Claw,5687|Build Up,5689|Placate,5691|Focus,5693|Eviscerate,5695|Shockwave";
powers[44] = "5697|Barrage,5699|Energy Punch,5701|Bone Smasher,5703|Assassin's Strike,5705|Build Up,5707|Placate,5709|Stun,5711|Energy Transfer,5713|Total Focus";
powers[45] = "5715|Sting of the Wasp,5717|Gambler's Cut,5719|Flashing Steel,5721|Assassin's Blade,5723|Build Up,5725|Placate,5727|Divine Avalanche,5729|Soaring Dragon,5731|Golden Dragonfly";
powers[46] = "5733|Thunder Kick,5735|Storm Kick,5737|Crippling Axe Kick,5739|Assassin's Blow,5741|Focus Chi,5743|Placate,5745|Cobra Strike,5747|Crane Kick,5749|Eagles Claw";
powers[47] = "5751|Barb Swipe,5753|Lunge,5755|Spine Burst,5757|Assassin's Impaler,5759|Build Up,5761|Placate,5763|Impale,5765|Ripper,5767|Throw Spines";
powers[48] = "5769|Hide,5771|Kinetic Shield,5773|Power Shield,5775|Entropy Shield,5777|Energy Protection,5779|Repulse,5781|Energy Drain,5783|Conserve Power,5785|Overload";
powers[50] = "5796|Hide,5798|Fast Healing,5800|Reconstruction,5802|Dull Pain,5804|Integration,5806|Resilience,5808|Instant Healing,5810|Revive,5812|Moment of Glory";
powers[51] = "5814|Hide,5816|Focused Fighting,5818|Focused Senses,5820|Agile,5822|Practiced Brawler,5824|Dodge,5826|Quickness,5828|Evasion,5830|Elude";
powers[118] = "5787|Hide,5788|Ninja Reflexes,5789|Danger Sense,5790|Caltrops,5791|Kuji-In Rin,5792|Kuji-In Sha,5793|Smoke Flash,5794|Blinding Powder,5795|Kuji-In Retsu";
powers[126] = "2396|Shadow Punch,2397|Smite,2398|Shadow Maul,2399|Assassins Eclipse,2400|Build Up,2401|Placate,2402|Siphon Life,2403|Touch of Fear,2404|Midnight Grasp";
powers[127] = "2405|Hide,2406|Dark Embrace,2407|Murky Cloud,2408|Shadow Dweller,2409|Obsidian Shield,2410|Dark Regeneration,2411|Cloak of Fear,2412|Oppressive Gloom,2413|Soul Transfer";
powers[505] = "2562|Spirit Shark,2563|Water Spout,2564|Spirit Shark Jaws,2565|Summon Guardian";
powers[506] = "2566|Mace Blast,2567|Mace Beam,2568|Web Cocoon,2569|Summon Spiderlings";
powers[507] = "2570|Mu Bolts,2571|Zapp,2572|Electric Shackles,2573|Summon Adept";
powers[508] = "2574|Dark Blast,2575|Moonbeam,2576|Soul Storm,2577|Summon Widow";
powers[52] = "1064|Burst,1066|Slug,1068|Buckshot,1070|M30 Grenade,1072|Beanbag,1074|Sniper Rifle,1076|Flamethrower,1078|Ignite,1080|Full Auto";
powers[53] = "1118|Flares,1120|Fire Blast,1122|Fire Ball,1124|Rain of Fire,1126|Fire Breath,1128|Aim,1130|Blaze,1132|Blazing Bolt,1134|Inferno";
powers[54] = "1100|Power Bolt,1102|Power Blast,1104|Energy Torrent,1106|Power Burst,1108|Sniper Blast,1110|Aim,1112|Power Push,1114|Explosive Blast,1116|Nova";
powers[55] = "1082|Charged Bolts,1084|Lightning Bolt,1086|Ball Lightning,1088|Short Circuit,1090|Aim,1092|Zapp,1094|Tesla Cage,1096|Voltaic Sentinel,1098|Thunderous Blast";
powers[56] = "1136|Ice Bolt,1138|Ice Blast,1140|Frost Breath,1142|Aim,1144|Freeze Ray,1146|Ice Storm,1148|Bitter Ice Blast,1150|Bitter Freeze Ray,1152|Blizzard";
powers[57] = "1154|Shriek,1156|Scream,1158|Howl,1160|Shockwave,1162|Shout,1164|Amplify,1166|Sirens Song,1168|Screech,1170|Dreadful Wail";
powers[58] = "1047|Snap Shot,1048|Aimed Shot,1050|Fistful of Arrows,1052|Blazing Arrow,1054|Aim,1056|Explosive Arrow,1058|Ranged Shot,1060|Stunning Shot,1062|Rain of Arrows";
powers[59] = "1172|Web Grenade,1174|Caltrops,1176|Taser,1178|Targeting Drone,1180|Smoke Grenade,1182|Cloaking Device,1184|Trip Mine,1186|Time Bomb,1188|Auto Turret";
powers[60] = "1190|Power Thrust,1192|Energy Punch,1194|Build Up,1196|Bone Smasher,1198|Conserve Power,1200|Stun,1202|Power Boost,1204|Boost Range,1206|Total Focus";
powers[61] = "1208|Electric Fence,1210|Charged Brawl,1212|Lightning Field,1214|Havoc Punch,1216|Build Up,1218|Lightning Clap,1220|Thunder Strike,1222|Power Sink,1224|Shocking Grasp";
powers[62] = "1226|Ring of Fire,1228|Fire Sword,1230|Combustion,1232|Fire Sword Circle,1234|Build Up,1236|Blazing Aura,1238|Consume,1240|Burn,1242|Hot Feet";
powers[63] = "1244|Chilblain,1246|Frozen Fists,1248|Ice Sword,1250|Chilling Embrace,1252|Build Up,1254|Ice Patch,1256|Shiver,1258|Freezing Touch,1260|Frozen Aura";
powers[467] = "2414|Snow Storm,2415|Flash Freeze,2416|Frozen Armor,2417|Hibernate";
powers[468] = "2418|Static Discharge,2419|Shocking Bolt,2420|Charged Armor,2421|EM Pulse";
powers[469] = "2422|Bonfire,2423|Char,2424|Fire Shield,2425|Rise of the Phoenix";
powers[470] = "2426|Personal Force Field,2427|Repulsion Field,2428|Temp Invulnerability,2429|Force of Nature";
powers[471] = "2430|Body Armor,2431|Cryo Freeze Ray,2432|Sleep Grenade,2433|LRM Rocket";
powers[64] = "1441|Stone Prison,1442|Fossilize,1444|Stone Cages,1446|Quicksand,1448|Salt Crystals,1450|Stalagmites,1452|Earthquake,1454|Volcanic Gasses,1456|Animate Stone";
powers[65] = "1458|Ring of Fire,1460|Char,1462|Fire Cages,1464|Smoke,1466|Hot Feet,1468|Flashfire,1470|Cinders,1472|Bonfire,1474|Fire Imps";
powers[66] = "1476|Crush,1478|Lift,1480|Gravity Distortion,1482|Propel,1484|Crushing Field,1486|Dimension Shift,1488|Gravity Distortion Field,1490|Wormhole,1492|Singularity";
powers[67] = "1494|Chilblain,1496|Block of Ice,1498|Frostbite,1500|Arctic Air,1502|Shiver,1504|Ice Slick,1506|Flash Freeze,1508|Glacier,1510|Jack Frost";
powers[68] = "1512|Spectral Wounds,1514|Blind,1516|Deceive,1518|Flash,1520|Superior Invisibility,1522|Group Invisibility,1524|Phantom Army,1526|Spectral Terror,1528|Phantasm";
powers[69] = "1530|Mesmerize,1532|Levitate,1534|Dominate,1536|Confuse,1538|Mass Hypnosis,1540|Telekinesis,1542|Total Domination,1544|Terrify,1546|Mass Confusion";
powers[70] = "1548|Healing Aura,1550|Heal Other,1552|Absorb Pain,1554|Resurrect,1556|Clear Mind,1558|Fortitude,1560|Recovery Aura,1562|Regeneration Aura,1564|Adrenalin Boost";
powers[71] = "1566|Personal Force Field,1568|Deflection Shield,1570|Force Bolt,1572|Insulation Shield,1574|Detention Field,1576|Dispersion Bubble,1578|Repulsion Field,1580|Repulsion Bomb,1582|Force Bubble";
powers[72] = "1584|Transfusion,1586|Siphon Power,1588|Repel,1590|Siphon Speed,1592|Increase Density,1594|Speed Boost,1596|Inertial Reduction,1598|Transference,1600|Fulcrum Shift";
powers[73] = "1602|Radiant Aura,1604|Radiation Infection,1606|Accelerate Metabolism,1608|Enervating Field,1610|Mutation,1612|Lingering Radiation,1614|Choking Cloud,1616|Fallout,1618|EM Pulse";
powers[74] = "1620|Gale,1622|O2 Boost,1624|Snow Storm,1626|Steamy Mist,1628|Freezing Rain,1630|Hurricane,1632|Thunder Clap,1634|Tornado,1636|Lightning Storm";
powers[75] = "1638|Entangling Arrow,1640|Flash Arrow,1642|Glue Arrow,1644|Ice Arrow,1646|Poison Gas Arrow,1648|Acid Arrow,1650|Disruption Arrow,1652|Oil Slick Arrow,1654|EMP Arrow";
powers[76] = "1656|Sonic Siphon,1658|Sonic Barrier,1660|Sonic Haven,1662|Sonic Cage,1664|Disruption Field,1670|Sonic Dispersion,1668|Sonic Repulsion,1666|Clarity,1672|Liquefy";
powers[472] = "2434|Fire Blast,2435|Fire Ball,2436|Fire Shield,2437|Consume";
powers[473] = "2438|Ice Blast,2439|Hibernate,2440|Frozen Armor,2441|Ice Storm";
powers[474] = "2442|Power Blast,2443|Conserve Power,2444|Temp Invulnerability,2445|Power Boost";
powers[475] = "2446|Mental Blast,2447|Indomitable Will,2448|Mind Over Body,2449|Psionic Tornado";
powers[476] = "2450|Hurl Boulder,2451|Fissure,2452|Rock Armor,2453|Earths Embrace";
powers[77] = "1674|Twilight Grasp,1675|Tar Patch,1677|Darkest Night,1679|Howling Twilight,1681|Shadow Fall,1683|Fearsome Stare,1685|Petrifying Gaze,1687|Black Hole,1689|Dark Servant";
powers[78] = "1691|Healing Aura,1693|Heal Other,1695|Absorb Pain,1697|Resurrect,1699|Clear Mind,1701|Fortitude,1703|Recovery Aura,1705|Regeneration Aura,1707|Adrenalin Boost";
powers[79] = "1709|Personal Force Field,1711|Deflection Shield,1713|Force Bolt,1715|Insulation Shield,1717|Detention Field,1719|Dispersion Bubble,1721|Repulsion Field,1723|Repulsion Bomb,1725|Force Bubble";
powers[80] = "1727|Transfusion,1729|Siphon Power,1731|Repel,1733|Siphon Speed,1735|Increase Density,1737|Speed Boost,1739|Inertial Reduction,1741|Transference,1743|Fulcrum Shift";
powers[81] = "1745|Radiant Aura,1747|Radiation Infection,1749|Accelerate Metabolism,1751|Enervating Field,1753|Mutation,1755|Lingering Radiation,1757|Choking Cloud,1759|Fallout,1761|EM Pulse";
powers[82] = "1763|Gale,1765|O2 Boost,1767|Snow Storm,1769|Steamy Mist,1771|Freezing Rain,1773|Hurricane,1775|Thunder Clap,1777|Tornado,1779|Lightning Storm";
powers[83] = "1781|Entangling Arrow,1783|Flash Arrow,1785|Glue Arrow,1787|Ice Arrow,1789|Poison Gas Arrow,1791|Acid Arrow,1793|Disruption Arrow,1795|Oil Slick Arrow,1797|EMP Arrow";
powers[84] = "1799|Sonic Siphon,1801|Sonic Barrier,1803|Sonic Haven,1805|Sonic Cage,1807|Disruption Field,1813|Sonic Dispersion,1811|Sonic Repulsion,1809|Clarity,1815|Liquefy";
powers[85] = "1817|Charged Bolts,1819|Lightning Bolt,1821|Ball Lightning,1823|Short Circuit,1825|Aim,1827|Zapp,1829|Tesla Cage,1831|Voltaic Sentinel,1833|Thunderous Blast";
powers[86] = "1835|Power Bolt,1837|Power Blast,1839|Energy Torrent,1841|Power Burst,1843|Sniper Blast,1845|Aim,1847|Power Push,1849|Explosive Blast,1851|Nova";
powers[87] = "1853|Dark Blast,1855|Gloom,1857|Moonbeam,1859|Dark Pit,1861|Tenebrous Tentacles,1863|Night Fall,1865|Torrent,1867|Life Drain,1869|Blackstar";
powers[88] = "1871|Mental Blast,1873|Subdue,1875|Psionic Lance,1877|Psychic Scream,1879|Telekinetic Blast,1881|Will Domination,1883|Psionic Tornado,1885|Scramble Thoughts,1887|Psychic Wail";
powers[89] = "1889|Neutrino Bolt,1891|X-Ray Beam,1893|Irradiate,1895|Electron Haze,1897|Proton Volley,1899|Aim,1901|Cosmic Burst,1903|Neutron Bomb,1905|Atomic Blast";
powers[90] = "1925|Snap Shot,1927|Aimed Shot,1929|Fistful of Arrows,1931|Blazing Arrow,1933|Aim,1935|Explosive Arrow,1937|Ranged Shot,1939|Stunning Shot,1941|Rain of Arrows";
powers[91] = "1907|Shriek,1909|Scream,1911|Howl,1913|Shockwave,1915|Shout,1917|Amplify,1919|Sirens Song,1921|Screech,1923|Dreadful Wail";
powers[477] = "2454|Oppressive Gloom,2455|Dark Consumption,2456|Dark Embrace,2457|Soul Drain";
powers[478] = "2458|Electric Fence,2459|Thunder Strike,2460|Charged Armor,2461|Power Sink";
powers[479] = "2462|Conserve Power,2463|Power Build Up,2464|Temp Invulnerability,2465|Total Focus";
powers[480] = "2466|Dominate,2467|Mass Hypnosis,2468|Mind Over Body,2469|Telekinesis";
powers[92] = "1262|Hack,1263|Slash,1265|Slice,1267|Build Up,1269|Parry,1271|Confront,1273|Whirling Sword,1275|Disembowel,1277|Head Splitter";
powers[93] = "1279|Swipe,1281|Strike,1283|Slash,1285|Spin,1287|Follow Up,1289|Confront,1291|Focus,1293|Eviscerate,1295|Shockwave";
powers[94] = "1297|Shadow Punch,1299|Smite,1301|Shadow Maul,1303|Touch of Fear,1305|Siphon Life,1307|Confront,1309|Dark Consumption,1311|Soul Drain,1313|Midnight Grasp";
powers[95] = "1315|Sting of the Wasp,1317|Gambler's Cut,1319|Flashing Steel,1321|Build Up,1323|Divine Avalanche,1325|Calling the Wolf,1327|The Lotus Drops,1329|Soaring Dragon,1331|Golden Dragonfly";
powers[96] = "1333|Thunder Kick,1335|Storm Kick,1337|Cobra Strike,1339|Focus Chi,1341|Crane Kick,1343|Warriors Challenge,1345|Crippling Axe Kick,1347|Dragons Tail,1349|Eagles Claw";
powers[97] = "1351|Barb Swipe,1353|Lunge,1355|Spine Burst,1357|Build Up,1359|Impale,1361|Confront,1363|Quills,1365|Ripper,1367|Throw Spines";
powers[98] = "1369|Dark Embrace,1371|Death Shroud,1373|Murky Cloud,1375|Obsidian Shield,1377|Dark Regeneration,1379|Cloak of Darkness,1381|Cloak of Fear,1383|Oppressive Gloom,1385|Soul Transfer";
powers[99] = "1387|Resist Physical Damage,1389|Temp Invulnerability,1391|Dull Pain,1393|Resist Elements,1395|Unyielding,1397|Resist Energies,1399|Invincibility,1401|Tough Hide,1403|Unstoppable";
powers[100] = "1405|Fast Healing,1407|Reconstruction,1409|Quick Recovery,1411|Dull Pain,1413|Integration,1415|Resilience,1417|Instant Healing,1419|Revive,1421|Moment of Glory";
powers[101] = "1423|Focused Fighting,1425|Focused Senses,1427|Agile,1429|Practiced Brawler,1431|Dodge,1433|Quickness,1435|Lucky,1437|Evasion,1439|Elude";
powers[481] = "2470|Conserve Power,2471|Focused Accuracy,2472|Laser Beam Eyes,2473|Energy Torrent";
powers[482] = "2474|Torrent,2475|Petrifying Gaze,2476|Dark Blast,2477|Tenebrous Tentacles";
powers[483] = "2478|Web Grenade,2479|Caltrops,2480|Shuriken,2481|Exploding Shuriken";
powers[102] = "2122|Resist Physical Damage,2123|Temp Invulnerability,2125|Dull Pain,2127|Resist Elements,2129|Unyielding,2131|Resist Energies,2133|Invincibility,2135|Tough Hide,2137|Unstoppable";
powers[103] = "2139|Blazing Aura,2141|Fire Shield,2143|Healing Flames,2145|Temperature Protection,2147|Consume,2149|Plasma Shield,2151|Burn,2153|Fiery Embrace,2155|Rise of the Phoenix";
powers[104] = "2157|Frozen Armor,2159|Hoarfrost,2161|Chilling Embrace,2163|Wet Ice,2165|Permafrost,2167|Icicles,2169|Glacial Armor,2171|Energy Absorption,2173|Hibernate";
powers[105] = "2175|Rock Armor,2177|Stone Skin,2179|Earth's Embrace,2181|Mud Pots,2183|Rooted,2185|Brimstone Armor,2187|Crystal Armor,2189|Minerals,2191|Granite Armor";
powers[106] = "2193|Gash,2195|Chop,2199|Beheader,2197|Taunt,2201|Build Up,2203|Swoop,2205|Whirling Axe,2207|Cleave,2209|Pendulum";
powers[107] = "2211|Scorch,2213|Fire Sword,2217|Combustion,2215|Taunt,2219|Breath of Fire,2221|Build Up,2223|Fire Sword Circle,2225|Incinerate,2227|Greater Fire Sword";
powers[108] = "2229|Frozen Fists,2231|Ice Sword,2235|Frost,2233|Taunt,2237|Build Up,2239|Ice Patch,2241|Freezing Touch,2243|Greater Ice Sword,2245|Frozen Aura";
powers[109] = "2247|Barrage,2249|Energy Punch,2253|Bone Smasher,2251|Taunt,2255|Whirling Hands,2257|Stun,2259|Build Up,2261|Energy Transfer,2263|Total Focus";
powers[110] = "2265|Stone Fist,2267|Stone Mallet,2271|Heavy Mallet,2269|Taunt,2273|Build Up,2275|Fault,2277|Hurl Boulder,2279|Tremor,2281|Seismic Smash";
powers[111] = "2283|Jab,2285|Punch,2289|Haymaker,2287|Taunt,2291|Hand Clap,2293|Knockout Blow,2295|Rage,2297|Hurl,2299|Foot Stomp";
powers[112] = "2301|Bash,2303|Pulverize,2311|Jawbreaker,2305|Taunt,2309|Build Up,2307|Clobber,2313|Whirling Mace,2315|Shatter,2317|Crowd Control";
powers[485] = "2482|Chilblain,2483|Block of Ice,2484|Ice Blast,2485|Ice Storm";
powers[486] = "2486|Stone Prison,2487|Salt Crystals,2488|Fossilize,2489|Stalagmites";
powers[487] = "2490|Conserve Power,2491|Focused Accuracy,2492|Laser Beam Eyes,2493|Energy Torrent";
powers[488] = "2494|Ring of Fire,2495|Char,2496|Fire Blast,2497|Fire Ball";
powers[119] = "2578|Gleaming Bolt,2579|Glinting Eye,2580|Gleaming Blast,2581|Bright Nova,2582|Radiant Strike,2583|Proton Scatter,2585|Luminous Detonation,2584|Build Up,2586|Incandescent Strike,2587|Pulsar,2588|Glowing Touch,2589|Solar Flare,2590|Photon Seekers,2591|Dawn Strike";
powers[120] = "2592|Incandescence,2593|Shining Shield,2594|Essence Boost,2595|Thermal Shield,2596|Quantum Shield,2597|Group Energy Flight,2598|White Dwarf,2599|Reform Essence,2600|Conserve Energy,2601|Quantum Flight,2602|Restore Essence,2603|Light Form";
powers[121] = "2604|Shadow Bolt,2605|Ebon Eye,2606|Gravimetric Snare,2607|Dark Nova,2608|Shadow Blast,2609|Starless Step,2611|Dark Detonation,2610|Sunless Mire,2612|Gravity Well,2613|Essence Drain,2614|Gravitic Emanation,2615|Unchain Essence,2616|Dark Extraction,2617|Quasar";
powers[122] = "2618|Absorption,2619|Gravity Shield,2620|Orbiting Death,2621|Penumbral Shield,2622|Shadow Cloak,2623|Twilight Shield,2624|Black Dwarf,2625|Stygian Circle,2626|Nebulous Form,2627|Inky Aspect,2628|Stygian Return,2629|Eclipse";

powers[509] = "5843|Nimble Slash|1,5835|Power Slice|1,5836|Ablating Strike|2,5837|Typhoon's Edge|6,5838|Blinding Feint|8,5839|Taunt|12,5840|Vengeful Slice|18,5841|Sweeping Strike|26,5842|One Thousand Cuts|32";
powers[510] = "5898|High Pain Tolerance|1,5899|Mind Over Body|2,5900|Fast Healing|4,5901|Indomitable Will|10,5902|Rise to the Challenge|16,5903|Quick Recovery|20,5904|Heightened Senses|28,5905|Resurgence|35,5906|Strength of Will|38";
powers[511] = "5852|Nimble Slash|1,5853|Power Slice|1,5854|Ablating Strike|2,5855|Assassin's Blades|6,5856|Build Up|8,5857|Placate|12,5858|Vengeful Slice|18,5859|Sweeping Strike|26,5860|One Thousand Cuts|32";
powers[512] = "5888|Hide|1,5889|High Pain Tolerance|2,5890|Reconstruction|4,5891|Mind Over Body|10,5892|Indomitable Will|16,5893|Heightened Senses|20,5894|Fast Healing|28,5895|Resurgence|35,5896|Strength of Will|38";
powers[513] = "5834|Nimble Slash|1,5844|Power Slice|1,5845|Ablating Strike|2,5846|Typhoon's Edge|6,5847|Blinding Feint|8,5848|Taunt|12,5849|Vengeful Slice|18,5850|Sweeping Strike|26,5851|One Thousand Cuts|32";
powers[514] = "5870|High Pain Tolerance|1,5871|Mind Over Body|2,5872|Fast Healing|4,5873|Indomitable Will|10,5874|Rise to the Challenge|16,5875|Quick Recovery|20,5876|Heightened Senses|28,5877|Resurgence|35,5878|Strength of Will|38";
powers[515] = "5879|High Pain Tolerance|1,5880|Mind Over Body|1,5881|Fast Healing|2,5882|Indomitable Will|6,5883|Rise to the Challenge|8,5884|Quick Recovery|12,5885|Heightened Senses|18,5886|Resurgence|26,5887|Strength of Will|32";
powers[516] = "5861|Nimble Slash|1,5862|Power Slice|2,5863|Ablating Strike|4,5864|Taunt|10,5865|Typhoon's Edge|16,5866|Blinding Feint|20,5867|Vengeful Slice|28,5868|Sweeping Strike|35,5869|One Thousand Cuts|38";

// POOLS
powers[128] = "2319|Stealth,2320|Grant Invisibility,2321|Invisibility,2322|Phase Shift";
powers[129] = "2324|Boxing,2326|Kick,2327|Tough,2328|Weave";
powers[130] = "2330|Swift,2331|Hurdle,2332|Health,2333|Stamina";
powers[131] = "2335|Hover,2336|Air Superiority,2337|Fly,2338|Group Fly";
powers[132] = "2340|Maneuvers,2341|Assault,2342|Tactics,2343|Vengeance";
powers[133] = "2345|Jump Kick,2346|Combat Jumping,2347|Super Jump,2348|Acrobatics";
powers[135] = "2350|Aid Other,2351|Stimulant,2352|Aid Self,2353|Resuscitate";
powers[136] = "2355|Challenge,2356|Provoke,2357|Intimidate,2358|Invoke Panic";
powers[137] = "2360|Flurry,2361|Hasten,2362|Super Speed,2363|Whirlwind";
powers[138] = "2365|Recall Friend,2366|Teleport Foe,2367|Teleport,2368|Team Teleport";

var at_forum = new Array();
at_forum['1'] = 3;
at_forum['2'] = 16;
at_forum['3'] = 10;
at_forum['4'] = 8;
at_forum['5'] = 6;
at_forum['6'] = 2;
at_forum['7'] = 4;
at_forum['8'] = 11;
at_forum['9'] = 7;
at_forum['10'] = 5;
at_forum['11'] = 9;
at_forum['12'] = 9;


/**** END:  static.js ****/

/**** START: cit.js ****/

function linkCIT(a,build,h){

	if (a < 2){
		o = (a == 0) ? 'citdel' : 'citlist';
		
		new Ajax.Request('/ajax.php',
			{
				method: 'post',
				parameters: {op: o,
							buildID: build,
							hv: h},
				onSuccess: function(transport){
					var response = transport.responseText || 'no response text';
					finishCITLink(response,o);
				},
				onFailure: function(){ alert('failed'); }
			});
		
		if (a == 1){
			$('cit_buildID').value = build;
		}
	}
	else {
		o = 'citlink';
		cit = $('cit_chars').value;
		build = $('cit_buildID').value;

		new Ajax.Request('/ajax.php',
			{
				method: 'post',
				parameters: {op: o,
							buildID: build,
							citID: cit},
				onSuccess: function(transport){
					var response = transport.responseText || 'no response text';
					finishCITLink(response,o);
				},
				onFailure: function(){alert('failed'); }
			});
	}
}


/**** END:  cit.js ****/

/**** START: planner.js ****/

function reset_all(){

	resetPowers();
	
	document.planner.level.value = 0;
	document.planner.atpower.value = 0;
	document.planner.enh_count.value = 0;
	document.planner.slots.value = 0;
	document.planner.primary.value = '';
	document.planner.secondary.value = '';
	document.planner.pool1.value = '';
	document.planner.pool2.value = '';
	document.planner.pool3.value = '';
	document.planner.pool4.value = '';
	document.planner.app.value = '';

	document.planner.pool1.disabled = false;
	document.planner.pool2.disabled = false;
	document.planner.pool3.disabled = false;
	document.planner.pool4.disabled = false;
	document.planner.app.disabled = false;

	makePowerAvailable(1, 'prim',   14);
	makePowerAvailable(1, 'sec',    12);
	makePowerAvailable(1, 'pool1_', 4);
	makePowerAvailable(1, 'pool2_', 4);
	makePowerAvailable(1, 'pool3_', 4);
	makePowerAvailable(1, 'pool4_', 4);
	makePowerAvailable(1, 'app', 	4);
	
	document.planner.enhmode.value = 0;

}


/* POPULATE POWER TABLES
*************************************************/

function fillTable(row, name, id){
	$(row).name = id;
	$(row).innerHTML = name;	
}


/* POPULATE PRIMARY/SECONDARY SELECT MENUS
*************************************************/

function fillPrimSec(){

	var form = document.planner;
	var at = form.at.value;

	if (at == ''){

		window.location.reload();

	} else {

		reset_all();

		// change the stylesheet
		if (at <= 5){
			setStyle('villain');
		} else {
			setStyle('hero');
		}
		
		$('atbg').style.background = "url('/img/at"+at+".png') top left no-repeat";
		
		// show/hide extra kheldian powers
		if (at == 11 || at == 12){
			showKheldPowers(1);
		} else {
			showKheldPowers(0);	
		}
		
		// fill the data
		atname = getOptionText('at',at,'planner').toLowerCase();
		pri = eval(atname+"[1]").split(',');
		sec = eval(atname+"[2]").split(',');
		app = eval(atname+"[4]").split(',');
		
		form.primary.options.length = 1;
		form.secondary.options.length = 1;
		form.app.options.length = 1;
		// primary
		for (x=0; x<pri.length;x++){
			data = pri[x].split('|');
			form.primary.options[form.primary.options.length] = new Option(data[1],data[0]);
		}
		// secondary
		for (x=0; x<sec.length;x++){
			data = sec[x].split('|');
			form.secondary.options[form.secondary.options.length] = new Option(data[1],data[0]);
		}
		// app
		for (x=0; x<app.length;x++){
			data = app[x].split('|');
			form.app.options[form.app.options.length] = new Option(data[1],data[0]);
		}

	}

}

function fillPrimSecLoad(){

	var form = document.planner;
	var at = form.at.value;

	if (at == ''){

		window.location.reload();

	} else {

		// change the stylesheet
		if (at <= 5){
			setStyle('villain');
		} else {
			setStyle('hero');
		}
		
		// show/hide extra kheldian powers
		if (at == 11 || at == 12){
			showKheldPowers(1);
		} else {
			showKheldPowers(0);	
		}
		
		// fill the data
		atname = getOptionText('at',at,'planner').toLowerCase();
		pri = eval(atname+"[1]").split(',');
		sec = eval(atname+"[2]").split(',');
		app = eval(atname+"[4]").split(',');
		
		form.primary.options.length = 1;
		form.secondary.options.length = 1;
		form.app.options.length = 1;
		// primary
		for (x=0; x<pri.length;x++){
			data = pri[x].split('|');
			form.primary.options[form.primary.options.length] = new Option(data[1],data[0]);
		}
		// secondary
		for (x=0; x<sec.length;x++){
			data = sec[x].split('|');
			form.secondary.options[form.secondary.options.length] = new Option(data[1],data[0]);
		}
		// app
		for (x=0; x<app.length;x++){
			data = app[x].split('|');
			form.app.options[form.app.options.length] = new Option(data[1],data[0]);
		}
		
	}
}

function fillPrimSecSearch(){

	var form = document.sea;
	var at = form.at.value;
	
	if (at == ''){
		form.primary.options.length = 1;
		form.secondary.options.length = 1;
		return;	
	}
	else {
		
		// fill the data
		atname = getOptionText('at',at,'sea').toLowerCase();
		pri = eval(atname+"[1]").split(',');
		sec = eval(atname+"[2]").split(',');
		
		form.primary.options.length = 1;
		form.secondary.options.length = 1;

		// primary
		for (x=0; x<pri.length;x++){
			data = pri[x].split('|');
			form.primary.options[form.primary.options.length] = new Option(data[1],data[0]);
		}
		// secondary
		for (x=0; x<sec.length;x++){
			data = sec[x].split('|');
			form.secondary.options[form.secondary.options.length] = new Option(data[1],data[0]);
		}
		
	}	
}

function fillPrimSecPowers(){

	var form = document.powers;
	var at = form.at.value;
	
	if (at == ''){
		form.primary.options.length = 1;
		form.secondary.options.length = 1;
		return;	
	}
	else {
		
		// fill the data
		atname = getOptionText('at',at,'powers').toLowerCase();
		pri = eval(atname+"[1]").split(',');
		sec = eval(atname+"[2]").split(',');
		app = eval(atname+"[4]").split(',');
		
		form.powerset.options.length = 0;

		oSelect = document.powers.powerset;
		while (oSelect.firstChild) {
			oSelect.removeChild(oSelect.firstChild);
		}

		var oGroup1 = document.createElement('optgroup');
		oGroup1.label = 'PRIMARIES';

		// primary
		for (x=0; x<pri.length;x++){
			data = pri[x].split('|');
			oOption = document.createElement('option');
			oOption.value = data[0];
			oOption.text = data[1];

			oGroup1.appendChild(oOption);
		}
		
		var oGroup2 = document.createElement('optgroup');
		oGroup2.label = 'SECONDARIES';

		// secondary
		for (x=0; x<sec.length;x++){
			data = sec[x].split('|');
			oOption = document.createElement('option');
			oOption.value = data[0];
			oOption.text = data[1];
			oOption.style.color = 'black';

			oGroup2.appendChild(oOption);
		}

		var oGroup3 = document.createElement('optgroup');
		oGroup3.label = 'APP/PPP\'s';

		// APP/PPP
		for (x=0; x<app.length;x++){
			data = app[x].split('|');
			oOption = document.createElement('option');
			oOption.value = data[0];
			oOption.text = data[1];

			oGroup3.appendChild(oOption);
		}

		oSelect.appendChild(oGroup1);
		oSelect.appendChild(oGroup2);
		oSelect.appendChild(oGroup3);
		
	}	
}
/* POPULATE PRIMARY POWER DATA TABLE
*************************************************/

function fillPowers(pool,par){

	var form = document.planner;
	var p = form[par].value;

	at = parseInt(form.at.value);

	if (p == ''){

		if (pool.match(/pool/) || pool.match(/app/)){
			tot = 4;
		}

		else if (pool == 'prim'){
			tot = 14;
		}

		else {
			tot = 12;
		}

		for( x = 1; x <= tot; x++ ){
			fillTable(pool+x,'&nbsp;','');
		}

	} else {

		if (par.match(/pool/) && form[par].value != ''){

			if (at == 11 || at == 12){
				if (p == 131 || p == 138){
					alert("Kheldians can not select Flight or Teleportation pools");
					form[par].value = '';
					return;
				}
			}

			switch (par){

				case 'pool1':
					if (form.pool1.value == form.pool2.value || form.pool1.value == form.pool3.value || form.pool1.value == form.pool4.value){
						alert("You've already selected this pool");
						form.pool1.value = '';
						return;
					}
				break;

				case 'pool2':
					if(form.pool2.value == form.pool1.value || form.pool2.value == form.pool3.value || form.pool2.value == form.pool4.value){
                        alert("You've already selected this pool");
                        form.pool2.value = '';
                        return;
                    }
				break;

				case 'pool3':
					if(form.pool3.value == form.pool1.value || form.pool3.value == form.pool2.value || form.pool3.value == form.pool4.value){
                        alert("You've already selected this pool");
                        form.pool3.value = '';
                        return;
                    }
				break;

				case 'pool4':
					if(form.pool4.value == form.pool1.value || form.pool4.value == form.pool2.value || form.pool4.value == form.pool3.value){
                        alert("You've already selected this pool");
                        form.pool4.value = '';
                        return;
                    }
				break;
			}

		}

		if ((pool == 'prim' || pool == 'sec') && form.p.value == ''){

			resetPowers();

		}
		else if (form.p.value != ''){
			l = form.level.value;
			
			makePowerAvailable(l, 'prim',   14);
			makePowerAvailable(l, 'sec',    12);
			makePowerAvailable(l, 'pool1_', 4);
			makePowerAvailable(l, 'pool2_', 4);
			makePowerAvailable(l, 'pool3_', 4);
			makePowerAvailable(l, 'pool4_', 4);
		}

		// fill the data
		power = powers[p].split(',');
		
		for (x=0; x<power.length; x++){
			data = power[x].split('|');
			$(pool+(x+1)).name = data[0];
			$(pool+(x+1)).innerHTML = data[1];
				
			if ((pool+(x+1)) == 'sec1' && form.load.value == 0){
				choosePower(data[0], 'sec1');
			}
			
			r = $(pool+(x+1)+'_i');
			r.childNodes[0].href = "javascript:showDetail('"+data[0]+"');";
		}
	}
}

/* POPULATE <SPAN> TAG WITH NEW POWER SELECTION
*************************************************/

function fillSpan(pownum, powID, tdID){
		
	level = left($('selection'+pownum).innerHTML, 4);
	level = level.replace('(','');
	level = level.replace(')','');

	name = $(tdID).innerHTML;

	$('seltext'+pownum).innerHTML = name;
	$('selection'+pownum).name = powID;
	$('li_'+pownum+'_1').innerHTML = "<a href=\"javascript:showEnhDiv('"+powID+"','li_"+pownum+"_1');\"><img id=\""+powID+"-"+level+"\" alt=\""+level+"\" src=\"/img/enh/Empty.gif\" /></a>";

}

/* SHOW/HIDE KHELDIAN EXTRA POWER LIST
*************************************************/

function showKheldPowers(a){

	// hide
	if (a == 1){
		
		// primary
		for (x=1; x<10;x++){
			$('prim'+x).onmouseover = "showToolTip('"+k_pri_levs[x]+"');"
		}
		for (x=10; x<=14; x++){
			$('prim'+x).style.display = '';
			$('prim'+x+'_i').style.display = '';
			$('prim'+x).onmouseover = "showToolTip();"
		}
		// secondary
		for (x=1; x<10;x++){
			$('sec'+x).onmouseover = "return escape('Available at Level "+sec_levs[x]+"')";
		}
		for (x=10; x<=12; x++){
			$('sec'+x).style.display = '';
			$('sec'+x+'_i').style.display = '';
		}
		
		$('app_div').style.display = 'none';
	
	} else {
	
		// primary
		for (x=1; x<10; x++){
			$('prim'+x).onmouseover = "showToolTip('"+k_pri_levs[x]+"');"
		}
		for (x=10; x<=14; x++){
			$('prim'+x).style.display = 'none';
			$('prim'+x+'_i').style.display = 'none';
		}
		// secondary
		for (x=1;x<10;x++){
			$('sec'+x).onmouseover = "return escape('Available at Level "+k_sec_levs[x]+"')";
		}
		for (x=10; x<=12; x++){
			$('sec'+x).style.display = 'none';
			$('sec'+x+'_i').style.display = 'none';
			$('sec'+x).onmouseover = "return escape('Available at Level "+k_sec_levs[x]+"')";
		}
		
		$('app_div').style.display = '';
	
	}

}


/* POWER DETAIL HOVERBOX
*************************************************/

function showDetail(powID){

	if (powID){
		var form = document.planner;
	
		// get power data
		var ao = new AjaxObject();
		ao.sndReq('get', '/ajax.php?op=power_detail&x='+powID);			
	}

}

/* LOGIN HOVERBOX
*************************************************/

function doShowLogin(){

	form = document.planner;

	xy = form.x.value + ',' + form.y.value;
	showLightbox('login',xy);

	$('username').focus();

}

function doShowRegister(){

    form = document.planner;

    xy = form.x.value + ',' + form.y.value;
    showLightbox('regbox',xy);
	
	$('runame').focus();

}


function checkLogin(){

	var user = $('username').value;
	var pass = $('password').value;

	$('message').innerHTML = '';

	new Ajax.Request('/ajax.php',
		{
			method: 'post',
			parameters: {op: 'login',u: user, p: pass},
			onSuccess: function(transport){
				var response = transport.responseText || 'no response text';
				finishLogin(response);
			},
			onFailure: function(){ alert('failed'); }
		});
	
	$('username').value = ''
	$('password').value = '';
}

function checkReg(){

	var user = $('runame').value;
	var global = $('global').value;
	var email = $('email').value;
	var pass = $('rpass').value;
	var pass2= hex_md5($('rpass2').value);
	
	$('rpass').value = '';
	$('rpass2').value = '';
	
	msg = '';
	
	if (trim(user).length == 0){
		msg += "=> Please select a Username!\n";
	}
		 
	if (pass.length < 5) {
		msg += "=> Password must be at least 5 characters long!\n";
	}
	else if (hex_md5(pass) != pass2){
		msg += "=> Passwords do no match!\n";	
	}
	
	if (trim(global).length == 0){
		msg += "=> Please enter your Global handle!\n";		
	}
	if (trim(email).length == 0){
		msg += "=> Please enter your Email address!\n";
	}
	
	if (msg != ''){	
		msg = "The following must be corrected before registering:\n\n" + msg;
		alert(msg);
		return false;	
	} else {
		var ao = new AjaxObject();
		ao.sndReq('get', '/ajax.php?op=register&u='+user+'&g='+global+'&p='+pass2+'&e='+email);
	}
	
}

function logout(){
	
	hideLightbox();
	
	$('username').value = ''
	$('password').value = '';
	
	var ao = new AjaxObject();
	ao.sndReq('get', '/ajax.php?op=logout');
	
}

function showDonate(){
    showLightbox('donate','0,0');
}


/* Special Ed
*************************************************/
function powerCompare(){

	for (x=1;x<=40;x++){
							
		name = $('seltext'+x).innerHTML;
											
		if (name != '' && name != '&nbsp;'){
					
			for (z=1;z<=14;z++){
				if (trim($('prim'+z).innerHTML) == trim(name)){
					$('prim'+z).className = 'selected';
					break;
				}
			}
			
			for (z=1;z<=12;z++){
				if (trim($('sec'+z).innerHTML) == trim(name)){
					$('sec'+z).className = 'selected';
					break;
				}
			}
			
			for (z=1;z<=4;z++){
				if (trim($('pool1_'+z).innerHTML) == trim(name)){
					$('pool1').disabled = true;
					$('pool1_'+z).className = 'selected';
					break;
				}
			}
			for (z=1;z<=4;z++){
				if (trim($('pool2_'+z).innerHTML) == trim(name)){
					$('pool2').disabled = true;
					$('pool2_'+z).className = 'selected';
					break;
				}
			}
			for (z=1;z<=4;z++){
				if (trim($('pool3_'+z).innerHTML) == trim(name)){
					$('pool3').disabled = true;
					$('pool3_'+z).className = 'selected';
					break;
				}
			}
			for (z=1;z<=4;z++){
				if (trim($('pool4_'+z).innerHTML) == trim(name)){
					$('pool4').disabled = true;
					$('pool4_'+z).className = 'selected';
					break;
				}
			}
			for (z=1;z<=4;z++){
				if (trim($('app'+z).innerHTML) == trim(name)){
					$('app').disabled = true;
					$('app'+z).className = 'selected';
					break;
				}
			}

		}
	}
	
	setTimeout("hideLightbox();",500);
}


function togglePvP(buildID){

	b = $('pvp'+buildID).checked;
	
	var ao = new AjaxObject();
	
	if (b){
		ao.sndReq('get','/ajax.php?op=pvp&x=on&y='+buildID);
	} else {
		ao.sndReq('get','/ajax.php?op=pvp&x=off&y='+buildID);
	}

}

function togglePrivate(buildID){

	b = $('private'+buildID).checked;
	
	var ao = new AjaxObject();
	
	if (b){
		ao.sndReq('get','/ajax.php?op=private&x=on&y='+buildID);
	} else {
		ao.sndReq('get','/ajax.php?op=private&x=off&y='+buildID);
	}

}

function deleteBuild(name, id){
	msg = "Are you sure you want to DELETE " + name + "?";
	
	if (confirm(msg)){
		new Ajax.Request('/ajax.php',
			{
				method: 'post',
				parameters: {op: 'delete',x: id},
				onSuccess: function(transport){
					var response = transport.responseText || 'no response text';
					finishDeleteBuild(response,name);
				},
				onFailure: function(){ alert('failed'); }
			});
	}
}

function dupeBuild(name, id){
	msg = "Are you sure you want to DUPLICATE " + name + "?";
	
	if (confirm(msg)){
		new Ajax.Request('/ajax.php',
			{
				method: 'post',
				parameters: {op: 'duplicate', buildID: id},
				onSuccess: function(transport){
					var response = transport.responseText || 'no response text';
					finishDupeBuild(response);
				},
				onFailure: function(){ alert('failed'); }
			});
	}
}

function filterBuilds(){

	var form = document.sea;
	
	at = form.at.value;
	p  = form.primary.value;
	s  = form.secondary.value;
	pvp = form.pvp.value;
	svr = form.server.value;
	nme = form.name.value;
	pnm = form.powname.value;

	if (at == '' && pvp == '' && svr == '' && nme == '' && pnm == ''){
		$('fh1').innerHTML = 'Please be more specific with your filter!';		
		$('fh1').style.display = 'block';
	} else {		
		$('sea').submit();
	}

}

function createPost(buildID){

	form = document.planner;
	
	at = form.at.value;
	p  = getOptionText('primary',form.primary.value,'planner');
	s  = getOptionText('secondary',form.secondary.value,'planner');
	if (document.check_save.save_pvp[0].checked){
		pvp = 0;
	} else {
		pvp = 1;	
	}
	
	forumID = at_forum[at];
	
	qstring = 'board='+forumID;
	qstring+= '&buildID='+buildID;
	qstring+= '&p='+p;
	qstring+= '&s='+s;
	qstring+= '&pvp='+pvp;
	
	window.location = 'http://www.cohplanner.com/forum/index.php?action=post;'+qstring;

}

function changeRating(r){
	$('rating').value = r;

	for (x=1;x<=5;x++){
		$('star'+x).className = '';	
	}
	for (x=1;x<=r;x++){
		$('star'+x).className = 'starred';
	}
}
function checkComment(){
	if ($('cbuildID').value == ''){
		alert('Sorry, there is an error with the form.\n\nPlease send an email to polarisone@gmail.com to address the issue!');
		return false;
	}
	
	if (trim($('cnote').value) == ''){
		alert('Please enter a comment!');
		return false;
	}

	if ($('rating').value == 0){
		msg = 'Are you sure you don\'t want to rate this build before commenting?';
		if (confirm(msg)){
			$('comment_note').value = $('cnote').value;
			$('comment_form').submit();
			//
		} else {
			return false;
		}
	}

	$('comment_note').value = $('cnote').value;
	document.comment_form.submit();
}

function toggleCommentForm(){
	form = $('comment_form');
	logi = $('comment_login');

	if (form.style.display == 'block'){
		try{
			logi.style.display = 'block';
		$('comment_submit').disabled = true;
		} catch (e){}
		form.style.display = 'none';
	} else {
		try{
			logi.style.display = 'none';
		$('comment_submit').disabled = false;
		} catch (e) {}
		form.style.display = 'block';
	}
}

function toggleImgUpload(bID){
	disp = ($('img_upload').style.display == 'block') ? 'none' : 'block';

	if (disp == 'block'){
		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();
		
		xc = parseInt($('x').value)-315;
		yc = (parseInt(arrayPageScroll[1]) + parseInt($('y').value)) - 100;
		
		$('img_frame').src = '/img_iframe.php';
		
		$('img_upload').style.left = xc;
		$('img_upload').style.top = yc;
		$('img_upload').style.width = '300px';
		
		setTimeout("setFrameData("+bID+")",500);

	} else{
		ifr.elements['img_sub'].disabled=true;
	}
	
	$('img_upload').style.display = disp;
}

function setFrameData(bID){
	ifr = frames['img_frame'].document.forms[0];
		
	ifr.elements['img_buildID'].value = bID;
	ifr.elements['img_sub'].disabled=false;
	ifr.elements["img_sub"].style.display = "inline";
	ifr.elements["img_avatar"].style.display = "inline";
	ifr.elements["img_cancel"].value = "Cancel";
}

function imgDel(bID){
	msg = "Are you SURE you want to delete the avatar for this build?";

	if (confirm(msg)){
		new Ajax.Request('/ajax.php',
			{
				method: 'post',
				parameters: {op: 'imgdel', buildID: bID},
				onSuccess: function(transport){
					var response = transport.responseText || 'no response text';
					finishImgDel(response,bID);
				},
				onFailure: function(){ alert('failed'); }
			});
	}
}

function showTooltip(l){
	$('ttlevel').innerHTML = l;
	xy = form.x.value + ',' + form.y.value;
    showLightbox('tooltip',xy);
}

function checkIOs(){
	if ($('show_ios').checked){
		$('exp').value = 'long';
	}
}


/**** END:  planner.js ****/

/**** START: powers.js ****/

function resetPowers(){
	for ( x=1; x <= 40; x++ ){
		if ($('seltext'+x).innerHTML != 'Sprint' && $('seltext'+x).innerHTML != 'Brawl' && $('seltext'+x).innerHTML != 'Rest'){
			$('seltext'+x).innerHTML = '';	
		}
		for (i=1; i<6; i++){
			$('li_'+x+'_'+i).innerHTML = '';
		}
		$('selection'+x).className = 'none';
	}
	
	lvl = document.planner.level.value; 
	
	// reset selected power td's
	for ( x=1; x <= 14; x++ ){
		$('prim'+x).className = 'none';
		if (lvl > 1)
			$('prim'+x).innerHTML = '&nbsp;';
	}
	for ( x=1; x <= 12; x++ ){
		$('sec'+x).className = 'none';
		if (lvl > 1)
			$('sec'+x).innerHTML = '&nbsp;';
	}
	for ( x=1; x <= 4; x++ ){
		for ( z=1; z <= 4; z++ ){
			$('pool'+x+'_'+z).className = 'none';
			$('pool'+x+'_'+z).innerHTML = '&nbsp;';
		}
	}
	for ( x=1; x <= 4; x++ ){
		$('app'+x).className = 'none';
		$('app'+x).innerHTML = '&nbsp;';
	}

	document.planner.level.value = 1;
	document.planner.atpower.value = 0;

	document.planner.pool1.disabled = false;
	document.planner.pool2.disabled = false;
	document.planner.pool3.disabled = false;
	document.planner.pool4.disabled = false;
	document.planner.app.disabled = false;

	makePowerAvailable(1, 'prim',   14);
	makePowerAvailable(1, 'sec',    12);
	makePowerAvailable(1, 'pool1_', 4);
	makePowerAvailable(1, 'pool2_', 4);
	makePowerAvailable(1, 'pool3_', 4);
	makePowerAvailable(1, 'pool4_', 4);
	
	$('li_25_1').innerHTML = "<a href=\"javascript:showEnhDiv('5831','li_25_1');\"><img src=\"/img/enh/Empty.gif\"></a></li>";
	$('li_26_1').innerHTML = "<a href=\"javascript:showEnhDiv('5832','li_26_1');\"><img src=\"/img/enh/Empty.gif\"></a></li>";
	$('li_27_1').innerHTML = "<a href=\"javascript:showEnhDiv('5833','li_27_1');\"><img src=\"/img/enh/Empty.gif\"></a></li>";
}

function makePowerAvailable(level, td, i){

	var form = document.planner;

	arr = left(td,3);
	at = form.at.value;

	// loop through powers and make available current-level ones
	// only do this if it is a power-selectable level though
	var str_level = ','+level+',';
	var x_lev = form.level.value;
	if ( power_levels.indexOf(str_level) >= 0 ){

		for (x=1; x <= i; x++){

			this_td = $(td+x);
						
			if ((td=='prim' || td=='sec') && (at == 11 || at == 12)){
				levs = eval('k_'+arr+'_levs['+x+']');
			} else {
				levs = eval(arr+'_levs['+x+']');
			}

			if (levs <= level){
				

				if (this_td.className == 'selected'){

					if (level == 1){

						if (td == 'sec'){
							this_td.className = 'selected';
						} else {
							this_td.className = 'available';
						}

					}

				} else {

					if (td == 'prim' || td == 'sec'){
						this_td.className = 'available';
					}

					if (td.indexOf('pool') >= 0){

						// when power is < 6 make avail always
						if (levs == 6 && levs <= level){
							this_td.className = 'available';
							if (x == 2 && levs < 14 && $(td+'1').className != 'selected'){
								this_select = left(td,5);
								eval("form."+this_select+".disabled = false;");
							}
						}

						// the level 14 power needs a pre-req as well
						else if (levs == 14){

							// checking for either previous power has been chosen
							if (eval("$('"+td+"1').className") == 'selected' || eval("$('"+td+"2').className") == 'selected'){
								this_td.className = 'available';
							}

						}

						// the level 20 power needs two pre-reqs
						else if (levs == 20){
							// tally up the number of selected pre-reqs
							pq = 0;
							for (l=1;l<=3;l++){
								if ( eval("$('"+td+""+l+"').className") == 'selected'){
									pq++;
								}
							}

							if ( pq >=2 ){
								this_td.className = 'available';
							}

						}

					}

					if (td.indexOf('app') >= 0){

						// when power is < 41 make avail always
						if (levs == 41 && levs <= level){
							this_td.className = 'available';
							if (x == 2 && levs < 44 && $(td+'1').className != 'selected'){
								$('app').disabled = false;
							}
						}

						// the level 14 power needs a pre-req as well
						else if (levs == 44){

							// checking for either previous power has been chosen
							if (eval("$('"+td+"1').className") == 'selected' || eval("$('"+td+"2').className") == 'selected'){
								this_td.className = 'available';
							}

						}

						// the level 20 power needs two pre-reqs
						else if (levs == 47){
							// tally up the number of selected pre-reqs
							pq = 0;
							for (l=1;l<=3;l++){
								if ( eval("$('"+td+""+l+"').className") == 'selected'){
									pq++;
								}
							}

							if ( pq >=2 ){
								this_td.className = 'available';
							}

						}

					}
				}

			 } else { 
				
				try{
					this_td.className = 'none';
				} catch(a){}

			}

		}

	}

}

/* SELECTING A POWER
*************************************************/
function choosePower(powID,tdID){

	var form = document.planner;

	var at = parseInt(form.at.value);

	if ($(tdID).className == 'selected' || $(tdID).className == 'none'){
		return;
	}	

	if ($('seltext1').innerHTML != '' && $('seltext2').innerHTML == ''){
		var atpow = 1;
		var nextpow = atpow + 1;
	} else {
		var atpow = parseInt(form.atpower.value);
		var nextpow = atpow + 1;
	}

	if (trim($(tdID).innerHTML) == '&nbsp;'){
		return;
	}

	if ($('seltext1').innerHTML == '' && left(tdID,3) != 'sec'){
		return;
	}

	current_level = parseInt(form.level.value);

	// check if this power is allowed for this level
	this_pow_type  = left(tdID,3);

	if ((this_pow_type == 'pri' && tdID.length == 6) || (this_pow_type == 'sec' && tdID.length == 5)){
		this_pow_level = right(tdID,2);
	} else {
		this_pow_level = right(tdID,1);
	}

	// get the pool if it is one
	if (this_pow_type == 'poo'){
		pool_type  = left(tdID,5);
	}

	if ((this_pow_type=='pri' || this_pow_type=='sec') && (at == 11 || at == 12)){
		max_currently_allowed = parseInt(eval('k_'+this_pow_type+"_levs["+this_pow_level+"]"));
	} else {
		max_currently_allowed = parseInt(eval(this_pow_type+"_levs["+this_pow_level+"]"));
	}

	str_level = ',' + current_level + ',';

	if ( max_currently_allowed <= current_level && power_levels.indexOf(str_level) >= 0){

		if ($(tdID).className != 'selected'){
			// add power text to power selection box
			fillSpan(nextpow,powID, tdID);
			makeSlotsAvailableSpecial(nextpow,powID);
			// change power list to selected
			$(tdID).className = 'selected';			
			// increase level if not the first 2ndary power
			if (nextpow != 1){
				setTimeout("upLevel()",175);
			}

			if (at == 11 || at == 12){
				// Bright/Dark Nova & White/Black Dwarf
				if (powID == 2581 || powID == 2598 || powID == 2607 || powID == 2624){
					var ao = new AjaxObject();
					ao.sndReq('get','/ajax.php?op=power_khelds2&x='+powID+'&y='+at+'&z='+current_level);
				}
			}

		}

		// if a pool power 	or app, lock the select box
		if (this_pow_type == 'poo'){
			eval("form."+pool_type+".disabled = true;");
		} else if (this_pow_type == 'app'){
			form.app.disabled = true;
		}

		// increase current power number
		form.atpower.value = nextpow;
	}

}


/**** END:  powers.js ****/

/**** START: export.js ****/

/* EXPORTING THE DATA
*************************************************/
function doExport(style){

	if ($('show_ios').checked && left(style,4) != 'long' && style != 'forum_build'){
		alert("If you are using Invention Enhancements,\nI *strongly* recommend using one of the \"Long Export\" options.\n\nInventions will not display properly unless you do!");
	}

	form = document.planner;
	at = form.at.value;

	out = '';
	inh = '';
	
	var color_nam = 'yellow';
	var color_lev = 'gold';
	var color_enh = 'LimeGreen';
	var color_elv = 'LightSkyBlue';
	
	var f_color_nam = 'Navy';
	var f_color_lev = 'Red';
	var f_color_enh = 'Teal';
	var f_color_elv = 'Blue';
	
	sitestr = (window.location).toString();
	site = sitestr.replace(/\/planner/,'/');
	site = site.replace(/(builds|load)\/[0-9]*/,'');

	for ( x=1; x<= 24; x++){

        level = left(document.getElementById('selection'+x).innerHTML, 4);
        level = level.replace('(','');
        level = level.replace(')','');

        powname = document.getElementById('seltext'+x).innerHTML;
		powID   = document.getElementById('selection'+x).name;

		enhs = '';

		enhs_arr = new Object();

		for (l=1; l<=6;l++){
			
			try{

				li = document.getElementById('li_'+x+'_'+l);					

				srcs = (li.childNodes[0]).childNodes[0].src;
				lev = (li.childNodes[0]).childNodes[0].alt;
				title = (li.childNodes[0]).childNodes[0].title;

				if (!srcs.match(/new.gif/)){
					
					if (srcs.match(/hos/)){
						dir = 'img/hos/';
					} else if (srcs.match(/ios/)){
						dir = 'img/ios/';
					} else {
						dir = 'img/enh/';
					}
					
					enhc = srcs.replace(site+dir,'');
					enhc = enhc.replace(/.gif/,'');
					enhc = enhc.replace(/.png/,'');
									
					if (style == 'short' || style == 'shortu'){
						enhc = shorten(enhc.replace(/%20/g,' '));
						enhc = enhc.replace(' ','');
						enhc = enhc.replace(/Exposure/,'');
						if (enhs_arr[enhc]){
							enhs_arr[enhc]++;
						} else {
							enhs_arr[enhc] = 1;
						}
					} else if (left(style,4) == 'long'){
						if (dir == 'img/ios/'){
							title = title.replace(/\([0-9]+\)/,'');
							title = title.replace(enhc.replace(/%20/,' '),'');
							enhs += 'IO - ' + enhc.replace(/%20/g,' ') + ' ' + title + ' (' + lev + ')\n ';
						} else {
							enhs += enhc.replace(/%20/g,' ') + '(' + lev + ')\n ';
						}
					} else {
						enhs += shorten(enhc.replace(/%20/g,' ')) + '(' + lev + '),';
					}
				}
			
			} catch (e) { }
	
		}

		if (style == 'short' || style == 'shortu'){

			for (i in  enhs_arr){

				eName = i;
				eCount = enhs_arr[eName];

				enhs += eCount + 'x' + eName + ',';

			}

		} else {
			enhs = enhs.replace('(0','(');
		}

		enhs = left(enhs, enhs.length-1);

		if (powname){
			switch (style){
				case "simple":
				case "short":
					out += level +' => ' + powname + ' ==> ' + enhs + "\n";
				break;

				case "ubb":
				case "shortu":				
					out += '[color:"'+color_lev+'"]' + level + " =>[/color] " + powname + ' ==> [color:"'+color_enh+'"]' + enhs + "[/color]\n";
				break;

				case "ubb2":				
					out += '[color:"'+f_color_lev+'"]' + level + " =>[/color] " + powname + ' ==> [color:"'+f_color_enh+'"]' + enhs + "[/color]\n";
				break;
				
				case "phpbb":
					out += '[color='+color_lev+']' + level + " =>[/color] " + powname + ' ==> [color='+color_enh+']' + enhs + "[/color]\n";
				break;
				
				case "forum_build":
				case "planner":
					out += '[color='+f_color_lev+']' + level + " =>[/color] " + powname + ' ==> [color='+f_color_enh+']' + enhs + "[/color]\n";
				break;

				case 'long':
					out += level +' => ' + powname + '\n' + enhs + "\n";
				break;
				
				case 'longubb':
					out += '[color:"'+color_lev+'"]' + level + " =>[/color] " + powname + '\n[color:"'+color_enh+'"]' + enhs + "[/color]\n";
				break;

				case 'longubb2':
					out += '[color:"'+f_color_lev+'"]' + level + " =>[/color] " + powname + '\n[color:"'+f_color_enh+'"]' + enhs + "[/color]\n";
				break;

				case 'longpl':
					out += '[color='+f_color_lev+']' + level + " =>[/color] " + powname + '\n[color='+f_color_enh+']' + enhs + "[/color]\n";
				break;
			}
		}

	}

	for ( x=25; x<= 40; x++){

		level = left(document.getElementById('selection'+x).innerHTML, 4);
		level = level.replace('(','');
		level = level.replace(')','');

		powname = document.getElementById('seltext'+x).innerHTML;
		powID   = document.getElementById('selection'+x).name;

		enhs = '';

		enhs_arr = new Object();

		for (l=1; l<=6;l++){
		
			try{

				li = document.getElementById('li_'+x+'_'+l);
	
				src = (li.childNodes[0]).childNodes[0].src;
				lev = (li.childNodes[0]).childNodes[0].alt;
				
				if (!src.match(/new.gif/)){
					if (src.match(/hos/)){
						dir = 'img/hos/';
					} else if (src.match(/ios/)){
						dir = 'img/ios/';
					} else {
						dir = 'img/enh/';
					}
					
					enhc = src.replace(site+dir,'');
					enhc = enhc.replace(/.gif/,'');
					enhc = enhc.replace(/.png/,'');
		
					if (style == 'short' || style == 'shortu'){
						enhc = shorten(enhc.replace(/%20/g,' '));
						enhc = enhc.replace(' ','');
						enhc = enhc.replace(/Exposure/,'');
						if (enhs_arr[enhc]){
							enhs_arr[enhc]++;
						} else {
							enhs_arr[enhc] = 1;
						}
					} else if (left(style,4) == 'long'){
						if (dir == 'img/ios/'){
							title = title.replace(/\([0-9]+\)/,'');
							title = title.replace(enhc.replace(/%20/,' '),'');
							enhs += 'IO - ' + enhc.replace(/%20/g,' ') + ' ' + title + ' (' + lev + ')\n ';
						} else {
							enhs += enhc.replace(/%20/g,' ') + '(' + lev + ')\n ';
						}
					} else {
						enhs += shorten(enhc.replace(/%20/g,' ')) + '(' + l + '),';
					}
				}
			
			} catch (e) {}
	
		}

		if (style == 'short' || style == 'shortu'){
			for (i in  enhs_arr){

				eName = i;
				eCount = enhs_arr[eName];

				enhs += eCount + 'x' + eName + ',';

			}
		} else {
			enhs = enhs.replace('(0','(');
		}

		enhs = left(enhs, enhs.length-1);

		if (powname){
			switch (style){
				case "simple":
				case "short":
					inh += level +' => ' + powname + ' ==> ' + enhs + "\n";
				break;

				case "ubb":
				case "shortu":
					inh += '[color:"'+color_lev+'"]' + level + " =>[/color] " + powname + ' ==> [color:"'+color_enh+'"]' + enhs + "[/color]\n";
				break;

				case 'ubb2':
					inh += '[color:"'+f_color_lev+'"]' + level + " =>[/color] " + powname + ' ==> [color:"'+f_color_enh+'"]' + enhs + "[/color]\n";
				break;

				case "phpbb":
					inh += '[color='+color_lev+']' + level + " =>[/color] " + powname + ' ==> [color='+color_enh+']' + enhs + "[/color]\n";
				break;
				case "forum_build":
				case "planner":
					inh += '[color='+f_color_lev+']' + level + " =>[/color] " + powname + ' ==> [color='+f_color_enh+']' + enhs + "[/color]\n";
				break;
				
				case 'long':
					out += level +' => ' + powname + '\n' + enhs + "\n";
				break;
				
				case 'longubb':
					out += '[color:"'+color_lev+'"]' + level + " =>[/color] " + powname + '\n[color:"'+color_enh+'"]' + enhs + "[/color]\n";
				break;

				case 'longubb2':
					out += '[color:"'+f_color_lev+'"]' + level + " =>[/color] " + powname + '\n[color:"'+f_color_enh+'"]' + enhs + "[/color]\n";
				break;
				
				case 'longpl':
					out += '[color='+f_color_lev+']' + level + " =>[/color] " + powname + '\n[color='+f_color_enh+']' + enhs + "[/color]\n";
				break;

			}
		}

	}

	out += "+---------------------------------------------\n";
	out += inh;

	cname = document.planner.charname.value;

	if (cname == '' || cname == 'Character Name'){
		cname = 'N/A';
	}
	
	n = "Name: " + cname + "\n";
    l = "Level: " + document.planner.level.value + "\n";
   	if (style != 'forum_build'){
		a = "Archetype: " + document.planner.at.options[document.planner.at.options.selectedIndex].text + "\n";
		p = "Primary: " + document.planner.primary.options[document.planner.primary.options.selectedIndex].text + "\n";
		s = "Secondary: " + document.planner.secondary.options[document.planner.secondary.options.selectedIndex].text + "\n";
	}

    var m = '';

    if(style == 'ubb' || style == 'phpbb' || style == 'shortu' || style == 'forum_build' || style == 'ubb2' || style == 'planner'){
        m = '[b]';
    }

	if (style != 'forum_build' && style != 'planner'){
	    m+= "+---------------------------------------------\n";
	    m+= "+ Built with SuckerPunch's Online Planner\n";
	    m+= "+ http://www.cohplanner.com\n";
	    m+= "+---------------------------------------------\n";
	}
	else{
		m+= "+---------------------------------------------\n";
	}
    if (style == 'ubb'){
        m+= "[color:\"yellow\"]";
		out = out.replace(/\(/g,'[color:\"'+color_elv+'\"](');
		out = out.replace(/\)/g,')[/color]');
	} else if (style == 'ubb2'){
        m+= "[color:\""+f_color_nam+"\"]";
		out = out.replace(/\(/g,'[color:\"'+f_color_elv+'\"](');
		out = out.replace(/\)/g,')[/color]');
    } else if (style == 'phpbb'){
		m+= "[color=yellow]";
		out = out.replace(/\(/g,'[color='+color_elv+'](');
		out = out.replace(/\)/g,')[/color]');
	} else if (style == 'forum_build' || style == 'planner'){
		m+= "[color="+f_color_nam+"]";
		out = out.replace(/\(/g,'[color='+f_color_elv+'](');
		out = out.replace(/\)/g,')[/color]');		
	}
	if (style == 'forum_build'){
		m+= n + l;
	}
	else {
		m+= n + l + a +p + s;
	}
    
    if (style == 'ubb' || style == 'phpbb' || style == 'shortu' || style == 'forum_build' || style == 'planner' || style == 'ubb2'){
        m+= "[/color]";
    }

	m+= "+---------------------------------------------\n";


    m+= out;

    if (style == 'ubb' || style == 'phpbb' || style == 'shortu' || style == 'forum_build' || style == 'planner' || style == 'ubb2'){
        m += '[/b]';
    }

	if (style == 'forum_build'){
		return m;
	} else {

		document.ex.export_text.value = m;
	
		showLightbox('exportbox','0,0');
		document.ex.export_text.select();
		document.ex.export_text.focus();
	}
}

function doLoadBuild(buildID,load){

	var form = document.planner;
	
	var ao = new AjaxObject();
	ao.sndReq('get', '/ajax.php?op=load_build&x='+buildID+'&load='+load);
	
}


function startSave(){
	
	var form = document.planner;
	hideLightbox();
	
	if (form.level == 0 || form.at.value == '' || form.primary.value == '' || form.secondary.value == ''){
		alert("Nothing to save!");
		return;	
	}
	
	name = form.charname.value;
	at = form.at.value;
	p = form.primary.value;
	s = form.secondary.value;
	
	if (name == 'Character Name') name = 'N/A';

	new Ajax.Request('/ajax.php',
		{
			method: 'post',
			parameters: {op:'checkexists', name: name, at: at, p: p, s: s},
			onSuccess: function(transport){
				var response = transport.responseText || 'no response text';
				finishStartSave(response);
			},
			onFailure: function(){ alert('failed') }
		});
	
	new Ajax.Request('/ajax.php',
		{
			method: 'post',
			parameters: {op: 'citlist'},
			onSuccess: function(transport){
				var response = transport.responseText || 'no response text';
				finishCheckCIT(response);
			},
			onFailure: function(){ alert('failed') }
		});
}

function doSave(){

	form = document.planner;
	at = form.at.value;
	
	hideLightbox();
	showLightbox('saving','0,0');
	
	form.charname.value = document.check_save.save_name.value;
	document.savey.pvp.value = document.check_save.save_pvp.value;
	document.savey.overwrite.value = getCheckedValue(document.check_save.save_ov);
	document.savey.server.value = document.check_save.save_server.value;
	document.savey.origin.value = document.check_save.save_origin.value;
	document.savey.s_priv.value = document.check_save.save_private.value;
	document.savey.citID.value = document.check_save.save_cit.value;
	
	out = '';
	inh = '';
	
	if (form.level == 0 || form.at.value == '' || form.primary.value == '' || form.secondary.value == ''){
		alert("Nothing to save!");
		return;	
	}
	
	sitestr = (window.location).toString();
    site = sitestr.replace(/\/planner/,'/');
    site = site.replace(/(builds|load)\/[0-9]*/,'');

	for ( x=1; x<= 40; x++){
		
		// selection ID
		out += x + '>>';
		
		if (document.getElementById('selection'+x).innerHTML != '' && document.getElementById('selection'+x).innerHTML != '&nbsp;'){

			level = left(document.getElementById('selection'+x).innerHTML, 4);
			level = level.replace('(','');
			level = level.replace(')','');
	
			powname = document.getElementById('seltext'+x).innerHTML;
			powID   = document.getElementById('selection'+x).name;
			
			// power name, ID, and level
			out += powname + '>>' + powID + '>>' + level + '>>';
		
			for (l=1; l<=6;l++){
				
				// liID
				out += 'li_'+x+'_'+l + ':';
				
				li = document.getElementById('li_'+x+'_'+l);
				
				if (li.innerHTML == '' || li.innerHTML == '&nbsp;'){
					out += '0:0>>';
				} else {

					try{
						srcs = (li.childNodes[0]).childNodes[0].src;
						lev = (li.childNodes[0]).childNodes[0].alt;
						title = (li.childNodes[0]).childNodes[0].title;
		
						if (!srcs.match(/new.gif/)){
							
							if (srcs.match(/hos/)){
								dir = 'img/hos/';
							} else if (srcs.match(/ios/)){
								dir = 'img/ios/';
							} else {
								dir = 'img/enh/';
							}
							
							enhc = srcs.replace(site,'');

							if (dir == 'img/ios/'){
								enhc2 = enhc.replace(/.gif/,'');
								enhc2 = enhc2.replace(/.png/,'');
								enhc2 = enhc2.replace(dir,'');
								enhc2 = enhc2.replace(/%20/,' ');
								
								title = title.replace(/\([0-9]+\)\s/,'');
								title = title.replace(enhc2,'');
								title = title.replace(/:\s/,'');
								title = title.replace(/,/,'&#44;');
								title = title.replace('*','&#42;');

								enhc = enhc + '"' + title;
							} else {
							}

							out += enhc + ':' + lev + '>>';
	
						} else {
							out += '0:0>>';
						}
					} catch (e) { out += '0:0>>'; }
				}

				if (l == 6){
				
					out = left(out, out.length-2);
				
				}
			}
		}
		
		if (x < 40){
			out += "*";
		}
	}
	
	cname = form.charname.value;

	if (cname == '' || cname == 'Character Name'){
		cname = 'N/A';
	}		
		
	u  = form.u.value;
	at = form.at.value;
	p  = trim(form.primary.value);
	s  = trim(form.secondary.value);
			
	form2 = document.savey;
	
	form2.u.value = u;
	form2.n.value = cname;
	form2.at.value = at;
	form2.p.value = p;
	form2.s.value = s;
	form2.pool1.value = form.pool1.value;
	form2.pool2.value = form.pool2.value;
	form2.pool3.value = form.pool3.value;
	form2.pool4.value = form.pool4.value;
	form2.app.value = form.app.value;
	form2.atpower.value   = form.atpower.value;
	form2.atslots.value   = form.atslots.value;
	form2.enh_count.value = form.enh_count.value;
	form2.enh_tot.value	  =	form.enh_tot.value;
	form2.enh_level.value =	form.enh_level.value;
	form2.level.value     = form.level.value;
	form2.slots.value	  = form.slots.value;
	form2.data.value = out;
	form2.forum_build.value = doExport('forum_build');
	
	document.savey.submit();

}

function shorten(n){

	switch (n){

		case 'Accuracy':
			return 'Acc';
			break;

		case 'Attack Rate':
			return 'Rech';
			break;

		case 'Confusion Duration':
			return 'Confuse';
			break;

		case 'Damage':
			return 'Dam';
			break;

		case 'Damage Resistance':
			return 'DamRes';
			break;

		case 'Defense Buff':
			return 'DefBuff';
			break;

		case 'Defense DeBuff':
			return 'DefDeBuff';
			break;

		case 'Disorient Duration':
			return 'DisDur';
			break;

		case 'Endurance Cost':
			return 'EndCost';
			break;

		case 'Endurance Modification':
			return 'EndMod';
			break;

		case 'Fear Duration':
			return 'Fear';
			break;

		case 'Flight Speed':
			return 'Flight';
			break;

		case 'Heal':
			return 'Heal';
			break;

		case 'Hold Duration':
			return 'Hold';
			break;

		case 'Immobilization Duration':
			return 'Immob';
			break;

		case 'Intangibility Duration':
			return 'IntgDur';
			break;

		case 'Interrupt Time':
			return 'Interrupt';
			break;

		case 'Jump':
			return 'Jump';
			break;

		case 'KnockBack Distance':
			return 'KBDist';
			break;

		case 'Range':
			return 'Range';
			break;

		case 'Running Speed':
			return 'RunSpd';
			break;

		case 'Sleep Duration':
			return 'Sleep';
			break;

		case 'Slow powers':
			return 'Slow';
			break;

		case 'Taunt Effectiveness':
			return 'Taunt';
			break;

		case 'ToHit Buff':
		case 'ToHit Buffs':
			return 'ToHitBuff';
			break;

		case 'ToHit DeBuffs':
			return 'ToHitDeBuff';
			break;

		case 'Empty':
			return 'Empty';
			break;

		default:
			return n;
			break;
	}
}


/**** END:  export.js ****/

/**** START: toggle.js ****/

var active; 
function toggle(t)
{
	// if there's an active drop down we hide itcingu
	if(active != null)
	{
		for(var i=0; i<active.childNodes.length; i++)
			if(active.childNodes[i].nodeName == "UL")
				active.childNodes[i].style.display = "none";
	}

	// if the user didn't just click the active one (hiding it)
	if(active != t)
	{
		// set the active dropdown
		active = t;

		// set each UL in the dropdown to be "block"
		for(var i=0; i<active.childNodes.length; i++)
			if(active.childNodes[i].nodeName == "UL")
				active.childNodes[i].style.display = "block";

		// bring it to the top
		active.style.zIndex = "999";
	}
	else
		active = null;
}

function untogglefromlink(t)
{
	// when a link is clicked in the drop down you can call this function to hide it, eg:
	// <a href="page.html" onclick="untogglefromlink(this);">whatever</a>.
	toggle(t.parentNode.parentNode.parentNode);
}

/**** END:  toggle.js ****/

/**** START: funclib.js ****/

/* STANDARD STUFF
*************************************************/
function trim(str) {
	str = str.replace(/^\s*|\s*$/,"")
	return str;
}

function isNumeric(strString) {
	var strValidChars = "0123456789.-";
	var strChar;
	var blnResult = true;

	if (strString.length == 0) return false;

	for (i = 0; i < strString.length && blnResult == true; i++){
		strChar = strString.charAt(i);
		if (strValidChars.indexOf(strChar) == -1){
			blnResult = false;
		}
	}
}

function urldecode(psEncodeString){
  var lsRegExp = /\+/g;
  return unescape(String(psEncodeString).replace(lsRegExp, " "));
}


function left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}

function right(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

function getOptionText(s,v,form){
	sel = eval("document."+form+"."+s);
	for (x=0;x<sel.options.length;x++){
		if (sel.options[x].value == v){
			return sel.options[x].innerHTML;	
		}
	}
}

/* ELEMENT HIJACKING
*************************************************/

function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements)
}

/* CURSOR HIJACKING
*************************************************/
function getLoc(event){
	xc = event.clientX;
	yc = event.clientY;
	document.planner.x.value = xc;
	document.planner.y.value = yc;
}


/* STYLESHEET HIJACKING
*************************************************/

function setStyle(title) {
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && a.getAttribute("title") !='main') {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = false;
     }
   }

	/*
	if ($('u').value == 0){
		$('saveLog').style.display = 'block';
		$('saveBut').style.display = 'none';
	} else {
		$('saveLog').style.display = 'none';
		$('saveBut').style.display = 'block';
	}
	*/
}

function altRow(bg){
	if (bg == ''){
		bg = '#E9E9E9';
	} else {
		bg = '';	
	}
	
	return bg;
}
function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}


/**** END:  funclib.js ****/

/**** START: ajax.js ****/

function finishLogin(response){
	i = response.split('=>');
	success = i[0];
	global  = i[1];
	userID  = i[2];
	
	if (success == 'true'){
		$('u').value = userID;
		$('username_li').innerHTML = '<a href="/'+global+'">'+global+'</a>&nbsp;&nbsp;[ <a id="logout" href="javascript:logout();">Log Out</a> ]&nbsp;';
		
		$('slogin').style.display = 'none';
		$('sregister').style.display = 'none';
		$('username_li').style.display = 'inline';
		$('smanage').style.display = 'inline';
		
		hideLightbox();
		try{toggleCommentForm();} catch (e) {}
	} else {
		$('message').innerHTML = '<strong style="color:red">Incorrect username/password!</strong>';	
	}
}

function finishCITLink(response,op){
	i = response.split('=>');
	
	success = i[0];
	
	if (op == 'citlist'){
		if (success == 0){
			alert('Sorry, CIT link failed. Error 1');
			return;
		}
		else {
			ch = i[1].split('?');
			ch = ch.sort();

			$('cit_chars').options.length = 0;

			for (x=0; x<ch.length; x++){
				chars = ch[x].split(',');
				$('cit_chars').options[$('cit_chars').length] = new Option(chars[0] + ' ('+chars[2]+')' ,chars[1]);
			}
			
			var arrayPageSize = getPageSize();
			var arrayPageScroll = getPageScroll();
			
			xc = parseInt($('x').value)-315;
			yc = (parseInt(arrayPageScroll[1]) + parseInt($('y').value)) - 15;
		
			$('cit_list').style.display = 'block';
			$('cit_list').style.left = xc;
			$('cit_list').style.top = yc;
			$('cit_list').style.width = '300px';
		}	
	}

	if (op == 'citlink'){
		if (success == 0){
			alert('Sorry, CIT link failed. Error 2.');
			return;
		}
		else {
			buildID = i[1];
			citlink = '<a href="javascript:;" onClick="linkCIT(0,\''+buildID+'\');">';
			citlink+= '<img src="/img/cit_unlink.gif" title="Unlink this build from CIT" alt="Unlink this build from CIT" />';
			citlink+= '</a>';

			$('cit'+buildID).innerHTML = citlink;
			$('cit_list').style.display = 'none';

			alert('CIT Build successfully linked!');
			return;
		}
	}

	if (op == 'citdel'){
		buildID = i[1];
		
		if (success == 0){
			alert('Sorry, unlink operation failed');
			return;
		}
		else{
			citlink = '<a href="javascript:;" onClick="linkCIT(1,\''+buildID+'\');">';
			citlink+= '<img src="/img/cit_link.gif" title="Link this build to a CIT character" alt="Link this build to a CIT character" />';
			citlink+= '</a>';
			$('cit'+buildID).innerHTML = citlink;
			
			alert('Build successfully unlinked from CIT');
			return;
		}
	}
}

function finishDeleteBuild(response,n){
	i = response.split('=>');
	success = i[0];
	
	if (success == 0){
		alert("Delete failed!");	
	} else {
		alert(n + ' deleted!');
		window.location='/manage';
	}
}

function finishDupeBuild(response){
	if (response == '0'){
		alert("Build Duplication Failed! :(");	
	} else {
		alert('Build duplicated!');
		window.location='/manage';
	}
}

function finishStartSave(response){
	i = response.split('=>');
	exists = i[0];

	$('save_name').value = form.charname.value;
	
	if (exists != 'false'){
		
		buildIDs = i[0].split(',');;	
		names = i[1].split(',');
		levels = i[2].split(',');
		extras = i[3];

		$('save_exists').style.display = 'block';
		
		tbl = $('save_builds');
		
		if (tbl.rows.length > 1){
			len = tbl.rows.length;
			for (t = 1; t <= len; t++){
				try {
					tbl.deleteRow(1);
				} catch(e){ }
			}
		}
		
		for (x=0;x<buildIDs.length;x++){
			lastRow = tbl.rows.length;
			var row = tbl.insertRow(lastRow);
			
			url = "<a href=\"http://www.cohplanner.com/?a=load&id="+buildIDs[x]+"\" target=\"_blank\">";
			
			cell = row.insertCell(0);
			cell.innerHTML = "<input type=\"radio\" name=\"save_ov\" value=\""+buildIDs[x]+"\" style=\"border: 0;\">";
			
			cell = row.insertCell(1);
			cell.innerHTML = 'Replace <b>' + url + names[x] + '</a></b> [Level ' + levels[x] + ']';
		}
		
		if (extras != 0){
			extra = extras.split(',');
			
			document.check_save.save_pvp.value = extra[0];
			document.check_save.save_origin.value = extra[1];
			document.check_save.save_server.value = extra[2];
			document.check_save.save_private.value = extra[3];
		}
		
	} else {
		tbl = $('save_builds');
		
		if (tbl.rows.length > 1){
			len = tbl.rows.length;
			for (t = 1; t <= len; t++){
				try {
					tbl.deleteRow(1);
				} catch(e){ }
			}
		}
		$('save_exists').style.display = 'none';
	}
								
	showLightbox('savecheck','0,0');
}

function finishCheckCIT(response){
	i = response.split('=>');
	
	if (i[0] != 0){
		ch = i[1].split('?');
		ch = ch.sort();

		$('save_cit').options.length = 0;

		// one empty one
		$('save_cit').options[$('save_cit').length] = new Option('Select CIT Character:','0');
		
		for (x=0; x<ch.length; x++){
			chars = ch[x].split(',');
			if (chars[0] == $('save_name').value){
				$('save_cit').options[$('save_cit').length] = new Option(chars[0] + ' ('+chars[2]+')' ,chars[1], true);
			} else {
				$('save_cit').options[$('save_cit').length] = new Option(chars[0] + ' ('+chars[2]+')' ,chars[1], false);
			}
		}
		
		$('cit_li').style.display = 'block';
		$('save_cit').style.visibility = 'visible';
	}	
}

function finishImgDel(response,bID){
	if (response == '0'){
		alert('There was an error deleting the avatar.\n\nPlease log out and log back in, and try again!');
		return;
	} else {
		alert('Avatar deleted successfully!');
		$('img'+bID).innerHTML = '<a href="javascript:;" onClick="toggleImgUpload('+bID+');"><img src="/img/img_add.gif" /></a>';
	}
}

function AjaxObject() {
	this.createRequestObject = function() {
		var ro;
		if ( window.XMLHttpRequest) {
			try { ro = new XMLHttpRequest();
			}			
			catch (e) { ro = new ActiveXObject("Microsoft.XMLHTTP"); 
			}
		}
		else {	ro = new ActiveXObject("Microsoft.XMLHTTP");
		}
		return ro;	
	}
	this.sndReq = function(action, url) {
		this.http.open(action,url);
		this.http.onreadystatechange = this.handleResponse;
		this.http.send(null);
	}
	this.handleResponse = function() {
		if ( me.http.readyState == 4) {
			var rawdata = me.http.responseText.split("|");
				
			for ( var i = 0; i < rawdata.length; i++ ) {
								
				var item = (rawdata[i]).split("=>");
								
				if (item[0] != "") {
					type = item[0];
					form = document.planner;
					
					switch (type){
						
						case 'select':
							pool = item[1];
							ids = item[2];
							names = item[3];							
	
							sear = document.sea;
																				
							if (pool == '1'){ 
								p = 'primary';
							} 
							else if (pool == '2') {
								p = 'secondary';	
							}
							else if (pool == '4') {
								p = 'app';	
							}
														
							ids = ids.split(',');
							names = names.split(',');							
							
							eval("form."+p+".options.length = 1;");
							
							for (x=0; x<ids.length; x++){
								eval("form."+p+".options[form."+p+".options.length] = new Option('"+names[x]+"','"+ids[x]+"');");
							}
						break;
						
						case 'pools_search':
													
							pool = item[1];
							ids = item[2];
							names = item[3];							
	
							sear = document.sea;
																				
							if (pool == '1'){ 
								p = 'primary';
							} else {
								p = 'secondary';	
							}
														
							ids = ids.split(',');
							names = names.split(',');							
							
							eval("sear."+p+".options.length = 1;");
							
							for (x=0; x<ids.length; x++){
								eval("sear."+p+".options[sear."+p+".options.length] = new Option('"+names[x]+"','"+ids[x]+"');");
							}
						
						break;
						
						case 'html':
							pool = item[1];						
							ids  = item[2];
							names= item[3];
												
							names = names.split(',');
							ids = ids.split(',');

							for (x=0; x<names.length; x++){
								
								$(pool+(x+1)).name = ids[x];
								$(pool+(x+1)).innerHTML = names[x];
								
								if ((pool+(x+1)) == 'sec1' && form.load.value == 0){
									choosePower(ids[x], 'sec1');
								}
								
								r = $(pool+(x+1)+'_i');
								r.childNodes[0].href = "javascript:showDetail('"+ids[x]+"');";
								
							}
							
							if (form.at.value == 11 || form.at.value == 12){
								disp = '';
								form.app.disabled = true;
								$('app_div').style.display = 'none';
							} else {
								disp = 'none';
								form.app.disabled = false
								$('app_div').style.display = '';
							}
							
						break;
						
						case 'span':
							name = item[1];
							id   = item[2];
							val  = item[3];
							e    = String(item[4]);

							level = left($('selection'+id).innerHTML, 4);
							level = level.replace('(','');
							level = level.replace(')','');
	
							$('seltext'+id).innerHTML = urldecode(name);
							$('selection'+id).name = urldecode(val);
							$('li_'+id+'_1').innerHTML = "<a href=\"javascript:showEnhDiv('"+val+"','li_"+id+"_1');\"><img id=\""+val+"-"+level+"\" alt=\""+level+"\" src=\"/img/enh/Empty.gif\" /></a>";
						break;
						
						case 'kspan': // special for khelds
							name = item[1];
							id   = item[2];
							level  = item[3];
							e    = String(item[4]);

							for (x=25;x<=40;x++){
								if ($('seltext'+x).innerHTML == ''){
	
									$('seltext'+x).innerHTML = urldecode(name);
									$('selection'+x).name = urldecode(e);
	
									$('selection'+x).innerHTML = '('+level+')'+ $('selection'+x).innerHTML;
	
									img = "<a href=\"javascript:showEnhDiv('"+e+"','li_"+x+"_1');\"><img id=\""+e+"-"+level+"\" alt=\""+level+"\" src=\"/img/enh/Empty.gif\" /></a>";
	
									$('li_'+x+'_1').innerHTML = img;
	
									return;
								}
							}
							makeSlotsAvailable();
						break;
						
						case 'kspan2':
							name = item[1];
							id   = item[2];
							level= item[3];
							e    = String(item[4]);
	
							if (level.length == 1){
								level = '0' + String(level);
							}
	
							g = name.split('|');
	
							didit = 0;
	
							for (x=25;x<=40;x++){
								if ($('seltext'+x).innerHTML == '' && didit == 0){
	
									$('seltext'+x).innerHTML = urldecode(name);
									$('selection'+x).name = urldecode(id);
	
									$('selection'+x).innerHTML = $('selection'+x).innerHTML.replace(/\(\d+\)/,'');
									$('selection'+x).innerHTML = '('+level+')'+ $('selection'+x).innerHTML;
	
									img = "<a href=\"javascript:showEnhDiv('"+id+"', 'li_"+x+"_1');\"><img id=\""+id+"-"+level+"\" alt=\""+level+"\" src=\"/img/enh/Empty.gif\" /></a>";
									
									$('li_'+x+'_1').innerHTML = img;
	
									didit = 1;
								}
							}
							makeSlotsAvailable();
						break;
						
						case 'enh':
							enhs  = urldecode(item[1]).split(',');
							powID = item[2];
							liID  = item[3];
							names = urldecode(item[4]).split(',');
							hos = urldecode(item[5]).split(',');
							ios = urldecode(item[6]).split(',');
							ioes = urldecode(item[7]).split(',,');
							
							e_name = names[0];
	
							out = '';
	
							for ( g = 0; g < enhs.length; g++ ){
								out += "<a href=\"javascript:chooseEnh('"+liID+"','"+enhs[g]+"');\" title=\""+enhs[g]+"\"><img src=\"/img/enh/" + enhs[g] + ".gif\" /></a>";
							}
							
							out += "<a href=\"javascript:chooseEnh('"+liID+"','Empty');\" title=\"Empty\"><img src=\"/img/enh/Empty.gif\" /></a>";
							
							if (hos != 0){
								out += "<br />";
								for (h = 0; h < hos.length; h++){
									if (hos[h].length > 0){
										out += "<a href=\"javascript:chooseEnh('"+liID+"','"+hos[h]+"');\" title=\""+ho_list[hos[h]]+"\"><img src=\"/img/hos/" + hos[h] + ".gif\" /></a>";
									}
								}
							}
							
							if (ios != 0){
								out += "<br />";
								last = '';
								for (i = 0; i < ios.length; i++){
									if (ios[i].length > 0){
										if (last != ios[i]){
											out += '<br /><strong>' + ios[i] + '</strong><br />';
										}
										out += "<a href=\"javascript:chooseEnh('"+liID+"','IO-"+ios[i]+"-"+ioes[i]+"');\" title=\""+ios[i]+": "+ioes[i]+"\"><img src=\"/img/ios/" + ios[i] + ".png\" /></a>";
										last = ios[i];
										//out += "<a href=\"javascript:showIOSets('"+ios[i]+"');\" title=\""+ios[i]+"\"><img src=\"/img/ios/" + ios[i] + ".png\" /></a>";
									}
								}
							}
	
							$('enh_name').innerHTML = e_name;
							$('enh_imgs').innerHTML = out;
							
							xy = form.x.value + ',' + form.y.value;
							setTimeout("showLightbox('enh','"+xy+"');",150);
						break;
						
						case 'detail':
							name	= urldecode(item[1]);
							detail	= urldecode(item[2]);
							val		= item[3];
							e		= String(item[4]);
				
							data   = urldecode(val).split('+');			
							descr  = urldecode(data[0]);

							if (detail == ''){ detail = 'No Data'; }
							if (descr  == ''){ descr  = 'No Data'; }

							$('details_h1').innerHTML   = '&nbsp;' + name;
							$('details_span2').innerHTML= "(" + detail + ")";
							$('details_span').innerHTML = descr + "<br />";
							$('details_div').innerHTML  = '';
							if (data[2].length > 0){
								$('details_div').innerHTML  += "<b style=\"color:red\">Recharge:</b> " + data[2] + "<br />";
							}
							if (data[3].length > 0){
								$('details_div').innerHTML  += "<b style=\"color:red\">End Cost:</b> " + data[3] + "<br />";
							}
							bix = data[4].replace("|1x0(None)",'');
							bix = bix.replace("|0x0(None)",'');
							bix = bix.replace("|0x0()",'');
							bix = bix.replace("0x0(None)",'');
							bix = bix.replace("0x0()",'');
							bix = bix.replace("1x0(None)",'');
							if (bix.length > 0){
								bix = bix.replace(/\|/g, ', ');
								$('details_div').innerHTML  += "<b style=\"color:red\">Brawl Index:</b> " + bix + " <small>(Total: " + data[5] + ")</small><br />";
							}
							
							$('details_div').innerHTML  += "<br /><b>Enhancements:</b><br />";
							enhs = data[1].split(',');
							img = '';
							for (x=0;x < enhs.length; x++){
								img +=	"<img src=\"/img/enh/"+enhs[x]+".gif\">&nbsp;";
							}
							$('details_div').innerHTML  += img + "<br />";
							
							xy = form.x.value + ',' + form.y.value;
		
							showLightbox('details',xy);	
						break;
						
						case 'user':
							name = urldecode(item[1]);			

							if (name == 'false') {
								$('reg_msg').style.display = 'block';
								$('reg_msg').style.color = 'red';
								$('reg_msg').innerHTML = 'Please select a different username.';
							} 
							else {
								$('reg_msg').style.display = 'block';
								$('reg_tbl').style.display = 'none';
								$('reg_msg').style.color = 'green';
								$('reg_msg').innerHTML = 'Account Created!<br>You may now login!<br>';
								$('reg_msg').innerHTML+= '<a href="javascript:hideLightbox();doShowLogin();">Login Now</a><br><br>';
							}
						break;
						
						case 'save':
							name = urldecode(item[1]);
							alert(name);
						break;
						
						case 'load':
							dat = urldecode(item[1]);
						
							if (dat==0){
								alert('Build Load Failed!');
								hideLightBox();
							} else {
								load = item[18];

								a		 = item[2];
								p		 = item[3];
								s		 = item[4];
								atpower	 = item[5];
								enh_count= item[6];
								enh_tot	 = item[7];	
								level	 = item[8];
								slotss	 = item[9];
								pool1	 = item[10];
								pool2	 = item[11];
								pool3	 = item[12];
								pool4	 = item[13];
								appp	 = item[14];
								name	 = item[15];
								enh_level= item[16];
								atslots  = item[17];

								form = document.planner;

								if (load == 1){
									pname = item[19];
									sname = item[20];
									gbl   = item[21];
									$('charname').innerHTML = name.toUpperCase() + $('charname').innerHTML;
									$('primary').innerHTML = pname;
									$('secondary').innerHTML = sname;
									$('globalID').innerHTML = '<a href="/'+gbl+'">'+gbl+'</a>';
								}
								else if (load == 2){
									// nuffin'
								}
								else {

									form.at.value = a;
									
									form.charname.value  = name;
									form.load.value 	 = 1;

									form.pool1.value = pool1;
									form.pool2.value = pool2;
									form.pool3.value = pool3;
									form.pool4.value = pool4;
									
									fillPrimSecLoad();
									
									form.primary.value = p;
									form.secondary.value = s;
									form.app.value = appp;
									
									fillPowers('prim','primary');
									fillPowers('sec','secondary');
									fillPowers('app','app');
									fillPowers('pool1_','pool1');
									fillPowers('pool2_','pool2');
									fillPowers('pool3_','pool3');
									fillPowers('pool4_','pool4');
									
									form.atpower.value   = atpower;
									form.atslots.value   = atslots;
									form.enh_count.value = enh_count;
									form.enh_tot.value   = enh_tot;
									form.enh_level.value = enh_level;
									form.level.value     = level;
									form.slots.value     = slotss;
								}
								
								lines = dat.split("*");
								
								// fill out the powers and slots
								iocheck=0;
								for (x=0;x<40;x++){
									ldata = lines[x].split('>>');
																		
									if ((x+1) == ldata[0] && ldata[1] != 'undefined'){
										 if (ldata[1].length > 20){
                                         	$('seltext'+(x+1)).innerHTML = left(ldata[1],17) + '...';
                                         } else {
                                         	$('seltext'+(x+1)).innerHTML = ldata[1];
                                         }

										$('selection'+(x+1)).name = ldata[2];	
										
										check = 0;
										
										for (l=4;l<=9;l++){
											if (!ldata[l].match(/0:0/)){
												
												liArr = ldata[l].split(':');
												
												li = liArr[0];
												lie = liArr[1];
												lil = liArr[2];
												lit = lil;

												if (lie.match('hos')){
													if (!lie.match(/img\/hos/)){
														lie = lie.replace('hos/','/img/hos/');
													}
												} else if (lie.match('ios')){

													if (iocheck == 0 && load == 0){
														$('show_ios').checked = true;
														$('exp').value = 'long';
													}

													iocheck = 1;
													
													liez = lie.split('"');
													lie = liez[0];
													lit = '('+lil+'): '+ (lie.replace(/img\/ios\//,'')).replace(/\.png/,'') +': '+liez[1].replace(/&#44;/,',');
												}else{

													if (!lie.match(/img\/enh/)){
														lie = lie.replace('img/','img/enh/');
													}
												}

												if (load == 0){
													$(li).innerHTML = "<a href=\"javascript:showEnhDiv('"+ldata[2]+"','"+li+"');\"><img id=\""+ldata[2]+lil+"\" alt=\""+lil+"\" title=\""+lit+"\" src=\"/"+lie+"\"></a>";
												} 
												else if (load == 2){
													lie = lie.replace('img/enh/','img/enh/18_');
													lie = lie.replace('gif','png');
													
													lie = lie.replace('img/hos/','img/hos/18_');
													lie = lie.replace('gif','png');
													
													lie = lie.replace('img/ios/','img/ios/18_');

													if (lie.match('enh')){
														lil = lie.replace('img/enh/18_','');
														lil = lil.replace('.png','');
														lil = liArr[2] + ': ' + lil;
													}
													
													if (lie.match('hos')){
														lil = lie.replace('img/hos/18_','');
														lil = lil.replace('.png','');
														lil = liArr[2] + ': ' + lil;
													}

													if (lie.match('ios')){
														lil = lie.replace('img/ios/18_','');
														lil = lil.replace('.png','');
														lil = liArr[2] + lit.replace(/\([0-9]+\)/,'');
													}
													
													$(li).innerHTML = "<img id=\""+ldata[2]+lil+"\" title=\""+lil+"\" alt=\""+lil+"\" title=\""+lit+"\" src=\"/"+lie+"\">";
												} 
												else {
													$(li).innerHTML = "<img id=\""+ldata[2]+lil+"\" alt=\""+lil+"\" title=\""+lit+"\" src=\"/"+lie+"\">";
												}
												
											} else {
												liArr = ldata[l].split(':');												
												li = liArr[0];
											
												if (slotss > 0 && !li.match(/_1$/) && ldata[2] != 'undefined' && check == 0 && enh_level < level){
													//$(li).innerHTML = "<a href=\"javascript:placeEmptyEnh('"+li+"','"+ldata[2]+"')\"><img src=\"/img/enh/new.gif\"></a>";
													check = 1;
												}
											}
										}
									}
								}

								if (load == 0){
									if (a == 11 || a == 12){
										showKheldPowers(1);	
									} else {
										showKheldPowers(2);
									}
									
									makePowerAvailable(level, 'prim',   14);
									makePowerAvailable(level, 'sec',    12);
									makePowerAvailable(level, 'pool1_', 4);
									makePowerAvailable(level, 'pool2_', 4);
									makePowerAvailable(level, 'pool3_', 4);
									makePowerAvailable(level, 'pool4_', 4);
									makePowerAvailable(level, 'app', 	4);
									
									if (enh_level == 50 && slotss == 0){
									} else {
										makeSlotsAvailable();
									}
									
									$('atbg').style.background = "url('/img/at"+a+".png') top left no-repeat";

									powerCompare();
								}
								
								// change the stylesheet
								if (load < 2){
									if (a <= 5){
										setStyle('villain');
									} else {
										setStyle('hero');
									}
								}

								if (item[18] == 1){
									hideLightbox();
								}
							}
							
						break;
						
						case 'login':
							success = item[1];
							global  = item[2];
							userID  = item[3];
							form = document.planner;
							
							if (success == 'true'){
								$('username_li').innerHTML = '<a href="/'+global+'">'+global+'</a>&nbsp;&nbsp;[ <a id="logout" href="javascript:logout();">Log Out</a> ]&nbsp;';
								form.u.value = userID;
								
								$('slogin').style.display = 'none';
								$('sregister').style.display = 'none';
								$('username_li').style.display = 'inline';
								$('smanage').style.display = 'inline';

								hideLightbox();
								toggleCommentForm();
							} else {
								$('message').innerHTML = '<span style="color:red">Incorrect username/password!</span>';	
							}
						
						break;
						
						case 'logout':
						
							form = document.planner;
													
							$('slogin').style.display = 'inline';
							$('sregister').style.display = 'inline';
							$('username_li').style.display = 'none';
							$('smanage').style.display = 'none';
							
							form.u.value = '';

							toggleCommentForm();

						break;
						
					}
				}
			}
		}
	}
	var me = this;
	this.http = this.createRequestObject();
}


/**** END:  ajax.js ****/

/**** START: static_ios.js ****/

var io_set = new Object();
io_set['Bonesnap'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Attack Rate';
io_set['Pulverizing Fisticuffs'] = 'Damage,Accuracy|Damage,Accuracy,Attack Rate|Damage,Accuracy,Attack Rate,Endurance Cost';
io_set['Bruising Blow'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate';
io_set['Pounding Slugfest'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|2% chance of 8 * Melee_Stun (Stun)';
io_set['Smashing Haymaker'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Endurance Cost,Attack Rate';
io_set['Kinetic Combat'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Endurance Cost,Attack Rate|20% chance of 0.67 Knockup';
io_set['Focused Smite'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Endurance Cost,Attack Rate|Damage,Accuracy,Attack Rate';
io_set['Touch of Death'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Endurance Cost,Accuracy|Damage,Endurance Cost,Attack Rate|15% chance of 0.67 * Melee_Damage (Negative)';
io_set['Crushing Impact'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Accuracy,Attack Rate|Damage,Endurance Cost,Accuracy|Damage,Endurance Cost,Attack Rate';
io_set['Makos Bite'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Endurance Cost,Attack Rate|Damage,Accuracy,Attack Rate,Endurance Cost|20% chance of 0.67 * Melee_Damage (Energy)';
io_set['Far Strike'] = 'Damage,Range|Damage,Attack Rate|Accuracy,Endurance Cost';
io_set['Salvo'] = 'Damage,Accuracy|Damage,Endurance Cost,Attack Rate|Damage,Accuracy,Range,Endurance Cost';
io_set['Volley Fire'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate';
io_set['Tempest'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|25% chance of 13% Endurance Drain';
io_set['Maelstroms Fury'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Endurance Cost,Attack Rate';
io_set['Entropic Chaos'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Endurance Cost,Attack Rate|10% chance of 0.5 * Melee_HealSelf (Heal)';
io_set['Ruin'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Endurance Cost,Attack Rate|Damage,Accuracy,Attack Rate';
io_set['Decimation'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Endurance Cost,Attack Rate|Damage,Accuracy,Attack Rate|5% chance of Build Up (10 sec)';
io_set['Thunderstrike'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Accuracy,Attack Rate|Damage,Endurance Cost,Accuracy|Damage,Endurance Cost,Attack Rate';
io_set['Devastation'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Accuracy,Attack Rate|Damage,Accuracy,Attack Rate,Endurance Cost|15% chance of 8 * Melee_Immobilize (Hold)';
io_set['Air Burst'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Range';
io_set['Detonation'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Range|Damage,Endurance Cost,Accuracy|Damage,Accuracy,Range';
io_set['Positrons Blast'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Damage,Range|Damage,Endurance Cost,Accuracy|20% chance of 0.42 * Melee_Damage (Energy)';
io_set['Cleaving Blow'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Attack Rate';
io_set['Multi Strike'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|Damage,Endurance Cost,Attack Rate';
io_set['Sciroccos Dervish'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Attack Rate|Accuracy,Attack Rate|Damage,Endurance Cost,Accuracy|20% chance of 0.15 * Melee_Damage (Lethal per tick for 4.25 sec)';
io_set['Exploit Weakness'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,Range|Damage,Attack Rate';
io_set['Calibrated Accuracy'] = 'Damage,Accuracy|Accuracy,Endurance Cost|Accuracy,InterruptTime|Accuracy,Range|Accuracy,Attack Rate|Damage,Accuracy,Attack Rate';
io_set['Executioners Contract'] = 'Damage,Accuracy|Damage,Endurance Cost|Damage,InterruptTime|Damage,Range|Damage,Attack Rate|10% chance of 8 * Melee_Stun (Stun)';
io_set['Extreme Measures'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,InterruptTime,Range|Damage,InterruptTime,Attack Rate|Damage,Endurance Cost,Attack Rate|Accuracy,Attack Rate,Range';
io_set['Sting of the Manticore'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,InterruptTime,Range|Damage,InterruptTime,Attack Rate|Damage,Endurance Cost,Attack Rate|20% chance of 0.15 * Melee_Damage (Toxic per tick for 4.25 sec)';
io_set['Unquestioning Loyalty'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy';
io_set['Commanding Presence'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|PBAoE (20 feet) Pet +Res(Taunt,Placate)';
io_set['Brilliant Leadership'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|Accuracy|Damage (at 0.5 value)';
io_set['Edict of the Master'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|Damage (at 0.5 value)|PBAoE (20 feet) Pet +Def(All)';
io_set['Blood Mandate'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|Accuracy|Damage (at 0.5 value)';
io_set['Sovereign Right'] = 'Damage,Accuracy|Damage,Endurance Cost|Accuracy,Endurance Cost|Damage,Endurance Cost,Accuracy|Accuracy|PBAoE (20 feet) Pet +Res(all but Psionic)';
io_set['Karma'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|-4 Magnitude Knockup Protection';
io_set['Kismet'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|Endurance Cost,Attack Rate|Defense Buff,Endurance Cost,Attack Rate|+7.5% ToHit';
io_set['Serendipity'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|Endurance Cost,Attack Rate|Defense Buff,Endurance Cost,Attack Rate|Defense|Endurance Cost';
io_set['Gift of the Ancients'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|Endurance Cost,Attack Rate|Defense Buff,Endurance Cost,Attack Rate|Defense|+7.5% RunSpeed';
io_set['Red Fortune'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|Endurance Cost,Attack Rate|Defense Buff,Endurance Cost,Attack Rate|Defense|Endurance Cost';
io_set['Luck of the Gambler'] = 'Defense Buff,Endurance Cost|Defense Buff,Attack Rate|Endurance Cost,Attack Rate|Defense Buff,Endurance Cost,Attack Rate|Defense|+7.5% Attack Rate';
io_set['Steadfast Protection'] = 'Damage Resistance,Endurance Cost|Damage Resistance,+3% Def(All)|-4 Magnitude Knockback/Knockup Protection';
io_set['Impervious Skin'] = 'Damage Resistance,Endurance Cost|Endurance Cost,Attack Rate|Damage Resistance,Attack Rate|Damage Resistance,Endurance Cost,Attack Rate|+Res(Mez effects)';
io_set['Reactive Armor'] = 'Damage Resistance,Endurance Cost|Endurance Cost,Attack Rate|Damage Resistance,Attack Rate|Damage Resistance,Endurance Cost,Attack Rate|Damage Resistance|Endurance Cost';
io_set['Impervium Armor'] = 'Damage Resistance,Endurance Cost|Endurance Cost,Attack Rate|Damage Resistance,Attack Rate|Damage Resistance,Endurance Cost,Attack Rate|Damage Resistance|1.0 * Melee_Res_Dmg (Psionic)';
io_set['Titanium Coating'] = 'Damage Resistance,Endurance Cost|Endurance Cost,Attack Rate|Damage Resistance,Attack Rate|Damage Resistance,Endurance Cost,Attack Rate|Damage Resistance|Endurance Cost';
io_set['Aegis'] = 'Damage Resistance,Endurance Cost|Endurance Cost,Attack Rate|Damage Resistance,Attack Rate|Damage Resistance,Endurance Cost,Attack Rate|Damage Resistance|0.6 * Melee_Res_Dmg (Psionic),+Res(Mez effects)';
io_set['Triage'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate';
io_set['Regenerative Tissue'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate|+20% Regeneration';
io_set['Harmonized Healing'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate|Heal|Endurance Cost';
io_set['Miracle'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate|Heal|+12.5% Recovery';
io_set['Doctored Wounds'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate|Heal|Attack Rate';
io_set['Numinas Convalesence'] = 'Heal,Endurance Cost|Endurance Cost,Attack Rate|Heal,Attack Rate|Heal,Endurance Cost,Attack Rate|Heal|+15% Regeneration,+9.4% Recovery';
io_set['Paralytic'] = 'Damage,Accuracy|Damage,Hold|Accuracy,Endurance Cost|Hold,Range|Endurance Cost,Range,Attack Rate';
io_set['Neuronic Shutdown'] = 'Damage,Accuracy|Damage,Hold|Accuracy,Endurance Cost|Hold,Range|Endurance Cost,Range,Attack Rate|20% chance of 0.15 * Melee_Damage (Psionic per tick for 4.25 sec)';
io_set['Essence of Curare'] = 'Damage,Accuracy|Damage,Hold|Accuracy,Endurance Cost|Hold,Range|Endurance Cost,Range,Attack Rate|Attack Rate,Hold,Damage';
io_set['Ghost Widows Embrace'] = 'Damage,Accuracy|Damage,Hold|Accuracy,Endurance Cost|Hold,Range|Endurance Cost,Range,Attack Rate|20% chance of 0.67 * Melee_Damage (Psionic)';
io_set['Stagger'] = 'Damage,Accuracy|Damage,Stun|Accuracy,Endurance Cost|Stun,Range|Endurance Cost,Range,Attack Rate';
io_set['Razzle Dazzle'] = 'Damage,Accuracy|Damage,Stun|Accuracy,Endurance Cost|Stun,Range|Endurance Cost,Range,Attack Rate|2% chance of 8 * Melee_Immobilize (Immobilize)';
io_set['Rope A Dope'] = 'Damage,Accuracy|Damage,Stun|Accuracy,Endurance Cost|Stun,Range|Endurance Cost,Range,Attack Rate|Stun,Accuracy';
io_set['Stupefy'] = 'Damage,Accuracy|Damage,Stun|Accuracy,Endurance Cost|Stun,Range|Endurance Cost,Range,Attack Rate|20% chance of 6.0 Knockup';
io_set['Rooting Grasp'] = 'Damage,Accuracy|Damage,Immobilize|Accuracy,Endurance Cost|Immobilize,Range|Endurance Cost,Range,Attack Rate';
io_set['Debiliative Action'] = 'Damage,Accuracy|Damage,Immobilize|Accuracy,Endurance Cost|Immobilize,Range|Endurance Cost,Range,Attack Rate|2% chance of 8 * Melee_Stun (Stun)';
io_set['Enfeebled Operation'] = 'Damage,Accuracy|Damage,Immobilize|Accuracy,Endurance Cost|Immobilize,Range|Endurance Cost,Range,Attack Rate|Accuracy,Immobilize';
io_set['Trap of the Hunter'] = 'Damage,Accuracy|Damage,Immobilize|Accuracy,Endurance Cost|Immobilize,Range|Endurance Cost,Range,Attack Rate|20% chance of 0.15 * Melee_Damage (Lethal per tick for 4.25 sec)';
io_set['Curtail Speed'] = 'Accuracy,Slow|Damage,Slow|Accuracy,Endurance Cost|Range,Slow|Endurance Cost,Attack Rate,Slow';
io_set['Impeded Swiftness'] = 'Accuracy,Slow|Damage,Slow|Accuracy,Endurance Cost|Range,Slow|Endurance Cost,Attack Rate,Slow|20% chance of 0.67 * Melee_Damage (Smashing)';
io_set['Tempered Readiness'] = 'Accuracy,Slow|Damage,Slow|Accuracy,Endurance Cost|Range,Slow|Endurance Cost,Attack Rate,Slow|Accuracy,Damage,Slow';
io_set['Pacing of the Turtle'] = 'Accuracy,Slow|Damage,Slow|Accuracy,Endurance Cost|Range,Slow|Endurance Cost,Attack Rate,Slow|20% chance of -20% Attack Rate';
io_set['Hibernation'] = 'Damage,Accuracy|Damage,Sleep|Accuracy,Endurance Cost|Sleep,Range|Attack Rate,Endurance Cost,Sleep';
io_set['Induced Coma'] = 'Damage,Accuracy|Damage,Sleep|Accuracy,Endurance Cost|Sleep,Range|Attack Rate,Endurance Cost,Sleep|20% chance of -20% Attack Rate';
io_set['Lethargic Repose'] = 'Damage,Accuracy|Damage,Sleep|Accuracy,Endurance Cost|Sleep,Range|Attack Rate,Endurance Cost,Sleep|Sleep,Accuracy';
io_set['Call of the Sandman'] = 'Damage,Accuracy|Damage,Sleep|Accuracy,Endurance Cost|Sleep,Range|Attack Rate,Endurance Cost,Sleep|10% chance of 0.5 * Melee_HealSelf (Heal)';
io_set['Horror'] = 'Damage,Accuracy|Damage,Fear|Accuracy,Endurance Cost|Fear,Range|Attack Rate,Endurance Cost,Fear';
io_set['Unspeakable Terror'] = 'Damage,Accuracy|Damage,Fear|Accuracy,Endurance Cost|Fear,Range|Attack Rate,Endurance Cost,Fear|2% chance of 8 * Melee_Stun (Stun)';
io_set['Nightmare'] = 'Damage,Accuracy|Damage,Fear|Accuracy,Endurance Cost|Fear,Range|Attack Rate,Endurance Cost,Fear|Accuracy,Fear';
io_set['Glimpse of the Abyss'] = 'Damage,Accuracy|Damage,Fear|Accuracy,Endurance Cost|Fear,Range|Attack Rate,Endurance Cost,Fear|20% chance of 0.67 * Melee_Damage (Psionic)';
io_set['Befuddling Aura'] = 'Damage,Accuracy|Damage,Confuse|Accuracy,Endurance Cost|Confuse,Range|Attack Rate,Endurance Cost,Confuse';
io_set['Cacophany'] = 'Damage,Accuracy|Damage,Confuse|Accuracy,Endurance Cost|Confuse,Range|Attack Rate,Endurance Cost,Confuse|20% chance of 0.67 * Melee_Damage (Energy)';
io_set['Perplex'] = 'Damage,Accuracy|Damage,Confuse|Accuracy,Endurance Cost|Confuse,Range|Attack Rate,Endurance Cost,Confuse|Attack Rate,Confuse';
io_set['Malaises Illusions'] = 'Damage,Accuracy|Damage,Confuse|Accuracy,Endurance Cost|Confuse,Range|Attack Rate,Endurance Cost,Confuse|20% chance of 0.67 * Melee_Damage (Psionic)';
io_set['Soaring'] = 'Flight Speed|Endurance Cost|Endurance Cost,Flight Speed (both at 1.0 value)';
io_set['Freebird'] = 'Endurance Cost|Flight Speed|+Stealth (35 feet PvE / 389 feet PvP)';
io_set['Springfoot'] = 'Jump|Endurance Cost|Endurance Cost,Jump (both at 1.0 value)';
io_set['Unbounded Leap'] = 'Endurance Cost|Jump|+Stealth (35 feet PvE / 389 feet PvP)';
io_set['Quickfoot'] = 'RunSpeed|Endurance Cost|Endurance Cost,RunSpeed (both at 1.0 value)';
io_set['Celerity'] = 'Endurance Cost|RunSpeed|+Stealth (35 feet PvE / 389 feet PvP)';
io_set['Jaunt'] = 'Range|Endurance Cost|Endurance Cost,Range (both at 1.0 value)';
io_set['TimeSpace Manipulation'] = 'Endurance Cost|Range|+Stealth (35 feet PvE / 389 feet PvP)';


/**** END:  static_ios.js ****/

