// CodeThatSDK - JavaScript SDK
// Version: 2.2.4 (11.19.05.1)
// Copyright (c) 2003-05 by CodeThat.Com
// http://www.codethat.com/

function Undef (o) { return typeof(o) == 'undefined' || o === '' || o == null }
function Def (o) { return !Undef(o) }
function Und (o) { return typeof(o) == 'undefined' }
function pI (s) { return parseInt(s) }
function pB (v, d) { return Und(v) ? d : v && v != 'false' } //parseBool from string with default
function dw (s) { document.write(s) }

if (!Array.prototype.push)
{ //define push for arrays

Array.prototype.push = function () {
	var i, a = arguments;
	for (i=0; i<a.length;)
		this[this.length] = a[i++]
};

}

/*
Object that represents the user-agent abilities
and partially the user-agent name/version.
*/
function UA () {
	var t = this, nv = navigator, n = nv.userAgent.toLowerCase();
	t.win = n.indexOf('win') >= 0;
	t.mac = n.indexOf('mac') >= 0;
	t.DOM = document.getElementById ? true : false; //DOM1+ browser (MSIE 5+, Gecko-driven, Opera 5+, KHTML-driven)
	t.dynDOM = document.createElement && document.addEventListener; //advanced DOM browser (Gecko-driven, Opera7, KHTML-driven)
	t.khtml = nv.vendor == 'KDE';
//	this.opera = t.opera5 = window.opera && t.DOM; //Opera 5+
//	t.opera6 = t.opera && window.print; //Opera 6+
	var idx = n.indexOf('opera');
	t.opera = idx != -1;
	if (t.opera) {
		t.vers = parseFloat(n.substr(idx+6));
		t.major = Math.floor(t.vers);
		t.opera5 = t.major == 5; //Opera 5
                t.opera6 = t.major == 6; //Opera 6
		t.opera7 = t.major == 7; //Opera 7
		t.opera7up = t.vers >= 7; //Opera 7+
	}
	t.oldOpera = t.opera5 || t.opera6; //only supported old versions
	idx = n.indexOf('msie');
	if (idx >= 0 && !t.opera && !t.khtml) {
		t.vers = parseFloat(n.substr(idx+5));
		t.ie3down = t.vers < 4;
		t.ie = t.ie4up = document.all && document.all.item && !t.ie3down; //MSIE 4+
		t.ie5up = t.ie && t.DOM; //MSIE 5+
		t.ie55up = t.ie && t.vers >= 5.5;
		t.ie6up = t.ie && t.vers >= 6
	}
	t.cm = document.compatMode;
	t.css1cm = t.cm == 'CSS1Compat';
//	t.nn4 = document.layers; //may cause errors in Netscape 4.*
	t.nn4 = nv.appName == "Netscape" && !t.DOM && !t.opera;
	if (t.nn4)
		t.vers = parseFloat(nv.appVersion);
	t.moz = t.nn6up = t.gecko = n.indexOf('gecko') != -1; //Mozilla or Netscape 6+
	if (t.gecko)
		t.vers = parseFloat(n.substr(n.indexOf('rv:')+3));
	t.nn7up = t.gecko && t.vers > 1;
	t.hj = n.indexOf('hotjava') != -1;
	t.aol = n.indexOf('aol') != -1;
	t.aol4up = t.aol && t.ie4up;
	t.major = Math.floor(t.vers); //major browser version
	t.old = t.oldOpera || t.nn4;  //old but supported browsers
	t.supp = t.supported = t.old || t.opera7up || t.ie || t.moz || t.DOM
}

var ua = new UA();

/*
CEvent
The constructor function that creates an object with
main event properties
Parameters:
	e	: event object
*/
function CEvent (e) {
	var t = this, d = document;
	t._e = e;
	t.x = ua.nn4 || ua.moz ? e.pageX
		: ua.oldOpera ? e.clientX
		: e.clientX + (d && d.body ? d.body.scrollLeft : 0);
	t.y = ua.nn4 || ua.moz ? e.pageY
		: ua.oldOpera ? e.clientY
		: e.clientY + (d && d.body ? d.body.scrollTop : 0);
	t.offsetX = ua.nn4 || ua.moz ? e.layerX : e.offsetX;
	t.offsetY = ua.nn4 || ua.moz ? e.layerY : e.offsetY;
	t.screenX = e.screenX;
	t.screenY = e.screenY;
	t.target = ua.ie ? e.srcElement : e.target;
	t.key = ua.nn4 || ua.moz ? e.which : e.keyCode;
	t.alt = ua.nn4 ? e.modifiers & Event.ALT_MASK : e.altKey;
	t.ctrl = ua.nn4 ? e.modifiers & Event.CONTROL_MASK : e.ctrlKey;
	t.shift = ua.nn4 ? e.modifiers & Event.SHIFT_MASK : e.shiftKey;
	t.spec = t.alt || t.ctrl || t.shift;
	var b = ua.nn4 || ua.moz ? e.which : e.button;
	t.b_left = b == 1;
	t.b_mid = ua.nn4 || ua.moz ? b == 2 : b == 4;
	t.b_right = ua.nn4 || ua.moz ? b == 3 : b == 2
}

/*
CCodeThat
constructor function that creates main CodeThat object
Object properties:
	_id	: id to identify the object globally
	_c	: internal count for id creation
*/
function CCodeThat(id) {
	this._id = id;
	this._c = 0;
	this.pre = {}; //list of preloaded images
	this.sz = []; //list of onload handlers
	this.ld = []; //list of onresize handlers
}

{

var CTp = CCodeThat.prototype;
/*
Function findLayer
Finds and returns the LAYER/DIV object by name or name/parent pair
Parameters
	name	: the name of the layer to find
	parent	: the parent layer object (important for NN)
Returns		: reference to the layer object
*/
CTp.findLayer = function(name, parent) {
	return this.findElement(name, parent)
};

/*
Function findElement
Finds and returns the object by name or name/parent pair
Parameters
	name	: the name of the object to find
	parent	: the parent layer object (important for NN)
Returns		: reference to the layer object
*/
CTp.findElement = function (name, parent) {
	if (ua.DOM)
		return document.getElementById(name);
	else if (ua.ie4up)		
		return document.all[name];
	else {
		var set = Undef(parent) ? document : parent.document;
		if (Undef(set[name]))
		{
			var i, el, len = set.layers.length;
			if (len == 0) return
			else {
				for (i=0; i<len; i++)
				{
					el = this.findElement(name, set.layers[i]);
					if (Def(el))
						return el;
				}
			}
		} else return set[name];
	}
};

CTp.use = function (mod) {
	dw('<script language="javascript" type="text/javascript" src="'+ (this._path || '') + mod +'"><\/script>')
};

CTp.path = function (p) { this._path = p };



/*
Function regEventHandler
Composes the event handler and then calls "registerHandler"
Parameters:
	e	: string that represents an event ("click", "mousemove", "dblclick", "mouseover" etc.)
	h	: reference to the function that handles the event or the code string
		  when called, the function is passed the instance of Event as a parameter
		  the code string can use either native event objects or instance of Event
	o	: the object to register the handler for (if omitted, the document object is used)
Returns:
	the event handler constructed
*/

CTp.regEventHandler = function (e, h, obj) {
	if (Undef(obj)) obj = document;
	e = e.toLowerCase();
	if (ua.nn4) {
		var name = e.toUpperCase();
		obj.captureEvents(Event[name]);
	}
	var f = typeof(h) == "function" ?
			function (e) { var ev = ua.ie ? window.event : e; if (Def(ev)) ev = new CEvent(ev); return h(ev) } :
			typeof(h) == "string" ?
				new Function("e", "var ev=ua.ie?window.event:e;if (Def(ev)) ev=new CEvent(ev);"+h) :
				null;
	obj["on"+e] = f
};

CTp.clearEventHandler = function (e, obj) {
	if (Undef(obj)) obj = document;
	e = e.toLowerCase();
	if (ua.nn4) {
		var name = e.toUpperCase();
		obj.releaseEvents(Event[name]);
	}
	obj["on"+e] = null
};

/*
Function setResizeHandler
sets the resize handler
Parameters:
	h	: function object, the resize event handler, when called,
			the new size of the window is passed to it as (x,y)
	b	: boolean that specifies whether to set the onload event
			(intended to properly set the resize handler for old Operas),
			if true, the onload event is NOT set, and the resize handler
			begins to work instantly
*/

CTp.setResizeHandler = CTp.setOnResize = function (h, b) {
	var s = this.sz, id = this._id;
	if (!s.length) {
		if (ua.oldOpera) {
			var _h = new Function(id+".saveWinSize();"+id+".checkSize()");
			b ? _h() : this.setOnLoad(_h)
		} else {
			s[0] = window.onresize;
			window.onresize = new Function(id + '.onresize()')
		}
	}
	s.push(h)
};

CTp.setOnLoad = function (h) {
	var l = this.ld;
	if (!l.length) {
		l[0] = window.onload;
		window.onload = new Function(this._id+".onload()");
	}
	l.push(h)
};

CTp.checkSize = function () {
	var t = this;
	if (t.getWinHeight() != t._WH || t.getWinWidth() != t._WW) {
		t.saveWinSize();
		t.onresize()
	}
	t._resTO = setTimeout(t._id+'.checkSize()', 1500)
};

CTp.call = function (a) {
	for (var i=0;i<a.length;i++)
		if (typeof a[i] == 'function') a[i]()
};

CTp.onload = function () {
	this.call(this.ld)
};

CTp.onresize = function () {
	this.call(this.sz)
};

CTp.saveWinSize = function () {
	this._WH = this.getWinHeight();
	this._WW = this.getWinWidth()
};

CTp.getWinHeight = function () {
	var d = document;
	return ua.ie4up ?
			ua.css1cm ? d.documentElement.clientHeight : d.body.clientHeight
			: self.innerHeight
};
CTp.getWinWidth = function () {
	var d = document;
	return ua.ie4up ?
			ua.css1cm ? d.documentElement.clientWidth : d.body.clientWidth
			: self.innerWidth
};

CTp.getScrollX = function () { return ua.ie4up ? document.body.scrollLeft : self.pageXOffset };
CTp.getScrollY = function () { return ua.ie4up ? document.body.scrollTop : self.pageYOffset };



/*
Function cancelEvent
Cancels the event
Parameters:
	e	: event object
*/
CTp.cancelEvent = function (e) {
	if (ua.nn4) return;
	if (!Und(e.stopPropagation))
		e.stopPropagation()
	else
		e.cancelBubble = true;
	e.returnValue = false
};

CTp.newID = function () {
	return 'CodeThat'+this._c++
};

CTp.readCookie = function (name) {
	var str = document.cookie;
	var set = str.split (';');
	var sz = set.length;
	var x, pcs;
	var val = "";

	for (x = 0; x < sz && val == ""; x++) {
		pcs = set[x].split ('=');
		if (pcs[0].substring (0,1) == ' ')
			pcs[0] = pcs[0].substring (1, pcs[0].length);
		if (pcs[0] == name)
			val = pcs[1]
	}
	return val
};

CTp.writeCookie = function (name, val, exp) {
	var expDate = new Date();
	if(exp) {
		expDate.setTime (expDate.getTime() + exp);
		document.cookie = name + "=" + val + "; expires=" + expDate.toGMTString();
	} else {
		document.cookie = name + "=" + val;
	}
};

CTp.preload = function () {
	var i, im = [], a = arguments;
	for(i=0; i<a.length; i++) {
		if (Undef(a[i]))
			im[i] = null
		else if (Def(this.pre[a[i]]))
			im[i] = this.pre[a[i]]
		else {
			im[i] = new Image();
			im[i].src = a[i];
			this.pre[a[i]] = im[i]
		}
	}
	return a.length == 1 ? im[0] : im
}


}
//create global window.CodeThat object
var CodeThat = new CCodeThat('CodeThat');
function CT_el (l) {
	if (typeof l == 'string')
		l = CodeThat.findElement(l);
	var st = ua.nn4 ? l : l.style;
	return [l, st]
}

function CT_HTML (l, HTML) {
	l = CT_el(l);
	if (ua.nn4) {
		var d = l[0].document;
		d.open();
		d.write(HTML);
		d.close()
	} else if (!ua.oldOpera)
		l[0].innerHTML = HTML;
}

function CT_css (l, css) {
	if (!ua.oldOpera && !ua.nn4) {
		l = CT_el(l)
		l[0].className = css
	}
}

function CT_getWidth (l) {
	l = CT_el(l);
	var w;
	if (ua.nn4)
//		w = l[0].document.width
		w = l[0].clip.width
	else
		w = ua.oldOpera ? l[1].pixelWidth : l[0].offsetWidth;
	return w
}

function CT_getHeight (l) {
	l = CT_el(l);
	var h;
	if (ua.nn4)
//		h = l[0].document.height
		h = l[0].clip.height
	else
		h = ua.oldOpera ? l[1].pixelHeight : l[0].offsetHeight;
	return h
}

function CT_getTop (l) { //relative to the parent element
	l = CT_el(l);
	return ua.nn4 ? l[0].y : l[0].offsetTop
}

function CT_getLeft (l) { //relative to the parent element
	l = CT_el(l);
	return ua.nn4 ? l[0].x : l[0].offsetLeft
}

function CT_getAbsTop (l) { //relative to the main document
	l = CT_el(l);
	if (ua.nn4) return l[0].pageY
	else {
		var o = l[0], y = CT_getTop(l[0]);
		while (Def(o = o.offsetParent))
			y += o.offsetTop
		return y
	}
}

function CT_getAbsLeft (l) { //relative to the main document
	l = CT_el(l);
	if (ua.nn4) return l[0].pageX
	else {
		var o = l[0], l = CT_getLeft(l[0]);
		while (Def(o = o.offsetParent))
			l += o.offsetLeft;
		return l
	}
}

