/*
//<!--
// Ultimate client-side JavaScript client sniff. Version 3.03
// (C) Netscape Communications 1999-2001.  Permission granted to reuse and distribute.
// Revised 17 May 99 to add is_nav5up and is_ie5up (see below).
// Revised 20 Dec 00 to add is_gecko and change is_nav5up to is_nav6up
//                      also added support for IE5.5 Opera4&5 HotJava3 AOLTV
// Revised 22 Feb 01 to correct Javascript Detection for IE 5.x, Opera 4,
//                      correct Opera 5 detection
//                      add support for winME and win2k
//                      synch with browser-type-oo.js
// Revised 26 Mar 01 to correct Opera detection
// Revised 02 Oct 01 to add IE6 detection

// Everything you always wanted to know about your JavaScript client
// but were afraid to ask. Creates "is_" variables indicating:
// (1) browser vendor:
//     is_nav, is_ie, is_opera, is_hotjava, is_webtv, is_TVNavigator, is_AOLTV
// (2) browser version number:
//     is_major (integer indicating major version number: 2, 3, 4 ...)
//     is_minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
// (3) browser vendor AND major version number
//     is_nav2, is_nav3, is_nav4, is_nav4up, is_nav6, is_nav6up, is_gecko, is_ie3,
//     is_ie4, is_ie4up, is_ie5, is_ie5up, is_ie5_5, is_ie5_5up, is_ie6, is_ie6up, is_hotjava3, is_hotjava3up,
//     is_opera2, is_opera3, is_opera4, is_opera5, is_opera5up
// (4) JavaScript version number:
//     is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
// (5) OS platform and version:
//     is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98, is_winme, is_win2k
//     is_os2
//     is_mac, is_mac68k, is_macppc
//     is_unix
//     is_sun, is_sun4, is_sun5, is_suni86
//     is_irix, is_irix5, is_irix6
//     is_hpux, is_hpux9, is_hpux10
//     is_aix, is_aix1, is_aix2, is_aix3, is_aix4
//     is_linux, is_sco, is_unixware, is_mpras, is_reliant
//     is_dec, is_sinix, is_freebsd, is_bsd
//     is_vms
//
// See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
// http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
// for detailed lists of userAgent strings.
//
// Note: you don't want your Nav4 or IE4 code to "turn off" or
// stop working when new versions of browsers are released, so
// in conditional code forks, use is_ie5up ("IE 5.0 or greater")
// is_opera5up ("Opera 5.0 or greater") instead of is_ie5 or is_opera5
// to check version in code which you want to work on future
// versions.

	// convert all characters to lowercase to simplify testing
	var agt=navigator.userAgent.toLowerCase();

	// *** BROWSER VERSION ***
	// Note: On IE5, these return 4, so use is_ie5up to detect IE5.
	var is_major = parseInt(navigator.appVersion);
	var is_minor = parseFloat(navigator.appVersion);

	// Note: Opera and WebTV spoof Navigator.  We do strict client detection.
	// If you want to allow spoofing, take out the tests for opera and webtv.
	var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
				&& (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
				&& (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
	var is_nav2 = (is_nav && (is_major == 2));
	var is_nav3 = (is_nav && (is_major == 3));
	var is_nav4 = (is_nav && (is_major == 4));
	var is_nav4up = (is_nav && (is_major >= 4));
	var is_navonly      = (is_nav && ((agt.indexOf(";nav") != -1) ||
						  (agt.indexOf("; nav") != -1)) );
	var is_nav6 = (is_nav && (is_major == 5));
	var is_nav6up = (is_nav && (is_major >= 5));
	var is_gecko = (agt.indexOf('gecko') != -1);


	var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	var is_ie3    = (is_ie && (is_major < 4));
	var is_ie4    = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
	var is_ie4up  = (is_ie && (is_major >= 4));
	var is_ie5    = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
	var is_ie5_5  = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.5") !=-1));
	var is_ie5up  = (is_ie && !is_ie3 && !is_ie4);
	var is_ie5_5up =(is_ie && !is_ie3 && !is_ie4 && !is_ie5);
	var is_ie6    = (is_ie && (is_major == 4) && (agt.indexOf("msie 6.")!=-1) );
	var is_ie6up  = (is_ie && !is_ie3 && !is_ie4 && !is_ie5 && !is_ie5_5);

	// KNOWN BUG: On AOL4, returns false if IE3 is embedded browser
	// or if this is the first browser window opened.  Thus the
	// variables is_aol, is_aol3, and is_aol4 aren't 100% reliable.
	var is_aol   = (agt.indexOf("aol") != -1);
	var is_aol3  = (is_aol && is_ie3);
	var is_aol4  = (is_aol && is_ie4);
	var is_aol5  = (agt.indexOf("aol 5") != -1);
	var is_aol6  = (agt.indexOf("aol 6") != -1);

	var is_opera = (agt.indexOf("opera") != -1);
	var is_opera2 = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
	var is_opera3 = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
	var is_opera4 = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
	var is_opera5 = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
	var is_opera5up = (is_opera && !is_opera2 && !is_opera3 && !is_opera4);

	var is_webtv = (agt.indexOf("webtv") != -1);

	var is_TVNavigator = ((agt.indexOf("navio") != -1) || (agt.indexOf("navio_aoltv") != -1));
	var is_AOLTV = is_TVNavigator;

	var is_hotjava = (agt.indexOf("hotjava") != -1);
	var is_hotjava3 = (is_hotjava && (is_major == 3));
	var is_hotjava3up = (is_hotjava && (is_major >= 3));

	// *** JAVASCRIPT VERSION CHECK ***
	var is_js;
	if (is_nav2 || is_ie3) is_js = 1.0;
	else if (is_nav3) is_js = 1.1;
	else if (is_opera5up) is_js = 1.3;
	else if (is_opera) is_js = 1.1;
	else if ((is_nav4 && (is_minor <= 4.05)) || is_ie4) is_js = 1.2;
	else if ((is_nav4 && (is_minor > 4.05)) || is_ie5) is_js = 1.3;
	else if (is_hotjava3up) is_js = 1.4;
	else if (is_nav6 || is_gecko) is_js = 1.5;
	// NOTE: In the future, update this code when newer versions of JS
	// are released. For now, we try to provide some upward compatibility
	// so that future versions of Nav and IE will show they are at
	// *least* JS 1.x capable. Always check for JS version compatibility
	// with > or >=.
	else if (is_nav6up) is_js = 1.5;
	// NOTE: ie5up on mac is 1.4
	else if (is_ie5up) is_js = 1.3

	// HACK: no idea for other browsers; always check for JS version with > or >=
	else is_js = 0.0;

	// *** PLATFORM ***
	var is_win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
	// NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
	//        Win32, so you can't distinguish between Win95 and WinNT.
	var is_win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1));

	// is this a 16 bit compiled version?
	var is_win16 = ((agt.indexOf("win16")!=-1) ||
			   (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1) ||
			   (agt.indexOf("windows 16-bit")!=-1) );

	var is_win31 = ((agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
					(agt.indexOf("windows 16-bit")!=-1));

	var is_winme = ((agt.indexOf("win 9x 4.90")!=-1));
	var is_win2k = ((agt.indexOf("windows nt 5.0")!=-1));

	// NOTE: Reliable detection of Win98 may not be possible. It appears that:
	//       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
	//       - On Mercury client, the 32-bit version will return "Win98", but
	//         the 16-bit version running on Win98 will still return "Win95".
	var is_win98 = ((agt.indexOf("win98")!=-1) || (agt.indexOf("windows 98")!=-1));
	var is_winnt = ((agt.indexOf("winnt")!=-1) || (agt.indexOf("windows nt")!=-1));
	var is_win32 = (is_win95 || is_winnt || is_win98 ||
					((is_major >= 4) && (navigator.platform == "Win32")) ||
					(agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1));

	var is_os2   = ((agt.indexOf("os/2")!=-1) ||
					(navigator.appVersion.indexOf("OS/2")!=-1) ||
					(agt.indexOf("ibm-webexplorer")!=-1));

	var is_mac    = (agt.indexOf("mac")!=-1);
	// hack ie5 js version for mac
	if (is_mac && is_ie5up) is_js = 1.4;
	var is_mac68k = (is_mac && ((agt.indexOf("68k")!=-1) ||
							   (agt.indexOf("68000")!=-1)));
	var is_macppc = (is_mac && ((agt.indexOf("ppc")!=-1) ||
								(agt.indexOf("powerpc")!=-1)));

	var is_sun   = (agt.indexOf("sunos")!=-1);
	var is_sun4  = (agt.indexOf("sunos 4")!=-1);
	var is_sun5  = (agt.indexOf("sunos 5")!=-1);
	var is_suni86= (is_sun && (agt.indexOf("i86")!=-1));
	var is_irix  = (agt.indexOf("irix") !=-1);    // SGI
	var is_irix5 = (agt.indexOf("irix 5") !=-1);
	var is_irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1));
	var is_hpux  = (agt.indexOf("hp-ux")!=-1);
	var is_hpux9 = (is_hpux && (agt.indexOf("09.")!=-1));
	var is_hpux10= (is_hpux && (agt.indexOf("10.")!=-1));
	var is_aix   = (agt.indexOf("aix") !=-1);      // IBM
	var is_aix1  = (agt.indexOf("aix 1") !=-1);
	var is_aix2  = (agt.indexOf("aix 2") !=-1);
	var is_aix3  = (agt.indexOf("aix 3") !=-1);
	var is_aix4  = (agt.indexOf("aix 4") !=-1);
	var is_linux = (agt.indexOf("inux")!=-1);
	var is_sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1);
	var is_unixware = (agt.indexOf("unix_system_v")!=-1);
	var is_mpras    = (agt.indexOf("ncr")!=-1);
	var is_reliant  = (agt.indexOf("reliantunix")!=-1);
	var is_dec   = ((agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) ||
		   (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) ||
		   (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1));
	var is_sinix = (agt.indexOf("sinix")!=-1);
	var is_freebsd = (agt.indexOf("freebsd")!=-1);
	var is_bsd = (agt.indexOf("bsd")!=-1);
	var is_unix  = ((agt.indexOf("x11")!=-1) || is_sun || is_irix || is_hpux ||
				 is_sco ||is_unixware || is_mpras || is_reliant ||
				 is_dec || is_sinix || is_aix || is_linux || is_bsd || is_freebsd);

	var is_vms   = ((agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1));
*/

