﻿var _gaq=_gaq||[];

String.prototype.startsWith=function(str) { return (this.match("^"+str)==str); }
String.prototype.endsWith=function(str) { return (this.match(str+"$")==str); }
String.prototype.distanceString=function(str) { return distanceString(this,str); }
String.prototype.similarityString=function(str) { return similarityString(this,str); }
String.prototype.stripTags=function () { return this.replace(/(<([^>]+)>)/ig,""); };
String.prototype.format=function (c) { if(arguments.length<=1) { return c } var b=arguments.length-2;for(var a=0;a<=b;a++) { c=c.replace(new RegExp("\\{"+a+"\\}","gi"),arguments[a+1]) } return c };
Array.prototype.contains=function(e) { for(var i=0;i<this.length;i++) { if(this[i]==e) { return true } } return false }
Array.prototype.remove=function(c,b) { var a=this.slice((b||c)+1||this.length);this.length=c<0?this.length+c:c;return this.push.apply(this,a) };

//http://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchronous-js/
var jsAsync={d:document,id:function(a){return jsAsync.d.getElementById(a)},tag:function(a){return jsAsync.d.getElementsByTagName(a)},ce:function(a){return jsAsync.d.createElement(a)},js:function(a){js=setTimeout("jsAsync.create('"+a+"')",1)},create:function(a,b){s=jsAsync.ce("script");s.type="text/javascript";s.src=a;if(b){b.appendChild(s)}else{jsAsync.tag("head")[0].appendChild(s)}}};


//Publish/Subscribe (aka "events") implementation - http://www.dustindiaz.com/javascript-observer-class/
function Observer()
{this.fns=[];}
Observer.prototype={
	subscribe: function(fn)
	{ this.fns.push(fn); },
	unsubscribe: function(fn)
	{
		this.fns=this.fns.filter(
            function(el)
            {
            	if(el!==fn)
            	{ return el; }
            }
        );
	},
	fire: function(o,thisObj)
	{
		var scope=thisObj||window;
		for(var i=0;i<this.fns.length;i++)
		{ this.fns[i].call(scope,o); } /* call requires a scope, but the first arg passed to the function is o */
	}
};

function GetEnumString(enumValue,enumType)
{
	//enumValue example:
	//7
	
	//enumType example:
	//{RUNNING_SCORE: 0,ORDINARY_TIME: 1,EXTRA_TIME: 2,PENALTY_SHOOTOUT: 3,FINAL_RESULT: 4,HALF_TIME: 5,PERIOD1: 6,PERIOD2: 7,PERIOD3: 8,QUARTER1: 9,QUARTER2: 10,QUARTER3: 11,QUARTER4: 12,SET1: 13,SET2: 14,SET3: 15,SET4: 16,SET5: 17,WON_SETS: 18,TIEBREAK1: 19,TIEBREAK2: 20,TIEBREAK3: 21,TIEBREAK4: 22,TIEBREAK5: 23,LAPS: 24,LAPS_BEHIND: 25,PIT_STOPS: 26,INNING1: 27,INNING2: 28,INNING3: 29,INNING4: 30,INNING5: 31,INNING6: 32,INNING7: 33,INNING8: 34,INNING9: 35,EXTRA_INNING: 36,STROKES1: 37,STROKES2: 38,STROKES3: 39,STROKES4: 40,STROKES5: 41,PAR: 42,POSITION: 43,MADE_CUT: 44,MATCH_PLAY_SCORE: 45,RANK: 46,DURATION: 47,POINTS: 48,DISTANCE: 49,COMMENT: 50,HITS: 51,ERRORS: 52,MISSES: 53}
	//Returns : "PERIOD2"

	for(property in enumType)
	{
		if(enumType[property]==enumValue)
		{return property;}
	}
}

function parseJSON(jsonData)
{
	return eval('('+jsonData+')');
	if(typeof(JSON)!=="undefined" && typeof(JSON.parse)==="function")
	{ return JSON.parse(jsonData); }
	else
	{ return eval('('+jsonData+')'); }
}
function correctAspNetJSON(jsonData)
{ return jsonData.replace(/"\\\/(Date\([0-9-]+\))\\\/"/gi,"new $1"); }

function randomString(length)
{
	var chars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');

	if(!length)
	{ length=Math.floor(Math.random()*chars.length); }

	var str='';
	for(var i=0;i<length;i++)
	{ str+=chars[Math.floor(Math.random()*chars.length)]; }
	return str;
}

