if( !window.Node ) {
	var Node = {
		ELEMENT_NODE                :  1,
		ATTRIBUTE_NODE              :  2,
		TEXT_NODE                   :  3,
		CDATA_SECTION_NODE          :  4,
		ENTITY_REFERENCE_NODE       :  5,
		ENTITY_NODE                 :  6,
		PROCESSING_INSTRUCTION_NODE :  7,
		COMMENT_NODE                :  8,
		DOCUMENT_NODE               :  9,
		DOCUMENT_TYPE_NODE          : 10,
		DOCUMENT_FRAGMENT_NODE      : 11,
		NOTATION_NODE               : 12
	}
}

function agentMatches( str ) {
	return (navigator.userAgent.toLowerCase().indexOf( str.toLowerCase() )
		!= -1);
	}

function isIE( )
	{ return agentMatches( 'MSIE' ); }

function isIE6( )
	{ return ( isIE( ) && isAtMostVersion( 6 ) ); }

function isSafari( )
	{ return agentMatches( 'Safari' ); }

function isFirefox( )
	{ return agentMatches( 'Firefox' ); }

function isOpera( )
	{ return agentMatches( 'Opera' ); }

function isMac( )
	{ return agentMatches( 'Mac' ); }
	
function getBrowserVersion( ) {
	if( isIE( ) ) {
	    t = 'msie ';
		var p = navigator.userAgent.toLowerCase().indexOf( t ) + t.length;
		return parseInt( navigator.userAgent.substring( p ) );
		}
	else
	if( isSafari( ) ) {
		v = navigator.userAgent.match( /Version\/(\d+)/ );
		if( v == null
		||  v.length != 2 ) {
			return 2;
			}
		else {
			return v[1];
			}
		}
	else {
	    // This doesn't give great results, but parseInt( navigator.userAgent ) 
	    // yields NaN
		return parseInt( navigator.appVersion );
		}
	}

function isAtLeastVersion( version ) {
	return ( getBrowserVersion( ) >= version );
}

function isAtMostVersion( version ) {
	return ( getBrowserVersion( ) <= version );
}

function auri( path ) {
	if( !isset( 'AURI' ) ) {
		console.warn( 'No AURI defined!' );
		}
	return AURI + path;
	}

function full_auri( path ) {
	if( !isset( 'FULL_AURI' ) ) {
		console.warn( 'No FULL_AURI defined!' );
		}
	return FULL_AURI + path;
	}

function keys( o ) {
	var r = [];
	for( var k in o ) {
		r.push( k );
		}
	return r;
	}

function isset( v ) {
	return ( typeof( window[ v ] ) != 'undefined' );
}

function jump( path ) {
	if( window.location ) {
		loc = window.location;
		if( !path ) {
			loc.reload( );
		}
		else {
			loc.replace( auri( path ) );
		}
	}
}
	
function getObj( id ) {
	if( is_object( id ) ) {
		return id;
		}
	return document.getElementById( id );
	}

function getObjX( obj ) {
	var x = 0;
	
	if( obj.offsetLeft ) {
		x += obj.offsetLeft;
		while( obj.offsetParent ) {
			obj = obj.offsetParent;
			x += Math.abs( obj.offsetLeft );
			}
		}
	else
	if( obj.x ) {
		x += obj.x;
		}
	
	return x;
	}

function getObjY( obj ) {
	var y = 0;

	if( obj.offsetParent ) {
		while( obj.offsetParent ) {
			y += obj.offsetTop;
			obj = obj.offsetParent;
			}
		y += obj.offsetTop;
		}
	else
	if( obj.y ) {
		y += obj.y;
		}
		
	return y;
	}
	
function getObjWidth( obj ) {
	return obj.offsetWidth;
	}

function getObjHeight( obj ) {
	return obj.offsetHeight;
	}
	
function getSourceObject( e ) {
	return e.srcElement;
	}
	
function getEventX( e ) {
	var e = getEvent( e );

	if( e && e.clientX )
		return e.clientX;
	else
		return false;
	}

function getEventY( e ) {
	var e = getEvent( e );

	if( e && e.clientY )
		return e.clientY;
	else
		return false;
	}
	
function getEvent( e ) {

	if( window.event )
		return window.event;
		
	if( isFirefox( ) && e )
		return e;
	
	return null;
	}