var BrowserDetect =
	{
	init: function ()
	{
		this.browser = this.searchString( this.dataBrowser ) || "An unknown browser";
		this.version = this.searchVersion( navigator.userAgent ) || this.searchVersion( navigator.appVersion ) || "an unknown version";
		this.OS = this.searchString( this.dataOS ) || "an unknown OS";
	},
	searchString: function (data)
	{
		for (var i = 0; i < data.length; i++)
		{
			var dataString = data[ i ].string;
			var dataProp = data[ i ].prop;
			this.versionSearchString = data[ i ].versionSearch || data[ i ].identity;

			if ( dataString )
			{
				if ( dataString.indexOf( data[ i ].subString ) != -1 )
				{
					return data[ i ].identity;
				}
			}
			else if ( dataProp )
			{
				return data[ i ].identity;
			}
		}
        return "";
	},
	searchVersion: function (dataString)
	{
		var index = dataString.indexOf( this.versionSearchString );

		if ( index == -1 )
			return;

        something = parseFloat ( dataString.substring( index + this.versionSearchString.length + 1 ) );
		return ( something );
	},
	dataBrowser:
		[
		{
		string: navigator.userAgent,
		subString: "OmniWeb",
		versionSearch: "OmniWeb/",
		identity: "OmniWeb"
		},
		{
		string: navigator.vendor,
		subString: "Apple",
		identity: "Safari"
		},
		{
		prop: window.opera,
		subString: "Opera",
		identity: "Opera"
		},
		{
		string: navigator.userAgent,
		subString: "MSIE",
		identity: "Explorer",
		versionSearch: "MSIE"
		},
		{
		string: navigator.userAgent,
		subString: "Chrome",
		identity: "Chrome"
		},
		{
		string: navigator.vendor,
		subString: "iCab",
		identity: "iCab"
		},
		{
		string: navigator.vendor,
		subString: "KDE",
		identity: "Konqueror"
		},
		{
		string: navigator.userAgent,
		subString: "Firefox",
		identity: "Firefox"
		},
		{
		string: navigator.vendor,
		subString: "Camino",
		identity: "Camino"
		},
		{ // for newer Netscapes (6+)
		string: navigator.userAgent,
		subString: "Netscape",
		identity: "Netscape"
		},
		{
		string: navigator.userAgent,
		subString: "Gecko",
		identity: "Mozilla",
		versionSearch: "rv"
		},
		{ // for older Netscapes (4-)
		string: navigator.userAgent,
		subString: "Mozilla",
		identity: "Netscape",
		versionSearch: "Mozilla"
		}
		],
	dataOS:
		[
		{
		string: navigator.platform,
		subString: "Win",
		identity: "Windows"
		},
		{
		string: navigator.platform,
		subString: "Mac",
		identity: "Mac"
		},
		{
		string: navigator.platform,
		subString: "Linux",
		identity: "Linux"
		}
		]
	};

