                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
try { if(navigator.appVersion.match(/3.1.. Safari/)) {
	var d = document.createElement('div');
	var tgt = 'jsk-ifrmsess-' + Math.random();
	d.innerHTML = '<iframe id="' + tgt + '" name="' + tgt + '" src="about:blank" width=0 height=0 style="border: none"></iframe>';
	var f = function() {
		document.body.appendChild(d);
		var ifrsess = d.firstChild;
		var getFrame = function(FrameName, Parent) {
			var tp = Parent ? getFrameDoc(Parent) : document;
			var fr = tp.getElementById(FrameName).contentWindow;
			return fr;
		}
		var getFrameDoc = function(FrameName, Parent) {
			var FEl = getFrame(FrameName, Parent);
			return FEl.contentDocument || FEl.document;
		}
		ifrsess.onreadystatechange = function() {
			if((ifrsess.readyState) && (ifrsess.readyState != 'complete')){
				return;
			}
			var iDOC = getFrameDoc(tgt);
			var frm = iDOC.createElement('form');
			frm.method = 'post';
			frm.action = window.location.protocol + '//js-kit.com/session-get-new';
			iDOC.body.appendChild(frm);
			frm.submit();
		}
		ifrsess.onreadystatechange();
	}
	if(document.body) f();
	else setTimeout(f, 0);
} } catch(e) {};
/* Copyright (c) 2006, 2007, 2008 Lev Walkin <vlm@lionet.info>.
 * You may copy and modify this script as long as the above copyright notice,
 * this condition and the following disclaimer is left intact.
 * This software is provided by the author "AS IS" and no warranties are
 * implied, including fitness for a particular purpose. In no event shall
 * the author be liable for any damages arising in any way out of the use
 * of this software, even if advised of the possibility of such damage.
 * $Id: comments.js 7116 2008-09-13 00:34:01Z jskit $
 */

if(!window.$JCA) {
  var $JCA = [];
  var $JCLT = {
	leaveComment: 'Leave a comment',
	nameLabel: 'Your name:',
	emailLabel: 'Send replies to email:',
	emailNote: '(if provided, email will not be displayed or shared)',
	ratingLabel: 'Rating:',
	commentLabel: 'Comment:',
	submit: 'Submit comment',
	cancel: 'Cancel',
	tooShort: 'Your message is too short',
	tooLong: 'Message size should not exceed 3000 bytes',
	junkCtl: 'Junk control',
	byVotes: 'by',
	selectedAvatar: 'Selected Avatar',
	uploadAvatar: 'Upload new avatar:',
	removeAvatar: 'Remove Avatar',
	removeAvatarConfirm: 'Remove this avatar?',
	openidLabel: 'Your OpenID URL:',
	openidNote: '(OpenID 1.1 providers only)',
	openidLogin: 'Logged via',
	jskitAccount: 'JS-Kit as: ',
	logout: 'logout',
	less: 'less',
	more: 'more',
	optionsU: 'Options &#x25b2;',
	optionsD: 'Options &#x25bc;',
	isJunkVote: 'Is this inappropriate junk or SPAM message?',
	submitPM: 'Leave private message'
  };
  var $JCL = window.JSCC_Translate || function(t) {
	return (window.$JCLTL ? $JCLTL[t] : false) || $JCLT[t] || t;
  }
}


if(!window.JSKitEPB){
	var JSKitEPB = new JSKitEPBLib();
}

function JSKitEPBLib() {
	this.JSK$EPB = window.JSK$EPB ? window.JSK$EPB : {};
}

JSKitEPBLib.prototype.isAdmin = function(Path) {
	var arrIndexOf = function(arr, Val) {
		var ValLC = Val.toLowerCase();
		for(var i = arr.length - 1; i >= 0; i--) {
			var v = arr[i];
			if(typeof(v) == "string")
				v = v.toLowerCase();
			if(v == ValLC) return i;
		}
		return -1;
	}
	return this.JSK$EPB.mac && this.JSK$EPB.profile && this.JSK$EPB.profile.owner && arrIndexOf(this.JSK$EPB.profile.owner,Path) != -1 ? 1 : 0;
}

JSKitEPBLib.prototype.getValue = function(ValueName) {
	return !this.JSK$EPB.profile || !this.JSK$EPB.mac || this.JSK$EPB.profile[ValueName] == undefined ? undefined : this.JSK$EPB.profile[ValueName];
}

JSKitEPBLib.prototype.serializeElement = function(Pref,El,ArrKey) {
	var rslt = [];
	if(typeof(El) == 'object') {
		if(El instanceof Array) {
			if(ArrKey) {
				var len = El.length;
				for(var i=0; i<len; i++)
					rslt = rslt.concat(this.serializeElement(Pref,El[i],ArrKey));
			}
		} else {
			for(var i in El)
				rslt = rslt.concat(this.serializeElement(Pref,El[i],i));
		}
	} else {
		if(ArrKey) {
			rslt.push({'Name': Pref+ArrKey, 'Value': El});
		}
	}
	return rslt;
}

JSKitEPBLib.prototype.serialize = function() {
	var rslt = [];
	var pref = "epb-";
	var epb = this.JSK$EPB;
	if(!epb.profile || !epb.mac) return rslt;
	rslt.push({'Name': pref+"mac",'Value': epb.mac});
	return rslt.concat(this.serializeElement(pref,epb.profile));
}

JSKitEPBLib.prototype.getURIEncodedSerialize = function() {
	var ser = this.serialize();
	var ar = [];
	for(var i in ser) {
		ar.push(ser[i].Name + "=" + encodeURIComponent(ser[i].Value));
	}
	return ar.join("&");
}



if(!window.JSKitLib) JSKitLib = {vars:{}};



JSKitLib.isPreIE7 = function() {
	if (document.body.filters && parseInt(navigator.appVersion.split("MSIE") [1]) < 7)
		return true;
}

JSKitLib.isIE = function() {
	if (document.body.filters && navigator.appVersion.match(/MSIE/))
		return true;
}

JSKitLib.getBrowser = function() {
	if (JSKitLib.vars.browser) return JSKitLib.vars.browser;
	if (document.body.filters && navigator.appVersion.match(/MSIE/)) {
			JSKitLib.vars.browser = "IE";
	} else if ((navigator.appCodeName.toLowerCase()=="mozilla") 
		&& (navigator.appName.toLowerCase()=="netscape") 
		&& (navigator.product.toLowerCase()=="gecko") 
	) {
		if (navigator.userAgent.toLowerCase().indexOf("safari")!=-1) {
			JSKitLib.vars.browser = "safari";
		} else if (navigator.userAgent.toLowerCase().indexOf("firefox")!=-1) {
			JSKitLib.vars.browser = "gecko";
		}
	} else if (navigator.product && navigator.product.toLowerCase()=="gecko") {
		JSKitLib.vars.browser = "gecko";
	}
	return JSKitLib.vars.browser;
}

JSKitLib.isSafari = function() {
	if (navigator.appVersion.match(/Safari/)) {
		return true;
	}
}

JSKitLib.isOpera = function() {
	if (navigator.appName.match(/Opera/)) {
		return true;
	}
}



