function x(msg)
{
	window.status=msg;
}

function ws_in(rin, uni, upr, pin, ppr, ain, apr, fin, qin)
{
	window.status='INs details :: raw: '+rin+', unique: '+uni+' ['+upr+'%], proxy: '+pin+' ['+ppr+'%]'+', active: '+ain+' ['+apr+'%]'+', fact: '+fin+', quality: '+qin;
}

function ws_cl(rcl, gcl, gpr, ocl, opr, fcl, qcl)
{
	window.status='CLICKs details :: raw: '+rcl+', content: '+gcl+' ['+gpr+'%], trade: '+ocl+' ['+opr+'%]'+', fact: '+fcl+', quality: '+qcl;
}

function ws_out(rout, uout, upr, frcd, fout, qout)
{
	window.status='OUTs details :: raw: '+rout+', unique: '+uout+' ['+upr+'%], forced: '+frcd+', fact: '+fout+', quality: '+qout;
}

function ws_pr(rpr, opr, fpr)
{
	window.status='PRODs details :: raw: '+rpr+', trade: '+opr+', fact: '+fpr;
}

function show_graph(what)
{
	window.open('./act.php?silent=1&action=root_graph&what='+what, 'graph', 'width=400, height=600, scrollbars=yes, resizable');
}

function newwin(url, title, opts)
{
	window.open(url, title, opts);
}

function trinvertchange(ttt)
{
	document.tradersform.invert[0].selected=document.tradersform.invert2[0].selected=ttt[0].selected;
	document.tradersform.invert[1].selected=document.tradersform.invert2[1].selected=ttt[1].selected;
}

function enableChecker(checker, element)
{
	element.disabled=false;
}

function setState(checkbox, obj)
{  

	if(checkbox.checked)
		obj.disabled = false;
	else
		obj.disabled = true;
}

function selectcolor(selector)
{
	selector.style.background=selector.value;
}

function changeForm(form, actparams, winname, winparams)
{
	form.action=form.action+actparams;
	if(winname!='') {
		win=window.open('', winname, winparams);
		form.target=winname;
	}
}

/**
 * alphaAPI
 * Original Author: chrisken
 * Original Url: http://www.cs.utexas.edu/users/chrisken/alphaapi.html
 *
 * Modified by dallen
 */
function alphaAPI(element, fadeInDelay, fadeOutDelay, startAlpha, stopAlpha, offsetTime, deltaAlpha)
{
	// {{{ properties

	this.element = typeof(element) == 'object' ? element : document.getElementById(element);
	this.fadeInDelay = fadeInDelay || 40;
	this.fadeOutDelay = fadeOutDelay || this.fadeInDelay;
	this.startAlpha = startAlpha;
	this.stopAlpha = stopAlpha;
	// make sure a filter exists so an error is not thrown
	if (typeof(this.element.filters) == 'object')
	{
		if (typeof(this.element.filters.alpha) == 'undefined')
		{
			this.element.style.filter += 'alpha(opacity=100)';
		}
	}

	this.offsetTime = (offsetTime || 0) * 1000;
	this.deltaAlpha = deltaAlpha || 10;
	this.timer = null;
	this.paused = false;
	this.started = false;
	this.cycle = false;
	this.command = function() {};

	// }}}
	// {{{ repeat()

	this.repeat = function(repeat)
	{
		this.cycle = repeat ? true : false;
	}

	// }}}
	// {{{ setAlphaBy()

	this.setAlphaBy = function(deltaAlpha)
	{
		this.setAlpha(this.getAlpha() + deltaAlpha);
	}
	
	// }}}
	// {{{ toggle()

	this.toggle = function()
	{
		if (!this.started)
		{
			this.start();
		}
		else if (this.paused)
		{
			this.unpause();
		}
		else
		{
			this.pause();
		}
	}
	
	// }}}
	// {{{ timeout()

	this.timeout = function(command, delay)
	{
		this.command = command;
		this.timer = setTimeout(command, delay);
	}
	
	// }}}
	// {{{ setAlpha()

	this.setAlpha = function(opacity)
	{
		if (typeof(this.element.filters) == 'object')
		{
			this.element.filters.alpha.opacity = opacity;
		}
		else if (this.element.style.setProperty)
		{
			this.element.style.setProperty('-moz-opacity', opacity / 100, '');
		}
	}	

	// }}}
	// {{{ getAlpha()

	this.getAlpha = function()
	{
		if (typeof(this.element.filters) == 'object')
		{
			return this.element.filters.alpha.opacity;
		}
		else if (this.element.style.getPropertyValue)
		{
			return this.element.style.getPropertyValue('-moz-opacity') * 100;
		}

		return 100;
	}
	
	// }}}
	// {{{ start()

	this.start = function()
	{
		this.started = true;
		this.setAlpha(this.startAlpha);
		// determine direction
		if (this.startAlpha > this.stopAlpha)
		{
			var instance = this;
			this.timeout(function() { instance.fadeOut(); }, this.offsetTime);
		}
		else
		{
			var instance = this;
			this.timeout(function() { instance.fadeIn(); }, this.offsetTime);
		}
	}
	
	// }}}
	// {{{ stop()

	this.stop = function()
	{
		this.started = false;
		this.setAlpha(this.stopAlpha);
		this.stopTimer();
		this.command = function() {};
	}
	
	// }}}
	// {{{ reset()

	this.reset = function()
	{
		this.started = false;
		this.setAlpha(this.startAlpha);
		this.stopTimer();
		this.command = function() {};
	}

	// }}}
	// {{{ pause()

	this.pause = function()
	{
		this.paused = true;
		this.stopTimer();
	}
	
	// }}}
	// {{{ unpause()

	this.unpause = function()
	{
		this.paused = false;
		if (!this.started)
		{ 
			this.start();
		}
		else
		{
			this.command(); 
		}
	}
	
	// }}}
	// {{{ stopTimer()

	this.stopTimer = function()
	{
		clearTimeout(this.timer);
		this.timer = null;
	}

	// }}}
	// {{{ fadeOut()

	this.fadeOut = function()
	{
		this.stopTimer();
		if (this.getAlpha() > this.stopAlpha)
		{
			this.setAlphaBy(-1 * this.deltaAlpha);
			var instance = this;
			this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay);
		}
		else
		{
			if (this.cycle)
			{
				var instance = this;
				this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay);
			}
			else
			{
				this.started = false;
			}
		}
	}
	
	// }}}
	// {{{ fadeIn()

	this.fadeIn = function()
	{
		this.stopTimer();
		if (this.getAlpha() < this.startAlpha)
		{
			this.setAlphaBy(this.deltaAlpha);
			var instance = this;
			this.timeout(function() { instance.fadeIn(); }, this.fadeInDelay);
		}
		else
		{
			if (this.cycle)
			{
				var instance = this;
				this.timeout(function() { instance.fadeOut(); }, this.fadeOutDelay);
			}
			else
			{
				this.started = false;
			}
		}
	}
		
	return this;	

	// }}}
}
// {{{ global constants