function distanceString(s1,s2)
{
	// http://kevin.vanzonneveld.net
	//levenshtein
	if(s1==s2)
	{ return 0; }

	var s1_len=s1.length;
	var s2_len=s2.length;
	if(s1_len===0)
	{ return s2_len; }
	if(s2_len===0)
	{ return s1_len; }

	// BEGIN STATIC
	var split=false;
	try
	{ split=!('0')[0]; }
	catch(e)
	{ split=true; /*Earlier IE may not support access by string index*/ }
	// END STATIC

	if(split)
	{
		s1=s1.split('');
		s2=s2.split('');
	}

	var v0=new Array(s1_len+1);
	var v1=new Array(s1_len+1);

	var s1_idx=0,s2_idx=0,cost=0;
	for(s1_idx=0;s1_idx<s1_len+1;s1_idx++)
	{ v0[s1_idx]=s1_idx; }
	var char_s1='',char_s2='';
	for(s2_idx=1;s2_idx<=s2_len;s2_idx++)
	{
		v1[0]=s2_idx;
		char_s2=s2[s2_idx-1];

		for(s1_idx=0;s1_idx<s1_len;s1_idx++)
		{
			char_s1=s1[s1_idx];
			cost=(char_s1==char_s2)?0:1;
			var m_min=v0[s1_idx+1]+1;
			var b=v1[s1_idx]+1;
			var c=v0[s1_idx]+cost;
			if(b<m_min)
			{ m_min=b; }
			if(c<m_min)
			{ m_min=c; }
			v1[s1_idx+1]=m_min;
		}
		var v_tmp=v0;
		v0=v1;
		v1=v_tmp;
	}
	return v0[s1_len];
}

function similarityString(s1,s2)
{
	var most;

	if(s1.length>s2.length)
	{ most=s1.length; }
	else
	{ most=s2.length; }

	return 1-parseFloat(parseInt(distanceString(s1,s2))/most);
}


function S4()
{ return (((1+Math.random())*0x10000)|0).toString(16).substring(1); }
function getGUID()
{ return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); }

function isDebugging()
{ return document.Debug||window.location.hash=="#Debug"; }
function alertIfDebug(string)
{
	if(isDebugging())
	{ alert(string); }
}
function debug(string)
{
	if(isDebugging())
	{ document.getElementById("debug").innerHTML+=string+"<br />"; }
}

function getHtmlContent(html)
{
	//HTML is contained between <content> and </content>
	//html=html.replace(/\n/g,"\uffff");	//. doesn't match line breaks, so convert line breaks to a special character and then convert it back to line breaks
	html=html.replace(/[\n\r\t]/g," ");
	html=html.replace(/(.*)<content>/img,"");
	html=html.replace(/<\/content>(.*)/img,"");
	//html=html.replace(/\uffff/g,"\n");	//\n are useless :D
	return html;
}

function HTMLEncode(string)
{
	var div=document.createElement("div");
	var text=document.createTextNode(string);
	div.appendChild(text);
	return div.innerHTML;
}

function URLEncode(string)
{ return encodeURIComponent(string); }

function URLDecode(string)
{ return decodeURIComponent(string); }

function Nl2Br(string)
{ return string.replace(/\n/g,"<br />\n"); }

function getObjectFields(obj)
{
	var result=[];
	for(var id in obj)
	{
		try
		{result.push(id+": "+obj[id].toString());}
		catch(err)
    { result.push(id+": inaccessible"); }
	}
	return result;
}


function formatNumber(number,decimals)
{
	var decimalSeparator=",";
	var thousandsSeparator=" ";

	if(!decimals)
	{ decimals=0; }

	var roundingPow=Math.pow(10,decimals);
	number=Math.round(number*roundingPow)/roundingPow;

	number=""+number;
	var nParts=number.split(".");
	var entPart=nParts[0];
	var decPart=nParts[1];

	var retString="";
	var len;
	do
	{
		len=Math.min(3,entPart.length);
		retString=entPart.substr(entPart.length-len,len)+thousandsSeparator+retString;
		entPart=entPart.substr(0,entPart.length-len);
	}
	while(entPart.length>0);

	if(decPart)
	{
		decPart=padRight(decPart,decimals,"0")
		retString=trim(retString)+decimalSeparator+decPart;
	}
	return trim(retString);
}
function formatAbrev(number,decimalsWhenAbrev,decimalsWhenNotAbrev)
{
	var abrev="";
	if(number>=1000000)
	{
		number=formatNumber(number/1000000,decimalsWhenAbrev);
		abrev=" M";
	}
	else if(number>=1000)
	{
		number=formatNumber(number/1000,decimalsWhenAbrev);
		abrev=" k";
	}
	else
	{ number=formatNumber(number/1000,decimalsWhenNotAbrev); }
	return number+abrev;
}