function getEventTarget( e ) {
    if( e.target ) {            // Gecko
        return e.target;
    }
    
    if( e.srcElement ) {        // IE
        return e.srcElement;
    }
    
    return null;
}

function getStyle( obj, in_style ) {
	if( obj.style && obj.style[ in_style ] ) {
		return obj.style[ in_style ];
	}
	else
	if( window.getComputedStyle ) {
		return window.getComputedStyle( obj, null )[ in_style ];
	}
	else
	if( obj.currentStyle ) {
		return obj.currentStyle[ in_style ];
	}
}

function attachHandler( obj, handle, handler, useCapture ) {
	if( document.addEventListener ) {
		handle = handle.replace( /^on/, '' );
		if( typeof( useCapture ) == 'undefined' ) {
			useCapture = false;
		}
		obj.addEventListener( handle, handler, useCapture );
	}
	else
    if( document.attachEvent ) {
    	if( handle.search( /^on/ ) == -1 ) {
    		handle = 'on'+handle;
    	}
        obj.attachEvent( handle, handler );
    }
    else {
        eval( 'obj.' + handle + ' = handler' );
    }
}

function getKeyPressed( e ) {
    if( e.which )           // Gecko
        return e.which;
    else
    if( e.keyCode )         // IE
        return e.keyCode;
    else
        uv_error( 'Unable to determine the pressed key' );
}

function fireClickOnEnterKeyPress( e, obj ) {
	if( new Event( e ).key == 'enter' ) {
		emulate_onclick( obj, e );
	}
}

// Deprecated in favor of javascript's native event handling (use either attachHandler or mootools' addEvent method). Overuse of this function causes IE to "detect" an infinite loop and throw a stack overflow error.
function chainHandlers( first, last ) {
	return f = function( e ) {
		var r = true;

		if( first ) {
			this.__t_call = first;
			r = this.__t_call( e );
			if( r === false ) {
				return r;
				}
			}

		if( last ) {
			this.__t_call = last;
			r = this.__t_call( e );
			}

		return r;
		}
	}

function abortEvent( e ) {
	if( !e ) 
		var e = window.event;

	e.cancelBubble = true;
	if( e.stopPropagation )
		e.stopPropagation();
	
	return false;
	}

function abortEventAndPreventDefault( e ) {
	abortEvent( e );
	if (e.preventDefault) { return e.preventDefault( ); }
	return false;
}

function setCookie( n, v ) {
	document.cookie = n + '=' + v + '; path=/';
	}

function getCookie( n ) {
	var nameEQ = n+'=';
	var ca = document.cookie.split(';');
	for( var ii = 0; ii < ca.length; ii++ ) {
		var c = ca[ii];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0)
			return c.substring(nameEQ.length,c.length);
		}

	return null;
	}

function eraseCookie(name) {
	setCookie(name,'');
	}


function getText( obj ) {

	if( obj.innerText )
		return obj.innerText;
	
	return null;
	}

function setText( obj, text ) {
	obj.innerText = text;
	}

function getHTML( obj ) {
	if( obj.innerHTML )
		return obj.innerHTML;
	
	return null;
}

function getIFrameHTML( iframe ) {
    if( iframe.contentDocument ) {
        return iframe.contentDocument;
    }
    else
    if( iframe.contentWindow
    &&  iframe.contentWindow.document
    ) {
        return iframe.contentWindow.document;
    }
    else
    if( iframe.document ) {
        return iframe.document;
    }
    
    return null;
}

function getIFrameXML( iframe ) {
	if( iframe.contentDocument ) {
		if( iframe.contentDocument.XMLDocument ) {
			return iframe.contentDocument.XMLDocument;
		}
		else {
			return iframe.contentDocument;
		}
	}
}

function setHTML( obj, html ) {
	obj.innerHTML = html;
	}

var _lockedObjects = null;

function adjustLockedPositions( ) {
	if( typeof( _lockedObjects ) == 'object' ) {
		var dx = getScrollOffsetX( );
		var dy = getScrollOffsetY( );
		for( var k in _lockedObjects ) {
			_lockedObjects[ k ].style.top = z = 
				(_lockedObjects[ k ]._lockBaseOffsetY + dy) + 'px';
			_lockedObjects[ k ].style.left =
				(_lockedObjects[ k ]._lockBaseOffsetX + dx) + 'px';
			}
		}
	}