/**
 * Global constants (DO NOT EDIT)
 */

// browsers
var domLib_userAgent = navigator.userAgent.toLowerCase();
var domLib_isOpera = domLib_userAgent.indexOf('opera 7') != -1 ? 1 : 0;
var domLib_isKonq = domLib_userAgent.indexOf('konq') != -1 ? 1 : 0;
var domLib_isIE = !domLib_isKonq && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1);
var domLib_isIE5up = domLib_isIE;
var domLib_isIE50 = domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1;
var domLib_isIE55 = domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1;
var domLib_isIE5 = domLib_isIE50 || domLib_isIE55;
var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50;
var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55;
var domLib_isGecko = domLib_userAgent.indexOf('gecko') != -1 ? 1 : 0;

// abilities
var domLib_useLibrary = domLib_isOpera || domLib_isKonq || domLib_isIE5up || domLib_isGecko ? 1 : 0;
var domLib_canTimeout = !(domLib_isKonq || domLib_isIE50);
var domLib_canFade = domLib_isGecko || domLib_isIE55up;

// event variables
var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget';
var domLib_eventButton = domLib_isIE ? 'button' : 'which';
var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget';
var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer';
// :FIX: bug in Opera that it can't set maxWidth to 'none'
var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none';
var domLib_hidePosition = '-1000px';
var domLib_scrollbarWidth = 14;
var domLib_autoId = 1;
var domLib_zIndex = 100;

// detection
var domLib_selectElements;

var domLib_timeoutStateId = 0;
var domLib_timeoutStates = new Hash();

// }}}
// {{{ Object.prototype.clone

Object.prototype.clone = function()
{
	var copy = {};
	for (var i in this)
	{
		var value = this[i];
		try
		{
			if (value != null && typeof(value) == 'object' && value != window && !value.nodeType)
			{
				// for IE5 which doesn't inherit prototype
				value.clone = Object.clone;
				copy[i] = value.clone();
			}
			else
			{
				copy[i] = value;
			}
		}
		catch(e)
		{
			copy[i] = value;
		}
	}

	return copy;
}

// }}}
// {{{ class Hash()

function Hash()
{
	this.length = 0;
	this.elementData = [];
	for (var i = 0; i < arguments.length; i += 2)
	{
		if (typeof(arguments[i + 1]) != 'undefined')
		{
			this.elementData[arguments[i]] = arguments[i + 1];
			this.length++;
		}
	}

	this.get = function(in_key)
	{
		return this.elementData[in_key];
	}

	this.set = function(in_key, in_value)
	{
		if (typeof(in_value) != 'undefined')
		{
			if (typeof(this.elementData[in_key]) == 'undefined')
			{
				this.length++;
			}

			return this.elementData[in_key] = in_value;
		}

		return false;
	}

	this.remove = function(in_key)
	{
		var tmp_value;
		if (typeof(this.elementData[in_key]) != 'undefined')
		{
			this.length--;
			tmp_value = this.elementData[in_key];
			delete this.elementData[in_key];
		}

		return tmp_value;
	}

	this.size = function()
	{
		return this.length;
	}

	this.has = function(in_key)
	{
		return typeof(this.elementData[in_key]) != 'undefined';
	}
}

// }}}
// {{{ domLib_isDescendantOf()