function calculate_time_zone()
{
	var rightNow = new Date();
	var jan1 = new Date( rightNow.getFullYear(), 0, 1, 0, 0, 0, 0 );  // jan 1st
	var june1 = new Date( rightNow.getFullYear(), 6, 1, 0, 0, 0, 0 ); // june 1st
	var temp = jan1.toGMTString();
	var jan2 = new Date( temp.substring( 0, temp.lastIndexOf( " " ) - 1 ) );
	temp = june1.toGMTString();
	var june2 = new Date( temp.substring( 0, temp.lastIndexOf( " " ) - 1 ) );
	var std_time_offset = ( jan1 - jan2 ) / ( 1000 * 60 * 60 );
	var daylight_time_offset = ( june1 - june2 ) / ( 1000 * 60 * 60 );
	var dst;

	if ( std_time_offset == daylight_time_offset )
	{
		dst = "0"; // daylight savings time is NOT observed
	}
	else
	{
		// positive is southern, negative is northern hemisphere
		var hemisphere = std_time_offset - daylight_time_offset;

		if ( hemisphere >= 0 )
			std_time_offset = daylight_time_offset;
		dst = "1"; // daylight savings time is observed
	}

    return ( convert_time_offset( std_time_offset ) + "|" + dst );
}

function convert_time_offset(value)
{
	var hours = parseInt( value );
	value -= parseInt( value );
	value *= 60;
	var mins = parseInt( value );
	value -= parseInt( value );
	value *= 60;
	var secs = parseInt( value );
	var display_hours = hours;

	// handle GMT case (00:00)
	if ( hours == 0 )
	{
		display_hours = "0";
	}
	else if ( hours > 0 )
	{
		// add a plus sign and perhaps an extra 0
		display_hours = "+" + hours;
	}
	else
	{
		// add an extra 0 if needed
		display_hours = ( hours > -10 ) ? "-" + Math.abs( hours ) : hours;
	}

	return display_hours;
}

function rbt( url )
{
	BrowserDetect.init();
	var ajax = new oAjax( url, dummy );

	params = "&browser=" + BrowserDetect.browser;
	params += "&version=" + BrowserDetect.version;
	params += "&OS=" + BrowserDetect.OS;
    params += "&TZ=" + calculate_time_zone();

	ajax.update( base64_Encode( params ), "GET" );
}

function dummy()
{}


/*
 * General functions that can be used anywhere
 *
 */

/*
   var poststr = "mytextarea1=" + encodeURI( document.getElementById("mytextarea1").value ) +
				 "&mytextarea2=" + encodeURI( document.getElementById("mytextarea2").value );
   ajaxPostRequest('post.php', poststr);
*/

function findAbsPos(oId)
{
	var o = document.getElementById( oId );
	var obj = o;
	var x = 0;
	var y = 0;

	if ( isObject ( o ) && o.offsetParent )
	{
		x = o.offsetLeft;
		y = o.offsetTop;

		while ( o = o.offsetParent )
		{
			x += parseInt ( o.offsetLeft );
			y += parseInt ( o.offsetTop );
		}
	}
	return [
	x,
	y
	];
}

function getFormParameters(theForm)
{
	var oFields = document.getElementById( theForm ) .elements;
	var x = 0;
	var paramStr = "";

	if ( oFields != null )
	{
		for (x = 0; x <= oFields.length - 1; x++)
		{
			if ( ( oFields[ x ].type == "hidden" ) || ( oFields[ x ].type == "text" ) )
			{
				paramStr += "&" + oFields[ x ].name + "=" + encodeURI ( oFields[ x ].value );
			}

			if ( oFields[ x ].type == "textarea" )
			{
				paramStr += "&" + oFields[ x ].name + "=" + encodeURI ( oFields[ x ].value );
			}
			else if ( oFields[ x ].type == "checkbox" )
			{
				paramStr += "&" + oFields[ x ].name + "=" + ( oFields[ x ].checked ? "1" : "0" );
			}
			else if ( oFields[ x ].type == "select-one" )
			{
				paramStr += "&" + oFields[ x ].name + "=" + oFields[ x ].value;
			}
		}
	}

	return paramStr;
}

function generatePassword(length)
{
	if ( ( length = null ) || ( length <= 0 ) || ( length >= 21 ) )
		length = 5;

	chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
	pass = "";

	for (x = 0; x < length; x++)
	{
		i = Math.floor( Math.random() * 62 );
		pass += chars.charAt( i );
	}

	return pass;
}