function formatDuration(durationSeconds)
{
	if(durationSeconds)
	{
		var str="";
		var e;
		e=getFormatPart(durationSeconds,30*24*60*60,"month","months");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		e=getFormatPart(durationSeconds,7*24*60*60,"week","weeks");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		e=getFormatPart(durationSeconds,24*60*60,"day","days");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		e=getFormatPart(durationSeconds,60*60,"hour","hours");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		e=getFormatPart(durationSeconds,60,"minute","minutes");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		e=getFormatPart(durationSeconds,1,"second","seconds");
		str+=e.str;
		durationSeconds-=e.durationSeconds;

		return str;
	}
	return "-";
}
function getFormatPart(durationSeconds,partDuration,partSingular,partPlural)
{
	var str="";
	var partValue=Math.floor(durationSeconds/partDuration);	//30 days
	if(partValue!=0 && !isNaN(partValue))
	{
		str+=" "+partValue+" ";
		str+=partValue>=2?partPlural:partSingular;
	}
	return { "str": str,"durationSeconds": partValue*partDuration };
}

function padLeft(number,length,padCharacter)
{
	if(!padCharacter)
	{ padCharacter="0"; }
	return padLeftRight(number,length,padCharacter,"");
}
function padRight(number,length,padCharacter)
{
	if(!padCharacter)
	{ padCharacter="0"; }
	return padLeftRight(number,length,"",padCharacter);
}
function padLeftRight(number,length,padLeftCharacter,padRightCharacter)
{
	number=""+number;
	while(number.length<length)
	{ number=padLeftCharacter+number+padRightCharacter; }
	return number;
}
function trim(str,chars)
{ return ltrim(rtrim(str,chars),chars); }

function ltrim(str,chars)
{
	chars=chars||"\\s";
	return str.replace(new RegExp("^["+chars+"]+","g"),"");
}

function rtrim(str,chars)
{
	chars=chars||"\\s";
	return str.replace(new RegExp("["+chars+"]+$","g"),"");
}

function convertDateToUser(date)
{
	return date;

	// convert to msec
	// add local time zone offset
	// get UTC time in msec
	utc=date.getTime()+(date.getTimezoneOffset()*60000);

	// create new Date object for different city
	// using supplied offset
	return new Date(utc+(3600000*offset));
}
function convertDateFromUser(date)
{
	return date;
}