JSKitLib.stopEventPropagation = function(e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

JSKitLib.preventDefaultEvent = function(e) {
  if (!e) var e = window.event;
  e.returnValue = false;
  if (e.preventDefault) e.preventDefault();
}

JSKitLib.addLoadEvent = function(newLoadEvent) {
	var origLoadEvent = window.onload;
	if (typeof origLoadEvent == "function") {
		window.onload = function() { 
			origLoadEvent();
			newLoadEvent();
		}
	} else {
		window.onload = newLoadEvent;
	}
}

JSKitLib.deferCallIfIE = function(func) {
	if (JSKitLib.isIE() && ! JSKitLib.vars.windowOnLoadFired && ! window.$JSKitNoDeferCallIfIE) {
		JSKitLib.addLoadEvent(func);
	} else {
		func();
	}
}

JSKitLib.addHandlers = function(element,moveHandler,upHandler,capture){
	if (document.addEventListener) {
		document.addEventListener("mousemove", moveHandler, true);
		document.addEventListener("mouseup", upHandler, true);
	} else if (document.attachEvent) { 
		if (capture){
			element.setCapture();
			element.attachEvent("onlosecapture", upHandler);
		}
		element.attachEvent("onmousemove", moveHandler);
		element.attachEvent("onmouseup", upHandler);
	}
}

JSKitLib.removeHandlers = function(element,moveHandler,upHandler,capture){
	if (document.removeEventListener) {
		document.removeEventListener("mouseup", upHandler, true);
		document.removeEventListener("mousemove", moveHandler, true);
	} else if (document.detachEvent) {
		if (capture){
			element.detachEvent("onlosecapture", upHandler);
			element.releaseCapture();
		}
		element.detachEvent("onmouseup", upHandler);
		element.detachEvent("onmousemove", moveHandler);
	}
}

JSKitLib.addResizeEvent = function(newEvent) {
	var origEvent = window.onresize;
	if (typeof origEvent == "function") {
		window.onresize = function() { 
			origEvent();
			newEvent();
		}
	} else {
		window.onresize = newEvent;
	}
}

JSKitLib.notDraggable = function(element) {
	element.onselectstart = function(ev) { JSKitLib.stopEventPropagation(ev); return true; }
	element.onmousedown = JSKitLib.stopEventPropagation;
	return element;
}

JSKitLib.getMousePosition = function(e) {
	if (!e) var e = window.event;
	if (e.clientX || e.clientY) {
		return {x:e.clientX, y:e.clientY};
	} else {
		return {x:e.pageX, y:e.pageY};
	}
}

JSKitLib.preventSelect = function(element, exceptions) {
	var browser = JSKitLib.getBrowser();
	var prevent = function() {
		if (browser == 'IE' || browser == 'safari') {
			element.onselectstart = function() { return false; }
		} else if (browser == 'gecko') {
			JSKitLib.addClass(element, 'js-nsgecko');
		}
	}
	if (typeof exceptions == 'object') {
		var include = exceptions.include || [];
		var exclude = exceptions.exclude || [];
		// Do not handle for certain browsers
		if (exclude.length) {
			for (var i=0; i < exclude.length; i++) {
				if (exclude[i] != browser) {
					prevent();
				}
			}
		}
		// Handle for certain browsers
		if (include.length) {
			for (var i=0; i < include.length; i++) {
				if (include[i] == browser) {
					prevent();
				}
			}
		}
	} else {
		prevent();
	}
}



JSKitLib.addCss = function(cssCode, name) {
	if(name) {
		name = "js-" + name + "-css";
		if (document.getElementById(name)) return;
	}
	var se = document.createElement("style");
	se.type = "text/css";
	if(name) se.id = name;
	if (se.styleSheet) se.styleSheet.cssText = cssCode;
	else se.appendChild(document.createTextNode(cssCode));
	var hd = document.getElementsByTagName("head");
	if(hd && hd[0]) hd[0].appendChild(se);
	else document.write('<style>'+cssCode+'</style>');
}

JSKitLib.getElementsByClass = function(node, searchClass, tag) {
	var classElements = [];
	node = node || document;
	tag = tag || '*';
	var tagElements = node.getElementsByTagName(tag);
	var regex = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
	for (var i=0, j=0; i < tagElements.length; i++) {
		if (regex.test(tagElements[i].className)) {
			classElements[j] = tagElements[i];
			j++;
		}
	}
	return classElements;
};

JSKitLib.mapClass2Object = function(ctl, e) {
        var cName = e.className;
        if (cName && (cName.indexOf('js-') != -1)) {
                if(cName.indexOf(' ') > -1) {
                        var classes = cName.match(/\S+/g);
                        for (var i=0; i < classes.length; i++) {
                                ctl[classes[i]] = e;
                        }
                } else {
                        ctl[cName] = e;
                }
        }
        if(e.name) ctl[e.name] = e;
        var cn = e.childNodes;
        if(cn) {
                var clen = cn.length;
                for(var i = 0; i < clen; i++)
                        JSKitLib.mapClass2Object(ctl, cn[i]);
        }
        return ctl;
}

JSKitLib.hasClass = function(element, className) {
	return element.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
}

JSKitLib.addClass = function(element, className) {
	if (!JSKitLib.hasClass(element, className)) {
		element.className += ' ' + className;
	}
}

JSKitLib.removeClass = function(element, className) {
	if (JSKitLib.hasClass(element, className)) {
		var regex = new RegExp('(\\s|^)' + className + '(\\s|$)');
		element.className = element.className.replace(regex, ' ');
	}
}



JSKitLib.visible = function(element) {
	return element.style.display != 'none';
}

JSKitLib.show = function(element) {
	element.style.display = '';
}

JSKitLib.hide = function(element) {
	element.style.display = 'none';
}

JSKitLib.toggle = function(element) {
	(element.style.display == 'none') ? JSKitLib.show(element) :  JSKitLib.hide(element);
}

JSKitLib.getStyle = function(element) {
	if (typeof element.style.cssText != "undefined") {
		return element.style.cssText;
	} else {
		return element.getAttribute("style");
	}
}

JSKitLib.setStyle = function(element, style) {
	if (typeof element.style.cssText != "undefined") {
		element.style.cssText = style;
	} else {
		element.setAttribute("style", style);
	}
}

JSKitLib.addStyle = function(element, style) {
	var oldStyle = JSKitLib.getStyle(element);
	JSKitLib.setStyle(element, oldStyle + '; ' + style); // IE needs ;
}

JSKitLib.findPos = function(obj) {
	var origObj = obj;
	var curleft = curtop = curright = curbottom = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft;
		curtop = obj.offsetTop;
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	curright = curleft + origObj.offsetWidth;
	curbottom = curtop + origObj.offsetHeight;
	return [curleft,curtop,curright,curbottom];
}

JSKitLib.getJSKitBodyElement = function() {
	var be = document.getElementById('js-kit-body-element');
	if (!be) {
		be = document.createElement('div');
		be.id = "js-kit-body-element";
		document.body.appendChild(be);
	}
	return be;
}

JSKitLib.isChildNodeOf = function(parent, child) {
	if (parent === child) 
		return false
	while (child && child !== parent) {
		child = child.parentNode;
	}
	return child === parent;
}

JSKitLib.setOpacity = function(div, val) {
	if(document.body.filters) {
		if(val == 1) div.style.filter = '';
		else div.style.filter = 'alpha(opacity: ' + Math.round(val * 100) + ')';
	} else {
		div.style.opacity = val;
	}
}



JSKitLib.addPNG = function(node, imageURL) {
	if (JSKitLib.isIE()) {
		var cp = $JSKitGlobal.cachedPngs;
		for(var j=0; j<cp.length; j++) {
			k = 0;
			while(k<length(cp[j].nodes)) {
				if(cp[j].nodes[k]==node) {
					cp[j].nodes.splice(k, 1);
				} else {
					k++;
				}
			}
		}
		if(cp[imageURL]) {
			if(cp[imageURL].loaded) {
				node.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageURL + "', sizingMethod='crop')"
			} else {
				cp[imageURL].nodes.push(node);
			}
		} else {
			cp[imageURL] = {nodes:[node]};
			var tPng = document.createElement("IMG");
			tPng.style.display = "none";
			tPng.onload = function() {
				cp[imageURL].loaded = true;
				var n = cp[imageURL].nodes;
				for(var i=0; i<n.length; i++) {
					n[i].runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageURL + "', sizingMethod='crop')";
				}
				cp[imageURL].nodes = [];
			};
			node.appendChild(tPng);
			tPng.src = imageURL;
		}
	} else {
		node.style.backgroundImage = 'url(' + imageURL + ')';
		node.style.backgroundRepeat = 'no-repeat';        
	}
	return node;
}

JSKitLib.preloadImg = function(imgURL) { 
	if (!JSKitLib.preloadImgList) JSKitLib.preloadImgList = {};
	if (!JSKitLib.preloadImgList[imgURL]) {
		(new Image()).src = imgURL; 
		JSKitLib.preloadImgList[imgURL] = true;
	}
};

JSKitLib.pngBar = function(color, div, fixed) {
	var str;
	var url = "'//js-kit.com/images/bars/bar-" + color + ".png'";
	if(document.body.filters) {
		str = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src="
			+ url + ", sizingMethod='"+(fixed?'crop':'scale')+"')";
		if(div) div.runtimeStyle.filter = str;
		return "filter: " + str + ";";
	} else {
		str = "url(" + url + ")";
		if(div) div.style.backgroundImage = str;
		return "background: " + str + ";";
	}
};

JSKitLib.createMiniStarObject = function(rating, scale, specs) {
	var fullStar = specs.full;
	var emptyStar = specs.empty;
	var starWidth = specs.width;
	var starHeight = specs.height;

	var setImage = function(star, imageURL) {
		if(star.imageURL == imageURL)
			return; // Already set and we know it

		star.imageURL = imageURL;
		JSKitLib.addPNG(star, imageURL);
	}

	var obj = document.createElement('div');
	var objWidth = 0;
	var objHeight = starHeight;

	/* Increment by Full Star Ratings */
	for (var i=2; i <= scale; i += 2) {
		var star = document.createElement('div');

		star.style.cssFloat   = 'left';
		star.style.styleFloat = 'left';
		star.style.width    = starWidth + 'px';
		star.style.height   = starHeight + 'px';
		star.style.fontSize = starHeight + 'px'; // ie6

		objWidth += starHeight;

		if (rating >= i) {
			setImage(star, fullStar);
		} else {
			setImage(star, emptyStar);
		}

		obj.appendChild(star);
	}

	JSKitLib.setStyle(obj, "height: " + objHeight + "px; width: " + objWidth + "px; float: left; margin-right: 5px;");

	return obj;
}

JSKitLib.mkAvatar = function(s, avatar, uriAvatar, onmousemove, onmouseout, onmousedown, outeronmousedown, settext) {
	var outer = s.cr('div');
	JSKitLib.setStyle(outer, "float: left;");
	outer.style.display = "inline-block";
	outer.onselectstart = function() {return false;}
	outer.style.margin = "2px";
	JSKitLib.addClass(outer, "js-hideBorder");
	var WH = {'width': avatar.width,'height': avatar.height,'name':avatar.name};
	outer.style.width = "118px";
	outer.style.align = "center";
	var div = s.cr('div');
	div.style.margin = "2px";
	div.style.width = "114px";
	div.style.height = "114px";
	div.style.backgroundPosition = 'top center';
	var img = s.cr('div');
	img.style.width = WH['width'] + 'px';
	img.style.height = WH['height'] + 'px';
	img.style.left=((114-WH['width'])/2)+'px';
	img.style.position = "relative";
	JSKitLib.addPNG(img, uriAvatar + WH['name']);
	var sub = s.cr('div');
	sub.style.padding = "2px 5px 0px 5px";
	sub.style.fontFamily = "Helvetica, Verdana";
	sub.style.fontSize = "8pt";
	sub.style.height = "14px";
	var sel = s.cr('div'); settext(sel, 'selectedAvatar');
	sel.style.display = 'none';
	sel.style.textAlign = 'center';
	var rem = s.cr('div'); settext(rem, 'removeAvatar');
	rem.style.display = 'none';
	rem.style.textDecoration = 'underline';
	rem.style.textAlign = 'center';
	rem.style.cursor = 'pointer';
	sub.onmouseover = function() {
		return onmousemove(avatar, outer, sel, rem);
	}
	sub.onmouseout = function() {
		return onmouseout(avatar, outer, sel, rem);
	}
	rem.onmousedown = function(e) {
		JSKitLib.stopEventPropagation(e || window.event);
		return onmousedown(avatar, outer, sel, rem);
	}
	sub.appendChild(rem);
	sub.appendChild(sel);
	div.appendChild(img);
	div.appendChild(sub);
	outer.appendChild(div);
	outer.onmousedown = function() {
		return outeronmousedown(avatar, outer, sel, rem);
	}
	if(avatar.chosen) outeronmousedown(avatar, outer, sel, rem, true);
	return outer;
}



JSKitLib.getOuterHTML = function(node) {
	var clone = node.cloneNode(true);
	var parent = document.createElement('div');
	parent.appendChild(clone);
	var ihtml = parent.innerHTML;

    // ff converts sp characters inside of href to hex ascii
	var ihtmlHref = ihtml.match(/href\s*=\s*"[^"]*(%7B|%7D)[^"]*"/g) || [];
	for (var i=0; i< ihtmlHref.length; i++) {
		var a = ihtmlHref[i];
		var b = a.replace(/%7B/g, '{');
		b = b.replace(/%7D/g, '}');
		ihtml = ihtml.replace(a, b);
	}
	return ihtml;
};

JSKitLib.html = function() {
        var div = document.createElement("div");
        for(var text = '', i = 0; i < arguments.length; i++)
                text += arguments[i];
        div.innerHTML = text;
        var ch = div.firstChild;
        div = null;
        return ch;
}

JSKitLib.htmlQuote = function (newValue, param) {
	newValue = newValue.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")
	param = param || {};
	if(!param.title)
		newValue = newValue.replace(/ /,"&nbsp;");
	if(param.attribute)
		newValue = newValue.replace(/"/g,"&quot;");
	return newValue;
}

JSKitLib.addJS = function(src,content) {
	var sId = "js-kit-script-"+src.replace(/[\/.]/g, '');
	content.jsk$scriptId = sId;
	if(document.getElementById(sId)) {
		return;
	}
	var s = document.createElement('script');
	s.id = sId;
	s.type ='text/javascript';
	s.src = src;
	content.appendChild(s);
}



JSKitLib.map = function(f, arr) {
	if(arr) for(var i = 0; i < arr.length; i++) f(arr[i], i, arr);
	return arr;
}

JSKitLib.filter = function(f, arr) {
	var newArr = [];
	if(arr)
		for(var i = 0; i < arr.length; i++)
			if(f(arr[i], i, arr))
				newArr.push(arr[i]);
	return newArr;
}

JSKitLib.fmap = function(o,f) {
	var r, a = [], l = o.length;
	if(l > 0 || l === 0)
		for(var i = 0; i < l; i++) {
			r = f.call(this,o[i],i,arguments);
			if(r !== undefined) a.push(r);
		}
	else
		for(var i in o)
			if(o.hasOwnProperty(i)) {
				r = f.call(this,o[i],i,arguments);
				if(r !== undefined) a.push(r);
			}
	return a;
}

JSKitLib.foldl = function(acc,o,f) {
	var r, l = o.length;
	if(l > 0 || l === 0)
		for(var i = 0; i < l; i++) {
			r = f.call(this,o[i],acc,i);
			if(r != undefined) acc = r;
		}
	else
		for(var i in o)
			if(o.hasOwnProperty(i)) {
				r = f.call(this,o[i],acc,i);
				if(r != undefined) acc = r;
			}
	return acc;
}

JSKitLib.intersperse = function(f) {
	return JSKitLib.foldl([], this, function(e, acc, i) {
		if(acc.length) acc.push(f);
		acc.push(e);
	});
}



var JSKitGlobal = function() {

	this._appAvailable = {};
	this._appObjects = {};  // Specific objects of an application type 
	this._appObjectActions = {}; // app.object.actions
	
	this.cachedPngs = {};

	this._isAppAvailable = function(app) {
		return (this._appAvailable[app]) ? true : false;
	}

	this.isRatingsAppAvailable = function() {
		return this._isAppAvailable('ratings');
	}

	this.isCommentsAppAvailable = function() {
		return this._isAppAvailable('comments');
	}

	this._setAppAvailable = function(app) {
		this._appAvailable[app] = true;
		/* index this app */
		this.indexAppObjects(app);
		/* execute any queued actions */
		this.executeAppObjectActions(app);
	}

	this.setRatingsAppAvailable = function() {
		this._setAppAvailable('ratings');
	}

	this.setCommentsAppAvailable = function() {
		this._setAppAvailable('comments');
	}

	this.indexAppObjects = function(app) {
		if (app == 'ratings') {
			var appArray = $JRA;
		} else if (app == 'comments') {
			var appArray = $JCA;
		} else {
			alert('Attempt to index invalid app type');
			return;
		}
		for (var i=0; i < appArray.length; i++) {
			// Check that it's not standalone
			if (appArray[i].isStandalone()) {
				continue;
			}
			var uniq = appArray[i].uniq;
			if ( ! this._appObjects[uniq] ) {
				this._appObjects[uniq] = {};
			}
			if ( ! this._appObjects[uniq][app]) {
				this._appObjects[uniq][app] = [];
			}
			this._appObjects[uniq][app].push(appArray[i]);
		}
	}

	this.executeAppObjectActions = function(app) {
		if (this._appObjectActions[app]) {
			for (var i=0; i < this._appObjectActions[app].length; i++) {
				var uniq = this._appObjectActions[app][i].uniq;
				if (this._getAppObject(app, uniq)) {
					this._appObjectActions[app][i].action();
				}
			}
		}
	}

	this._getAppObject = function(app, uniq) {
		if (this._appObjects[uniq] && this._appObjects[uniq][app]) {
			return this._appObjects[uniq][app][0];  // Return only the first
		}
		return null;
	}

	this.getCommentsAppObject = function(uniq) {
		return this._getAppObject('comments', uniq);
	}

	/* Returns a Ratings Object */
	this.getRatingsAppObject = function(uniq) {
		return this._getAppObject('ratings', uniq);
	}

	this.copyRatingsAppObject = function(uniq, node) {
		if ( ! this.isRatingsAppAvailable()) {
			return;
		}
		var oldObj = this.getRatingsAppObject(uniq);
		var newObj = oldObj.clone(node, { 'view':'user', 'commentprompt':'no', 'menu':'no'  } );
		return newObj;
	}

	this._tryAppObjectAction = function(app, uniq, action) {
		if (this._isAppAvailable(app)) {
			if (this._getAppObject(app, uniq)) {
				action();
			}
		} else {
			if ( ! this._appObjectActions[app]) {
				this._appObjectActions[app] = [];
			}
			this._appObjectActions[app].push( { 'uniq' : uniq, 'action' : action } );
		}
	}

	this.tryRatingsAppObjectAction = function(uniq, action) {
		this._tryAppObjectAction('ratings', uniq, action);
	}

	this.tryCommentsAppObjectAction = function(uniq, action) {
		this._tryAppObjectAction('comments', uniq, action);
	}
}

/* Singleton-like handler */
JSKitGlobal.getInstance = function() {
	if ( ! window.JSKitGlobalInstance) {
		JSKitGlobalInstance = new JSKitGlobal();
	}
	return JSKitGlobalInstance;
}



/* JSKitGlobal  object */
$JSKitGlobal = JSKitGlobal.getInstance();



JSKitLib.getPermalink = function(target) {
	return target.getAttribute('permalink') || window.location.href;
}

JSKitLib.getTitle = function(target) {
	return target.getAttribute('title') || document.title;
}

JSKitLib.getRef = function(self, ignorePath) {
	var wl = window.location;
	return wl.protocol + '//'
		+ (self.pathOverride
			? (self.config.domain.replace(/\/.*/, '')
				+ (ignorePath ? '' : self.pathOverride))
			: (self.config.domain + wl.pathname));
}

JSKitLib.getPath = function(self) {
	return self.path;
}

JSKitLib.getConfig = function(target, getValue, cf) {
	for(var i = 3; i < arguments.length; i++) {
		var arg = arguments[i];
		if(typeof(arg) == 'string') arg = [arg];
		var name = arg[0];
		var value = getValue.call(this, name, target.getAttribute(name));
		if(arg.length > 1) {
			if(typeof(arg[1]) == 'number') {
				if(value) {
					var n = parseInt(value);
					if(isNaN(n) || n < 0) {
						if(value == "no")
							value = 0;
						else
							value = arg[1];
					} else {
						value = n;
					}
				} else
					value = arg[1];
			} else if(typeof(arg[1]) == 'object') {
				for(var j=arg[1].length; j; j--)
					if(arg[1][j-1] == value)
						break;
				if(!j) value = arg[1][j];
			} else {
				if(!value) value = arg[1];
			}
		}
		cf[name] = value;
	}
	return cf;
}



function JSDL(elmParent, arrDragElms) {
       var self = this;
       self.isIE = JSKitLib.isIE();
       var drgElms = arrDragElms || [elmParent];
       for(var i=0; i<drgElms.length; i++) {
               self.addDraggableChild(drgElms[i]);
       }
       self.elmParent = elmParent;
       self.setParent = 1;
}

JSDL.prototype.reSetDragParent = function () {
       if(!this.setParent) return;
       if(this.elmParent.parentNode!=document.body || this.elmParent.style.position!='absolute') {
               var elmPos;
               if(this.elmParent.parentNode) {
                       elmPos = this.getElmAbsPos(this.elmParent, false);
                       this.elmParent.parentNode.removeChild(this.elmParent);
               }
               document.body.appendChild(this.elmParent);
               this.elmParent.style.position = 'absolute';
               if(elmPos) {
                       this.elmParent.style.left = elmPos.x + "px";
                       this.elmParent.style.top = elmPos.y + "px";
               }
       }
       this.setParent = 0;
}

JSDL.prototype.getCurScroll = function() {
       var scroll_left=0,scroll_top=0;
       if(self.pageXOffset){
               scroll_left=self.pageXOffset;
       } else {
               if(document.documentElement&&document.documentElement.scrollLeft){
                       scroll_left=document.documentElement.scrollLeft;
               } else {
                       if(document.body){
                               scroll_left=document.body.scrollLeft;
                       }
               }
       }
       if(self.pageYOffset){
               scroll_top=self.pageYOffset;
       } else {
               if(document.documentElement&&document.documentElement.scrollTop){
                       scroll_top=document.documentElement.scrollTop;
               } else {
                       if(document.body){
                               scroll_top=document.body.scrollTop;
                       }
               }
       }
       return {"scroll_left":scroll_left,"scroll_top":scroll_top};
}

JSDL.prototype.getElmAbsPos = function (element, usescroll){
       var x=0;
       var y=0;
       var e=element;
       var scroll_left=0,scroll_top=0,cur_scroll;
       if(usescroll){
               cur_scroll=this.getCurScroll();
               scroll_left=cur_scroll.scroll_left;
               scroll_top=cur_scroll.scroll_top;
       }
       if(!this.isIE){
               while(e){
                       x+=e.offsetLeft;
                       y+=e.offsetTop;
                       e=e.offsetParent;
               }
               e=element;
               while(e && e!=document.body && e!=document.documentElement){
		       x -= e.scrollLeft || 0;
		       y -= e.scrollTop || 0;
                       e=e.parentNode;
               }
               if(usescroll){
                       x-=scroll_left;
                       y-=scroll_top;
               }
               return {x:x,y:y};
       }
       e=element;
       while(e){
               var left_border=0;
               var top_border=0;
               if(e!=element){
                       var left_border = parseInt(e.style.borderLeftWidth) || 0;
                       var top_border = parseInt(e.style.borderTopWidth) || 0;
               }
               if(document.compatMode == "BackCompat"){
                       x+=e.offsetLeft-left_border;
                       y+=e.offsetTop-top_border;
               } else {
                       x+=e.offsetLeft+left_border;
                       y+=e.offsetTop+top_border;
               }
               try {
                       e=e.offsetParent;
               } catch(err) { e=null; };
       }
       if(usescroll){
               x-=scroll_left;
               y-=scroll_top;
       }
       return {x:x,y:y};
}

JSDL.prototype.addDraggableChild = function(dragElm) {
       var self = this;
       dragElm.style.cursor = "move";
       dragElm.onmousedown = function(e){self.onStartDragHandler(e);}
}

JSDL.prototype.onStartDragHandler = function (e) {
       var self = this;
       self.reSetDragParent();
       e=e || window.event;
       var elmPos = self.getElmAbsPos(this.elmParent, false);
       var mousePos = JSKitLib.getMousePosition(e);
       self.startx = mousePos.x - elmPos.x;
       self.starty = mousePos.y - elmPos.y;
       var maxLeft = document.body.clientWidth - self.elmParent.offsetWidth -
               (parseInt(self.elmParent.style.marginLeft) || 0) -
               (parseInt(self.elmParent.style.marginRight) || 0);

       var onMoveDragHandler = function(event) {
               event = event || window.event;
               var mousePos = JSKitLib.getMousePosition(event);
               var left = mousePos.x - self.startx;
	       self.elmParent.style.left = (left >= maxLeft ? maxLeft : (left < 0 ? 0 : left)) + "px";
               self.elmParent.style.top = (mousePos.y - self.starty < 0) ? 0 : (mousePos.y - self.starty) + "px";
       }

       var onStopDragHandler = function(event) {
               event = event || window.event;
               JSKitLib.removeHandlers(self.elmParent, onMoveDragHandler,
                       onStopDragHandler, true);
               JSKitLib.stopEventPropagation(event);
               if(self.elmParent.jsk$on_stop_drag) self.elmParent.jsk$on_stop_drag(e);
       }

       JSKitLib.addHandlers(self.elmParent, onMoveDragHandler,
               onStopDragHandler, true);
       JSKitLib.stopEventPropagation(e);
       JSKitLib.preventDefaultEvent(e);
       if(self.elmParent.jsk$on_start_drag) self.elmParent.jsk$on_start_drag(e);
}


/* JavaScript Comment Class */
new JSCC(); 

/* JSKitGlobal : App is ready */
$JSKitGlobal.setCommentsAppAvailable();


function JSIPE(obj) {
	var self = this;
	self.obj = obj;
	var form = this.makeForm(obj.title);
	var inp = form.input;
	self.form = form;

	form.cleaner.onmousedown = function(e){
		inp.value = "";
		form.cleaner.style.visibility = "hidden";
		inp.focus();
		JSKitLib.preventDefaultEvent(e || window.event);
	}
	
	var keyHandler = function(e) {
		e = e || window.event;
		setTimeout(function(){
			form.cleaner.style.visibility = (inp.value.length != 0) ? "visible" : "hidden";
			if(obj.type == "Tab") form.cleaner.style.display = "none";
		}, 0);
		switch(e.keyCode || e.which) {
			case 27:
				if(obj.mode == "full") self.finishEditing(obj.field, obj.field.lastValue);
				if(obj.jsk$on_cancel_exit) obj.jsk$on_cancel_exit();
			break;
			case 10: case 13:
				JSKitLib.preventDefaultEvent(e);
				if (inp.value && obj.mode == "full")
					self.finishEditing(obj.field, inp.value);
				if(obj.jsk$on_submit_exit) obj.jsk$on_submit_exit(inp.value);
			break;
			case 9:
				JSKitLib.preventDefaultEvent(e);
				if (obj.siblings) obj.siblings[(obj.field.pos+1)%obj.siblings.length].tabKeyHandler();
			break;
		}
	}
	self.addKeyHndl(keyHandler);		
	if (obj.inpSize) inp.style.width = obj.inpSize;
	form.cleaner.style.visibility = "hidden";
	if(obj.mode == "form") return form;

	if(!window.jsipe$glob) window.jsipe$glob = {};
	var glob = window.jsipe$glob;
	obj.field.style.cursor = "pointer";
	if(obj.siblings) obj.field.pos = obj.siblings.length;

	this.finishEditing = function(field, newValue) {
		if(!field.input) return;
		glob.isEditing = false;
		field.input.onblur = JSKitLib.isOpera() ? undefined : "";
		field.input.onkeypress = JSKitLib.isOpera() ? undefined : "";
		field.input = null;
		field.wasEdited(newValue);
		field.style.textDecoration = field.oldDecoration;
	}

	var onclickHandler = function() {
		if(obj.field.input) return false;
		if(obj.jsipe$start && !obj.jsipe$start()) return false;
		if(glob.stopEditing) glob.stopEditing();
		if(obj.containerElement.tId) {
			clearTimeout(obj.containerElement.tId);
			obj.containerElement.tId = 0} 
		obj.field.oldDecoration = obj.field.style.textDecoration;
		obj.field.isHtmlLink = obj.field.firstChild.tagName == 'A';
		obj.field.lastValue = obj.itemObject[obj.Property];
		obj.field.ondblclick = JSKitLib.isOpera() ? undefined : "";
		inp.type = 'text';
		inp.value = obj.itemObject[obj.Property];
		self.addKeyHndl(keyHandler);		

		inp.onblur = function(e) {
			if(self.form.input.value) {
				self.finishEditing(self.obj.field, self.form.input.value);
				if (obj.field.lastValue == self.form.input.value) {
					if(obj.jsk$on_cancel_exit) obj.jsk$on_cancel_exit(self.form.input.value)}
				else{
					if(obj.jsk$on_submit_exit) obj.jsk$on_submit_exit(self.form.input.value)}
			};
			//Do not close field until non-empty
		}

		obj.field.input = inp;
		glob.stopEditing = function() {
			glob.stopEditing = null;
			if((obj.field.input)&&obj.field.input.value) self.finishEditing(obj.field, obj.field.input.value);
		}
		while(obj.field.hasChildNodes())
			obj.field.removeChild(obj.field.firstChild);
		obj.field.appendChild(form.main);
		obj.field.style.textDecoration = "none";
		form.cleaner.style.visibility = (inp.value.length != 0) ? "visible" : "hidden";
		if(obj.type == "Tab") form.cleaner.style.display = "none";
		inp.onselectstart = function(e) {
			JSKitLib.stopEventPropagation(e || window.event);
			return true;
		};
		obj.containerElement.onselectstart = function(e) { return true };
		inp.focus();
		inp.select();
		glob.isEditing = true;
		return false;
	}

	var ondblclickHandler = function() {
		if(0 && obj.field.isHtmlLink)
			window.location.href = this.firstChild.value;
	}

	switch(obj.type) {
	case "Tab":
		obj.field.ondblclick = onclickHandler;
		break;
	case "Others":
                obj.field.onclick = onclickHandler;
                obj.field.tabKeyHandler = onclickHandler;
                obj.field.ondblclick = ondblclickHandler;
		break;
	case "Search":
		obj.field.onclick = onclickHandler;
		break;
	}
}

JSIPE.prototype.addKeyHndl = function(keyHandler){
	var inp = this.form.input;
        switch(this.obj.type) {
        case "Tab":
                if (JSKitLib.isIE()) inp.onkeydown = keyHandler;
                else if(JSKitLib.isSafari()) inp.onkeyup = keyHandler;
                else inp.onkeypress = keyHandler;
                break;
        case "Others":
		if(JSKitLib.isOpera()) inp.onkeypress = keyHandler;
		else inp.onkeydown = keyHandler;
                break;
        case "Search":
		if (JSKitLib.isIE() || JSKitLib.isSafari())
			inp.onkeydown = keyHandler;
		else inp.onkeypress = keyHandler;
                break;
        }
}

JSIPE.prototype.makeForm = function(title){
	var text = this.dtContent.replace(/TITLE/, title || "");
	var div = JSKitLib.html(text);
	var ctls = JSKitLib.mapClass2Object({}, div);
	if(!title) ctls['js-JSIPETitle'].style.display = "none";
	return {'main': div,'input': ctls['js-JSIPEInput'], 'cleaner':ctls['js-JSIPECleaner']};
}

JSIPE.prototype.dtContent
='<table border=0 style="padding: 0px; display: inline" cellspacing="0px" cellpadding="0px">'
+'      <tr>'
+'              <td class="js-JSIPETitle" style="padding:0px 4px 0px 0px; cursor: text;"><b>TITLE</b></td>'
+'              <td style="padding: 0px;">'
+'                      <input class="js-JSIPEInput" style="vertical-align:middle; padding: 0px;"></input></td>'
+'              <td style="padding: 0px;">'
+'                      <img class="js-JSIPECleaner" style="margin-left: 4px; vertical-align:bottom; cursor: pointer;" src="http://js-kit.com/images/clear-search-button.gif" width="16" height="16"></img></td>'
+'      </tr>'
+'</table>';




if(!window.JSKW$Events){
        var JSKW$Events = new JSEC();
}

/////////////////////////////////////
// JS Event Class
/////////////////////////////////////
function JSEC() {
	this.contextHandles = [];
}

JSEC.prototype.registerEventCallback = function (contextHandle, eventHandle, eventName) {
	if(!contextHandle) {
		contextHandle = new JSECC(eventHandle, eventName);
		this.contextHandles.push(contextHandle);
		contextHandle.cHdlId = this.contextHandles.length - 1;
	} else {
		contextHandle.registerEventCallback(eventHandle, eventName);
	}
	return contextHandle;
}

JSEC.prototype.deRegisterEventCallback = function (contextHandle, eventHandle, eventName) {
	contextHandle.deRegisterEventCallback(eventHandle, eventName);
}

JSEC.prototype.syncBroadcast = function (eventName) {
	var args = arguments;
	JSKitLib.fmap(this.contextHandles, function(c){
		if(c) c.broadCast.apply(c, args);
	});
}

JSEC.prototype.asyncBroadcast = function (eventName) {
	var self = this;
	var args = arguments;
	setTimeout(function(){
		self.syncBroadcast.apply(self, args);
	}, 0);
}

JSEC.prototype.invalidateContext = function (contextHandle) {
	contextHandle.invalidateContext();
	delete this.contextHandles[contextHandle.cHdlId];
}

/////////////////////////////////////
// JS Event Context Class
/////////////////////////////////////
function JSECC(eventHandle, eventName) {
	this.registeredCallbacks = [];
	if(eventName || eventHandle) this.registerEventCallback(eventHandle, eventName);
}

JSECC.prototype.registerEventCallback = function (eventHandle, eventName) {
	var ev = eventName || '';
	if(!this.registeredCallbacks[ev]) this.registeredCallbacks[ev] = [];
	this.registeredCallbacks[ev].push(eventHandle);
}

JSECC.prototype.deRegisterEventCallback = function (eventHandle, eventName) {
	var ev = eventName || '';
	var self = this;
	if(!eventHandle) {
		delete this.registeredCallbacks[ev];
		return;
	}
	JSKitLib.fmap(this.registeredCallbacks[ev], function(evHdl, i){
		if(eventHandle==evHdl) {
			delete self.registeredCallbacks[ev][i];
		}
	});
	if(!this.registeredCallbacks[ev].length) delete this.registeredCallbacks[ev];
}

JSECC.prototype.invalidateContext = function () {
	this.registeredCallbacks = [];
	try {
		this.jsk$invalidate();
	} catch(e) { ; };
}

JSECC.prototype.broadCast = function (eventName) {
	var self = this;
	var ar = [''];
	var args = arguments;
	if(eventName!='') ar.push(eventName);
	JSKitLib.fmap(ar, function(ev){
		if(self.registeredCallbacks[ev]) JSKitLib.fmap(self.registeredCallbacks[ev], function(evHdl){
			evHdl.apply(self, args);
		});
	});
}


function JSCC(target, extra) {
	/* Find the target DIV for all the blog comments */
	this.jcaIndex = $JCA.length;
	$JCA.push(this);
	this.get = function(id) { return document.getElementById(id); }
	this.cr = function(tag) { return document.createElement(tag); }
	var wl = window.location;
	this.uriDomain = (wl.protocol.substr(0, 4) != 'http' ? 'http:' : '')
				+ '//js-kit.com';
	this.uriAvatar = this.uriDomain + '/avatar/';
	this.uri = this.uriDomain + '/comment';
	this.fieldDfl = {};
	this.TC = {};
	this.tmpID = 0;
	this.pathOverride = "";
	this.uniq = wl.pathname;
	this.cmtById = {};
	this.objById = {};
	this.utmpl={};
	this.config = (extra?extra.config:null)||{};
	this.IM = this.config.nolc && extra && extra.sargs && extra.sargs.source=='profileIM' ? (extra.sargs['destProfile'] ? 'foreign' : 'own') : false;
	this.gen = 0;
	this.ctag = null;
	this.czidx = 300;
	this.stripecount = 2;
	this.curstripe = 0;

	this.isStandalone = function() {
		return (this.config.standalone == 'yes');
	}

	this.scoringEnabled = function() {
		return ((this.config.scoring != 'no') && (this.serverOptions.scoring));
	}

	var idName = "js-kit-comments";

	var target = arguments.length ? arguments[0] : this.get(idName);

	if(target) {
		this.labelHTML = target.getAttribute("label");
		var path = target.getAttribute("path");
		if(path) {
			path = String(path);
			var ar = path.match(/^https?:\/\/[^\/]+(.*)/);
			if(ar) this.pathOverride = ar[1];
			else this.pathOverride = path.replace(/^([^\/]+)/,
					wl.pathname + "/$1");
			path = this.pathOverride;
		} else { path=wl.pathname; }
		this.uniq = target.getAttribute("uniq") || path;

		var cn = target.childNodes;
		for(var n=0;n < cn.length;n++) 
			this.utmpl[cn[n].className] = JSKitLib.getOuterHTML(cn[n]);
		if(cn.length) target.innerHTML = "";
		target.style.display = "block";
		target.style.visibility = "visible";
		var utsc = this.utmpl['js-singleComment'];
		if(utsc) this.dtComment = utsc;

		// Override
		var jovs = window.JSKit$Override;
		if(jovs) {
		  for(var i = jovs.length-1; i>=0; i--) {
			var fName = jovs[i][0];
			var func = jovs[i][1];
			this[fName] = func;
		  }
		}
	} else {
		if(!document.body)
			alert("Enclose the script in a <BODY></BODY> tag!");
		var els = document.body.getElementsByTagName(idName);
		var oWay = false;
		if(els && els.length) oWay = true;
		else els = document.body.getElementsByTagName("div");
		if(els && els.length) {
			$JCA.shift();
			for(var i=0; i < els.length;i++)
			  if(oWay || els[i].className.match(/js-kit-comments/))
				new JSCC(els[i]);
			if($JCA.length) return;
			$JCA.push(this);
		}
		document.write('<div id="'+idName+'"></div>');
		target = this.get(idName);
	}
	target.className = idName;
	target.id = "";

	// Handling user configuration settings
	this.config = JSKitLib.getConfig(
		target,
		function(N, V){ return V; },
		this.config,
		['avatars', 'yes'],
		['gravatars', 'no'],
		'gravatar_default',
		['gravatar_rating', 'PG'],
		['gravatar_size', 28],
		['standalone', 'no'],
		['scoring', 'yes'],
		['paginate', 50],
		['backwards', this.config.nolc && !this.IM ? 'yes' : 'no'],
		['domain', wl.host],
		['sort', ['date','karma','name','status','rating']],
		['thread', ['yes','no']],
		'adminBgColor',
		'moderate',
		'permalink'
	);
	this.config.thread = this.config.nolc && !this.IM ? 'no' : this.config.thread;
	this.config.permalink = JSKitLib.getPermalink(target);
	this.config.domain = this.config.moderate || this.config.domain;
	if(this.config.paginate <= 0) this.config.paginate = 200;
	if(target.getAttribute('backwards'))
		this.backwards = (this.config.backwards == 'yes');
	else if(target.getAttribute('paginate'))
		this.backwards = !!this.config.paginate;
	else
		this.backwards = !!this.config.nolc && !this.IM;
	this.preq = {
		srt:this.config.sort,
		ord:(this.backwards?'desc':'asc'),
		thr:this.config.thread,
		sp: 1, pn: 5, ps: this.config.paginate };
	if(!this.preq.ps) this.preq.ps = 100;
	this.preq.pn = Math.round(50 / this.preq.ps);
	if(this.preq.pn < 2) this.preq.pn = 2;

	var self = this;
	self.target = target;

	this.runscr = function(url, args) {
		var sc = this.cr("script");
		sc.setAttribute("charset", "utf-8");
		sc.src = url + (args?"?"+args:"");
		this.target.appendChild(sc);
		return false;
	}

	this.server = function(ext, data) {
		if(this.serverFilter && !this.serverFilter(ext)) return;
		// ensure window.location is current (re:blogspot)
		var wl = window.location;
		var epb = JSKitEPB.getURIEncodedSerialize();
		var sargs = JSKitLib.fmap(((extra||{})['sargs']||{}),
		function(v,k){return k+'='+encodeURIComponent(v);}).join('&');
		var requrl = "ref=" + encodeURIComponent(JSKitLib.getRef(self))
			+ (this.config.moderate?'&mod':'')
			+ "&" + data + (epb ? "&" + epb : "")
			+ (sargs ? '&' + sargs : '');
		var action = ext.match(this.uriDomain) ? ext: this.uri + ext;
		return this.runscr(action, requrl);
	}

	this.serverPOST = function(ext, postdata, ajax) {
		if(this.serverFilter && !this.serverFilter(ext)) return;
		var wl = window.location;
		postdata.push({'Name': 'ref', 'Value': JSKitLib.getRef(self)});
		JSKitLib.fmap(((extra||{})['sargs']||{}),
			function(v,k){postdata.push({'Name': k, 'Value': v});});
		var action = ext.match(this.uriDomain) ? wl.protocol + ext: wl.protocol + self.uri + ext;

		postdata = postdata.concat(JSKitEPB.serialize());
		var getPOSTForm = function(doc, action, postdata) {
			var frm = doc.createElement('form');
			frm.method = 'post';
			frm.action = action;
			for(var j = 0; j < postdata.length; j++){
				var frmel = doc.createElement("input");
				frmel.type = "hidden";
				frmel.name = postdata[j].Name;
				frmel.value = postdata[j].Value;
				frm.appendChild(frmel);
			}
			doc.body.appendChild(frm);
			return frm;
		}

		if(ajax) {
			var i = this.TC['js-CommentsArea'];

			var d = this.cr('div');				
			var tgt = 'jsk-ifrmpost-' + this.jcaIndex + Math.random();
			d.innerHTML = '<iframe id="' + tgt + '" name="' + tgt + '" src="about:blank" width=0 height=0 style="border: none"></iframe>';
			i.appendChild(d);
			var ifrpost = d.firstChild;
			var getFrame = function(FrameName, Parent) {
				var tp = Parent ? getFrameDoc(Parent) : document;
				var fr = tp.getElementById(FrameName).contentWindow;
				return fr;
			}
			var getFrameDoc = function(FrameName, Parent) {
				var FEl = getFrame(FrameName, Parent);
				return FEl.contentDocument ? FEl.contentDocument : FEl.document;
			}

			ifrpost.onreadystatechange = function() {
				if((ifrpost.readyState) && (ifrpost.readyState != 'complete')){
					return;
				}
				var iDOC = getFrameDoc(tgt);
				var td = iDOC.createElement('div');
				var tgtch = 'jsk-ifrmpostch-' + self.jcaIndex + Math.random();
				td.innerHTML = '<iframe id="' + tgtch + '" name="' + tgtch + '" src="" width=0 height=0 style="border: none"></iframe>';
				iDOC.body.appendChild(td);
				var pfr = td.firstChild;

				pfr.onreadystatechange = function() {
					if((pfr.readyState) && (pfr.readyState != 'complete')){
						return;
					}
					if(self.config.moderate) {
						postdata.push({'Name': 'mod', 'Value': ''});
					}
					if(JSKitLib.isIE()){
						postdata.push({'Name': 'IE', 'Value': ''});
					}
					if(navigator.userAgent.indexOf("Opera") != -1){
						postdata.push({'Name': 'Opera', 'Value': ''});
					}
					if(navigator.userAgent.indexOf("Safari") != -1){
						postdata.push({'Name': 'Safari', 'Value': ''});
					}
					var iDOC = getFrameDoc(tgtch, tgt);
					var frm = getPOSTForm(iDOC, action, postdata);

					var getFrameLocation = function(FrameName, Parent) {
						var fr = getFrameDoc(FrameName, Parent);
						return decodeURIComponent(fr.location.href);
					};
					var processpfronload = function () {
						if((pfr.readyState) && (pfr.readyState != 'complete')){
							return;
						}
						var js;
						if(JSKitLib.isIE()){
							var curfr=getFrame(tgt);
							js=decodeURIComponent(curfr.document.title);
						} else if(navigator.userAgent.indexOf("Opera") != -1){
							js=decodeURIComponent(this.location.hash).substr(1);
						} else if(navigator.userAgent.indexOf("Safari") != -1){
							js=decodeURIComponent(frames[tgt].frames[tgtch].location.hash).substr(1);
						} else {
							js=getFrameLocation(tgt).substr(12);
						}
						if(js){
							var sc=self.cr('script');
							sc.text=js;
							self.target.appendChild(sc);
						}
					};
					pfr.onreadystatechange = processpfronload;
					pfr.onload = processpfronload;
					frm.submit();
				};
				pfr.onload = pfr.onreadystatechange;
				if(!JSKitLib.isIE()){
					pfr.onload();
				}
			};
			ifrpost.onload = ifrpost.onreadystatechange;
			if(!JSKitLib.isIE()){
				ifrpost.onload();
			}
		}
		else {
			var frm = getPOSTForm(document, action, postdata);
			frm.submit();
		}
	}

	this.getlocation = function() {
		var wh = String(window.location.href);
		var lp = wh.match(/(.*)#JSKTID=(lapc_[0-9a-f]{10})$/);
		return lp ? {href: lp[1], jsktid: lp[2]}: {href: window.location.href, jsktid: ''};
	}

	this.getpages = function(sp, ap) {
		var preq = self.preq;
		if(!sp) sp = preq.sp;
		self.loading = (new Date()).valueOf();

		var loc = self.getlocation();
		self.server("s-data.js", "jx="+self.jcaIndex
			+ "&gen=" + self.gen
			+ "&srt=" + preq.srt
			+ "&ord=" + preq.ord
			+ (preq.thr=='yes'?'':"&prs=flat")
			+ "&sp="+ sp + "&pn="+ preq.pn + "&ps="+ preq.ps
			+ (loc.jsktid ? '&jsktid=' + loc.jsktid : '')
			+ (ap?ap:''));
	}
	this.getpages();
}

// Optionally leave all CSS up to template
if (!window.$JSKitNoCommentCss) {

	JSKitLib.addCss(''
	+ ".js-OldComments { margin-bottom: 1px; clear:both;}"
	+ ".js-LeaveComment { margin: 3pt 0; }"
	+ ".js-CreateComment, .js-commentInputOpenID, .js-commentOpenID { display: none; }"
	+ ".js-OpenIDError { color: #F00; display: block; max-width: 250px;}"
	+ ".js-CCMore { padding-left: 3px }"
	+ ".js-commentOptions { float: left; }"
	+ ".js-commentSubmit { float: right; }"
	+ ".js-CreateCommentBg { margin: 1em; padding: 0.5em; border: solid 1px #c0c0c0; text-align: left; float: left; }"
	+ ".js-CreateCommentArea { -moz-border-radius: 7px; -webkit-border-radius: 7px; padding: 5px 5px 5px 9px; }"
	+ ".js-CommentsArea .js-CreateCommentArea { background-color: #cbcbcb; }"
	+ ".js-OldComments .js-CreateCommentArea { background-color: transparent; }"
	+ ".js-CreateCommentFieldsWrap { margin-left: -4px; background-color: #ececec; border: solid 1px #b0b0b0; padding: 4px; -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }"
	+ '.js-CreateCommentFields { color: #404040; background-color: #f8f8f8; padding: 4px 4px 4px 4px; -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }'
	+ ".js-PageNavTop { margin-bottom: 3px; } "
	+ ".js-PageNavBottom { margin-top: 3px; } "
	+ ".js-PageNOther { text-decoration: none; }"
	+ ".js-PageNCur { font-weight: bold; }"
	+ ".js-commentFieldSubject { font-weight: bold; margin-bottom: 5px; }"
	+ ".js-commentFieldLabel { margin-top: 5px; }"
	+ ".js-commentOpenID { margin-top: 5px; }"
	+ ".js-commentOpenIDURL { margin-left: 3px; padding-left: 19px; min-height: 16px; background: url('//js-kit.com/images/openid-16x16.png') no-repeat 0 -2px; font-weight: bold; }"
	+ ".js-commentFieldNote { font-family: Verdana; font-size: 7pt; color: #808080; }"
	+ ".js-siteAdmin { font-weight: bold; }"
	+ ".js-singleComment { font-size: 8pt; font-family: Verdana, Helvetica; border: solid 1px #c0c0c0; text-align: left; margin-bottom: -1px; }"
	+ ".js-singleCommentBg { padding: 0.3em; position: relative; }"
	+ '.js-singleCommentHeader { color: #484848; margin: 3px 0; }'
	+ '.js-singleCommentBody { clear: both; color: #404040; background-color: #fefefe; padding: 4px 4px 4px 8px; -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }'
	+ 'table.js-singleCommentBodyT { margin: 0; padding: 0; font-family: Verdana, Helvetica; text-align: left; font-size: 8pt; color: #404040; }'
	+ '.js-singleCommentQuote { font-family: "Times New Roman"; font-size: 32px; line-height: 24px; position: relative; top: 4px; padding-right: 1px; }'
	+ ".js-singleCommentINFO { color: #808080; float: right; padding: 3px; margin-left: 2em; text-align: right;}"
	+ ".js-singleCommentAvatar { float: right; }"
	+ ".js-singleCommentName { font-weight: bold; }"
	+ ".js-singleCommentDate { font-size: 7pt; }"
	+ ".js-singleCommentOrigin { display: none; position: absolute; bottom: 0.3em; font-size: 7pt; color: #808080; }"
	+ ".js-singleCommentKarmaComMod { clear: both; }"
	+ ".js-singleCommentKarma { float: left; font-size: 7pt; color: #808080; margin-right: 2em; padding-top: 3px; }"
	+ ".js-singleCommentKarmaShow { float: left; font-size: 7pt; color: #808080; margin-right: 2em; padding-top: 3px; display: none; }"
	+ ".js-singleCommentKarmaScore { display: none; }"
	+ ".js-singleCommentComMod { white-space: nowrap; float: left; font-size: 7pt; color: #808080; display: none; padding-top: 3px; margin-right: 3em; }"
	+ ".js-singleCommentCtls { float: right; white-space: nowrap; }"
	+ 'div.js-singleCommentReply { font-size: 8pt; background: url(http://js-kit.com/images/button-clear.gif) no-repeat; width: 72px; height: 16px; line-height: 9px; text-align: center; color: #404040; padding-top: 2px; float: left; cursor: pointer; margin: 0 1em 0 4px; }'
	+ ".js-commentControl { float: left; margin-right: 2em; }"
	+ ".js-commentFieldInput { border: solid 1px #7f99b9; width: 100%; }"
	+ ".js-CmtButton { margin-right: 0.5em }"
	+ ".js-CCButtons { margin: 0.3em 0 0.5em 0 }"
	+ ".js-CCButtons INPUT { font-size: 8pt; }"
	+ ".js-poweredBy { margin-top: 2pt; margin-right: 2pt; color: #808080; font-size: 7pt; font-family: Verdana, Helvetica; }"
	+ ".js-poweredBy A { text-decoration: none; color: #8080a0 }"
	+ ".js-antispamBy { text-align: right; }"
	+ ".js-Progress { position: absolute; visibility: hidden; right: 5px; top: 5px; width: 15px; height: 15px; }"
	+ ".js-SettingsWindow { padding: 0.3em; border: solid 1px #cccccc; color: #404040; white-space: normal; font-family: Verdana, Helvetica;}"
	+ ".js-SettingsWindowHeader { text-align:center; padding: 5px 0; margin-bottom: 5px; background-color: #e6e9ec; font-size: 10pt; font-family: Verdana, Helvetica; color: #435362}"
	+ ".js-ControlBlockText, .js-ControlBlockTextDisabled {font-size: 8pt; text-align: left;}"
	+ ".js-ControlBlockButton {font-size: 8pt;}"
	+ ".js-ControlBlockTextDisabled {color: #808080}"
	+ ".js-showBorder {border:ridge 2px #a0a0a0;}"
	+ ".js-hideBorder {border:solid 2px #fefefe;}"
	+ ".js-SearchTitle {margin-right: 5px;}"
	+ ".js-SearchWords {padding: 0px; margin-right: 5px; border-bottom: 1px dashed #0000ff}"
	+ ".js-uploadAvatarForm {margin-top: 0px;}"
	+ ".js-singleCommentConversationHead {padding: 0.3em; " + (JSKitLib.isIE() ? "margin-top: 36px !important;" : "margin-top: 26px !important;") + "}"
	+ ".js-singleCommentConversationChild {padding: 0.3em; margin-top: -1px !important}"
	+ ".js-Conversation {padding: 0.3em; position: relative; top: -20px; display: inline; }"
	+ ".js-ConversationWrapper { height: 0px; " + (JSKitLib.isIE() ? "overflow: hidden;" : "") + "}"
	, 'cmt');
	(function(v){v=parseFloat(v.split("MSIE")[1]);
	if(v>=5.5)JSKitLib.addCss('.js-singleComment{zoom:1} .js-singleCommentBg{zoom:1}', 'zoom');})
	(navigator.appVersion);
	if(navigator.userAgent.indexOf("Opera")>=0)
	JSKitLib.addCss("wbr:after{content:\"\\00200B\"}", 'wbr');
	else
	JSKitLib.addCss(".js-singleCommentTEXT{word-wrap:break-word}", 'wbr');

}

JSCC.prototype.setDefaultField = function(name,value) {
	var epbval = JSKitEPB.getValue(name);
	this.fieldDfl[name]= epbval == undefined ? value : epbval;
}

JSCC.prototype.addChild = function(to, what) {
	if (typeof(to) != 'object')
		return;

	if(arguments.length == 3 && arguments[2])
		to.insertBefore(what, to.firstChild);
	else
		to.appendChild(what);
}

JSCC.prototype.a = function() {
	var a = this.cr("a");
	a.href = "javascript:void(0);";
	for(var text = '', i = 0; i < arguments.length; i++)
		text += arguments[i];
	a.innerHTML += text;
	return a;
}

JSCC.prototype.text = function(div, text) {
	if(div.tagName == "INPUT") {
		div.value = text;
	} else {
		while(div.hasChildNodes()) div.removeChild(div.firstChild);
		div.appendChild(document.createTextNode(text));
	}
	return div;
}

JSCC.prototype.div = function(id) {
	var div = this.cr("div");
	for(var i = 1; i < arguments.length; i++) {
		var arg = arguments[i];
		switch(typeof(arg)) {
		case "string":
			this.addChild(div, document.createTextNode(arg));
			break;
		case "undefined":
			break;
		default:
		case "object":
			if(!arg) break;
			this.addChild(div, arg);
			break;
		}
	}
	if(id) {
		div.className = id;
		var idText = String(id);
		if(idText.charCodeAt(3) < 91)
			this.TC[idText] = div;
	}
	return div;
}

JSCC.prototype.dtComment
 = '<div class="js-singleComment">'
 + '<div class="js-singleCommentBg">'
 + '<div class="js-singleCommentAvatar"></div>'
 + '<div class="js-singleCommentINFO">'
   + '<div class="js-singleCommentName" style="clear:both">{Name}</div>'
   + '<div class="js-singleCommentDate">{Date}</div>'
 + '</div>'
 + '<div class="js-singleCommentRating" style="display:none;"></div>'
 + '<div class="js-singleCommentText">{Text}</div>'
 + '<div class="js-singleCommentKarmaComMod">'
     + '<div class="js-singleCommentKarma">{Label:Like this comment?}'
         + ' [<a class="js-singleCommentKarmaY">{Label:yes}</a>]'
         + ' [<a class="js-singleCommentKarmaN">{Label:no}</a>]'
     + ' <span class="js-singleCommentKarmaScore">({Label:Score}:'
     + ' <span class="js-singleCommentKarmaValue">0</span> {Label:byVotes}'
     + ' <span class="js-singleCommentKarmaVoters">0</span>)'
     + '</span>'
     + '</div>'
     + '<div class="js-singleCommentKarmaShow">{Label:Community assigned karma score}:'
     + ' <span class="js-singleCommentKarmaValueShow">0</span> {Label:byVotes}'
     + ' <span class="js-singleCommentKarmaVotersShow">0</span>'
     + '</div>'
     + '<div class="js-singleCommentComMod">'
         + '{Label:Mark as} <a class="js-singleCommentComModMark">{Label:offensive}</a>'
     + '</div>'
   + '<div class="js-singleCommentCtls">'
     + '<span class="js-singleCommentReplyable">[<a class="js-singleCommentReply">{Label:reply}</a>]</span>'
     + '<span class="js-singleCommentDeletable"> [<a class="js-singleCommentDelete">{Label:delete}</a>]</span>'
     + '<span class="js-singleCommentModeratable"> [<a class="js-singleCommentModerate">{Label:moderate}</a>]</span>'
   + '</div>'
 + '<div class="js-singleCommentOrigin"><a href="{link}">{displayPath}</a></div>'
 + '</div>'
 + '<br clear="all" />'
 + '</div>'
 + '</div>'
;

JSCC.prototype.dtComment2
 = '<div class="js-singleComment">'
 + '<div class="js-singleCommentBg">'
 + '<div class="js-singleCommentHeader">'
 + '<div style="float: left;"><span class="js-singleCommentName">{Name}</span><span class="js-singleCommentProfileLinkable"> [<span class="js-singleCommentName" style="color: #0066cc">?</span>]</span> {Label::depth?replies:says}:</div>'
 + '<div class="js-singleCommentDate" style="float: right;">{Age}</div>'
 + '<div style="clear: both"></div>'
 + '</div>'
 + '<div class="js-singleCommentBody">'
 + '<table border="0" width="100%" cellspacing="0" cellpadding="0" class="js-singleCommentBodyT">'
 + '<tr style="vertical-align: top"><td colspan="2" style="padding-bottom: 8px;">'
 + '<div class="js-singleCommentRating" style="display:none;"></div>'
 + '<div class="js-singleCommentText"><span class="js-singleCommentQuote">&#x201C;</span>{Text}</div>'
 + '</td><td width="{SO:maxAvatarWidth+4}" align="right" rowspan="2">'
 + '<div class="js-singleCommentAvatar"></div>'
 + '</td></tr><td style="vertical-align: bottom">'
     + '<div class="js-singleCommentKarma"><span style="white-space: nowrap">{Label:Like this comment?}</span>'
         + ' [<a class="js-singleCommentKarmaY">{Label:yes}</a>]'
         + ' [<a class="js-singleCommentKarmaN">{Label:no}</a>]'
     + ' <span class="js-singleCommentKarmaScore">({Label:Score}:'
     + ' <span class="js-singleCommentKarmaValue">0</span> {Label:byVotes}'
     + ' <span class="js-singleCommentKarmaVoters">0</span>)'
     + '</span>'
     + '</div>'
     + '<div class="js-singleCommentKarmaShow">{Label:Community assigned karma score}:'
     + ' <span class="js-singleCommentKarmaValueShow">0</span> {Label:byVotes}'
     + ' <span class="js-singleCommentKarmaVotersShow">0</span>'
     + '</div>'
     + '<div class="js-singleCommentComMod">'
         + '{Label:Mark as} <a class="js-singleCommentComModMark">{Label:offensive}</a>'
     + '</div>'
 + '</td><td style="vertical-align: bottom;">'
   + '<div class="js-singleCommentCtls">'
     + '<span class="js-singleCommentReplyable"><div class="js-singleCommentReply">{Label:reply}</div></span>'
     + '<span class="js-singleCommentDeletable"> [<a class="js-singleCommentDelete">{Label:delete}</a>]</span>'
     + '<span class="js-singleCommentModeratable"> [<a class="js-singleCommentModerate">{Label:moderate}</a>]</span>'
   + '</div>'
 + '</td></tr><tr><td colspan="3">'
 + '<div class="js-singleCommentOrigin"><a href="{link}">{displayPath}</a></div>'
 + '</td></tr></table>'
 + '</div>'	// Body
 + '</div>'
 + '</div>'
;

JSCC.prototype.dtCreate
 = '<div class="js-CreateComment">'
 + '<div class="js-CreateCommentBg">'
 + '<div class="js-commentFieldSubject">{Label:leaveComment}</div>'
 + '<div class="js-commentFieldLabel">{Label:nameLabel}</div>'
 + '<div><input name="js-CmtName" SIZE=32 /></div>'
 + '<div class="js-commentInputEmail">'
 + '<div class="js-commentFieldLabel">{Label:emailLabel}'
   + '<div class="js-commentFieldNote">{Label:emailNote}</div>'
 + '</div>'
 + '<div><input name="js-CmtEmail" type="email" SIZE=32 /></div>'
 + '</div>'
 + '<div class="js-commentFieldLabel js-commentRatingDisplay">{Label:ratingLabel}</div>'
 + '<div class="js-commentFieldRating js-commentRatingDisplay"></div>'
 + '<div class="js-commentFieldLabel">{Label:commentLabel}</div>'
 + '<div><textarea name="js-CmtText" ROWS=4 COLS=32></textarea></div>'
 + '<div class="js-commentOpenID">{Label:openidLogin}'
 + ' <span class="js-commentOpenIDURL"></span> [<a class="js-commentOpenIDLogout">{Label:logout}</a>]'
 + '</div>'
 + '<div class="js-commentInputOpenID">'
 + '<div class="js-commentFieldLabel">{Label:openidLabel}'
 + '<div class="js-commentFieldNote">{Label:openidNote}</div>'
 + '</div>'
 + '<div><input name="js-CmtOpenID" type="openid" SIZE=32 /></div>'
 + '<div class="js-OpenIDError"></div>'
 + '</div>'
 + '<div class="js-commentAvatarArea"></div>'
 + '<div class="js-CCButtons"><input type="submit" name="js-Cmtsubmit" class="js-CmtButton" VALUE="{Label:submit}">'
 + '<input type="reset" name="js-Cmtcancel" class="js-CmtButton" VALUE="{Label:cancel}">'
 + '<span class="js-CCMore">[<a class="js-commentMore">{Label:more}</a>]</span>'
 + '</div>'
 + '<div class="js-poweredBy js-antispamBy">(<a href="http://mediatrendsx.com" target="blank">Powered by MTX, LLC</a>)</div>'
 + '<div class="js-poweredBy js-antispamBy">(Spam filtering by <a href="http://akismet.com/" target="akismet">Akismet</a>)</div>'
 + '</div><br clear="all" /></div>'
;

JSCC.prototype.dtCreate2
 = '<div class="js-CreateComment">'
 + '<div class="js-CreateCommentArea">'
 + '<div class="js-commentFieldSubject" style="margin: 0">{Label:leaveComment}</div>'
 + '<div class="js-CreateCommentFieldsWrap">'
 + '<div class="js-CreateCommentFields">'
 + '<div class="js-commentFieldLabel">{Label:nameLabel}</div>'
 + '<div><input class="js-commentFieldInput" name="js-CmtName" SIZE=32 /></div>'
 + '<div class="js-commentInputEmail">'
 + '<div class="js-commentFieldLabel">{Label:emailLabel}'
   + '<div class="js-commentFieldNote">{Label:emailNote}</div>'
 + '</div>'
 + '<div><input class="js-commentFieldInput" name="js-CmtEmail" type="email" SIZE=32 /></div>'
 + '</div>'
 + '<div class="js-commentFieldLabel js-commentRatingDisplay">{Label:ratingLabel}</div>'
 + '<div class="js-commentFieldRating js-commentRatingDisplay"></div>'
 + '<div class="js-commentFieldLabel">{Label:commentLabel}</div>'
 + '<div><textarea class="js-commentFieldInput" name="js-CmtText" ROWS=4 COLS=32></textarea></div>'
 + '<div class="js-commentOpenID">{Label:openidLogin}'
 + ' <span class="js-commentOpenIDURL"></span> [<a class="js-commentOpenIDLogout">{Label:logout}</a>]'
 + '</div>'
 + '<div class="js-commentInputOpenID">'
 + '<div class="js-commentFieldLabel">{Label:openidLabel}'
 + '<div class="js-commentFieldNote">{Label:openidNote}</div>'
 + '</div>'
 + '<div><input class="js-commentFieldInput" name="js-CmtOpenID" type="openid" SIZE=32 /></div>'
 + '<div class="js-OpenIDError"></div>'
 + '</div>'
 + '<div class="js-commentAvatarArea"></div>'
 + '</div>' // Fields
 + '<div class="js-CCButtons">'
 + '<div class="js-commentOptions"><input type="button" class="js-commentMore" value="{Label:optionsD}" less="{Label:optionsU}" more="{Label:optionsD}"></input></div>'
 + '<div class="js-commentSubmit">'
 + '<input type="reset" name="js-Cmtcancel" class="js-CmtButton" VALUE="{Label:cancel}">'
 + '<input type="submit" name="js-Cmtsubmit" class="js-CmtButton" VALUE="{Label:submit}">'
 + '</div>'
 + '<div style="clear: both"></div>'
 + '</div>'
 + '<div class="js-poweredBy js-antispamBy">(<a href="http://mediatrendsx.com" target="blank">Powered by MTX, LLC</a>)</div>'
 + '<div class="js-poweredBy js-antispamBy">(Spam filtering by <a href="http://akismet.com/" target="akismet">Akismet</a>)</div>'
 + '</div>'
 + '</div><br clear="all" /></div>'
;


JSCC.prototype.dtProfileCreate
 = '<div class="js-CreateComment">'
 + '<div class="js-CreateCommentBg">'
 + '<div class="js-commentFieldSubject">{Label:leaveComment}</div>'
 + '<div class="js-commentInputName">'
 + '<div class="js-commentFieldLabel">{Label:nameLabel}</div>'
 + '<div><input name="js-CmtName" SIZE=32 /></div>'
 + '</div>'
 + '<div class="js-commentInputEmail">'
 + '<div class="js-commentFieldLabel">{Label:emailLabel}'
   + '<div class="js-commentFieldNote">{Label:emailNote}</div>'
 + '</div>'
 + '<div><input name="js-CmtEmail" type="email" SIZE=32 /></div>'
 + '</div>'
 + '<div class="js-commentFieldLabel js-commentRatingDisplay">{Label:ratingLabel}</div>'
 + '<div class="js-commentFieldRating js-commentRatingDisplay"></div>'
 + '<div class="js-commentFieldLabel">{Label:commentLabel}</div>'
 + '<div><textarea name="js-CmtText" ROWS=4 COLS=32></textarea></div>'
 + '<div class="js-CCButtons"><input type="submit" name="js-Cmtsubmit" class="js-CmtButton" VALUE="{Label:submitPM}">'
 + '<input type="reset" name="js-Cmtcancel" class="js-CmtButton" VALUE="{Label:cancel}">'
 + '</div>'
 + '</div><br clear="all" /></div>'
;

JSCC.prototype.dtConversation
 = '<div class="js-ConversationWrapper">'
 + '<div class="js-Conversation">'
 + '{Label}<span class="js-ConversationName"><b>{Name}</b></span>'
 + '</div>'
 + '</div>'
;

JSCC.prototype.mapComments = function(cmts) {
	var cn = cmts.childNodes;
	if(cn) {
		var clen = cn.length;
		var cmt, id, obj;
		for(var i = 0; i < clen; i++) {
			cmt = cn[i];
			id = cmt.id;
			if(id && (obj = this.objById[id])) {
				this.fixComment(cmt, obj);
			} else {
				this.mapComments(cmt);
			}
		}
	}
}

JSCC.prototype.localDate = function(t) {
	if(!t) return "";
	var d = new Date(t * 1000);
	return d.toLocaleDateString();
}

JSCC.prototype.localTime = function(t) {
	if(!t) return "";
	var d = new Date(t * 1000);
	return d.toLocaleTimeString();
}

JSCC.prototype.localAge = function(t) {
	if(!t) return "";
	if(t)
	var d = new Date(t * 1000);
	var day = Math.ceil((new Date()).valueOf() / 86400000) * 86400;
	var when = Math.floor((day - t) / 86400);
	switch(when) {
	case 0: when = $JCL("Today"); break;
	case 1: when = $JCL("Yesterday"); break;
	default:
		if(when > 0 && when < 6)
			when = when + $JCL(" days ago");
		else
			when = d.toLocaleDateString();
	}
	return when + ", " + d.toLocaleTimeString();
}

JSCC.prototype.gtmpl = function(t, mObj) {
	var lowercase = function(a, m) { return String(m).toLowerCase(); }
	t = t.replace(/^[^<]*(<.*>)[^>]*$/m, "$1");
	t = t.replace(/(<[\/]?[A-Z]+)/g, lowercase);
	if(mObj && mObj.ID) t = t.replace(/(<[a-z]+)/, '$1 id="' + mObj.ID + '"');
	t = t.replace(/{Label:([^:}]+[^}]*)}/g,function(a,m){return $JCL(m);});
	return t;
}
JSCC.prototype.tmpl = function(t, obj, dontPutId) {
	var self = this;
	t = self.gtmpl(t, dontPutId ? false : obj);
	t = t.replace(/{Age}/g, self.localAge(obj.TS));
	t = t.replace(/{Date}/g, self.localDate(obj.TS));
	t = t.replace(/{Time}/g, self.localTime(obj.TS));
	var text = String(obj.Text);
	if ((obj.status == 'M' || obj.status == 'H')
		&& (this.serverOptions.mmode == 'pre' || (obj.msgtype && obj.msgtype.match(/T|P/)))) {
		text += (this.serverOptions.mtext || '');
	}
	text = text.replace(/^[ \s]+|[ \s]+$/, '');
	text = text.replace(/\n\n+/g, '\n\n');
	text = text.replace(/\n/g, '&nbsp;<br />');
	if(text.indexOf('<') == -1)
	text = text.replace(/([^&<>\s]{12})([^&<>\s]{12})/g, '$1<wbr></wbr>$2');
	text = text.replace(/{/g, '&#123;');
	t = t.replace(/{Text}/g, text);
	t = t.replace(/{Label:(:([a-z]+)\?([^:}]*):([^}]*))?([^}]*)}/g,
		function(a,b,p,f,s,m){
			if(p) m = (obj[p]?f:s)+m;
			return $JCL(m);
		});
	var d = {"SO:":this.serverOptions,"":obj};
	t = t.replace(/{([A-Z]+:)?([A-Za-z0-9]+)(\+\d+)?}/g,
		function(a,t,m,p){ var v = ((d[t]||obj)[m])||''; if(p) v = parseInt(v) + parseInt(p); return v; });
	return t;
}