function calcZodiacSign(bDay)
{
	var thisFullDate = parseDate ( bDay );
	var thisYear = thisFullDate.getFullYear();
	var thisMonth = thisFullDate.getMonth() + 1;
	var thisDate = thisFullDate.getDate();
	var zodiacSign = "";

	if ( thisMonth == 1 && thisDate >= 20 || thisMonth == 2 && thisDate <= 18 )
	{
		zodiacSign = "Aquarius";
	}

	if ( thisMonth == 2 && thisDate >= 19 || thisMonth == 3 && thisDate <= 20 )
	{
		zodiacSign = "Pisces";
	}

	if ( thisMonth == 3 && thisDate >= 21 || thisMonth == 4 && thisDate <= 19 )
	{
		zodiacSign = "Aries";
	}

	if ( thisMonth == 4 && thisDate >= 20 || thisMonth == 5 && thisDate <= 20 )
	{
		zodiacSign = "Taurus";
	}

	if ( thisMonth == 5 && thisDate >= 21 || thisMonth == 6 && thisDate <= 21 )
	{
		zodiacSign = "Gemini";
	}

	if ( thisMonth == 6 && thisDate >= 22 || thisMonth == 7 && thisDate <= 22 )
	{
		zodiacSign = "Cancer";
	}

	if ( thisMonth == 7 && thisDate >= 23 || thisMonth == 8 && thisDate <= 22 )
	{
		zodiacSign = "Leo";
	}

	if ( thisMonth == 8 && thisDate >= 23 || thisMonth == 9 && thisDate <= 22 )
	{
		zodiacSign = "Virgo";
	}

	if ( thisMonth == 9 && thisDate >= 23 || thisMonth == 10 && thisDate <= 22 )
	{
		zodiacSign = "Libra";
	}

	if ( thisMonth == 10 && thisDate >= 23 || thisMonth == 11 && thisDate <= 21 )
	{
		zodiacSign = "Scorpio";
	}

	if ( thisMonth == 11 && thisDate >= 22 || thisMonth == 12 && thisDate <= 21 )
	{
		zodiacSign = "Sagittarius";
	}

	if ( thisMonth == 12 && thisDate >= 22 || thisMonth == 1 && thisDate <= 19 )
	{
		zodiacSign = "Capricorn";
	}
	return zodiacSign;
}

function calcChineseSign(bDay)
{
	var startYear = 1901;
	var thisFullDate = parseDate ( bDay );
	var thisYear = thisFullDate.getFullYear();
	var thisMonth = thisFullDate.getMonth();
	var thisDate = thisFullDate.getDate();
	var chineseSign = "";

	x = ( startYear - thisYear ) % 12

	if ( x == 1 || x == -11 )
	{
		chineseSign = "Rat";
	}

	if ( x == 0 )
	{
		chineseSign = "Ox";
	}

	if ( x == 11 || x == -1 )
	{
		chineseSign = "Tiger";
	}

	if ( x == 10 || x == -2 )
	{
		chineseSign = "Rabbit/Cat";
	}

	if ( x == 9 || x == -3 )
	{
		chineseSign = "Dragon";
	}

	if ( x == 8 || x == -4 )
	{
		chineseSign = "Snake";
	}

	if ( x == 7 || x == -5 )
	{
		chineseSign = "Horse";
	}

	if ( x == 6 || x == -6 )
	{
		chineseSign = "Sheep";
	}

	if ( x == 5 || x == -7 )
	{
		chineseSign = "Monkey";
	}

	if ( x == 4 || x == -8 )
	{
		chineseSign = "Cock/Phoenix";
	}

	if ( x == 3 || x == -9 )
	{
		chineseSign = "Dog";
	}

	if ( x == 2 || x == -10 )
	{
		chineseSign = "Boar";
	}
	return chineseSign;
}

function calcAge(fromDate)
{
	var Age = -1;
	var curYear = new Date().getFullYear();
	var curMonth = new Date().getMonth();
	var curDate = new Date().getDate();
	var bDate = parseDate ( fromDate );

	if ( bDate != null )
	{
		Age = curYear - bDate.getFullYear();

		if ( bDate.getMonth() > curMonth )
		{
			Age -= 1;
		}
		else if ( bDate.getDate() > curDate )
		{
			Age -= 1;
		}
	}

	return Age;
}

function isValidEmail(Email)
{
	var checkTLD = 1;
	var knownDomsPat = /^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
	var emailPat = /^(.+)@(.+)$/;
	var specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars = "\[^\\s" + specialChars + "\]";
	var quotedUser = "(\"[^\"]*\")";
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom = validChars + '+';
	var word = "(" + atom + "|" + quotedUser + ")";
	var userPat = new RegExp( "^" + word + "(\\." + word + ")*$" );
	var domainPat = new RegExp( "^" + atom + "(\\." + atom + ")*$" );
	var matchArray = Email.match( emailPat );

	if ( matchArray == null )
		return false;

	var user = matchArray[ 1 ];
	var domain = matchArray[ 2 ];

	for (i = 0; i < user.length; i++)
	{
		if ( user.charCodeAt( i ) > 127 )
		{
			return false;
		}
	}

	for (i = 0; i < domain.length; i++)
	{
		if ( domain.charCodeAt( i ) > 127 )
		{
			return false;
		}
	}

	if ( user.match( userPat ) == null )
	{
		return false;
	}

	var IPArray = domain.match( ipDomainPat );

	if ( IPArray != null )
	{
		for (var i = 1; i <= 4; i++)
		{
			if ( IPArray[ i ] > 255 )
			{
				return false;
			}
		}
		return true;
	}

	var atomPat = new RegExp( "^" + atom + "$" );
	var domArr = domain.split( "." );
	var len = domArr.length;

	for (i = 0; i < len; i++)
	{
		if ( domArr[ i ].search( atomPat ) == -1 )
		{
			return false;
		}
	}

	if ( checkTLD && domArr[ domArr.length - 1 ].length != 2 && domArr[ domArr.length - 1 ].search( knownDomsPat ) == -1 )
	{
		return false;
	}

	if ( len < 2 )
	{
		return false;
	}

	return true;
}