function domLib_isDescendantOf(in_object, in_ancestor)
{
	if (in_object == in_ancestor)
	{
		return true;
	}

	while (in_object != document.documentElement)
	{
		try
		{
			if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor)
			{
				return true;
			}
			else if ((tmp_object = in_object.parentNode) == in_ancestor)
			{
				return true;
			}
			else
			{
				in_object = tmp_object;
			}
		}
		// in case we get some wierd error, just assume we haven't gone out yet
		catch(e)
		{
			return true;
		}
	}

	return false;
}

// }}}
// {{{ domLib_detectCollisions()

// :WARNING: hideList is being used as an object property and is not a string
function domLib_detectCollisions(in_object, in_recover)
{
	// no need to do anything for opera
	if (domLib_isOpera)
	{
		return;
	}

	if (typeof(domLib_selectElements) == 'undefined')
	{
		domLib_selectElements = document.getElementsByTagName('select');
	}

	// if we don't have a tip, then unhide selects
	if (in_recover)
	{
		for (var cnt = 0; cnt < domLib_selectElements.length; cnt++)
		{
			var thisSelect = domLib_selectElements[cnt];

			if (!thisSelect.hideList)
			{
				thisSelect.hideList = new Hash();
			}

			// if this is mozilla and it is a regular select or it is multiple and the
			// size is not set, then we don't need to unhide
			if (domLib_isGecko && (!thisSelect.multiple || thisSelect.size < 0))
			{
				continue;
			}

			thisSelect.hideList.remove(in_object.id);
			if (!thisSelect.hideList.length)
			{
				domLib_selectElements[cnt].style.visibility = 'visible';
			}
		}

		return;
	}

	// okay, we have a tip, so hunt and destroy
	var objectOffsets = domLib_getOffsets(in_object);

	for (var cnt = 0; cnt < domLib_selectElements.length; cnt++)
	{
		var thisSelect = domLib_selectElements[cnt];

		// if this is mozilla and not a multiple-select or the multiple select size
		// is not defined, then continue since mozilla does not have an issue
		if (domLib_isGecko && (!thisSelect.multiple || thisSelect.size < 0))
		{
			continue;
		}

		// if the select is in the tip, then skip it
		// :WARNING: is this too costly?
		if (domLib_isDescendantOf(thisSelect, in_object))
		{
			continue;
		}

		if (!thisSelect.hideList)
		{
			thisSelect.hideList = new Hash();
		}

		var selectOffsets = domLib_getOffsets(thisSelect); 
		// for mozilla we only have to worry about the scrollbar itself
		if (domLib_isGecko)
		{
			selectOffsets.set('left', selectOffsets.get('left') + thisSelect.offsetWidth - domLib_scrollbarWidth);
			selectOffsets.set('leftCenter', selectOffsets.get('left') + domLib_scrollbarWidth/2);
			selectOffsets.set('radius', Math.max(thisSelect.offsetHeight, domLib_scrollbarWidth/2));
		}

		var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2));
		var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius');
		// the encompassing circles are overlapping, get in for a closer look
		if (center2centerDistance < radiusSum)
		{
			// tip is left of select
			if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) ||
			// tip is right of select
				(objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) ||
			// tip is above select
				(objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) ||
			// tip is below select
				(objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom')))
			{
				thisSelect.hideList.remove(in_object.id);
				if (!thisSelect.hideList.length)
				{
					thisSelect.style.visibility = 'visible';
				}
			}
			else
			{
				thisSelect.hideList.set(in_object.id, true);
				thisSelect.style.visibility = 'hidden';
			}
		}
	}
}

// }}}
// {{{ domLib_getOffsets()

function domLib_getOffsets(in_object)
{
	var originalObject = in_object;
	var originalWidth = in_object.offsetWidth;
	var originalHeight = in_object.offsetHeight;
	var offsetLeft = 0;
	var offsetTop = 0;

	while (in_object)
	{
		offsetLeft += in_object.offsetLeft;
		offsetTop += in_object.offsetTop;
		in_object = in_object.offsetParent;
	}

	return new Hash(
		'left',			offsetLeft,
		'top',			offsetTop,
		'right',		offsetLeft + originalWidth,
		'bottom',		offsetTop + originalHeight,
		'leftCenter',	offsetLeft + originalWidth/2,
		'topCenter',	offsetTop + originalHeight/2,
		'radius',		Math.max(originalWidth, originalHeight) 
	);
}

// }}}
// {{{ domLib_setTimeout()

function domLib_setTimeout(in_function, in_timeout, in_args)
{
	if (typeof(in_args) == 'undefined')
	{
		in_args = [];
	}

	if (in_timeout == 0)
	{
		in_function(in_args);
		return 0;
	}

	// must make a copy of the arguments so that we release the reference
	if (typeof(in_args.clone) != 'function')
	{
		in_args.clone = Object.clone;
	}

	var args = in_args.clone();

	if (domLib_canTimeout)
	{
		return setTimeout(function() { in_function(args); }, in_timeout);
	}
	else
	{
		var id = domLib_timeoutStateId++;
		var data = new Hash();
		data.set('function', in_function);
		data.set('args', args);
		domLib_timeoutStates.set(id, data);

		data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout));
		return id;
	}
}

// }}}
// {{{ domLib_clearTimeout()