JSCC.prototype.FRef = function(cmt, tgt, funcName) {
	if(!cmt || !tgt) return;

	var self = this;
	var args = arguments;

	tgt.href = "";
	tgt.onclick = function() {
	  try {
		var arr = [];
		if(cmt) arr.push(cmt.id);
		for(var i = 3; i < args.length; i++) arr.push(args[i]);
		self[funcName].apply(self, arr);
	  } catch(e) { ; }
		return false;
	}
}

JSCC.prototype.cmtSetSpamStatus = function(cmt, s) {
	cmt.cobj.status = s ? 'S' : 'A';
	if(s) {
		cmt.style.background = '#ffffe0 url(' + this.uriDomain + '/images/bio-hazard.gif) bottom right repeat-x';
		cmt.style.color = '#404040';
	} else {
		cmt.style.backgroundColor = "";
		cmt.style.backgroundImage = "";
		cmt.style.color = '';
	}
	if(cmt.domINFO) cmt.domINFO.style.backgroundColor = s ? '#ffffe0' : "";
}

JSCC.prototype.cmtSetOffensiveStatus = function(cmt, s) {
	cmt.cobj.status = s ? 'O' : 'A';
	if(s) {
		cmt.style.background = '#ffffe0 url(' + this.uriDomain + '/images/bio-hazard.gif) bottom right repeat-x';
		cmt.style.color = '#404040';
	} else {
		cmt.style.backgroundColor = "";
		cmt.style.backgroundImage = "";
		cmt.style.color = '';
	}
	if(cmt.domINFO) cmt.domINFO.style.backgroundColor = s ? '#ffffe0' : "";
}