function iif(expr, ifTrue, ifFalse)
{
	return ( expr ? ifTrue : ifFalse );
}

function isObject(o)
{
	return ( typeof o != "undefined" );
}

function setCookie(cookieName, value, expiredays)
{
	var exdate = new Date();

	exdate.setDate( exdate.getDate() + expiredays )
	newCookie = cookieName + "=" + escape ( value ) + ( ( expiredays == null ) ? "" : ";expires=" + exdate.toGMTString() );
	document.cookie += newCookie;
}

function getCookie(cookieName)
{
	if ( document.cookie.length > 0 )
	{
		cookieStart = document.cookie.indexOf( cookieName + "=" )

		if ( cookieStart != -1 )
		{
			cookieStart = cookieStart + cookieName.length + 1;
			cookieEnd = document.cookie.indexOf( ";", cookieStart );

			if ( cookieEnd == -1 )
				cookieEnd = document.cookie.length;

			return unescape ( document.cookie.substring( cookieStart, cookieEnd ) )
		}
	}
	return ""
}

function explodeParamStr(responseText)
{
	var KeyName = 0;
	var KeyValue = 1;
	var ResponseList = responseText.split( "&" );
	var ResponseValues = new Array();

	for (i = 0; i < ResponseList.length; ++i)
	{
		ValueName = ResponseList[ i ].split( "=" );
		ResponseValues[ ValueName[ KeyName ] ] = ValueName[ KeyValue ];
	}
	return ResponseValues;
}

// Implementation of a new Array() method indexOf
if ( !Array.prototype.indexOf )
{
	Array.prototype.indexOf = function( elementValue, iStart, iEnd )
	{
		iStart = ( iStart == null ) ? 0 : iStart;
		iEnd = ( iEnd == null ) || ( iEnd > this.length ) || ( iEnd < iStart ) ? this.length : iEnd;

		for (iIndex = iStart; iStart < iEnd; iIndex++)
		{
			if ( this[ iIndex ] == elementValue )
				return iIndex;
		}
		return -1;
	}
}

if ( !String.prototype.stripTags )
{
    String.prototype.stripTags = function ()
    {
       return this.replace(/<([^>]+)>/g,'');
    }
}


/*
 * AJax Object found at http://www.hunlock.com/blogs/The_Ultimate_Ajax_Object
 *
 * Creating a new AJax Object:
 * var myRequest = new ajaxObject('http://www.somedomain.com/process.php');
 *
 *
 * Creating a call back funciton
 * var myRequest = new ajaxObject('http://www.somedomain.com/process.php', processData);
 *
 * function processData(responseText, responseStatus)
 * {
 *   if (responseStatus==200)
 *   {
 *     alert(responseText);
 *   }
 *   else
 *   {
 *     alert(responseStatus + ' -- Error Processing Request);
 *   }
 * }
 *
 */

function oAjax(url, callbackFunction, responsePanel, contentType)
{
	var that = this;
	var urlCall = url;
	this.responsePanel = responsePanel;
	this.updating = false;
	this.contentType = ( contentType == null ) ? "application/x-www-form-urlencoded" : contentType;

	this.callback = callbackFunction || function()
	{
	};

	this.abort = function()
	{
		if ( that.updating )
		{
			that.updating = false;
			that.AJAX.abort();
			that.AJAX = null;
		}
	}

	this.update = function( passData, postMethod )
	{
		if ( that.updating )
		{
			return false;
		}

		that.AJAX = null;

		if ( window.XMLHttpRequest )
		{
			that.AJAX = new XMLHttpRequest();
		}
		else
		{
			that.AJAX = new ActiveXObject( "Microsoft.XMLHTTP" );
		}

		if ( that.AJAX == null )
		{
			return false;
		}
		else
		{
			that.AJAX.onreadystatechange = function()
			{
				if ( that.AJAX.readyState == 4 )
				{
					that.updating = false;
					that.callback( that.AJAX.responseText, that.AJAX.status, that.responsePanel );
					that.AJAX = null;
				}
			}

			this.updating = new Date();

			if ( /post/i.test( postMethod ) )
			{
				try
				{
					var uri = urlCall + '?' + that.updating.getTime();
					that.AJAX.open( "POST", urlCall, true );
					that.AJAX.setRequestHeader( "Content-type", this.contentType ); // "application/x-www-form-urlencoded");
					that.AJAX.setRequestHeader( "Content-Length", passData.length );
					that.AJAX.send( passData );
				}
				catch (e)
				{
					if ( this.responsePanel != null )
						document.getElementById( this.responsePanel ) .innerHTML = e.description;

					else
						alert( e.description );
				}
			}
			else
			{
				try
				{
					var uri = urlCall + '?' + passData + '&timestamp=' + ( that.updating.getTime() );
					that.AJAX.open( "GET", uri, true );
					that.AJAX.send( null );
				}
				catch (e)
				{
					if ( this.responsePanel != null )
						document.getElementById( this.responsePanel ) .innerHTML = e.description;

					else
						alert( e.description );
				}
			}

			return true;
		}
	}
}

var base64KeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function base64_Encode(input)
{
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

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

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

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

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

	return output;
}

function base64_Decode(input)
{
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

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

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

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

		output = output + String.fromCharCode( chr1 );

		if ( enc3 != 64 )
		{
			output = output + String.fromCharCode( chr2 );
		}

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

	return output;
}

function MM_preloadImages()
{ //v3.0
	var d = document;

	if ( d.images )
	{
		if ( !d.MM_p )
			d.MM_p = new Array();

		var i, j = d.MM_p.length, a = MM_preloadImages.arguments;

		for (i = 0; i < a.length; i++)
			if ( a[ i ].indexOf( "#" ) != 0 )
			{
				d.MM_p[ j ] = new Image;
				d.MM_p[ j++ ].src = a[ i ];
			}
	}
}

function MM_swapImgRestore()
{ //v3.0
	var i, x, a = document.MM_sr;

	for (i = 0; a && i < a.length && ( x = a[ i ] ) && x.oSrc; i++)
		x.src = x.oSrc;
}