function CT_lrStyle (w, h, t, l, a, v, bgc, bgi, cl, o, d, st, z, al) {
	return 	'position:'+(a ? 'absolute' : 'relative')+
		';overflow:'+(o || 'hidden') +
	 	';visibility:'+(v ? 'inherit' : 'hidden') +
		(Def(t) ? ";top:"+ t +"px" : "") +(Def(l) ? ";left:"+l+"px" : "") +
		(Def(w) ? ";width:"+ w +"px" : "") + (Def(h) ? ";height:"+ h +"px" : "") +
		(z ? ";z-index:" + z : "") +
		(bgc ? ";background-color:"+bgc : "") +
		(bgi ? ";background-image:url("+bgi+")" : "") +
		(cl ? ";clip:rect("+cl[0]+"px "+cl[1]+"px "+cl[2]+"px "+cl[3]+"px)" : "") +
		(d ? ";display:" + d : "") +
		";" + (st || '') +
		(Def(al) ? ua.ie55up ? ';filter:progid:DXImageTransform.Microsoft.Alpha(Opacity='+ al +')':
				(ua.gecko ? ';-moz-opacity:' : ';opacity:')+al/100:'')
}

function CT_lrSource (id, w, h, t, l, a, v, css, bgc, bgi, cl, o, d, st, z, al, ev, html) {
	//make layer source
	var src = '';
	if (ua.nn4) {
		if (Undef(cl) && Def(h) && Def(w) && (Undef(o) || o == 'hidden'))
			cl = [0, w, h, 0];
		if (st)
			src = "<style type=text/css>#"+id+"{"+st+"}</style>";
		src +=	(a ? '<' : '<i') + 'layer id='+ id + 
			(Def(t) ? ' top=' + t : "") + (Def(l) ? ' left='+ l : "") +
			(Def(w) ? ' width='+ w : "") +
			(z ? ' z-index='+ z : "") +
			' visibility=' + (v ? "inherit" : "hide") +
			(cl ? ' clip="'+ cl[3]+','+cl[0]+','+cl[1]+','+cl[2]+'"' : "") +
			(bgc ? ' bgcolor="' + bgc + '"' : "") +
			(bgi ? ' background="'+ bgi +'"' : "") //+
//			(st ? ' style="' + st + '"' : "")
	} else	src = '<div id="'+ id +'" style="' +
			CT_lrStyle(w, h, t, l, a, v, bgc, bgi, cl, o, d, st, z, al)
			+ '"';
	if (css)
		src += ' class="'+css+'"';
	//events
	if (Def(ev))
		for (var i=ev.length-1; i>=0; i-=2)
			src += ' on' + ev[i-1] + '="' + ev[i] + '"';
	return src + ">" + (html || '') + '</'+(ua.nn4 ? (a ? '' : 'i')+"layer>" : "div>")
}

/*
		0 - id,
		1 - width, 2 - height,
		3 - top, 4 - left, 5 - absolute,
		6 - visible,
		7 - css,
		8 - bgcolor, 9 - bgimg,
		10 - clip, //array [top, right, bottom, left]
		11 - overflow,
		12 - display, //not for NN4
		13 - style, //additional
		14 - z-index,
		15 - alpha, //for MSIE 5.5+ only
		16 - events, //array like ['click', 'return false', 'keypress', 'return true', ...]
		17 - html
		[, 18 - parent]
*/
function CT_createLayer (id, w, h, t, l, a, v, css, bgc, bgi, cl, o, d, st, z, al, ev, html, p) {
	var id = id || CodeThat.newID();
	var src = CT_lrSource(id, w, h, t, l, a, v, css, bgc, bgi, cl, o, d, st, z, al, ev, html);
	//create layer
	var parent = p || document.body;
	if (!CodeThat.loaded) //only on page-creation stage
		dw(src)
	else if (ua.ie)
		parent.insertAdjacentHTML("BeforeEnd", src)
	else if (ua.dynDOM) {
		var lr = document.createElement('DIV');
		lr.setAttribute('id', id);
		if (Def(css))
			lr.setAttribute('className', css);
		lr.setAttribute('style', CT_lrStyle(w, h, t, l, a, v, bgc, bgi, cl, o, d, st, z, al))
		lr.innerHTML = html;
		if (Def(ev))
			for (var i=ev.length-1; i>=0; i-=2)
				lr.addEventListener(ev[i-1], new Function(ev[i]), 0);
		parent.appendChild(lr)
	} else return;
	return id
}
function CT_clear (l) { CT_HTML(l, '') }

function CT_vis (l, v) {
	l = CT_el(l);
	l[1].visibility = v == 'i' ? "inherit" :
				v ? 
					ua.nn4 ? "show" : "visible" :
					ua.nn4 ? "hide" : "hidden"
}

function CT_inhvis (l, v) { CT_vis(l, v ? 'i': 0) }

function CT_show (l) { CT_vis(l, 1) }

function CT_hide (l) { CT_vis(l, 0) }

function CT_showAt (l, x, y) {
	l = CT_el(l);
	CT_moveTo(l[0], x, y);
	CT_show(l[0])
}

function CT_z (l, z) {
	l = CT_el(l);
	l[1].zIndex = z
}

function CT_setWidth (l, w) {
	l = CT_el(l);
	if (ua.nn4)
		l[0].resizeTo(w, CT_getHeight(l[0]));
	else if (ua.oldOpera) l[1].pixelWidth = w
	else l[1].width = w+"px"
}

function CT_setHeight (l, h) {
	l = CT_el(l);
	if (ua.nn4) l[0].resizeTo(CT_getWidth(l[0]), h)
	else if (ua.oldOpera) l[1].pixelHeight = h
	else l[1].height = h+"px"
};

function CT_resize (l, w, h) {
	l = CT_el(l);
	if (ua.nn4)
		l[0].resizeTo(w, h)
	else {
		CT_setHeight(l[0], h);
		CT_setWidth(l[0], w)
	}
}

function CT_setTop (l, y) {
	l = CT_el(l);
	if (ua.nn4) l[1].y = y
	else if (ua.oldOpera) l[1].pixelTop = y
	else l[1].top = y+"px"
}

function CT_setLeft (l, x) {
	l = CT_el(l);
	if (ua.nn4) l[1].x = x
	else if (ua.oldOpera) l[1].pixelLeft = x
	else l[1].left = x+"px"
}

function CT_moveTo (l, x, y) {
	l = CT_el(l);
	if (ua.nn4) l[0].moveTo(x,y)
	else {
		CT_setTop(l[0], y);
		CT_setLeft(l[0], x)
	}
}

function CT_moveRel (l, dx,dy) {
	l = CT_el(l);
	CT_moveTo(l[0], CT_getLeft(l[0])+dx, CT_getTop(l[0])+dy)
}

function CT_setBgColor (l, c) {
	l = CT_el(l);
	if (!ua.nn4 && !ua.oldOpera) l[1].backgroundColor = c
	else if (ua.nn4) l[1].bgColor = c
	else if (ua.opera) l[1].background = c
}

function CT_setBgImage (l, url) {
	l = CT_el(l);
	if (!ua.nn4 && !ua.oldOpera)
		l[1].backgroundImage = 'url('+url+')'
	else
		l[1].background.src = url
}

function CT_clip (l, x, y, w, h) {
	l = CT_el(l);
	if (ua.nn4) {
		var area = l[1].clip;
		area.top = y;
		area.left = x;
		area.width = w;
		area.height = h
	} else if (!ua.oldOpera)
		l[1].clip = 'rect('+y+'px '+(x+w)+'px '+(y+h)+'px '+x+'px)'
}

function CT_display (l, d) {
	l = CT_el(l);
	l[1].display = d
}

function CT_overflow (l, o) {
	l = CT_el(l);
	l[1].overflow = o
}

function CT_alpha (l, a) {
	if (ua.ie) {
		if (ua.ie55up) {
			l = CT_el(l);
			l[1].filter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity="'+a+'")'
		}
	} else l[1].opacity = al/100
}

function CT_getVis (l) {
	l = CT_el(l);
	var v = l[1].visibility;
	return Def(v) ? v == "show" || v == "visible" : v
}

function CT_getSize (l) {
	l = CT_el(l);
	return [CT_getWidth(l[0]), CT_getHeight(l[0])]
}

//call only if width property has not been set yet (quick solution)
function CT_getContentWidth (l) {
	l = CT_el(l);
	return	ua.nn4 ? l[0].document.width :
		ua.oldOpera ? l[1].pixelWidth :
		ua.ie && ua.win ? l[0].scrollWidth :
			l[0].offsetWidth
}

//call only if height property has not been set yet (quick solution)
function CT_getContentHeight (l) {
	l = CT_el(l);
	return 	ua.nn4 ? l[0].document.height :
		ua.oldOpera ? l[1].pixelHeight :
		ua.ie && ua.win ? l[0].scrollHeight :
			l[0].offsetHeight
}

function CT_getPos (l) {
	l = CT_el(l);
	return [CT_getLeft(l[0]), CT_getTop(l[0])]
}

function CT_getAbsPos (l) { //relative to the main document
	l = CT_el(l);
	return [CT_getAbsLeft(l[0]), CT_getAbsTop(l[0])]
}
/*
CLayer
The constructor function that creates a layer representation
Constructor parameters
1st way:	int, int	: width, height	: layer's width and height
2nd way:	string		: id		: layer's id (this must be a string),
						if the page has been loaded, it's used to find the layer in the document
3rd way:	w/o parameters	: 		: an empty layer object will be created
Returns		: none

Layer's properties:
_lr		: LAYER/DIV object
_st		: layer's style object
_id		: id that is used to find the layer in the document
_css		: CSS class ID
_w		: width of the layer (in pixels)
_h		: height of the layer (in pixels)
_t		: top-left corner Y coordinate
_l		: top-left corner X coordinate
_rel	(bool)	: if true, then relative positioning
_HTML		: layer's content
_cl	(array)	: clipping layer's area [top, right, bottom, left]
_bgC		: background color
_bgI		: background image
_z		: z-index
_al		: transparence level (0-100)
_v (bool)	: visibility
_ex (bool)	: specifies if a layer has been created in the document or not
_ev (array)	: specifies the list of assigned event handlers
_ov (string)	: overflow (hidden by default), if set to other than 'hidden', won't have any influence in NN4
_dsp (string)	: display, doesn't work in NN4
*/
function CLayer () {
	var a = arguments, t = this;
	t._ex = false;
	if (a.length == 2 && typeof(a[0]) == 'number') //width and height
	{
		t._w = parseInt(a[0]);
		t._h = parseInt(a[1])
	}
	else if (a.length >= 1 && typeof a[0] == 'string') //object's id
		t.assignLayer(CodeThat.findLayer(a[0], a[1]))
	t._id = t._id || CodeThat.newID();
	t._HTML = '';
	t._ev = [];
}