JSCC.prototype.blockAction = function(action) {
	var s = this;
	var cid = s.ctBlock.forId;
	var cmt = s.cmtById[cid];
	s.hideSettingsWindow('ctBlock');
	switch(action) {
	case "approve":
		s.cmtApprove(cid);
		break;
	case "approveuser":
		s.cmtApproveUser(cid);
		break;
	case "delete":
		s.cmtDelete(cid, 'delete');
		break;
	case "spam":
		s.cmtSetSpamStatus(cmt, true);
		if(s.config.moderate)
			s.pathOverride = cmt.cobj.path;
		s.server('.jnk','id='+cid+"&junk=yes");
		setTimeout(function() { // screen del
			s.cmtDelete(cid, 'ignore');
		}, 1000);
		break;
	case "ip":
	case "user":
		if(s.config.moderate)
			s.pathOverride = cmt.cobj.path;
		s.server('.blk','id='+cid+"&by="+action);
		s.cmtDelete(cid, 'delete');
		break;
	}
}

JSCC.prototype.cmtBlock = function(cid) {
	var s = this;
	var cmt = s.cmtById[cid];
	var status = cmt.cobj.status;
	var msgtype = cmt.cobj.msgtype || '';
	if(s.ctBlock) { s.hideSettingsWindow('ctBlock'); return; }
	if(!s.blockDom) { s.blockDom = {}; }
	if(!s.blockDom[status]) { var jca = '$JCA[' + s.jcaIndex + '].blockAction';
	var cb = function(a, d) {
		return '" class="js-ControlBlockButton" '+(d ? 'disabled="on"' : '')+'" onclick="this.blur();'+jca+"('"+a+'\');return false;" /></span></td></tr>';}
	var trth =  '<tr><td style="font-size: 9pt; background-color: #8192a2; color: #ffffff;"align=left><nobr>';
	var trtd = '</nobr></td></tr><tr><td class="js-ControlBlockText">';
	var trtdd = '</nobr></td></tr><tr><td class="js-ControlBlockTextDisabled">';
	var tinp = '<span style="float:right"><input type=submit value="';

	var mtrt = trtd, aumsg, ammsg;
	switch(status) {
	case 'A':
		mtrt = trtdd;
		aumsg = "This user has a trusted status";
		ammsg = "The message is not blocked";
		break;
	case 'S':
		aumsg = "Approve this and future messages from this user";
		ammsg = "This message is not spam or junk";
		break;
	case 'O':
		aumsg = "Approve this message";
		ammsg = "This message is not spam or junk";
	default: // M/H
		aumsg = "Approve future messages from this user";
		ammsg = "Accept this message as good";
	}

	s.blockDom[status] = JSKitLib.html('<table border="0" cellpadding="4" cellspacing="0">'
	+ (s.serverOptions.mmode != 'onhold' ? '' : (
		trth + 'Approve user' + trtd + aumsg
		+ tinp + 'Approve user' + cb('approveuser', status == 'A')))
	+ trth + 'Approve message'
	+ mtrt + ammsg
	+ tinp + 'Approve message' + cb('approve', status == 'A')
	+ trth + 'Delete unwanted comment'
	+ trtd + 'Get rid of comment without prejudice'
	+ tinp + 'Delete' + cb('delete')
	+ trth + 'Flag as Spam or Junk'
	+ trtd + 'Train <a href="http://akismet.com">Akismet</a> to flag similar comments in the future'
	+ tinp + 'Spam/Junk' + cb('spam')
	+ trth + 'Block this commenter'
	+ trtd + 'Make comments from this user invisible to other users'
	+ tinp + 'Block User'+cb('user')
	+ trth + 'Block commenter\'s IP'
	+ trtd + 'Make comments from this IP invisible to other users'
	+ tinp + 'Block IP'+cb('ip')
	+ "</table>");
	}
	s.settingsWindow('ctBlock', cmt.domCtls || cmt.domINFO, s.blockDom[status]);
	s.ctBlock.forId = cid;
}
JSCC.prototype.cmtApprove = function(cid) {
	var cmt = this.cmtById[cid];
	if(cmt.cobj.status == 'S') {
		this.cmtSetSpamStatus(cmt, false);
		cmt.cobj.status = 'S'; // cmtDelete's deal
	}
	if(cmt.cobj.status == 'O') {
		this.cmtSetOffensiveStatus(cmt, false);
		cmt.cobj.status = 'O';
	}
	this.cmtDelete(cid, 'message');
}

JSCC.prototype.cmtApproveUser = function(cid) {
	var cmt = this.cmtById[cid];
	if(cmt.cobj.status == 'S') {
		this.cmtSetSpamStatus(cmt, false);
		cmt.cobj.status = 'S'; // cmtDelete's deal
	}
	this.cmtDelete(cid, 'user');
}