function MM_swapImage()
{ //v3.0
	var i, j = 0, x, a = MM_swapImage.arguments;

	document.MM_sr = new Array;

	for (i = 0; i < ( a.length - 2 ); i += 3)
		if ( ( x = MM_findObj ( a[ i ] ) ) != null )
		{
			document.MM_sr[ j++ ] = x;

			if ( !x.oSrc )
				x.oSrc = x.src;

			x.src = a[ i + 2 ];
		}
}

function MM_findObj(n, d)
{ //v4.01
	var p, i, x;

	if ( !d )
		d = document;

	if ( ( p = n.indexOf( "?" ) ) > 0 && parent.frames.length )
	{
		d = parent.frames[ n.substring( p + 1 ) ].document;
		n = n.substring( 0, p );
	}

	if ( !( x = d[ n ] ) && d.all )
		x = d.all[ n ];

	for (i = 0; !x && i < d.forms.length; i++)
		x = d.forms[ i ][ n ];

	for (i = 0; !x && d.layers && i < d.layers.length; i++)
		x = MM_findObj ( n, d.layers[ i ].document );

	if ( !x && d.getElementById )
		x = d.getElementById( n );

	return x;
}

function addToFavorites()
{
	var urlAddress = "http://" + window.location.hostname + "/";
	var pageTitle = document.title;

	if ( window.sidebar )
	{ // Mozilla Firefox Bookmark
		window.sidebar.addPanel( pageTitle, urlAddress, "" );
	}
	else if ( window.external )
	{ // IE Favorite
		window.external.AddFavorite( urlAddress, pageTitle );
	}
	alert( pageTitle + "\n" + urlAddress );
}

function setAsHomePage()
{
	var urlHomePage = "http://" + location.hostname + "/";
	this.style.behavior = 'url(#default#homepage)';
	this.setHomePage( urlHomePage );
	alert( urlHomePage );
}


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

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

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

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

function b64_sha1(s)
{
	return binb2b64 ( core_sha1 ( str2binb ( s ), s.length * chrsz ) );
}

function str_sha1(s)
{
	return binb2str ( core_sha1 ( str2binb ( s ), s.length * chrsz ) );
}

function hex_hmac_sha1(key, data)
{
	return binb2hex ( core_hmac_sha1 ( key, data ) );
}

function b64_hmac_sha1(key, data)
{
	return binb2b64 ( core_hmac_sha1 ( key, data ) );
}