function domLib_clearTimeout(in_id)
{
	if (domLib_canTimeout)
	{
		clearTimeout(in_id);
	}
	else
	{
		if (domLib_timeoutStates.has(in_id))
		{
			clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId'))
			domLib_timeoutStates.remove(in_id);
		}
	}
}

// }}}
// {{{ domLib_getEventPosition()

function domLib_getEventPosition(in_eventObj)
{
	var eventPosition = new Hash();
	if (domLib_isKonq)
	{
		eventPosition.set('x', in_eventObj.x);
		eventPosition.set('y', in_eventObj.y);
	}
	else if (domLib_isIE)
	{
		if (document.documentElement.clientHeight)
		{
			eventPosition.set('x', in_eventObj.clientX + document.documentElement.scrollLeft);
			eventPosition.set('y', in_eventObj.clientY + document.documentElement.scrollTop);
		}
		// :WARNING: consider case where document.body doesn't yet exist for IE
		else
		{
			eventPosition.set('x', in_eventObj.clientX + document.body.scrollLeft);
			eventPosition.set('y', in_eventObj.clientY + document.body.scrollTop);
		}
	}
	else
	{
		eventPosition.set('x', in_eventObj.pageX);
		eventPosition.set('y', in_eventObj.pageY);
	}

	return eventPosition;
}

// }}}
// {{{ makeTrue()

function makeTrue()
{
	return true;
}

// }}}
// {{{ makeFalse()

function makeFalse()
{
	return false;
}

// }}}
// {{{ docs <-- this is a VIM (text editor) text fold

/**
 * DOM Tooltip 0.6.0
 *
 * Summary:
 * Allows developers to add custom tooltips to the webpages.  Tooltips are
 * controlled through three style class definitions.  This library also detects
 * collisions against native widgets in the browser that cannot handle the
 * zIndex property.  But this library is even more than that...with all the
 * features it has, it has the potential to replace the need for popups
 * entirely as it can embed just about any html inside the tooltip, leading to
 * the possibility of having whole forms or iframes right inside the tip...even
 * other programs!!!
 *
 * Maintainer: Dan Allen <dan@mojavelinux.com>
 *
 * License: LGPL
 * However, if you use this library, you become an official bug reporter :)
 * Please post to my forum where you use it so that I get a chance to see my
 * baby in action.  If you are doing this for commercial work perhaps you could
 * send me a few Starbucks Coffee gift dollars to encourage future developement
 * (NOT REQUIRED).  E-mail me for my address.
 *
 * Homepage: http://www.mojavelinux.com/forum/viewtopic.php?t=127
 *
 * Freshmeat Project: http://freshmeat.net/projects/domtt/?topic_id=92
 *
 * Updated: 2003/02/14
 *
 * Supported Browsers: Mozilla (Gecko), IE 5.0+, Konqueror, Opera 7
 *
 * Usage:
 * All this is required is to put the function call in the event tag for an
 * html element. The status option (for changing the status bar text) is only
 * available through all events, but when used with 'onmouseover' you have to
 * return true so that the browser does not display the link text in the status
 * bar.  To do this, wrap the domTT_activate call in the function makeTrue(),
 * which will just return true, and then prefix it with a 'return'
 *
 * Example: <a href="index.html" onmouseover="return makeTrue(domTT_activate(this, event, 'caption', 'Help', 'content', 'This is a link with a tooltip', 'statusText', 'Link', 'trial', true));">click me</a>
 *
 * Options:
 * Each option is followed by the value for that option.  The variable event
 * must be the first parameter, as shown above.  The options avaiable are:
 *
 *	predefined (optional, must be first item if used, loads default values)
 *	caption (optional)
 *	content (required)
 *	closeLink (optional, defaults to domTT_closeLink global setting variable)
 *	statusText (optional, if used with mouseover must wrap call in 'return domTT_true()')
 *	type (optional, defaults to 'greasy' but can be 'sticky' or 'velcro')
 *	classPrefix (optional, defaults to 'domTT', for changing style class)
 *	delay (optional, defaults to global delay value domTT_activateDelay)
 *	parent (optional, defaults to document.body)
 *	closeAction (optional, defaults to global domTT_closeAction, either 'hide' or 'remove')
 *	trail (optional, follow the mouse cursor while tooltip is active)
**/

// }}}
// {{{ Settings (editable)

/**
 * Settings (editable)
 */
var domTT_offsetX = 0;
var domTT_offsetY = 2;
var domTT_direction = 'southeast';
var domTT_mouseHeight = 20;
var domTT_closeLink = 'X';
var domTT_screenEdgePadding = 5;
var domTT_activateDelay = 500;
var domTT_maxWidth = 300;
var domTT_useGlobalMousePosition = true;
var domTT_classPrefix = 'domTT';
var domTT_fade = 'neither';
var domTT_lifetime = 0;
var domTT_grid = 0;
var domTT_closeAction = 'hide';
var domTT_dragStickyTips;
if (typeof(domTT_dragStickyTips) == 'undefined')
{
	var domTT_dragStickyTips = false;
}

// }}}
// {{{ Global constants

/**
 * Global constants (DO NOT EDIT)
 */
var domTT_predefined = new Hash();
var domTT_tooltips = new Hash();

// }}}
// {{{ document.onmousemove