function lockPosition( obj ) {
	
	if( typeof( _lockedObjects ) != 'array' ) {

		window.onscroll = chainHandlers(
			adjustLockedPositions, window.onscroll
			);

		_lockedObjects = [];
		}
	
	if( !in_array( obj, _lockedObjects ) ) {
		obj._lockBaseOffsetX = getObjX( obj.style.top );
		obj._lockBaseOffsetY = getObjY( obj.style.left );
		_lockedObjects.push( obj );
		adjustLockedPositions( );
		}
	}


function clearNode( node ) {
	if( node.removeChild ) {
		while( node.firstChild ) {
			node.removeChild( node.firstChild );
			}
		}

	return node;
	}

function removeNode( node ) {
	if( node ) {
		if( node.parentNode ) {
			if( node.parentNode.removeChild ) {
				node.parentNode.removeChild( node );
				}
			}
		}
	}

function replaceNode( node, new_node ) {
	if( node && new_node && node.parentNode ) {
		if( node.parentNode.replaceChild ) {
			node.parentNode.replaceChild( new_node, node );
		}
	}
}

// Transfer a node across dom documents
function transferNode( node, new_node ) {
    if( document.importNode ) {
        replaceNode(
              node
            , document.importNode( new_node, true )
        );
    }
    else {
        node.innerHTML = new_node.cloneNode( true ).innerHTML;
    }
}

var warn = function warn( ) { }

function is_array( v ) {
	return ( is_object( v ) && v.constructor == Array );
}

function is_string( v ) {
	return ( typeof( v ) == 'string' );
}

function is_number( v ) {
	return( typeof( v ) == 'number' );
}

function is_object( v ) {
	return ( typeof( v ) == 'object' );
}

function in_array( obj, arr ) {
	for( var k in arr ) {
		if( arr[k] == obj )
			return true;
		}
	return false;
	}

function objlen( obj ) {
	var N = 0;
	for( var k in obj ) N++;
	return N;
	}

function getWindowWidth( ) {
	if( window
	&&	window.innerWith ) {
		return window.innerWidth;
		}
	else
	if( document.documentElement
	&&	document.documentElement.clientWidth ) {
		return document.documentElement.clientWidth;
		}
	else
	if( document.body
	&&	document.body.clientWidth ) {
		return document.body.clientWidth;
		}
	}

function getWindowHeight( ) {
	if( window
	&&	window.innerHeight ) {
		return window.innerHeight;
		}
	else
	if( document.documentElement
	&&	document.documentElement.clientHeight ) {
		return document.documentElement.clientHeight;
		}
	else
	if( document.body
	&&	document.body.clientHeight ) {
		return document.body.clientHeight;
		}
	}

function getDocumentHeight( ) {

	if( document
	&&	document.body
	&&	document.body.scrollHeight ) {
		return document.body.scrollHeight;
		}
	else
	if(	document
	&&	document.documentElement
	&&	document.documentElement.scrollHeight ) {
		return document.documentElement.scrollHeight;
		}

	}
	
function getDocumentWidth( ) {
	if(	document
	&&	document.body ) {
		return document.body.clientWidth;
		}
	}
	
function getScrollOffsetY( ) {
	if( document
	&&	document.body
	&&	document.body.scrollTop )
		{ return document.body.scrollTop; }

	if( document
	&&	document.documentElement
	&&	document.documentElement.scrollTop )
		{ return document.documentElement.scrollTop; }

	if( window.pageYOffset )
		{ return window.pageYOffset; }
	
	return 0;
	}

function getScrollOffsetX( ) {
	if( document
	&&	document.body
	&&	document.body.scrollTop )
		{ return document.body.scrollLeft; }

	if( document
	&&	document.documentElement
	&&	document.documentElement.scrollTop )
		{ return document.documentElement.scrollLeft; }

	if( window.pageYOffset )
		{ return window.pageXOffset; }
	
	return 0;
	}

function emulate_onclick( obj, e ) {
	if( obj ) {
		if( obj.onclick ) {
			return obj.onclick( e );
			}
		}
	}



String.prototype.trim = function( ) {
	return this.replace( /^\s+|\s+$/g, '' );
	}
	
function appendSibling( o, n ) {
	o.parentNode.insertBefore( n, o.nextSibling );
	return n;
	}
	
function insertBefore( node, before ) {
    return before.parentNode.insertBefore( node, before );
}