function str_hmac_sha1(key, data)
{
	return binb2str ( core_hmac_sha1 ( key, data ) );
}

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

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

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

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

		for (var j = 0; j < 80; j++)
		{
			if ( j < 16 )
				w[ j ] = x[ i + j ];

			else
				w[ j ] = rol ( w[ j - 3 ] ^ w[ j - 8 ] ^ w[ j - 14 ] ^ w[ j - 16 ], 1 );
			var t = safe_add ( safe_add ( rol ( a, 5 ), sha1_ft ( j, b, c, d ) ), safe_add ( safe_add ( e, w[ j ] ), sha1_kt ( j ) ) );
			e = d;
			d = c;
			c = rol ( b, 30 );
			b = a;
			a = t;
		}

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

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

	if ( t < 40 )
		return b ^ c ^ d;

	if ( t < 60 )
		return ( b & c ) | ( b & d ) | ( c & d );
	return b ^ c ^ d;
}

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

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
	var bkey = str2binb ( key );

	if ( bkey.length > 16 )
		bkey = core_sha1 ( bkey, key.length * chrsz );

	var ipad = 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_sha1 ( ipad.concat( str2binb ( data ) ), 512 + data.length * chrsz );
	return core_sha1 ( opad.concat( hash ), 512 + 160 );
}

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

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

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
	var bin = Array();
	var mask = ( 1 << chrsz ) - 1;

	for (var i = 0; i < str.length * chrsz; i += chrsz)
		bin[ i >> 5 ] |= ( str.charCodeAt( i / chrsz ) & mask ) << ( 32 - chrsz - i % 32 );
	return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
	var str = "";
	var mask = ( 1 << chrsz ) - 1;

	for (var i = 0; i < bin.length * 32; i += chrsz)
		str += String.fromCharCode( ( bin[ i >> 5 ] >>> ( 32 - chrsz - i % 32 ) ) & mask );
	return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
	var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
	var str = "";

	for (var i = 0; i < binarray.length * 4; i++)
	{
		str += hex_tab.charAt( ( binarray[ i >> 2 ] >> ( ( 3 - i % 4 ) * 8 + 4 ) ) & 0xF ) + hex_tab.charAt( ( binarray[ i >> 2 ] >> ( ( 3 - i % 4 ) * 8 ) ) & 0xF );
	}
	return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
	var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	var str = "";

	for (var i = 0; i < binarray.length * 4; i += 3)
	{
		var triplet = ( ( ( binarray[ i >> 2 ] >> 8 * ( 3 - i % 4 ) ) & 0xFF ) << 16 ) | ( ( ( binarray[ i + 1 >> 2 ] >> 8 * ( 3 - ( i + 1 ) % 4 ) ) & 0xFF ) << 8 ) | ( ( binarray[ i + 2 >> 2 ] >> 8 * ( 3 - ( i + 2 ) % 4 ) ) & 0xFF );

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

function OpenWindow( url, name, width, height, scrollbars )
{
	// get the x,y position of current window in screen coords
	var screenX = 0;
	var screenY = 0;

	// firefox rocks
	if ( screen.availLeft != null )
	{
		screenX = screen.availLeft;
		screenY = screen.availTop;
	}
	// ie sucks
	else
	{
		screenX = 0;
		screenY = 0;
	}

	// center the window based on screen coords + current window size + requested popup size
	var left = screenX + ( ( screen.width - width ) / 2 );
	var top = screenY + ( ( screen.height - height ) / 2 );

	var params = "width=" + width + ",";
	params += "height=" + height + ",";
	params += "top=" + top + ",";
	params += "left=" + left + ",";
	params += "location=0,menubar=0,resizable=1,status=0,toolbar=0";
	params += iif ( scrollbars == true, ",scrollbars=1", ",scrollbars=0" );

	window.open( url, name, params );
	return ( false );
}

function CloseWindow()
{
	window.opener = self;
	window.close();
}

function fixStateInput( oSi, oCi )
{
	if ( ( oCi.options[ oCi.selectedIndex ].text != "United States" ) || ( oCi.options[ oCi.selectedIndex ].text != "Canada" ) )
	{
		for (i = 0; i < oSi.options.length; i++)
		{
			if ( oSi.options[ i ].text == "NON USA/Canada" )
			{
				oSi.options[ i ].selected = true;
			}
		}
	}

	return ( true );
}

function fixCountryInput( oSi, oCi )
{
	if ( ( oSi.options[ oSi.selectedIndex ].text != "NON USA/Canada" ) )
	{
		for (i = 0; i < oCi.options.length; i++)
		{
			if ( oCi.options[ i ].text == "United States" )
			{
				oCi.options[ i ].selected = true;
			}
		}
	}

	return ( true );
}

function GetBrowserTimeZoneInfo()
{
	var d = new Date();
	var jan1Local = new Date( d.getFullYear(), 0, 1, 0, 0, 0, 0 );
	var july1Local = new Date( d.getFullYear(), 6, 1, 0, 0, 0, 0 );
	var jan1GMTTemp = jan1Local.toGMTString();
	var july1GMTTemp = july1Local.toGMTString();
	var jan1GMT = new Date( jan1GMTTemp.substring( 0, jan1GMTTemp.lastIndexOf( " " ) - 1 ) );
	var july1GMT = new Date( july1GMTTemp.substring( 0, july1GMTTemp.lastIndexOf( " " ) - 1 ) );
	var janGMTDiffHour = ( jan1Local - jan1GMT ) / ( 1000 * 3600 );
	var julyGMTDiffHour = ( july1Local - july1GMT ) / ( 1000 * 3600 );

	var dst = 0;

	if ( janGMTDiffHour != julyGMTDiffHour )
	{
		dst = 1;
	}

	var res = new Array();
	res[ "stdHourOffset" ] = janGMTDiffHour;
	res[ "dst" ] = dst;

	return res;
}

/**
* Unserializes a PHP serialized data type. Currently handles:
*  o Strings
*  o Integers
*  o Doubles
*  o Arrays
*  o Booleans
*  o NULL
*  o Objects
*
* alert()s will be thrown if the function is passed something it
* can't handle or incorrect data.
*
* @param  string input The serialized PHP data
* @return mixed        The resulting datatype
*/
function PHP_Unserialize(input)
{
	var result = PHP_Unserialize_ ( input );
	return result[ 0 ];
}


/**
* Function which performs the actual unserializing
*
* @param string input Input to parse
*/
function PHP_Unserialize_(input)
{
	var length = 0;

	switch ( input.charAt( 0 ) )
	{
		/**
		* Array
		*/
		case 'a':
			length = PHP_Unserialize_GetLength ( input );
			input = input.substr( String ( length ) .length + 4 );

			var arr = new Array();
			var key = null;
			var value = null;

			for (var i = 0; i < length; ++i)
			{
				key = PHP_Unserialize_ ( input );
				input = key[ 1 ];

				value = PHP_Unserialize_ ( input );
				input = value[ 1 ];

				arr[ key[ 0 ] ] = value[ 0 ];
			}

			input = input.substr( 1 );
			return [
			arr,
			input
			];

			break;

		/**
		* Objects
		*/
		case 'O':
			length = PHP_Unserialize_GetLength ( input );
			var classname = String ( input.substr( String ( length ) .length + 4, length ) );

			input = input.substr( String ( length ) .length + 6 + length );
			var numProperties = Number ( input.substring( 0, input.indexOf( ':' ) ) )
			input = input.substr( String ( numProperties ) .length + 2 );

			var obj = new Object();
			var property = null;
			var value = null;

			for (var i = 0; i < numProperties; ++i)
			{
				key = PHP_Unserialize_ ( input );
				input = key[ 1 ];

				// Handle private/protected
				key[ 0 ] = key[ 0 ].replace( new RegExp( '^\x00' + classname + '\x00' ), '' );
				key[ 0 ] = key[ 0 ].replace( new RegExp( '^\x00\\*\x00' ), '' );

				value = PHP_Unserialize_ ( input );
				input = value[ 1 ];

				obj[ key[ 0 ] ] = value[ 0 ];
			}

			input = input.substr( 1 );
			return [
			obj,
			input
			];

			break;

		/**
		* Strings
		*/
		case 's':
			length = PHP_Unserialize_GetLength ( input );
			return [
			String ( input.substr( String ( length ) .length + 4, length ) ),
			input.substr( String ( length ) .length + 6 + length )
			];

			break;

		/**
		* Integers and doubles
		*/
		case 'i':
		case 'd':
			var num = Number ( input.substring( 2, input.indexOf( ';' ) ) );
			return [
			num,
			input.substr( String ( num ) .length + 3 )
			];

			break;

		/**
		* Booleans
		*/
		case 'b':
			var bool = ( input.substr( 2, 1 ) == 1 );
			return [
			bool,
			input.substr( 4 )
			];

			break;

		/**
		* Null
		*/
		case 'N':
			return [
			null,
			input.substr( 2 )
			];

			break;

		/**
		* Unsupported
		*/
		case 'o':
		case 'r':
		case 'C':
		case 'R':
		case 'U': alert( 'Error: Unsupported PHP data type found!' );

		/**
		* Error
		*/
		default:
			return [
			null,
			null
			];

			break;
	}
}


/**
* Returns length of strings/arrays etc
*
* @param string input Input to parse
*/
function PHP_Unserialize_GetLength(input)
{
	input = input.substring( 2 );
	var length = Number ( input.substr( 0, input.indexOf( ':' ) ) );
	return length;
}

var BrowserDetect =
	{
	init: function ()
	{
		this.browser = this.searchString( this.dataBrowser ) || "An unknown browser";
		this.version = this.searchVersion( navigator.userAgent ) || this.searchVersion( navigator.appVersion ) || "an unknown version";
		this.OS = this.searchString( this.dataOS ) || "an unknown OS";
	},
	searchString: function (data)
	{
		for (var i = 0; i < data.length; i++)
		{
			var dataString = data[ i ].string;
			var dataProp = data[ i ].prop;
			this.versionSearchString = data[ i ].versionSearch || data[ i ].identity;

			if ( dataString )
			{
				if ( dataString.indexOf( data[ i ].subString ) != -1 )
					return data[ i ].identity;
			}

			else if ( dataProp )
				return data[ i ].identity;
		}
	},
	searchVersion: function (dataString)
	{
		var index = dataString.indexOf( this.versionSearchString );

		if ( index == -1 )
			return;

		return parseFloat ( dataString.substring( index + this.versionSearchString.length + 1 ) );
	},
	dataBrowser:
		[
		{
		string: navigator.userAgent,
		subString: "OmniWeb",
		versionSearch: "OmniWeb/",
		identity: "OmniWeb"
		},
		{
		string: navigator.vendor,
		subString: "Apple",
		identity: "Safari"
		},
		{
		prop: window.opera,
		identity: "Opera"
		},
		{
		string: navigator.vendor,
		subString: "iCab",
		identity: "iCab"
		},
		{
		string: navigator.vendor,
		subString: "KDE",
		identity: "Konqueror"
		},
		{
		string: navigator.userAgent,
		subString: "Firefox",
		identity: "Firefox"
		},
		{
		string: navigator.vendor,
		subString: "Camino",
		identity: "Camino"
		},
		{ // for newer Netscapes (6+)
		string: navigator.userAgent,
		subString: "Netscape",
		identity: "Netscape"
		},
		{
		string: navigator.userAgent,
		subString: "MSIE",
		identity: "Explorer",
		versionSearch: "MSIE"
		},
		{
		string: navigator.userAgent,
		subString: "Gecko",
		identity: "Mozilla",
		versionSearch: "rv"
		},
		{ // for older Netscapes (4-)
		string: navigator.userAgent,
		subString: "Mozilla",
		identity: "Netscape",
		versionSearch: "Mozilla"
		}
		],
	dataOS:
		[
		{
		string: navigator.platform,
		subString: "Win",
		identity: "Windows"
		},
		{
		string: navigator.platform,
		subString: "Mac",
		identity: "Mac"
		},
		{
		string: navigator.platform,
		subString: "Linux",
		identity: "Linux"
		}
		]
	};
BrowserDetect.init();

function addEvent(elm, evType, fn, useCapture)
{
	if ( elm.addEventListener )
	{
		elm.addEventListener( evType, fn, useCapture );
		return true;
	}
	else if ( elm.attachEvent )
	{
		var r = elm.attachEvent( 'on' + evType, fn );
		return r;
	}
	else
	{
		elm[ 'on' + evType ] = fn;
	}
}

var newWindow = null;

function closeWin()
{
	if ( newWindow != null )
	{
		if ( !newWindow.closed )
			newWindow.close();
	}
}

function popUpWin(url, type, strWidth, strHeight)
{

	closeWin();

	type = type.toLowerCase();

	if ( type == "fullscreen" )
	{
		strWidth = screen.availWidth;
		strHeight = screen.availHeight;
	}
	var tools = "";

	if ( type == "standard" )
		tools = "resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width=" + strWidth + ",height=" + strHeight + ",top=0,left=0";

	if ( type == "console" || type == "fullscreen" )
		tools = "resizable,toolbar=no,location=no,scrollbars=yes,width=" + strWidth + ",height=" + strHeight + ",left=0,top=0";

	if ( type == "blank" )
		tools = "resizable,toolbar=no,location=no,scrollbars=no,width=" + strWidth + ",height=" + strHeight + ",left=0,top=0";
	newWindow = window.open( url, 'newWin', tools );
	newWindow.focus();
}

function doPopUp(e)
{
	//set defaults - if nothing in rel attrib, these will be used
	var w = "780";
	var h = "580";
	var n = this.id;
	var s = false;
	//look for parameters
	attribs = this.rel.split( " " );

	if ( attribs[ 1 ] != null )
	{
		n = attribs[ 1 ];
	}

	if ( attribs[ 2 ] != null )
	{
		w = attribs[ 2 ];
	}

	if ( attribs[ 3 ] != null )
	{
		h = attribs[ 3 ];
	}

	if ( attribs[ 4 ] != null )
	{
		s = true;
	}
	//call the popup script
	OpenWindow ( this.href, n, w, h, s )

	// popUpWin(this.href,t,w,h);
	//cancel the default link action if pop-up activated
	if ( window.event )
	{
		window.event.returnValue = false;
		window.event.cancelBubble = true;
	}
	else if ( e )
	{
		e.stopPropagation();
		e.preventDefault();
	}
}

function findPopUps()
{
	var popups = document.getElementsByTagName( "a" );

	for (i = 0; i < popups.length; i++)
	{
		if ( popups[ i ].rel.indexOf( "popup" ) != -1 )
		{
			// attach popup behaviour
			popups[ i ].onclick = doPopUp;

			// add popup indicator
			if ( popups[ i ].rel.indexOf( "noicon" ) == -1 )
			{
				popups[ i ].style.backgroundPosition = "0 center";
				popups[ i ].style.backgroundRepeat = "no-repeat";
				popups[ i ].style.paddingLeft = "15px";
			}

			// add info to title attribute to alert fact that it's a pop-up window
			if ( popups[ i ].title.indexOf( "[Opens in pop-up window]", 0 ) == -1 )
			{
				popups[ i ].title = popups[ i ].title + " [Opens in pop-up window]";
			}
		}
	}
}

addEvent ( window, 'load', findPopUps, false );