if (domLib_useLibrary && domTT_useGlobalMousePosition)
{
	var domTT_mousePosition = new Hash();
	document.onmousemove = function(in_event)
	{
		if (typeof(in_event) == 'undefined')
		{
			in_event = event;
		}

		domTT_mousePosition = domLib_getEventPosition(in_event);
		if (domTT_dragStickyTips && domTT_dragMouseDown)
		{
			domTT_dragUpdate(in_event);
		}
	}
}

// }}}
// {{{ domTT_activate()

function domTT_activate(in_this, in_event)
{
	if (!domLib_useLibrary) { return false; }

	// make sure in_event is set (for IE, some cases we have to use window.event)
	if (typeof(in_event) == 'undefined')
	{
		in_event = window.event;
	}

	var owner = document.body;
	// we have an active event so get the owner
	if (in_event.type.match(/key|mouse|click|contextmenu/i))
	{
		// make sure we have nothing higher than the body element
		if (in_this.nodeType && in_this.nodeType != 9)
		{
			var owner = in_this;
		}
	}
	// non active event
	else
	{
		if (!(owner = document.getElementById(in_this)))
		{
			owner = document.body.appendChild(document.createElement('div'));
			owner.style.display = 'none';
			owner.id = in_this;
		}
	}

	// make sure the owner has a unique id
	if (!owner.id)
	{
		owner.id = '__autoId' + domLib_autoId++;
	}

	var tooltip = domTT_tooltips.get(owner.id);
	if (tooltip)
	{
		if (tooltip.get('eventType') != in_event.type)
		{
			if (tooltip.get('type') == 'greasy')
			{
				tooltip.set('closeAction', 'destroy');
				domTT_deactivate(owner.id);
			}
			else if (tooltip.get('status') != 'inactive')
			{
				return owner.id;
			}
		}
		else
		{
			if (tooltip.get('status') == 'inactive')
			{
				tooltip.set('status', 'pending');
				tooltip.set('activateTimeout', domLib_setTimeout(function(argv) { 
					domTT_show(argv[0], argv[1]); 
				}, tooltip.get('delay'), [owner.id, in_event]));

				return owner.id;
			}
			// either pending or active, let it be
			else
			{
				return owner.id;
			}
		}
	}

	// setup the default options hash
	var options = new Hash(
		'caption',		'',
		'content',		'',
		'closeLink',	domTT_closeLink,
		'parent',		document.body,
		'position',		'absolute',
		'type',			'greasy',
		'direction',	domTT_direction,
		'delay',		domTT_activateDelay,
		'classPrefix',	domTT_classPrefix,
		'closeAction',	domTT_closeAction,
		'lifetime',		domTT_lifetime,
		'grid',			domTT_grid,
		'fade',			domTT_fade,
		'trail',		true
	);

	// load in the options from the function call
	for (var i = 2; i < arguments.length; i += 2)
	{
		// load in predefined
		if (arguments[i] == 'predefined')
		{
			var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
			for (var j in predefinedOptions.elementData)
			{
				options.set(j, predefinedOptions.get(j));
			}
		}
		// set option
		else
		{
			options.set(arguments[i], arguments[i + 1]);
		}
	}

	options.set('eventType', in_event.type);

	// immediately set the status text if provided
	if (options.has('statusText')) {
		try { window.status = options.get('statusText'); } catch(e) {}
	}

	// if we didn't give content...assume we just wanted to change the status and return
	if (!options.has('content') || options.get('content') == '')
	{
		if (typeof(owner.onmouseout) != 'function')
		{
			owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
		}

		return owner.id;
	}

	options.set('owner', owner);
	options.set('id', '[domTT]' + owner.id);
	domTT_create(options);
	// determine the show delay
	options.set('delay', in_event.type.match(/click|mousedown|contextmenu/i) ? 0 : parseInt(options.get('delay')));
	domTT_tooltips.set(owner.id, options);
	options.set('status', 'pending');
	options.set('activateTimeout', domLib_setTimeout(function(argv) { 
		domTT_show(argv[0], argv[1]); 
	}, options.get('delay'), [owner.id, in_event]));

	return owner.id;
}

// }}}
// {{{ domTT_create()