JSCC.prototype.routeMsg = function(fname, args) {
	var myRef = JSKitLib.getRef(this);
	var a = [this];
	var rtShared = {};
	for(var i = 0; i < $JCA.length; i++) {
		if($JCA[i].jcaIndex != this.jcaIndex
		&& JSKitLib.getRef($JCA[i]) == myRef &&
		!this.IM && !$JCA[i].IM)
			a.push($JCA[i]);
	}
	for(var i = 0; i < a.length; i++) {
		var e = a[i];
		e.rtShared = rtShared;
		if(i) e.serverFilter = function(n) {
			return (n == 's-data.js'); }
		e[fname].apply(e, args);
		delete e.serverFilter;
	}
}

JSCC.prototype.cmtDelete = function(cid, approvalMode) {
	this.routeMsg("cmtDeleteAct", arguments);
}

JSCC.prototype.cmtDeleteAct = function(cid, approvalMode) {
	var cmt = this.cmtById[cid];
	if(!cmt) {
		(this.objById[cid]||{}).status = 'D';
		this.serverOptions.pages.tc--;
		this.reCalcPages();
		return;
	}

	if(arguments.length == 1) approvalMode = 'delete';

	var oldStatus = cmt.cobj.status;
    
	if(this.config.moderate || (this.config.nolc && !this.IM))
		this.pathOverride = cmt.cobj.path;
	if(this.config.nolc && !this.IM)
		this.config.domain = cmt.cobj.domain;
	switch(approvalMode) {
	case 'message':
		var perm = (this.config.permalink ? ('&permalink=' + encodeURIComponent(this.config.permalink)) : '');
		if (!this.inlineModeration) {
			this.preHandlerDelete(cmt);
		}
		if(oldStatus == 'S') {
			this.server('.jnk', 'id=' + cid + '&junk=no' + perm);
		} else if(oldStatus == 'O') {
			this.server('-appr.cgi', 'id=' + cid + perm);
		} else {
			this.server('.del', 'id=' + cid + '&apr=message' + perm);
		}
		if (this.inlineModeration) {
			this.postHandlerModerate(cid);
		} else {
			this.postHandlerDelete();
		}
		break;
	case 'user':
		if (!this.inlineModeration) {
			this.preHandlerDelete(cmt);
		}
		this.server('.del', 'id=' + cid + '&apr=user'
			+ (oldStatus == 'S' ? '&junk=no' : ''));
		if (this.inlineModeration) {
			this.postHandlerModerate(cid);
		} else {
			this.postHandlerDelete();
		}
		break;
	case 'delete':
		this.preHandlerDelete(cmt);
		this.server('.del', 'id=' + cid);
		this.postHandlerDelete();
		break;
	case 'ignore':
		/* Just delete from screen */
	default:
		this.preHandlerDelete(cmt);
		this.postHandlerDelete();
	}
}

JSCC.prototype.preHandlerDelete = function(cmt) {
	var p = this.getPageByCmtId(cmt.cobj.ID) - 1;
	if(this.IM) {
		var cobj = cmt.cobj;
		if(p>=0) {
			var cnt = 0;
			for(var i=0; i<this.pages[p].oarr.length; i++) {
				if(this.pages[p].oarr[i].conversation==cobj.conversation
					&& this.pages[p].oarr[i].status!='D'
					&& this.pages[p].oarr[i].status!='DT') cnt++;
			}
			if(cnt>1 && cmt.cobj.hasCnvs) {
				cmt.cobj.status = 'DT';
				var jsc = function(t){return cmt.ctls['js-singleComment'+t]};
				var av = jsc('Avatar');
				if(av) av.style.display = "none";
				var ci = jsc('INFO');
				if(ci) ci.style.display = "none";
				var cc = jsc('Ctls');
				if(cc) cc.style.display = "none";
				cmt.cobj.Text = 'Deleted';
				this.objRerender(cmt.cobj, cmt);
				return;
			} else if(cnt<=1){
				var i = 0;
				var cn = this.pages[p].div.childNodes;
				while(i<cn.length) {
					if(cn[i].cobj.status == 'D') {
						i++;
						continue;
					}
					if(cn[i].cobj.conversation==cobj.conversation) {
						cn[i].cobj.status = 'D';
						cn[i].style.display = "none";
						this.pages[p].items--;
						this.serverOptions.pages.tc--;
					}
					i++;
				}
				this.rePaginate();
				return;
			}
		}
	}
	cmt.cobj.status = 'D';
	cmt.style.display = "none";
	if(p>=0) this.pages[p].items--;
	this.serverOptions.pages.tc--;
	this.rePaginate();
	this.reCalcPages();
	if(this.IM) this.reConversation();
}

JSCC.prototype.postHandlerDelete = function() {

	var p = this.pages[this.curPage - 1];
	if(p.ss) {
		this.ctag = null;
		this.czidx = 300;
		var pageNo = this.curPage;
		this.curPage = 0;
		this.displayPage(pageNo);
	}
	this.reStripe();
}

JSCC.prototype.postHandlerModerate = function(cid) {
	var cmt = this.cmtById[cid];
	cmt.cobj.status = 'A';
	this.objRerender(cmt.cobj, cmt);
}

JSCC.prototype.createCommentAsHTML = function(obj) {
	if(obj.status == 'D') return '';
	if(this.objppc) this.objppc(obj);
	return this.tmpl(this.dtComment, obj);
}

JSCC.prototype.createSingleComment = function(obj) {
	if(!obj.ID || !obj.Text) return undefined;

	if(obj.status == 'D') {
		var cmt = this.cr("div");
	} else {
		var oldN = obj.Name;
		obj.Name = (this.IM && obj.yours) ? 'Me' : oldN;
		var cmt = JSKitLib.html(this.createCommentAsHTML(obj));
		obj.Name = oldN;
	}

	cmt.id = obj.ID;
	this.fixComment(cmt, obj);

	return cmt;
}

JSCC.prototype.markOffensive = function(cid) {
	var p = confirm($JCL("isJunkVote"));
	if(p) {
		if ((this.adminMode) && (!this.inlineModeration)) {
			this.cmtDelete(cid);
		} else {
			this.server('-mark.off','id='+cid);
		}
	}
}

JSCC.prototype.showProfile = function(av, obj, profileLevel) {
	if(!obj.profile || !this.serverOptions.showProfile) return;
	av.cmtTarget = this.target;
	av.targetRef = JSKitLib.getRef(this);
	if(window.JSKW$Prof) {
		JSKW$openProfile(obj.profile, av, profileLevel);
	} else {
		window.jsk$prof$tgt = av;
		this.server(this.uriDomain + '/api/profile/get',
			'target=jsk%24prof%24tgt&profile=' + obj.profile);
       }
}

JSCC.prototype.fixComment = function(cmt, obj) {
	var self = this;

	self.objById[obj.ID] = obj;
	self.cmtById[obj.ID] = cmt;
	if(obj.status == 'D') {
		cmt.style.display = 'none';
		return;
	}

	if(obj.depth) {
		cmt.style.marginLeft = this.level4margin(obj.depth)
	} else {
		obj.depth = 0;
	}

	var ctls = JSKitLib.mapClass2Object({}, cmt);
	cmt.ctls = ctls;
	cmt.cobj = obj;
	var jsc = function(t){return ctls['js-singleComment'+t]}

	var stripe = jsc('Body') || jsc('');
	stripe.className += " js-singleCommentDepth" + (obj.depth || 0);
	if(!(cmt.style.display.match(/none/))){
		stripe.className += " js-comment-stripe-" + ((this.curstripe++ % this.stripecount) + 1);
	}

	if(self.IM && typeof(obj.conversation)=='number') {
		var cnvs = self.conversations[obj.conversation];
		var p = self.getPageByCmtId(obj.ID) - 1;
		var existsCnvs = false;
		if(p>=0) {
			if(!self.pages[p].conversations) self.pages[p].conversations = {};
			if(self.pages[p].conversations[obj.conversation]) {
				existsCnvs = true;
			} else {
				self.pages[p].conversations[obj.conversation] = 1;
			}
		}
		if(cnvs && !existsCnvs) {
			obj.hasCnvs = true;
			this.appendConversation(cmt, obj.conversation);
		} else {
			this.appendConversationChild(cmt);
		}
	}

	/* Handle avatars */
	var av = self.placeAvatar(obj, jsc('Avatar'));

	/* Handle if ratings are present */
	if (obj.Rating > 0 && ( ! this.isStandalone()) ) {
		var self = this;
		var action = function() {
			if (jsc('Rating')) {
				jsc('Rating').appendChild(self.createMiniStarObject(obj.Rating, 10));
				jsc('Rating').style.display = '';
				var clear = document.createElement('div');
				clear.style.clear = 'left';
				jsc('Rating').appendChild(clear);
			}
		}
		$JSKitGlobal.tryRatingsAppObjectAction(this.uniq, action);
	} else {
		if (jsc('Rating')) {
			jsc('Rating').style.display = 'none';
		}
	}

	/* Handle Haloscan Specific Items */
	if (obj.Haloscan) {
		if (jsc('Url') && obj.Url) {
			jsc('Url').style.display = '';
		}
	}

	var sa = jsc("Name");
	if(sa) {
		self.rerenderName(cmt);
		if(obj.admin) sa.className = sa.className + " js-siteAdmin";
	}
	var pl = jsc("ProfileLinkable");
	if(pl) {
		if(!(obj.profile && !this.config.nolc))
			pl.style.display = 'none';
	}

	if(!this.scoringEnabled()
	|| obj.yours || !obj.karma || (obj.msgtype && obj.msgtype.match(/T|P/) && !this.serverOptions.trackbackreply) || this.config.nolc) {
		var kA = jsc("Karma");
		if(kA) kA.style.display = "none";
	}
	var kS = jsc("KarmaScore");
	if(kS && obj.karma) {
		var kVal = jsc("KarmaValue");
		var kVot = jsc("KarmaVoters");
		if(obj.karma.votes) {
			self.text(kVal, obj.karma.score);
			self.text(kVot, obj.karma.votesText);
			kS.style.display = "inline";
		}
		var kY = jsc("KarmaY");
		if(kY) {
			kY.href = "";
			kY.onclick = function() {
				obj.karma.recomputeScore(1);
				self.text(kVal, obj.karma.score);
				self.text(kVot, obj.karma.votesText);
				kS.style.display = "inline";
				this.blur();
				return false;
			}
		}
		var kN = jsc("KarmaN");
		if(kN) {
			kN.href = "";
			kN.onclick = function() {
				obj.karma.recomputeScore(-1);
				self.text(kVal, obj.karma.score);
				self.text(kVot, obj.karma.votesText);
				kS.style.display = "inline";
				this.blur();
				return false;
			}
		}
	}
	var kSS = jsc("KarmaShow");
	if(kSS && obj.karma && obj.yours && obj.karma.votes) {
		kSS.style.display = "inline";
		var kVal = jsc("KarmaValueShow");
		var kVot = jsc("KarmaVotersShow");
		self.text(kVal, obj.karma.score);
		self.text(kVot, obj.karma.votesText);
	}

	if(this.serverOptions.commod && !obj.yours && !this.config.nolc && (!obj.msgtype || !obj.msgtype.match(/T|P/) || this.serverOptions.trackbackreply)){
		var cmO = jsc("ComMod");
		if(cmO){
			cmO.style.display = "inline";
			cmM = jsc("ComModMark");
			if(cmM) {
				cmM.href = "";
				cmM.onclick = function() {
					self.markOffensive(obj.ID);
					return false;
				}
			}
		}
	}

	if(this.config.nolc || this.config.moderate) {
		var cP = jsc("Origin");
		if(cP) {
			cP.style.display = "inline";
		}
	}
    /* FIXME(?) Lev, this.serverOptions are not defined in moderation mode
       but the result is likely as desired, i.e. admin can still reply */
	if (this.serverOptions.mmode == "pause" || (obj.msgtype && obj.msgtype.match(/T|P/) && !this.serverOptions.trackbackreply) || (this.config.nolc && (!this.IM || obj.yours))) {
		var rb = jsc("Replyable");
		if(rb) rb.style.display = "none";
	}

	this.FRef(cmt, jsc("Reply"), "ShowCommentDialog");
	this.FRef(cmt, jsc("Delete"), "cmtDelete");
	this.FRef(cmt, jsc("Block"), "cmtBlock");
	this.FRef(cmt, jsc("Moderate"), "cmtBlock");
	this.FRef(cmt, jsc("Approve"), "cmtApprove");
	this.FRef(cmt, jsc("ApproveUser"), "cmtApproveUser");

	var au = jsc("ApproveUser");
	if (au && this.serverOptions.mmode != "onhold")
		au.style.display = "none";

	var hideCtl = jsc("Deletable");
	if(hideCtl && ((!obj.yours && !this.IM && !JSKitEPB.isAdmin(this.pathOverride)) || (this.adminMode && !this.config.nolc)))
		hideCtl.style.display = "none";

	var hideCtl = jsc("Moderatable");
	if(hideCtl && (!this.adminMode || this.config.nolc))
		hideCtl.style.display = "none";

	cmt.bg = jsc('Bg');
	if(this.czidx < 10) this.czidx = 300; else this.czidx--;
	cmt.bg.style.zIndex = this.czidx;
	cmt.domINFO = jsc('INFO');
	cmt.domCtls = jsc('Ctls') || jsc('Control');

	if(obj.isEmbryonic) {
		/* Waiting for permanent ID */
		if(cmt.domCtls) cmt.domCtls.style.visibility = "hidden";
	}

	if(obj.status == 'S')
		this.cmtSetSpamStatus(cmt, true);

	if(obj.status == 'O')
		this.cmtSetOffensiveStatus(cmt, true);

	if(obj.admin && this.config.adminBgColor) {
		cmt.style.backgroundColor = this.config.adminBgColor;
	}

}

JSCC.prototype.level2margin = function(level) {
	if(level < 20) return "10px";
	if(level < 40) return "4px";
	return "0px";
}
JSCC.prototype.level4margin = function(level) {
	if(level <= 20) return (10 * level) + 'px';
	if(level <= 40) return (200 + 4 * level) + 'px';
	return '280px';
}
JSCC.prototype.getPageByCmtId = function(ID) {
	for(var i=0; i<this.pages.length; i++) {
		for(var j=0; j<this.pages[i].oarr.length; j++) {
			if(ID==this.pages[i].oarr[j].ID) return i+1;
		}
	}
	return 0;
};
JSCC.prototype.cmtInDiv = function(div, obj, fincb) {
  var cmt = this.createSingleComment(obj);
  if(!cmt) return null;

  if(obj.ParentID) {
	var prn = this.objById[obj.ParentID];
	var td = prn ? prn.depth : 0;
	if(prn) {
		obj.depth = 1 + td;
		cmt.style.marginLeft = this.level4margin(obj.depth);
		if(this.IM && typeof(prn.conversation)=='number') obj.conversation = prn.conversation;

		this.replyPlacement(obj.ParentID, true, function(immed, apl) {
			if(apl) apl[0].insertBefore(cmt, apl[1]);
			prn.thread.push([obj, '-']);
			var page = this.pages[this.curPage-1];
			page.oarr.splice(apl[2], 0, obj)
			page.harr.splice(apl[2], 0, this.createCommentAsHTML(obj));
			page.items++;
			try { this.czidx = 300;
				for(var i = 0; i < page.oarr.length; i++) {
				var sbl = this.cmtById[page.oarr[i].ID];
				sbl.bg.style.zIndex = this.czidx--;
				}
			} catch(e){;}
			fincb.apply(this, [cmt]);
		});
		return;
	}
  }

  // Fixme! create additional pages as necessary.
  if(this.preq.ord == 'desc') {
	this.displayPage(1, function(immed) {
		var page = this.pages[0];
		page.oarr.unshift(obj);
		page.harr.unshift(this.createCommentAsHTML(obj))
  		this.addChild(page.div, cmt, true);
	  	page.items++;
		fincb.apply(this, [cmt]);
	});
  } else {
	this.displayPage(this.pages.length, function(immed) {
		var page = this.pages[this.curPage - 1];
		page.oarr.push(obj);
		page.harr.push(this.createCommentAsHTML(obj));
  		this.addChild(page.div, cmt, false);
	  	page.items++;
		fincb.apply(this, [cmt]);
	});
  }
  this.rePaginate();
  if(this.IM) {
	  for(var i=0; i<this.conversations.length; i++) {
		  if(this.conversations[i].current) {
			  obj.conversation = i;
			  break;
		  }
	  }
	  if(typeof(obj.conversation)!='number') {
		  this.conversations.push({'direction':'out'});
		  obj.waitConversation = {cnvsIdx: this.conversations.length-1};
	  }
	  this.reConversation();
  }
}

JSCC.prototype.setOpacity = function(div, val) {
	if(div) {
		div.style.opacity = val;
		div.style.filter = 'alpha(opacity: ' + Math.round(val * 100) + ')';
	} else {
		if(document.body.filters)
			return 'zoom:1;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=' + Math.round(val * 100) + ');';
		else
			return 'opacity: ' + val + ';';
	}
}

JSCC.prototype.flash = function(cmt) {
	if(!cmt) return;

	var self = this;
	var bg = cmt.bg;

	try {
		bg.style.backgroundColor = "#ffff00";
		self.setOpacity(bg, 0);
	} catch(e) { return; }

	cmt.cntDown = 3.14 / 2;
	cmt.cntMode = 0;

	cmt.intvl = setInterval(function() {
		cmt.cntDown -= cmt.cntMode ? 0.5 : 0.3;
		if(cmt.cntDown > 0) {
			if(cmt.cntMode)
				var c = Math.sin(cmt.cntDown);
			else
				var c = Math.cos(cmt.cntDown);
			self.setOpacity(bg, c);
		} else if(cmt.cntMode) {
			clearInterval(cmt.intvl);
			cmt.intvl = null;
			bg.style.backgroundColor = "";
			self.setOpacity(bg, 1);
		} else {
			cmt.cntMode = 1;
			cmt.cntDown = 3.14 / 2;
		}
	}, 100);
}

JSCC.prototype.foldInputFields = function(e, acc, f) {
  if(e.getAttribute) {
	var name = e.getAttribute('NAME');
	if(name && (name.substr(0, 6) == 'js-Cmt')
	&& name.charCodeAt(6) < 97) {
		var shortName = name.substr(6);
		acc = f.call(this, e, acc, shortName) || acc;
	}
  }
  var cn = e.childNodes;
  if(cn) {
	var clen = cn.length;
	for(var i = 0; i < clen; i++)
		acc = this.foldInputFields(cn[i], acc, f);
  }
  return acc;
}

JSCC.prototype.inputFieldsMsg = function(ctl, cmtObj, pText) {
	return this.foldInputFields(ctl, [], function(e, a, name){
		var text = name=='Text' ? pText : e.value;
		text = (name=='OpenID' && this.openID) ? this.openID : e.value;
		a.push({"Name": "js-Cmt" + name, "Value": text});
		if(name == 'Text' && this.serverOptions.htmlMode)
			text = text.replace(/<[\/]?[a-z]{1,3}(\s+(href|src)=[^>]+)?>/g, '');
		text = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
		cmtObj[name] = text;
	});
}

JSCC.prototype.cmtInPlace = function(cobj, fincb) {
	var div = this.TC["js-OldComments"];
	this.tmpID++;
	cobj.ID = "jst-" + this.tmpID;
	cobj.isEmbryonic = true;
	cobj.status = 'A';
	if(this.serverOptions.showProfile) cobj.profile = this.serverOptions.profile;
	var shar = this.rtShared;
	if(shar) {
		if(shar.goesInto) shar.goesInto.push(this);
		else shar.goesInto = [this];
		cobj.goesInto = shar.goesInto;
	}
	if(this.chosenAvatar) {
		var a = this.chosenAvatar[0];
		cobj.avatar = a.name;
		cobj.avatarWidth = a.width;
		cobj.avatarHeight = a.height;
	}
	cobj.thread = [];
	cobj.depth = 0;
	cobj.jcaIndex = this.jcaIndex;
	cobj.admin = this.adminMode;
	var d = new Date();
	cobj.TS = Math.round(d.valueOf() / 1000);
	this.cmtInDiv(div, cobj, function(cmt) {
		if(cmt) this.flash(cmt);
		fincb.apply(this, [cmt]);
	});
}

JSCC.prototype.pageShiftLastItem = function() {
	// Find the last non-deleted item on this page;
	var page = this.pages[this.curPage - 1];
	var pli;
	for(var li = page.div.lastChild; li; li = pli) {
		pli = li.previousSibling;
		if(li.cobj) {
			li.parentNode.removeChild(li);
			if(li.cobj.status != 'D')
				break;
		}
	}
	this.pageShiftItemDescription(this.curPage);
}

JSCC.prototype.pageShiftItemDescription = function(pageNo, flush) {
	if(pageNo >= this.pages.length) return;
	var page = this.pages[pageNo - 1];
	var npage = this.pages[pageNo];
	npage.rmdiv();
	var obj;

	if(flush) {
		npage.ss = 0;
		npage.rmdiv();
		npage.items = 0;
		return this.pageShiftItemDescription(pageNo + 1, flush);
	}

	while(obj = page.oarr.pop()) {
		var html = page.harr.pop();
		if(npage.ss) {
			flush = true;
		} else {
			npage.harr.unshift(html);
			npage.oarr.unshift(obj);
		}
		if(obj.status != 'D') {
			page.items--;
			if(!flush) npage.items++;
			break;
		}
	}
	this.pageShiftItemDescription(pageNo + 1, flush);
}