function cloneNode( node, recurse ) {
    return node.cloneNode( recurse ? true : false );
}

if( isFirefox() ) {
	HTMLElement.prototype.__defineGetter__(
		 'innerText'
		, function () { return this.textContent; }
	);
	
	HTMLElement.prototype.__defineSetter__(
		 'innerText'
		, function (v) { return this.textContent = v; }
	);
}



var popped = new Object();
function open_pop( name, uri, width, height, features ) {
	pop = popped[ name ];
	pop = window.open(
		  uri
		, name
		, 'width=' + width + ',height=' + height + ',' + features
		);
	
	/**
	 *	@browser ?
	 *	Catches instance where opener is refreshed and loses link to pop-up.
	 */
	pop.resizeTo( width, height );
	pop.focus();
	
	popped[name] = pop;
	
	return pop;
	}

function close_pop( name ) {
	popped[name].close();
	}

function bind( obj, method /*, arg, arg, arg */ ) {

	var args = new Array( );
	for( var ii = 2; ii < arguments.length; ii++ ) {
		args.push( arguments[ii] );
		}
	
	if( !obj ) {
		obj = window;
		}

	return function( ) {
		var targs = args;
		var jj = 0;
		for( var jj = 0; jj < arguments.length; jj++ ) {
			targs.push( arguments[ jj ] );
			}
		if( is_string( method ) ) {
			return obj[method].apply( obj, args );
			}
		else {
			return method.apply( obj, args );
			}
		}
	}
	


function add( ) {
	var zz;
	var _t = 0;
	for( zz = 0; zz < arguments.length; zz++ ) {
		_t += arguments[zz];
		}
	return _t;
	}
	
function assert( code ) {
	if( !eval( code ) ) {
		alert( 'Assertion Failed: ' + code );
		}
	}

assert( 'add( ) == 0' );
assert( 'add( 35 ) == 35' );
assert( 'add( 1, 1 ) == 2' );
assert( 'add( 2, 3, 4 ) == 9' );
assert( 'bind( null, add, 3 )( ) == 3' );
assert( 'bind( null, add, 3, 4 )( ) == 7' );
assert( 'bind( null, add, 3 )( 3 ) == 6' );
assert( 'bind( null, bind( null, add, 3, 4 ), 5, 6 )( 7, 8 ) == 33' );
	
	

function extend( dst, src ) {
	for( k in src ) {
		dst[ k ] = src[ k ];
		}
	return dst;
	}
	

/**
 * This is DEPRECATED! Use extend() instead!
 */
function intrude( dst, src ) {
	for( var k in src ) {
		dst[k] = src[k];
		}
	return dst;
	}

		
function alert_obj( obj ) {
	if( isset( 'console' ) ) {
		console.dir( obj );
		return;
	}
	
	var s = '';
	for( var k in obj ) {
		try {
			s += k + ': ' + obj[ k ] + "\n";
			}
		catch( e ) {
			s += k + '!' + "\n";
			}
		}
	alert( s );
	}

function accepts( obj, msg ) {
	if( isFunction( obj[ msg ] ) ) {
		return true;
		}
	return false;
	}


function addClass( obj, className ) {
	if( !obj.className ) {
		obj.className = '';
		}

	obj.className = ( obj.className + ' ' + className ).trim( );
	}
	
function hasClass( obj, className ) {
	if( !obj.className ) {
		obj.className = '';
		}

	return obj.className.test(
		new RegExp( '(^|\\s)' + className + '(\\s|$)' )
		);
	}

function removeClass( obj, className ) {
	if( !obj.className ) {
		obj.className = '';
		}

	obj.className = obj.className.replace(
		 new RegExp( "(^|\\s+)(" + className + ")(\\s+|$)", 'g' )
		,' '
		).trim( );
	}

function swapClass( obj, newClassName, oldClassName ) {
	removeClass( obj, oldClassName );
	addClass( obj, newClassName );
}

function error( msg ) {
    log( 'Error: ' + msg );
}

function warn( msg ) {
    log( 'Warning: ' + msg );
}

function log( msg ) {
    if( isset( 'console' ) ) {
        console.log( msg );
    }
}

function locale_asset_prefix( locale ) {
	switch( locale ) {
		case 'fr_CA':
			return 'fr.';
		default:
			return '';
	}
}