function domTT_create(in_options)
{
	var owner = in_options.get('owner');

	// create the tooltip and hide it
	var tipObj = document.body.appendChild(document.createElement('div'));
	tipObj.style.position = 'absolute';
	tipObj.style.left = '0px';
	tipObj.style.top = '0px';
	tipObj.style.visibility = 'hidden';
	tipObj.id = in_options.get('id');
	tipObj.className = in_options.get('classPrefix');

	if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
	{

		// layout the tip with a hidden formatting table
		var tipLayoutTable = tipObj.appendChild(document.createElement('table'));
		tipLayoutTable.style.borderCollapse = 'collapse';
		if (domLib_isKonq)
		{
			tipLayoutTable.cellSpacing = 0;
		}

		var tipLayoutTbody = tipLayoutTable.appendChild(document.createElement('tbody'));

		var numCaptionCells = 0;
		var captionRow = tipLayoutTbody.appendChild(document.createElement('tr'));
		var captionCell = captionRow.appendChild(document.createElement('td'));
		captionCell.style.padding = '0px';
		var caption = captionCell.appendChild(document.createElement('div'));
		caption.className = in_options.get('classPrefix') + 'Caption';
		caption.style.height = '100%';
		caption.appendChild(document.createTextNode(in_options.get('caption')));

		if (in_options.get('type') == 'sticky')
		{
			var numCaptionCells = 2;
			var closeLinkCell = captionRow.appendChild(document.createElement('td'));
			closeLinkCell.style.padding = '0px';
			var closeLink = closeLinkCell.appendChild(document.createElement('div'));
			closeLink.className = in_options.get('classPrefix') + 'Caption';
			closeLink.style.height = '100%';
			closeLink.style.textAlign = 'right';
			closeLink.style.cursor = domLib_stylePointer;
			// merge the styles of the two cells
			closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
			closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
			closeLink.style.marginLeft = caption.style.marginRight = '0px';
			if (in_options.get('closeLink').nodeType)
			{
				closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
			}
			else
			{
				closeLink.innerHTML = in_options.get('closeLink');
			}

			closeLink.onclick = function() { domTT_deactivate(owner.id); };
			closeLink.onmousedown = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } in_event.cancelBubble = true; };
		}

		var contentRow = tipLayoutTbody.appendChild(document.createElement('tr'));
		var contentCell = contentRow.appendChild(document.createElement('td'));
		contentCell.style.padding = '0px';
		if (numCaptionCells)
		{
			if (domLib_isIE)
			{
				contentCell.colSpan = numCaptionCells;
			}
			else
			{
				contentCell.setAttribute('colspan', numCaptionCells);
			}
		}

		var content = contentCell.appendChild(document.createElement('div'));
		if (domLib_isIE50)
		{
			content.style.height = '100%';
		}
	}
	else
	{
		var content = tipObj.appendChild(document.createElement('div'));
	}

	content.className = in_options.get('classPrefix') + 'Content';

	if (in_options.get('content').nodeType)
	{
		content.appendChild(in_options.get('content').cloneNode(1));
	}
	else
	{
		content.innerHTML = in_options.get('content');
	}

	// adjust the width if specified
	if (in_options.has('width'))
	{
		tipObj.style.width = parseInt(in_options.get('width')) + 'px';
	}

	// check if we are overridding the maxWidth
	// if the browser supports maxWidth, the global setting will be ignored (assume stylesheet)
	var maxWidth = domTT_maxWidth;
	if (in_options.has('maxWidth'))
	{
		if ((maxWidth = in_options.get('maxWidth')) === false)
		{
			tipObj.style.maxWidth = domLib_styleNoMaxWidth;
		}
		else
		{
			maxWidth = parseInt(in_options.get('maxWidth'));
			tipObj.style.maxWidth = maxWidth + 'px';
		}
	}

	// :HACK: fix lack of maxWidth in CSS for Konq and IE
	if (maxWidth !== false && (domLib_isIE || domLib_isKonq) && tipObj.offsetWidth > maxWidth)
	{
		tipObj.style.width = maxWidth + 'px';
	}

	// tooltip floats
	if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
	{
		// determine the offset relative to the pointer
		switch (in_options.get('direction'))
		{
			case 'northeast':
				var offset_x = domTT_offsetX;
				var offset_y = 0 - tipObj.offsetHeight - domTT_offsetY;
			break;
			case 'northwest':
				var offset_x = 0 - tipObj.offsetWidth - domTT_offsetX;
				var offset_y = 0 - tipObj.offsetHeight - domTT_offsetY;
			break;
			case 'southwest':
				var offset_x = 0 - tipObj.offsetWidth - domTT_offsetX;
				var offset_y = domTT_mouseHeight + domTT_offsetY;
			break;
			case 'southeast':
				var offset_x = domTT_offsetX;
				var offset_y = domTT_mouseHeight + domTT_offsetY;
			break;
		}
	}
	// tooltip is fixed
	else
	{
		var offset_x = 0;
		var offset_y = 0;
		in_options.set('trail', false);
	}

	in_options.set('offsetX', offset_x);
	in_options.set('offsetY', offset_y);
	in_options.set('offsetWidth', tipObj.offsetWidth);
	in_options.set('offsetHeight', tipObj.offsetHeight);
	if (domLib_canFade && typeof(alphaAPI) == 'function')
	{
		if (in_options.get('fade') != 'neither')
		{
			var fadeHandler = new alphaAPI(tipObj, 50, 50, 100, 0, null, 10);
			fadeHandler.setAlpha(0);
			in_options.set('fadeHandler', fadeHandler);
		}
	}
	else
	{
		in_options.set('fade', 'neither');
	}

	// setup mouse events
	if (in_options.get('trail') && typeof(owner.onmousemove) != 'function')
	{
		owner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
	}

	if (typeof(owner.onmouseout) != 'function')
	{
		owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
	}

	if (in_options.get('type') == 'sticky')
	{
		if (in_options.get('position') == 'absolute' && domTT_dragStickyTips)
		{
			if (domLib_isIE)
			{
				captionRow.onselectstart = function() { return false; };
			}

			// setup drag
			captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event);  };
			captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
			captionRow.onmouseup = function() { domTT_dragStop(); };
		}
	}
	else if (in_options.get('type') == 'velcro')
	{
		tipObj.onmouseout = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj)) { domTT_deactivate(owner.id); }};
	}

	if (in_options.get('position') == 'relative')
	{
		tipObj.style.position = 'relative';
	}

	if (in_options.get('parent') != document.body)
	{
		in_options.get('parent').appendChild(tipObj);
	}

	in_options.set('node', tipObj);
	in_options.set('status', 'inactive');
}

