/*
Copyright (c) 2007-2009, AOL LLC
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the AOL LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// http://dev.aol.com/axs
// Version 1.2
// March 10, 2009
// C. Blouch

var axs={
	//Boolean platform detection for Mac systems used to change alt to option and css rules
	onmac:navigator.platform.toLowerCase().indexOf("mac")>-1,
	//Browser sniffs used in various places
	onff:navigator.userAgent.toLowerCase().indexOf("firefox")>-1,
	onie:navigator.userAgent.toLowerCase().indexOf("msie")>-1,
	onsaf:navigator.userAgent.toLowerCase().indexOf("safari")>-1,
	//Move focus to any item in the DOM passed in.
	// obj-DOM node to focus on
	// tv-tabindex value to set on the object. Default is -1.
	focus:function(obj,tv){
		//These items don't need tabindex added. It first checks to make sure we don't need to bother modifying attributes
		var focus_exceptions={A:1,AREA:1,BUTTON:1,INPUT:1,OBJECT:1,SELECT:1,TEXTAREA:1};
		//Four checks here
		//1. If we are passed in a tab value then go right ahead and set the tabindex
		//2. If we are not given a tabindex then we need to make sure the object even needs one at all
		//by verifying that it's not on the focus_exceptions list otherwise go on and check for an existing tabindex
		//so we don't clobber one that is already assigned.
		//3. Firefox check
		//getAttribute("tabIndex") returns a null when there is no tabIndex, so go ahead and add it
		//If it isn't null then there is a an existing tabIndex so leave things alone.
		//Doing a getAttributeNode().specified in FF on a null node breaks, but why would somebody move focus to nothing?
		//4. IE check
		//In IE getAttribute("tabIndex") returns a 0 even when there is no tabIndex so we don't know if tabIndex DNE or 
		//if it was previously set to 0. So getAttribute should fail in IE because 0!=null. The getAttributeNode checks whether the
		//tabIndex value was specified or is just a default value. We first have to check if the getAttributeNode method exists
		//because IE5.5 and below lack this. If the method exists we use it to check if tabIndex is not specified.
		//If true we go ahead and add a tabIndex.
		//Also note that "tabIndex" must have the capital I to work in IE, even though the html is specified as "tabindex"
		if(
			tv ||
			!focus_exceptions[obj.nodeName] &&
			(obj.getAttribute("tabIndex")==null ||
			(obj.getAttributeNode && !obj.getAttributeNode("tabIndex").specified))
		)
		{
			//If we aren't passed in a value to set tabindex to then default to -1
			if(!tv)tv=-1;
			obj.setAttribute("tabIndex",tv);
		}
		//We check that the .focus method is available before invoking it to protect older browser from JS errors
		if(obj.focus)obj.focus();
	},
	//Register a key to function
	//key - "[control]+[alt]+[shift]+char"
	//fun - function or method to invoke when key is pressed
	//p - an optional hash map of parameters
	//p.des - Description of what the function does. Leave out to not make additional table entries
	//p.args - array of arguments to call the function with
	//p.node - the object to attach the keyboard combo to. Defaults to "document" if not specified
	//p.bub - boolean whether to bubble events or not. Defaults to false.
	//p.obj - Override This returned to your funtion to point to some other object instead of the node
	//EXAMPLE
	//axs.keyreg("alt-shift-p",doWork,{args:["c1.html",123,x]},bub:true,node:axs.id("box1"),"Make the update");
	//Bug: On Firefox 2.0 Mac any key in the number row will not work with shift or alt modifiers ie shift+7, alt+=
	//FF keycode gets reported as 0 instead of correct value. Known bug to be fixed in FF 3.0 which is scheduled
	//for release late winter 2007. See https://bugzilla.mozilla.org/show_bug.cgi?id=44259
	//FF3 fix was incomplete. Still issues with shift and -;',./ returning a 0 keycode on Mac
	//See https://bugzilla.mozilla.org/show_bug.cgi?id=448434
	keyreg:function(key,fun,p){
		//If there is no keymap or arrays of keycodes set them up
		if(!axs.keyreg.map){
			axs.keyreg.map=[];
			axs.keyreg.shift={"~":192,"!":49,"@":50,"#":51,"$":52,"%":53,"^":54,"&":55,"*":56,"(":57,")":48,"_":109,"+":61,"{":219,"}":221,"|":220,":":59,'"':222,"<":188,">":190,"?":191};
			axs.keyreg.special={"backspace":8,"enter":13,"escape":27,"pageup":33,"pagedown":34,"end":35,"home":36,"left":37,"up":38,"right":39,"down":40,"insert":45,"delete":46,"f1":112,"f2":113,"f3":114,"f4":115,"f5":116,"f6":117,"f7":118,"f8":119,"f9":120,"f10":121,"f11":122,"f12":123,"tab":124,"space":32,
			//These are not really tokens but are here to workaround the goofy keycodes not matching
			//the ascii values for these 7 characters.
			",":188,"-":109,".":190,"/":191,"`":192,"\\":220,"'":222};
		}
		if(!p)var p={};
		var tl,i,k,c,cc,ts,tc,ta,s="";
		//Check special case where + is the key they want
		if(key.indexOf("++")!=-1)cc=61;
		//Break the key string into list of tokens
		tl=key.split("+");
		k=tl.length;
		//Walk through all the tokens
		for(i=0;i<k;i++){
			c=tl[i];
			//If the token is longer than 0 characters
			if(c){
				//Check for shift key
				if(c=="shift")ts=1;
				//Check for control key
				else if(c=="control")tc=1;
				//Check for alt key
				else if(c=="alt")ta=1;
				//Check for special, shifted or regular keycode
				else if(!cc){
					cc=axs.keyreg.special[c]||axs.keyreg.shift[c]||c.toUpperCase().charCodeAt(0);
					//If on the shift list then signal shift key needed even if the user did not
					//include it in the key combination registration
					if(axs.keyreg.shift[c])ts=1;
				}
			}
		}
		//Build a string to represent the key combination to register
		//Use "Option" if on a Mac instead of Alt
		if(ts)s="shift+";
		if(tc)s+="control+";
		if(ta)s+="alt+";
		s+=cc;
		//If we've been given a description with key combo then add it to the registration
		//If we're on a Mac, replace reference to "alt" with "option" since that's what their keyboards call it
		if(p.des)axs.keyreg.map[axs.keyreg.map.length]={"des":p.des,"key":axs.onmac?s.replace("alt","option"):s};
		if(!p.args)p.args=[];
		//Create keyboard handler for this key combination
		var f=function(event){
			//In IE look in window.event on FF look in passed-in var
			var e=event||window.event,kb=e.keyCode||e.which,kk="";
			//Check and adjust for IE giving winky values for semicolon/colon, equals/plus
			//Should be keycode 59 and 61 but IE gives 186 and 187
			if(kb=="186")kb="59";
			if(kb=="187")kb="61";
			//build a string representing the current key combination
			if(e.shiftKey)kk="shift+";
			if(e.ctrlKey)kk+="control+";
			if(e.altKey)kk+="alt+";
			kk+=kb;
			//If the key they hit is the one we are looking for
			if(s==kk){
				//Call the appropriate function
				//If we are passed an object, return that to the registered function.
				//Otherwise give the DOM node that this function was attached to (this)
				fun.apply(p.obj||this,p.args);
				//Since we processed the keystroke, check if we should stop bubbling
				if(!p.bub==true){
					//Stop propogation the IE way
					e.cancelBubble=true;
					e.returnValue=false;
					//Stop propogation the standards way
					if(e.stopPropagation){
						e.stopPropagation();
						e.preventDefault();
					}
					return false;
				}else{return true}
			}
			return true;
		}
		//Attach the keyboard handler to the node
		//If no node is specified then attach to the overall document
		axs.ae(p.node||document,"keydown",f);
	},
	//Go through all the keymappings and make a table to let folks know what the keys do
	keychart:function(){
		var s,t,i,b,x,e,f,u,c,d=document,l;
		//Is this the first time keychart is being executed?
		if(!axs.id("axs_kt")){
			//Function to hide or show the keyboard shortcuts
			var sh=function(){
				var o=axs.ids("axs_kt");
				o.display=o.display!="none"?"none":"block";
				return false;
			}
			//Doctor up the css hide/show if on a mac
			if(axs.onmac)axs.keychart.l10n.css_hide=axs.keychart.l10n.css_hidem;
			//Register control+alt+h (default) as the hide/show keychart shortcut
			axs.keyreg(axs.keychart.l10n.key,sh,{des:axs.keychart.l10n.keyshow});
			//Create the container for the table and the hide/show link at the top of the page if it DNE
			e=d.createElement("div");
			e.style.display="none";
			e.id="axs_kt";
			d.body.insertBefore(e,d.body.firstChild);
			//Create link
			f=d.createElement("a");
			f.style.cssText=axs.keychart.l10n.css_hide;
			f.href="#";
			f.innerHTML=axs.keychart.l10n.linkshow;
			f.onclick=sh;
			f.onfocus=function(){axs.ids("axs_kl").cssText=axs.keychart.l10n.css_show;};
			f.onblur=function(){axs.ids("axs_kl").cssText=axs.keychart.l10n.css_hide;};
			f.id="axs_kl";
			d.body.insertBefore(f,d.body.firstChild);
		}
		//Create table head with localized text
		c="<table summary='"+axs.keychart.l10n.summary+"'><caption>"+axs.keychart.l10n.caption+"</caption><tr><th>"+axs.keychart.l10n.combo+"</th><th>"+axs.keychart.l10n.act+"</th></tr>";
		//Walk through all the known keymaps
		l=axs.keyreg.map.length;
		for(i=0;i<l;i++){
			var k=0;
			u=axs.keyreg.map[i].key;
			//Make a copy of the registered key combination
			t=u.split("+");
			//Get the key code off the end of the registered key combination
			b=t.length>1?t[t.length-1]:t;
			//Is the key special? Check the list for a token.
			for(x in axs.keyreg.special)if(axs.keyreg.special[x]==b)k=x;
			//Replace keycode with the token if it exists, otherwise use the actual letter
			c+="<tr><td>"+u.replace(b,k?k:String.fromCharCode(b))+"</td><td>"+axs.keyreg.map[i].des+"</td></tr>";
		}
		c+="</table>";
		//If there is help text, add that at the end
		c+=axs.keychart.l10n.help;
		//Inject the table the div
		axs.r(axs.id("axs_kt"),c);
	},

	//GetElementsByClassName - returns array of objects that match a certain classname within an object
	//o - object to search within. Could just be the document object or some other container object
	//c - class name string to match
	//Handles complete matches, multiple classes on an object, extra spaces etc.
	//Can't add to general Element or Object prototype because of IE bugs so this
	//Remains a standalone method
	//Added native getElementsByClassName support when present
	//Optimized loop to be as fast as possible in non-native case
	gecn:function(o,c){
		var m=[],d,l;
		//If there is native support, use that instead
		if(o.getElementsByClassName){
			d=o.getElementsByClassName(c);
			l=d.length;
			//Copy result into array because native implementation is dynamic so DOM changes can have
			//side effects on array indexes causing hard to find bugs.
			for(var i=0;i<l;i++){m[i]=d[i]}
		}
		else{
			//Get all the DOM elements within the specified object
			//And define a regex to search out the class names
			var q=new RegExp("(\\b)"+c+"(\\b)");
			d=o.getElementsByTagName('*');
			l=d.length;
			//Loop through all the objects and look for ones with the right class
			//And store them in an array
			do if(d[l-1].className.search(q)>-1)m[m.length]=d[l-1];
			while(--l);
		}
		return m;
	},
	//Flash Detect
	//Returns the version of flash installed or 0 if not found
	//Also returns 0 if version found is less than min.
	//If version is greater than max, returns max
	//min - minimum version to check for - default is 6
	//max - maximum version to check for - default is 9
	//Scan only happens one time with result stored in axs.fd.result
	//To force rescan set axs.fd.result to 0
	fd:function(min,max){
		//If we did not already run the tests then run them.
		//Otherwise just return the previous finding
		if(!axs.fd.result){
			//See if user passed in a minimum version to check for.
			// Otherwise the lowest we should probably care about is 6
			if(!min)min=6;
			//See if the user passed in a max version to check for
			//Otherwise the highest we should currently check for is 10
			if(!max)max=10;
			var fv=0,x;
			//If the browser supports checking plugins, do it that way
			if(navigator.plugins&&navigator.plugins.length){
				//Get the info for the Flash plugin
				x=navigator.plugins["Shockwave Flash"];
				//Split the string on the major/minor version number then split after the space
				//to get just the major version number
				if(x && x.description){
					fv=x.description.split(".")[0].split(" ");
					fv=fv[fv.length-1];
				}
				//If the version is less than our min return 0
				if(fv<min)fv=0;
				//If the version is greater than our max return max
				if(fv>max)fv=max;
			}else{
				//Check the IE way starting with the highest known current version
				var c=max;
				//Loop from highest to lower limit until we find something or hit the lower limit
				while(!fv&&min<=c){
					//If we fail, catch the error so we can loop again
					try{
						x=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+c);
						//If the previous line worked then we found something so store it which ends the loop
						fv=c;
					}
					catch(e){}
					//If we found nothing on this try, try the next older version and loop again
					if(!fv)c--;
				}
			}
			//Store the result for future reference
			axs.fd.result=fv;
		}
		return axs.fd.result;
	},
	//High Contrast Detect
	//Returns true if the browser is running in high contrast mode, false if not or -1 if on Mac or Safari
	hc:function(){
		//Check if we're running Safari or Mac return a -1 as we can't detect high contrast on these
		if(axs.onsaf||axs.onmac)return -1;
		else{
			var e,c;
			//Create a test div
			e=document.createElement("div");
			//Set its color style to something unusual
			e.style.color="rgb(31,41,59)";
			//Attach to body so we can inspect it
			document.body.appendChild(e);
			//Use standard means if available, otherwise use the IE methods
			c=document.defaultView?document.defaultView.getComputedStyle(e,null).color:e.currentStyle.color;
			//Delete the test DIV
			document.body.removeChild(e);
			//get rid of extra spaces in result
			c=c.replace(/ /g,"");
			//Check if we got back what we set
			//If not we are in high contrast mode
			return c!="rgb(31,41,59)";
		}
	},
	//Change a xoxo specified flash into an object.embedd
	//p - Package of optional settings is passed in
	//p.o - DOM object to search for flash xoxo in - default is Document
	//p.c - className of xoxo objects to convert - default is axs_flash_xoxo
	//p.r - DOM object to replace with Flash object - default is the xoxo list object
	//p.p - replace the parent of the xoxo for progressive enhancement - default is false
	flash_xoxo:function(p){
		var d={},o,fl,m,q=new RegExp(/^\s+|\s+$/g);
		//If we are not passed in p, make it an empty array
		if(!p)p={};
		//Check if there is an object to scope the search to, otherwise use Document
		if(!p.o)p.o=document;
		//Check if there was a class name specified to search for, otherwise use axs_flash_xoxo
		if(!p.c)p.c="axs_flash_xoxo";
		o=axs.gecn(p.o,p.c);
		//Loop through each instance of flash xoxo found
		fl=o.length;
		for(m=0;m<fl;m++){
			var dt,l,i,dd,nam,s=s1=s2=s3="",n=o[m];
			d.pair=d.param={};
			//Pull out all the DTs from the first xoxo list found
			dt=n.getElementsByTagName("dt");
			l=dt.length;
			//Loop through a set of dt elements
			for(i=0;i<l;i++){
				//Get the DD that belongs to this DT
				dd=dt[i].nextSibling;
				//Might be junk inbetween so keep skipping until we get to the dd
				while(dd.nodeType!=1)dd=dd.nextSibling;
				nam=dd.innerHTML.replace(q,"").toLowerCase();
				//Is this node a parameter? If so then grab the second value
				if(dt[i].innerHTML.replace(q,"").toLowerCase()=="param"){
					//Get the next DD node
					dd=dd.nextSibling;
					//Make sure it's not some junk. If not, traverse until we find one
					while(dd.nodeType!=1)dd=dd.nextSibling;
					//Store the name/value in the PARAM of the data object
					d.param[nam]=dd.innerHTML.replace(q,"");
				}else{
					//Not a parameter so store it in the PAIR of the data object
					d.pair[dt[i].innerHTML.replace(q,"").toLowerCase()]=nam;
				}
			}
			//We now have parsed one xoxo set so generate the embedd string
			//Build name value pairs in both object and embed formats
			for(i in d.pair){
				if(i!="version"&&i!="src")s1+=i+'="'+d.pair[i]+'" ';
				if(i!="version"&&i!="id"&&i!="name")s2+=i+'="'+d.pair[i]+'" ';
			}
			for(i in d.param){
				s3+='<param name="'+i+'" value="'+d.param[i]+'" />';
				s2+=i+'="'+d.param[i]+'" ';
			}
			//Add object, classid and codebase
			s='<object '+s1+'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+d.pair.version+',0,0,0">';
			//Add the movie as a parameter from the src pair so we don't have to put it in the xoxo twice
			s+=s3+'<param name="movie" value="'+d.pair.src+'" />';
			//Now make the embed tag
			s+='<embed '+s2+' type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></object>';
			//If we're given a node to replace then put the new flash there
			if(p.r)axs.r(p.r,s)
			else{
				//No node specified so if parent node replacement request put it there
				if(!p.p)p.p=0;
				if(p.p)axs.r(n.parentNode,s);
				//Otherwise just replace the xoxo list itself with the flash
				else{
					//First update what's inside the xoxo list with the flash object
					axs.r(n,s);
					//Move the flash object just above the xoxo list
					n.parentNode.insertBefore(n.firstChild,n);
					//Delete the xoxo list
					n.parentNode.removeChild(n);
				}
			}
		}
	},
	//MSAA Detect
	// c - callback function to pass results to
	// Returns true, false, -1 if could not detect or -2 if detector could not load
	// Can't detect if not Flash 8 or higher for IE or Flash 9 or higher for FF or if running on Safari
	md:function(c){
		//Check if we're running Safari or Mac return a -1 as we can't detect MSAA
		if(axs.onsaf||axs.onmac)c(-1);
		else{
			//Store the URL for the SWF file
			axs.md.url="md.swf";
			var d=document,e=d.createElement("div"),s;
			//Store the callback function for the flash to call with the results
			axs.md.cb=function(r){
				//If we get a result then stop the failure timer
				if(r!=-1)clearTimeout(axs.md.t);
				//Delete the detector node
				e.parentNode.removeChild(e);
				//Return the results
				c(r);
			};
			//Create DIV to insert the Flash object into
			d.body.appendChild(e);
			//Style the DIV so it is visibly hidden but still functions
			e.style.cssText='position:absolute;top:-999px;';
			//Embed our flash MSAA detect object
			//Requires Flash 8 or higher for IE, 9 or higher for FF
			axs.r(e,'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+(axs.onff?9:8)+',0,0,0"><param name="movie" value="'+axs.md.url+'" /><param name="allowScriptAccess" value="always" /><embed src="'+axs.md.url+'" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" allowScriptAccess="always" /></object>');
			//If the detect fails for some reason, call the users callback with no results
			axs.md.t=setTimeout(function(){axs.md.cb(-2)},2000);
		}
	},
	//Ajax document fetcher
	// u		URL to make request to
	// a		attribute map
	// a.cb		callback function
	// a.meth	Method to use on ajax request such as get, post, put
	// a.head	Content type header to add to transaction
	// a.data	put data here if you want to switch from GET to POST
	// a.p		Package of elements to pass on to callback function
	gdoc:function(u,a){
		var f,r,m;
		//If we are not passed in a, make it an empty array
		if(!a)a={};
		//When Ajax state goes to 4, invoke the provided callback.
		//Handle case where callback might be an object method or a function
		f=function(){if(r.readyState>3)typeof(a.cb)=="function"?a.cb.call(null,r,a.p):window[a.cb](r,a.p)}
		//If we are not passed a method default to get unless there is post data
		if(!a.meth){
			m="GET";
			a.data?m='POST':a.data="";
		}else{
			m=a.meth;
			if(!a.data)a.data="";
		}
		//Create request objec in either the standards or Microsoft way
		r= window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
		//Setup callback for when Ajax completes
		r.onreadystatechange=f;
		//Make the Ajax request
		r.open(m,u,1);
		//Set Header to work around Safari weirdness if not passed in
		a.head?r.setRequestHeader('content-type',a.head):r.setRequestHeader('content-type','text/xml');
		//Make it so
		r.send(a.data);
	},
	//document.getElementById() wrapped to be id()
	id:function(id){return document.getElementById(id)},
	//document.getElementById().style wrapped to be ids()
	ids:function(id){return axs.id(id).style},
	//Replace contents in object O with text T
	r:function(o,t){o.innerHTML=t},
	//Add function, method or anonymous function f to be called when object o fires event e
	//Handles both the standard addEventListner and IE attachEvent ways to do this.
	//Works around a pile of IE bugs/quirks with attachEvent
	//Using m for the method works around a Safari quirk
	//Using global ae_ct for the array index works around IE bug with anonymous functions
	//We preface the count with "h" for hack since in IE the object reference can't start with a number
	//o - object to attach event to
	//e - name of event to register
	//f - function or method to trigger
	ae:function(o,e,f){
		var m="addEventListener",a;
		//Do things the standards way if we can
		if(o[m])o[m](e,f,false);
		//Otherwise do it the IE way
		else if((a=o.attachEvent)){
			//Set up counter to make string unique
			if(!axs.ae.c)axs.ae.c=0;
			//Create array index string to hold wrapper function
			var t="h"+axs.ae.c++;
			//Store the function to call in the object with a known index to call later
			o['s'+t]=f;
			//Store a new function in the object which calls the original function and passes in window.event
			o[t]=function(){o['s'+t](window.event)}
			//Attach the wrapper function as the handler for the event on this object
			a('on'+e,o[t]);
		}
	},
	// Log
	// Text m is appended to the log content with a millisecond level timestamp
	log:function(m){
		if(axs.debug){
			var d=document;
			if(!axs.log.d){
				var e=d.createElement("div"),f=function(a,b){e.setAttribute(a,b)};
				f("id","_axslog");
				//Add ARIA attributes so new entries will be announced by AT
				f("role","log");
				f("aria-live","rude");
				f("aria-relevant","additions");
				f("aria-atomic","false");
				d.body.appendChild(e);
				e.style.cssText='background-color:#ccf;height:10em;width:30em;overflow:auto;font-size:11px;position:absolute;top:525px;text-align:left;';
				axs.log.d=1;
			}
			var n=d.createElement("div"),t=new Date(),o=axs.id("_axslog");
			n.innerHTML="<b>"+t.getMinutes()+"m"+t.getSeconds()+"s"+t.getMilliseconds()+"ms:</b>"+m;
			o.insertBefore(n,o.firstChild);
		}
	}
}
//Localization tables
axs.keychart.l10n={
	summary:"This table describes the shortcut keys implemented on this page",
	caption:"Key combinations and the actions they invoke.",
	combo:"Key Combination",
	act:"Action",
	keyshow:"Show or hide the keyboard shortcut help",
	linkshow:"Keyboard shortcut table - Click this link to show or hide",
	key:"control+alt+h",
	help:"",
	css_hidem:"height:0px;width:0px;overflow:hidden;display:block;",
	css_hide:"height:1px;width:1px;overflow:hidden;position:absolute;top:-99px;",
	css_show:"height:auto;width:auto;overflow:visible;"
}