

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// CLIENT LIBRARY / NEGORA © 2007
	//
	// Description: Functions to work with the client objects regardless of the browser model.
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// SHORTCUT FUNCTIONS
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function GET (_id) {
		return (CliElem.get (_id));
	}
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// NAVIGATOR
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliNav () {
	}
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// CONSTANTS
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
		CliNav.ieobj/*@cc_on = {
		quirksmode : (document.compatMode == "BackCompat"),
		version : parseFloat (navigator.appVersion.match (/MSIE (.+?);/) [1])
		}@*/;
		
		CliNav.IE = false;
		if (CliNav.ieobj != null) CliNav.IE = true;
		delete CliNav.ieobj;
		
		CliNav.GECKO = false;
		if (navigator.product != null && navigator.product.toLowerCase () == "gecko") CliNav.GECKO = true;
		
		CliNav.OPERA = false;
		if (window.opera != null) CliNav.OPERA = true;
		
		CliNav.WIN = false;
		if (navigator.appVersion.toLowerCase ().indexOf ("win") != -1) CliNav.WIN = true;
		
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// SCREEN
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliScreen () {
	}
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE SCREEN FEATURES
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliScreen.getW = function () {
			return window.screen.width;
		}
		CliScreen.getH = function () {
			return window.screen.height;
		}
		CliScreen.getAvailW = function  () {
			return window.screen.availWidth;
		}
		CliScreen.getAvailH = function () {
			return window.screen.availHeight;
		}
	
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// WINDOW
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliWin () {
	}
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE WINDOW FEATURES
		//
		// ? _frame			Frame						O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.getX = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				if (_frame.$dom_chroma_lt == null) CliWin.regIEChroma (_frame);
				return _frame.screenLeft - _frame.$dom_chroma_lt;
			} else {
				return _frame.screenX;
			}
			
		}
		
		CliWin.getY = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				if (_frame.$dom_chroma_lt == null) CliWin.regIEChroma (_frame);
				return _frame.screenTop - _frame.$dom_chroma_tp;
			} else {
				return _frame.screenY;
			}
			
		}
		
		CliWin.getW = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				if (_frame.$dom_chroma_lt == null) CliWin.regIEChroma (_frame);
				return _frame.$dom_chroma_lt + _frame.document.documentElement.offsetWidth + _frame.$dom_chroma_rt;
			} else {
				return _frame.outerWidth;
			}
			
		}
		
		CliWin.getH = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				if (_frame.$dom_chroma_lt == null) CliWin.regIEChroma (_frame);
				return _frame.$dom_chroma_tp + _frame.document.documentElement.offsetHeight + _frame.$dom_chroma_bt;
			} else {
				return _frame.outerHeight;
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE SCROLL FEATURES
		//
		// ? _frame			Frame								O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.getScrollX = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				return _frame.document.documentElement.scrollLeft;
			} else {
				return _frame.pageXOffset;
			}
			
		}
		
		CliWin.getScrollY = function (_frame) {
			
			if (_frame == null) _frame = window;
			
			if (CliNav.IE) {
				return _frame.document.documentElement.scrollTop;
			} else {
				return _frame.pageYOffset;
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT SETS THE SCROLL FEATURES
		//
		// _x					Coordinate in the X axys						i
		// _y					Coordinate in the Y axys						i
		// ? _frame			Frame												O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.setScrollX = function (_x, _frame) {
			
			if (_frame == null) _frame = window;
			_frame.scrollTo (_x, domScrollGetY (_frame));
			
		}
		
		CliWin.setScrollY = function (_y, _frame) {
			
			if (_frame == null) _frame = window;
			_frame.scrollTo (domScrollGetX (_frame), _y);
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT ALIGNS A WINDOW TO THE SCREEN OR ANOTHER WINDOW
		//
		// _align_ref				Alignment reference						S			screen | win
		// _align					Horizontal alignment						S			right | center | left | null
		// _valign					Vertical alignment							S			top | middle | bottom | null
		// ? _frame				Frame											O
		// ? _frame_ref			Reference frame							O			Only if "_align_ref = win"
		//
		// Note 1: On Opera, since it doesn't allow windows to move out of the working area, "screen" is switched
		// by "win" always.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
		CliWin.align = function (_align_ref, _align, _valign, _frame, _frame_ref) {
			
			if (_frame == null) _frame = window;
			if (CliNav.OPERA && _align_ref == "screen") _align_ref = "win";
	
			// It gets the target frame coordinates and size.
			var list_t = {"x": CliWin.getX (_frame), "y": CliWin.getY (_frame), "w": CliWin.getW (_frame), "h": CliWin.getH (_frame)};
	
			// It gets the screen coordinates and size.
			var list_r = {"x": 0.0, "y": 0.0, "w": "" + CliScreen.getAvailW (_frame_ref), "h": "" + CliScreen.getAvailH (_frame_ref)};
			
			// If the alignment reference is another frame, it substitues that values by the frame ones.
			if (_align_ref == "win") {
				list_r ["x"] = CliWin.getX (_frame_ref);
				list_r ["y"] = CliWin.getY (_frame_ref);
				list_r ["w"] = CliWin.getW (_frame_ref);
				list_r ["h"] = CliWin.getH (_frame_ref);
			}		
			
			// It calculates the final coordinates of the frame, depending on the alignment variables.
			var list_coor = CoreGeom.alignTwo (list_t, list_r, _align, _valign, "inner");
			
			// It moves the frame to the new position.
			_frame.moveTo (list_coor ["x"], list_coor ["y"]);
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT OPENS A WINDOW ALIGNED TO THE SCREEN OR ANOTHER WINDOW
		//
		// _url						URL											S			Like in the "window.open" command
		// _name					Frame name									S			Like in the "window.open" command
		// _attrib					Attributes									S			Like in the "window.open" command
		// _align_ref				Alignment reference						S			screen | win
		// _align					Horizontal alignment						S			right | center | left | null
		// _valign					Vertical alignment							S			top | middle | bottom | null
		// ? _frame_ref			Reference frame							O			Only if "_align_ref = "win"
		//
		// Note 1: The URL must be absolute.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.openAligned = function (_url, _name, _attrib, _align_ref, _align, _valign, _frame_ref) {

			if (_frame_ref == null) _frame_ref = window;
			if (_attrib != "") _attrib += ", ";
			
			// It adapts the URL respect to the "wopen.html" location. This file is used to load the page.
			if (_url.charAt (0) != "/" && _url.substring (0, 4).toLowerCase () != "http")
				_url = window.location.pathname.replace (new RegExp ("[^/]+$", "gm"), _url);
			
			// If the reference frame hasn't got a "$dom_list_onchildload" list, it's made.
			if (_frame_ref.$dom_list_onchildload == null) _frame_ref.$dom_list_onchildload = new Object ();
			
			// It builds a temporary list of parameters which will be used for the alignment and load of the URL.
			_frame_ref.$dom_list_onchildload [_name + "_wopen"] = {"url": _url, "align_ref": _align_ref, "align": _align, "valign": _valign};

			return _frame_ref.open ($INIT.getSysPath () + "html/wopen.html", _name, _attrib + "left=0, top=0");
	
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT FIRES A CUSTOMIZED FUNCTION IN THE PARENT / OPENER FRAME (IF EXISTS) WHEN THIS ONE IS FULLY LOADED
		//
		// ? _list_var			List of arbitrary variables	to be passed to the function						O
		// ? _alt_name		Alternative name to identify the caller window								S
		//
		// Note 1: This function allows the parent / opener frame to execute asynchronous code from this frame once it's fully
		// loaded, what avoids problems caused by code which hasn't been loaded yet.
		// Note 2: The receiver function must be stored into a list in the parent / opener frame called "$dom_list_onchildload".
		// Note 3: They key used in the list must match the name of the caller window.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.loaded = function (_list_var, _alt_name) {
			
			if (_alt_name == null) _alt_name = window.name;
			
			if (window.parent != window && window.parent.$dom_list_onchildload != null
			    && window.parent.$dom_list_onchildload [_alt_name] != null) {
					window.parent.$dom_list_onchildload [_alt_name] (_list_var);
			} else if (window.opener != null && window.opener.$dom_list_onchildload != null
				&& window.opener.$dom_list_onchildload [_alt_name] != null) {
					window.opener.$dom_list_onchildload [_alt_name] (_list_var);
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IE FIX: IT REGISTERS THE SIZES OF EACH PART OF A FRAME CHROMA AS NEW ATTRIBUTES OF THE OWN FRAME
		//
		// ? _frame			Frame												O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliWin.regIEChroma = function (_frame) {
				
			// It gets the coordinates and size of the original client area.
			var x_ca = _frame.screenLeft;
			var y_ca = _frame.screenTop;
			var w_ca = _frame.document.documentElement.offsetWidth;
			var h_ca = _frame.document.documentElement.offsetHeight;
			
			// It resizes the frame to fill the whole available area of the screen (-1 to evite maximizing) and moves it to the coordinate (0, 0).
			_frame.moveTo (0, 0);
			_frame.resizeTo (CliScreen.getAvailW (_frame) - 1, CliScreen.getAvailH (_frame) - 1);			
			
			// It calculates the sizes of each part of the frame chroma and registers them as attributes of the own frame.
			_frame.$dom_chroma_tp = _frame.screenTop;
			_frame.$dom_chroma_rt = CliScreen.getAvailW (_frame) - _frame.screenLeft - _frame.document.documentElement.offsetWidth - 1;
			_frame.$dom_chroma_bt = CliScreen.getAvailH (_frame) - _frame.screenTop - _frame.document.documentElement.offsetHeight - 1;
			_frame.$dom_chroma_lt = _frame.screenLeft;
			
			// It calculates the original coordinates and size of the frame.
			var x = x_ca - _frame.$dom_chroma_lt;
			var y = y_ca - _frame.$dom_chroma_tp;
			var w = w_ca + _frame.$dom_chroma_lt + _frame.$dom_chroma_rt;
			var h = h_ca + _frame.$dom_chroma_tp + _frame.$dom_chroma_bt;
			
			// It restores the window to its original size and position.
			_frame.resizeTo (w, h);
			_frame.moveTo (x, y);
			
		}
	
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// LOCATION
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliLocation () {
	}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE NAME OF THE FILE FROM A LOCATION OBJECT
		//
		// _location				Location object from a frame															O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliLocation.fileName = function (_location) {
			return _location.pathname.substring (_location.pathname.lastIndexOf ("/") + 1);
		}
	
	
	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// ELEMENT
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliElem () {
	}
	
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS AN ELEMENT FROM A FRAME
		//
		// _id					Element ID							S
		// ? _frame			Frame									O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.get = function (_id, _frame) {
			if (_frame == null) _frame = window;
			return _frame.document.getElementById (_id);
		}
	

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS AN ELEMENT FEATURES
		//
		// _elem			Element								O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.getX = function (_elem) {
			
			var x = 0;
			while (_elem.offsetParent != null) {
				x += CliElem.getRelX (_elem);
				_elem = _elem.offsetParent;		
			}
			
			return x;
			
		}
		
		CliElem.getRelX = function (_elem) {
			
			var x = _elem.offsetLeft;
			
			// On IE, the default body margin is applied to it as a pure CSS margin, whereas other browser applies it as a padding.
			// Because of this, to get the offset of an element in the body coordinate system, it's necessary to know the value of that margin.
			if (CliNav.IE && _elem.offsetParent == _elem.ownerDocument.body) {
				x += _elem.offsetParent.offsetLeft;
			}
	
			return x;
			
		}
		
		CliElem.getY = function (_elem) {
			
			var y = 0;
			while (_elem.offsetParent != null) {
				y += CliElem.getRelY (_elem);
				_elem = _elem.offsetParent;
			}
			
			return y;
			
		}
		
		CliElem.getRelY = function (_elem) {
			
			var y = _elem.offsetTop;
	
			// On IE, the default body margin is applied to it as a pure CSS margin, whereas other browser applies it as a padding.
			// Because of this, to get the offset of an element in the body coordinate system, it's necessary to know the value of that margin.
			if (CliNav.IE && _elem.offsetParent == _elem.ownerDocument.body) {
				y += _elem.offsetParent.offsetTop;
			}
	
			return y;
			
		}
		
		CliElem.getW = function (_elem) {
			
			if (_elem.tagName.toLowerCase () != "table") {
				return _elem.offsetWidth;
			} else {
				return parseInt (_elem.width, 10);
			}
			
		}
		
		CliElem.getH = function (_elem) {
			return _elem.offsetHeight;
		}

	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE HTML CODE OF AN ELEMENT
		//
		// _elem				Element									O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.getHTML = function (_elem) {
			
			if (CliNav.IE) {
				
				return _elem.outerHTML;
				
			} else {
				
				var ly = document.createElement ("div");
				ly.appendChild (_elem.cloneNode (true));
				return ly.innerHTML;
	
			}
		
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE WINDOW / DOCUMENT WHERE THE ELEMENT IS CONTAINED
		//
		// _elem			Element								O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
		CliElem.getWin = function (_elem) {
			
			var doc = _elem.ownerDocument;
			if (doc == null) doc = _elem;
			
			if (CliNav.IE) {
				return _elem.parentWindow;
			} else {
				return _elem.defaultView;
			}
			
		}

	 
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT ADDS AN EVENT TO AN ELEMENT (BUBBLE STAGE)
		//
		// _elem					Element										O
		// _eve_name			Event	name									S
		// _func					Listener function							O
		//
		// Note 1: The listener receives 2 parameters: the event and the element which is handling it.
		// 
		// Note 2: Don't use "this" in the listener function to get a pointer to the element which is currently handling the event
		// because its behaviour is browser dependable. Use the 2nd parameter instead.
		//
		// Note 3: To use variables in the listener whose value need to be set during the declaration of it, add them
		// as attributes of "_elem" previously, and recover them inside of that listener. Example: elem.my_var = my_value.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.addEvent = function (_elem, _eve_name, _func) {
			
			if (CliNav.IE) {
				_elem.attachEvent (_eve_name, function () { _func (event, _elem); } );
			} else {
				_eve_name = _eve_name.substring (2);
				_elem.addEventListener (_eve_name, function (_eve) { _func (_eve, _elem); }, false);
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT REMOVES AN EVENT OF AN ELEMENT
		//
		// _elem					Element											O
		// _eve_name			Event	name										S
		// _func					Listener function								O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.remEvent = function (_elem, _eve_name, _func) {
			
			if (CliNav.IE) {
				_elem.detachEvent (_eve_name, _func);
			} else {
				_elem.removeEventListener (_eve_name, _func, true);
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT FIRES AN EVENT WITH THE DESIRED FEATURES ON THE SPECIFIED ELEMENT
		//
		// _elem				Element																				O
		// _type				Type of event																		S
		// ? _eve				Existing event from which the event attributes will be taken				O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliElem.fireEvent = function (_elem, _type, _eve) {
			
			// It sets the default attributes of the event.
			var screen_x = 0;
			var screen_y = 0;
			var client_x = 0;
			var client_y = 0;
			var button = 0;
			
			// It sets the attributes of the event, if an existing one has been specified.
			if (_eve != null) {
				screen_x = _eve.screenX;
				screen_y = _eve.screenY;
				client_x = _eve.clientX;
				client_y = _eve.clientY;
				button = _eve.button;
			}
			
			if (CliNav.IE) {
				
				// It initializates the event features.
				var eve_man = document.createEventObject ();
				eve_man.screenX = screen_x;
				eve_man.screenY = screen_y;
				eve_man.clientX = client_x;
				eve_man.clientY = client_y;
				eve_man.button = button;
				
				// It fires the event on the element.
				_elem.fireEvent (_type, eve_man);
				
			} else {
				
				// It removes the "on" part from the event type name.
				_type = _type.substring (2);
				
				// Depending on the event type, it gets the proper event module.
				var module = "";			
				switch (_type) {
					case "mouseover":
					case "mouseout":
					case "mousemove":
					case "mousedown":
					case "mouseup":
					case "click":
						module = "MouseEvents";
					break;
					default:
						module = "HTMLEvents";
					break;
				}
				
				// Depending on the resulting event module, it employs a different way to initializate the event features.
				var eve_man = document.createEvent (module);
				if (module == "MouseEvents") {
					eve_man.initMouseEvent (_type, true, true, window, 0, screen_x, screen_y, client_x, client_y, false, false, false, false, button, null);
				} else {
					eve_man.initEvent (_type, true, true);
				}
				
				// It fires the event on the element.
				_elem.dispatchEvent (eve_man);
				
			}
			
		}
		
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT COPIES THE CONTENT OF THE "ALT" TO THE "TITLE" ATTRIBUTE OF ALL IMAGES UNDER THIS ELEMENT
		//
		// _elem				Element																				O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
		
		CliElem.imgAltToTitle = function (_elem) {
			
			var list_img = _elem.getElementsByTagName ("img");
			for (var key in list_img) {
				list_img [key].title = list_img [key].alt;
			}
			
		}

	
	

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// EVENT
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliEvent () {
	}
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// CONSTANTS
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		CliEvent.KEY_NULL = 0;
		CliEvent.KEY_TAB = 9;
		CliEvent.KEY_ENTER = 13;
		CliEvent.KEY_ESC = 27;
	
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS AN EVENT FEATURES
		//
		// _eve				Event											O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.getX = function (_eve) {
			
			if (CliNav.IE) {
				return event.clientX + event.target.ownerDocument.documentElement.scrollLeft;
			} else {
				return _eve.pageX;
			}
	
		}
		
		CliEvent.getY = function (_eve) {
			
			if (CliNav.IE) {
				return event.clientY + event.target.ownerDocument.documentElement.scrollTop;
			} else {
				return _eve.pageY;
			}
			
		}
		
		CliEvent.getKey = function (_eve) {
			
			if (CliNav.IE) {
				return event.keyCode;
			} else {
				return _eve.which;
			}
			
		}
	
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE ELEMENT ON WHICH THE EVENT OCCURED
		//
		// _eve					Event																	O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.getTarget = function (_eve) {
			
			if (CliNav.IE) {
				return _eve.srcElement;
			} else {
				return _eve.target;
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// FOR "ONMOUSEOVER" AND "ONMOUSEOUT" EVENTS IT GETS THE ELEMENT WHICH THE POINTER LEFT BEFORE MOVING
		//
		// _eve					Event																	O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.getRelTarget = function (_eve) {
			
			if (CliNav.IE) {
				if (_eve.type == "mouseover") {
					return _eve.fromElement;
				} else {
					return _eve.toElement;
				}
			} else {
				return _eve.relatedTarget;
			}
			
		}
	
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT STOPS THE EVENT PROPAGATION
		//
		// _eve					Event																	O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.stopBubble = function (_eve) {
			
			if (CliNav.IE) {
				_eve.cancelBubble = true;
			} else {
				_eve.stopPropagation ();
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT AVOIDS THE BROWSER TO PERFORM THE DEFAULT ACTION ASSOCIATED TO THIS KIND OF EVENT
		//
		// _eve					Event																	O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.avoidBrowser = function (_eve) {
			
			if (CliNav.IE) {
				_eve.returnValue = false;
			} else {
				_eve.preventDefault ();
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT CHECKS IF THE RELATED TARGET IS AN INNER ELEMENT OF THE SPECIFIED ONE (USUALLY THE CURRENT TARGET)
		//
		// _eve					Event																	O
		// _this					Element against which compare								O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliEvent.isRelTargetInner = function (_eve, _this) {
			
			// If it's in the "at target" phase and the causing element isn't under the target one, it returns true.
			// If not, false.
			if (CliXML.isInTree (CliEvent.getRelTarget (_eve), _this)) {
				return true;
			} else {
				return false;
			}
			
		}
	


			
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// XMLHTTPREQUEST
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliXMLHttp () {
	}
		
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE XMLHTTPREQUEST OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CliXMLHttp.get = function () {
			
			var req = null;
					
			if (CliNav.IE) {
				req = new ActiveXObject ("Microsoft.XMLHTTP");
			} else {
				req = new XMLHttpRequest ();
			}
			
			return req;
			
		}
		
		
		
		
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// STYLE SHEETS
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliCSS () {
	}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE DESIRED CSS RULE FROM ANY OF THE LOADED CSS STYLE SHEETS AS STYLE OBJECT
		//
		// _name						Name of the CSS rule											S
		//
		// Note 1: It gets the first one which matches (in order of aparition).
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.getRule = function (_name) {
			
			for (var i = document.styleSheets.length - 1; i >= 0; i--) {
				
				var list_rule = null;
				if (CliNav.IE) {
					list_rule = document.styleSheets [i].rules;
				} else {
					list_rule = document.styleSheets [i].cssRules;
				}
				
				for (var j = list_rule.length - 1; j >= 0; j--) {
					if (list_rule [j].selectorText == _name) return list_rule [j].style;
				}
				
			}
			
			return null;
			
		}


		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE INTEGER VALUE OF A CSS STYLE ATTRIBUTE WHICH CONTENTS SOME KIND OF MEASUREMENT
		//
		// _css_value			CSS attribute value												S		thin | medium | thick | [px]
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.getPXValue = function (_css_value) {
			
			if (_css_value != null) {
				switch (_css_value) {
					case "auto": return 0; break;
					case "thin": return 1; break;
					case "medium": return 3; break;
					case "thick": return 5; break;
					default: return parseInt (_css_value.replace ("px", ""), 10); break;
				}
			} else {
				return null;
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS THE COMPUTED STYLE OBJECT OF AN ELEMENT
		//
		// _elem						Element										O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.getCompStyle = function (_elem) {
		
			if (CliNav.IE) {
				return _elem.currentStyle;
			} else {
				return window.getComputedStyle (_elem, "");
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT MODIFIES THE CSS STYLE ATTRIBUTES ON AN ELEMENT, BACKING UP THE ORIGINAL VALUES IF NEEDED
		//
		// _elem					Element																		O
		// _list_css				List of CSS styles															O
		// ? _bak					It backups the original values of the specified styles				O
		//
		// Note 1: Doing a backup of the original attributes makes it possible to recover them later.
		// Note 2: If a backup of certain attribute already exists it isn't overwritten. Only the original is kept.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.set = function (_elem, _list_css, _bak) {
			
			if (_bak == null) _bak = false;
			
			// If the backup list doesn't exist, it's made from scratch.
			if (_elem.$list_css_bak == null) _elem.$list_css_bak = new Object ();
			
			// It backups the original attributes separately from the assignation of the new ones in order to avoid that "whole"
			// attributes (such as "border") affect to individual ones (such as "border-top").
			if (_bak) {
				for (var attrib in _list_css) {
					if (_elem.$list_css_bak [attrib] == null) {
						_elem.$list_css_bak [attrib] = _elem.style [attrib];
					}
				}
			}
			
			for (var attrib in _list_css) {
				_elem.style [attrib] = _list_css [attrib];
			}
			
		}


		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT RESTORES THE CSS STYLE ATTRIBUTES OF AN ELEMENT WHICH HAVE A BACKUP
		//
		// _elem					Element																	O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.restore = function (_elem) {
			if (_elem.$list_css_bak != null) {
				for (var attrib in _elem.$list_css_bak) {
					_elem.style [attrib] = _elem.$list_css_bak [attrib];
				}
			}
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS / SETS AN ELEMENT CSS OPACITY
		//
		// _elem			Element										O
		// _value			Amount of opacity							i				0 - 100
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliCSS.getOpacity = function (_elem) {
			
			var list_cstyle= CliCSS.getCompStyle (_elem);	
			
			if (CliNav.IE) {
				if (_elem.filters.alpha == null || _elem.filters.alpha.opacity == null) _elem.style.filter = "alpha (opacity=100)";
				return _elem.filters.alpha.opacity;
			} else {
				
				var attrib = "opacity";
				if (CliNav.GECKO) attrib = "MozOpacity";
				
				if (list_cstyle [attrib] != null && list_cstyle [attrib] != null) {
					return parseFloat (list_cstyle [attrib]) * 100;
				} else {
					return 1;
				}
				
			}
			
		}
		
		CliCSS.setOpacity = function (_elem, _value) {
			
			if (CliNav.IE) {
				_elem.style.filter = "alpha (opacity=" + _value + ")";
			} else {
				
				var attrib = "opacity";
				if (CliNav.GECKO) attrib = "MozOpacity";
				
				_elem.style [attrib] = _value / 100;
				
			}
			
		}

	


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// XML
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function CliXML () {
	}


		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS AN XML OBJECT FROM A XML DOCUMENT (VÍA "POST")
		//
		// _url						URL of the XML document								S
		// ? _list_var				List of variables	 to pass to the URL					O			It can be "null"
		// ? _async				Asynchronous mode										b
		// ? _cache				Cacheable													b
		// ? _async_func		Function to execute on 100% load						O			Only for asynchronous load
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliXML.loadGET = function (_url, _list_var, _async, _cache, _async_func) {
	
			if (_async == null) _async = false;
			if (_cache == null) _cache = true;
			
			// If a list of variables was specified, it appends them to the URL.
			if (_list_var != null) {
				
				// It encodes the list of variables to the URL format.
				CoreList.forEach (_list_var, "custom",
					function (_value) {
						return encodeURIComponent (_value);
					}
				);
				
				// It joins keys and values to the URL.
				_url += "?" + CoreList.join (_list_var, "=", "&");
				
			}
			
			// It gets and initializes the request object.
			var req = CliXMLHttp.get ();
			req.open ("GET", _url, _async);
			req.setRequestHeader ("Content-Type", "text/html");
			if (_cache) {
				req.setRequestHeader ("Cache-Control", "public");
			} else {
				req.setRequestHeader ("Cache-Control", "no-cache");
			}
	
			// If it's an asynchronous load, the request object is forced to perform the desired function when it's fulfilled at 100%.
			// Note: It receives the resulting XML object as parameter.
			if (_async) {
				req.onreadystatechange = function (_eve) {
					if (req.readyState == 4 && req.status == 200) {
						if (CliNav.IE) req.responseXML.setProperty ("SelectionLanguage", "XPath");
						_async_func (req.responseXML);
					} else {
						_async_func (null);
					}
				}
			}
			
			// It performs the load.
			req.send (null);
			
			// If it isn't an asyncrhonous load, it gets the resulting XML object (null if it coudln't be loaded properly).
			// If not, it returns a "true" value.
			if (! _async) {
				if (req.readyState == 4 && req.status == 200) {
					if (CliNav.IE) req.responseXML.setProperty ("SelectionLanguage", "XPath");
					return req.responseXML;
				} else {
					return null;
				}
			} else {
				return true;
			}
		
		}


		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT SUBMITS A FORM ASYNCHRONOUSLY AND HANDLES THE RESULTING XML DOCUMENT
		//
		// _form					Form																				O
		// _func_xml				Function to handle the resulting XML document							O
		// ? _debug				Debug mode (shows the iframe on screen)								b
		//
		// Note 1: "_func_xml" receives the XML document as argument.
		// Note 2: It's obliged to set the "action" and "target" attributes of the form.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliXML.loadPOST = function (_form, _func_xml, _debug) {
			
			// IMPORTANT: This function needs to build an iframe object but IE seems not to handle its JS "onload" event properly (among other
			// specific features of this kind of element). To make it work, it's necessary to insert the iframe as pure HTML code in the document.
			// In this case, it's "injected" into a hidden layer which is added to the document.
			
			if (GET ("div_" + _form.target) == null) {
	
				if (_debug == null) _debug = false;
							
				// It makes a hidden layer and adds it to the document.
				var ly = VFXBuild.div ({"position": "absolute", "left": "0px", "top": "0px", "visibility": "hidden", "backgroundColor": "#ffffff"},
					"div_" + _form.target);
				if (_debug) ly.style ["visibility"] = "visible";
				ly = _form.ownerDocument.body.appendChild (ly);
				
				// It saves references to the caller form and the XML handler function.
				ly.$rel_form = _form;
				ly.$func_xml = _func_xml;
				
				// It builds and links an "onload" event handler.
				ly.$func_onload = function (_eve, _this) {
	
					// If the destination of the form doesn't match the name of the loaded file, it prevents to run the process.			
					if (this.$rel_form.action.indexOf (CliLocation.fileName (_this.contentWindow.location)) != -1) {

						// It executes the XML handler function.
						if (CliNav.IE) {
							_this.contentWindow.document.XMLDocument.setProperty ("SelectionLanguage", "XPath");
							this.$func_xml (_this.contentWindow.document.XMLDocument, this);
						} else {
							this.$func_xml (_this.contentWindow.document, this);
						}
						
						// It removes the layer.
						_this.contentWindow.location.href = $INIT.getSysPath () + "html/blank.html";
						this.parentNode.removeChild (this);
	
					}
				};
					
				// It builds the iframe HTML code into the layer.
				ly.innerHTML = "<iframe id=\"" + _form.target + "\" name=\"" + _form.target + "\" src=\"" + $INIT.getSysPath ()
				+ "html/blank.html\" width=\"640\" height=\"480\" onload=\"this.parentNode.$func_onload (event, this);\"></iframe>";
						
				// It submits the form into the iframe.
				_form.submit ();
				
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT MAKES A XML DOCUMENT FROM A TEXT STRING
		//
		// _str_xml				XML string																					S
		// ? _encoding			Text encoding																				S
		//
		// Note 1: It's not necessary to add the DOCTYPE sentence because it's added automatically.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliXML.parse = function (_str_xml, _encoding) {
			
			var doctype = "";
			if (_encoding == null) {
				doctype = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
			} else {
				doctype = "<?xml version=\"1.0\" encoding=\"" + _encoding + "\"?>";
			}
			
			if (_str_xml.substring (0, 5) != "<?xml") _str_xml = doctype + _str_xml;
			
			if (CliNav.IE) {
				var xml = new ActiveXObject ("MSXML2.DOMDocument");
				xml.loadXML (_str_xml);
				return xml;
			} else {
				return (new ObjParser ()).parseFromString (_str_xml, "text/xml");
			}
			
		}
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT GETS A NODE OR NODE LIST (AS AN ITERATOR IN THIS CASE) SPECIFIED BY A XPATH
		//
		// _node					Node																	O
		// _xpath					XPath																	S
		// _type					Type of object which the XPath returns						S				node | iterator
		//
		// Note 1: Example of XPath: nodeA[1]/nodeA1[3]/nodeA13[1] .
		// Note 2: If the pointed object is a list of nodes it returns an iterator. Use "iterateNext ()" to get every node.
		// Note 3: IE doesn't returns an iterator but a node list. To keep the compatibility it will return an iterator basic emulator.
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliXML.getByXPath = function (_node, _xpath, _type) {
			
			if (_type == null) _type = "node";
			
			if (CliNav.IE) {
				
				if (_type == "node") {
					return _node.selectNodes (_xpath) [0];
				} else {
					
					// XPATHRESULT EMULATOR (USED WITH IE)
					/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
					
					function XPathResultEmulator (_list_node) {
						this.list_node = _list_node;
						this.index = 0;
					}
					
					XPathResultEmulator.prototype.iterateNext = function () {
						if (this.index >= this.list_node.length) {
							return null;
						} else {
							this.index++;
							return this.list_node [this.index - 1];
						}
					}
					
					
					// On IE, the XPath query returns a node list instead of a XPathResult so it's necessary to build a emulation of that object
					// in order to keep the cross-browser compatibility.
					return new XPathResultEmulator (_node.selectNodes (_xpath));
					
				}
				
			} else {
				
				// If the node hasn't got an owner document reference it's because the own node is the document.
				var doc = _node.ownerDocument;
				if (doc == null) doc = _node;
				
				if (_type == "node") {
					return doc.evaluate (_xpath, _node, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
				} else {
					return doc.evaluate (_xpath, _node, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
				}
				
			}
		
		}
	
	
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// IT FINDS OUT IF A NODE IS PART OF ANOTHER'S TREE (OR ITSELF)
		//
		// _node					Node to be searched																		O
		// _node_root			Node whose tree could content the another node									O
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		CliXML.isInTree = function (_node, _node_root) {
			
			if (_node == _node_root) {
				return true;
			} else if (_node == null) {
				return false;
			} else {
				return CliXML.isInTree (_node.parentNode, _node_root);
			}
			
		}
		
	