// Search for a proper place for a reply
JSCC.prototype.replyPlacement = function(msgId, finalPlace, plcb) {
	if(!msgId) { plcb.apply(this, [true, null]); }
	var pobj = this.objById[msgId];
	if(!pobj) return null;

	var shiftF = function(imm, cmt, arridx, cb) {
		if(this.pages[this.curPage - 1].items >= this.config.paginate) {
			if(this.curPage == this.pages.length)
				this.pages.push(this.pages.empty());
			// Find first non-deleted comment on this page
			for(var ndc = cmt.nextSibling; ndc && ndc.cobj.status == 'D'; ndc = ndc.nextSibling);
			if(ndc) {
				// Move the last comment off the page.
				this.pageShiftLastItem();
			} else {
				this.displayPage(this.curPage + 1, function(immed) {
					var pdiv = this.pages[this.curPage - 1].div;
					var r = [pdiv, pdiv.firstChild, 0];
					cb.apply(this, [immed, r]);
				});
				return;
			}
		}
		/* Reply's place is right beside the entry */
		var r = [cmt.parentNode, cmt.nextSibling, arridx];
		cb.apply(this, [imm, r]);
	}

	// Find the last reply to this comment
	var lreplyObj = null;
	while(pobj.thread.length) {
		lreplyObj = pobj.thread[pobj.thread.length-1][0];
		if(lreplyObj && lreplyObj.status == 'D') {
			pobj.thread.pop();
			lreplyObj = null;
		} else break;
	}
	if(!lreplyObj) lreplyObj = pobj;

	// Find the reply object's page
	var idx;
	for(var pdx = this.curPage - 1; pdx < this.pages.length; pdx++) {
		var page = this.pages[pdx];
		var oarr = page.oarr;
		var oal = oarr.length;
		for(idx = 0; idx < oal; idx++)
			if(oarr[idx].ID == lreplyObj.ID) break;
		if(idx < oarr.length) break;
	}
	if(pdx == this.pages.length) {
		var pcmt = this.cmtById[msgId] || this.get(msgId);
		return plcb.apply(this, [true, [pcmt.parentNode, pcmt.nextSibling, 0]]);
	}

	// Show the page corresponding to that page index
	this.displayPage(pdx+1, function(immed) {
		// Insert right before the last recorded reply
		var prevReply = this.cmtById[lreplyObj.ID] || this.get(lreplyObj.ID);
		if(finalPlace)
			shiftF.apply(this, [immed, prevReply, idx + 1, plcb]);
		else
			plcb.apply(this, [immed, [prevReply.parentNode, prevReply.nextSibling]]);
	});
}

JSCC.prototype.ShowCommentDialog = function(msgId, nofocus) {
	this.forMsg = this.objById[msgId||''];

	var isReply = msgId ? true : false;
	var cct = this.TC["js-LeaveComment"];
	var ccd = this.TC["js-CreateComment"];

	/* Remove dialog from sight */
	this.CommentCancelled();

	this.replyPlacement(msgId, false, function(immediate, apl) {
		if(apl) apl[0].insertBefore(ccd, apl[1]);

		if(this.backwards && msgId)
			cct.style.visibility = "hidden";
		else
			cct.style.display = "none";
		ccd.style.display = "block";
		try {
			var sub = this.TC["js-Cmtsubmit"];
			var can = this.TC["js-Cmtcancel"];
			var text = this.TC["js-CmtText"];
			var prev = function(e){JSKitLib.stopEventPropagation(e); JSKitLib.preventDefaultEvent(e); return false;}

			if(navigator.appName=='Opera') {
				var onkey = function(){};
			} else if(JSKitLib.isIE()) {
				var onkey = function(d,f){d.onkeydown=f};
			} else {
				var onkey = function(d,f){d.onkeypress=f};
			}

			/* combined ratings */
			var commentRatingElements = JSKitLib.getElementsByClass(ccd, "js-commentRatingDisplay");
			var commentRatingDisplay = 'none';
			this.submitRating = false;
			if (this.hasRatingsAppObject() && ( ! isReply)) {
				if (this.TC["js-commentFieldRating"]) {
					this.embedRatingsAppObject(this.TC["js-commentFieldRating"]);
					commentRatingDisplay = '';
					this.submitRating = true;
				}
			}
			for (var i=0; i < commentRatingElements.length; i++) {
				commentRatingElements[i].style.display = commentRatingDisplay;
			}

			/* TinyMCE support (A) */
			if(!text.id) text.id = "js-CmtText-" + this.jcaIndex;
			if(!text.richEditor && this.serverOptions.wysiwyg) try {
				var s = this; 
				var ctx;
				var addMCECtrl = function(){
					if(s.tmce.foreign) tinyMCE.settings = s.tmce.cfg;
					tinyMCE.execCommand('mceAddControl', false, text.id);
					text.richEditor = true;
					if(text.mceLoadedCtx) {
						JSKW$Events.invalidateContext(text.mceLoadedCtx);
						text.mceLoadedCtx = null;
					}
				}
				if(window.tinyMCE) {
					if(tinyMCE.getInstanceById(text.id) == null) addMCECtrl();
				} else { 
					ctx = JSKW$Events.registerEventCallback(undefined, addMCECtrl, "mceLoaded");
					text.mceLoadedCtx = ctx;
				}
			} catch(e) {}

			var flds = this.foldInputFields(ccd, [],
			function(e, a, name) {
				var dfl = this.fieldDfl[name];
				if(dfl) {
					if(e.jsk$setdfl)
						e.jsk$setdfl(dfl);
					else if(!e.value)
						e.value = dfl;
				}
				var aclen = a.length;
				if(e.richEditor) {
					if (e.value) {
						e.value = e.value.replace(/^\n\n+/, '');
						e.value = e.value.replace(/\n\n+/g, '</p><p>');
						e.value = '<p>' + e.value + '</p>';
					}
					var o = { focus: function() {
		var setupFocusing = function(ed) {
			var focus = function(){tinyMCE.execCommand('mceFocus',false,text.id);};
			var delayFocus = function(){setTimeout(focus, 10)};
			if(!nofocus) {
				if(ed.initialized) focus();
				else ed.onInit.add(delayFocus);
			};
			var keyHandler = function(ed, e) { 
				if(e.keyCode != 9) return true;
				window.focus();
				a[aclen+(e.shiftKey?-1:1)].focus();
				return prev(e);
			};
			if (JSKitLib.isIE()) ed.onKeyDown.add(keyHandler); else ed.onKeyPress.add(keyHandler);
		}
		var ed = tinyMCE.getInstanceById(text.id);
		if(ed) {
			setupFocusing(ed);
		} else {
			var t = setInterval(function() {
				var ed = tinyMCE.getInstanceById(text.id);
				if(ed) { clearInterval(t); setupFocusing(ed); }
			}, 100);
		}
	} };
					if(aclen) onkey(a[aclen-1], function(e) { 
						e = e || window.event; 
						if(e.keyCode == 9 && !e.shiftKey) { 
							this.blur();
							o.focus(); 
							return prev(e); 
						}
					});
					a.push(o);
				} else {
					a.push(e);
				}
			});

			flds.push(sub);
			flds.push(can);

			var okd = function(offset) { return function(e) {
				e = e || window.event;
				if(e.keyCode != 9) return true;
				this.blur();
				flds[offset+(e.shiftKey?(flds.length-2):0)].focus();
				return prev(e);
			} }

			onkey(flds[flds.length-1], okd(0));
			onkey(flds[0], okd(1));

			// Place initial focus.
			if(!nofocus)
				for(var i = 0; i < flds.length; i++)
					if(!flds[i].value || flds[i].type == 'submit') {
						flds[i].focus();
						break;
					}

		} catch(e) { }
	});
	return false;
}

JSCC.prototype.CommentCancelled = function() {
	var cct = this.TC["js-LeaveComment"];
	var ccd = this.TC["js-CreateComment"];
	var car = this.TC["js-CommentsArea"];
	cct.style.visibility = "";
	cct.style.display = "";
	ccd.style.display = "";
	var text = this.TC["js-CmtText"];
	if(text.richEditor) {
		tinyMCE.execCommand('mceRemoveControl', false, text.id);
		text.richEditor = false;
		if(text.mceLoadedCtx) {
			JSKW$Events.invalidateContext(text.mceLoadedCtx);
			text.mceLoadedCtx = null;
		}
	}
	if(car && ccd.parentNode != car) {
		ccd.parentNode.removeChild(ccd);
		this.addChild(car, ccd, this.backwards);
	}
	return false;
}

JSCC.prototype.CommentSubmitted = function() {

	/* TinyMCE support (B) */
	var text = this.TC["js-CmtText"];
	if(text.richEditor) {
		tinyMCE.triggerSave(false, false);
		text.value = String(text.value).
				replace(/<p>/g, '\n').replace(/<\/p>/g, '').replace(/<br\/>/g, '\n').replace(/<br>/g, '\n');
	}
	var textValue = text.value;
	var textMsg = encodeURIComponent(textValue);

	if(!textMsg || !textMsg.length) {
		alert($JCL("tooShort"));
		return;
	}
	if(text.value.length > 3000) {
		alert($JCL("tooLong"));
		return;
	}

	var form = this.TC["js-CreateComment"];

	var prn = this.forMsg;
	var noavt = this.noAvatar;
	var avt = this.chosenAvatar ? this.chosenAvatar[0] : null;
	var permalink = this.config.permalink;
	var moderate = this.config.moderate;

	var tmpObj = {yours:true};
	if(prn) {
		tmpObj.ParentID = prn.ID;
		tmpObj.path = prn.path;
		if(prn.permalink) {
			tmpObj.permalink = prn.permalink;
			permalink = prn.permalink;
		}
	}

	var message = this.inputFieldsMsg(form, tmpObj, textValue);

	/* combined ratings */
	if (this.submitRating) {
		rating = this.getRatingsAppObject().userRating;
		message.push({'Name': 'js-CmtRating', 'Value': rating});
		tmpObj.Rating = rating;
	}
	if(prn) {
		message.push({'Name': 'js-CmtParentID', 'Value': prn.ID});
		if(this.IM=='own' && prn.profile) {
			message.push({'Name': 'destProfile', 'Value': prn.profile});
		}
	}
	if(permalink) message.push({'Name': 'permalink', 'Value': permalink});
	if(noavt) message.push({'Name': 'avatar', 'Value': 'no'});
	if(avt) message.push({'Name': 'avatar', 'Value': avt.name});

	if(moderate) this.pathOverride = this.forMsg.path;

	if (!this.openID && this.TC["js-CmtOpenID"] && this.TC["js-CmtOpenID"].value != "") {
		var loc = this.getlocation();
		message.push({'Name': 'location', 'Value': loc.href});
		message.push({'Name': 'action', 'Value': 'lapc'});
		message.push({'Name': 'jx', 'Value': this.jcaIndex});
		this.serverPOST(this.uriDomain + '/settings/auth.cgi', message, 0);
	} else {
		this.CommentCancelled();
		this.routeMsg("attachComment",
			[tmpObj, message, textMsg.length > 1700]);
	}
}

JSCC.prototype.attachComment = function(tmpObj, tmpMsg, longMsg) {
	var cmtObj = this.cloneObj(tmpObj);
	var msg = JSKitLib.fmap(tmpMsg, function(e){return e});

	if(cmtObj.ParentID && !this.objById[cmtObj.ParentID]) {
		JSKitLib.fmap(this.pages, function(p){p.ss=true});
		return;
	}

	var rtShared = this.rtShared;
	var submitMsg = function() {
		if(rtShared.sent) return;
		rtShared.sent = true;
		/* Kick in message submission */
		msg.push({'Name': 'tid', 'Value': cmtObj.ID});
		if (longMsg) {
			this.serverPOST('.put', msg, 1);
		} else {
			var puturl = "";
			for(var i = 0; i < msg.length; i++) {
				puturl += "&" + msg[i].Name + "=" + encodeURIComponent(msg[i].Value);
			}
			this.server('.put', puturl);
		}
	}

	this.cmtInPlace(cmtObj, function() {
		this.reZIndex(cmtObj);
		this.controls.reveal();
		this.serverOptions.pages.tc++;
		this.reCalcPages();
		submitMsg.call(this);
	});
}

JSCC.prototype.cloneObj = function(f) {
	var t = {};
	for(var p in f) t[p] = f[p];
	return t;
}

JSCC.prototype.reZIndex = function(cmtObj) {
	var m=[];
	for(var cmtId in this.cmtById) {
		if((cmtObj.ID!=cmtId) && (this.cmtById[cmtId].bg) && (this.cmtById[cmtId].parentNode)){
			m.push({id: cmtId, zi: this.cmtById[cmtId].bg.style.zIndex});
		}
	}
	var curZ = 300;
	var d = -1;
	m.sort(function(x,y){ return d*(x.zi-y.zi); });
	var self = this;
	this.curstripe = 0;
	var setStripe = function(cmt) {
		if(!(cmt.ctls['js-singleComment'].style.display.match(/none/)) 
			&& cmt.parentNode 
			&& (!cmt.parentNode.style 
			|| (cmt.parentNode.style && !(cmt.parentNode.style.display.match(/none/))))) {
			var r = cmt.ctls['js-singleComment'].className.match(/(.*)js-comment-stripe-(\d+)(.*)/);
			if(r) {
				cmt.ctls['js-singleComment'].className = r[1]+"js-comment-stripe-"+((self.curstripe++ % self.stripecount) + 1)+r[3];
			} else {
				cmt.ctls['js-singleComment'].className += " js-comment-stripe-"+((self.curstripe++ % self.stripecount) + 1);
			}
		}
	}
	var flg = 0;
	if((!cmtObj.ParentID) && (this.preq.ord == 'desc')) {
		this.cmtById[cmtObj.ID].bg.style.zIndex = curZ;
		curZ += d;
		setStripe(this.cmtById[cmtObj.ID]);
	}
	for(var i=0; i<m.length; i++){
		if(cmtObj.ParentID && cmtObj.ParentID == m[i].id){
			this.cmtById[m[i].id].bg.style.zIndex = curZ;
			curZ += d;
			setStripe(this.cmtById[m[i].id]);
			var pobj = this.objById[m[i].id];
			if(pobj.thread.length>1) {
				flg = pobj.thread[pobj.thread.length-2][0].ID;
			} else {
				this.cmtById[cmtObj.ID].bg.style.zIndex = curZ;
				curZ += d;
				setStripe(this.cmtById[cmtObj.ID]);
			}
		} else if (flg == m[i].id) {
			flg = 0;
			this.cmtById[m[i].id].bg.style.zIndex = curZ;
			curZ += d;
			this.cmtById[cmtObj.ID].bg.style.zIndex = curZ;
			curZ += d;
			setStripe(this.cmtById[m[i].id]);
			setStripe(this.cmtById[cmtObj.ID]);
		} else {
			this.cmtById[m[i].id].bg.style.zIndex = curZ;
			curZ += d;
			setStripe(this.cmtById[m[i].id]);
		}
	}
	if((!cmtObj.ParentID) && (this.preq.ord != 'desc')) {
		this.cmtById[cmtObj.ID].bg.style.zIndex = curZ;
		curZ += d;
		setStripe(this.cmtById[cmtObj.ID]);
	}
	this.czidx = curZ;
}

JSCC.prototype.reStripe = function() {
	var m=[];
	this.curstripe = 0;
	for(var cmtId in this.cmtById) {
		var pn = this.cmtById[cmtId].parentNode;
		if(!(this.cmtById[cmtId].ctls['js-singleComment'].style.display.match(/none/)) 
			&& pn && (!pn.style
			|| (pn.style && !(this.cmtById[cmtId].parentNode.style.display.match(/none/))))){
			m.push({id: cmtId, zi: this.cmtById[cmtId].bg.style.zIndex});
		}
	}
	var d=this.preq.ord == 'desc' ? -1 : 1;
	m.sort(function(x,y){ return d*(x.zi-y.zi); });
	var self = this;
	var setStripe = function(cmt) {
		var r = cmt.ctls['js-singleComment'].className.match(/(.*)js-comment-stripe-(\d+)(.*)/);
		if(r) {
			cmt.ctls['js-singleComment'].className = r[1]+"js-comment-stripe-"+((self.curstripe++ % self.stripecount) + 1)+r[3];
		} else {
			cmt.ctls['js-singleComment'].className += " js-comment-stripe-"+((self.curstripe++ % self.stripecount) + 1);
		}
	}
	for(var i=0; i<m.length; i++){
		setStripe(this.cmtById[m[i].id]);
	}
}

JSCC.prototype.getRatingsAppObject = function() {
	if (this.isStandalone()) {
		return null;
	} else {
		return $JSKitGlobal.getRatingsAppObject(this.uniq);
	}
}

JSCC.prototype.hasRatingsAppObject = function() {
	return this.getRatingsAppObject() ? true : false;
}

JSCC.prototype.embedRatingsAppObject = function(node) {
	// One time
	if ( ! this.embedRatingsAppObjectCompleted) {
		$JSKitGlobal.copyRatingsAppObject(this.uniq, node);
		this.embedRatingsAppObjectCompleted = true;
	}
}

JSCC.prototype.createMiniStarObject = function(rating, scale) {

	var rao = this.getRatingsAppObject();
	var fullStar = rao.miniFullStar['user'];
	var emptyStar = rao.miniEmptyStar['user'];
	var starWidth = rao.miniStarWidth + 'px';
	var starHeight = rao.miniStarHeight + 'px';

	var setImage = function(star, imageURL) {
		if(star.imageURL == imageURL)
			return; // Already set and we know it

		star.imageURL = imageURL;

		if(document.body.filters) {
			star.runtimeStyle.filter
				= "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"
				+ imageURL + "', sizingMethod='crop')"
		} else {
			star.style.backgroundImage = 'url(' + imageURL + ')';
		}
	}

	var obj = document.createElement('div');

	/* Increment by Full Star Ratings */
	for (var i=2; i <= scale; i += 2) {

		var star = this.cr('div');

		star.style.cssFloat   = 'left';
		star.style.styleFloat = 'left';
		star.style.width    = starWidth;
		star.style.height   = starHeight;

		if (rating >= i) {
			setImage(star, fullStar);
		} else {
			setImage(star, emptyStar);
		}

		obj.appendChild(star);
	}

	return obj;
}

JSCC.prototype.rerenderName = function(cmt) {
	var self = this;
	var ctls = cmt.ctls;
	var jsc = function(t){return ctls['js-singleComment'+t]};
	var sa = jsc("Name");
	if(sa && cmt.cobj.profile && self.serverOptions.showProfile && !(cmt.cobj.msgtype && cmt.cobj.msgtype.match(/T|P/))) {
		sa.style.textDecoration = 'underline';
		sa.style.cursor = 'pointer';
		sa.onclick = function() {
			self.showProfile(sa, cmt.cobj, self.serverOptions.profileLevel);
			return false;
		}
	}
}

JSCC.prototype.gotPermanentId = function(tmpid, msgId) {
	var self = this;
	var cobj = this.objById[tmpid];
	var cmt = this.cmtById[tmpid];
	delete self.objById[tmpid];
	delete self.cmtById[tmpid];
	delete cobj.isEmbryonic;
	cobj.ID = msgId;
	cmt.id = msgId;
	self.cmtById[msgId] = cmt;
	self.objById[msgId] = cobj;
	var need_obj_rerender = false;
	var aux = arguments.length > 2 ? arguments[2] : {};
	var props = {'Text': cobj, 'status': cobj,
		'mtext': self.serverOptions,
		'mmode': self.serverOptions};
	for(var pname in props) {
		if(aux.hasOwnProperty(pname)) {
			props[pname][pname] = aux[pname];
			need_obj_rerender = true;
		}
	}
	if (need_obj_rerender) {
		self.objRerender(cobj, cmt);
	}
	if(self.serverOptions.showProfile && !self.serverOptions.profile && aux.profile) {
		self.serverOptions.profile = aux.profile;
		cobj.profile = aux.profile;
		self.rerenderName(cmt);
	}
	var cnvsObj = {};
	cnvsObj.Name = cobj.Name;
	if(aux.avatar) {
		cobj.avatar = aux.avatar;
		cobj.avatarWidth = aux.avatarWidth;
		cobj.avatarHeight = aux.avatarHeight;
		cnvsObj.avatar = aux.avatar;
		cnvsObj.avatarWidth = aux.avatarWidth;
		cnvsObj.avatarHeight = aux.avatarHeight;
		self.placeAvatar(cobj);
	}
	if(aux.destName){
		cobj.destName = aux.destName;
		cnvsObj.destName = aux.destName;
	}
	if(aux.destavatar) {
		cobj.destavatar = aux.destavatar;
		cobj.destavatarWidth = aux.destavatarWidth;
		cobj.destavatarHeight = aux.destavatarHeight;
		cnvsObj.destavatar = aux.destavatar;
		cnvsObj.destavatarWidth = aux.destavatarWidth;
		cnvsObj.destavatarHeight = aux.destavatarHeight;
	}
	if(this.IM && cobj.waitConversation) {
		cnvsObj.direction = "out";
		this.conversations[cobj.waitConversation.cnvsIdx] = cnvsObj;
		cobj.conversation = cobj.waitConversation.cnvsIdx;
		cobj.waitConversation = false;
		cobj.hasCnvs = false;
		this.reConversation();
	}
	if(cmt.domCtls) cmt.domCtls.style.visibility = "";
}