var dateFormat=function()
{
	var token=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip=/[^-+\dA-Z]/g,
		pad=function(val,len)
		{
			val=String(val);
			len=len||2;
			while(val.length<len) val="0"+val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function(date,mask,utc)
	{
		var dF=dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if(arguments.length==1&&Object.prototype.toString.call(date)=="[object String]"&&!/\d/.test(date))
		{
			mask=date;
			date=undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date=date?new Date(date):new Date;
		if(isNaN(date)) throw SyntaxError("invalid date");

		mask=String(dF.masks[mask]||mask||dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if(mask.slice(0,4)=="UTC:")
		{
			mask=mask.slice(4);
			utc=true;
		}

		var _=utc?"getUTC":"get",
			d=date[_+"Date"](),
			D=date[_+"Day"](),
			m=date[_+"Month"](),
			y=date[_+"FullYear"](),
			H=date[_+"Hours"](),
			M=date[_+"Minutes"](),
			s=date[_+"Seconds"](),
			L=date[_+"Milliseconds"](),
			o=utc?0:date.getTimezoneOffset(),
			flags={
				d: d,
				dd: pad(d),
				ddd: dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D+7],
				m: m+1,
				mm: pad(m+1),
				mmm: dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m+12],
				yy: String(y).slice(2),
				yyyy: y,
				h: H%12||12,
				hh: pad(H%12||12),
				H: H,
				HH: pad(H),
				M: M,
				MM: pad(M),
				s: s,
				ss: pad(s),
				l: pad(L,3),
				L: pad(L>99?Math.round(L/10):L),
				t: H<12?"a":"p",
				tt: H<12?"am":"pm",
				T: H<12?"A":"P",
				TT: H<12?"AM":"PM",
				Z: utc?"UTC":(String(date).match(timezone)||[""]).pop().replace(timezoneClip,""),
				o: (o>0?"-":"+")+pad(Math.floor(Math.abs(o)/60)*100+Math.abs(o)%60,4),
				S: ["th","st","nd","rd"][d%10>3?0:(d%100-d%10!=10)*d%10]
			};

		return mask.replace(token,function($0)
		{
			return $0 in flags?flags[$0]:$0.slice(1,$0.length-1);
		});
	};
} ();

// Some common format strings
dateFormat.masks={
	"default": "ddd mmm dd yyyy HH:MM:ss",
	shortDate: "m/d/yy",
	mediumDate: "mmm d, yyyy",
	longDate: "mmmm d, yyyy",
	fullDate: "dddd, mmmm d, yyyy",
	shortTime: "h:MM TT",
	mediumTime: "h:MM:ss TT",
	longTime: "h:MM:ss TT Z",
	isoDate: "yyyy-mm-dd",
	isoTime: "HH:MM:ss",
	isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n={
	dayNames: [
		"Sun","Mon","Tue","Wed","Thu","Fri","Sat",
		"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
	],
	monthNames: [
		"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",
		"January","February","March","April","May","June","July","August","September","October","November","December"
	]
};

// For convenience...
Date.prototype.format=function(mask,utc)
{return dateFormat(this,mask,utc);};


function logClick(position)
{
	if(position.x>=0&&position.y>=0)
	{
		var loggedIn=IdentificationId?true:false;
		var page=document.location.href;
		try
		{ TGB.WebServices.BeterZ.UtilitiesWebService.LogClick(page,loggedIn,position.x,position.y); }
		catch(err)
		{ }
	}
}
function showClics(limit)
{
	var loggedIn=IdentificationId?true:false;
	var page=document.location.href;
	try
	{
		TGB.WebServices.BeterZ.UtilitiesWebService.GetClicks(page,loggedIn,limit,function(result)
		{
			if(result!=null)
			{
				for(var i=0;i<result.length;i++)
				{ addClick(result[i].X,result[i].Y); }
			}
		});
	}
	catch(err)
	{ }
}
function getClickContainerObj()
{
	var clickContainerObj=jQuery("#container").get(0);
	if(!clickContainerObj)
	{
		clickContainerObj=jQuery("#header").get(0);
		if(!clickContainerObj)
		{ clickContainerObj=jQuery("body").get(0); }
	}
	return clickContainerObj;
}

function changeLocale(locale)
{
	var url=document.location.href;
	url=url.replace(new RegExp("http://(..|..-..)\.","i"),"http://"+locale+".");
	url=AddURLParameter(url,"Locale",locale);
	url=AddURLParameter(url,"UserAuthentication",IdentificationId);
	document.location.href=url;

	return false;
}

//Doesn't encode param name and value! do it yourself!
function AddURLParameter(url,strParamName,strParamValue)
{
	//Remove the hash from url (#...), which leads to problems as we append the param to it
	url=url.replace(/#(.*)/i,"");
	
	var sep="?";
	if(url.indexOf("?")>=0)
	{ sep="&"; }
	url=RemoveURLParameter(url,strParamName);
	url+=sep+strParamName+"="+strParamValue;
	return url;
}

function RemoveURLParameter(url,strParamName)
{return url.replace("?"+strParamName+"=","?NOP=").replace("&"+strParamName+"=","&NOP=");}

function GetURLParameter(strParamName)
{
	var strReturn="";
	var strHref=window.location.href;
	if(strHref.indexOf("?")> -1)
	{
		var strQueryString=strHref.substr(strHref.indexOf("?"));
		var aQueryString=strQueryString.split("&");
		for(var i=0;i<aQueryString.length;i++)
		{
			if(aQueryString[i].indexOf(strParamName.toLowerCase()+"=")> -1)
			{
				var aParam=aQueryString[i].split("=");
				strReturn=aParam[1];
				break;
			}
		}
	}
	return unescape(strReturn);
}

function FixGACampaignTracking(utm_source,utm_campaign,utm_medium,utm_content)
{
	/*var z=pageTracker.u.V[4][1]().split('.');
	var cookies=pageTracker.a.cookie.split(';');
	if(!z[2]||!z[3])
	{
		for(i=0;i<cookies.length;i++)
		{
			var re=new RegExp(/__utmz\=(.*)/);
			var mymatch=re.exec(cookies[i]);
			if(mymatch)
			{ z=cookies[i].split('.'); }
		}
	}

	if(z[2]&&z[3])
	{
		var zstr_id=[pageTracker.f,pageTracker.ja,z[2],z[3]].join('.');
		var zcsr='utmcsr='+utm_source;
		var zccn='utmccn='+utm_campaign;
		var zcmd='utmcmd='+utm_medium;
		var zcct='utmcct='+utm_content;
		var zstr_content=[zcsr,zccn,zcmd,zcct].join('|');
		pageTracker.u.V[4][2](zstr_id+'.'+zstr_content);
		pageTracker.u.V[4][3]();
	}*/

	//Avoid overring the current hash
	if(!document.location.hash||document.location.hash=="#"||document.location.hash=="#null")
	{ document.location.href=document.location.hash="#utm_source="+utm_source+"&utm_campaign="+utm_campaign+"&utm_medium="+utm_medium+"&utm_content="+utm_content; }
}

function SafeTrackPage(page)
{
	try
	{ _gaq.push(["_trackPageview",page]); }
	catch(err)
	{ }
}

function SafeTrackEvent(category,action,optional_label,optional_value_integer) {
	try
	{ _gaq.push(["_trackEvent",category,action,optional_label,optional_value_integer]); }
	catch(err)
	{ }
}

function SafeAddTransaction(category,sku,item,total,taxes,shipping)
{
	try
	{
		_gaq.push(["_addTrans",orderId,"",total,taxes,shipping,"","",""]);
		_gaq.push(["_addItem",orderId,sku,item,category,total-taxes-shipping,"1"]);
		_gaq.push(["_trackTrans"]);
	}
	catch(err)
	{ }
}

function getPosition(elt)
{
	var position={ x: 0,y: 0 };
	if(elt.offsetParent)
	{
		do
		{
			position.x+=elt.offsetLeft;
			position.y+=elt.offsetTop;
		}
		while(elt=elt.offsetParent);
	}
	return position;
}
function getCursorPosition(e)
{
	e=e||window.event;
	var cursor={ x: 0,y: 0 };
	if(e.pageX||e.pageY)
	{
		cursor.x=e.pageX;
		cursor.y=e.pageY;
	}
	else
	{
		var de=document.documentElement;
		var b=document.body;
		cursor.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
		cursor.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
	}
	return cursor;
}
function getElementDimensions(elt)
{ return { width: elt.offsetWidth,height: elt.offsetHeight }; }

//function hex_sha1(...)
var hexcase=0;var b64pad="";var chrsz=8;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)) } function sha1_vm_test() { return hex_sha1("abc")=="a9993e364706816aba3e25717850c26c9cd0d89d" } function core_sha1(x,len) { 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) } 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 } function sha1_kt(t) { return (t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514 } 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) } function safe_add(x,y) { var lsw=(x&0xFFFF)+(y&0xFFFF);var msw=(x>>16)+(y>>16)+(lsw>>16);return (msw<<16)|(lsw&0xFFFF) } function rol(num,cnt) { return (num<<cnt)|(num>>>(32-cnt)) } 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 } 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 } 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 } 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 createString(arrayIds)
{
	var stringTxt="";
	if(arrayIds!=null)
	{
		for(var i=0;i<arrayIds.length;i++)
		{ stringTxt+="|"+arrayIds[i]; }
	}
	return stringTxt;
}
function addIdToString(stringTxt,id)
{
	if(stringTxt==null)
	{ stringTxt=""; }

	var ids=stringTxt.split("|");
	for(var i=0;i<ids.length;i++)
	{
		if(ids[i]==id)
		{ return stringTxt; }
	}
	return stringTxt+"|"+id;
}
function removeIdToString(stringTxt,id)
{
	if(stringTxt==null)
	{ stringTxt=""; }

	var ids=stringTxt.split("|");
	stringTxt="";
	for(var i=0;i<ids.length;i++)
	{
		if(ids[i]!=id)
		{ stringTxt+="|"+ids[i]; }
	}
	return stringTxt;
}
function getIds(stringTxt)
{
	if(stringTxt==null)
	{ return new Array(); }
	stringTxt=stringTxt.replace(" ","").replace("||","|").replace("||","|").replace("||","|").replace("||","|").replace("||","|");
	var ids=stringTxt.split("|");
	var idsClean=new Array();

	var j=0;
	for(var i=0;i<ids.length;i++)
	{
		if(ids[i])
		{ idsClean[j++]=ids[i]; }
	}
	return idsClean;
}