// }}}
// {{{ domTT_show()

function domTT_show(in_ownerId, in_event)
{
	// should always find one since this call would be cancelled if tip was killed
	var tooltip = domTT_tooltips.get(in_ownerId);
	var status = tooltip.get('status');
	var tipObj = tooltip.get('node');

	if (tooltip.get('position') == 'absolute')
	{
		if (tooltip.has('x') && tooltip.has('y'))
		{
			var mouse_x = tooltip.get('x');
			var mouse_y = tooltip.get('y');
		}
		else if (!domTT_useGlobalMousePosition || status == 'active' || tooltip.get('delay') == 0)
		{
			var eventPosition = domLib_getEventPosition(in_event);
			var mouse_x = eventPosition.get('x');
			var mouse_y = eventPosition.get('y');
		}
		else
		{
			var mouse_x = domTT_mousePosition.get('x');
			var mouse_y = domTT_mousePosition.get('y');
		}

		// we are using a grid for updates
		if (tooltip.get('grid'))
		{
			// if this is not a mousemove event or it is a mousemove event on an active tip and
			// the movement is bigger than the grid
			if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouse_x) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouse_y) > tooltip.get('grid'))))
			{
				tooltip.set('lastX', mouse_x);
				tooltip.set('lastY', mouse_y);
			}
			// did not satisfy the grid movement requirement
			else
			{
				return false;
			}
		}

		var coordinates = {'x' : mouse_x + tooltip.get('offsetX'), 'y' : mouse_y + tooltip.get('offsetY')};
		coordinates = domTT_correctEdgeBleed(tooltip.get('offsetWidth'), tooltip.get('offsetHeight'), coordinates.x, coordinates.y, domTT_offsetX, domTT_offsetY, tooltip.get('type'));

		// update the position
		tipObj.style.left = coordinates.x + 'px';
		tipObj.style.top = coordinates.y + 'px';

		// increase the tip zIndex so it goes over previously shown tips
		tipObj.style.zIndex = domLib_zIndex++;
	}

	// if tip is not active, active it now and check for a fade in
	if (status == 'pending')
	{
		// unhide the tooltip
		tooltip.set('status', 'active');
		tipObj.style.display = '';
		tipObj.style.visibility = 'visible';

		var fade = tooltip.get('fade');
		if (fade != 'neither')
		{
			var fadeHandler = tooltip.get('fadeHandler');
			if (fade == 'out' || fade == 'both')
			{
				fadeHandler.pause();
				if (fade == 'out')
				{
					fadeHandler.reset();
				}
			}

			if (fade == 'in' || fade == 'both')
			{
				fadeHandler.fadeIn();
			}
		}

		if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
		{
			tooltip.set('lifetimeTimeout', domLib_setTimeout(function(argv) { domTT_deactivate(argv[0]); }, tooltip.get('lifetime'), [in_ownerId]));
		}
	}

	if (tooltip.get('position') == 'absolute')
	{
		domLib_detectCollisions(tipObj);
	}
}

// }}}
// {{{ domTT_deactivate()

function domTT_deactivate(in_ownerId)
{
	var tooltip = domTT_tooltips.get(in_ownerId);
	if (tooltip)
	{
		var status = tooltip.get('status');
		if (status == 'pending')
		{
			// cancel the creation of this tip if it is still pending
			domLib_clearTimeout(tooltip.get('activateTimeout'));
			tooltip.set('status', 'inactive');
		}
		else if (status == 'active')
		{
			if (tooltip.get('lifetime'))
			{
				domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
			}

			var tipObj = tooltip.get('node');
			if (tooltip.get('closeAction') == 'hide')
			{
				var fade = tooltip.get('fade');
				if (fade != 'neither')
				{
					var fadeHandler = tooltip.get('fadeHandler');
					if (fade == 'out' || fade == 'both')
					{
						fadeHandler.pause();
						fadeHandler.fadeOut();
					}
					else
					{
						fadeHandler.stop();
					}
				}
				else
				{
					tipObj.style.display = 'none';
				}
			}
			else
			{
				tooltip.get('parent').removeChild(tipObj);
				domTT_tooltips.remove(in_ownerId);
			}

			tooltip.set('status', 'inactive');
			// unhide all of the selects that are owned by this object
			domLib_detectCollisions(tipObj, true); 
		}
	}
}

// }}}
// {{{ domTT_mouseout()

function domTT_mouseout(in_owner, in_event)
{
	if (!domLib_useLibrary) { return false; }

	if (typeof(in_event) == 'undefined')
	{
		in_event = event;
	}

	var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner);
	var tooltip = domTT_tooltips.get(in_owner.id);
	if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
	{
		// deactivate tip if exists and we moved away from the owner
		if (!toChild)
		{
			domTT_deactivate(in_owner.id);
		}
	}
	else if (!toChild)
	{
		try { window.status = window.defaultStatus; } catch(e) {}
	}
}

// }}}
// {{{ domTT_mousemove()