function JSReplyMSGId(tmpid, msgId) {
	try {
		var cmt = document.getElementById(tmpid);
		var cobj = cmt.cobj;
		if(cobj.goesInto) {
			var args = arguments;
			JSKitLib.fmap(cobj.goesInto,
				function(s){s.gotPermanentId.apply(s,args)});
		} else {
			var self = $JCA[cobj.jcaIndex];
			self.gotPermanentId(tmpid, msgId);
		}
	} catch(e){}
}

function JSCCKarma(cObj, self) {
	var kObj = { p: cObj.karmaP || 0, n: cObj.karmaN || 0 };
	this.score = kObj.p - kObj.n;
	this.votes = kObj.p + kObj.n;
	this.cObj = cObj;
	this.self = self;
	this.vote2text();
	return this;
}
JSCCKarma.prototype.vote2text = function() {
	this.votesText = this.votes + ' '
			+ ((this.votes == 1) ? $JCL("vote") : $JCL("votes"));
}

JSCCKarma.prototype.recomputeScore = function(scoreAdjustment) {
	var now = new Date();
	if(this.votedAlready) {
		this.score -= this.myVote;
	} else {
		this.votes += 1;
		this.votedAlready = true;
		var kObj = this;
		setTimeout(function() {
			kObj.self.server('-karma', 'id=' + kObj.cObj.ID
				+ '&action=' + encodeURIComponent((kObj.myVote > 0 ? '+' : '-')));
			}, 2000);
	}
	this.score += scoreAdjustment;
	this.myVote = scoreAdjustment;
	this.vote2text();
}

JSCC.prototype.divPages = function(so, items_ho) {
	var srv = so.pages;
	var cpp = this.preq.ps;
	var hitems = items_ho[0];
	var oitems = items_ho[1];
	var replace = (this.ctag != so.tag);
	this.curPage = 0;

	var f = function() {
		var div = this.div;
		if(div) {
			this.div = null;
			if(div.parentNode) div.parentNode.removeChild(div);
		}
	}

	if(this.pages) {
		if(replace) {
			for(var i = this.pages.length; i; i--) {
				var p = this.pages[i-1];
				p.rmdiv();
			}
			this.pages = [];
		}
	} else {
		this.pages = [];
		replace = true;
	}
	this.pages.empty = function(sv) {
		return {ss:(sv?true:false),harr:[],oarr:[],items:0,div:null,rmdiv:f}};

	if(replace) {
		for(var i = srv.sp; i > 1; i--)
			this.pages.push(this.pages.empty(true));
	}
	var i = srv.sp - 1;
	for(var start = 0; start < hitems.length; start += cpp, i++) {
		var cnt = (start + cpp > hitems.length)
				? hitems.length - start : cpp;
		var page = {
			harr: hitems.slice(start, start + cnt),
			oarr: oitems.slice(start, start + cnt),
			items: cnt, div: null, rmdiv: f };
		if(replace) {
			this.pages.push(page);
		} else {
			var p = this.pages[i];
			p.rmdiv();
			p.harr = page.harr;
			p.oarr = page.oarr;
			p.items = page.items;
			p.ss = false;
		}
	}
	var togo = srv.tp - (srv.sp + srv.pn - 1);
	if(replace) {
		for(var i = togo; i > 0; i--)
			this.pages.push(this.pages.empty(true));
	}
	if(this.pages.length == 0)
		this.pages.push(this.pages.empty());
}

JSCC.prototype.htmlPaginate = function(thread) {
	this.icount = 0;	/* Page item count */
	return this.htmlPaginator(thread, [], []);
}

JSCC.prototype.htmlPaginator = function(thread, harr, oarr) {
	var tl = thread.length;
	for(var i = 0; i < tl; i++) {
		var thr = thread[i];
		var obj = thr[0];
		var html = thr[1];
		var present = (obj.status == 'D') ? 0 : 1;
		if(present) {
			oarr.push(obj);
			harr.push(html);
		}
		this.htmlPaginator(obj.thread, harr, oarr);
	}
	return [harr,oarr];
}

// Part of externally useable API
JSCC.prototype.rerender = function() {
	var pageToDisplay = this.curPage;
	this.curPage = 0;
	this.pages[pageToDisplay - 1].ss = true;
	this.displayPage(pageToDisplay);
}

JSCC.prototype.setPath = function(path) {
	this.pathOverride = path;    
}

JSCC.prototype.displayPage = function(pageNo, cb) {

	if(this.loading && !cb) {
		var nt = (new Date()).valueOf();
		if((nt - this.loading) > 5000) {
			this.gen++;
		} else  {
			return;
		}
	}

	if(pageNo < 1)
		return;

	if(pageNo > this.pages.length)
		pageNo = this.pages.length;

	var immediate = true;

	if(this.curPage != pageNo) {
		try { if(this.curPage) {this.pages[this.curPage - 1].div.style.display = 'none';
			this.rePaginate(true);}
		} catch(e) { }
		this.curPage = pageNo;
		var page = this.pages[this.curPage - 1];
		if(page.ss) page.rmdiv();
		if(page.div) {
			page.div.style.display = '';
		} else {
			var oc = this.TC["js-OldComments"];
			page.div = this.cr('div');
			if(page.ss) {
				this.text(page.div, $JCL("Loading..."));
				immediate = false;
				this.dataLoader = function() {
					this.curPage = 0;
					this.displayPage(pageNo);
					if(cb) cb.apply(this, [immediate]);
				}
				if(this.preq.pn < 10)
					this.preq.pn += 5;
				this.getpages(pageNo - Math.ceil(this.preq.pn / 2));
			} else {
				page.div.innerHTML = page.harr.join('');
				this.mapComments(page.div);
			}
			oc.appendChild(page.div);
		}
	} else {
		var page = this.pages[this.curPage - 1];
	}

	this.rePageNavigator(page);
	if(immediate && cb) cb.apply(this, [immediate]);
}

JSCC.prototype.cutSearchLine = function(text) {
	return (text.length > 15) ? text.slice(0,15) + "..." : text;
}

JSCC.prototype.SearchLine = function() {
	var self = this;	
	var sExit = self.cr('span');
	var title = self.cr('span');
	title.className = 'js-SearchTitle';
	title.innerHTML = '<b>'+$JCL("You searched for")+':</b>';
	sExit.appendChild(title);
	var line = self.cr('span');
	line.className = 'js-SearchWords';
	text = self.cutSearchLine(self.searchString);
	line.insertBefore(document.createTextNode(text),line.firstChild);
	sExit.appendChild(line);
	var del = self.cr('input');
	del.type = 'button';
	del.value = 'Clear Search';
	sExit.appendChild(del);
	var obj={
		 'containerElement':	 	sExit,
		 'field': 			line,
		 'itemObject': 			self,
		 'type':			'Search',
		 'Property': 			'searchString',
		 'title':			$JCL("You searched for")+': ',
		 'mode': 			'full'
		};
	obj.jsipe$start = function(){
		del.style.display = "none";
		line.style.border = "0px";
		title.style.display = "none";
		return true;
	}
	obj.jsk$on_submit_exit = function(value){
		self.searchString = value;	
		self.viewControl({name: "search"});
	}
	line.wasEdited = function(value){
                while(line.hasChildNodes())
                        line.removeChild(line.firstChild);	
		line.appendChild(document.createTextNode(self.cutSearchLine(value)));
		del.style.display = "";
		line.style.borderBottom = "";
		title.style.display = "";
	}
	del.onclick = function(){
		this.name="del-line";
		self.viewControl(this);
	}
	var jsipe = new JSIPE(obj);
	return sExit;
}

JSCC.prototype.navSym = { "prev": "&larr;", "next": "&rarr;" };

JSCC.prototype.rePageNavigator = function(page) {
	var nav = '';
	if(this.pages.length > 1)
		nav = this.pageNavigator(this.pages.length, this.curPage);
	var nvs = ['Top','Bottom'];
	for(var i = 0; i < nvs.length; i++) {
		var bar = this.TC['js-PageNav' + nvs[i]];
		bar.innerHTML = '<div>' + nav + '</div>';
		bar.onselectstart = function() { return false; }
		if(i) bar.style.display = ((!page || (page.items <= 5)) ? 'none' : '');
		if(this.searchString) this.addChild(bar, this.SearchLine(), true);
	}
}

JSCC.prototype.pageNavigator = function(pages, cur) {
	var self = this;
	var arr = [$JCL('Page: ')];
	var f = function(i, txt, cmt, css) {
		return '<a href="#'+cmt+'" onclick="$JCA['+self.jcaIndex+'].displayPage('+i+'); return false;" onmouseover="window.status='+"'"+cmt+"'"+'; return false;" onmouseout="window.status=\'\'; return true;" class="js-PageNOther" style="' + (css?css:'') + '">' + txt + '</a> ';
	}
	arr.push(f(cur - 1, this.navSym.prev, $JCL('Previous page'),
		cur == 1 ? this.setOpacity(null, 0.3) : ''));
	for(var i = 1; i <= pages; i++) {
		if((i == 4 || i == 3) && (cur - i) > 3) {
			i = Math.floor((cur - i) / 2 + i);
			arr.push(f(i, '&hellip;', 'Page-' + i));
			if(pages - cur > 3 || cur == pages)
				i = cur - 2;
			else
				i = cur - 1;
		}
		if((i == cur + 3) && (pages - cur) > 4) {
			i = Math.floor((pages - cur) / 2 + cur);
			arr.push(f(i, '&hellip;', 'Page-' + i));
			i = pages - 1;
		}
		if(i == cur) {
			arr.push('<span class="js-PageNCur">' + i + '</span> ');
		} else {
			arr.push(f(i, i, 'Page-' + i));
		}
	}
	arr.push(f(cur + 1, this.navSym.next, $JCL('Next page'),
		pages == cur ? this.setOpacity(null, 0.3) : ''));
	return arr.join('');
}

JSCC.prototype.hideSettingsWindow = function(wname) {
	if(this[wname]) this.settingsWindow(wname);
}

JSCC.prototype.showProgress = function(wname, on) {
	if(this[wname]) this[wname].showProgress(on);
}

JSCC.prototype.settingsWindow = function(wname, atDiv, html) {
	var s = this;
	if(s[wname]) {
		if(!s.sWHideable) return;
		s[wname].parentNode.removeChild(s[wname]);
		delete s[wname];
		return;
	}
	var nohide = function() {
		s.sWHideable = false;
		if(s.swsHidt) clearTimeout(s.swsHidt);
		s.swsHidt = setTimeout(function(){s.sWHideable=true}, 100);
	}
	var div = this.cr("div");
	div.className = "js-SettingsWindow";
	div.style.background = '#FFFFFF url('+this.uriDomain
				+'/images/bg-header-gray.png) bottom repeat-x';
	div.onclick = nohide;
	div.onselectstart = function() { return false; }

	div.style.zIndex = s.config.nolc ? 14400 : 400;
	if(typeof(html) == 'string') {
		div.innerHTML = html;
	} else {
		if(!html.dropWidth) div.style.width = '20em';
		div.appendChild(html);
	}

	var pgr = this.cr('div');
	pgr.className = "js-Progress";
	var url = this.uriDomain + '/images/progress-wg.png';
	if(document.body.filters) {
                pgr.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + url + ", sizingMethod=crop)";
       	} else pgr.style.backgroundImage = 'url(' + url + ')';
	div.appendChild(pgr);
	div.showProgress = function(on) {
		if(!on) {
			if(div.pIntvl) clearInterval(div.pIntvl);
			div.pIntvl = null;
			pgr.style.visibility  = 'hidden';
			return;
		} else if(div.pIntvl) return;
		var f = function() {
			pgr.vison = !pgr.vison;
			pgr.style.visibility = pgr.vison
				? 'visible' : 'hidden';
		}
		f();
		div.pIntvl = setInterval(f, 500);
	}

	s[wname] = div;
	var swh = this.cr("div");
	swh.className = "js-SettingsWindowHeader";
	swh.innerHTML = (wname == 'ctWnd') ? "View Options" : "Moderation";
	div.insertBefore(swh, div.firstChild);
	div.style.position = "absolute";

	var jsd = new JSDL(div, [swh]);
	document.body.appendChild(div);
	div.style.left = jsd.getElmAbsPos(atDiv, false).x + "px";
	div.style.top =  jsd.getElmAbsPos(atDiv, false).y + atDiv.offsetHeight + "px";

	try {
		if (document.body.clientWidth < jsd.getElmAbsPos(atDiv, false).x + div.offsetWidth)
			div.style.left = document.body.clientWidth - div.offsetWidth -
                        	(parseInt(div.style.marginLeft) || 0) -
                                (parseInt(div.style.marginRight) || 0) + "px";
	} catch(e) {;}
	
	var ifrWr;
	if(JSKitLib.getBrowser() == 'gecko' && !atDiv.notShowIfr) {
                ifrWr = this.cr("div");
                ifrWr.id = "jsk-yIfr";
                var yIfr = this.cr("iframe");
                yIfr.style.position = "absolute";
                yIfr.style.top = 0;
                yIfr.style.left = 0;
                yIfr.style.zIndex = -1;
                yIfr.style.display = "block";
                yIfr.style.height = div.offsetHeight + "px";
                yIfr.style.width = div.offsetWidth + "px";
                yIfr.scrolling = "no";
                yIfr.frameBorder = "0";
                ifrWr.appendChild(yIfr);
                div.appendChild(ifrWr);
	}
	div.jsk$on_start_drag = function(){if(ifrWr) ifrWr.style.display = "none"};
	div.jsk$on_stop_drag = function(){if(ifrWr) ifrWr.style.display = ""};
	nohide();
}

JSCC.prototype.viewControl = function(sel) {
	var s = this;
	var ap = '&usr=yes';
	switch(sel.name) {
	case "jss-srt":
		var newSortBy = sel.options[sel.selectedIndex].value;
		if(newSortBy == s.preq.srt) return true;
		s.preq.srt = newSortBy;
		s.showProgress('ctWnd', true);
		break;
	case "jss-rev":
		var newOrder = sel.selectedIndex?'desc':'asc';
		if(s.preq.ord == newOrder) return true;
		s.preq.ord = newOrder;
		s.showProgress('ctWnd', true);
		break;
	case "jss-prs":
		var newPrs = sel.options[sel.selectedIndex].value;
		if(newPrs == s.preq.thr) return true;
		s.preq.thr = newPrs;
		s.showProgress('ctWnd', true);
		break;
        case "search":
                ap += "&srch=" + encodeURIComponent(s.searchString);
                break;
        case "del-line":
                break;
	default: return false;
	}
	s.dataLoader = function() {
		this.showProgress('ctWnd', false);
		this.curPage = 0;
		this.displayPage(1); }
	s.ctag = null;
	s.czidx = 300;
	s.getpages(0, ap);
	return true;
}

JSCC.prototype.refreshAvatars = function(area) {
	this.avatarArea = area;
	this.server('s-data.js', "avt=true&jx=" + this.jcaIndex
		+ "&rnd=" + Math.random());
}

JSCC.prototype.splitAvatarDim = function(so, dim) {
	var re = /(\d+)x(\d+)/;
	var vl=re.exec(dim) || ['96', '96'];
	so.maxAvatarWidth = parseInt(vl[1]);
	so.maxAvatarHeight = parseInt(vl[2]);
}

JSCC.prototype.calcAvatarDim = function (Width, Height, Avatar) {
	var so = this.serverOptions;
	var MW = so.maxAvatarWidth;
	var MH = so.maxAvatarHeight;
	if((MW>=96)&&(MH>=96)&&(Width<=100)&&(Height<=100)){
		return {'width': Width,'height': Height,'name': Avatar};
	} else if((MW<Width)||(MH<Height)){
		var DW = (MW<Width) ? MW/Width : 1;
		var DH = MH<Height ? MH/Height : 1;
		var D = DW < DH ? DW : DH;
		DW = Math.round(Width*D+0.000001);
		DH = Math.round(Height*D+0.000001);
		Name = Avatar.substr(0,Avatar.length-4)+'-'+DW.toString()+'x'+DH.toString()+Avatar.substr(Avatar.length-4);
		return {'width': DW, 'height': DH,'name': Name};
	} else {
		return {'width': Width,'height': Height,'name': Avatar};
	}
}

JSCC.prototype.placeGravatar = function(obj, div) {

	if (this.config.gravatars != 'yes') { return; }

	if (obj.Haloscan && obj.GravatarID) {

		var img = this.cr('img');
		img.style.width = this.config.gravatar_size + 'px';
		img.style.height = this.config.gravatar_size + 'px';
		img.src = 'http://www.gravatar.com/avatar.php?' 
			+ 'gravatar_id=' + obj.GravatarID
			+ '&default=' + this.config.gravatar_default
			+ '&rating=' + this.config.gravatar_rating
			+ '&size=' + this.config.gravatar_size;

		while(div.hasChildNodes()) div.removeChild(div.firstChild);
		div.style.width = img.style.width;
		div.appendChild(img);

	}
}

JSCC.prototype.placeAvatar = function(obj, div) {
	if(this.config.avatars != 'yes') {
		this.placeGravatar(obj, div);
		return;
	}

	div = div || obj.avatarPlace;
	if(!div) return;
	if(!obj.avatar) {
		obj.avatarPlace = div;
		return;
	}
	var img = this.cr('img');
	img.style.visibility = 'hidden';
	var WH = this.calcAvatarDim(obj.avatarWidth,obj.avatarHeight,obj.avatar);
	img.style.width = WH['width'] + 'px';
	img.style.height = WH['height'] + 'px';
	img.src = this.uriDomain + '/blob/' + WH['name'];
	while(div.hasChildNodes()) div.removeChild(div.firstChild);
	JSKitLib.addPNG(div, this.uriDomain + '/blob/' + WH['name']);
	div.style.width = WH['width'] + 'px';
	div.appendChild(img);

	var self = this;
	if(obj.profile && this.serverOptions.showProfile) {
		div.style.cursor = 'help';
		div.onclick = function(e) {
			JSKitLib.stopEventPropagation(e);
			JSKitLib.preventDefaultEvent(e);
			self.showProfile(div, obj, self.serverOptions.profileLevel);
			return false;
		}
	}
	return div;
}

JSCC.prototype.replaceAvatars = function(avatars) {
	var s = this;
	var area = s.avatarArea;
	var onmousemove = function(avatar, outer, sel, rem) {
		rem.style.display = '';
		sel.style.display = 'none';
	};
	var onmouseout = function(avatar, outer, sel, rem) {
		rem.style.display = 'none';
		if(s.chosenAvatar && s.chosenAvatar[1] == outer)
			sel.style.display = '';
	};
	var onmousedown = function(avatar, outer, sel, rem) {
		if(confirm($JCL('removeAvatarConfirm'))) {
			outer.parentNode.removeChild(outer);
			s.runscr(s.uriAvatar + "remove?avrm=" + encodeURIComponent(avatar.name));
		}
	};
	var outeronmousedown = function(avatar, outer, sel, rem) {
		if(s.chosenAvatar) {
                        JSKitLib.removeClass(s.chosenAvatar[1], 'js-showBorder');
                        JSKitLib.addClass(s.chosenAvatar[1], 'js-hideBorder');
			s.chosenAvatar[2].style.display = 'none';
			s.chosenAvatar[3].style.display = 'none';
		}
		if(s.chosenAvatar && s.chosenAvatar[1] == outer) {
			s.noAvatar = true;
			s.chosenAvatar = null;
		} else {
			JSKitLib.removeClass(outer, 'js-hideBorder');
                        JSKitLib.addClass(outer, 'js-showBorder');
			s.chosenAvatar = [avatar, outer, sel, rem];
			s.noAvatar = false;
			sel.style.display = '';
			rem.style.display = 'none';
		}
		return 0;
	};
	var settext = function(sel, label){ return s.text(sel, $JCL(label)); };
	if(s.oldAvatars && s.oldAvatars.length
	&& (s.oldAvatars.length + 1) == avatars.length) {
		var a1 = s.oldAvatars.pop();
		var a2 = avatars[avatars.length-2];
		if(a1.name === a2.name) {
			var a = JSKitLib.mkAvatar(s, avatars[avatars.length-1], s.uriAvatar, onmousemove, onmouseout, onmousedown, outeronmousedown, settext);
			area.insertBefore(a, area.firstChild);
			s.oldAvatars = avatars;
			return;
		}
	}
	s.oldAvatars = avatars;
	while(area.hasChildNodes()) area.removeChild(area.firstChild);
	for(var i = avatars.length - 1; i >= 0; i--)
		area.appendChild(JSKitLib.mkAvatar(s, avatars[i],s.uriAvatar, onmousemove, onmouseout, onmousedown, outeronmousedown, settext));
}