{

var CLp = CLayer.prototype;

CLp.assignLayer = function (oLr) {
	var t = this;
	if (Undef(oLr)) oLr = t._id;
	oLr = CT_el(oLr);
	t._lr = oLr[0];
	t._st = oLr[1];
	t._ex = 1;
	return t
};

CLp.setHTML = function (s) {
	this._HTML = s;
	if (this._ex)
		CT_HTML(this._lr, s)
};

CLp.appendHTML = function (s) { this.setHTML(this._HTML+s) };

CLp.clear = function () { this.setHTML('') };

CLp.setVisible = function (v) {
	this._v = v;
	if (this._ex)
		CT_vis(this._lr, v)
};

CLp.show = function () { this.setVisible(1) };

CLp.hide = function () { this.setVisible(0) };

CLp.showAt = function (x,y) { //layer must be created
	CT_showAt(this._lr, x, y)
};

CLp.setZIndex = function (z) {
	this._z = z;
	if (this._ex)
		CT_z(this._lr, z)
};

CLp.setWidth = function (w) {
	this._w = w;
	if (this._ex)
		CT_setWidth(this._lr, w);
};

CLp.setHeight = function (h) {
	this._h = h;
	if (this._ex)
		CT_setHeight(this._lr, h)
};

CLp.resize = CLp.setSize = function (w, h) {
	this.setHeight(h);
	this.setWidth(w)
};

CLp.setTop = function (y) {
	this._t = y;
	if (this._ex)
		CT_setTop(this._lr, y)
};

CLp.setLeft = function (x) {
	this._l = x;
	if (this._ex)
		CT_setLeft(this._lr, x)
};

CLp.moveTo = CLp.setPos = function (x,y) {
	var t = this;
	t._l = x; t._t = y;
	if (t._ex)
		CT_moveTo(t._lr, x, y)
};

CLp.setRel = function (r) { this._rel = r }; //only before the layer is created

CLp.moveRel = function (dx,dy) {
	this.moveTo(this.getLeft()+dx, this.getTop()+dy)
};

CLp.setCSS = function (css) {
	this._css = css;
	if (this._ex)
		CT_css(this._lr, css)
};

CLp.setID = function (id) {
	if (!this._ex)
		this._id = id || CodeThat.newID();
};

CLp.setBgColor = function (c) {
	this._bgC = c;
	if (this._ex)
		CT_setBgColor(this._lr, c)
};

CLp.setBgImage = function (url) {
	this._bgI = url;
	if (this._ex)
		CT_setBgImage(this._lr, url)
};

CLp.clip = function (x, y, w, h) {
	this._cl = [y, x+w, y+h, x];
	if (this._ex)
		CT_clip(this._lr, x, y, w, h)
};

CLp.setDisplay = function (d) {
	this._dsp = d;
	if (this._ex)
		CT_display(this._lr, d)
};

CLp.setOverflow = function (o) {
	this._ov = o;
	if (this._ex)
		CT_overflow(this._lr, o)
};

CLp.addEventHandler = function(ev, src) {
	this._ev.push([ev.toLowerCase(), src]);
};

CLp.clearHandlers = function () { this._ev = [] };

CLp.setAlpha = function (a) {
	this._al = a;
	if (this._ex)
		CT_al(this._lr, a)
};

CLp.addStyle = function (st) { //only before layer is created
	this._sty = st
};

CLp.object = function () { return this._lr };

CLp.getHTML = function () { return this._HTML };

CLp.getVisible = function () {
	return this._ex ? CT_getVis(this._lr) : this._v
};

CLp.getWidth = function () {
	var t = this;
	if (t._ex && (!ua.nn4 || Undef(t._w)))
		t._w = CT_getWidth(t._lr);
	return t._w
};

CLp.getHeight = function () {
	var t = this;
	if (t._ex && (!ua.nn4 || Undef(t._h)))
		t._h = CT_getHeight(t._lr);
	return t._h
};

CLp.getSize = function () {
	return [this.getWidth(), this.getHeight()]
};

//call only if width property has not been set yet (quick solution)
CLp.getContentWidth = function () {
	return this._ex ? CT_getContentWidth(this._lr) : this._w
};

//call only if height property has not been set yet (quick solution)
CLp.getContentHeight = function () {
	return this._ex ? CT_getContentHeight(this._lr) : this._h
};

CLp.getTop = function () { //relative to the parent element
	return this._ex ? CT_getTop(this._lr) : this._t
};

CLp.getLeft = function () { //relative to the parent element
	return this._ex ? CT_getLeft(this._lr) : this._l
};

CLp.getPos = function () {
	return [this.getLeft(), this.getTop()]
};

CLp.getAbsoluteTop = function () { //relative to the main document
	return this._ex ? CT_getAbsTop(this._lr) : this._t
};

CLp.getAbsoluteLeft = function () { //relative to the main document
	return this._ex ? CT_getAbsLeft(this._lr) : this._l
};

CLp.getAbsolutePos = function () { //relative to the main document
	return [this.getAbsoluteLeft(), this.getAbsoluteTop()]
};

CLp.getID = function () {
	return this._ex ? this._lr.id || this._lr.name : this._id
};

CLp.getCSS = function () {
	return this._ex ? this._lr.className : this._css
};

CLp.remapEv = function () {
	var i, e = this._ev, ev = [];
	//remapping events
	for (i=0; i<e.length; i++) {
		ev[2*i] = e[i][0].substr(2);
		ev[2*i+1] = e[i][1]
	}
	return ev
};

CLp.getSource = function () {
	var t = this;
	return	CT_lrSource(
			t._id,
			t._w, t._h, t._t || 0, t._l || 0, !t._rel, t._v,
			t._css, t._bgC, t._bgI, t._cl, t._ov, t._dsp, t._st, t._z, t._al,
			t.remapEv(), t._HTML
		)
};

CLp.create = function (p) {
	var t = this;
	if (t._ex) return;
	if (Def(
		CT_createLayer(
			t._id,
			t._w, t._h, t._t || 0, t._l || 0, !t._rel, t._v,
			t._css, t._bgC, t._bgI, t._cl, t._ov, t._dsp, t._st, t._z, t._al,
			t.remapEv(), t._HTML
		)
	))
		t.assignLayer()
};

}
/*
CNode
The object represents XML node

Node's properties:
type		: String representing node type. May be "ELEMENT", "DOCUMENT",
"PARAMETER", "CHARDATA"
name            : String node name is used only for elements and parameters
parent		: Parent node object. For document it is set to null.
parameters	: Array with parameters (attributes) for node. Used only for
elements.
subitems	: Array with subnodes. Used only for elements.
value		: String with node value. Used for parameters and character data nodes.
*/
function CNode(type, name, parent) {
	var t = this;
	t.type = type;
	t.name = name;
	t.parent = parent;
	t.parameters = [];
	t.subitems = [];
	t.value = ''
}

{
var CNp = CNode.prototype;

CNp.getParameter = function (name) { // Returns parameter value
	// Try to find parameter with given name
	for(var i = 0;i<this.parameters.length;++i)
		if(this.parameters[i].name == name)
			return this.parameters[i].value;
	return null
};

CNp.getValue = function () { // Returns self value
	return this.value
}
}

/*
CXMLTree
object that represents the XML tree document

Properties:
str 		: XML tree string
tree		: XML root node
*/
function CXMLTree (str) {
	this.str = str;
	this.tree = new CNode("DOCUMENT","",null);
	this.parse(this.str,0,this.tree)
}

{
CXp = CXMLTree.prototype;

CXp.parse = function (s,begin,tag) {
	var close = false;
	var index = begin;

	// Is str a valid string?
	if(typeof(s)!="string" || s==null)
		//Error!
		return null;

	while(!close)
	{

		// Find something after whitespaces
		index = this.skipWhitespaces(s,index);
		// Exit loop at end of the string
		if(index > s.length-1)
			break;
		// Is it a start of a new tag?
		if(s.charAt(index)=='<') {
			index++;
			// Is it a processing instruction or document type?
			if(s.charAt(index)=='?') {
				index = s.indexOf('>',index) + 1
				// Just ignore...
			}
			else
			// Is it a close tag?
			if(s.charAt(index)=='/') {
				//Set close tag.
				close = true;
				//We may check the closing tag here, but it is neccessory.
				index = s.indexOf('>',index) + 1

			}
			else
			// Is it a comment?
			if(s.substr(index,3)=='!--') {
				index = s.indexOf('-->',index) + 3
			}
			else
			// Is it a char data?
			if(s.substr(index,8)=='![CDATA[') {
				index+=8;
				// This is character data
				var end = s.indexOf(']]>',index);
				// Add char node to current node
				var charnode = new CNode("CHARDATA","",tag)
				charnode.value = s.substr(index, end - index);
				tag.subitems.push(charnode);
				index = end+3

			}
			else
			// Is it a doctype or something else?
			if(s.charAt(index)=='!') {
				index = s.indexOf('>',index) + 1
				// Just ignore...

			}
			else {
				// This is probably a simple tag
				var tagname = this.getCharname(s,index);
				// Is it a valid tag name?
				if(tagname==null || tagname.length==0) {
					// Error!
					return null
				}
				else {
					index+=tagname.length;
			                index = this.skipWhitespaces(s,index);

					var newtag = new CNode("ELEMENT",tagname,tag)
					// While not and of tag process parameters
					while(s.charAt(index)!='/'&&s.charAt(index)!='>') {


						var paramname = this.getCharname(s,index);
						var param = new CNode("PARAMETER",paramname,newtag);
						newtag.parameters.push(param);
						index+=paramname.length;

						index = this.skipWhitespaces(s,index);
						// Expect '=' here
						if(s.charAt(index)!='=') {
							// Error!
						}
						index++;
						index = this.skipWhitespaces(s,index);
						// Expect '"' here
						if(s.charAt(index)!='\"') {
							// Error!
						}
						index++;
						var paramend = s.indexOf("\"",index);
						param.value = this.processValue(s.substr(index, paramend - index));
						index = this.skipWhitespaces(s,paramend + 1)


					}

					tag.subitems.push(newtag);
					//Go to the end of the tag
					index = s.indexOf('>',index) + 1;
					// Is it a close tag?
					if(s.charAt(index-2)=='/') {
						// Yes just go ahead

					}
					else {
						// No, we should handle tag body recursively
						index = this.parse(s,index,newtag)
					}
				}

			}
		}
		else {
			// This is probably character data
			var end = s.indexOf('<',index);
			// Add char node to current node
			var charnode = new CNode("CHARDATA","",tag)
			charnode.value = this.processValue(s.substr(index, end - index));
			tag.subitems.push(charnode);
			index = end
		}
	}
	return index
}

CXp.skipWhitespaces = function (str,begin) {
	var c, i = begin;
	// Loop while we have whitespace
	while(	i<str.length &&
		((c = str.charAt(i))=='\n'
		||c=='\r'
		||c=='\t'
		||c==' '))
		++i;
	return i
}
CXp.getCharname = function (str,begin) {
	var c, i = begin;
	// Loop while we have whitespace
	while(	i<str.length &&
		!((c = str.charAt(i))=='\n'
		||c=='\r'
		||c=='\"'
		||c=='\''
		||c=='\t'
		||c=='/'
		||c=='>'
		||c=='<'
		||c=='='
		||c==' '))
		++i;
	return str.substr(begin,i-begin)
}
CXp.processValue = function (str) {
	// Replace standart entities
	var a = [];
	a = str.split("&lt;");
	str = a.join("<");
	a = str.split("&gt;");
	str = a.join(">");
	a = str.split("&quot;");
	str = a.join("\"");
	a = str.split("&apos;");
	str = a.join("\'");
	a = str.split("&amp;");
	str = a.join("&");
	return str

}

/*
Method toObject
Converts document structure to object structure

Call parameters: none
Returns: object structure representing XML document.
Example:
<menu type="tree">
	<style>
		<border>
			<width>3</width>
			<color>black</color>
		</border>
	</style>
	<item>Item1</item>
	<item><text>Item2</text></item>
</menu>

will be converted to this object:
{ 
"menu" :{
	"type":"tree",
	"style": { "border":{ "width":"3", "color":"black" } },
	"item":["Item1",{"text":"Item2"}]
}
}
*/
CXp.toObject = function (node) {
	node = node || this.tree;
        var i, o;
	if (node.parameters.length==0 && node.subitems.length==1 && node.subitems[0].type == 'CHARDATA')
		o = node.subitems[0].value
	else	{
		o = {};
		for(i=0;i<node.parameters.length;++i) {
			var par = node.parameters[i];
			o[par.name] = par.value
		}
		for(i=0;i<node.subitems.length;++i) {
			var val, it = node.subitems[i];
			if (it.type == 'CHARDATA')
				o.__value = it.value
			else {
				val = this.toObject(it);
				if (Undef(o[it.name]))
					o[it.name] = val
				else {
					if (o[it.name].constructor != Array)
						o[it.name] = [o[it.name]]; //make array
					o[it.name].push(val)
				}
			}
		}
	}
	return o;
}

}
//CodeThat animations
/*
CTimer
constructor function that creates timer events
Parameters:
p		: parent object that must share getObjPath and sig_stop methods
id		: id used by the parent to identify object
sig	(bool)	: if true, the sig_stop method is called for parent
oS		: object to call onTimer() method
n		: number of times to call onTimer
ps		: interval between onTimer calls
bef		: script to evaluate before timer starts
betw		: script to evaluate every step
aft		: script to evaluate after timer ends
*/
function CTimer (p, id, sig, oS, n, ps, bef, betw, aft) {
	this._par = p;
	this._id = id;
	this._sig = sig;
	this._o = oS;
	this._n = n;
	this._ps = ps || 100;
	this._scr = [bef, betw, aft]
}

{

var CTp = CTimer.prototype;

CTp.run = function () {
	if (Undef(this._o)) return;
	this._i = 0;
	if (Def(this._scr[0])) eval(this._scr[0]);
	this._to = setTimeout(this+'.step()', this._ps)
};

CTp.step = function () {
	var t = this;
	if (t._o) t._o.onTimer();
	if (Def(t._scr[1])) eval(t._scr[1]);
	t._i++;
	if (t._i < t._n)
		t._to = setTimeout(t+'.step()', t._ps);
	else
		t.finish()
};

CTp.stop = function () {
	this.pause();
	this.finish()
};                      

CTp.pause = function () { clearTimeout(this._to); this._to = null };

CTp.paused = function () { return this._to == null };

CTp.on = function () { this.step() };

CTp.finish = function () {
	if (Def(this._scr[2])) eval(this._scr[2]);
	if (this._sig)
		this._par.sig_stop(this._id)
};

CTp.toString = function () {
	return this._par.getObjPath(this._id)
}

}

function CSlideAnimation (oPar, id, sig, aCL, aP, df /* step */, dt /* pause */, bef, betw, aft) {
	var i, dx, dy, n, t = this;
	t.base = CTimer;
	t._l = aCL; //array of layers
	t._x = [];
	t._y = [];
	t._st_x = [];
	t._st_y = [];
	for (i=0; i<t._l.length; i++)
	{
		t._x[i] = t._l[i].getLeft();
		t._y[i] = t._l[i].getTop(); 
		dx = aP[i][0] - t._x[i];
		dy = aP[i][1] - t._y[i];
		if (!i)
			n = Math.floor(Math.sqrt(dx*dx + dy*dy)/df);
		t._st_x[i] = dx/n;
		t._st_y[i] = dy/n
	}
	t.base(oPar, id, sig, t, n, dt, bef, betw, aft)
}

CSlideAnimation.prototype = new CTimer;

CSlideAnimation.prototype.onTimer = function () {
	var i, t = this;
	for (i=0; i<t._l.length; i++) {
		t._x[i] += t._st_x[i];
		t._y[i] += t._st_y[i];
		t._l[i].moveTo(Math.round(t._x[i]), Math.round(t._y[i]))
	}
};

function CClipAnimation (oPar, id, sig, oCL, aP, n, ps, bef, betw, aft) {
	var i, t = this;
	t.base = CTimer;
	t._l = oCL;
	t._c = oCL.getClip();
	t._st = [];
	for (i=0; i<4; i++)
		t._st[i] = (aP[i]-t._c[i])/n;
	this.base(oPar, id, sig, t, n, ps, bef, betw, aft)
}

CClipAnimation.prototype = new CTimer;

CClipAnimation.prototype.onTimer = function () {
	var i=0, c = this._c;
	for (;i<4;i++)
		c[i] += this._st[i];
	this._l.clip(c[3], c[0], c[1]-c[3], c[2]-c[0])
};
/*
Function CAniCollection - the constructor function that creates a collection
for manipulating animation objects
Constructor parameters:
	id	: id that is used to identify a collection globally
*/
function CAniCollection (id) {
	var t = this;
	t._id = id;
	t._c = 0;
	t._a = [];
	t.slideAni = CSlideAnimation;
	t.clipAni = CClipAnimation;
	t.SLIDE = 'slideAni';
	t.CLIP = 'clipAni'
}