function getHashValue(hashParameterName)
{
	var hash=document.location.hash;
	if(hash)
	{
		hash=hash.replace("#","");
		var hashElements=hash.split("&");
		for(var i=0;i<hashElements.length;i++)
		{
			var hashElement=hashElements[i];
			if(hashElement.startsWith(hashParameterName+"="))
			{
				var elements=hashElement.split("=");
				return elements[1];
			}
		}
	}
	return null;
}
function setHashValue(hashParameterName,hashParameterValue)
{
	var hash=document.location.hash;
	if(hash)
	{
		hash=hash.replace("#","");
		hash=hash.replace(hashParameterName+"=","NOP=");
	}
	hash=hash.replace(/NOP=.*?(&|$)/g,"");
	hash+="&"+hashParameterName+"="+hashParameterValue;
	hash=hash.replace(/&&/g,"&");
	hash=hash.replace(/^&/,"");
	document.location.href="#"+hash;
}

function getUniqueId()
{ return (new Date()).getTime()+Math.floor(Math.random()*1000000); }

// Expects URL with queryString as param href
function createGetToPostHiddenFields(href,jObjectCheckExistContainer)
{
	if(!jObjectCheckExistContainer&&window.jQuery!=undefined)
	{ jObjectCheckExistContainer=jQuery("input[name='PostBackKey']").closest("span"); }

	try
	{
		var lex1=href.split('?');
		var action=lex1[0];
		var qstr=lex1[1];

		var insertion="";
		if(qstr!=null)
		{
			var params=qstr.split('&');	//Buggy when using &amp; as separator
			for(var i=0;i<params.length;i++)
			{
				var keyValue=params[i].split('=');
				var name=keyValue[0];

				if(name)
				{
					var insertIt=true;
					if(jObjectCheckExistContainer)
					{
						if(jObjectCheckExistContainer.find("input[name='"+name+"']").size()>0)
						{ insertIt=false; }
					}

					if(insertIt)
					{ insertion+='<input type="hidden" name="'+name+'" value="'+keyValue[1]+'"/>'; }
				}
			}
		}

		//document.forms[0].innerHTML+=insertion;	//This don't work with select (select back their initial values because of the += (reloads the "innerHTML" content)
		document.getElementById("getToPost").innerHTML=insertion;	//Works perfectly but requires an additionnal getToPost div
	}
	catch(e)
	{ alert("Error "+e); }
}
function getToPost(href)
{
	try
	{
		createGetToPostHiddenFields(href);
		submitMyPageAsPostback();
		return;
	}
	catch(e)
	{ alert("Error "+e); }
	submitMyPageAsPostback();
}