JSCC.prototype.dataLoader = function(so, nc) {
	var s = this;
	var tc = s.TC;
	var d=function(){return s.div.apply(s,arguments);}

	var cc = JSKitLib.html(s.gtmpl(s.utmpl['js-CreateComment'] || (s.config.nolc ? s.dtProfileCreate : s.dtCreate)));
	JSKitLib.mapClass2Object(tc, cc);
	if(s.config.profileLC) {
		var cin = tc['js-commentInputName'];
		if(cin) cin.style.display = 'none';
		var cie = tc['js-commentInputEmail'];
		if(cie) cie.style.display = 'none';
	}
	var ac = function(name, cb) {
		var o = tc['js-'+name];
		if(!o) return;
		if(o.tagName == 'A') o.href="javascript:void(0);";
		o.style.cursor = 'pointer';
		o.onselectstart = function() { return false; }
		o.onclick = cb;
	}

	ac('Cmtsubmit', function() { s.CommentSubmitted(); return false; });
	ac('Cmtcancel', function() { if(s.onCancel) s.onCancel(); return s.CommentCancelled(); });
	var o = tc['js-CmtEmail'];
	if(o) {
		o.style.color = '#808080';
		o.value = $JCL('email is ' + (s.adminMode ? 'mandatory for you (admin)' : 'optional'));
		o.jsk$setdfl = function(val) {
			o.style.color = '';
			o.jsk$setdfl = false;
			o.value = val || '';
		}
		o.onfocus = function() { if(o.jsk$setdfl) o.jsk$setdfl(); }
	}

	if (s.openID) {
		var oidurl = tc['js-commentOpenIDURL'];
		if (oidurl) {
			var openid = String(s.openID);
			var m = openid.match(/^http:\/\/([a-z0-9\.\-]+?).js-kit.com\/$/);
			if(m) {
				oidurl.innerHTML = $JCL("jskitAccount") + "<b>" + m[1] + "</b>";
				oidurl.style.fontWeight = 'normal';
				oidurl.style.background = 'none';
				oidurl.style.paddingLeft = '0px';
			} else {
				oidurl.innerHTML = s.openID;
			}
		}
		var oiddiv = tc['js-commentOpenID'];
		if (oiddiv) { oiddiv.style.display = 'block'; }
	}

	ac('commentOpenIDLogout', function() {
		s.server(s.uriDomain + '/settings/logout.cgi', '');
		for (var i = 0; i < $JCA.length; i++) {
			var w = $JCA[i];
			var oiddiv = w.TC['js-commentOpenID'];
			if (oiddiv) { oiddiv.style.display = 'none'; }
			w.openID = 0;
			var morediv = w.TC['js-commentMore'];
			oiddiv = w.TC['js-commentInputOpenID'];
			if (morediv && oiddiv) { oiddiv.style.display = morediv.ashown ? 'block' : 'none'; }
		}
	});

	if(!tc['js-commentMore'] && s.config.avatars != 'yes') { 
		var m = tc['js-CCMore']; 
		if(m) m.style.display = 'none'; 
	} 

	var onCommentMore = function(obj, label) {
		obj.ashown = !obj.ashown;
		
		var adiv;
		if(s.config.avatars == 'yes') {
			adiv = tc['js-commentAvatarArea'];
			adiv.style.display = obj.ashown ? '' : 'none';
		}
		if (!s.openID) {
			var oiddiv = tc['js-commentInputOpenID'];
			if (oiddiv) {oiddiv.style.display = obj.ashown ? 'block' : 'none';}
		}
		s.text(obj, obj.ashown ? label.less : label.more);
		if(!obj.ashown) return false;

		if(s.config.avatars == 'yes' && !adiv.ifr) {
			adiv.style.maxWidth = '260px';
			if(JSKitLib.isPreIE7) JSKitLib.addStyle(adiv,
				 'width: expression(this.scrollWidth > 260 ? "260px" : this.scrollWidth+"px")');
			var tgt = 'js-ifrm-'+s.jcaIndex + Math.random();
			adiv.innerHTML = '<iframe name="'+tgt+'" width=0 height=0 style="border: none"></iframe>';
			var ifr = adiv.firstChild;

			var aarea = s.cr('div');
			adiv.appendChild(aarea);
			setTimeout(function(){s.refreshAvatars(aarea)}, 10);

			var frm = s.cr('form');
			JSKitLib.setStyle(frm, "clear: both;");
			JSKitLib.addClass(frm, "js-uploadAvatarForm");
			frm.method = 'post';
			frm.encoding = 'multipart/form-data';
			frm.action = s.uriAvatar + 'add';
			frm.target = tgt;
			var lbl = s.cr('div');
			lbl.style.paddingTop = "5px";
			var lblChange = function(mode) {
				while(lbl.hasChildNodes())
					lbl.removeChild(lbl.firstChild);
				lbl.appendChild(document.createTextNode(
					mode ? $JCL("Loading...")
					     : $JCL('uploadAvatar')));
			}
			lblChange(0);
			frm.appendChild(lbl);
			var upf = s.cr('input');
			upf.type = 'file';
			upf.name = 'image';
			upf.onchange = function() {
					lblChange(1); frm.submit()
					var sub = s.TC["js-Cmtsubmit"];
					sub.disabled = 'true';
					upf.disabled = 'true';
				};
			frm.appendChild(upf);
			adiv.appendChild(frm);
			s.onCancel = function() {
				var sub = s.TC["js-Cmtsubmit"];
				sub.disabled = '';
				upf.disabled = '';
				lblChange(0); frm.reset();
			}
			var f = function() { s.onCancel();
					s.refreshAvatars(aarea); }
			ifr.onreadystatechange = function() {
				if(ifr.readyState == 'complete') f();
			}
			ifr.onload = f;
			adiv.ifr = ifr;
		}
		return false;
	};

	ac('commentAddAvatar', function() {
		var label = {'less': '-', 'more': '+'};
		return onCommentMore(this, label);
	});
	ac('commentMore', function() {
		var label = {'less': this.getAttribute("less") || $JCL('less'),
			'more': this.getAttribute("more") || $JCL('more') };
		return onCommentMore(this, label);
	});

	var labelHTML = s.labelHTML || $JCL('leaveComment');

	if(so.mmode == "pause") {
		var lca = null;
	} else {
		var lca = d('js-commentControl', s.a($JCL(labelHTML)));
		lca.onclick = function() { return s.ShowCommentDialog(); };
	}

	var jmg = d('js-commentControl js-commentTool', JSKitLib.html('<font face="Webdings">&#64;&nbsp;</font>'), s.a($JCL("Controls")));
	jmg.onclick = function() {
		var srt = ["date", "name"];
		if(!s.config.moderate && s.scoringEnabled()) srt.push("karma");
		if(s.adminMode) srt.push("status");
		/* s.submitRating check is not good for all the cases */
		if ( $JSKitGlobal.isRatingsAppAvailable() ) srt.push("rating");
		var srtOpts = [];
		for(var i = 0; i < srt.length; i++) {
			srtOpts.push('<option value="'+srt[i] + '"'
				+ (srt[i]==s.preq.srt?" selected":"")+'>'
				+$JCL(srt[i])+'</option>');
		}
		var bkw = ["ascending", "descending"];
		var bkwOpts = [];
		for(var i = 0; i < bkw.length; i++) {
			bkwOpts.push('<option value="'+bkw[i]+'"'
				+ ((!!i) == (s.preq.ord=='desc')?" selected":"")+'>'
				+$JCL(bkw[i])+'</option>');
		}
		var prs = ["on (threaded)", "off (flat)"];
		var prsMap = {'on (threaded)':'yes','off (flat)':'no'}
		var prsOpts = [];
		for(var i = 0; i < prs.length; i++) {
			prsOpts.push('<option value="'+prsMap[prs[i]]+'"'
				+ (prsMap[prs[i]] == s.preq.thr?" selected":"")+'>'
				+$JCL(prs[i])+'</option>');
		}
		var div = s.cr("div");
		div.innerHTML = 
			"<table border=0 cellpadding=4>"
			+ "<tr><td align=right>" + $JCL("Sort by") + '</td><td align=left><select name="jss-srt" onchange="$JCA['+s.jcaIndex+'].viewControl(this);return true;">'
			+ srtOpts.join("")
			+ "</select></td></tr>"
			+ "<tr><td align=right>" + $JCL("Order") + '</td><td align=left><select name="jss-rev" onchange="$JCA['+s.jcaIndex+'].viewControl(this);return true;">'
			+ bkwOpts.join("")
			+ "</select></td></tr>"
			+ "<tr><td align=right>" + $JCL("Threading") + '</td><td align=left><select name="jss-prs" onchange="$JCA['+s.jcaIndex+'].viewControl(this);return true;">'
			+ prsOpts.join("")
			+ "</select></td></tr>"
			+ "<tr><td align=right>" + $JCL("Search") + '</td><td id="js-SearchCell" align=left></td></tr>'
			+ (s.adminMode && !s.config.moderate?('<tr><td align=center colspan=2><a href="'+s.uriDomain+'/moderate/'+s.config.domain+'" onclick="window.location.href = this.href; return true;">Moderate whole site</a></td></tr>'):'')
			+ "</table>"
		this.notShowIfr = true;
		s.settingsWindow('ctWnd', this, div);
                var obj={'mode': 'form', 'inpSize': '121px', type: 'Search'};
                var form = new JSIPE(obj);
                obj.jsk$on_submit_exit = function(){
                        s.searchString = form.input.value;
                        s.viewControl({name: "search"});
			s.hideSettingsWindow('ctWnd');
                }
		form.input.value = s.searchString || "";
		if (s.searchString) form.cleaner.style.visibility = "visible";
		var sCell = document.getElementById("js-SearchCell");
		if (sCell) s.addChild(sCell, form.main);

		return false;
	}
	s.controls = jmg;
	if(nc || s.config.moderate) {
		s.controls.reveal = function(){};
	} else {
		s.controls.style.display = 'none';
		s.controls.reveal = function(){s.controls.style.display=''}
	}

	if(so.subs || so.noJunk) {
		var pb = "";
	} else {
		var propLink = JSKitLib.html('<a href="http://MediaTrendsx.com" target="blank">Powered by MediaTrendsX, LLC</a>');
		var prop = d('', "(", propLink, ")");
		prop.style.position = 'relative';
		var pb = d("js-commentControl js-poweredBy", prop);
	}

	var ca = d("js-CommentsArea",
		(s.config.nolc && !s.IM)?null:d("js-LeaveComment", s.config.moderate || s.IM=='own' ?null:lca, s.IM ? null : jmg, !s.config.nolc ? pb : null,
			JSKitLib.html('<br clear="all"/>')),
		tc["js-CreateComment"]);
	var pageNavTop = d('js-PageNavTop');
	var pageNavBottom = d('js-PageNavBottom');
	s.addChild(ca, d(null, pageNavTop, d("js-OldCommentsWrap", d("js-OldComments")), pageNavBottom), !s.backwards);
	s.displayPage(so.pages.sp);
	ca.onclick = function() {
		s.hideSettingsWindow('ctWnd');
		s.hideSettingsWindow('ctBlock');
	}
	s.addChild(s.target, ca);
	if(lca && ((s.config.nolc && s.IM=='foreign') || so.expandLeaveCmt) && !s.config.moderate) {
		s.ShowCommentDialog(undefined, true);
	}
}

JSCC.prototype.objRerender = function(obj, cmt) {
	cmt.ctls['js-singleCommentText'].innerHTML =
		this.tmpl("{Text}", obj, true);
}

JSCC.prototype.getLastReply = function(pobj) {
	var lreplyObj = null;
	while(pobj.thread.length) {
		lreplyObj = pobj.thread[pobj.thread.length-1][0];
		if(lreplyObj && lreplyObj.status == 'D') {
			pobj.thread.pop();
			lreplyObj = null;
		} else break;
	}
	if(!lreplyObj) lreplyObj = pobj;
	return this.cmtById[lreplyObj.ID] || this.get(lreplyObj.ID);
}

JSCC.prototype.rePaginate = function() {
	var i,j,k,lr;
	var oarr, harr;
	for(i=this.curPage-1; i<this.pages.length; i++) {
		if(this.pages[i].ss) continue;
		k = 0;
		j = 0;
		while(k<this.pages[i].items) {
			if(k>=this.config.paginate) {
				lr = this.cmtById[this.pages[i].oarr[j].ID] || this.get(this.pages[i].oarr[j].ID);
				if(lr && lr.parentNode) lr.parentNode.removeChild(lr);
				oarr = this.pages[i].oarr.pop();
				harr = this.pages[i].harr.pop();
				this.pages[i].items--;
				if(i+1==this.pages.length) this.pages.push(this.pages.empty());
				this.pages[i+1].oarr.unshift(oarr);
				this.pages[i+1].harr.unshift(harr);
				if(this.pages[i+1].div) this.pages[i+1].div.insertBefore(lr || this.createSingleComment(oarr), this.pages[i+1].div.firstChild);
				this.pages[i+1].items++;				
			} else {
				if(this.pages[i].oarr[j].status != 'D') k++;
				j++;
			}
		}
		j = i+1;
		l = 0;
		while((k<this.config.paginate) && (j!=this.pages.length)) {
			if(this.pages[j].ss) break;
			if(l==this.pages[j].oarr.length) {
				j++;
				continue;
			}
			lr = this.cmtById[this.pages[j].oarr[l].ID] || this.get(this.pages[j].oarr[l].ID);
			if(lr && lr.parentNode) lr.parentNode.removeChild(lr);
			oarr = this.pages[j].oarr.shift();
			harr = this.pages[j].harr.shift();
			this.pages[j].items--;
			this.pages[i].oarr.push(oarr);
			this.pages[i].harr.push(harr);
			if(this.pages[i].div) this.pages[i].div.appendChild(lr || this.createSingleComment(oarr));
			this.pages[i].items++;				
			if(l<this.pages[j].oarr.length && this.pages[j].oarr[l].status!='D'){
				k++;
			}
		}
	}
}

JSCC.prototype.reCalcPages = function() {
	var npc = Math.ceil(this.serverOptions.pages.tc/this.serverOptions.pages.ps);
	while(this.pages.length<npc) {
		this.pages.push(this.pages.empty());
	}
	var ncp = this.curPage;
	while(this.pages.length>npc) {
		if(ncp==this.pages.length) ncp--;
		this.pages[this.pages.length-1].rmdiv();
		this.pages.pop();
	}
	if(ncp!=this.curPage) {
		this.displayPage(ncp);
	}
	this.rePageNavigator(this.pages.length>0 ? this.pages[this.pages.length-1] : undefined);
}

JSCC.prototype.appendConversation = function (cmt, conversation) {
	var cnvsObj = {};
	var cnvs = this.conversations[conversation];
	var self = this;
	if(!cnvs) return;
	JSKitLib.fmap(["Name","avatar","avatarHeight","avatarWidth"],
		function(V){ cnvsObj[V] = cnvs.direction=="in" ? cnvs[V] : cnvs["dest"+V] });
	cnvsObj.Label = "Conversation with ";
	var dtc = JSKitLib.html(this.tmpl(this.dtConversation, cnvsObj));
	var ctls = JSKitLib.mapClass2Object({}, dtc);
	var nm = ctls['js-ConversationName'];
	if(nm && this.serverOptions.showProfile) {
		nm.style.textDecoration = 'underline';
		nm.style.cursor = 'pointer';
		nm.onclick = function() {
			self.showProfile(nm, {profile: cnvs.profile}, self.serverOptions.profileLevel);
			return false;
		}
	}
	cmt.insertBefore(dtc, cmt.firstChild);
	JSKitLib.addClass(cmt, "js-singleCommentConversationHead");
}

JSCC.prototype.removeConversation = function (cmt) {
	JSKitLib.removeClass(cmt, "js-singleCommentConversationHead");
	cmt.removeChild(cmt.firstChild);
}

JSCC.prototype.appendConversationChild = function (cmt) {
	JSKitLib.addClass(cmt, "js-singleCommentConversationChild");
}

JSCC.prototype.removeConversationChild = function (cmt) {
	JSKitLib.removeClass(cmt, "js-singleCommentConversationChild");
}

JSCC.prototype.reConversation = function() {
	var i,j,k,lr;
	var oarr, harr;
	for(i=this.curPage-1; i<this.pages.length; i++) {
		var p = this.pages[i];
		p.conversations = {};
		if(p.ss) continue;
		var cn = p.div.childNodes;
		for(j=0; j<cn.length; j++) {
			var cobj = cn[j].cobj;
			if(!p.conversations[cobj.conversation]) {
				p.conversations[cobj.conversation] = 1;
				if(!cobj.hasCnvs) {
					cobj.hasCnvs = true;
					this.removeConversationChild(cn[j]);
					this.appendConversation(cn[j], cobj.conversation);
				}
			} else {
				if(cobj.hasCnvs) {
					cobj.hasCnvs = false;
					this.removeConversation(cn[j]);
				}
				this.appendConversationChild(cn[j]);
			}
		}
	}
}

/* Must be last to support Opera */
JSCC.prototype.newData = function(arr, so) {
	var s = this;
	s.serverOptions = so;
	s.openID = so.openID;
	s.searchString = so.srch;
	s.adminMode = !!so.adminMode;
	s.inlineModeration = (s.adminMode && !s.config.moderate);
	if(this.config.nolc) so.avatardim = '48x48';
	s.splitAvatarDim(so, so.avatardim);

	if(so.skin === "smoothgray" && !s.hasOwnProperty("dtComment")) {
		s.navSym = { "prev": '&#x25c0;', "next": '&#x25b6;' };
		s.dtComment = JSCC.prototype.dtComment2;
		s.dtCreate = JSCC.prototype.dtCreate2;
		JSKitLib.addCss(""
		+ ".js-OldCommentsWrap { margin-bottom: 1px; clear: both; background-color: #cbcbcb; -moz-border-radius: 7px; -webkit-border-radius: 7px; padding: 5px; }"
		+ ".js-OldComments { background-color: #ececec; border: solid 1px #b0b0b0; padding: 4px; -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }"
		+ ".js-singleComment { border-style: none; margin: 0px; background-color: #ececec; }"
		+ ".js-PageNOther { font-weight: bold; color: #0066cc; } "
		+ ".js-PageNCur { color: #fe9600; } "
		, "skin");
	}

	if(so.req) {
		s.preq.srt = so.req.srt;
		s.preq.ord = so.req.ord;
		s.preq.thr = ((so.req.prs == 'flat') ? 'no' : 'yes');
	}

	s.gen++;
	s.loading = false;

	if(s.ctag != so.tag) {
		s.objById = {};
		s.cmtById = {};
	}

	var flat = (s.searchString) ? true : s.preq.thr != 'yes';

	var ttt = []; // top level thread
	var nc = 0;
	var newChilds = {};
	for(var i = 0; i < arr.length; i++) {
		var obj = arr[i];
		if(!obj.ID || !obj.Text) continue;
		if(this.IM && obj.yours) obj.Name = 'Me';
		if(flat) {
			delete(obj.ParentID);
			delete(obj.depth);
		}
		s.objById[obj.ID] = obj;
		obj.thread = [];
		obj.karma = new JSCCKarma(obj, this);
		if(obj.status != 'D') nc++;
		var cmtHTML = s.createCommentAsHTML(obj);
		var prn = s.objById[obj.ParentID];
		if(prn) {
			if(!newChilds[obj.ParentID]) {
				ttt.push([obj, cmtHTML]);
			}
			prn.thread.push([obj, cmtHTML]);
		} else {
			ttt.push([obj, cmtHTML]);
		}
		newChilds[obj.ID] = 1;
	}
	s.divPages(so, s.htmlPaginate(ttt));

	if(this.IM) this.conversations = so.conversations;

	s.ctag = so.tag;
	s.dataLoader(so, nc);

	s.tmce = { foreign: true, cfg: {
		mode: "none",
		plugins: (so.media?",youtube":""),
		theme: "advanced",
		theme_advanced_buttons1: 
			"bold,italic,underline,|,undo,redo,link,unlink"
			+ (so.media?",youtube":""),
		theme_advanced_buttons2: "",
		theme_advanced_buttons3: "",
		theme_advanced_toolbar_location: "top",
		theme_advanced_toolbar_align: "left",
		extended_valid_elements:
			"a[href],b,i,u,em,strong,sup,sub"
			+ (so.media?",object[classid|codebase|width|height|align],param[name|value],embed[quality|type|pluginspage|width|height|src|align|wmode]":"")
	}};

	var showCD = function() {
		if(so.ShowSavedCommentDialog)
			so.ShowSavedCommentDialog(s);
	}

	if(so.wysiwyg && !window.tinyMCE) {
		so.wysiwyg = false;
		var inittmce = function() {
			s.tmce.foreign = false;
			s.tmce.cfg.plugins = "inlinepopups"+(so.media?",youtube":""); // !inl-pop
			s.tmce.cfg.strict_loading_mode = true;
			tinyMCE.init(s.tmce.cfg);
			so.wysiwyg = true;
			showCD();
		}
		var oldcb = window.jsk$tmcecb;
		if(oldcb) {
			jsk$tmcecb = function() { if(oldcb) oldcb(); so.wysiwyg = true; showCD(); };
		} else {
			jsk$tmcecb = inittmce;
			s.runscr(s.uriDomain + '/extra/tiny_mce/tmce.js');
		}
	} else {
		showCD();
	}

	var f = s.onDataLoad;
	if(f) { s.onDataLoad = null; setTimeout(f, 0); }
}

