function ltrim(str){
	return str.replace(/^(\s+)/g, '');
}

function rtrim(str){
	return str.replace(/(\s+)$/g, '');
}

function trim(str){
	return ltrim(rtrim(str));
}
var Navegador = function(){
	this.esIE = false;// Internet Explorer
	this.esIE6 = false;
	this.esIE7 = false;
	this.esIE8 = false;
	this.esFf = false;// Mozilla
	this.esOp = false;// Opera
	this.esNs = false;// Netscape
	
	if(window.navigator.userAgent.search(RegExp("MSIE","im"))!=-1){
		this.esIE = true;
		if(window.navigator.userAgent.search(RegExp("MSIE 7","im"))!=-1) this.esIE8 = true;
		else if(window.navigator.userAgent.search(RegExp("MSIE 7","im"))!=-1) this.esIE7 = true;
		else if(window.navigator.userAgent.search(RegExp("MSIE 6","im"))!=-1) this.esIE6 = true;
	}
	else if(window.navigator.userAgent.search(RegExp("Firefox","im"))!=-1) this.esFf = true;
	else if(window.navigator.userAgent.search(RegExp("Opera","im"))!=-1) this.esOp = true;
	else if(window.navigator.userAgent.search(RegExp("Safari","im"))!=-1) this.esSa = true;
	else if(window.navigator.userAgent.search(RegExp("Netscape","im"))!=-1) this.esNs = true;
};
var Nav = new Navegador();
Function.prototype.closure = function(obj){
	// Init object storage.
	if (!window.__objs){
		window.__objs = [];
		window.__funs = [];
	}
	
	// For symmetry and clarity.
	var fun = this;
	
	// Make sure the object has an id and is stored in the object store.
	var objId = obj.__objId;
	if (!objId) __objs[objId = obj.__objId = __objs.length] = obj;
	
	// Make sure the function has an id and is stored in the function store.
	var funId = fun.__funId;
	if (!funId) __funs[funId = fun.__funId = __funs.length] = fun;
	
	// Init closure storage.
	if (!obj.__closures) obj.__closures = [];
	
	// See if we previously created a closure for this object/function pair.
	var closure = obj.__closures[funId];
	if (closure) return closure;
	
	// Clear references to keep them out of the closure scope.
	obj = null;
	fun = null;
	
	// Create the closure, store in cache and return result.
	var o = __objs[objId].__closures[funId] = function (){
		if(!!__funs[funId] && !!__objs[objId]) return __funs[funId].apply(__objs[objId], arguments);
		else return false;
	};
	o.__funId = funId;
	return o;
	
};

var EliminarClosures = function(o){
	var i = 0;
	if(o){
		if(o.__objId){
			for(i in o.__closures){
				delete(window.__funs[i]);
				delete(o.__closures[i]);
			}
			delete(window.__objs[o.__objId]);
			/*delete(o.__closures);
			delete(o.__objId);*/
			o.__closures = null;
			o.__objId = null;
		}
	}
	i = null;
}

var LimpiarClosures = function(){
	if(!!Nav && !Nav.esIE) window.addEventListener('unload', LimpiarClosures, false);
	else window.detachEvent("onunload",LimpiarClosures);
	
	if(window.__objs){
		for(i in window.__objs) EliminarClosures(window.__objs[i]);
	}
	window.__objs = [];
	window.__funs = [];
};

var Limpiar = function(){
	if(!!Nav && !Nav.esIE) window.addEventListener('unload', LimpiarClosures, false);
	else window.attachEvent("onunload", LimpiarClosures);
}();