function getObjClassId(obj,classNamePrefix)
{
	var cssClasses=obj.className.split(" ");
	return getClassId(cssClasses,classNamePrefix);
}
function getClassId(cssClasses,classNamePrefix)
{
	if(!classNamePrefix)
	{ classNamePrefix="Id_"; }

	for(var i=0;i<cssClasses.length;i++)
	{
		if(cssClasses[i].startsWith(classNamePrefix))
		{ return parseInt(cssClasses[i].replace(classNamePrefix,"")); }
	}
	return 0;
}

function AddWatermark(element,text)
{
	var obj=document.getElementById(element);
	if(obj)
	{
		obj.setAttribute("onfocus","javascript:FocusWatermark(\""+element+"\",\""+text+"\");");
		obj.setAttribute("onblur","javascript:BlurWatermark(\""+element+"\",\""+text+"\");");
		BlurWatermark(element,text);
	}
}
function FocusWatermark(element,text)
{
	var obj=document.getElementById(element);
	if(obj&&obj.value==text)
	{ obj.value=""; }
	obj.className="";
	//RemoveClassName(obj,"Watermark");
}
function BlurWatermark(element,text)
{
	var obj=document.getElementById(element);
	if(obj&&obj.value=="")
	{
		obj.value=text;
		obj.className="Watermark"
		//AddClassName(obj,"Watermark");
	}
	else if(obj&&obj.value!=text)
	{ obj.className=""; }
}