function domTT_mousemove(in_owner, in_event)
{
	if (!domLib_useLibrary) { return false; }

	if (typeof(in_event) == 'undefined')
	{
		in_event = event;
	}

	var tooltip = domTT_tooltips.get(in_owner.id);
	if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
	{
		domTT_show(in_owner.id, in_event);
	}
}

// }}}
// {{{ domTT_addPredefined()

function domTT_addPredefined(in_id)
{
	var options = new Hash();
	for (var i = 1; i < arguments.length; i += 2)
	{
		options.set(arguments[i], arguments[i + 1]);
	}

	domTT_predefined.set(in_id, options);
}

// }}}
// {{{ domTT_correctEdgeBleed()

function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_type)
{
	var bleedRight;
	var bleedBottom;
	// for IE in compliance mode, maybe others
	if (document.documentElement.clientHeight)
	{
		var pageHeight = document.documentElement.clientHeight;
		var pageWidth = document.documentElement.clientWidth;
		var pageYOffset = document.documentElement.scrollTop;
		var pageXOffset = document.documentElement.scrollLeft;
	}
	else
	{
		var pageWidth = document.body.clientWidth;
		var pageYOffset = window.pageYOffset;
		var pageXOffset = window.pageXOffset;
		if (domLib_isKonq)
		{
			var pageHeight = window.innerHeight;
		}
		else
		{
			var pageHeight = document.body.clientHeight;
		}
	}

	// we are bleeding off the right, move tip over to stay on page
	if ((bleedRight = (in_x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
	{
		in_x -= bleedRight;
	}

	// we are bleeding to the left, move tip over to stay on page
	// we don't want an 'else if' here, because if it doesn't fit we will bleed off the right
	if ((in_x - pageXOffset) < domTT_screenEdgePadding)
	{
		in_x = domTT_screenEdgePadding + pageXOffset;
	}

	// ** top/bottom corrections depends on type, because we can't end up with the mouse over
	// the tip if this is a greasy **
	// if we are bleeding off the bottom, flip to north
	if ((bleedBottom = (in_y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0) {
		if (in_type == 'sticky') {
			in_y -= bleedBottom;
		}
		else
		{
			in_y -= in_height + (2 * in_offsetY) + domTT_mouseHeight;
		}
	}

	// if we are bleeding off the top, flip to south
	// we don't want an 'else if' here, because if we just can't fit it, bleed off the bottom
	if ((in_y - pageYOffset) < domTT_screenEdgePadding)
	{
		if (in_type == 'sticky')
		{
			in_y = domTT_screenEdgePadding + pageYOffset;
		}
		else
		{
			in_y += in_height + (2 * in_offsetY) + domTT_mouseHeight;
		}
	}

	return {'x' : in_x, 'y' : in_y};
}

// }}}
// {{{ domTT_isActive()

function domTT_isActive(in_ownerId)
{
	var tooltip = domTT_tooltips.get(in_ownerId);
	if (!tooltip || tooltip.get('status') != 'active')
	{
		return false;
	}
	else
	{
		return true;
	}
}

// }}}
var domTT_dragStickyTips = true;
var domTT_currentDragTarget;
var domTT_dragMouseDown;
var domTT_dragOffsetLeft;
var domTT_dragOffsetTop;
// {{{ domTT_dragStart()

function domTT_dragStart(in_this, in_event)
{
	if (typeof(in_event) == 'undefined')
	{
		in_event = event;
	}

	var eventButton = in_event[domLib_eventButton];
	if (eventButton != 1 && !domLib_isKonq)
	{
		return;
	}

	domTT_currentDragTarget = in_this;
	in_this.style.cursor = 'move';

	// upgrade our z-index
	in_this.style.zIndex = ++domLib_zIndex;

	var eventPosition = domLib_getEventPosition(in_event);

	var targetPosition = domLib_getOffsets(in_this);
	domTT_dragOffsetLeft = eventPosition.get('x') - targetPosition.get('left');
	domTT_dragOffsetTop = eventPosition.get('y') - targetPosition.get('top');
	domTT_dragMouseDown = true;
}

// }}}
// {{{ domTT_dragUpdate()

function domTT_dragUpdate(in_event)
{
	if (domTT_dragMouseDown)
	{
		if (domLib_isGecko)
		{
			window.getSelection().removeAllRanges()
		}

		if (domTT_useGlobalMousePosition)
		{
			var eventPosition = domTT_mousePosition;
		}
		else
		{
			if (typeof(in_event) == 'undefined')
			{
				in_event = event;
			}

			var eventPosition = domLib_getEventPosition(in_event);
		}

		domTT_currentDragTarget.style.left = (eventPosition.get('x') - domTT_dragOffsetLeft) + 'px';
		domTT_currentDragTarget.style.top = (eventPosition.get('y') - domTT_dragOffsetTop) + 'px';

		// update the collision detection
		domLib_detectCollisions(domTT_currentDragTarget);
	}
}

// }}}
// {{{ domTT_dragStop()

function domTT_dragStop()
{
	if (domTT_dragMouseDown) {
		domTT_dragMouseDown = false; 
		domTT_currentDragTarget.style.cursor = 'default';
		domTT_currentDragTarget = null;
		if (domLib_isGecko)
		{
			window.getSelection().removeAllRanges()
		}
	}
}

// }}}