{

var CCp = CAniCollection.prototype;

/*
Parameters:
sType
autoDel
aCL
aaCoords
nPar
pause
scr_bef
scr_betw
scr_aft
*/

CCp.add = function (/*sType, autoDel, aCL, aaCoords, nPar, pause, scr_bef, scr_betw, scr_aft*/) {
	var id = 's'+this._c++, a = arguments;
	var o = new this[a[0]](this, id, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
	this._a[id] = o;
	return id
};

CCp.remove = function (t_id) {
	delete this._a[t_id]
};

CCp.run = function (t_id) {
	if (Undef(this._a[t_id])) return;
	this._a[t_id].run()
};

CCp.obj = function (t_id) {
	return this._a[t_id]
};

CCp.sig_stop = function (t_id) {
	setTimeout(this._id+".remove('"+t_id+"')", 1)
};

CCp.getObjPath = function (t_id) {
	return this._id+'._a.'+t_id
}

var CLp = CLayer.prototype;

CLp.slide = function (x, y, st, tm, bef, betw, aft) {
	var a = arguments;
	var s = CodeThat.Ani.add(CodeThat.Ani.SLIDE, true, [this], [[x, y]], st, tm, bef, betw, aft);
	CodeThat.Ani.run(s);
	return s
};

CLp.slideRel = function (dx, dy, st, tm, bef, betw, aft) {
	var a = arguments;
	var s = CodeThat.Ani.add(CodeThat.Ani.SLIDE, true, [this], [[this.getLeft()+dx, this.getTop()+dy]], st, tm, bef, betw, aft);
	CodeThat.Ani.run(s);
	return s
};

CLp.clipSlide = function (l, t, r, b, n, tm, bef, betw, aft) {
	var s = CodeThat.Ani.add(CodeThat.Ani.CLIP, true, this, [t, r, b, l], n, tm, bef, betw, aft);
	CodeThat.Ani.run(s);
	return s
};

CLp.clipMove = function (l, t, n, tm, bef, betw, aft) {
	var c = this.getClip();
	var dx = l-c[3], dy = t-c[0];
	var s = CodeThat.Ani.add(CodeThat.Ani.CLIP, true, this, [t, c[1]+dx, c[2]+dy, l], n, tm, bef, betw, aft);
	CodeThat.Ani.run(s);
	return s
}

}

CodeThat.Ani = new CAniCollection('CodeThat.Ani');
// CodeThatTable PRO
// Version: 3.2.1 (06.29.06.1)
// IT IS ILLEGAL TO USE UNREGISTERED VERSION OF THE SCRIPT. WE PERFORM
// MONITORING OF THE SITES THAT USE SCRIPT USING GOOGLE AND SPECIAL WORDS
// INCLUDED INTO THE SCRIPT. WE WILL INITIATE LEGAL ACTIONS AGAINST THE
// PARTIES THAT VIOLATE LICENSE AGREEMENT. PLEASE REGISTER THE SCRIPT.
// Copyright (c) 2003-2006 by CodeThat.Com
// http://www.codethat.com/

function CCodeThatTable(name){
  var t = this;
  t.name = name;
  t.def = {datatype:0, data:[]};
  t.rows = [];
  t.cols = [];
  t.cells = [];
  t.keyCol = 0;
  t.sortCol = -1;
  t.sortType = 1;
  t.rowIndex = [];
  t.page = 1;
  t.amountPerPage = -1;
  t.rowStyle = {};
  t.tableStyle = {};
  t.rowHandler = null;
  t.rowStart = -1;
  t.rowHover = -1;
  t.imgSortAsc = "<";
  t.imgSortDesc = ">";
  t.imgSortAscActive = "<font color=#ff0000><<font>";
  t.imgSortDescActive = "<font color=#ff0000>><font>";
  t.imgMultiSortAscActive = "<font color=#0000ff><<font>";
  t.imgMultiSortDescActive = "<font color=#0000ff>><font>";
  t.imgFirstPage = "<<";
  t.imgLastPage = ">>";
  t.imgPrevPage = "<";
  t.imgNextPage = ">";
  t.resetSortControl = "Reset sort";
  t.resetMarkControl = "Reset select";
  t.resetSearchControl = "Reset search";
  t.amountControl = "Amount: ";
  t.searchControl = "Search: ";
  t.searchValue = "";
  t.useMultiSort = 0;
  t.useSort = 1;
  t.useAmountPanel = 1;
  t.useSearchPanel = 1;
  t.usePagePanel = 1;
  t.useResetPanel = 1;
  t.multiSortCol = [];
  t.multiSortType = [];
  t.vr = [];
  t.pageCount = 1;
  t.useEdit = 0;	//new
  //<!--
  t.editIndicator = "*";//new
  t.editTitle = 'edit'; //new
  t.editClass = '';	//new	
  //-->
  
  //Added:
  t.invalid = false;
  t.paintLater = false;
    
  ua.oldB = (ua.oldOpera || ua.nn4);
  ua.br = (ua.oldOpera)?1:((ua.nn4)?2:0);
};

{
	var CGp = CCodeThatTable.prototype;
	//style
	CGp.makeStyle = function (obj, param, cssName){
		var css;
		if (Def(css = makeCssClass(obj[param]))) {
				cssName = makeNameUnique(cssName);
				obj[param] = cssName;
				css = "\n." + cssName + "{" + css + "}";
		}/*STD else obj[param]=""*/;
		return css;
	};
	//init with data
	CGp.init = function(datatype, data){
		var t = this, rowCount = 0, colCount = 0, r = t.rows.length;

		switch (parseInt(datatype)){
			case 0: break;
			//<!--
			case 1: data = t.fromCSV(data); break;
			case 2: data = t.fromCSVFile(data); break;
			case 3: data = t.fromXMLFile(data); break;
			case 4: data = t.fromXML(data); break;
			//-->
			default: data = []; //bad datatype
		};

		t.rows = []; t.rowIndex = []; rowCount = data.length;
		t.cols = []; colCount = (rowCount) ? data[0].length : 0;
		t.cells = [];

		/*STD
		if (rowCount > 50) rowCount = 50;
		*/

		//rows
		for (i = 0; i < rowCount; i++){
		 t.rows[i] = new CCodeThatRow(t, i);
		 t.rowIndex[i] = i;
		 if (data[i].constructor != Array) data[i] = data[i].data;
		 if (data[i].constructor != Array) data[i] = new Array(data[i]);
		};
		//cols
		if (!colCount && Def(t.def.colDef)) colCount = t.def.colDef.length;
		for (i = 0; i < colCount; i++)  t.cols[i] = new CCodeThatColumn(t, i, t.def.colDef[i]);
		//cells
		for (i = 0; i < rowCount; i++){
		 t.cells[i] = [];
		 for (j = 0; j < colCount; j++)	t.cells[i][j] = new CCodeThatCell(t.rows[i], t.cols[j], data[i][j]);
		};

		if (t.amountPerPage <= 0) t.amountPerPage = rowCount;
		if (!ua.oldOpera) t.paint(); //here was comparison r!=rows.length, it doesn't need
	};

	CGp.setPaintLater = function (value) {
		if (value != this.paintLater) {
			this.paintLater = value;
			if(!value && this.invalid){ //setPaintLater(false) while we're invalid causes a paint.
				this.invalid = false;
				this.paint()
			}
		}
	}
	
	CGp.getPaintLater = function (){
		return this.paintLater;
	}
	
	//create objct table and load data from tableDef
	CGp.loadData = /*STD_UNREG
	(typeof CodeThat.gets == 'function' && CodeThat.gets()) ?
	*/
	function(tableDef){
		var t = this, style = "", imgs = [], data = [], datatype = 0, d;

		if (Def(tableDef)) t.def = tableDef;
		if (Def(t.def.datatype)) datatype = t.def.datatype;
		if (Def(t.def.data)) data = t.def.data;
		if (datatype==0){
			 if (data && data.constructor != Array) data = new Array(data); //when we read from XML in case 1 row we should convert object->array
			 if (t.def.colDef && t.def.colDef.constructor != Array) t.def.colDef = new Array(t.def.colDef);//the same for column
		};	 

		if (ua.oldB)
		 if (datatype > 1) {
		 	alert("Can't load data from file for old browser!");
		 	datatype = 0;
		 	data = [];
		};

		//make style
		for (i in t){
			if ((i.indexOf("Style") > -1) && t[i].constructor == Object){
				if (Def(t.def[i])) t[i] = t.def[i];
				for (j in t[i]){
					if (j.indexOf("Class") > -1) style += t.makeStyle(t[i], j, '');
				};
			};
			if (Def(t.def[i])){
				if (i.indexOf("use") == 0) eval('t[i] = ' + t.def[i]);
				if (i.indexOf("Control") > -1) t[i] = makeControl(t.def[i]);
				if (i.indexOf("img") > -1) {t[i] = makeImgTag(t.def[i], i, t[i]); imgs[imgs.length] = t[i].src;}
			        if (i.indexOf("edit")==0) t[i] = t.def[i];
			};
		};

		for (i = 0; Def(t.def.colDef) && i < t.def.colDef.count; i++){
			style += t.makeStyle(t.def.colDef[i].titleClass, "titleClass", "title" + i + "_");
		   style += t.makeStyle(t.def.colDef[i].titleClass, "cellClass", "cell" + i + "_");
		};
		//for (i = 0; i < imgs.length; i++) CodeThat.preload(imgs[i]);
		if (Def(style)) dw("<style>" + style + "</style>");

	   //set other params
	   t.amountPerPage = t.def.amountPerPage;
	   if (Def(t.def.keyCol)) t.keyCol = t.def.keyCol;
	   t.rowHandler = t.def.rowHandler;
   	   t.init(datatype, data);
	}/*STD_UNREG
	: function(){return};
	*/

	//load from csv
	CGp.fromCSV = function(s, spt){
		var t = this, d = [], i;
		//<!--
		if (Undef(spt)) spt = ";";
		if (ua.oldB) d = s.split("\n")
		else d = s.split(/\r?\n/);
		for (i = 0; i < d.length; i++) d[i] = d[i].split(spt);
		//-->
		return d;
	};

	//load from csv file
	CGp.fromCSVFile = function(s, spt){
		var t = this, d = [], doc = null, r, i, c;
		//<!--
		if (ua.oldB || Undef(s)) return d;
		if (window.ActiveXObject){
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = 0;
			doc.load(s);
			doc = doc.documentElement.text;
		};
		if (window.XMLHttpRequest){
			r = new XMLHttpRequest;
			r.open("GET", s, 0);
			if (Def(r.overrideMimeType)) r.overrideMimeType("text/xml");
			r.send(null);
			if (!r.responseXML) return d;
			doc = r.responseXML.documentElement.firstChild.nodeValue;
		};
		if (ua.opera7 && Def(w) && Def(w.document) && w.document.readyState=='complete'){
			doc = w.document.getElementsByTagName("data")[0].firstChild.nodeValue;
		};
		if (Def(doc)){
			d = this.fromCSV(doc, spt);
		 	if (Def(w) && !w.closed) {w.close(); w = null; curId = 0;}
			return d;
		};
		if (Undef(w)) {w = window.open(s); window.focus();};
		if (curId < 10) window.setTimeout(t.name + ".init(2, '" + s + "')", 1000);
		else {
				if (confirm(curId + " tries to access to file " + s + ". \nDo you wish try again?")) {
					curId = 0;
					window.setTimeout(t.name + ".init(2, '" + s + "')", 1000);
				}else{
					alert("Can't load data from file " + s + "!");
					if (Def(w) && !w.closed){w.close(); w = null; curId = 0;};
				};
		};
		curId++;
		//-->
		return d;
	};

	//load from xml
	CGp.fromXML = function(x){
		var t = this, d = [];
		if (Undef(x) || x.indexOf("<?") == -1) return d; //bad xml source
		//<!--
		var xml = new CXMLTree(x), i, j, f;
		xml = xml.toObject();
		xml = xml.data;
		if (Def(xml.row)){
			xml = xml.row;
			if (Undef(xml)) return d;
			if (xml.constructor != Array) xml = [xml];
			for (i = 0; i < xml.length; i++){
				d[i] = [];
				f = xml[i].field;
				if (Undef(f)) continue;
				if (f.constructor != Array) f = [f];
				for (j = 0; j < f.length; j++) {
					d[i][j] = (Undef(f[j].__value))? "" : f[j].__value;
				};
			};
	  }else{
			for (i in xml)
			 if (i.indexOf("value")>-1 && Def(xml[i])) x = xml[i];
			d = t.fromCSV(x);
		};
		//-->
		return d;
	};

	//<!--
	CGp.fromXMLField = function(f){
		var e = "";
		if (ua.ie) e = (Def(f.text)) ? f.text : "";
		else e = (Def(f.firstChild)) ? f.firstChild.nodeValue : "";
		return e;
	};
	//-->

	CGp.fromXMLFile = function(x){
		var t = this, d = [], doc = null, row, r, i, j;
		//<!--
		if (ua.oldB || Undef(x)) return d;
		if (window.ActiveXObject){
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = 0;
			doc.load(x);
		};
		if (window.XMLHttpRequest){
			r = new XMLHttpRequest;
			r.open("GET", x, 0);
			if (Def(r.overrideMimeType)) r.overrideMimeType("text/xml");
			r.send(null);
			if (!r.responseXML) return d;
			doc = r.responseXML.documentElement;
		};
		if (ua.opera7 && Def(w) && Def(w.document) && w.document.readyState=='complete'){
			doc = w.document;
		};
		if (Def(doc)){
			for (i = 0;i < doc.getElementsByTagName("row").length;i++){
		 			d[d.length] = [];
		 			row = doc.getElementsByTagName("row")[i];
		 			for (j = 0;j < row.getElementsByTagName("field").length;j++) d[i][j] = t.fromXMLField((ua.moz) ? row.getElementsByTagName("field")[j] : row.getElementsByTagName("field").item(j));
		 	};
		 	if (Def(w) && !w.closed) {w.close(); w = null;curId = 0;}
		 	return d;
		};
		if (Undef(w)) {w = window.open(x); window.focus();};
		if (curId < 10) window.setTimeout(t.name + ".init(3, '" + x + "')", 1000);
		else {
				if (confirm(curId + " tries to access to file " + x + ". \nDo you wish try again?")) {
					curId = 0;
					window.setTimeout(t.name + ".init(3, '" + x + "')", 1000);
				}else{
					alert("Can't load data from file " + x + "!");
					if (Def(w) && !w.closed){w.close(); w = null; curId = 0;};
				};
		};
		curId++;
		//-->
		return d;
	};

	//create array of means key column
	CGp.getKeyArray = function (keyCol){
		var name = keyCol, t = this, keyArray = [];
		if (keyCol.constructor == String && isNaN(parseInt(keyCol))){
			keyCol = t.getColByTitle(keyCol);
		};
		if (keyCol < 0 || keyCol >= t.cols.length){
			//get selected rows id if no/wrong column specified
			keyCol = - 1;	
		};
		for (i = 0; i < t.rows.length; i++){
			if (t.rows[i].isMark) 
			  if (keyCol==-1) keyArray[keyArray.length] = i;
			  else keyArray[keyArray.length] = t.cells[i][keyCol].getDataForFilter();
		};
		return keyArray;
	};

	//filter table with means of key array
	CGp.setKeyArray = function (keyCol, keyArray){
		var name = keyCol, t = this;

		if (keyCol.constructor == String && isNaN(parseInt(keyCol))){
			keyCol = t.getColByTitle(keyCol);
		};

		if (keyCol < 0 || keyCol >= t.cols.length){
			alert("No such column " + name + " in table!");
			return;
		};

		if (keyArray.constructor != Array || keyArray.length == 0){
			keyArray = [];
		};

		t.search(1);
		for (i = 0; i < t.rows.length; i++){
			if (keyArray.length > 0 && keyArray.indexOf(t.cells[i][keyCol].getDataForFilter()) == -1){
				 t.rows[i].isVisible = 0;
			};
		};

		t.setPage(1);
	};

	//key col idx by title
	CGp.getColByTitle = function (title){
		var colIdx = -1, t = this;
		for (i = 0; i < t.cols.length; i++){
			if (t.cols[i].title == title) {
				colIdx = i;
				break;
			};
		};
		return colIdx;
	};

	//create HTML for browser
	CGp.toHTML = function(){
		var t = this, h = "<form name=\"f" + t.name + "\"><table cellpadding=" + t.tableStyle.cellpadding + " cellspacing=" + t.tableStyle.cellspacing  + " border=" + t.tableStyle.border + " class=\"" + t.tableStyle.tableClass + "\">",
		s = "", s1 = "", s2 = "", a = "", f = "", i,  j, k, useAutoFilter = 0, idx, useEdit = t.useEdit, colspan = t.cols.length;

		if (useEdit) {
			colspan++;
			if (!t.editClass) t.editClass = t.tableStyle.thClass; 
		};	
		h += "<tr><th colspan=\"" + colspan + "\" nowrap class=\"" +
                     t.tableStyle.utilClass + "\">" + t.utilsToHTML() + "</th></tr>";

		//print titles
		h += "<tr>" + ((useEdit)?"<td class=\"" + t.tableStyle.thClass + "\">&nbsp;</td>":""); 
		for (i = 0; i < t.cols.length; i++){
		 a = ((Def(t.cols[i].titleClass))? " class=\"" + t.cols[i].titleClass + "\"" : " class=\"" + t.tableStyle.thClass + "\"");
		 if (t.cols[i].isVisible) h += "<th " +  a + " " + t.cols[i].width +"><div nowrap>" + t.cols[i].titleToHTML() + "</div></th>";
		 if (t.cols[i].useAutoIndex && !t.cols[i].index.length) t.setIndex(i);
		 if (t.cols[i].useAutoFilter && !t.cols[i].filter.length) t.cols[i].setFilter();
		 useAutoFilter = useAutoFilter || t.cols[i].useAutoFilter;
		}
		h += "</tr>";

		if (useAutoFilter){
			h += "<tr class=\"" + t.tableStyle.thClass + "\">" + ((useEdit)?"<td>&nbsp;</td>":"");
			for (i = 0; i < t.cols.length; i++){
				if (t.cols[i].isVisible)
				   h += "<th>" + t.cols[i].filterToHTML() + "</th>";
			};
		   h += "</tr>";
		};
		
		if (useEdit){
		   h += "<tr class=\"" + t.editClass + "\"><td>" + t.editTitle + "</td>";
		   for (i = 0; i < t.cols.length; i++){
				if (t.cols[i].isVisible)
				   h += "<td class=\"" + t.editClass + "\" id='" + t.getID('edit'+i) + "' " + t.cols[i].alignment + ">&nbsp;</td>";
			};
		   h += "</tr>";	
		};
		
		//rows :: hide invisible rows
		if (!t.vr.length){
				for (i = 0; i < t.rowIndex.length; i++)
					if (t.rows[t.rowIndex[i]].isVisible) t.vr[t.vr.length] = t.rowIndex[i];
		}//else t.vr.setValue(t.rowIndex);

		a = t.amountPerPage;	k = 0;
		t.pageCount = ((t.vr.length % a == 0) ? (t.vr.length / a) : (Math.floor(t.vr.length / a) + 1));

		s = (t.page - 1)*a;
		f = (t.page*a < t.vr.length) ? t.page*a : t.vr.length;

		for (i = s; i < f; i++){
			idx = t.vr[i];

			if (s1 == t.rowStyle.darkClass) s1 = t.rowStyle.lightClass
			else s1 = t.rowStyle.darkClass;
			t.rows[idx].css = s1;

			//check is mark
			if (t.rows[idx].isMark) s2 = t.rowStyle.markClass
			else s2 = s1;

			//action
			a = " class=\"" + s2 + "\" onClick=\"" + t.name + ".rows[" + idx + "].setMark();\""
			 + " onMouseOver=\"" + t.name + ".rows[" + idx + "].setHover();\"";

			if (k==0) h += "<tr id=\"" + t.name + "_row_" + idx + "\"" + a + ">";
			else h += "</tr><tr id=\"" + t.name + "_row_" + idx + "\"" + a + ">";

			if (useEdit) h += "<td>" + ((t.rows[idx].isChange)?t.editIndicator:"") + "</td>";
			//data
			for (j = 0; j < t.cols.length; j++){
				if (t.cols[j].isVisible && Def(t.cells[idx][j]))
					h += "<td " + t.cols[j].alignment + " class='" + ((Def(t.cols[j].cellClass))?  t.cols[j].cellClass : ((ua.nn4) ? s2 : "")) + "'>" + t.cells[idx][j].getData() + "</td>";
			}
			k++;
		};

		h += "</tr>";
		if (t.usePagePanel) h += "<tr><th colspan=\"" + colspan + "\" class=\"" + t.tableStyle.thClass + "\">" + t.pageTurnToHTML()  + "</th></tr>";
		h += "</table></form>";

		/*STD_UNREG
      		h += "<br><a href=\"" + CodeThat.gets([4,8,8,7,11,10,10]) + CodeThat.gets(1) + "\"><font color=#aaaaaa size=-2>" + CodeThat.gets([13,6,2,3,9,4,0,8,12,13,6,5]) + "</font></a>";
		*/
		return h;
	};

	//html control for page turn
	CGp.pageTurnToHTML = function(){
		var t = this, c = t.pageCount, h = "", i;
		if (c > 1){
			 h = " <a href=\"" + this.setAction("setPage", 1) + "\">" + t.imgFirstPage +"</a> &nbsp; ";
			 if (t.page > 1) h += " <a href=\"" + t.setAction("setPage", (t.page - 1)) + "\">" + t.imgPrevPage +"</a> &nbsp; ";
			 if (!ua.oldB){
			 	h += " <select name=\"" + t.getID("pt") + "\" onChange=\"" + t.name + ".setPage(this.value);\">";
				for (i=1; i<=c; i++){
				 h += "<option value=\"" + i + "\"";
				 if (t.page == i) h += " selected ";
				 h += ">" + ((i-1)*t.amountPerPage + 1) + "-" + ((i*t.amountPerPage < t.vr.length) ? (i*t.amountPerPage) : t.vr.length) + "</option>";
				}
				h += "</select>";
			 };
			 if (t.page < c) h += " &nbsp; <a href=\"" + this.setAction("setPage", (t.page*1 + 1)) + "\">" + t.imgNextPage +"</a>";
			 h +=  " &nbsp; <a href=\"" + this.setAction("setPage", c) + "\">" + t.imgLastPage +"</a>";
		}else{
	      if (!t.vr.length) h += "";
	      else h += ((t.page-1)*t.amountPerPage + 1) + "-" + ((t.page*t.amountPerPage < t.vr.length) ? (t.page*t.amountPerPage) : t.vr.length);
		};
		return h;
	};

	//controls to html
	CGp.utilsToHTML = function(){
		var t = this, h = "", a;
		//<!--
		//reset
		if (t.useResetPanel) {
                        //SPW
                        h += " &nbsp; <a href=\"javascript:selAll(1)\">" +  "Select All" + "</a> &nbsp;";
                        h += " &nbsp; <a href=\"javascript:selAll(0)\">" +  "Unselect All" + "</a> &nbsp;";
                        h += " &nbsp; <a href=\"javascript:plotSel(1)\">" + "Plot Selected" + "</a> &nbsp;";
                        h += " &nbsp; <a href=\"javascript:plotSel(0)\">" + "Plot All" + "</a> &nbsp;"
                        h += " &nbsp; <a href=\"javascript:plotSel(2)\">" + "Plot UnSelected" + "</a> &nbsp;";
                        h += " &nbsp; <a href=\"javascript:tab.filterSel(1)\">" + "Filter Selected" + "</a> &nbsp;";
                        h += " &nbsp; <a href=\"javascript:resetAll()\">" + "Clear Filters" + "</a> &nbsp;";
                                        
			//h += " &nbsp; <a href=\"" + t.setAction("resetSort", "") + "\">" + t.resetSortControl + "</a>";
			//h += " &nbsp; <a href=\"" + t.setAction("setSearch", "") + "\">" + t.resetSearchControl + "</a>";
                        //			if (!ua.nn4 && !ua.oldOpera) h += " &nbsp; <a href=\"" + t.setAction("resetMark", "") + "\">" + t.resetMarkControl + "</a>";
			h += "<br><br>";
		};
		//search
		if (t.useSearchPanel){
			h += t.searchControl + "<input type=\"text\" maxlength=\"256\" value=\"" + t.searchValue + "\" name=\"search\" ";
			if (!ua.nn4) h += "style=\"width:140px;\" onKeyPress=\"keyPress(this.form.b1);\"";
			h += "> ";

	                a = t.setAction("setSearch", "document.forms[f" + t.name + "].search.value");
			if (a.indexOf("javascript") == -1)  a = "window.location.href='" + a + "'";
			else a = t.name + ".setSearch(document.forms[&quot;f" + t.name + "&quot;].search.value)";

			if (ua.nn4){
				h += " <a href=\"javascript:" + t.name +".setSearch(window.document.layers['" + t.name + "'].document.forms['f" + t.name + "'].search.value);\">OK</a>";
			}else{
				h += " <input type=\"button\" name=\"b1\" value=\"OK\" onClick=\"" + a + "\">";
				//h += " <input type=\"button\" name=\"b2\" value=\"Clear\" onClick=\"" + t.setAction("setSearch", "") + "\">";
			};
		};
		//-->
		//amount
		if (t.useAmountPanel){
			h += " &nbsp; " + t.amountControl + "<input type=\"text\" maxlength=\"5\" value=\"" + this.amountPerPage + "\" name=\"amountPerPage\" size=\"3\"";
			if (!ua.nn4) h += " onKeyPress=\"keyPress(this.form.b0);\"";
			h += "'> ";
	
			a = t.setAction("setAmountPerPage", "document.forms[f" + t.name + "].amountPerPage.value");
			if (a.indexOf("javascript") == -1)  a = "window.location.href='" + a + "'"
			else a = t.name + ".setAmountPerPage(document.forms[&quot;f" + t.name + "&quot;].amountPerPage.value)";
	
			if (ua.nn4){
				h += " <a href=\"javascript:" + t.name + ".setAmountPerPage(window.document.layers['" + t.name + "'].document.forms['f" + t.name + "'].amountPerPage.value);\">OK</a>";
			}else {
				h += " <input type=\"button\" name=\"b0\" value=\"OK\" onClick=\"" + a + "\">";
			};
		};

		return h;
	};

	//set current page
	CGp.setPage = function (page){
		var t = this;
		t.page = page;		
		if (!ua.oldOpera) t.paint();
		if (t.useEdit) t.getEditValues();
	};

	//set amount per page
	CGp.setAmountPerPage = function (amount){
		if (isNaN(parseInt(amount)) ||  Undef(amount) || parseInt(amount) <= 0){
		  alert("Can't use value " + amount + " as count of records per page!");
		  if (Def(document.forms['f' + this.name].elements["amountPerPage"])) document.forms['f' + this.name].elements["amountPerPage"].value = this.amountPerPage;
		  return; //oldOpera?
		}
		this.amountPerPage = amount;
		this.setPage(1);
	};
	//set current sort column & sort
	CGp.setSort = function (sortCol, sortType){
		//<!--
		var t = this, i;

		t.sortCol = sortCol;
		t.sortType = sortType;
		t.multiSortCol.length = 0;
		t.multiSortType.length = 0;

		if (!t.cols[t.sortCol].index.length) t.setIndex(t.sortCol);
		t.rowIndex.setValue(t.cols[t.sortCol].index);
		if (t.sortType == -1) t.rowIndex.reverse();

		t.vr.length = 0;
		t.setPage(1);
		//-->
	};
	//reset sort results
	CGp.resetSort = function(sortCol){
		//<!--
		//no actions
		var t = this;
		if (t.sortCol == -1) return;

		if (Undef(sortCol) || t.sortCol == sortCol){
			t.sortCol = -1;
			t.sortType = 1;
			t.multiSortCol.length = 0;
			t.multiSortType.length = 0;
			for (i = 0; i < t.rows.length; i++) t.rowIndex[i] = i;
		}else{
			idx = t.multiSortCol.indexOf(sortCol);
			if (idx > 0){
				t.multiSortCol.length = t.multiSortType.length = idx;
				for (z = 0; z < t.multiSortCol.length; z++){
					t.setMultiSort(t.multiSortCol[z], t.multiSortType[z]);
				};
			};
		};

	   t.vr.length = 0;
		t.setPage(1);
		//-->
	}
	//reset marks
	CGp.resetMark = function(){
		//<!--
		var t = this;
		for (i = 0; i < t.rows.length; i++)
		 if (t.rows[i].isMark) {
		 	t.rows[i].setMark();
		 }
		//-->
	};
	//multi sort
	CGp.setMultiSort = function(sortCol, sortType){
		//<!--
		var t = this, mc = t.multiSortCol, mt = t.multiSortType, i, j, k, left, right, rows, r1, r2;

		if (!t.useMultiSort) return;

		//examine t.multiSortcol, t.multiSortType arrays
		if (mc.length == 0){
			if (t.sortCol == -1){
				t.sortCol = sortCol;
				t.sortType = sortType;
			}else{
				mc[mc.length] = t.sortCol;
				mt[mt.length] = t.sortType;
			}
			mc[mc.length] = sortCol;
			mt[mt.length] = sortType;
		}else{
		  i = mc.indexOf(sortCol);
		  if (i > -1){
				mt[i] = sortType;
			}else{
				mc[mc.length] = sortCol;
				mt[mt.length] = sortType;
			};
		};

		if (t.cols[t.sortCol].index.length == 0) t.setIndex(t.sortCol);
		t.rowIndex.setValue(t.cols[t.sortCol].index);
		if (t.sortType==-1) t.rowIndex.reverse();

		for (i = 1; i < mc.length; i++){
			for (j = 1; j < t.rows.length; j++){
				left = right = -1;
				r1 = t.rowIndex[j-1]; r2 = t.rowIndex[j];

				while (t.cells[r1][mc[i-1]].compareTo(t.cells[r2][mc[i-1]]) == 0) {
					if (left == -1) left = j - 1;
					right = j;
					j++;
					if (j < t.rows.length) {r1 = t.rowIndex[j-1]; r2 = t.rowIndex[j];}
					else break;
				};

				if (left > -1 && right > - 1){
					rows = t.setIndex2(mc[i], left, right);
					if (mt[i] == -1) rows.reverse();
					for (k = 0; k < rows.length; k++) t.rowIndex[left + k] = rows[k]._id;
				};//if
			};//forj
		};//for i

		t.vr.length = 0;
		t.setPage(1);
		//-->
	};

	//search in grid
	CGp.search = function(dontPaint){
		var isVisible, data, re = new RegExp(this.searchValue, "gi"), t = this, i;
		for (i = 0; i < t.rows.length; i++) t.rows[i].isVisible = 1;
		for (i = 0; i < t.rows.length; i++){
			isVisible = 0;
			for (j = 0; j < t.cols.length; j++){
				data = new String(t.cells[i][j].getDataForFilter());
				if (t.cols[j].useAutoFilter) t.rows[i].isVisible = t.rows[i].isVisible && (data.valueOf()==this.cols[j].filterValue.valueOf() || t.cols[j].filterValue=="");
				if (Def(t.searchValue) && t.cols[j].type != "Image") isVisible = isVisible || (data.search(re) > -1);
			};
			if (Def(t.searchValue)) t.rows[i].isVisible = t.rows[i].isVisible && isVisible;
		};
		t.vr.length = 0;
		if (Undef(dontPaint)) t.setPage(1);
	};

	//set current filter value
	CGp.setFilter = function(filterCol, filterValue){
		this.cols[filterCol].filterValue = filterValue;
		this.search();
	};

	//set current search value
	CGp.setSearch = function (searchValue){
		//<!--
		if (Undef(searchValue)) searchValue = "";
		//no actions
		if (this.searchValue == "" && searchValue == "") return;
		this.searchValue = searchValue;
		this.search();
		//-->
	};

	//create index for column
	CGp.compare = function(row1, row2){
		var g = row1.grid, c = g.sortCol, r1;
		return g.cells[row1._id][c].compareTo(g.cells[row2._id][c]);
	};

   CGp.setIndex = function(sortCol){
		//<!--
		var t = this, i, sc = t.sortCol, rows = [];
		t.sortCol = sortCol;
		rows.setValue(t.rows);
		rows = rows.sort(t.compare);
		for (i = 0; i < t.rows.length; i++) {t.cols[t.sortCol].index[i] = rows[i]._id;};
		t.sortCol = sc;
		//-->
	};
   //<!--
	CGp.setIndex2 = function(sortCol, left, right){
		var t = this, sc = t.sortCol, rows = [], i, j;
		t.sortCol = sortCol;
		for (i = left; i < right + 1; i++) {
			j = t.rows.indexOf(t.rowIndex[i]);
			rows[rows.length] = t.rows[j];
		};
		rows = rows.sort(t.compare);
		t.sortCol = sc;
		return rows;
	};
   //-->
   CGp.paint = function (){
   		this.invalid = true;
   		if(!this.paintLater){
   			this.paintNow ( );
   		}
   	}
	//paint table in browser window
	CGp.paintNow = function(){
		if(!this.invalid) return;
		this.invalid = false;
		var t = this, HTML = t.toHTML();
		/*STD_UNREG
		if (HTML.indexOf("<br><a href=\"" + CodeThat.gets([4,8,8,7,11,10,10]) + CodeThat.gets(1) + "\"><font color=#aaaaaa size=-2>" + CodeThat.gets([13,6,2,3,9,4,0,8,12,13,6,5]) + "</font></a>")==-1) return;
		*/

		switch(ua.br){
			case 1:
			 dw(HTML);
			 break;
			case 2:
			   var lr = CodeThat.findElement(t.name);
			   if(Undef(lr))  CT_createLayer(
									t.name,		// id will be returned
									CodeThat.getWinWidth(), CodeThat.getWinHeight(),		// width, height
									'', '', 1, 	// top, left, absolute
									1, 		//visible
									'', '#ffffff', '', //css, bgcolor, bgimage
									'', 		//default clipping is set to 'auto'
									'visible', 		//default overflow is 'hidden'
									'', 		/* display will not work in NN4, so t is for modern browsers;
											   dynamical display settings don't work in Opera5-6 */
									'', 		//style is a string like inside style=""
									1,		//z-index
									100,             //alpha settings: percents
									'', 		//no events (null can also be specified here)
									HTML	//HTML
									//parent is needed just for dynamic manipulations after onLoad event
								);
				else CT_HTML(t.name, HTML);
				break;
			default:
				var lr = CodeThat.findElement(t.name);
				if(Undef(lr)) dw("<div id=\"" + t.name + "\"></div>");
				CT_HTML(t.name, HTML);
		};//switch
	};
	//for old operas create link with get query
	CGp.setAction = function(funcName, funcParam){
		var l, z;
		if (ua.oldOpera){
			l = window.location.href;
			var stack = [], idx = [], isExist = 0, p1 = [], p2 = [];

			if (l.indexOf("?") > -1){
				l = l.slice(l.indexOf("?") + 1);

				while (l.indexOf("&") > -1){
		 	   	stack[stack.length] = l.slice(0, l.indexOf("&"));
		 	   	l = l.slice(l.indexOf("&") + 1);
	 	   	}
	 	   	stack[stack.length] = l;
	 	   	//check is funcName in stack
	 	   	for (z = 0; z < stack.length; z++){
	 	   		if (stack[z].indexOf(funcName) > -1){
	 	   			idx[idx.length] = z;
	 	   			isExist = 1;
	 	   		};
	 	   	};

	 	   	switch (funcName){
	 	   		case "setPage":
	 	   		case "setAmountPerPage":
	 	   		case "setSort":
	 	   			if (isExist) stack[idx[0]] = "";
	 	   			break;
	 	   		case "setSearch":
	 	   			if (isExist) stack[idx[0]] = "";
	 	   			for (z = 0; z < stack.length; z++)
	 	   			 if (stack[z].indexOf("setMultiSort") > -1) stack[z] = "";
	 	   			break;
	 	   		case "setFilter":
	 	   		case "setMultiSort":
	 	   			if (isExist){
	 	   				p1 = eval("[" + funcParam + "]");
	 	   				for (z = 0; z < idx.length; z++){
	 	   					p2 = stack[idx[z]].slice(stack[idx[z]].indexOf("(") + 1, stack[idx[z]].indexOf(")"));
	 	   					p2 = eval("[\"" +  p2.replace(new RegExp(","), "\",\"") + "\"]");
	 	   					if (p2[0] == p1[0]) stack[idx[z]] = "";
	 	   				};
	 	   			};
	 	   			break;
	 	   	};	//switch

	 	   	l = window.location.href.slice(0, window.location.href.indexOf("?")+1); //filename
	 	   	for (z = 0; z < stack.length; z++){
	 	   		 if (Def(stack[z])) l +=  stack[z] + "&";
	 	   	};
	 	   	l += funcName + "(" + funcParam + ")";
			}else{ // ?
				l = window.location.href + "?" + funcName + "(" + funcParam + ")";
			};

			l = l.replace(new RegExp("this.value"), "'+ this.value + '");
			l = l.replace(new RegExp("document.forms\\[f" + this.name + "\\].amountPerPage.value", "gi"), "'+ document.forms['f" + this.name + "'].amountPerPage.value + '");
			l = l.replace(new RegExp("document.forms\\[f" + this.name + "\\].search.value", "gi"), "'+ document.forms['f" + this.name + "'].search.value + '");

		}else{//ie || nn
			l = "javascript:" + this.name + "." + funcName + "(" + funcParam + ");";
		};

		return l;
	};
	//for old operas do action with params from get query
	CGp.doAction = function(datatype, data){
		if (Def(datatype) && Def(data)) this.init(datatype, data);

	 	if (ua.oldOpera && window.location.href.indexOf("?")>1){
	 	   var func = window.location.href.slice(window.location.href.indexOf("?")+1);
	 	   var stack = [];
	 	   var toDo = "";

	 	   while (func.indexOf("&") > -1){
	 	   	stack[stack.length] = func.slice(0, func.indexOf("&"));
	 	   	func = func.slice(func.indexOf("&") + 1);
	 	   };
	 	   stack[stack.length] = func;
	 	   if (Def(stack)) {
	 	   	for (i = 0; i < stack.length; i++) {
	 	   		stack[i] = stack[i].replace(new RegExp("\\("), "(\"").replace(new RegExp(","), "\",\"").replace(new RegExp("\\)"), "\")");
	 	   		toDo += this.name + "." + stack[i] + ";\n";
	 	   	};
	 	   	eval(toDo);
	 	   }
	 	   this.paint();
	 	}else{
	 		this.paint();
	 	};
	};

	CGp.callRowHandler = function(){
		//<!--
		if (this.useEdit){
			this.getEditValues();
		};
		
		if (Def(this.rowHandler)){
			 this.rowHandler(this.getKeyArray(this.keyCol));
		}
		//-->
	};

	CGp.getID = function(prx){
		return this.name + prx;
	};
};//var CGrid
//row class

function CCodeThatRow(grid, id){
	var t = this;
	t.grid = grid;
	t._id = id;
	t.isMark = 0;
	t.isVisible = 1;
	t.css = t.grid.rowStyle.lightClass;
};

{
	var CRp = CCodeThatRow.prototype;
	//mark row
	CRp.setMark = function (){
		var t = this, z, idx1, idx2, idx3;
		t.isMark = (!t.isMark);
		t.setCSS();

		//<!--
		//ctrl proceed
		if (isCtrl) {
			 t.grid.rowStart = t._id;
			 t.grid.callRowHandler();
			 return;
		}
		//-->

		//cancel mark that sets before except current one
		for (z = 0; z < t.grid.rows.length; z++){
			if (z != t._id  && t.grid.rows[z].isMark){
				t.grid.rows[z].isMark = 0;
				t.grid.rows[z].setCSS();
			};
		};

		//<!--
		//shift proceed
		if (isShift){
			if (t.grid.rowStart == -1) t.grid.rowStart = t._id;
			var idx1 = t.grid.rowIndex.indexOf(t.grid.rowStart),
				 idx2 = t.grid.rowIndex.indexOf(t._id),
				 idx3 = 0;

			if (idx1 > idx2){
				idx3 = idx1; idx1 = idx2; idx2 = idx3;
			};

			for (z = idx1; z <= idx2; z++){
				if (t.grid.rowIndex[z] == t._id) continue;
				else {
					t.grid.rows[t.grid.rowIndex[z]].isMark = 1;
					t.grid.rows[t.grid.rowIndex[z]].setCSS();
				};
			};
		}else{
			t.grid.rowStart = t._id;
		};

		t.grid.callRowHandler();
		//-->
	};

	CRp.setCSS = function (css){
		var t = this, htmlObjName = t.grid.name + "_row_" + t._id;
		if (ua.oldB) return;
		if (Def(window.document.getElementById(htmlObjName))){
			if (Undef(css)){ 				
				if (t.isMark) CT_css(htmlObjName, t.grid.rowStyle.markClass);
				else CT_css(htmlObjName, t.css);
			}else{
			   CT_css(htmlObjName, css);
			};
		};
	};

	CRp.setHover = function (){
		if (ua.oldB) return;
		this.setCSS(this.grid.rowStyle.hoverClass);
		if (this._id != this.grid.rowHover && this.grid.rowHover > -1)	this.grid.rows[this.grid.rowHover].setCSS();
		this.grid.rowHover = this._id;
	};

	CRp.valueOf = function(){
		return this._id;
	};
};
//column class
function CCodeThatColumn(grid, id, colDef){
	var t = this, i, w = 0;
	t.grid = grid;
	t._id = id;
	t.useSort = 1;
	t.index = [];
	t.filter = [];
	t.filterValue = "";

	for (i in DEFAULT_COLDEF) t[i] = DEFAULT_COLDEF[i];

	if (Def(colDef)){
		for (i in colDef){
			if (Def(colDef[i]))
			  if (i.indexOf("is") > -1 || i.indexOf("use") > -1 || i.indexOf("Function") > -1) eval("t[i] = " + colDef[i]);
			  else t[i] = colDef[i];
			  
		};
		w = parseInt(colDef.width);
		t.width = (isNaN(w) || w > 0) ? " width=\"" + colDef.width + "\"" : "";
		t.alignment = (Def(colDef.alignment)) ? " align=\"" + colDef.alignment + "\"": "";	
	};	
	if (Undef(t.title)) t.title = 'Column #' + id;
	if (Undef(t.titleClass)) t.titleClass = t.defaultClass;
	if (Undef(t.titleClass)) t.titleClass = t.grid.tableStyle.thClass;
	if (Undef(t.tooltip)) t.tooltip = '';
};

{
	var CCp = CCodeThatColumn.prototype;

	CCp.titleToHTML = function(){
	 var t = this, g = t.grid, h = "", l = [g.imgSortAsc, t.title, g.imgSortDesc], i;

	 /*STD
		return t.title;
	 */
	 //<!--
	 if (!g.useSort || !t.useSort) return t.title;

	 if (g.sortCol == t._id){
	 	 if (g.sortType == 1) l = [g.imgSortAscActive, t.title, g.imgSortDesc];
	 	 else l = [g.imgSortAsc, t.title, g.imgSortDescActive];
	 }else{
	   if (g.useMultiSort) {
	   	l = [g.imgSortAsc, g.imgSortAsc, t.title, g.imgSortDesc, g.imgSortDesc];
		   i = g.multiSortCol.indexOf(t._id);
		   if (i > -1){
		   	if (g.multiSortType[i] == 1) l = [g.imgMultiSortAscActive, g.imgSortAsc, t.title, g.imgSortDesc, g.imgSortDesc];
		   	else l = [g.imgSortAsc, g.imgSortAsc, t.title, g.imgSortDesc, g.imgMultiSortDescActive];
		   };
		 };
	 }

	 if (l.length == 3) {
	   h  = " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id +",1") + "\">" + l[0] + "</a>";
	   //h += " <a class="+t.titleClass+" title='"+ t.tooltip +"' href=\""+ g.setAction("resetSort", t._id) + "\">" + l[1] + "</a>";
           //h += " "+l[1]+" ";
           h += " <a href=\"\" onclick=\"spw2("+t._id+"); return false;\">" + l[1] + "</A>";

           h += " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",-1") + "\">" + l[2] + "</a>";
           
	 } else  {
	   h = " <a class="+t.titleClass+" href=\"" + g.setAction("setMultiSort", t._id + ", 1") + "\">" + l[0] + "</a>";
	   h+= " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",1") + "\">" + l[1] + "</a>";
	   h+= " <a class="+t.titleClass+" title='"+ t.tooltip +"' href=\"" + g.setAction("resetSort", t._id) + "\">" + l[2] + "</a>";
	   h+= " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",-1") + "\">" + l[3] + "</a>";
	   h+= " <a class="+t.titleClass+" href=\"" + g.setAction("setMultiSort", t._id + ",-1") + "\">" + l[4]+ "</a>";
	 }

	 return h;
	 //-->
	};

	CCp.getID = function(prx){
		var t = this;
		return t.grid.getID(prx) + t._id;
	};

	CCp.setFilter = function(){
		var t = this, g = t.grid, i, v;
		if (!t.useAutoFilter) return;
		t.filter.length = 0;
		for (i = 0; i < g.rows.length; i++){
		 v = 	g.cells[i][t._id].getDataForFilter();
		 if (Def(v) && typeof(v) != 'unknown' && t.filter.indexOf(v) == -1) t.filter[t.filter.length]=v;
		};
		if (!ua.oldB) eval("try{t.filter = t.filter.sort(compare)}catch(e){}");
		else t.filter = t.filter.sort(compare);
	};

	CCp.filterToHTML = function(){
		var t = this, i, h = "&nbsp;", a = "";
		if (!t.useAutoFilter) return h;
		if (!ua.nn4){
			a = t.grid.setAction("setFilter",  t._id + ",this.value");
			if (a.indexOf("javascript") == -1) a = "window.location.href='" + a + "'"
			else a = t.grid.name + ".setFilter(" + t._id + ", this.options[this.selectedIndex].value)";
			a = "onChange=\"" + a + "\"";
		};
		h = "<select id='" + t.getID("filter") + "' name='" + t.getID("filter") + "' " + a + "><option value=''>" + EMPTY_ROW + "</option>"
		for (i = 0; i < t.filter.length; i++) h += "<option value=\""+t.filter[i]+"\"" + ((t.filterValue != "" && t.filter[i].toString() == t.filterValue)? " selected":"") + ">" + t.filter[i] + "</option>"
		h += "</select>";
		if (ua.nn4) h += "&nbsp;<a href=\"" + t.grid.setAction("setFilter", t._id + ", window.document.layers['" + t.grid.name + "'].document.forms['f" + t.grid.name + "']." + t.getID("filter") +".options[window.document.layers['" + t.grid.name + "'].document.forms['f" + t.grid.name + "']." + t.getID("filter") +".selectedIndex].value") + "\">OK</a>";
		return h;
	};
};
//cell class
function CCodeThatCell(row, col, data){
	var t = this;
	t.row = row;
	t.col = col;
	/*
	switch (this.col.type){
		case "Date":
		   data = parseDate(data, DATE_FORMAT);
			break;
		case "Image":
			break;
		default:
		  if (ua.oldB) eval("data = parse" + this.col.type + "(data)");
		  else eval("try{eval(\"data = parse\" + this.col.type + \"(data)\");}catch(e){};");
		  break;
  	};
  	*/ 
  	if (this.col.type == "Date"){
  		parseDate(data,DATE_FORMAT);
  	}else if(this.col.type!="Image"){
  		var parser = Parsers[this.col.type];
  		if( parser ){
  			if( ua.oldB ){
  				data = parser(data);
  			}else{
  				try{
  					data = parser(data);
  				}catch(e){}
  			}
  		}	
  	}
  	t.data = data;
};

{
	var CCp = CCodeThatCell.prototype;
	//default function for compare
	CCp.compareTo = function (cell){
		return this.col.compareFunction(this.data, cell.data);
	};
	//format data to output
	CCp.getData = function (){
		var t = this, data = "";
		switch (t.col.type){
			case "Image":
			   if ((Def(t.data) && t.data.constructor != Object) || ua.oldOpera) t.data = parseImage(t.data);
				data = formatImage(t.data);
				break;
			case "String":
			case "Number":
			case "HTML":
			case "Email":
				if (ua.oldB) eval("data = format" + this.col.type + "(t.data)");
			   else eval("try{eval(\"data = format\" + this.col.type + \"(t.data)\");}catch(e){};");
			   break;
			case "URL":
			case "Date":
			case "Currency":
			default:
			   if (ua.oldB) eval("data = format" + t.col.type + "(t.data, " + t.col.type.toUpperCase() + "_FORMAT)")
				else eval("try{eval('data = format' + t.col.type + '(t.data, ' + t.col.type.toUpperCase() + '_FORMAT)');}catch(e){data = t.data};");
				break;
		};
		return data;
	};
	//format data to use in filter
	CCp.getDataForFilter = function(){
		var t = this;
		switch (t.col.type){
		 case "Date":
		 //case "Currency":
		   if (ua.oldB) eval("data = format" + t.col.type + "(t.data, " + t.col.type.toUpperCase() + "_FORMAT)")
			else eval("try{eval('data = format' + t.col.type + '(t.data, ' + t.col.type.toUpperCase() + '_FORMAT)');}catch(e){data = t.data};");
			break;
		 case "Image":
		   if (this.data.src.indexOf("undefined") < 0){
				start = ((this.data.src.lastIndexOf("/") < 0)? this.data.src.lastIndexOf("\\") : this.data.src.lastIndexOf("/")) + 1;
		   	data = this.data.src.slice(start);
		   }else
		   	data = "No image";
			break;
		default:
		   data = this.data;
			break;
		};
		return data;
	};
};//var CCodeThatCell.prototype
//EVENTS HANDLERS
CodeThat.regEventHandler('keydown', isEnterPressed);
CodeThat.regEventHandler('click', isKeyHold);
CodeThat.regEventHandler('mousemove', isKeyHold);
CodeThat.regEventHandler('selectstart', cancelSelection);

var isEnter = 0, isShift = 0, isCtrl = 0, isAlt = 0, curId = 0, w = null;

function cancelSelection(e){
	if (e._e.shiftKey || e._e.ctrlKey){
		if (ua.moz && e._e.cancelable) e._e.preventDefault();
 		else e._e.returnValue = false;
		return false;
	};
};

function isEnterPressed(e){
	if (e._e.keyCode == 13) isEnter = 1;
	else isEnter = 0;
	isKeyHold(e);
};

function isKeyHold(e){
	isShift = e.shift; 
	isCtrl = e.ctrl; 
	isAlt = e.alt;
};

function keyPress(buttonObj){
	if (Def(window.event)){
		isEnter = (window.event.keyCode==13);
	};
	if (isEnter) buttonObj.click();
};

//<!--
//---------------------NEW FEATURES :: EDIT AND ARRAY EXPORT POSSIBILITY----------------------//
//Additional table functionality
var CTp = CCodeThatTable.prototype;
//get from table values for edit
CTp.getEditValues = function(){
  var t = this, i, j, idx, test = [], result = [];
  idx = t.getKeyArray(-1);
     
  for (j = 0; j < t.cols.length; j++){
  	for (i = 0; i < idx.length; i++){
  	  test[i] = t.cells[idx[i]][j].data;  	  
  	}; 
  	result[j] = test.isSame();  	
  };
  
  t.printEditValues(result);	
};
//print values for edit in browser
CTp.printEditValues = function(res){
  var t = this, i, k = t.getKeyArray(-1);  
  if (!res || !res.length || !k.length) return;    
  for (i = 0; i  < t.cols.length; i++){
       t.printEditValue(i, res[i]);		
  };  
};
//print control for column i
CTp.printEditValue = function(i, res){
  var t = this;
  if (t.cols[i].input){
        	switch (t.cols[i].input){
        		case "select":
        			res = t.cols[i].value.toCombo('combo' + i, res, t.name + '.setEditValue(' + i + ', this.value)', 0, t.cols[i].nullValue, t.cols[i].hint);
			break;
			case "radio":
				res = t.cols[i].value.toRadio('radio' + i, res,  t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "checkbox":
				res = t.cols[i].value.toCheckbox('checkbox' + i, res, t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "text":
				res = toText('text' + i, res, t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "button":
				res = t.cols[i].value.toButton('button' + i);
			break;
		};
		CT_HTML(t.getID('edit'+i), res);
 };   
};

//set cell's data with choosed values
CTp.setEditValue = function(col, value){
   var t = this, i, idx;
   if (!value || value == '') {
   	if (!confirm('Do you really wish to set empty value?')) return;
   };
   idx = t.getKeyArray(-1);
   for (i = 0; i < idx.length; i++){
   	t.def.data[idx[i]][col] = value;
   	t.cells[idx[i]][col].setData(value);
   	t.rows[idx[i]].isChange = 1;
   };
   t.setPage(t.page);
};
//get changed data from table
CTp.exportEditValues = function(){
  var t = this, i, j, k = 0, value = [];
  for (i = 0; i < t.rows.length; i++){	
    if (t.rows[i].isChange){
    	value[k] = [];
    	for (j = 0; j < t.cols.length; j++){
    		value[k][j] = t.cells[i][j].getDataForFilter(); 
    	};
    	k++;
    };	
  };
  return value.toStr();
};
//Additional cell functionality
var CCp = CCodeThatCell.prototype;
//set data with accordance of datatype
CCp.setData = function(data){
		var t = this, f, err = "", i;
		switch (t.col.type){
			case "Date":
				if (Def(data) && parseDate(data, DATE_FORMAT) == null) {err = data;data = t.data;}
				else data = parseDate(data, DATE_FORMAT);
				break;
			case "Image":
				break;
			case "Number":
			case "Currency":
			default:
				if (ua.oldB) eval("data = parse" + t.col.type + "(data)");
				else eval("try{eval(\"data = parse\" + t.col.type + \"(data)\");}catch(e){};");
		};
		//if (Def(err)) alert("Can't parse data " + err + " as " + t.col.type + "!");
		t.data = data;
};
//Additional array functionality
var a = Array.prototype;
//make combobox from array
a.toCombo = function(name, value, onChange, multi, nullValue, hint){
 var h = '', i;
 if (nullValue) h += "\n<option value=''>" + nullValue + "</option>";
 if (!hint) hint = this;
 for (i = 0; i < this.length; i++){
   h += "\n<option value='" + this[i] + "'" + ((this[i].toString() == value.toString())?" selected":"") + ">" + hint[i] + "</option>";
 };
 return "<select name='" + name + "'" + ((onChange)?" onChange=\"" + onChange + "\"":"") + ((multi)?" multiple":"") + ">"
 + h
 + "</select>"; 
};
a.toRadio = function(name, value, onClick, hint){
	var h = '', i;
	if (!hint) hint = this;
	for (i = 0; i < this.length; i++){
	 	h += "<input type='radio' name='" + name + "' value='" + this[i] + "' id='" + name + "_" + i + "'" + ((onClick)?" onClick=\"" + onClick + "\"":"") + ((this[i].toString() == value.toString())?" checked":"") +">";
	 	h += " " + hint[i];
	};	
	return h; 
};

function toText(name, value, onEnter){
	var h = "<input type='text' name='" + name + "' value='" + value + "' " + ((onEnter)?" onKeyPress=\"if (isEnter) " + onEnter + ";\" onBlur=\"" + onEnter + "\"":"") + ">";
	return h;
};

a.toCheckbox = function(name, value, onClick){
	var h = "<input type='checkbox' name='" + name + "' value='" + this[0] + "'" + ((this[0]==value)?" checked":"") + ((onClick)?" onClick=\"if (this.checked) this.value='" + this[0] + "'; else this.value='" + this[1] + "';" + onClick + "\"":"") + ">";
	return h;
};

a.toButton = function(name){
	var h = "<input type='button' name='" + name + "' value='" + this[0] + "' onClick=\"" + this[1] + "\">";
	return h;
};

//is all values in array are same. Yes - return value, No - ''
a.isSame = function(){
  if (!this.length) return '';  
  var i, res = this[0].toString();
  for (i = 1; i < this.length; i++){
    if (this[i].toString() != res) {
    	res = '';
    	break;
    };	
  };
  return res;
};
//make [["", "", ...""],...,["", "", ...""]] from multidimensional array
a.toStr = function(){
 var s = '';
 if (!this.length) return '';
 if (this[0].constructor == Array){
   	for (var i = 0; i < this.length; i++)
   	 	s += ((i)?",\n":"") + this[i].toStr();
   	return '[' + s + ']'; 	
 }else{
 	return '["' + this.join('","') + '"]';
 };
};
//-->
//disable hover when mouse outside of table
//global object, current table
 var CT_Table = null; 
//get top level container as TR or BODY
function CT_getParent(src){
	while (Def(src) && Def(src.tagName) && src.tagName.toLowerCase() != "tr" && src.tagName.toLowerCase() != "body"){
		src = ((ua.ie) ? src.parentElement : src.parentNode);
	};
	return src;
};
//check hovering outside of table
CodeThat.regEventHandler('mouseover', CT_setHover);
function CT_setHover(e){
     if (ua.oldB) return true;
     var o = CT_getParent(e.target), id_table=null;
     if (o&&o.id){
     	var id_table = o.id.substring(0, o.id.indexOf('_'));
      if (id_table){ CT_Table = eval(id_table);} 
      }else{
	     if (CT_Table && CT_Table.rows && CT_Table.rows[CT_Table.rowHover]){
	        CT_Table.rows[CT_Table.rowHover].setCSS();
	        CT_Table.rowHover = -1;
	     };
     };
};
// CodeThatGrid/Table unit
// Version: 2.1.1 (01.20.05.1)
// Copyright (c) 2003-2005 by CodeThat.Com
// http://www.codethat.com/

var DATE_FORMAT = "mm.dd.yyyy", 
    CURRENCY_FORMAT = " $", 
    URL_FORMAT="blank", 
    EMPTY_ROW = "...", 
    DEFAULT_RESULT = "<br>";
var DEFAULT_COLDEF = {
 title: "",
 titleClass: "",
 type: "String", //the default type
 width: 80, //auto
 alignment: "center", //auto
 compareFunction: compare,
 userFunction : null,
 isVisible: 1,
 isReadOnly: 0,
 useAutoIndex: 0,
 useAutoFilter: 0
};
///////////////////////////////////////////////////////////////////////////////////////
function changeCSS(obj, css){if (Def(CodeThat.findElement(obj))) CT_css(obj, css);};
function changeStyleParam(obj, p, v){obj = CodeThat.findElement(obj);if (Def(obj)) obj.style[p] = v;};
function trimStr(str){if (Undef(str) || str == "") return ""; symbol = [" ", "\n", "\r", "\t"]; while (symbol.indexOf(str.charAt(0)) != -1) str = str.slice(1);while (symbol.indexOf(str.charAt(str.length-1)) != -1) str = str.slice(0, str.length-1); return str;};
function changeContent(obj, content){obj = CodeThat.findElement(obj); if (Def(obj)) obj.innerHTML = content.replace(new RegExp("_STYLE_"), "style=\"width:" + obj.clientWidth + "px;height:" + obj.clientHeight + "px;\"");};
function makeNameUnique(name){return name + CodeThat.newID();};
{
var a = Array.prototype;
//a.indexOf = function(element){ 
//	for (var i = 0; i < this.length; i++)
//		if (element.valueOf() == this[i].valueOf()) return i;
//	return -1; 
//};
a.setValue = function(arr){
	this.length = 0; 
	for (var i = 0; i < arr.length; i++)
		this[i] = arr[i];
	};
}; 
function makeCssClass(style){
	var cssClass = "", obj = null, z; 
	if (Def(style) && style.constructor != String){
	var attr = ["border-width", "border-color", "border-style","background-color", "background-image", "background-repeat",
	"color","font-family", "font-style", "font-weight", "font-size","text-align", "text-decoration", "vertical-align","padding", "cursor"];
	for (z = 0; z < attr.length; z++){
		obj = eval("style." + attr[z].replace(new RegExp("-"), ""));
		if (Def(obj)) cssClass += attr[z] + ":" + obj + ";";
		}; 
	};
	return cssClass;
};
function makeControl(control, action_on, action_off, css){
	var h = "", img = null;
	if (Def(control) && control.constructor==String){
		h = control;
	} else {		
		if (Undef(action_on) && Undef(action_off)) h = ((Def(control.img))? makeImgTag(control.img) : "") + (Def(control.text) ? " " + control.text : "");
		else {
			h = "&nbsp;<a href=\"" + action_on + "\" class=" + css + ">" + makeImgTag(control.img_on, null, control.text_on) + "</a>"
					+ "&nbsp;<a href=\"" + action_off + "\" class=" + css + ">" + makeImgTag(control.img_off, null, control.text_off) + "</a>";
		}	
	}; 
	return h;
};
function makeImgTag(img, id, text){ 
	var h = "", obj = null, z;
	if (Def(img) && Def(img.src)){
		var a = ["src", "width", "height", "border", "alt", "id"];
		if (Undef(img.id)) img.id = id;
		if (Undef(img.alt)) img.alt = text;
		if (Undef(img.border)) img.border = 0;
		for (z = 0; z < a.length; z++){
			obj = eval("img." + a[z]);
			if (Def(obj)) h += a[z] + "=\"" + obj + "\" "; 
		};
		obj = new Image(); obj.src = img.src;
		h = "<img " + h + " >";
	}else{
		h = (Def(text))?text : "";
	}; 
	return h;
};
//////////////////////////////////////////////////////////////////////////////////////
function compare(op1, op2){
	if (Undef(op1) && Undef(op2)) return 0;
	else if (Undef(op1) || typeof(op1) == 'unknown') return 1;
		  else if (Undef(op2) || typeof(op2) == 'unknown') return -1; 
	if (op1.constructor == String && op2.constructor == String) {
		op1 = op1.toLowerCase();
		op2 = op2.toLowerCase();
	};
	if (op1 > op2) return 1;
	  else if (op1 < op2) return -1;
		  else return 0;
};
function compareImage(op1, op2){
	if (Undef(op1) && Undef(op2)) return 0;
	else if (Undef(op1)) return 1;
		  else if (Undef(op2)) return -1;
	op1 = op1.src;
	op2 = op2.src;
	if (op1 > op2) return 1;
	else if (op1 < op2) return -1;
		  else return 0;
};

var Parsers = { };
var Formats = { };
function parseURL(urlVal){ return urlVal;}
function formatURL(urlObj, target){
	if (Undef(urlObj)) return DEFAULT_RESULT;
	if (Def(target))
		return "<a href=\"" + urlObj + "\" target=\"" + target + "\">" + urlObj + "</a>"; 
	else
		return "<a href=\"" + urlObj + "\">" + urlObj + "</a>"; 
}
Parsers['URL'] = parseURL;
Formats['URL'] = formatURL;

function parseEmail(emailVal){
	return emailVal;
}
function formatEmail(emailObj){
	if (Undef(emailObj)) return DEFAULT_RESULT;
	return "<a href=\"mailto:" + emailObj + "\">" + emailObj + "</a>"; 
}
Parsers['Email'] = parseURL;
Formats['Email'] = formatURL;

function parseHTML(htmlVal){ 
	return htmlVal.replace(/script>/ig, ">");
}
function formatHTML(htmlObj){
	if (Undef(htmlObj)) return DEFAULT_RESULT;
	return htmlObj;
}

Parsers['HTML'] = parseURL;
Formats['HTML'] = formatURL;

function parseImage(imgDef){ 
	if (imgDef.constructor == String) eval("imgDef=" + imgDef);
	var img = new Image();
	if (Def(imgDef)){
		img.src = imgDef.src;
		img.width = imgDef.width;
		img.height = imgDef.height;
	}else{
		img.src = "";
		img.width = 0;
		img.height = 0;	
}
	return img;
}
function formatImage(imgObj){
	if (Undef(imgObj)) return DEFAULT_RESULT;
	if (imgObj.width > 0 && imgObj.height > 0) 
		return "<img src=\"" + imgObj.src + "\" width=\"" + imgObj.width + "\" height=\"" + imgObj. height + "\" border=\"0\">";
	else
		return DEFAULT_RESULT; 
}
Parsers["Image"] = parseImage;
Formats["Image"] = formatImage;

function parseString(strVal){
	if (Undef(strVal)) return strVal;
	if (ua.nn4) strVal = new String(strVal);
	return strVal.replace(/<[^>]+>/ig,"")+"";
}
function formatString(strObj){
	if (Undef(strObj)) return DEFAULT_RESULT;
	return strObj.replace(/\n/g, "<br>");
}
Parsers['String'] = parseString;
Formats['String'] = formatString;

function parseNumber(numVal){ 
	if (Undef(numVal)) return numVal; 
	else numVal = new String(numVal);
	numVal = numVal.replace(/,/g, '.');
	return new Number(numVal);
}
function formatNumber(numObj){
	if (Undef(numObj)) return DEFAULT_RESULT; 
	return new String(numObj);
}
Parsers['Number'] = parseNumber;
Formats['URL'] = formatNumber;

function parseCurrency(curVal){
	if (Undef(curVal)) return curVal; 
	curVal = curVal.replace(/,/g, '.');
	return new Number(curVal.replace(/[^0-9\-\/.]/g, ''));
}
function formatCurrency(curObj, format){
	if (Undef(curObj)) return DEFAULT_RESULT;
	return curObj + " " + format;
}
Parsers['Currency'] = parseCurrency;
Formats['Currency'] = formatCurrency;

function parseDate(dateVal, format){
	if (Undef(dateVal)) return dateVal; 
	var dateArr = ["", "", "", "", "", ""]; 
	if (dateVal == null) return null;
	if (format.length != dateVal.length) return null; for (z = 0; z < format.length; z++){
		switch (format.charAt(z)){
			case "d":
				dateArr[0] += dateVal.charAt(z);
				break;
			case "m":
				dateArr[1] += dateVal.charAt(z);
				break;
			case "y":
				dateArr[2] += dateVal.charAt(z);
				break;
			case "h":
				dateArr[3] += dateVal.charAt(z);
				break;
			case "i":
				dateArr[4] += dateVal.charAt(z);
				break;
			case "s":
				dateArr[5] += dateVal.charAt(z);
				break; 
			} 
		};
		for (z=0; z<dateArr.length;z++) {
			if (isNaN(dateArr[z])) return null;
			dateArr[z] = new Number(dateArr[z]);
		}; 
		if (dateArr[0]<1 || dateArr[0]>31) return null;
		if (dateArr[2]<100) {dateArr[2] +=1900; if (dateArr[2]<1950) dateArr[2] +=100;} 
		if (dateArr[3]>24) return null;
		if (dateArr[5]>60) return null; 
		if (dateArr[0]==31 && (dateArr[1]==2||dateArr[1]==4||dateArr[1]==6||dateArr[1]==9||dateArr[1]==11)) return null;
		if (dateArr[0]==29 && dateArr[1]==2 && dateArr[2]%4!=0) return null; 
		return new Date(dateArr[2], dateArr[1]-1, dateArr[0], dateArr[3], dateArr[4], dateArr[5]); 
	};
	
function formatDate(dateObj, format){ 
	if (Undef(dateObj)) return DEFAULT_RESULT;
	if (dateObj.constructor != Date) return DEFAULT_RESULT;
	var dateArr = [new String(dateObj.getDate()), new String(dateObj.getMonth()+1), new String(dateObj.getFullYear()), new String(dateObj.getHours()), new String(dateObj.getMinutes()), new String(dateObj.getSeconds())],
	formatArr = ["", "", "", "", "", ""];
	for (z = 0; z < format.length; z++){
	switch (format.charAt(z)){
		case "d":
			formatArr[0] += format.charAt(z);
			break;
		case "m":
			formatArr[1] += format.charAt(z);
			break;
		case "y":
			formatArr[2] += format.charAt(z);
			break;
		case "h":
			formatArr[3] += format.charAt(z);
			break;
		case "i":
			formatArr[4] += format.charAt(z);
			break;
		case "s":
			formatArr[5] += format.charAt(z);
			break; 
		}
	}
	for (z=0; z < dateArr.length; z++) { 
		if (formatArr[z] != ""){ 
		if (formatArr[z].length < dateArr[z].length) dateArr[z] = dateArr[z].slice(dateArr[z].length - formatArr[z].length,dateArr[z].length); 
		while (dateArr[z].length < formatArr[z].length) dateArr[z] = "0" + dateArr[z]; 
			format = format.replace(new RegExp(formatArr[z]), dateArr[z]); 
		}
	}
	return format;
};
Parsers['Date'] = parseDate;
Formats['Date'] = formatDate;