document.LimpiarClosures  = LimpiarClosures;
AddEvent = function(o, e, f){
	if(Nav.esIE) o.attachEvent('on'+e, f);
	else o.addEventListener(e, f, ((Nav.esOp)? false : true));
};
RemEvent = function(o, e, f){
	if(Nav.esIE) o.detachEvent('on'+e, f);
	else o.removeEventListener(e, f, ((Nav.esOp)? false : true));
};
FireEvent = function(o, e){
	var evt = null;
	if(Nav.esIE) o.fireEvent('on'+e);
	else{
		if(e=='click' || e=='dblclick' || e=='mousedown' || e=='mousemove' || e=='mouseout' || e=='mouseover' || e=='mouseup'){
			evt = document.createEvent("MouseEvents");
			evt.initMouseEvent(e, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		}
		else if(e=='keydown' || e == 'keypress' || e == 'keyup'){
			evt = document.createEvent("KeyboardEvent");
			evt.initKeyEvent(e, true, true, null, false, false, false, false, 9, 0);
		}
		else{
			evt = document.createEvent("Event");
			evt.initEvent(e, true, false);
		}
		o.dispatchEvent(evt);
	}
}
StopEvent = function(e){
	if(Nav.esIE){
		e.returnValue = false;
		e.cancelBubble = true;
	}
	else{
		e.preventDefault();
		e.stopPropagation();
	}
}
// JavaScript Document
Request = function(oListener, metodo){
	this.pedido = new crearXHR();
	this.reportar = true;
	this.respuestaXML = null;
	this.respuestaHTML = null;
	this.archivo=null;
	this.valores=null;
	this.listener=oListener;
	//
	if(!metodo) this.metodo = 'POST';
	else this.metodo = metodo;
}
Request.prototype.pedir = function(a, v, m){
	//inicializamos
	if(!!a) this.archivo = a;
	if(!!v) this.valores = v;
	if(!!m) this.metodo = m;
	//
	this.respuestaXML = null;
	this.respuestaHTML = null;
	//
	this.cancelar(this.pedido);
	//
	this.pedido.onreadystatechange = this.procesar.closure(this);
	//
	this.pedido.open(this.metodo, this.archivo, true);
	//
	if(this.valores) this.pedido.send(this.valores);
	else this.pedido.send();
}
Request.prototype.procesar = function(){
	var termino = false;
	if(this.pedido && this.pedido.readyState == 4){
		
		if(this.pedido.status == 200){
			if(this.pedido.responseXML)this.respuestaXML = this.pedido.responseXML.documentElement;
			this.respuestaHTML = this.pedido.responseText;
			
			termino = true;
		}
		else if((this.pedido.status >= 12029 && this.pedido.status <= 12031)  || //
				 this.pedido.status == 12152 || this.pedido.status == 12159){
			//cancelado por el servidor
			this.pedir();
		}
		else if(this.reportar){
			ERROR.reportar(" Error en clase Request.\nESTADO: "+this.pedido.status+" "+this.pedido.statusText+"\nARCHIVO: "+this.archivo+"\nMETODO: "+this.metodo);
			
			termino = true;
		}
		
		if(termino == true){
			this.cancelar();
			
			if(this.listener && this.listener.onRequestLoad) this.listener.onRequestLoad();
			else if(typeof(this.listener)=='function') this.listener();
		}
	}
}
Request.prototype.cancelar = function(){
	cancelarPedido(this.pedido);
}

/* FUNCION DE CREACION DE XMLHttpRequest */
crearXHR = function(){
    var r = null
    if (window.XMLHttpRequest) r = new XMLHttpRequest()
    else if(window.ActiveXObject) {
		var msp = new Array('Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP')
        for(var i = 0; i < msp.length; i++){
            try { r = new ActiveXObject(msp[i]) } catch (e){}
        }
    }
    return r
}
/* FUNCION DE DETENCION DE XMLHttpRequest */
cancelarPedido = function(reqXHR){
	if(reqXHR!=null){
		reqXHR.onreadystatechange=new Function()//una funcion vacia...
		reqXHR.abort()
	}
}

//
ReportarError = function(f, m){
	this.archivo = (!!f)? f:'xmlHttpRequest/reportarError.php';
	this.metodo = (!!m)? m:'POST';
	this.req = new Request();
	this.req.reportar = false;
	this.alerta = true;
	
	this.reportar = function(msj){
		this.req.pedir(this.archivo, msj, this.metodo);
		if(this.alerta) alert("Ha ocurrido un error.\nLos administradores del sistema ya han sido notificados del mismo.\nSi el error continua pongase en contacto con los mismos."+msj);
		return false;
	};
}
ERROR = new ReportarError();
	
	var ER_STR = /^([^ \t\n\r]([ \t\n\r]|[^ \t\n\r])*[^ \t\n\r])+$|^[^ \t\n\r]$/;
	var ER_EMAIL = /^[a-z0-9]{1}[a-z0-9_\.\-]{0,29}@[a-z0-9]{1}[a-z0-9\.\-]*[a-z0-9]{1}\.[a-z]{2,4}(\.[a-z]{2})?$/;
	var ER_HTTP = new RegExp("^https?://(www\.[a-z0-9]{1}[a-z0-9\.\-]*[a-z0-9]{1}\.[a-z]{2,4}(\.[a-z]{2})?(.*)?|[a-vx-z0-9]{3,}1}[a-z0-9\.\-]*[a-z0-9]{1}\.[a-z]{2,4}(\.[a-z]{2})?(.*)?|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(.*)?)$");
	var DIR_ROOT = 'http://www.unblogged.net/';
	