function Increase(value)
{
	var step=GetStep(value);
	return Math.round((value-value%step+step)*100)/100;
}


function Decrease(value)
{
	var step=GetStep(value);
	return Math.round((value+value%step-step)*100)/100;
}

function GetStep(value)
{
	if(value<0.1)
	{ return 0.01; }
	else if(value<1)
	{ return 0.1; }
	else if(value<5)
	{ return 0.1; }
	else if(value<10)
	{ return 1; }
	else if(value<20)
	{ return 2; }
	else if(value<50)
	{ return 5; }
	else if(value<100)
	{ return 10; }
	else if(value<500)
	{ return 25; }
	else if(value<1000)
	{ return 100; }
	else if(value<10000)
	{ return 1000; }
	else
	{ return 10000; }
}

function CheckBoxValidatorDisableButton(chkId,mustBeChecked,btnId)
{
	var button=document.getElementById(btnId);
	var chkbox=document.getElementById(chkId);

	if(button&&chkbox)
	{ button.disabled=(chkbox.checked!=mustBeChecked); }
}

function CheckBoxValidatorEvaluateIsValid(val)
{
	var control=document.getElementById(val.controltovalidate);
	var mustBeChecked=Boolean(val.mustBeChecked=="true");
	return control.checked==mustBeChecked;
}

function CheckBoxListValidatorEvaluateIsValid(val)
{
	var control=document.getElementById(val.controltovalidate);
	var minimumNumberOfSelectedCheckBoxes=parseInt(val.minimumNumberOfSelectedCheckBoxes);

	var selectedItemCount=0;
	var liIndex=0;
	var currentListItem=document.getElementById(control.id+"_"+liIndex.toString());
	while(currentListItem!=null)
	{
		if(currentListItem.checked)
		{ selectedItemCount++; }
		liIndex++;
		currentListItem=document.getElementById(control.id+"_"+liIndex.toString());
	}

	return selectedItemCount>=minimumNumberOfSelectedCheckBoxes;
}

function ToQueryString(objArray)
{
	var qString="?";
	for(var key in objArray)
	{ qString+=URLEncode(key)+"="+URLEncode(objArray[key])+"&"; }
	return qString;
}
function FromQueryString(qString)
{
	var objArray=new Array();

	if(qString)
	{
		qString=qString.substring(1);
		var elements=qString.split("&");
		for(var i=0;i<elements.length;i++)
		{
			var element=elements[i];
			var subElements=element.split("=");
			var key=URLDecode(subElements[0]);
			var value=URLDecode(subElements[1]);

			if(key)
			{ objArray[key]=value; }
		}
	}

	return objArray;
}

function inspect(obj,maxLevels,level)
{
	var str='',type,msg;

	// Start Input Validations
	// Don't touch, we start iterating at level zero
	if(level==null) level=0;

	// At least you want to show the first level
	if(maxLevels==null) maxLevels=1;
	if(maxLevels<1)
		return '<font color="red">Error: Levels number must be > 0</font>';

	// We start with a non null object
	if(obj==null)
		return '<font color="red">Error: Object <b>NULL</b></font>';
	// End Input Validations

	// Each Iteration must be indented
	str+='<ul>';

	// Start iterations for all objects in obj
	for(property in obj)
	{
		try
		{
			// Show "property" and "type property"
			type=typeof (obj[property]);
			str+='<li>('+type+') '+property+
                 ((obj[property]==null)?(': <b>null</b>'):(': '+obj[property]))+'</li>';

			// We keep iterating if this property is an Object, non null
			// and we are inside the required number of levels
			if((type=='object')&&(obj[property]!=null)&&(level+1<maxLevels))
				str+=inspect(obj[property],maxLevels,level+1);
		}
		catch(err)
		{
			// Is there some properties in obj we can't access? Print it red.
			if(typeof (err)=='string') msg=err;
			else if(err.message) msg=err.message;
			else if(err.description) msg=err.description;
			else msg='Unknown';

			str+='<li><font color="red">(Error) '+property+': '+msg+'</font></li>';
		}
	}

	// Close indent
	str+='</ul>';

	return str;
}
