// var SUBDOMAIN = location.hostname.split(".")[0];
// var BASE_URL = SUBDOMAIN + ".socialpray.com";
var BASE_URL = location.hostname;
var PROTOCOL = location.protocol;
var PORT = (location.port) ? ":" + location.port : "";
var FULL_URL = PROTOCOL + "//" + BASE_URL + PORT;

var zConf = {
	SINGLE_TAG: ["br", "img", "hr", "input", "embed"],
	IMG_WIDTH: "600px",
	IMG_HEIGHT: "800px",
	EMBED_WIDTH: 425,
	EMBED_HEIGHT: 355
}

new function() {
	try {
		document.execCommand('BackgroundImageCache', false, true);
	} catch(e) { }
}

////////////////////////////////////////////////
// Browser Detect
////////////////////////////////////////////////
new function() {
	// http://www.quirksmode.org/js/detect.html
	Browser = {};

	var dataBrowser = [ { string: navigator.userAgent, subString: "Chrome", identity: "Chrome" }, { 	string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" }, { string: navigator.vendor, subString: "Apple", identity: "Safari" }, { prop: window.opera, identity: "Opera" }, { string: navigator.vendor, subString: "iCab", identity: "iCab" }, { string: navigator.vendor, subString: "KDE", identity: "Konqueror" }, { string: navigator.userAgent, subString: "Firefox", identity: "Firefox" }, { string: navigator.vendor, subString: "Camino", identity: "Camino" }, { string: navigator.userAgent, subString: "Netscape", identity: "Netscape" }, { string: navigator.userAgent, subString: "MSIE", identity: "MSIE", versionSearch: "MSIE" }, { string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" }, { string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" } ];

	for (var i=0;i<dataBrowser.length;i++){
		var dataString = dataBrowser[i].string;
		var dataProp = dataBrowser[i].prop;
		this.versionSearchString = dataBrowser[i].versionSearch || dataBrowser[i].identity;
		if (dataString) {
			if (dataString.indexOf(dataBrowser[i].subString) != -1)
				Browser[dataBrowser[i].identity.toLowerCase()] = true;
		}
		else if (dataProp)
			Browser[dataBrowser[i].identity.toLowerCase()] = true;
	}
}




////////////////////////////////////////////////
// event listener
////////////////////////////////////////////////
var OnEvent = new function() {
	this.__zunkBoxes = { def: [] }
};

OnEvent.clear = function(__box) {
	for(var b in this.__zunkBoxes) {
		if(this.__zunkBoxes[b] && this.__zunkBoxes[b].length > 0) {
			if(__box && b != __box) continue;
			var item = null;
			while(item = this.__zunkBoxes[b].pop()) {
				this.del(item[0], item[1], item[2]);
			}
		}
	}
};

OnEvent.add = function(_e, _a, _fn, _box) {
  var _m = ["addEventListener", "attachEvent"];
	if(_box) {
		if(!this.__zunkBoxes[_box]) this.__zunkBoxes[_box] = [];
		this.__zunkBoxes[_box].push([_e, _a, _fn])
	}
  else this.__zunkBoxes['def'].push([_e, _a, _fn]);
  return this.__bindEvent(_m, _e, _a, _fn);
};

OnEvent.del = function(_e, _a, _fn) {
  var _m = ["removeEventListener", "detachEvent"];
  return this.__bindEvent(_m, _e, _a, _fn);
};

OnEvent.__case_ie = function(_a) {
  var __map = {
    blur: "focusout"
  };

  return __map[_a] || _a;
}

OnEvent.__bindEvent = function(_m, _e, _a, _fn) {
  if (_e[_m[0]]) {
    _e[_m[0]](_a, _fn, false);
  } 
  else if (_e[_m[0]]) {
    _e[_m[0]]('on' + this.__case_ie(_a), _fn);
  } 
  else {
    _e['on' + _a] = _fn;
  }
};

////////////////////////////////////////////////
// Bind
////////////////////////////////////////////////
var BindEvent = function(_this, _fn, _args) {
  var fn = _fn;
  var args = __A(_args);
  return function(e) {
    return fn.apply(_this, args.concat([(e || window.event)]));
  };
}

var Bind = function(_this, _fn, _args) {
  var fn = _fn;
  var args = __A(_args);
  return function() {
    return fn.apply(_this, args.concat(__A(arguments)));
  };
}

////////////////////////////////////////////////
// utils.
////////////////////////////////////////////////
var __A = function(_v) {
  if (!_v) return [];
  if (_v.toArray && typeof(_v) != "string") return _v.toArray();
  var iterable = (typeof _v == "string") ? _v.split(/,/) : _v;
  var length =  iterable.length;
  var results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

var Log = function(message) {
  if(Browser.msie) {
    var str = message;
    var logger = document.getElementById("logger");
    if(!logger) {
      var logger = document.createElement("div");
      logger.id = "logger";
      logger.style.clear = "both";
      logger.style.position = "absolute";
      logger.style.bottom = "0px";
      logger.style.left = "0px";
      document.getElementsByTagName("body")[0].appendChild(logger);
    }

    if( typeof(message) == 'object' ){
      str = "";
      for(var i in message) {
        str += "<div style='border:1px solid black'>" + i + "<br />" + message[i] + "</div>";
      }
    }

    logger.innerHTML += "<br>" + str;
  } else {
    var str = message;
    if( !('firebug' in console) ){
      if( typeof(message) == 'object' ){
        str = '&lt;';
        str += message.nodeName.toLowerCase();
        for( var i = 0; i < message.attributes.length; i++ ){
          str += ' ' + message.attributes[i].nodeName.toLowerCase() + '="' + message.attributes[i].nodeValue + '"';
        }
        str += '&gt;';
      }
    }

    console.debug(str);
  }
}

var MoveToCenter = function(_element) {
	var wW = (Browser.safari && !document.evaluate) ? document.innerWidth : (Browser.opera) ? document.body.clientWidth : document.documentElement.clientWidth;
	var wH = (Browser.safari && !document.evaluate) ? document.innerHeight : (Browser.opera) ? document.body.clientHeight : document.documentElement.clientHeight;
	if(wW < 1) wW = document.body.clientWidth;
	if(wH < 1) wH = document.body.clientHeigth;

	var _x = (wW / 2) - _element.offsetWidth;
	var _y = (wH / 2);

  _element.style.top = _y + "px";
  _element.style.left = _x + "px";
};

var MoveToMousePos = function(_element, _mouse_position) {
	var wW = (Browser.safari && !document.evaluate) ? document.innerWidth : (Browser.opera) ? document.body.clientWidth : document.documentElement.clientWidth;
	var wH = (Browser.safari && !document.evaluate) ? document.innerHeight : (Browser.opera) ? document.body.clientHeight : document.documentElement.clientHeight;
	if(wW < 1) wW = document.body.clientWidth;
	if(wH < 1) wH = document.body.clientHeigth;

  var _x = _mouse_position.x;
  var _y = _mouse_position.y;

	// BEWARE!
	// MAGIC HERE!
	if(_x > ((wW / 2) + 101)) _x = _x - _element.offsetWidth;
	// if(_y > 250) _y = _y - _element.offsetHeight;

  _element.style.top = (_y) + "px";
  _element.style.left = (_x) + "px";
};

//
// minified ajax
//
var zAjax = function() {
  this._xhr = null;
  casting("Loading...");
};

zAjax.prototype.send = function(_o) {
  this._url = _o.url;
  this._data = _o.data;
  this._method = (_o.method) ? _o.method : "POST";
  this.scb = _o.success || function() {};
  this.fcb = _o.failure || function() {};

  if(_o.sync) return this.sync();
  else this.async();
};

zAjax.prototype.sync = function() {
  this.xhr().open(this._method, this._url, false);
  if(this._method == "POST") this.xhr().setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	this.xhr().setRequestHeader('X-Requested-With', 'XMLHttpRequest');
	this.xhr().setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*')
  if(this._data) this.xhr().send(this.toQueryString(this._data));
  else this.xhr().send(null)

  this.callback();
  return this.xhr();
};

zAjax.prototype.async = function() {
  this.xhr().open(this._method, this._url, true);
  if(this._method == "POST") this.xhr().setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	this.xhr().setRequestHeader('X-Requested-With', 'XMLHttpRequest');
	this.xhr().setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*')

  this.xhr().onreadystatechange = Bind(this, this.orsc);

  this.xhr().send(this.toQueryString(this._data));
};

zAjax.prototype.callback = function() {
  cancelCast();
  if(this.xhr().status == 200) this.scb(this.xhr());
  else this.fcb(this.xhr());
}

zAjax.prototype.toQueryString = function(data) {
  if(typeof data == "string") return this.addAuthenticityToken(data);
  var queries = new Array();
  for(var i in data) queries.push(i + "=" + encodeURIComponent(String(data[i])));
  return this.addAuthenticityToken(queries.join("&"));
};

zAjax.prototype.addAuthenticityToken = function(data) {
	if(typeof AUTH_TOKEN == "undefined") return data;
	var prehead = (data && !data.is_empty()) ? data + "&" : "";
	return prehead + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
};

zAjax.prototype.orsc = function() {
  if(this.xhr().readyState == 4) this.callback();
};

zAjax.prototype.xhr = function() {
  if(!this._xhr) this._xhr = this._XMLHttpRequest();

  return this._xhr;
};

zAjax.prototype._XMLHttpRequest = function() {
  var try_these = [
    function () { return new XMLHttpRequest(); },
    function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
    function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
    function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
    function () { throw "Browser does not support XMLHttpRequest"; }
  ];

  for (var i = 0; i < try_these.length; i++) {
    var func = try_these[i];
    try {
      return func();
    } catch (e) {
    }
  }
};

//
// Array prototype
//
Array.prototype.last = function() {
  return this[this.length - 1];
};

Array.prototype.is_empty = function() {
  return (!this || this.length <= 0)
};

if(!Array.indexOf) {
  Array.prototype.indexOf = function(_m) {
    for(var i=0; i<this.length; i++) if(this[i] == _m) return i;
    return -1;
  }
};

Array.prototype.include = function(_m) {
  return this.indexOf(_m) > -1;
};

Array.prototype.eject = function(_v) {
  return this.splice(this.indexOf(_v), 1);
}

Array.prototype.longest = function() {
  var length = 0;
  var longest = null;
  for(var i=0; i<this.length; i++) if(this[i].length > length) longest = i, length = this[i].length;

  return this[longest];
};

//
// String prototype
//
String.prototype.is_empty = function() {
  return (!this || this.replace(/\s/g, '').length <= 0);
}

String.prototype.caps = function() {
  var s = this.toLowerCase();
  s = s.replace(/(?:^|_)([a-zA-Z])/g, function(_m, _1) { return _1.toUpperCase() });

  return s;
};

String.prototype.nl2br = function() {
	var s = this.replace(/[\n]/g, "<br />");

	return s;
}

String.prototype.br2nl = function() {
	var s = this.replace(/<br(\s\/)?>/ig, "\n");

	return s;
}

String.prototype.strip_tags = function() {
  var s = this.replace(/<\/?[^>]+?>/gi, '');
  s = s.replace(/[\r\n]/g, '');

  return s;
}

String.prototype.strip_scripts = function() {
  var s = this.replace(/<script[^>]*>[\s\S]*?<\/script[^>]*>/gi, '');
  return s;
}

String.prototype.strip_ctrl_chars = function() {
	var s = this.replace(/[\ca-\cz]/, '');
	return s;
}

String.prototype.trim = function() {
  var s = this.replace(/^(&nbsp;|\s)+/, '');
  s = s.replace(/(&nbsp;|\s)+$/, '');

  return s;
}

String.prototype.__encode = function() {
  return encodeURIComponent(this);
}

String.prototype.__decode = function() {
  return decodeURIComponent(this);
}

String.prototype.__encode_entities = function() {
  return this.replace(/[<>&"]/g, function(_m) {
    return { '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;'}[_m] || _m;
  });
}

String.prototype.__decode_entities = function() {
  return this.replace(/&([a-z]{2,4});/gi, function(_m, _w) {
    return {'amp': '&', 'quot': '"', 'lt': '<', 'gt': '>'}[_w] || _m;
  })
}

String.prototype.__escape = function() {
  var s = this.replace(/&nbsp;/g, ' ');
  s = s.replace(/[?]/g, '%3F');
  s = s.replace(/[#]/g, '%23');
  s = s.replace(/[\[]/g, '%5B');
  s = s.replace(/[\]]/g, '%5D');
  s = s.replace(/[\/]/g, '%2F');
  s = encodeURI(this);

  return s;
}

String.prototype.__regexEscape = function() {
  return this.replace(/[@$()\^[\],.\/?*\|+]/g, function(a,b) {
    return "\\" + a;
  });
}

String.prototype.jsonize = function() {
	return eval("(" + this + ")");
}

var GrepMaxKey = function(o) {
  var max = 0;
  for(var idx in o) {
    max = Math.max(idx, max);
  }

  return max;
}

var toPostQueryString = function(_n, _o) {
  var result = new Array()
  for(var i in _o) {
    var _key = _n + "[" + i + "]";
    var _value = encodeURIComponent(_o[i]);

    result.push(_key + "=" + _value);
  }

  return result.join("&");
};

var Colors = new Array(
    '#F0F8FF','#FAEBD7','#00FFFF','#7FFFD4','#F0FFFF','#F5F5DC','#FFE4C4','#000000','#FFEBCD','#0000FF',
    '#8A2BE2','#A52A2A','#DEB887','#5F9EA0','#7FFF00','#D2691E','#FF7F50','#6495ED','#FFF8DC','#DC143C',
    '#00FFFF','#00008B','#008B8B','#B8860B','#A9A9A9','#006400','#BDB76B','#8B008B','#556B2F','#FF8C00',
    '#9932CC','#8B0000','#E9967A','#8FBC8F','#483D8B','#2F4F4F','#00CED1','#9400D3','#FF1493','#00BFFF',
    '#696969','#1E90FF','#D19275','#B22222','#FFFAF0','#228B22','#FF00FF','#DCDCDC','#F8F8FF','#FFD700',
    '#DAA520','#808080','#008000','#ADFF2F','#F0FFF0','#FF69B4','#CD5C5C','#4B0082','#FFFFF0','#F0E68C',
    '#E6E6FA','#FFF0F5','#7CFC00','#FFFACD','#ADD8E6','#F08080','#E0FFFF','#FAFAD2','#D3D3D3','#90EE90',
    '#FFB6C1','#FFA07A','#20B2AA','#87CEFA','#8470FF','#778899','#B0C4DE','#FFFFE0','#00FF00','#32CD32',
    '#FAF0E6','#FF00FF','#800000','#66CDAA','#0000CD','#BA55D3','#9370D8','#3CB371','#7B68EE','#00FA9A',
    '#48D1CC','#C71585','#191970','#F5FFFA','#FFE4E1','#FFE4B5','#FFDEAD','#000080','#FDF5E6','#808000',
    '#6B8E23','#FFA500','#FF4500','#DA70D6','#EEE8AA','#98FB98','#AFEEEE','#D87093','#FFEFD5','#FFDAB9',
    '#CD853F','#FFC0CB','#DDA0DD','#B0E0E6','#800080','#FF0000','#BC8F8F','#4169E1','#8B4513','#FA8072',
    '#F4A460','#2E8B57','#FFF5EE','#A0522D','#C0C0C0','#87CEEB','#6A5ACD','#708090','#FFFAFA','#00FF7F',
    '#4682B4','#D2B48C','#008080','#D8BFD8','#FF6347','#40E0D0','#EE82EE','#D02090','#F5DEB3','#FFFFFF',
    '#F5F5F5','#FFFF00','#9ACD32');  

var ColorNames = new Array(
    'AliceBlue','AntiqueWhite','Aqua','Aquamarine','Azure','Beige','Bisque','Black','BlanchedAlmond','Blue',
    'BlueViolet','Brown','BurlyWood','CadetBlue','Chartreuse','Chocolate','Coral','CornflowerBlue','Cornsilk',
    'Crimson','Cyan','DarkBlue','DarkCyan','DarkGoldenRod','DarkGray','DarkGreen','DarkKhaki','DarkMagenta',
    'DarkOliveGreen','Darkorange','DarkOrchid','DarkRed','DarkSalmon','DarkSeaGreen','DarkSlateBlue','DarkSlateGray',
    'DarkTurquoise','DarkViolet','DeepPink','DeepSkyBlue','DimGray','DodgerBlue','Feldspar','FireBrick','FloralWhite',
    'ForestGreen','Fuchsia','Gainsboro','GhostWhite','Gold','GoldenRod','Gray','Green','GreenYellow','HoneyDew',
    'HotPink','IndianRed','Indigo','Ivory','Khaki','Lavender','LavenderBlush','LawnGreen','LemonChiffon',
    'LightBlue','LightCoral','LightCyan','LightGoldenRodYellow','LightGrey','LightGreen','LightPink','LightSalmon',
    'LightSeaGreen','LightSkyBlue','LightSlateBlue','LightSlateGray','LightSteelBlue','LightYellow','Lime',
    'LimeGreen','Linen','Magenta','Maroon','MediumAquaMarine','MediumBlue','MediumOrchid','MediumPurple',
    'MediumSeaGreen','MediumSlateBlue','MediumSpringGreen','MediumTurquoise','MediumVioletRed','MidnightBlue',
    'MintCream','MistyRose','Moccasin','NavajoWhite','Navy','OldLace','Olive','OliveDrab','Orange','OrangeRed',
    'Orchid','PaleGoldenRod','PaleGreen','PaleTurquoise','PaleVioletRed','PapayaWhip','PeachPuff','Peru','Pink',
    'Plum','PowderBlue','Purple','Red','RosyBrown','RoyalBlue','SaddleBrown','Salmon','SandyBrown','SeaGreen',
    'SeaShell','Sienna','Silver','SkyBlue','SlateBlue','SlateGray','Snow','SpringGreen','SteelBlue','Tan','Teal',
    'Thistle','Tomato','Turquoise','Violet','VioletRed','Wheat','White','WhiteSmoke','Yellow','YellowGreen');

var randomColor = function() {
  return Colors[Math.floor( Math.random() * Colors.length )];
};

var zTag = function(tag_name, text, options) {
  var tag = new String();
  tag += "<";
  tag += tag_name;
  
  for(var i in options) {
    if(typeof options[i] != "string") continue;
    tag += ' ' + i.replace(/^_/, "") + '="' + options[i] + '"';
  }

  tag += ">";

  if(!zConf.SINGLE_TAG.include(tag_name.toLowerCase())) {
    tag += text;
    tag += "</";
    tag += tag_name;
    tag += ">";
  }

  return tag;
};

var zPageLink = function(_title) {
  return zTag("a", _title.__decode().__encode_entities(), {
    //_title: _title.__decode().__encode_entities(),
    _class: "zedit_class page_link",
    _href: _title
  })
};

var zImgShow = function(_path) {
  return zTag("p", 
    zTag("img", "", {
      _src: _path,
      _class: "zedit_class",
      _alt: _path.split("/").last()
    }), { 
    _class: "zedit_class"
  });
};

var zEmbed = function(_options) {
	return zTag("embed", "", {
		_src: _options.src,
		_width: _options.width + "px",
		_height: _options.height + "px",
		_wmode: "transparent",
		_type: "application/x-shockwave-flash"
	});
}


ExtractIdFromUrl = function(_name, _url) {
	var url = _url || location.href;
	var name = _name.pluralize();
	var patt = new RegExp(name + "/([0-9]+)")

	var _match = patt.exec(url);

	if(_match && _match.length >= 2) return _match[1];
	else return false;
};

var Normalize = function() {
};

Normalize.prototype.cleanup = function(s) {
  
  this.extract_tag(s);
};

Normalize.prototype.extract_tag = function(s) {
  var pattern = /(<([a-z]+)[^>]*>)(.*?)(?=<\/\2>)/gi;
  var result = new Array();
  while(match = pattern.exec(s)) {
    result.push({ _open: match[1], _text: match[3], _close: "</" + match[2] + ">" });
  }

  return result;
};

// by discussion. THH
function setCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function getCookie(name) {
	var nameKey = name + "=";
	var cookies = document.cookie.split(';');
	for(var i=0;i < cookies.length;i++) {
		var cookie = cookies[i];
		while (cookie.charAt(0)==' ') cookie = cookie.substring(1,cookie.length);
		if (cookie.indexOf(nameKey) == 0) return cookie.substring(nameKey.length,cookie.length);
	}
	return null;
}

function delCookie(name) {
	setCookie(name,"",-1);
}

var __serialize = function(cap, data) {
	var _ret = new Object();
	for(var key in data) if(data[key] && !String(data[key]).is_empty()) _ret[cap + "[" + key + "]"] = data[key];

	return _ret;
};

//
// eventor
//
var Eventor = function(_e) {
	this.title = "eventor";
	this.junkies = {};
	this.junkies["_event"] = _e;
};

Eventor.prototype = {

	_event: function() {
		return this.junkies["_event"];
	},

	_node: function() {
		if(!this.junkies["_node"]) {
			this.junkies["_node"] = this._event().target || this._event().srcElement;
			if(this.junkies["_node"].nodeType == 3) this.junkies["_node"] = this.junkies["_node"].parentNode
		}

		return this.junkies["_node"];
	},

	_type: function() {
		if(!this.junkies["_type"]) this.junkies["_type"] = this._event().type

		return this.junkies["_type"];
	},

	_keycode: function() {
		if(!this.junkies["_keycode"]) this.junkies["_keycode"] = this._event().keycode || this._event().keyCode;

		return this.junkies["_keycode"];
	},

	_page: function() {
		if(!this.junkies["_page"]) {

			var sl = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
			var st = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

			this.junkies["_page"] = { 
				x: this._event().pageX || this._event().clientX + sl,
				y: this._event().pageY || this._event().clientY + st
			}
		}

		return this.junkies["_page"];
	},

	_mouse: function() {
		if(!this.junkies["_mouse"]) {
			this.junkies["_mouse"] = {};
			this.junkies["_mouse"]["_x"] = this._event().clientX;
			this.junkies["_mouse"]["_y"] = this._event().clientY;
		}

		return this.junkies["_mouse"];
	},
	
	_wheel: function() {
		if(!this.junkies["_wheel"]) {
			// up < 0
			// down > 0
			this.junkies["_wheel"] = {};


			this.junkies["_wheel"]["_delta"] = this._event().detail / 3 * -1 || this._event().wheelDelta / 120;
			if(Browser.chrome) this.junkies["_wheel"]["_delta"] = this.junkies["_wheel"]["_delta"] / 3;
			this.junkies["_wheel"]["_direction"] = (this.junkies["_wheel"]["_delta"] > 0) ? "up" : "down";
		}

		return this.junkies["_wheel"];
	},

	break_event: function() {
		if (this._event().stopPropagation) {
			this._event().stopPropagation();
		} else {
			this._event().returnValue = false;
		}

		if (this._event().preventDefault) {
			this._event().preventDefault();
		} else {
			this._event().cancelBubble = true;
		}
	}
}



//
// selection
// 
var Selection = function(_win) {
	this.win = _win;
	this.junkies = {};
}

Selection.prototype = {

	_node: function() {
		if(!this.junkies["_node"]) this.junkies["_node"] = this._current_node();

		return this.junkies["_node"];
	},

	_current_node: function() {
		var _node = null;
		if(Browser.msie) {
			_node = this._range().parentElement();
		} else {
			_node = this._range().anchorNode
			if(!_node) _node = this.win.document.firstChild;
			if(_node.nodeType == 3) _node = _node.parentNode
		}

		return _node;
	},

	_range: function() {
		if(!this.junkies["_range"]) {
			if(Browser.msie) {
				this.junkies["_range"] = this.win.document.selection.createRange();
			} else {
				this.junkies["_range"] = this.win.getSelection();
			}
		}

		return this.junkies["_range"];
	},

	_html: function() {
		if(!this.junkies["_html"]) {
			if(Browser.chrome) {
				// skip
			} else if(Browser.mozilla) {
				var _r = this._range();
				this.junkies["_range"] = this._range().getRangeAt(0);
				this.junkies["_html"] = new XMLSerializer().serializeToString(this._range().cloneContents());
				this.junkies["_range"] = _r;
			} else {
				this.junkies["_html"] = this._range().htmlText;
			}
		}

		return this.junkies["_html"];
	},

// utils
	_node_focus: function(_node) {
		if(!_node) return;

		if(Browser.msie) {
			this._range().moveToElementText(_node);
			this._range().collapse(false);
			//this._range().move('character',-1);
			this._range().select();
			_node.focus();
		} else if(Browser.safari) {
			this._range().collapse(_node, (_node.nodeType == 1) ? _node.childNodes.length : _node.length);
		} else {
			var low_range = document.createRange();
			low_range.selectNode(_node);
			// var selected = this.iframe.contentWindow.getSelection();
			this._range().addRange(low_range);
			this._range().collapse(_node, _node.childNodes.length);
			this.win.focus();
		}
	},

	_focus_to_end: function() {
		var _node = this.win.document.getElementsByTagName("body")[0].lastChild;
		this._node_focus(_node);
	},

	_focus_to_marker: function() {
		var _marker = this.win.document.getElementById("_marker");
		if(_marker) {
			this._node_focus(_marker);
			_marker.parentNode.removeChild(_marker);
		}
	}
} // Selection prototype

// Global Utils
var CumulativeOffset = function(element) {
	var lt_y = 0;
	var lt_x = 0;
	do {
		lt_y += element.offsetTop  || 0;
		lt_x += element.offsetLeft || 0;
		element = element.offsetParent;
	} while (element);

	return [lt_x, lt_y];
};

var PositionedOffset = function(element) {
	var lt_y = 0;
	var lt_x = 0;
	do {
		lt_y += element.offsetTop  || 0;
		lt_x += element.offsetLeft || 0;
		element = element.offsetParent;
		if(element) {
			if(/^body$/i.test(element.tagName)) break;
			if(/(relative|absolute)/i.test(String(element.style.position))) break;
		}
	} while (element);

	return [lt_x, lt_y];
}

var extract_params = function(__query) {

	var query = __query || location.search;
	var ret = {};
	var _q = location.search.replace(/^\?/,"").split("&");
	for(var i=0; i<_q.length; i++) {
		var _kv = _q[i].split("=");
		ret[_kv[0]] = decodeURI(_kv[1]);
	}

	return ret;
};

var toQueryString = function(data, shell) {
  if(typeof data == "string") return data;
  var queries = new Array();
  for(var i in data) {
		var key = (shell) ? shell + "[" + encodeURIComponent(i) + "]" : i;
		queries.push(key + "=" + encodeURIComponent(String(data[i])));
	}
  return queries.join("&");
};

var __void = function() { };

function hash_index(condition_key, stack) {
	for(var key in stack) {
		if(stack[key] == condition_key) {
			return key;
			break;
		}
	}
}
