                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                // vim: set ts=8 sts=8 sw=8 noet:
/*
 * Copyright (c) 2006-2011 Echo <solutions@aboutecho.com>. All rights reserved.
 * 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: full-pack.js 37463 2012-02-08 08:45:01Z jskit $
 */



window.Backplane = window.Backplane || {
	"channelByBus": {},
	"config": {},
	"initialized": false,
	"subscribers": {},
	"awaiting": {
		"since": 0,
		"until": 0,
		"queue": []
	},
	"intervals": {
		"min": 1,
		"frequent": 5,
		"regular": 60,
		"slowdown": 120
	}
};

/**
 * Initializes the backplane library
 * 
 * @param {Object} config - Hash with configuration parameters.
 *   Possible hash keys:
 *     serverBaseURL (required) - Base URL of Backplane Server
 *     busName (required) - Customer's backplane bus name
 *     channelName (optional) - Custom specified channel name
 */
Backplane.init = function(config) {
	config = config || {};
	if (this.initialized || !config.serverBaseURL || !config.busName) return false;
	this.initialized = true;
	this.timers = {};
	this.config = config;
	this.channelByBus = this.getCookieChannels();
	// save custom channel name, if passed.
	this.config.customChannelName = config.channelName;
	this.config.channelName = this.getChannelName();
	this.config.serverBaseURL = this.normalizeURL(config.serverBaseURL);
	this.config.channelID = this.generateChannelID();
	this.request();
	return true;
};

/**
 * Subscribes to messages from Backplane server
 *
 * @param {Function} Callback - Callback function which accepts backplane messages
 * @returns Subscription ID which can be used later for unsubscribing
 */
Backplane.subscribe = function(callback) {
	if (!this.initialized) return false;
	var id = (new Date()).valueOf() + Math.random();
	this.subscribers[id] = callback;
	return id;
};

/**
 * Removes specified subscription
 *
 * @param {Integer} Subscription ID
 */
Backplane.unsubscribe = function(subscriptionID) {
	if (!this.initialized || !subscriptionID) return false;
	delete this.subscribers[subscriptionID];
};

/**
 * Returns channel ID (like http://backplane.customer.com/v1/bus/customer.com/channel/8ec92f459fa70b0da1a40e8fe70a0bc8)
 *
 * @returns Backplane channel ID
 */
Backplane.getChannelID = function() {
	if (!this.initialized) return false;
	return this.config.channelID;
};

/**
 * Notifies backplane library about the fact that subscribers are going
 * to receive backplane messages of any of the specified types
 * 
 * @param {Array} List of expected backplane message types
 */
Backplane.expectMessages = function(types) {
	this.expectMessagesWithin(60, types);
};
	
/**
 * Notifies backplane library about the fact that subscribers are going
 * to receive backplane messages within specified time interval.
 * 
 * @param {Integer} TimeInterval Time interval in seconds
 */
Backplane.expectMessagesWithin = function(interval, types) {
	if (!this.initialized || !interval) return false;
	this.awaiting.since = this.getTS();
	this.awaiting.interval = interval;
	// we should wait entire interval if no types were specified
	this.awaiting.nonstop = !types;
	if (types) {
		types = typeof types == "string" ? [types] : types;
		this.awaiting.queue.push(types);
	}
	var until = this.awaiting.since + interval;
	if (until > this.awaiting.until) {
		this.awaiting.until = until;
	}
	this.request();
};

/**
 * Internal functions
 */
Backplane.generateChannelID = function() {
	return this.config.serverBaseURL + "/bus/" + this.config.busName + "/channel/" + this.config.channelName;
};

Backplane.getChannelName = function() {
	if (!this.initialized) return false;
	if (this.config.customChannelName) return this.config.customChannelName;
	if (!this.channelByBus[this.config.busName]) {
		this.channelByBus[this.config.busName] = (new Date()).valueOf().toString() + Math.random().toString().substr(2, 5);
		this.setCookieChannels();
	}
	return this.channelByBus[this.config.busName];
};

Backplane.getTS = function() {
	return Math.round((new Date()).valueOf() / 1000);
};

Backplane.getCookieChannels = function() {
	var match = (document.cookie || "").match(/backplane-channel=(.*?)(?:$|;)/);
	if (!match || !match[1]) return {};
	var channelByBus = {};
	var parts = match[1].split("|");
	for (var i = 0; i < parts.length; i++) {
		var m = parts[i].split(":");
		channelByBus[decodeURIComponent(m[0])] = decodeURIComponent(m[1]);
	}
	return channelByBus;
};

Backplane.setCookieChannels = function() {
	var parts = [];
	for (var i in this.channelByBus) {
		if (this.channelByBus.hasOwnProperty(i)) {
			parts.push(encodeURIComponent(i) + ":" + encodeURIComponent(this.channelByBus[i]));
		}
	}
	var d = new Date();
	d.setFullYear(d.getFullYear() + 5);
	document.cookie = "backplane-channel=" + parts.join("|") + ";expires=" + d.toGMTString() + ";path=/";
};

Backplane.resetCookieChannel = function() {
	delete this.channelByBus[this.config.busName];
	this.setCookieChannels();
	this.config.channelName = this.getChannelName();
	this.config.channelID = this.generateChannelID();
};

Backplane.normalizeURL = function(rawURL) {
	return rawURL.replace(/^\s*(https?:\/\/)?(.*?)[\s\/]*$/, function(match, proto, uri){
		return (proto || window.location.protocol + "//") + uri;
	});
};

Backplane.calcTimeout = function() {
	var timeout, ts = this.getTS();
	if (ts < this.awaiting.until) {
		// stop frequent polling as soon as all the necessary messages received
		if (!this.awaiting.nonstop && !this.awaiting.queue.length) {
			this.awaiting.until = ts;
			return this.calcTimeout();
		}
		var relative = ts - this.awaiting.since;
		var limit = this.intervals.frequent - this.intervals.min;
		// we should reach this.intervals.frequent at the end
		timeout = this.intervals.min +
			Math.round(limit * relative / this.awaiting.interval);
	} else if (ts < this.awaiting.until + this.intervals.slowdown) {
		var relative = ts - this.awaiting.until;
		var limit = this.intervals.regular - this.intervals.frequent;
		// we should reach this.intervals.regular at the end
		timeout = this.intervals.frequent +
			Math.round(limit * relative / this.intervals.slowdown);
	} else {
		timeout = typeof this.since == "undefined" ? 0 : this.intervals.regular;
		this.awaiting.nonstop = false;
	}
	return timeout * 1000;
};

Backplane.request = function() {
	var self = this;
	if (!this.initialized) return false;
	this.stopTimer("regular");
	this.stopTimer("watchdog");
	this.timers.regular = setTimeout(function() {
		// if no response in the reasonable time just restart request
		self.timers.watchdog = setTimeout(function() {
			self.request();
		}, 5000);
		var script = document.createElement("script");
		script.type = "text/javascript";
		script.charset = "utf-8";
		script.src = self.config.channelID + "?callback=Backplane.response" +
				(self.since ? "&since=" + encodeURIComponent(self.since) : "") +
				"&rnd=" + Math.random();
		var container = document.getElementsByTagName("head")[0] || document.documentElement;
		container.insertBefore(script, container.firstChild);
		script.onload = script.onreadystatechange = function() {
			var state = script.readyState;
			if (!state || state === "loaded" || state === "complete") {
				script.onload = script.onreadystatechange = null;
				if (script.parentNode) {
					script.parentNode.removeChild(script);
				}
			}
		};
	}, this.calcTimeout());
};

Backplane.response = function(messages) {
	var self = this;
	this.stopTimer("watchdog");
	messages = messages || [];
	var since = messages.length ? messages[messages.length - 1].id : this.since;
	if (typeof this.since == "undefined") {
		// ignore messages frame came on initial request,
		// since we are using it only to receive id of the last message
		messages = [];
	}
	this.since = since || "";
	for (var i = 0; i < messages.length; i++) {
		// notify subscribers
		for (var j in this.subscribers) {
			if (this.subscribers.hasOwnProperty(j)) {
				this.subscribers[j](messages[i].message);
			}
		}
		// clean up awaiting specific events queue
		var queue = [];
		for (var k = 0; k < this.awaiting.queue.length; k++) {
			var satisfied = false;
			for (var l = 0; l < this.awaiting.queue[k].length; l++) {
				if (this.awaiting.queue[k][l] == messages[i].message.type) {
					satisfied = true;
				}
			}
			if (!satisfied) queue.push(this.awaiting.queue[k]);
		}
		this.awaiting.queue = queue;
	}
	this.request();
};

Backplane.stopTimer = function(name) {
	var timer = this.timers[name];
	if (timer) clearTimeout(timer);
};





/*!
 * jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2010, The Dojo Foundation
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Sat Feb 13 22:33:48 2010 -0500
 */
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);





/*!
 * jQuery UI 1.8
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 *//*
 * jQuery UI 1.8
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
jQuery.ui||(function(a){a.ui={version:"1.8",plugin:{add:function(c,d,f){var e=a.ui[c].prototype;for(var b in f){e.plugins[b]=e.plugins[b]||[];e.plugins[b].push([d,f[b]])}},call:function(b,d,c){var f=b.plugins[d];if(!f||!b.element[0].parentNode){return}for(var e=0;e<f.length;e++){if(b.options[f[e][0]]){f[e][1].apply(b.element,c)}}}},contains:function(d,c){return document.compareDocumentPosition?d.compareDocumentPosition(c)&16:d!==c&&d.contains(c)},hasScroll:function(e,c){if(a(e).css("overflow")=="hidden"){return false}var b=(c&&c=="left")?"scrollLeft":"scrollTop",d=false;if(e[b]>0){return true}e[b]=1;d=(e[b]>0);e[b]=0;return d},isOverAxis:function(c,b,d){return(c>b)&&(c<(b+d))},isOver:function(g,c,f,e,b,d){return a.ui.isOverAxis(g,f,b)&&a.ui.isOverAxis(c,e,d)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};a.fn.extend({_focus:a.fn.focus,focus:function(b,c){return typeof b==="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus();(c&&c.call(d))},b)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var b;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){b=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{b=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!b.length?a(document):b},zIndex:function(e){if(e!==undefined){return this.css("zIndex",e)}if(this.length){var c=a(this[0]),b,d;while(c.length&&c[0]!==document){b=c.css("position");if(b=="absolute"||b=="relative"||b=="fixed"){d=parseInt(c.css("zIndex"));if(!isNaN(d)&&d!=0){return d}}c=c.parent()}}return 0}});a.extend(a.expr[":"],{data:function(d,c,b){return !!a.data(d,b[3])},focusable:function(c){var d=c.nodeName.toLowerCase(),b=a.attr(c,"tabindex");return(/input|select|textarea|button|object/.test(d)?!c.disabled:"a"==d||"area"==d?c.href||!isNaN(b):!isNaN(b))&&!a(c)["area"==d?"parents":"closest"](":hidden").length},tabbable:function(c){var b=a.attr(c,"tabindex");return(isNaN(b)||b>=0)&&a(c).is(":focusable")}})})(jQuery);





/*
 * jQuery UI Effects 1.8
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/
 */jQuery.effects||(function(g){g.effects={};g.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(l,k){g.fx.step[k]=function(m){if(!m.colorInit){m.start=j(m.elem,k);m.end=i(m.end);m.colorInit=true}m.elem.style[k]="rgb("+Math.max(Math.min(parseInt((m.pos*(m.end[0]-m.start[0]))+m.start[0],10),255),0)+","+Math.max(Math.min(parseInt((m.pos*(m.end[1]-m.start[1]))+m.start[1],10),255),0)+","+Math.max(Math.min(parseInt((m.pos*(m.end[2]-m.start[2]))+m.start[2],10),255),0)+")"}});function i(l){var k;if(l&&l.constructor==Array&&l.length==3){return l}if(k=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(l)){return[parseInt(k[1],10),parseInt(k[2],10),parseInt(k[3],10)]}if(k=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(l)){return[parseFloat(k[1])*2.55,parseFloat(k[2])*2.55,parseFloat(k[3])*2.55]}if(k=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(l)){return[parseInt(k[1],16),parseInt(k[2],16),parseInt(k[3],16)]}if(k=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(l)){return[parseInt(k[1]+k[1],16),parseInt(k[2]+k[2],16),parseInt(k[3]+k[3],16)]}if(k=/rgba\(0, 0, 0, 0\)/.exec(l)){return a.transparent}return a[g.trim(l).toLowerCase()]}function j(m,k){var l;do{l=g.curCSS(m,k);if(l!=""&&l!="transparent"||g.nodeName(m,"body")){break}k="backgroundColor"}while(m=m.parentNode);return i(l)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};var e=["add","remove","toggle"],c={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};function f(){var n=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,o={},l,m;if(n&&n.length&&n[0]&&n[n[0]]){var k=n.length;while(k--){l=n[k];if(typeof n[l]=="string"){m=l.replace(/\-(\w)/g,function(p,q){return q.toUpperCase()});o[m]=n[l]}}}else{for(l in n){if(typeof n[l]==="string"){o[l]=n[l]}}}return o}function b(l){var k,m;for(k in l){m=l[k];if(m==null||g.isFunction(m)||k in c||(/scrollbar/).test(k)||(!(/color/i).test(k)&&isNaN(parseFloat(m)))){delete l[k]}}return l}function h(k,m){var n={_:0},l;for(l in m){if(k[l]!=m[l]){n[l]=m[l]}}return n}g.effects.animateClass=function(k,l,n,m){if(g.isFunction(n)){m=n;n=null}return this.each(function(){var r=g(this),o=r.attr("style")||" ",s=b(f.call(this)),q,p=r.attr("className");g.each(e,function(t,u){if(k[u]){r[u+"Class"](k[u])}});q=b(f.call(this));r.attr("className",p);r.animate(h(s,q),l,n,function(){g.each(e,function(t,u){if(k[u]){r[u+"Class"](k[u])}});if(typeof r.attr("style")=="object"){r.attr("style").cssText="";r.attr("style").cssText=o}else{r.attr("style",o)}if(m){m.apply(this,arguments)}})})};g.fn.extend({_addClass:g.fn.addClass,addClass:function(l,k,n,m){return k?g.effects.animateClass.apply(this,[{add:l},k,n,m]):this._addClass(l)},_removeClass:g.fn.removeClass,removeClass:function(l,k,n,m){return k?g.effects.animateClass.apply(this,[{remove:l},k,n,m]):this._removeClass(l)},_toggleClass:g.fn.toggleClass,toggleClass:function(m,l,k,o,n){if(typeof l=="boolean"||l===undefined){if(!k){return this._toggleClass(m,l)}else{return g.effects.animateClass.apply(this,[(l?{add:m}:{remove:m}),k,o,n])}}else{return g.effects.animateClass.apply(this,[{toggle:m},l,k,o])}},switchClass:function(k,m,l,o,n){return g.effects.animateClass.apply(this,[{add:m,remove:k},l,o,n])}});g.extend(g.effects,{version:"1.8",save:function(l,m){for(var k=0;k<m.length;k++){if(m[k]!==null){l.data("ec.storage."+m[k],l[0].style[m[k]])}}},restore:function(l,m){for(var k=0;k<m.length;k++){if(m[k]!==null){l.css(m[k],l.data("ec.storage."+m[k]))}}},setMode:function(k,l){if(l=="toggle"){l=k.is(":hidden")?"show":"hide"}return l},getBaseline:function(l,m){var n,k;switch(l[0]){case"top":n=0;break;case"middle":n=0.5;break;case"bottom":n=1;break;default:n=l[0]/m.height}switch(l[1]){case"left":k=0;break;case"center":k=0.5;break;case"right":k=1;break;default:k=l[1]/m.width}return{x:k,y:n}},createWrapper:function(k){if(k.parent().is(".ui-effects-wrapper")){return k.parent()}var l={width:k.outerWidth(true),height:k.outerHeight(true),"float":k.css("float")},m=g("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});k.wrap(m);m=k.parent();if(k.css("position")=="static"){m.css({position:"relative"});k.css({position:"relative"})}else{g.extend(l,{position:k.css("position"),zIndex:k.css("z-index")});g.each(["top","left","bottom","right"],function(n,o){l[o]=k.css(o);if(isNaN(parseInt(l[o],10))){l[o]="auto"}});k.css({position:"relative",top:0,left:0})}return m.css(l).show()},removeWrapper:function(k){if(k.parent().is(".ui-effects-wrapper")){return k.parent().replaceWith(k)}return k},setTransition:function(l,n,k,m){m=m||{};g.each(n,function(p,o){unit=l.cssUnit(o);if(unit[0]>0){m[o]=unit[0]*k+unit[1]}});return m}});function d(l,k,m,n){if(typeof l=="object"){n=k;m=null;k=l;l=k.effect}if(g.isFunction(k)){n=k;m=null;k={}}if(g.isFunction(m)){n=m;m=null}if(typeof k=="number"||g.fx.speeds[k]){n=m;m=k;k={}}k=k||{};m=m||k.duration;m=g.fx.off?0:typeof m=="number"?m:g.fx.speeds[m]||g.fx.speeds._default;n=n||k.complete;return[l,k,m,n]}g.fn.extend({effect:function(n,m,p,q){var l=d.apply(this,arguments),o={options:l[1],duration:l[2],callback:l[3]},k=g.effects[n];return k&&!g.fx.off?k.call(this,o):this},_show:g.fn.show,show:function(l){if(!l||typeof l=="number"||g.fx.speeds[l]){return this._show.apply(this,arguments)}else{var k=d.apply(this,arguments);k[1].mode="show";return this.effect.apply(this,k)}},_hide:g.fn.hide,hide:function(l){if(!l||typeof l=="number"||g.fx.speeds[l]){return this._hide.apply(this,arguments)}else{var k=d.apply(this,arguments);k[1].mode="hide";return this.effect.apply(this,k)}},__toggle:g.fn.toggle,toggle:function(l){if(!l||typeof l=="number"||g.fx.speeds[l]||typeof l=="boolean"||g.isFunction(l)){return this.__toggle.apply(this,arguments)}else{var k=d.apply(this,arguments);k[1].mode="toggle";return this.effect.apply(this,k)}},cssUnit:function(k){var l=this.css(k),m=[];g.each(["em","px","%","pt"],function(n,o){if(l.indexOf(o)>0){m=[parseFloat(l),o]}});return m}});g.easing.jswing=g.easing.swing;g.extend(g.easing,{def:"easeOutQuad",swing:function(l,m,k,o,n){return g.easing[g.easing.def](l,m,k,o,n)},easeInQuad:function(l,m,k,o,n){return o*(m/=n)*m+k},easeOutQuad:function(l,m,k,o,n){return -o*(m/=n)*(m-2)+k},easeInOutQuad:function(l,m,k,o,n){if((m/=n/2)<1){return o/2*m*m+k}return -o/2*((--m)*(m-2)-1)+k},easeInCubic:function(l,m,k,o,n){return o*(m/=n)*m*m+k},easeOutCubic:function(l,m,k,o,n){return o*((m=m/n-1)*m*m+1)+k},easeInOutCubic:function(l,m,k,o,n){if((m/=n/2)<1){return o/2*m*m*m+k}return o/2*((m-=2)*m*m+2)+k},easeInQuart:function(l,m,k,o,n){return o*(m/=n)*m*m*m+k},easeOutQuart:function(l,m,k,o,n){return -o*((m=m/n-1)*m*m*m-1)+k},easeInOutQuart:function(l,m,k,o,n){if((m/=n/2)<1){return o/2*m*m*m*m+k}return -o/2*((m-=2)*m*m*m-2)+k},easeInQuint:function(l,m,k,o,n){return o*(m/=n)*m*m*m*m+k},easeOutQuint:function(l,m,k,o,n){return o*((m=m/n-1)*m*m*m*m+1)+k},easeInOutQuint:function(l,m,k,o,n){if((m/=n/2)<1){return o/2*m*m*m*m*m+k}return o/2*((m-=2)*m*m*m*m+2)+k},easeInSine:function(l,m,k,o,n){return -o*Math.cos(m/n*(Math.PI/2))+o+k},easeOutSine:function(l,m,k,o,n){return o*Math.sin(m/n*(Math.PI/2))+k},easeInOutSine:function(l,m,k,o,n){return -o/2*(Math.cos(Math.PI*m/n)-1)+k},easeInExpo:function(l,m,k,o,n){return(m==0)?k:o*Math.pow(2,10*(m/n-1))+k},easeOutExpo:function(l,m,k,o,n){return(m==n)?k+o:o*(-Math.pow(2,-10*m/n)+1)+k},easeInOutExpo:function(l,m,k,o,n){if(m==0){return k}if(m==n){return k+o}if((m/=n/2)<1){return o/2*Math.pow(2,10*(m-1))+k}return o/2*(-Math.pow(2,-10*--m)+2)+k},easeInCirc:function(l,m,k,o,n){return -o*(Math.sqrt(1-(m/=n)*m)-1)+k},easeOutCirc:function(l,m,k,o,n){return o*Math.sqrt(1-(m=m/n-1)*m)+k},easeInOutCirc:function(l,m,k,o,n){if((m/=n/2)<1){return -o/2*(Math.sqrt(1-m*m)-1)+k}return o/2*(Math.sqrt(1-(m-=2)*m)+1)+k},easeInElastic:function(l,n,k,u,r){var o=1.70158;var q=0;var m=u;if(n==0){return k}if((n/=r)==1){return k+u}if(!q){q=r*0.3}if(m<Math.abs(u)){m=u;var o=q/4}else{var o=q/(2*Math.PI)*Math.asin(u/m)}return -(m*Math.pow(2,10*(n-=1))*Math.sin((n*r-o)*(2*Math.PI)/q))+k},easeOutElastic:function(l,n,k,u,r){var o=1.70158;var q=0;var m=u;if(n==0){return k}if((n/=r)==1){return k+u}if(!q){q=r*0.3}if(m<Math.abs(u)){m=u;var o=q/4}else{var o=q/(2*Math.PI)*Math.asin(u/m)}return m*Math.pow(2,-10*n)*Math.sin((n*r-o)*(2*Math.PI)/q)+u+k},easeInOutElastic:function(l,n,k,u,r){var o=1.70158;var q=0;var m=u;if(n==0){return k}if((n/=r/2)==2){return k+u}if(!q){q=r*(0.3*1.5)}if(m<Math.abs(u)){m=u;var o=q/4}else{var o=q/(2*Math.PI)*Math.asin(u/m)}if(n<1){return -0.5*(m*Math.pow(2,10*(n-=1))*Math.sin((n*r-o)*(2*Math.PI)/q))+k}return m*Math.pow(2,-10*(n-=1))*Math.sin((n*r-o)*(2*Math.PI)/q)*0.5+u+k},easeInBack:function(l,m,k,p,o,n){if(n==undefined){n=1.70158}return p*(m/=o)*m*((n+1)*m-n)+k},easeOutBack:function(l,m,k,p,o,n){if(n==undefined){n=1.70158}return p*((m=m/o-1)*m*((n+1)*m+n)+1)+k},easeInOutBack:function(l,m,k,p,o,n){if(n==undefined){n=1.70158}if((m/=o/2)<1){return p/2*(m*m*(((n*=(1.525))+1)*m-n))+k}return p/2*((m-=2)*m*(((n*=(1.525))+1)*m+n)+2)+k},easeInBounce:function(l,m,k,o,n){return o-g.easing.easeOutBounce(l,n-m,0,o,n)+k},easeOutBounce:function(l,m,k,o,n){if((m/=n)<(1/2.75)){return o*(7.5625*m*m)+k}else{if(m<(2/2.75)){return o*(7.5625*(m-=(1.5/2.75))*m+0.75)+k}else{if(m<(2.5/2.75)){return o*(7.5625*(m-=(2.25/2.75))*m+0.9375)+k}else{return o*(7.5625*(m-=(2.625/2.75))*m+0.984375)+k}}}},easeInOutBounce:function(l,m,k,o,n){if(m<n/2){return g.easing.easeInBounce(l,m*2,0,o,n)*0.5+k}return g.easing.easeOutBounce(l,m*2-n,0,o,n)*0.5+o*0.5+k}})})(jQuery);





/*!
 * jQuery UI Widget 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Widget
 */
(function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend({},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==undefined){h=i;return false}}):this.each(function(){var g=b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(f,h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);





/*!
 * jQuery UI Mouse 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Mouse
 *
 * Depends:
 *      jquery.ui.widget.js
 */
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);





/*
 * jQuery UI Position 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Position
 */
(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h=0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+=g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k,elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"?-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);





/*
 * jQuery UI Draggable 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Draggables
 *
 * Depends:
 *      jquery.ui.core.js
 *      jquery.ui.mouse.js
 *      jquery.ui.widget.js
 */
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.1"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);





/*
 * jQuery UI Resizable 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Resizables
 *
 * Depends:
 *      jquery.ui.core.js
 *      jquery.ui.mouse.js
 *      jquery.ui.widget.js
 */
(function(d){d.widget("ui.resizable",d.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");d.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&d.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(d('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!d(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var e=0;e<c.length;e++){var g=d.trim(c[e]),f=d('<div class="ui-resizable-handle '+("ui-resizable-"+g)+'"></div>');/sw|se|ne|nw/.test(g)&&f.css({zIndex:++a.zIndex});"se"==g&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[g]=".ui-resizable-"+g;this.element.append(f)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==String)this.handles[i]=d(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=d(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}d(this.handles[i])}};this._renderAxis(this.element);this._handles=d(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();d(this.element).addClass("ui-resizable-autohide").hover(function(){d(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){d(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){d(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(d(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:d(document).scrollTop(),left:d(document).scrollLeft()};if(e.is(".ui-draggable")||/absolute/.test(e.css("position")))e.css({position:"absolute",top:c.top,left:c.left});d.browser.opera&&/relative/.test(e.css("position"))&&e.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var g=m(this.helper.css("top"));if(a.containment){c+=d(a.containment).scrollLeft()||0;g+=d(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:g};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:c,top:g};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=d(".ui-resizable-"+this.axis).css("cursor");d("body").css("cursor",a=="auto"?this.axis+"-resize":a);e.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,e=this._change[this.axis];if(!e)return false;c=e.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var e=this._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName);e=g&&d.ui.hasScroll(e[0],"left")?0:c.sizeDiff.height;g={width:c.size.width-(g?0:c.sizeDiff.width),height:c.size.height-e};e=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var f=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(d.extend(g,{top:f,left:e}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}d("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,e=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(e=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(e=="nw"){b.top=a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,e=k(b.width)&&a.maxWidth&&a.maxWidth<b.width,g=k(b.height)&&a.maxHeight&&a.maxHeight<b.height,f=k(b.width)&&a.minWidth&&a.minWidth>b.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(f)b.width=a.minWidth;if(h)b.height=a.minHeight;if(e)b.width=a.maxWidth;if(g)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(f&&l)b.left=i-a.minWidth;if(e&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(g&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var e=[c.css("borderTopWidth"),c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],g=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=d.map(e,function(f,h){f=parseInt(f,10)||0;h=parseInt(g[h],10)||0;return f+h})}d.browser.msie&&(d(b).is(":hidden")||d(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||d('<div style="overflow:hidden;"></div>');var a=d.browser.msie&&d.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return d.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return d.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){d.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});d.extend(d.ui.resizable,{version:"1.8.1"});d.ui.plugin.add("resizable","alsoResize",{start:function(){var b=d(this).data("resizable").options,a=function(c){d(c).each(function(){d(this).data("resizable-alsoresize",{width:parseInt(d(this).width(),10),height:parseInt(d(this).height(),10),left:parseInt(d(this).css("left"),10),top:parseInt(d(this).css("top"),10)})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else d.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(){var b=d(this).data("resizable"),a=b.options,c=b.originalSize,e=b.originalPosition,g={height:b.size.height-c.height||0,width:b.size.width-c.width||0,top:b.position.top-e.top||0,left:b.position.left-e.left||0},f=function(h,i){d(h).each(function(){var j=d(this),l=d(this).data("resizable-alsoresize"),p={};d.each((i&&i.length?i:["width","height","top","left"])||["width","height","top","left"],function(n,o){if((n=(l[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(/relative/.test(j.css("position"))&&d.browser.opera){b._revertToRelativePosition=true;j.css({position:"absolute",top:"auto",left:"auto"})}j.css(p)})};typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?d.each(a.alsoResize,function(h,i){f(h,i)}):f(a.alsoResize)},stop:function(){var b=d(this).data("resizable");if(b._revertToRelativePosition&&d.browser.opera){b._revertToRelativePosition=false;el.css({position:"relative"})}d(this).removeData("resizable-alsoresize-start")}});d.ui.plugin.add("resizable","animate",{stop:function(b){var a=d(this).data("resizable"),c=a.options,e=a._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName),f=g&&d.ui.hasScroll(e[0],"left")?0:a.sizeDiff.height;g={width:a.size.width-(g?0:a.sizeDiff.width),height:a.size.height-f};f=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(d.extend(g,h&&f?{top:h,left:f}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};e&&e.length&&d(e[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});d.ui.plugin.add("resizable","containment",{start:function(){var b=d(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof d?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=d(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:d(document),left:0,top:0,width:d(document).width(),height:d(document).height()||document.body.parentNode.scrollHeight}}else{var e=d(a),g=[];d(["Top","Right","Left","Bottom"]).each(function(i,j){g[i]=m(e.css("padding"+j))});b.containerOffset=e.offset();b.containerPosition=e.position();b.containerSize={height:e.innerHeight()-g[3],width:e.innerWidth()-g[1]};c=b.containerOffset;var f=b.containerSize.height,h=b.containerSize.width;h=d.ui.hasScroll(a,"left")?a.scrollWidth:h;f=d.ui.hasScroll(a)?a.scrollHeight:f;b.parentData={element:a,left:c.left,top:c.top,width:h,height:f}}}},resize:function(b){var a=d(this).data("resizable"),c=a.options,e=a.containerOffset,g=a.position;b=a._aspectRatio||b.shiftKey;var f={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))f=e;if(g.left<(a._helper?e.left:0)){a.size.width+=a._helper?a.position.left-e.left:a.position.left-f.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?e.left:0}if(g.top<(a._helper?e.top:0)){a.size.height+=a._helper?a.position.top-e.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?e.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-f.left:a.offset.left-f.left)+a.sizeDiff.width);e=Math.abs((a._helper?a.offset.top-f.top:a.offset.top-e.top)+a.sizeDiff.height);g=a.containerElement.get(0)==a.element.parent().get(0);f=/relative|absolute/.test(a.containerElement.css("position"));if(g&&f)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(e+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-e;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=d(this).data("resizable"),a=b.options,c=b.containerOffset,e=b.containerPosition,g=b.containerElement,f=d(b.helper),h=f.offset(),i=f.outerWidth()-b.sizeDiff.width;f=f.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f});b._helper&&!a.animate&&/static/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f})}});d.ui.plugin.add("resizable","ghost",{start:function(){var b=d(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=d(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=d(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});d.ui.plugin.add("resizable","grid",{resize:function(){var b=d(this).data("resizable"),a=b.options,c=b.size,e=b.originalSize,g=b.originalPosition,f=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-e.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-e.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a}else if(/^(ne)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}else{if(/^(sw)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a}else{b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}b.position.left=g.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery);





/*
 * jQuery UI Button 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Button
 *
 * Depends:
 *      jquery.ui.core.js
 *      jquery.ui.widget.js
 */
(function(a){var g,i=function(b){a(":ui-button",b.target.form).each(function(){var c=a(this).data("button");setTimeout(function(){c.refresh()},1)})},h=function(b){var c=b.name,d=b.form,e=a([]);if(c)e=d?a(d).find("[name='"+c+"']"):a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form});return e};a.widget("ui.button",{options:{text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",i);this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,c=this.options,d=this.type==="checkbox"||this.type==="radio",e="ui-state-hover"+(!d?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){a(this).addClass("ui-state-hover");this===g&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||a(this).removeClass(e)}).bind("focus.button",function(){a(this).addClass("ui-state-focus")}).bind("blur.button",function(){a(this).removeClass("ui-state-focus")});d&&this.element.bind("change.button",function(){b.refresh()});if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).toggleClass("ui-state-active");b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed",true);var f=b.element[0];h(f).not(f).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");g=this;a(document).one("mouseup",function(){g=null})}).bind("mouseup.button",function(){if(c.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(f){if(c.disabled)return false;if(f.keyCode==a.ui.keyCode.SPACE||f.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(f){f.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",c.disabled)},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type==="radio"){this.buttonElement=this.element.parents().last().find("[for="+this.element.attr("id")+"]");this.element.addClass("ui-helper-hidden-accessible");var b=this.element.is(":checked");b&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")h(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",true):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement,c=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":""));d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>");d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon");this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{_create:function(){this.element.addClass("ui-buttonset");this._init()},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(":button, :submit, :reset, :checkbox, :radio, a, :data(button)").filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery);





/*
 * jQuery UI Tabs 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Tabs
 *
 * Depends:
 *      jquery.ui.core.js
 *      jquery.ui.widget.js
 */
(function(d){var s=0,u=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'},_create:function(){this._tabify(true)},_setOption:function(c,e){if(c=="selected")this.options.collapsible&&e==this.options.selected||this.select(e);else{this.options[c]=e;this._tabify()}},_tabId:function(c){return c.title&&c.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+ ++s},_sanitizeSelector:function(c){return c.replace(/:/g,"\\:")},_cookie:function(){var c=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++u);return d.cookie.apply(null,[c].concat(d.makeArray(arguments)))},_ui:function(c,e){return{tab:c,panel:e,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var c=d(this);c.html(c.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function e(g,f){g.css({display:""});!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}this.list=this.element.find("ol,ul").eq(0);this.lis=d("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);var a=this,b=this.options,h=/^#.+/;this.anchors.each(function(g,f){var j=d(f).attr("href"),l=j.split("#")[0],p;if(l&&(l===location.toString().split("#")[0]||(p=d("base")[0])&&l===p.href)){j=f.hash;f.href=j}if(h.test(j))a.panels=a.panels.add(a._sanitizeSelector(j));else if(j!="#"){d.data(f,"href.tabs",j);d.data(f,"load.tabs",j.replace(/#.*$/,""));j=a._tabId(f);f.href="#"+j;f=d("#"+j);if(!f.length){f=d(b.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else b.disabled.push(g)});if(c){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(b.selected===undefined){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){b.selected=g;return false}});if(typeof b.selected!="number"&&b.cookie)b.selected=parseInt(a._cookie(),10);if(typeof b.selected!="number"&&this.lis.filter(".ui-tabs-selected").length)b.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));b.selected=b.selected||(this.lis.length?0:-1)}else if(b.selected===null)b.selected=-1;b.selected=b.selected>=0&&this.anchors[b.selected]||b.selected<0?b.selected:0;b.disabled=d.unique(b.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(b.selected,b.disabled)!=-1&&b.disabled.splice(d.inArray(b.selected,b.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(b.selected>=0&&this.anchors.length){this.panels.eq(b.selected).removeClass("ui-tabs-hide");this.lis.eq(b.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[b.selected],a.panels[b.selected]))});this.load(b.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else b.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));this.element[b.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");b.cookie&&this._cookie(b.selected,b.cookie);c=0;for(var i;i=this.lis[c];c++)d(i)[d.inArray(c,b.disabled)!=-1&&!d(i).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");b.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(b.event!="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(b.fx)if(d.isArray(b.fx)){m=b.fx[0];o=b.fx[1]}else m=o=b.fx;var q=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},r=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};this.anchors.bind(b.event+".tabs",function(){var g=this,f=d(this).closest("li"),j=a.panels.filter(":not(.ui-tabs-hide)"),l=d(a._sanitizeSelector(this.hash));if(f.hasClass("ui-tabs-selected")&&!b.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}b.selected=a.anchors.index(this);a.abort();if(b.collapsible)if(f.hasClass("ui-tabs-selected")){b.selected=-1;b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){r(g,j)}).dequeue("tabs");this.blur();return false}else if(!j.length){b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this));this.blur();return false}b.cookie&&a._cookie(b.selected,b.cookie);if(l.length){j.length&&a.element.queue("tabs",function(){r(g,j)});a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var c=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(b,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});c.cookie&&this._cookie(null,c.cookie);return this},add:function(c,e,a){if(a===undefined)a=this.anchors.length;var b=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,e));c=!c.indexOf("#")?c.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var i=d("#"+c);i.length||(i=d(h.panelTemplate).attr("id",c).data("destroy.tabs",true));i.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);i.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);i.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");i.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(c){var e=this.options,a=this.lis.eq(c).remove(),b=this.panels.eq(c).remove();if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(c+(c+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=c}),function(h){return h>=c?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],b[0]));return this},enable:function(c){var e=this.options;if(d.inArray(c,e.disabled)!=-1){this.lis.eq(c).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=c});this._trigger("enable",null,this._ui(this.anchors[c],this.panels[c]));return this}},disable:function(c){var e=this.options;if(c!=e.selected){this.lis.eq(c).addClass("ui-state-disabled");e.disabled.push(c);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}return this},select:function(c){if(typeof c=="string")c=this.anchors.index(this.anchors.filter("[href$="+c+"]"));else if(c===null)c=-1;if(c==-1&&this.options.collapsible)c=this.options.selected;this.anchors.eq(c).trigger(this.options.event+".tabs");return this},load:function(c){var e=this,a=this.options,b=this.anchors.eq(c)[0],h=d.data(b,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(b,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(c).addClass("ui-state-processing");if(a.spinner){var i=d("span",b);i.data("label.tabs",i.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){d(e._sanitizeSelector(b.hash)).html(k);e._cleanup();a.cache&&d.data(b,"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.error(k,n,c,b)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},url:function(c,e){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.1"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(c,e){var a=this,b=this.options,h=a._rotate||(a._rotate=function(i){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=b.selected;a.select(++k<a.anchors.length?k:0)},c);i&&i.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(i){i.clientX&&a.rotate(null)}:function(){t=b.selected;h()});if(c){this.element.bind("tabsshow",h);this.anchors.bind(b.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(b.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);





/*
 * jQuery UI Dialog 1.8.1
 *
 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Dialog
 *
 * Depends:
 *      jquery.ui.core.js
 *      jquery.ui.widget.js
 *  jquery.ui.button.js
 *      jquery.ui.draggable.js
 *      jquery.ui.mouse.js
 *      jquery.ui.position.js
 *      jquery.ui.resizable.js
 */
(function(c){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");var a=this,b=a.options,d=b.title||a.originalTitle||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===f[0]&&e.shiftKey){g.focus(1);return false}}});c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(g,f){g=c('<button type="button"></button>').text(g).click(function(){f.apply(b.element[0],arguments)}).appendTo(e);c.fn.button&&g.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize,position:f.position,size:f.size}}a=a===undefined?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0];a=a||c.ui.dialog.prototype.options.position;if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(e,g){if(+b[e]===b[e]){d[e]=b[e];b[e]=g}})}else if(typeof a==="object"){if("left"in a){b[0]="left";d[0]=a.left}else if("right"in a){b[0]="right";d[0]=-a.right}if("top"in a){b[1]="top";d[1]=a.top}else if("bottom"in a){b[1]="bottom";d[1]=-a.bottom}}(a=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position({my:b.join(" "),at:b.join(" "),offset:d.join(" "),of:window,collision:"fit",using:function(e){var g=c(this).css(e).offset().top;g<0&&c(this).css("top",e.top-g)}});a||this.uiDialog.hide()},_setOption:function(a,b){var d=this,e=d.uiDialog,g=e.is(":data(resizable)"),f=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled");break;case "draggable":b?d._makeDraggable():e.draggable("destroy");break;case "height":f=true;break;case "maxHeight":g&&e.resizable("option","maxHeight",b);f=true;break;case "maxWidth":g&&e.resizable("option","maxWidth",b);f=true;break;case "minHeight":g&&e.resizable("option","minHeight",b);f=true;break;case "minWidth":g&&e.resizable("option","minWidth",b);f=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break;case "width":f=true;break}c.Widget.prototype._setOption.apply(d,arguments);f&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.1",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);





(function($){
	//Save original function reference for internal usage
	var _val = $.fn.val;
	$.iHint = function(target, options) {
		var jElement = $(target);
		//Default values
		target.iHint = {
			"text": "iHint Text",
			"className": "iHint-default"
		};
		//Override with extra parameters
		$.extend(target.iHint, options);
		//Set event callbacks, attributes and call blur
		jElement
			.blur(function() {
				if (!_val.call(jElement)) {
					jElement.addClass(target.iHint.className);
					_val.call(jElement, target.iHint.text);
				}
			})
			.focus(function() {
				if (_val.call(jElement) == target.iHint.text) {
					jElement.removeClass(target.iHint.className);
					_val.call(jElement, "");
				}
			})
			.trigger("blur");
	};
	$.fn.iHint = function(options) {
		return this.each(function() {
			new $.iHint(this, options);
		});
	};
	//override default "val" function so it could be used on iHint elements
	$.fn.val = function(value) {
		if (this[0] && this[0].iHint) {
			if (typeof(value) == 'undefined') {
				if (_val.apply(this, arguments) == this[0].iHint.text) {
					return "";
				}
			} else {
				this.removeClass(this[0].iHint.className);
				return _val.apply(this, arguments);
			}
		} 
		return _val.apply(this, arguments);
	};
})(jQuery);





/*
 * FancyBox - jQuery Plugin
 * Simple and fancy lightbox alternative
 *
 * Examples and documentation at: http://fancybox.net
 * 
 * Copyright (c) 2008 - 2010 Janis Skarnelis
 *
 * Version: 1.3.1 (05/03/2010)
 * Requires: jQuery v1.3+
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

(function(b){var m,u,x,g,D,i,z,A,B,p=0,e={},q=[],n=0,c={},j=[],E=null,s=new Image,G=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,S=/[^\.]\.(swf)\s*$/i,H,I=1,k,l,h=false,y=b.extend(b("<div/>")[0],{prop:0}),v=0,O=!b.support.opacity&&!window.XMLHttpRequest,J=function(){u.hide();s.onerror=s.onload=null;E&&E.abort();m.empty()},P=function(){b.fancybox('<p id="fancybox_error">The requested content cannot be loaded.<br />Please try again later.</p>',{scrolling:"no",padding:20,transitionIn:"none",transitionOut:"none"})},
K=function(){return[b(window).width(),b(window).height(),b(document).scrollLeft(),b(document).scrollTop()]},T=function(){var a=K(),d={},f=c.margin,o=c.autoScale,t=(20+f)*2,w=(20+f)*2,r=c.padding*2;if(c.width.toString().indexOf("%")>-1){d.width=a[0]*parseFloat(c.width)/100-40;o=false}else d.width=c.width+r;if(c.height.toString().indexOf("%")>-1){d.height=a[1]*parseFloat(c.height)/100-40;o=false}else d.height=c.height+r;if(o&&(d.width>a[0]-t||d.height>a[1]-w))if(e.type=="image"||e.type=="swf"){t+=r;
w+=r;o=Math.min(Math.min(a[0]-t,c.width)/c.width,Math.min(a[1]-w,c.height)/c.height);d.width=Math.round(o*(d.width-r))+r;d.height=Math.round(o*(d.height-r))+r}else{d.width=Math.min(d.width,a[0]-t);d.height=Math.min(d.height,a[1]-w)}d.top=a[3]+(a[1]-(d.height+40))*0.5;d.left=a[2]+(a[0]-(d.width+40))*0.5;if(c.autoScale===false){d.top=Math.max(a[3]+f,d.top);d.left=Math.max(a[2]+f,d.left)}return d},U=function(a){if(a&&a.length)switch(c.titlePosition){case "inside":return a;case "over":return'<span id="fancybox-title-over">'+
a+"</span>";default:return'<span id="fancybox-title-wrap"><span id="fancybox-title-left"></span><span id="fancybox-title-main">'+a+'</span><span id="fancybox-title-right"></span></span>'}return false},V=function(){var a=c.title,d=l.width-c.padding*2,f="fancybox-title-"+c.titlePosition;b("#fancybox-title").remove();v=0;if(c.titleShow!==false){a=b.isFunction(c.titleFormat)?c.titleFormat(a,j,n,c):U(a);if(!(!a||a==="")){b('<div id="fancybox-title" class="'+f+'" />').css({width:d,paddingLeft:c.padding,
paddingRight:c.padding}).html(a).appendTo("body");switch(c.titlePosition){case "inside":v=b("#fancybox-title").outerHeight(true)-c.padding;l.height+=v;break;case "over":b("#fancybox-title").css("bottom",c.padding);break;default:b("#fancybox-title").css("bottom",b("#fancybox-title").outerHeight(true)*-1);break}b("#fancybox-title").appendTo(D).hide()}}},W=function(){b(document).unbind("keydown.fb").bind("keydown.fb",function(a){if(a.keyCode==27&&c.enableEscapeButton){a.preventDefault();b.fancybox.close()}else if(a.keyCode==
37){a.preventDefault();b.fancybox.prev()}else if(a.keyCode==39){a.preventDefault();b.fancybox.next()}});if(b.fn.mousewheel){g.unbind("mousewheel.fb");j.length>1&&g.bind("mousewheel.fb",function(a,d){a.preventDefault();h||d===0||(d>0?b.fancybox.prev():b.fancybox.next())})}if(c.showNavArrows){if(c.cyclic&&j.length>1||n!==0)A.show();if(c.cyclic&&j.length>1||n!=j.length-1)B.show()}},X=function(){var a,d;if(j.length-1>n){a=j[n+1].href;if(typeof a!=="undefined"&&a.match(G)){d=new Image;d.src=a}}if(n>0){a=
j[n-1].href;if(typeof a!=="undefined"&&a.match(G)){d=new Image;d.src=a}}},L=function(){i.css("overflow",c.scrolling=="auto"?c.type=="image"||c.type=="iframe"||c.type=="swf"?"hidden":"auto":c.scrolling=="yes"?"auto":"visible");if(!b.support.opacity){i.get(0).style.removeAttribute("filter");g.get(0).style.removeAttribute("filter")}b("#fancybox-title").show();c.hideOnContentClick&&i.one("click",b.fancybox.close);c.hideOnOverlayClick&&x.one("click",b.fancybox.close);c.showCloseButton&&z.show();W();b(window).bind("resize.fb",
b.fancybox.center);c.centerOnScroll?b(window).bind("scroll.fb",b.fancybox.center):b(window).unbind("scroll.fb");b.isFunction(c.onComplete)&&c.onComplete(j,n,c);h=false;X()},M=function(a){var d=Math.round(k.width+(l.width-k.width)*a),f=Math.round(k.height+(l.height-k.height)*a),o=Math.round(k.top+(l.top-k.top)*a),t=Math.round(k.left+(l.left-k.left)*a);g.css({width:d+"px",height:f+"px",top:o+"px",left:t+"px"});d=Math.max(d-c.padding*2,0);f=Math.max(f-(c.padding*2+v*a),0);i.css({width:d+"px",height:f+
"px"});if(typeof l.opacity!=="undefined")g.css("opacity",a<0.5?0.5:a)},Y=function(a){var d=a.offset();d.top+=parseFloat(a.css("paddingTop"))||0;d.left+=parseFloat(a.css("paddingLeft"))||0;d.top+=parseFloat(a.css("border-top-width"))||0;d.left+=parseFloat(a.css("border-left-width"))||0;d.width=a.width();d.height=a.height();return d},Q=function(){var a=e.orig?b(e.orig):false,d={};if(a&&a.length){a=Y(a);d={width:a.width+c.padding*2,height:a.height+c.padding*2,top:a.top-c.padding-20,left:a.left-c.padding-
20}}else{a=K();d={width:1,height:1,top:a[3]+a[1]*0.5,left:a[2]+a[0]*0.5}}return d},N=function(){u.hide();if(g.is(":visible")&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){b.event.trigger("fancybox-cancel");h=false;return}j=q;n=p;c=e;i.get(0).scrollTop=0;i.get(0).scrollLeft=0;if(c.overlayShow){O&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});
x.css({"background-color":c.overlayColor,opacity:c.overlayOpacity}).unbind().show()}l=T();V();if(g.is(":visible")){b(z.add(A).add(B)).hide();var a=g.position(),d;k={top:a.top,left:a.left,width:g.width(),height:g.height()};d=k.width==l.width&&k.height==l.height;i.fadeOut(c.changeFade,function(){var f=function(){i.html(m.contents()).fadeIn(c.changeFade,L)};b.event.trigger("fancybox-change");i.empty().css("overflow","hidden");if(d){i.css({top:c.padding,left:c.padding,width:Math.max(l.width-c.padding*
2,1),height:Math.max(l.height-c.padding*2-v,1)});f()}else{i.css({top:c.padding,left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)});y.prop=0;b(y).animate({prop:1},{duration:c.changeSpeed,easing:c.easingChange,step:M,complete:f})}})}else{g.css("opacity",1);if(c.transitionIn=="elastic"){k=Q();i.css({top:c.padding,left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)}).html(m.contents());g.css(k).show();if(c.opacity)l.opacity=
0;y.prop=0;b(y).animate({prop:1},{duration:c.speedIn,easing:c.easingIn,step:M,complete:L})}else{i.css({top:c.padding,left:c.padding,width:Math.max(l.width-c.padding*2,1),height:Math.max(l.height-c.padding*2-v,1)}).html(m.contents());g.css(l).fadeIn(c.transitionIn=="none"?0:c.speedIn,L)}}},F=function(){m.width(e.width);m.height(e.height);if(e.width=="auto")e.width=m.width();if(e.height=="auto")e.height=m.height();N()},Z=function(){h=true;e.width=s.width;e.height=s.height;b("<img />").attr({id:"fancybox-img",
src:s.src,alt:e.title}).appendTo(m);N()},C=function(){J();var a=q[p],d,f,o,t,w;e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));o=a.title||b(a).title||e.title||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?b(a).children("img:first"):b(a);if(o===""&&e.orig)o=e.orig.attr("alt");d=a.nodeName&&/^(?:javascript|#)/i.test(a.href)?e.href||null:e.href||a.href||null;if(e.type){f=e.type;if(!d)d=e.content}else if(e.content)f="html";else if(d)if(d.match(G))f=
"image";else if(d.match(S))f="swf";else if(b(a).hasClass("iframe"))f="iframe";else if(d.match(/#/)){a=d.substr(d.indexOf("#"));f=b(a).length>0?"inline":"ajax"}else f="ajax";else f="inline";e.type=f;e.href=d;e.title=o;if(e.autoDimensions&&e.type!=="iframe"&&e.type!=="swf"){e.width="auto";e.height="auto"}if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=false;e.enableEscapeButton=false;e.showCloseButton=false}if(b.isFunction(e.onStart))if(e.onStart(q,p,e)===false){h=false;
return}m.css("padding",20+e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(i.children())});switch(f){case "html":m.html(e.content);F();break;case "inline":b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",function(){b(this).replaceWith(i.children())}).bind("fancybox-cancel",function(){b(this).replaceWith(m.children())});b(a).appendTo(m);F();break;case "image":h=false;b.fancybox.showActivity();
s=new Image;s.onerror=function(){P()};s.onload=function(){s.onerror=null;s.onload=null;Z()};s.src=d;break;case "swf":t='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+d+'"></param>';w="";b.each(e.swf,function(r,R){t+='<param name="'+r+'" value="'+R+'"></param>';w+=" "+r+'="'+R+'"'});t+='<embed src="'+d+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+w+"></embed></object>";m.html(t);
F();break;case "ajax":a=d.split("#",2);f=e.ajax.data||{};if(a.length>1){d=a[0];if(typeof f=="string")f+="&selector="+a[1];else f.selector=a[1]}h=false;b.fancybox.showActivity();E=b.ajax(b.extend(e.ajax,{url:d,data:f,error:P,success:function(r){if(E.status==200){m.html(r);F()}}}));break;case "iframe":b('<iframe id="fancybox-frame" name="fancybox-frame'+(new Date).getTime()+'" frameborder="0" hspace="0" scrolling="'+e.scrolling+'" src="'+e.href+'"></iframe>').appendTo(m);N();break}},$=function(){if(u.is(":visible")){b("div",
u).css("top",I*-40+"px");I=(I+1)%12}else clearInterval(H)},aa=function(){if(!b("#fancybox-wrap").length){b("body").append(m=b('<div id="fancybox-tmp"></div>'),u=b('<div id="fancybox-loading"><div></div></div>'),x=b('<div id="fancybox-overlay"></div>'),g=b('<div id="fancybox-wrap"></div>'));if(!b.support.opacity){g.addClass("fancybox-ie");u.addClass("fancybox-ie")}D=b('<div id="fancybox-outer"></div>').append('<div class="fancy-bg" id="fancy-bg-n"></div><div class="fancy-bg" id="fancy-bg-ne"></div><div class="fancy-bg" id="fancy-bg-e"></div><div class="fancy-bg" id="fancy-bg-se"></div><div class="fancy-bg" id="fancy-bg-s"></div><div class="fancy-bg" id="fancy-bg-sw"></div><div class="fancy-bg" id="fancy-bg-w"></div><div class="fancy-bg" id="fancy-bg-nw"></div>').appendTo(g);
D.append(i=b('<div id="fancybox-inner"></div>'),z=b('<a id="fancybox-close"></a>'),A=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),B=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));z.click(b.fancybox.close);u.click(b.fancybox.cancel);A.click(function(a){a.preventDefault();b.fancybox.prev()});B.click(function(a){a.preventDefault();b.fancybox.next()});if(O){x.get(0).style.setExpression("height",
"document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'");u.get(0).style.setExpression("top","(-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px'");D.prepend('<iframe id="fancybox-hide-sel-frame" src="javascript:\'\';" scrolling="no" frameborder="0" ></iframe>')}}};
b.fn.fancybox=function(a){b(this).data("fancybox",b.extend({},a,b.metadata?b(this).metadata():{})).unbind("click.fb").bind("click.fb",function(d){d.preventDefault();if(!h){h=true;b(this).blur();q=[];p=0;d=b(this).attr("rel")||"";if(!d||d==""||d==="nofollow")q.push(this);else{q=b("a[rel="+d+"], area[rel="+d+"]");p=q.index(this)}C();return false}});return this};b.fancybox=function(a,d){if(!h){h=true;d=typeof d!=="undefined"?d:{};q=[];p=d.index||0;if(b.isArray(a)){for(var f=0,o=a.length;f<o;f++)if(typeof a[f]==
"object")b(a[f]).data("fancybox",b.extend({},d,a[f]));else a[f]=b({}).data("fancybox",b.extend({content:a[f]},d));q=jQuery.merge(q,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},d,a));else a=b({}).data("fancybox",b.extend({content:a},d));q.push(a)}if(p>q.length||p<0)p=0;C()}};b.fancybox.showActivity=function(){clearInterval(H);u.show();H=setInterval($,66)};b.fancybox.hideActivity=function(){u.hide()};b.fancybox.next=function(){return b.fancybox.pos(n+1)};b.fancybox.prev=function(){return b.fancybox.pos(n-
1)};b.fancybox.pos=function(a){if(!h){a=parseInt(a,10);if(a>-1&&j.length>a){p=a;C()}if(c.cyclic&&j.length>1&&a<0){p=j.length-1;C()}if(c.cyclic&&j.length>1&&a>=j.length){p=0;C()}}};b.fancybox.cancel=function(){if(!h){h=true;b.event.trigger("fancybox-cancel");J();e&&b.isFunction(e.onCancel)&&e.onCancel(q,p,e);h=false}};b.fancybox.close=function(){function a(){x.fadeOut("fast");g.hide();b.event.trigger("fancybox-cleanup");i.empty();b.isFunction(c.onClosed)&&c.onClosed(j,n,c);j=e=[];n=p=0;c=e={};h=false}
if(!(h||g.is(":hidden"))){h=true;if(c&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){h=false;return}J();b(z.add(A).add(B)).hide();b("#fancybox-title").remove();g.add(i).add(x).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");i.css("overflow","hidden");if(c.transitionOut=="elastic"){k=Q();var d=g.position();l={top:d.top,left:d.left,width:g.width(),height:g.height()};if(c.opacity)l.opacity=1;y.prop=1;b(y).animate({prop:0},{duration:c.speedOut,easing:c.easingOut,
step:M,complete:a})}else g.fadeOut(c.transitionOut=="none"?0:c.speedOut,a)}};b.fancybox.resize=function(){var a,d;if(!(h||g.is(":hidden"))){h=true;a=i.wrapInner("<div style='overflow:auto'></div>").children();d=a.height();g.css({height:d+c.padding*2+v});i.css({height:d});a.replaceWith(a.children());b.fancybox.center()}};b.fancybox.center=function(){h=true;var a=K(),d=c.margin,f={};f.top=a[3]+(a[1]-(g.height()-v+40))*0.5;f.left=a[2]+(a[0]-(g.width()+40))*0.5;f.top=Math.max(a[3]+d,f.top);f.left=Math.max(a[2]+
d,f.left);g.css(f);h=false};b.fn.fancybox.defaults={padding:10,margin:20,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.3,overlayColor:"#666",titleShow:true,titlePosition:"outside",titleFormat:null,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",
easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,onStart:null,onCancel:null,onComplete:null,onCleanup:null,onClosed:null};b(document).ready(function(){aa()})})(jQuery);





/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
// Wrapped into anonymous function to avoid namespace interception
// Inner jQuery name used to minimize plugin changes
(function(jQuery){
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('h.i[\'1a\']=h.i[\'z\'];h.O(h.i,{y:\'D\',z:9(x,t,b,c,d){6 h.i[h.i.y](x,t,b,c,d)},17:9(x,t,b,c,d){6 c*(t/=d)*t+b},D:9(x,t,b,c,d){6-c*(t/=d)*(t-2)+b},13:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t+b;6-c/2*((--t)*(t-2)-1)+b},X:9(x,t,b,c,d){6 c*(t/=d)*t*t+b},U:9(x,t,b,c,d){6 c*((t=t/d-1)*t*t+1)+b},R:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t+b;6 c/2*((t-=2)*t*t+2)+b},N:9(x,t,b,c,d){6 c*(t/=d)*t*t*t+b},M:9(x,t,b,c,d){6-c*((t=t/d-1)*t*t*t-1)+b},L:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t*t+b;6-c/2*((t-=2)*t*t*t-2)+b},K:9(x,t,b,c,d){6 c*(t/=d)*t*t*t*t+b},J:9(x,t,b,c,d){6 c*((t=t/d-1)*t*t*t*t+1)+b},I:9(x,t,b,c,d){e((t/=d/2)<1)6 c/2*t*t*t*t*t+b;6 c/2*((t-=2)*t*t*t*t+2)+b},G:9(x,t,b,c,d){6-c*8.C(t/d*(8.g/2))+c+b},15:9(x,t,b,c,d){6 c*8.n(t/d*(8.g/2))+b},12:9(x,t,b,c,d){6-c/2*(8.C(8.g*t/d)-1)+b},Z:9(x,t,b,c,d){6(t==0)?b:c*8.j(2,10*(t/d-1))+b},Y:9(x,t,b,c,d){6(t==d)?b+c:c*(-8.j(2,-10*t/d)+1)+b},W:9(x,t,b,c,d){e(t==0)6 b;e(t==d)6 b+c;e((t/=d/2)<1)6 c/2*8.j(2,10*(t-1))+b;6 c/2*(-8.j(2,-10*--t)+2)+b},V:9(x,t,b,c,d){6-c*(8.o(1-(t/=d)*t)-1)+b},S:9(x,t,b,c,d){6 c*8.o(1-(t=t/d-1)*t)+b},Q:9(x,t,b,c,d){e((t/=d/2)<1)6-c/2*(8.o(1-t*t)-1)+b;6 c/2*(8.o(1-(t-=2)*t)+1)+b},P:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d)==1)6 b+c;e(!p)p=d*.3;e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);6-(a*8.j(2,10*(t-=1))*8.n((t*d-s)*(2*8.g)/p))+b},H:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d)==1)6 b+c;e(!p)p=d*.3;e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);6 a*8.j(2,-10*t)*8.n((t*d-s)*(2*8.g)/p)+c+b},T:9(x,t,b,c,d){f s=1.l;f p=0;f a=c;e(t==0)6 b;e((t/=d/2)==2)6 b+c;e(!p)p=d*(.3*1.5);e(a<8.w(c)){a=c;f s=p/4}m f s=p/(2*8.g)*8.r(c/a);e(t<1)6-.5*(a*8.j(2,10*(t-=1))*8.n((t*d-s)*(2*8.g)/p))+b;6 a*8.j(2,-10*(t-=1))*8.n((t*d-s)*(2*8.g)/p)*.5+c+b},F:9(x,t,b,c,d,s){e(s==u)s=1.l;6 c*(t/=d)*t*((s+1)*t-s)+b},E:9(x,t,b,c,d,s){e(s==u)s=1.l;6 c*((t=t/d-1)*t*((s+1)*t+s)+1)+b},16:9(x,t,b,c,d,s){e(s==u)s=1.l;e((t/=d/2)<1)6 c/2*(t*t*(((s*=(1.B))+1)*t-s))+b;6 c/2*((t-=2)*t*(((s*=(1.B))+1)*t+s)+2)+b},A:9(x,t,b,c,d){6 c-h.i.v(x,d-t,0,c,d)+b},v:9(x,t,b,c,d){e((t/=d)<(1/2.k)){6 c*(7.q*t*t)+b}m e(t<(2/2.k)){6 c*(7.q*(t-=(1.5/2.k))*t+.k)+b}m e(t<(2.5/2.k)){6 c*(7.q*(t-=(2.14/2.k))*t+.11)+b}m{6 c*(7.q*(t-=(2.18/2.k))*t+.19)+b}},1b:9(x,t,b,c,d){e(t<d/2)6 h.i.A(x,t*2,0,c,d)*.5+b;6 h.i.v(x,t*2-d,0,c,d)*.5+c*.5+b}});',62,74,'||||||return||Math|function|||||if|var|PI|jQuery|easing|pow|75|70158|else|sin|sqrt||5625|asin|||undefined|easeOutBounce|abs||def|swing|easeInBounce|525|cos|easeOutQuad|easeOutBack|easeInBack|easeInSine|easeOutElastic|easeInOutQuint|easeOutQuint|easeInQuint|easeInOutQuart|easeOutQuart|easeInQuart|extend|easeInElastic|easeInOutCirc|easeInOutCubic|easeOutCirc|easeInOutElastic|easeOutCubic|easeInCirc|easeInOutExpo|easeInCubic|easeOutExpo|easeInExpo||9375|easeInOutSine|easeInOutQuad|25|easeOutSine|easeInOutBack|easeInQuad|625|984375|jswing|easeInOutBounce'.split('|'),0,{}));
})(jQuery);



(function($) {


if (!window.Echo) window.Echo = {};
if (!Echo.Global) Echo.Global = {};
if (!Echo.Vars) Echo.Vars = {
	"regexps": {
		"matchLabel": /{Label:([^:}]+[^}]*)}/g,
		"matchData": /{Data:(([a-z]+\.)*[a-z]+)}/ig,
		"mobileUA": /mobile|midp-|opera mini|iphone|ipad|blackberry|nokia|samsung|docomo|symbian|windows ce|windows phone|android|up\.browser|ipod|netfront|skyfire|palm|webos|audiovox/i,
		"parseUrl": /^((([^:\/\?#]+):)?\/\/)?([^\/\?#]*)?([^\?#]*)(\?([^#]*))?(#(.*))?/,
		"w3cdtf": /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/
	}
};

$.extend({
	"addCss": function(cssCode, id) {
		Echo.Vars.css = Echo.Vars.css || {
			"index": 1,
			"processed": {}
		};
		if (id) {
			if (Echo.Vars.css.processed[id]) return;
			Echo.Vars.css.processed[id] = true;
		}
		var curCssCode = "";
		var oldStyle = Echo.Vars.css.anchor;
		if (oldStyle && oldStyle.length) {
			curCssCode = oldStyle.html();
		}
		// IE limit is 4095 rules per style tag
		// so we limit it to 100000 characters
		// (2000 rules x 50 characters per rule)
		if (curCssCode.length + cssCode.length > 100000) {
			Echo.Vars.css.index++;
			oldStyle = null;
			curCssCode = "";
		}
		var newStyle = $('<style id="echo-css-' + Echo.Vars.css.index + '" type="text/css">' + curCssCode + cssCode + '</style>');
		if (oldStyle && oldStyle.length) {
			// use replacing instead of adding css to existing element
			// because IE doesn't allow it
			oldStyle.replaceWith(newStyle);
		} else {
			if (Echo.Vars.css.anchor) {
				Echo.Vars.css.anchor.after(newStyle);
			} else {
				$(document.getElementsByTagName("head")[0] || document.documentElement).prepend(newStyle);
			}
		}
		Echo.Vars.css.anchor = newStyle;
	},
	"foldl": function(acc, object, callback) {
		$.each(object, function(key, item) {
			result = callback(item, acc, key);
			if (result !== undefined) acc = result;
		});
		return acc;
	},
	"intersperse": function(object, separator) {
		return $.foldl([], object, function(item, acc, key) {
			if (acc.length) acc.push(separator);
			acc.push(item);
		});
	},
	"getNestedValue": function(key, data, defaults, callback) {
		if (typeof key == "string") {
			key = key.split(/\./);
		}
		if (!key.length) return data;
		var found = true;
		var iteration = function(_key, _data) {
			if (callback) callback(_data, _key);
			if (typeof _data[_key] == "undefined") {
				found = false;
			} else {
				return _data[_key];
			}
		};
		// avoid foldl usage for plain keys
		var value = key.length == 1
			? iteration(key.pop(), data)
			: $.foldl(data, key, iteration);
		return found ? value : defaults;
	},
	"setNestedValue": function(obj, key, value) {
		var keys = key.split(/\./);
		var field = keys.pop();
		var data = $.getNestedValue(keys, obj, undefined, function(acc, v) {
			if (typeof acc[v] == "undefined") acc[v] = {};
		});
		data[field] = value;
	},
	"htmlize": function(text) {
		if (!text) return '';
		return $('<div>').text(text).html();
	},
	"object2JSON": function(obj) {
		var encodeJSONLiteral = function(string) {
			var replacements = {
				'\b': '\\b',
				'\t': '\\t',
				'\n': '\\n',
				'\f': '\\f',
				'\r': '\\r',
				'"' : '\\"',
				'\\': '\\\\'};
			return string.replace(/[\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff\\]/g,
				function (a) {
					return (replacements.hasOwnProperty(a))
						? replacements[a]
						: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
				}
			);
		}
		var out;
		switch (typeof obj) {
			case "number"  : out = isFinite(obj) ? obj : 'null'; break;
			case "string"  : out = '"' + encodeJSONLiteral(obj) + '"'; break;
			case "boolean" : out = '"' + obj.toString() + '"'; break;
			default :
				if (obj instanceof Array) {
					var container = $.map(obj, function(element) { return $.object2JSON(element); });
					out = '[' + container.join(",") + ']';
				} else if (obj instanceof Object) {
					var source = obj.exportProperties || obj;
					var container = $.foldl([], source, function(value, acc, property) {
						if (source instanceof Array) {
							property = value;
							value = obj[property];
						}
						acc.push('"' + property + '":' + $.object2JSON(value));
					});
					out = '{' + container.join(",") + '}';
				} else {
					out = 'null';
				}
		}
		return out;
	},
	"htmlTextTruncate": function(text, limit, postfix, forceClosingTags) {
		if (!limit || text.length < limit) return text;
		var tags = [], count = 0, finalPos = 0;
		var list = "br hr input img area param base link meta option".split(" ");
		var standalone = $.foldl({}, list, function(value, acc, key) {
			acc[value] = true;
		});
		for (var i = 0; i < text.length; i++) {
			var symbol = text.charAt(i);
			if (symbol == "<") {
				var tail = text.indexOf(">", i);
				if (tail < 0) return text;
				var source = text.substring(i + 1, tail);
				var tag = {"name": "", "closing": false};
				if (source.charAt(0) == "/") {
					tag.closing = true;
					source = source.substring(1);
				}
				tag.name = source.match(/(\w)+/)[0];
				if (tag.closing) {
					var current = tags.pop();
					if (!current || current.name != tag.name) return text;
				} else if (!standalone[tag.name]) {
					tags.push(tag);
				}
				i = tail;
			} else if (symbol == "&" && text.substring(i).match(/^(\S)+;/)) {
				i = text.indexOf(";", i);
			} else {
				if (count == limit) {
					finalPos = i;
					break;
				}
				count++;
			}
		}
		if (finalPos || forceClosingTags) {
			if (finalPos) {
				text = text.substring(0, finalPos) + (postfix || "");
			}
			for (var i = tags.length - 1; i >= 0; i--) {
				text += "</" + tags[i].name + ">";
			}
		}
		return text;
	},
	"mapClass2Object": function(e, ctl) {
		ctl = ctl || {};
		e.find("*").andSelf().each(function(i, el) {
			if (el.className) {
				var arr = el.className.split(/[ ]+/);
				$.each(arr, function(i, c) { ctl[c] = el; });
			}
		});
		return ctl;
	},
	"stripTags": function(text) {
		return $('<div>').html(text).text();
	},
	"parseUrl": function(url) {
		var parts = url.match(Echo.Vars.regexps.parseUrl);
		return parts ? {
			"scheme": parts[3],
			"domain": parts[4],
			"path": parts[5],
			"query": parts[7],
			"fragment": parts[9]
		} : undefined;
	},
	"toDOM": function(template, prefix, renderer) {
		var content = $(template);
		var elements = $.mapClass2Object(content);
		var dom = {
			"set": function(name, element) {
				elements[prefix + name] = element;
			},
			"get": function(name, ignorePrefix) {
				var element = elements[(ignorePrefix ? "" : prefix) + name];
				return element && $(element);
			},
			"remove": function(element) {
				var name;
				if (typeof element == "string") {
					name = prefix + element;
				} else {
					name = element.echo.name;
				}
				$(elements[name]).remove();
				delete elements[name];
			},
			"content": content
		};
		var rendererFunction;
		if (typeof renderer == 'object') {
			rendererFunction = function(name, element, dom) {
				if (!renderer[name]) return;
				return renderer[name](element, dom);
			}
		} else {
			rendererFunction = renderer;
		}
		$.each(elements, function(id, element) {
			var pattern = id.match(prefix + "(.*)");
			var name = pattern ? pattern[1] : undefined;
			if (name && rendererFunction) {
				element = $(element);
				element.echo = element.echo || {};
				element.echo.name = id;
				var node = rendererFunction(name, element, dom);
				if (typeof node != "undefined") element.empty().append(node);
			}
		});
		return dom;
	},
	"loadScriptContent": function(url, callback) {
		Echo.Vars.scriptState = Echo.Vars.scriptState || {};
		if (Echo.Vars.scriptState[url] == "loaded") {
			callback();
			return;
		}
		var id = Echo.Broadcast.subscribe("internal.scriptLoaded",
			function(topic, scriptURL) {
				if (url != scriptURL) return;
				Echo.Broadcast.unsubscribe("internal.scriptLoaded", id);
				callback();
			});
		if (Echo.Vars.scriptState[url] == "loading") return;
		Echo.Vars.scriptState[url] = "loading";
		var script = document.createElement("script");
		script.type = "text/javascript";
		script.charset = "utf-8";
		script.src = url;
		var container = document.getElementsByTagName("head")[0] ||
				document.documentElement;
		container.insertBefore(script, container.firstChild);
		script.onload = script.onreadystatechange = function() {
			var state = script.readyState;
			if (!state || state == "loaded" || state == "complete") {
				Echo.Vars.scriptState[url] = "loaded";
				Echo.Broadcast.publish("internal.scriptLoaded", url);
				script.onload = script.onreadystatechange = null;
			}
		};
	},
	"sendPostRequest": function(url, data, callback){
		var id = "echo-post-" + Math.random();
		var container =
			$("#echo-post-request").length
				? $("#echo-post-request").empty()
				: $('<div id="echo-post-request"/>').css({"height": 0}).prependTo("body");
		// it won't work if the attributes are specified as a hash in the second parameter
		$('<iframe id="' + id + '" name="' + id + '" width="0" height="0" frameborder="0" border="0"></iframe>').appendTo(container);
		var form = $("<form/>", {
			"target" : id,
			"method" : "POST",
			"enctype" : "application/x-www-form-urlencoded",
			"acceptCharset" : "UTF-8",
			"action" : url
		})
			.appendTo(container);
		$.each(data, function(key, value) {
			$("<input/>", {
				"type" : "hidden",
				"name" : key,
				"value" : value
			})
			.appendTo(form);
		});
		form.submit();
		callback();
	},
	"getVisibleColor": function(elem) {
		// calculate visible color of element (transparent is not visible)
		var color;
		do {
			color = elem.css('backgroundColor');
			if (color != '' && color != 'transparent' && !/rgba\(0, 0, 0, 0\)/.test(color) || $.nodeName(elem.get(0), 'body')) {
				break;
			}
		} while (elem = elem.parent());
		return color || 'transparent';
	},
	"timestampFromW3CDTF": function(t) {
		var parts = ['year', 'month', 'day', 'hours', 'minutes', 'seconds'];
		var dt = {};
		var matches = t.match(Echo.Vars.regexps.w3cdtf);
		$.each(parts, function(i, p) {
			dt[p] = matches[i + 1];
		});
		return Date.UTC(dt['year'], dt['month'] - 1, dt['day'],
			dt['hours'], dt['minutes'], dt['seconds']) / 1000;
	},
	"isMobileDevice": function() {
		return Echo.Vars.regexps.mobileUA.test(navigator.userAgent);
	}
});





if (!Echo.Plugins) Echo.Plugins = {};

Echo.isExtended = function(plugin, unique, value) {
	if (!plugin) return false;
	value = value || true;
	var id = [plugin].concat(unique).join(".");
	Echo.Vars.extensions = Echo.Vars.extensions || {};
	if (Echo.Vars.extensions[id] == value) return true;
	Echo.Vars.extensions[id] = value;
	return false;
};

Echo.extendRenderer = function(component, method, renderer, plugin) {
	if (!component || !Echo[component] || !method || !renderer || !$.isFunction(renderer) ||
		Echo.isExtended(plugin, [component, "renderer", method])) return;
	var _renderer = Echo[component].prototype.renderers[method] || function() {};
	Echo[component].prototype.renderers[method] = function() {
		var config = plugin && this.config.get("plugins." + plugin);
		if (!config || !config.enabled) {
			return _renderer.apply(this, arguments);
		}
		var self = this;
		if (!this.parentRenderer) {
			this.parentRenderer = function(name, args) {
				return self.parentRenderers[name].apply(self, args);
			}
		}
		this.parentRenderers = this.parentRenderers || {};
		this.parentRenderers[method] = _renderer;
		return renderer.apply(this, arguments);
	};
};

Echo.extendTemplate = function(component, html, action, anchor, plugin) {
	if (!component || !Echo[component] || !action || !anchor || !html ||
		Echo.isExtended(plugin, [component, "template", anchor, action], html)) return;
	var _template = Echo[component].prototype.template;
	var template = $.isFunction(_template) ? _template : function() { return _template; };
	var classify = {
		"insertBefore": "before",
		"insertAfter": "after",
		"insertAsFirstChild": "prepend",
		"insertAsLastChild": "append",
		"replace": "replaceWith"
	};
	Echo[component].prototype.template = function() {
		var config = plugin && this.config.get("plugins." + plugin);
		if (!config || !config.enabled) {
			return template.call(this);
		}
		var dom = $('<div/>').html(template.call(this));
		$('.' + anchor, dom)[classify[action]](html);
		return dom.html();
	};
};

Echo.include = function(scripts, callback) {
	if (!scripts.length) return callback();
	var script = scripts.pop();
	Echo.include(scripts, function() {
		if (typeof script.loaded == "undefined") {
			if (script.application) {
				script.loaded = function() {
					return !!Echo[script.application];
				}
			} else {
				callback();
			}
		}
		if ($.isFunction(script.loaded) && !script.loaded()) {
			$.loadScriptContent(script.url, callback);
		} else {
			callback();
		}
	});
};

Echo.createPlugin = function(config) {
	if (!config || !config.name || !config.init || !config.applications) return {};
	var name = config.name;
	var configuration = function() {
		var config = function(key) {
			return "plugins." + name + (key ? "." + key : "");
		};
		config.get = function(component, key, defaults, askParent) {
			return component.config.get(
				config(key),
				askParent ? component.config.get(key, defaults) : defaults
			);
		};
		config.set = function(component, key, value) {
			component.config.set(config(key), value);
		};
		config.remove = function(component, key) {
			component.config.remove(config(key));
		};
		return config;
	};
	var init = config.init || function() {};
	Echo.Plugins[name] = Echo.Plugins[name] || $.extend(config, {
		"init": function(plugin, application) {
			var enabled = plugin.config.get(application, "enabled");
			if (typeof enabled == "undefined") {
				plugin.config.set(application, "enabled", true);
			}
			init(plugin, application);
		},
		"set": function(component, key, value) {
			component.vars = component.vars || {};
			component.vars[name] = component.vars[name] || {};
			$.setNestedValue(component.vars[name], key, value);
		},
		"get": function(component, key) {
			var data = (component.vars || {})[name] || {};
			if (!key) return data;
			return $.getNestedValue(key, data);
		},
		"addCss": function(text) {
			$.addCss(text, "plugins-" + name);
		},
		"label": function(key, data) {
			return Echo.Localization.label(key, "Plugins." + name, data);
		},
		"addLabels": function(data) {
			Echo.Localization.extend(data, "Plugins." + name);
		},
		"topic": function(prefix, action) {
			var namespace = typeof prefix == "string" ? prefix : prefix.namespace;
			return namespace + ".Plugins." + name + "." + action;
		},
		"config": configuration(),
		"subscribe": function(application, topic, handler) {
			var self = this;
			return application.subscribe(topic, function() {
				if (!application.isPluginEnabled(self.name)) return;
				handler.apply(this, arguments);
			});
		},
		"publish": function(application, topic, data) {
			application.publish(topic, data);
		},
		"unsubscribe": function(application, topic, handlerId) {
			application.unsubscribe(topic, handlerId)
		},
		"extendRenderer": function(component, method, renderer) {
			Echo.extendRenderer(component, method, renderer, name);
		},
		"extendTemplate": function(component, html, action, anchor) {
			Echo.extendTemplate(component, html, action, anchor, name);
		},
		"addItemControl": function(application, control) {
			var controls = application.config.get("itemControls." + name, []);
			application.config.set("itemControls." + name, controls.concat(control));
		},
		"assembleConfig": function(component, data) {
			data.user = component.user;
			data.appkey = component.config.get("appkey", "");
			data.plugins = this.config.get(component, "nestedPlugins", []);
			data.contextId = component.config.get("contextId");
			data.apiBaseURL = component.config.get("apiBaseURL");
			return (new Echo.Config(data, this.config.get(component))).getAsHash();
		}
	});
	return Echo.Plugins[name];
};





if (!Echo.Broadcast) Echo.Broadcast = {};

Echo.Broadcast.initContext = function(topic, contextId) {
	contextId = contextId || 'empty';
	Echo.Vars.subscriptions = Echo.Vars.subscriptions || {};
	Echo.Vars.subscriptions[contextId] = Echo.Vars.subscriptions[contextId] || {};
	Echo.Vars.subscriptions[contextId][topic] = Echo.Vars.subscriptions[contextId][topic] || {};
	return contextId;
};

Echo.Broadcast.subscribe = function(topic, handler, contextId) {
	var handlerId = (new Date()).valueOf() + Math.random();
	contextId = Echo.Broadcast.initContext(topic, contextId);
	Echo.Vars.subscriptions[contextId][topic][handlerId] = handler;
	return handlerId;
};

Echo.Broadcast.unsubscribe = function(topic, handlerId, contextId) {
	contextId = Echo.Broadcast.initContext(topic, contextId);
	if (topic && handlerId) {
		delete Echo.Vars.subscriptions[contextId][topic][handlerId];
	} else if (topic) {
		delete Echo.Vars.subscriptions[contextId][topic];
	}
};

Echo.Broadcast.publish = function(topic, data, contextId) {
	contextId = Echo.Broadcast.initContext(topic, contextId);
	if (contextId == '*') {
		$.each(Echo.Vars.subscriptions, function(ctxId) {
			$.each(Echo.Vars.subscriptions[ctxId][topic] || {}, function(handlerId, handler) {
				handler.apply(this, [topic, data]);
			});
		});
	} else {
		if (Echo.Vars.subscriptions[contextId][topic]) {
			$.each(Echo.Vars.subscriptions[contextId][topic], function(handlerId, handler) {
				handler.apply(this, [topic, data]);
			});
		}
		if (contextId != 'empty') Echo.Broadcast.publish(topic, data, 'empty');
	}
};





if (!Echo.Object) Echo.Object = function() {};

Echo.Object.prototype.init = function(data) {
	$.extend(this, data || {});
};

Echo.Object.prototype.template = "";

Echo.Object.prototype.namespace = "";

Echo.Object.prototype.cssPrefix = "echo-";

Echo.Object.prototype.substitute = function(template, data) {
	var self = this;
	template = template.replace(Echo.Vars.regexps.matchLabel, function($0, $1) {
		return self.label($1);
	});
	template = template.replace(Echo.Vars.regexps.matchData, function($0, $1) {
		return $.getNestedValue($1, data, '');
	});
	return template;
};

Echo.Object.prototype.renderers = {};

Echo.Object.prototype.label = function(name, data) {
	var label = Echo.Localization.label(name, this.namespace, data);
	return label != name ? label : Echo.Localization.label(name, "", data);
};

Echo.Object.prototype.render = function(name, element, dom, extra) {
	var self = this;
	if (name) {
		if ($.isFunction(this.renderers[name])) {
			return this.renderers[name].call(this, element, dom, extra);
		}
	} else {
		var template = $.isFunction(this.template) ? this.template() : this.template;
		this.dom = $.toDOM(this.substitute(template, this.data || {}), this.cssPrefix, function() {
			return self.render.apply(self, arguments);
		});
		return this.dom.content;
	}
};

Echo.Object.prototype.rerender = function(name, recursive) {
	var self = this;
	if (!name) {
		if (this.dom) this.dom.content.replaceWith(this.render());
		return;
	}
	if (!this.dom) return;
	if (typeof name != "string") {
		$.map(name, function(element) {
			self.rerender(element, recursive);
		});
		return;
	} else if (!this.dom.get(name)) return;
	if (recursive) {
		var template = $.isFunction(this.template) ? this.template() : this.template;
		var html = this.substitute(template, this.data || {});
		var oldNode = this.dom.get(name);
		var newNode = $('.' + this.cssPrefix + name, $(html));
		newNode = $.toDOM(newNode, this.cssPrefix, function(name, element, dom) {
			self.dom.set(name, element);
			return self.render.apply(self, arguments);
		}).content;
		oldNode.replaceWith(newNode);
	} else {
		var element = this.dom.get(name);
		var node = this.renderers[name].call(this, element, this.dom);
		if (typeof node != "undefined") element.empty().append(node);
	}
};

Echo.Object.prototype.hyperlink = function(data, options) {
	options = options || {};
	if (options.openInNewWindow && !data.target) {
		data.target = '_blank';	
	}
	var caption = data.caption || "";
	delete data.caption;
	if (!options.skipEscaping) {
		data.href = $.htmlize(data.href);
	}
	data.href = data.href || "javascript:void(0)";
	var attributes = $.foldl([], data, function(value, acc, key) {
		acc.push(key + '="' + value + '"');
	});
	return "<a " + attributes.join(" ") + ">" + caption + "</a>";
};

Echo.Object.prototype.newContextId = function() {
	return (new Date()).valueOf() + Math.random();
};

Echo.Object.prototype.getContextId = function() {
	return this.config && this.config.get("contextId");
};

Echo.Object.prototype.subscribe = function(topic, handler) {
	return Echo.Broadcast.subscribe(topic, handler, this.getContextId());
};

Echo.Object.prototype.unsubscribe = function(topic, handlerId) {
	Echo.Broadcast.unsubscribe(topic, handlerId, this.getContextId());
};

Echo.Object.prototype.publish = function(topic, data) {
	Echo.Broadcast.publish(topic, data, this.getContextId());
};

Echo.Object.prototype.clearCache = function() {
	if (this.vars && this.vars.cache) this.vars.cache = {};
};





Echo.Application = function() {
	this.addCss();
};

Echo.Application.prototype = new Echo.Object();

Echo.Application.prototype.errorMessages = {
	"error_busy": "Loading. Please wait...",
	"error_timeout": "Loading. Please wait...",
	"error_waiting": "Loading. Please wait...",
	"error_result_too_large": "(result_too_large) The search result is too large.",
	"error_wrong_query": "(wrong_query) Incorrect or missing query parameter.",
	"error_incorrect_appkey": "(incorrect_appkey) Incorrect or missing appkey.",
	"error_internal_error": "(internal_error) Unknown server error.",
	"error_quota_exceeded": "(quota_exceeded) Required more quota than is available.",
	"error_incorrect_user_id": "(incorrect_user_id) Incorrect user specified in User ID predicate.",
	"error_unknown": "(unknown) Unknown error."
};

Echo.Application.prototype.initApplication = function(callback) {
	var self = this;
	var appkey = this.config.get("appkey");
	if (!appkey) {
		this.showMessage({
			"type": "error",
			"message": "Incorrect or missing mandatory parameter appkey"
		});
		return;
	}
	this.config.get("target").addClass("echo-ui");
	this.user = this.config.get("user") || new Echo.User({
		"appkey": appkey,
		"apiBaseURL": this.config.get("apiBaseURL"),
		"contextId": this.config.get("contextId")
	});
	this.user.init(function() {
		self.initPlugins(callback);
	});
	Echo.Localization.extend(this.errorMessages);
};

Echo.Application.prototype.messageTemplates = {
	'compact':
		'<span class="echo-application-message-icon echo-application-message-{Data:type}" title="{Data:message}">' +
		'</span>',
	'default':
		'<div class="echo-application-message">' +
			'<span class="echo-application-message-icon echo-application-message-{Data:type} echo-primaryFont">' +
				'{Data:message}' +
			'</span>' +
		'</div>'
};

Echo.Application.prototype.showMessage = function(data, target) {
	if (!this.config.get("debug") && data.type == "error") return;
	var template = this.messageTemplates[data.layout || this.messageLayout || "default"];
	(target || this.config.get("target")).empty().append(this.substitute(template, data));
};

Echo.Application.prototype.isWaitingForData = function(data) {
	return data && (data.errorCode == "waiting" || data.errorCode == "timeout" || data.errorCode == "busy");
};

Echo.Application.prototype.handleErrorResponse = function(data, config) {
	var self = this;
	config = config || {};
	var target = this.config.get("target");
	var calcWaitingTimeout = function() {
		// interval is calculated as e^x, x=[1..4]
		if (self.waitingTimeoutStep > 0) {
			if (self.waitingTimeoutStep < 4) {
				self.waitingTimeoutStep++;
			}
		} else {
			self.waitingTimeoutStep = 1;
		}
		return Math.round(Math.exp(self.waitingTimeoutStep)) * 1000;
	};

	if (this.error != data) {
		if (!this.config.get("debug")) {
			target.hide();
		} else {
			var label = this.label("error_" + data.errorCode);
			var message = label == "error_" + data.errorCode ? "(" + data.errorCode + ") " + (data.errorMessage || "") : label;
			target.show();
			this.showMessage({
				"type": this.isWaitingForData(data) ? "loading" : "error",
				"message": message
			}, config.messageTarget);
		}
	}
	this.error = data;
	if (this.isWaitingForData(data)) {
		this.waitingTimer = setTimeout(function() {
			self.cleanupErrorHandlers();
			if (config.waitingHandler) {
				config.waitingHandler();
			} else {
				self.refresh();
			}
		}, calcWaitingTimeout());
	} else {
		this.waitingTimeoutStep = 0;
	}
	if (config.callback) config.callback(data);
};

Echo.Application.prototype.cleanupErrorHandlers = function(successResponseReceived) {
	if (successResponseReceived) {
		this.waitingTimeoutStep = 0;
		delete this.error;
	}
	if (this.waitingTimer) {
		clearTimeout(this.waitingTimer);
	}
};

Echo.Application.prototype.initPlugins = function(callback) {
	var self = this;
	var plugins = this.config.get("pluginsOrder");
	var scripts = $.foldl([], plugins, function(name, acc) {
		var plugin = Echo.Plugins[name];
		if (plugin && plugin.dependencies && plugin.dependencies.length) {
			return acc.concat(plugin.dependencies);
		}
	});
	Echo.include(scripts, function() {
		$.map(plugins, function(name) {
			var plugin = Echo.Plugins[name];
			if (plugin && plugin.init && self.isPluginApplicable(plugin)) {
				plugin.init(plugin, self);
			}
		});
		if (callback) callback();
	});
};

Echo.Application.prototype.enablePlugin = function(name) {
	this.config.set("plugins." + name + ".enabled", true);
};

Echo.Application.prototype.disablePlugin = function(name) {
	this.config.set("plugins." + name + ".enabled", false);
};

Echo.Application.prototype.isPluginEnabled = function(name) {
	return this.config.get("plugins." + name + ".enabled", true);
};

Echo.Application.prototype.isPluginApplicable = function(plugin) {
	var self = this, applicable = false;
	$.each(plugin.applications, function(i, application) {
		if (Echo[application] && self instanceof Echo[application]) {
			applicable = true;
			return false; // break
		}
	});
	return applicable;
};

Echo.Application.prototype.initConfig = function(data, defaults, normalizer) {
	var _normalizer = {};
	_normalizer.target = function(el) { return $(el); };
	_normalizer.plugins = function(list) {
		var data = $.foldl({"hash": {}, "order": []}, list || [],
			function(plugin, acc) {
				var pos = $.inArray(plugin.name, acc.order);
				if (pos >= 0) {
					acc.order.splice(pos, 1);
				}
				acc.order.push(plugin.name);
				acc.hash[plugin.name] = plugin;
			});
		this.set("pluginsOrder", data.order);
		return data.hash;
	};
	data = $.extend({
		"plugins": []
	}, data || {});
	defaults = $.extend({
		"appkey": "",
		"apiBaseURL": "http://api.echoenabled.com",
		"liveUpdates": true,
		"liveUpdatesTimeout": 10,
		"liveUpdatesTimeoutMin": 3,
		"debug": true,
		"contextId": this.newContextId()
	}, defaults || {});
	this.config = new Echo.Config(data, defaults, function(key, value) {
		var handler = normalizer && normalizer[key] || _normalizer && _normalizer[key];
		return handler ? handler.call(this, value) : value;
	});
};

Echo.Application.prototype.sendAPIRequest = function(data, callback) {
	data.query.appkey = this.config.get("appkey");
	$.get(this.config.get("apiBaseURL") + "/v1/" + data.endpoint,
		data.query, callback, "jsonp");
};

Echo.Application.prototype.initLiveUpdates = function(requestParamsGetter, responseHandler) {
	var self = this;
	this.liveUpdates = {
		"originalTimeout": this.config.get("liveUpdatesTimeout"),
		"timers": {},
		"timeouts": [],
		"responseHandler": function(data) {
			if (self.liveUpdates.timers.watchdog) {
				clearTimeout(self.liveUpdates.timers.watchdog);
			}
			self.changeLiveUpdatesTimeout(data);
			responseHandler(data);
		},
		"requestParamsGetter": requestParamsGetter
	};
};

Echo.Application.prototype.changeLiveUpdatesTimeout = function(data) {
	var self = this;
	// backwards compatibility
	if (typeof data == "string") {
		data = {"liveUpdatesTimeout": data};
	}
	data.liveUpdatesTimeout = parseInt(data.liveUpdatesTimeout);
	var applyServerDefinedTimeout = function(timeout) {
		if (!timeout && self.liveUpdates.originalTimeout != self.config.get("liveUpdatesTimeout")) {
			self.config.set("liveUpdatesTimeout", self.liveUpdates.originalTimeout);
		} else if (timeout && timeout > self.config.get("liveUpdatesTimeout")) {
			self.config.set("liveUpdatesTimeout", timeout);
		}
	};
	var hasNewData = function(data) {
		// for "v1/search" endpoint at the moment
		return !!(data.entries && data.entries.length);
	};
	if (!this.nextSince) {
		applyServerDefinedTimeout(data.liveUpdatesTimeout);
		return;
	}
	var currentTimeout = this.config.get("liveUpdatesTimeout");
	var since = parseInt(this.nextSince);
	var currentTime = Math.floor((new Date()).getTime() / 1000);
	// calculate the delay before starting next request:
	//   - have new data but still behind and need to catch up - use minimum timeout
	//   - have new data but on the track - increase timeout by 1 second
	//   - have no new data - increase timeout by 2 seconds
	var timeout = hasNewData(data)
		? currentTime - since > currentTimeout
			? this.config.get("liveUpdatesTimeoutMin", 3)
			: currentTimeout + 1
		: currentTimeout + 2;
	if (timeout > this.liveUpdates.originalTimeout) {
		timeout = this.liveUpdates.originalTimeout;
	}
	this.config.set("liveUpdatesTimeout", timeout);
	// if timeout remains the same, take server side value into account
	if (timeout == this.liveUpdates.originalTimeout) {
		applyServerDefinedTimeout(data.liveUpdatesTimeout);
	}

};

Echo.Application.prototype.stopLiveUpdates = function() {
	if (this.liveUpdates.timers.regular) {
		clearTimeout(this.liveUpdates.timers.regular);
	}
	if (this.liveUpdates.timers.watchdog) {
		clearTimeout(this.liveUpdates.timers.watchdog);
	}
};

Echo.Application.prototype.startLiveUpdates = function(force) {
	var self = this;
	if (!this.liveUpdates || !force && !this.config.get("liveUpdates") && !this.liveUpdates.timeouts.length) return;
	this.stopLiveUpdates();
	if (force) {
		// if live updates requests were forced after some operation, we will
		// perform 3 attempts to get live updates: immediately, in 1 second
		// and in 3 seconds after first one
		this.liveUpdates.timeouts = [0, 1, 3];
	}
	var timeout = this.liveUpdates.timeouts.length
		? this.liveUpdates.timeouts.shift()
		: this.config.get("liveUpdatesTimeout");
	this.liveUpdates.timers.regular = setTimeout(function() {
		// if no response in the reasonable time just restart live updates
		self.liveUpdates.timers.watchdog = setTimeout(function() {
			self.startLiveUpdates();
		}, 5000);
		self.sendAPIRequest(
			self.liveUpdates.requestParamsGetter(),
			self.liveUpdates.responseHandler);
	}, timeout * 1000);
};

Echo.Application.prototype.addCss = function() {
	var id = 'echo-css-fancybox';
	if ($('#' + id).length) return;
	var container = document.getElementsByTagName("head")[0] || document.documentElement;
	// using insertBefore DOM method instead of jquery
	// because in jquery >= 1.5 link element inserted incorrectly in IE 7-8
	container
		.insertBefore($("<link>", {
			"rel": "stylesheet",
			"id": id,
			"type": "text/css",
			"href": "//c0.echoenabled.com/css/fancybox.css"
		}).get(0), $(container).children().get(0));
	$.addCss(
		'.echo-application-message { padding: 15px 0px; text-align: center; -moz-border-radius: 0.5em; -webkit-border-radius: 0.5em; border: 1px solid #E4E4E4; }' +
		'.echo-application-message-icon { display: inline-block; height: 16px; padding-left: 16px; background: no-repeat left center; }' +
		'.echo-application-message .echo-application-message-icon { padding-left: 21px; height: auto; }' +
		'.echo-application-message-empty { background-image: url(//c0.echoenabled.com/images/information.png); }' +
		'.echo-application-message-loading { background-image: url(//c0.echoenabled.com/images/loading.gif); }' +
		'.echo-application-message-error { background-image: url(//c0.echoenabled.com/images/warning.gif); }'
	, 'application');
};





Echo.User = function(config) {
	this.data = {};
	this.config = new Echo.Config(config, {
		"appkey": "",
		"apiBaseURL": "http://api.echoenabled.com",
		"contextId": undefined
	});
};

Echo.User.prototype.init = function(callback) {
	var self = this;
	this.callback = callback || function() {};
	if (!this.config.get("appkey") || !window.Backplane || !Backplane.getChannelID()) {
		this.set({});
		this.callback();
		return;
	}
	this.listenEvents();
	var state = this._global("get", "state");
	if (state == "ready") {
		this.set($.extend({}, this._global("get", "data")));
		this.callback();
	} else {
		var handlerId = Echo.Broadcast.subscribe("User.onInit", function(topic, data) {
			if (data.appkey != self.config.get("appkey")) return;
			Echo.Broadcast.unsubscribe("User.onInit", handlerId);
			self.set($.extend({}, self._global("get", "data")));
			self.callback();
		});
		if (state == "init") {
			this.request();
		}
	}
}

Echo.User.prototype.listenEvents = function() {
	var self = this;
	if (this.backplaneSubscriptionID) return;
	var publish = function(global) {
		var topic = (global ? "" : "internal.") + "User.onInvalidate";
		var data = {
			"data": self.data,
			"appkey": self.config.get("appkey")
		};
		var contextId = global ? undefined : self.config.get("contextId");
		Echo.Broadcast.publish(topic, data, contextId);
	};
	this.backplaneSubscriptionID = Backplane.subscribe(function(message) {
		if (message.type == "identity/ack") {
			var global = false;
			if (self._global("get", "state") == "ready") {
				global = true;
				self._global("set", "state", "init");
			};
			self.init(function() {
				publish();
				if (global) publish(true);
			});
		}
	});
};

Echo.User.prototype._global = function(action, key, value) {
	var appkey = this.config.get("appkey");
	Echo.Vars.users = Echo.Vars.users || {};
	Echo.Vars.users[appkey] = Echo.Vars.users[appkey] || {"state": "init", "data": {}};
	if (action == "get") {
		return Echo.Vars.users[appkey][key];
	}
	Echo.Vars.users[appkey][key] = value;
};

Echo.User.prototype.set = function() {
	if (!arguments.length) return;
	//checking for object type of argument and apply changes globally
	if (arguments.length == 1 && typeof arguments[0] == "object") {
		this._global("set", "data", arguments[0]);
		this.data = this.normalize(arguments[0]);
		this.account = this.assemble();
	//checking for key-value arguments and apply changes for this instance only
	} else if (arguments.length == 2 && typeof arguments[0] == "string") {
		this.account[arguments[0]] = arguments[1];
	}
};

Echo.User.prototype.get = function(key, defaults) {
	return (this.account.hasOwnProperty(key) && typeof this.account[key] != "undefined")
		? this.account[key]
		: defaults;
};

Echo.User.prototype.logout = function(callback) {
	var self = this;
	$.get(window.location.protocol + "//apps.echoenabled.com/v2/logout", {
		"sessionID": Backplane.getChannelID()
	}, function(data) {
		Backplane.expectMessages("identity/ack");
	}, "jsonp");
};

Echo.User.prototype.request = function(callback) {
	var self = this, appkey = this.config.get("appkey");
	this._global("set", "state", "waiting");
	$.get(this.config.get("apiBaseURL") + "/v1/users/whoami", {
		"appkey": appkey,
		"sessionID": Backplane.getChannelID()
	}, function(data) {
		if (data.result && data.result == "session_not_found") {
			data = {};
		}
		self._global("set", "state", "ready");
		self.set($.extend({}, data));
		Echo.Broadcast.publish("User.onInit", {"data": data, "appkey": appkey});
		if (callback) callback();
	}, "jsonp");
};

Echo.User.prototype.normalize = function(data) {
	var array2object = function(list) {
		return $.foldl({}, list || [], function(key, acc) { acc[key] = true; });
	};
	data = data || {};
	data.echo = data.echo || {};
	$.extend(data, data.echo);
	data.poco = data.poco || {"entry": {}};
	data.roles = array2object(data.echo.roles);
	data.markers = array2object(data.echo.markers);
	data.sessionID = window.Backplane && Backplane.getChannelID() || undefined;
	data.accounts = data.poco.entry.accounts || [];
	return data;
};

Echo.User.prototype.getActiveAccounts = function() {
	return $.map(this.data.accounts, function(entry) {
		if (entry.loggedIn == "true") return entry;
	});
};

Echo.User.prototype.assemble = function() {
	var accounts = this.getActiveAccounts();
	var account = accounts[0] || {};
	return $.extend(this.data, {
		"id": account.identityUrl || this.data.poco.entry.id || account.userid,
		"name": this.data.poco.entry.displayName || account.username,
		"avatar": $.foldl(undefined, account.photos || [], function(img) {
			if (img.type == "avatar") return img.value;
		}),
		"state": this.data.echo.state || "Untouched",
		"domain": account.domain,
		"logged": !!accounts.length,
		"defaultAvatar": "//c0.echoenabled.com/images/avatar-default.png",
		"fakeIdentityURL": "http://js-kit.com/ECHO/user/fake_user"
	});
};

Echo.User.prototype.hasIdentity = function(id) {
	var hasIdentity = false;
	$.each(this.data.accounts, function(i, account) {
		if (account.identityUrl && account.identityUrl == id) {
			hasIdentity = true;
			return false; // break
		}
	});
	return hasIdentity;
};

Echo.User.prototype.hasAny = function(field, values) {
	if (!this.account) return false;
	var self = this, satisfies = false;
	$.each(values, function(i, value) {
		var data = self.get(field, {});
		if ((typeof data == "string" && data == value) || data[value]) {
			satisfies = true;
			return false; // break
		}
	});
	return satisfies;
};

Echo.User.prototype.hasAnyRole = function(roles) {
	return this.hasAny("roles", roles);
};

Echo.User.prototype.isAdmin = function() {
	return this.hasAny("roles", ["administrator", "moderator"]);
};

Echo.User.prototype.logged = function() {
	return !!(this.account && this.account.logged);
};





Echo.Config = function(master, slave, normalizer) {
	var self = this;
	this.normalize = normalizer || function(key, value) { return value; };
	this.data = {};
	this.cache = {};
	if (!slave && !normalizer) {
		this.data = master;
	} else {
		$.each(this.combine(master, $.extend({}, slave)), function(key, value) {
			self.set(key, value);
		});
	}
};

Echo.Config.prototype.get = function(key, defaults) {
	var k = key;
	if (typeof k != "string") {
		k = k.join(".");
	}
	if (!this.cache.hasOwnProperty(k)) {
		this.cache[k] = $.getNestedValue(key, this.data);
	}
	return typeof this.cache[k] == "undefined" ? defaults : this.cache[k];
};

Echo.Config.prototype.set = function(key, value) {
	var keys = key.split(/\./);
	delete this.cache[key];
	if (typeof value == "object") {
		this.clearCacheByPrefix(key);
	}
	return $.setNestedValue(this.data, key, this.normalize(keys.pop(), value));
};

Echo.Config.prototype.remove = function(key) {
	var keys = key.split(/\./);
	var field = keys.pop();
	var data = $.getNestedValue(keys, this.data);
	delete data[field];
};

Echo.Config.prototype.combine = function(master, slave) {
	var self = this;
	return $.foldl(slave, master, function(value, acc, key) {
		acc[key] = $.isPlainObject(value) && slave.hasOwnProperty(key)
			? self.combine(value, slave[key])
			: value;
	});
};

Echo.Config.prototype.extend = function(extra) {
	var self = this;
	$.each(extra, function(key, value) {
		self.set(key, value);
	});
};

Echo.Config.prototype.getAsHash = function() {
	return this.data;
};

Echo.Config.prototype.clearCacheByPrefix = function(prefix) {
	var self = this;
	prefix += ".";
	$.each(this.cache, function(key, data) {
		// key starts with prefix
		if (!key.indexOf(prefix)) {
			delete self.cache[key];
		}
	});
};





if (!Echo.UI) Echo.UI = {
	cornersCss: function(radius, scopeClass) {
		return ('{scope}.ui-corner-tl { -moz-border-radius-topleft: {radius}; -webkit-border-top-left-radius: {radius}; border-top-left-radius: {radius}; }' +
		'{scope}.ui-corner-tr { -moz-border-radius-topright: {radius}; -webkit-border-top-right-radius: {radius}; border-top-right-radius: {radius}; }' +
		'{scope}.ui-corner-bl { -moz-border-radius-bottomleft: {radius}; -webkit-border-bottom-left-radius: {radius}; border-bottom-left-radius: {radius}; }' +
		'{scope}.ui-corner-br { -moz-border-radius-bottomright: {radius}; -webkit-border-bottom-right-radius: {radius}-bottom-right-radius: {radius}; }' +
		'{scope}.ui-corner-top { -moz-border-radius-topleft: {radius}; -webkit-border-top-left-radius: {radius}; border-top-left-radius: {radius}; -moz-border-radius-topright: {radius}; -webkit-border-top-right-radius: {radius}; border-top-right-radius: {radius}; }' +
		'{scope}.ui-corner-bottom { -moz-border-radius-bottomleft: {radius}; -webkit-border-bottom-left-radius: {radius}; border-bottom-left-radius: {radius}; -moz-border-radius-bottomright: {radius}; -webkit-border-bottom-right-radius: {radius}; border-bottom-right-radius: {radius}; }' +
		'{scope}.ui-corner-right {  -moz-border-radius-topright: {radius}; -webkit-border-top-right-radius: {radius}; border-top-right-radius: {radius}; -moz-border-radius-bottomright: {radius}; -webkit-border-bottom-right-radius: {radius}; border-bottom-right-radius: {radius}; }' +
		'{scope}.ui-corner-left { -moz-border-radius-topleft: {radius}; -webkit-border-top-left-radius: {radius}; border-top-left-radius: {radius}; -moz-border-radius-bottomleft: {radius}; -webkit-border-bottom-left-radius: {radius}; border-bottom-left-radius: {radius}; }' +
		'{scope}.ui-corner-all { -moz-border-radius: {radius}; -webkit-border-radius: {radius}; border-radius: {radius}; }').replace(/{scope}/g, scopeClass || "").replace(/{radius}/g, radius);
	}
};

(function() {
	$.addCss(
		'.echo-ui { text-align: left; }' +
		'.echo-ui .ui-helper-hidden { display: none; }' +
		'.echo-ui .ui-helper-hidden-accessible { position: absolute; left: -99999999px; }' +
		'.echo-ui .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }' +
		'.echo-ui .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }' +
		'.echo-ui .ui-helper-clearfix { display: inline-block; }' +
		'/* required comment for clearfix to work in Opera \\*/' +
		'* html .echo-ui .ui-helper-clearfix { height:1%; }' +
		'.echo-ui .ui-helper-clearfix { display:block; }' +
		'/* end clearfix */' +
		'.echo-ui .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }' +
		'.echo-ui .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}' +
		'.echo-ui .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }' +
		'.echo-ui .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }' +
		'.echo-ui .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }' +
		'.echo-ui .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }' +
		'.echo-ui .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }' +
		'.echo-ui .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }' +
		'.echo-ui .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }' +
		'.echo-ui .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }' +
		'.echo-ui .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}' +
		'.echo-ui .ui-state-disabled { cursor: default !important; }' +
		'.echo-ui .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; width: 16px; height: 16px; }' +
		'.echo-ui .ui-widget-header { font-weight: bold; border: 0px; }' +
		'.echo-ui, .echo-ui .ui-widget :active { outline: none; }' +
		'.echo-ui .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6; color: #555555; }' +
		'.echo-ui .ui-state-default a, .echo-ui .ui-state-default a:link, .echo-ui .ui-state-default a:visited { color: #555555; text-decoration: none; }' +
		'.echo-ui .ui-state-hover, .echo-ui .ui-state-focus { border: 1px solid #999999; background: #dfebf2; color: #212121; }' +
		'.echo-ui .ui-state-hover a, .echo-ui .ui-state-hover a:hover { color: #212121; text-decoration: none; }' +
		'.echo-ui .ui-state-active { border: 1px solid #aaaaaa; background: #dfebf2; color: #212121; }' +
		'.echo-ui .ui-state-active a, .echo-ui .ui-state-active a:link, .echo-ui .ui-state-active a:visited { color: #212121; text-decoration: none; }' +

		'.echo-primaryBackgroundColor {  }' +
		'.echo-secondaryBackgroundColor { background-color: #F4F4F4; }' +
		'.echo-trinaryBackgroundColor { background-color: #ECEFF5; }' +
		'.echo-primaryColor { color: #3A3A3A; }' +
		'.echo-secondaryColor { color: #C6C6C6; }' +
		'.echo-primaryFont { font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; line-height: 16px; }' +
		'.echo-secondaryFont { font-family: Arial, sans-serif; font-size: 11px; }' +
		'.echo-linkColor, .echo-linkColor a { color: #476CB8; }' +
		'.echo-clickable { cursor: pointer; }' +
		'.echo-relative { position: relative; }' +
		'.echo-clear { clear: both; }'
	, 'ui-general');
})();





Echo.UI.Dialog = function(data) {
	data.config = data.config || {};
	this.init(data);
	this.config.dialogClass = 'echo-ui echo-dialog ' + (this.config.dialogClass || '');
	this.addCss();
	this.contentElement = this.render().dialog(this.config).addClass('ui-corner-all');
	if (this.content) {
		if ($.isFunction(this.content)) {
			this.content(this.contentElement);
		} else {
			this.contentElement.append(this.content);
		}
	}
	this.widget = this.contentElement.dialog('widget');
	if (this.hasTabs) {
		// move tabs line to dialog header to prevent tabs scrolling
		$('.ui-dialog-titlebar', this.widget).after($('.echo-tabs-header', this.widget));
	}
};

Echo.UI.Dialog.prototype = new Echo.Object();

Echo.UI.Dialog.prototype.cssPrefix = "echo-dialog-";

Echo.UI.Dialog.prototype.template = "<div></div>";

Echo.UI.Dialog.prototype.open = function() {
	// hide contentElement for jquery to calculate dialog height correctly in IE
	this.contentElement.hide();
	this.contentElement.dialog('open');
	this.contentElement.show();
};

Echo.UI.Dialog.prototype.close = function() {
	this.contentElement.dialog('close');
};

Echo.UI.Dialog.prototype.addCss = function() {
	$.addCss(
		'.echo-dialog { position: absolute; padding: 0px 7px 20px 7px; width: 300px; border: 1px solid #aaaaaa; background: #dfebf2; -moz-border-radius: 7px; -webkit-border-radius: 7px; border-radius: 7px;' + (!$.browser.msie ? ' overflow: hidden;' : '') + ' }' +
		'.echo-dialog .ui-dialog-titlebar { background: #dfebf2; cursor: move; padding: 7px 0px 10px 5px; position: relative; color: #4a4a4a; font: 18px Helvetica,sans-serif; }' +
		'.echo-dialog .ui-dialog-titlebar .ui-state-default, .echo-dialog .ui-dialog-titlebar .ui-state-active, .echo-dialog .ui-dialog-titlebar .ui-state-hover, .echo-dialog .ui-dialog-titlebar .ui-state-focus { border: 0px; background: none; }' +
		'.echo-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } ' +
		'.echo-dialog .ui-dialog-titlebar-close { position: absolute; right: 0px; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 0px; height: 18px; }' +
		'.echo-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }' +
		'.echo-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0px; }' +
		'.echo-dialog .ui-dialog-content { border: 0; padding: 0px; margin: 0px; background: #ffffff; overflow: auto; }' +
		'.echo-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }' +
		'.echo-dialog .ui-icon-closethick { background: no-repeat top right url(//c0.echoenabled.com/images/container/closeWindow.png); }' +
		'.echo-dialog .ui-icon-grip-diagonal-se { background: no-repeat bottom right url(//c0.echoenabled.com/images/container/resizeHandle.png); }' +
		Echo.UI.cornersCss('7px', '.echo-dialog ')
	, 'ui-dialog');
	if ($.browser.msie) {
		$.addCss('.echo-dialog .ui-dialog-content { zoom: 1; position: relative; }', 'ui-dialog-ie');
	}
};





Echo.UI.Tabs = function(data) {
	var self = this;
	data.config = data.config || {};
	this.init(data);
	if (!this.tabs) return;
	var classPrefix = this.idPrefix;
	// add random part to get unique id
	this.idPrefix = this.idPrefix + Math.ceil(Math.random() * 999999999) + '-';
	this.addCss();
	var disabledTabs = $.foldl([], this.tabs, function(tab, acc, i) {
		tab.classPrefix = classPrefix;
		tab.idPrefix = self.idPrefix;
		if (tab.icon) {
			tab.label = '<span>' + tab.label + '</span>';
		}
		if (tab.disabled) {
			acc.push(i);
		}
	});
	this.target.append(this.render());
	this.tabIndexById = {};
	$.each(this.tabs, function(i, tab) {
		self.tabIndexById[tab.id] = i;
		if (tab.content) {
			var tgt = $('#' + tab.idPrefix + tab.id);
			if ($.isFunction(tab.content)) {
				tab.content(tgt);
			} else {
				tgt.append(tab.content);
			}
		}
	});
	// if tabs will be placed into another UI element (dialog, another tabs) better not to add another echo-ui class
	if (this.addUIClass !== false) {
		this.target.addClass('echo-ui');
	}
	$.extend(this.config, {
		"disabled": disabledTabs.concat(self.config.disabled || []),
		"select": function(event, ui) {
			self.content[ui.index ? 'addClass' : 'removeClass']('ui-corner-tl');
		}
	});
	this.headerElement = $('.echo-tabs-header', this.target).tabs(this.config);
	this.panelsElement = $('.echo-tabs-panels', this.target).tabs(this.config);
	$('.echo-tabs-header, .echo-tabs-header .ui-tabs-nav', this.target).removeClass('ui-corner-all');
	this.content = $(this.content || '.echo-tabs-panels', this.target);
	// top right corner of content panel should not be rounded while first tab is selected
	this.content.removeClass('ui-corner-all').addClass('ui-corner-tr ui-corner-bottom');
};

Echo.UI.Tabs.prototype = new Echo.Object();

Echo.UI.Tabs.prototype.cssPrefix = "echo-tabs-";

Echo.UI.Tabs.prototype.template = function() {
	var self = this;
	return '<div class="echo-tabs">' +
		'<div class="echo-tabs echo-tabs-header">' +
			'<ul>' +
				$.map(this.tabs, function(tab) {
					return self.substitute('<li><a class="echo-{Data:classPrefix}{Data:id}" href="#{Data:idPrefix}{Data:id}">{Data:label}</a></li>', tab);
				}).join("\n") +
			'</ul>' +
		'</div>' +
		'<div class="echo-tabs echo-tabs-panels"></div>' +
	'</div>';
};

Echo.UI.Tabs.prototype.renderers = {};

Echo.UI.Tabs.prototype.renderers.panels = function(element) {
	var self = this;
	$.each(this.tabs, function(i, tab) {
		var node = $.toDOM(self.substitute('<div id="{Data:idPrefix}{Data:id}" class="{Data:idPrefix}{Data:id}"></div>', tab));
		element.append(node.content);
	});
};

Echo.UI.Tabs.prototype.select = function(id) {
	this.headerElement.tabs('select', this.tabIndexById[id]);
}

Echo.UI.Tabs.prototype.addCss = function() {
	$.addCss(
		'.echo-ui .ui-tabs { position: relative; padding: 0px; border: 0px; }' +
		'.echo-tabs .echo-tabs-panels { background: #ffffff; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav { margin: 0; padding: 0px; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li a { float: left; padding: .3em .7em; text-decoration: none; font-size: 12px; font-family: Helvetica,sans-serif; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .echo-ui .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .echo-ui .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; color: #4a4a4a; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li a, .echo-ui .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; color: #393939; }' +
		'.echo-ui .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }' +
		'.echo-ui .ui-tabs .ui-tabs-hide { display: none !important; }' +
		'.echo-ui .echo-tabs-header .ui-state-hover, .echo-ui .echo-tabs-header .ui-state-focus { border: 0px; background: none; color: #212121; }' +
		'.echo-ui .echo-tabs-header .ui-state-default { border: 0px; background: none; font-weight: normal; }' +
		'.echo-ui .echo-tabs-header .ui-state-active { border: 0px; background: #ffffff; font-weight: bold; }' +
		'.echo-ui .ui-tabs .ui-tabs-nav li a span { display: inline-block; padding-left: 22px; }' +
		($.browser.opera ? '.echo-ui .ui-tabs-nav { height: 25px; overflow: hidden; }' : '') +
		Echo.UI.cornersCss('7px', '.echo-tabs ')
	, 'ui-tabs');
	if ($.browser.msie) {
		$.addCss('.echo-ui .ui-tabs { zoom:  1; position: static; }', 'ui-tabs-ie');
	}
};





Echo.UI.Button = function(element, states) {
	this.states = states || {};
	this.element = $(element);
	this.addCss();
	if (this.states.normal && !this.states.normal.label) {
		this.states.normal.label = $(element).html();
	}
	$(element).button(this.states.normal).wrap('<span class="echo-button"></span>');
	this.wrapper = $(element).parent();
};

Echo.UI.Button.prototype = new Echo.Object();

Echo.UI.Button.prototype.setState = function(name) {
	this.element.removeClass('ui-button-text-only ui-button-text-icons ui-button-text-icon');
	this.element.button('option', this.states[name]);
}

Echo.UI.Button.prototype.addCss = function() {
	$.addCss(
		'.echo-button .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; overflow: visible; }' +
		'.echo-button .ui-button-icon-only { width: 1.8em; }' +
		'.echo-button button.ui-button-icon-only { width: 2em; }' +
		'.echo-button .ui-button-icons-only { width: 3em; }' +
		'.echo-button button.ui-button-icons-only { width: 3.3em; }' +
		'.echo-button .ui-button .ui-button-text { display: block; }' +
		'.echo-button .ui-button-text-only .ui-button-text { padding: .4em .8em; }' +
		'.echo-button .ui-button-icon-only .ui-button-text, .echo-button .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }' +
		'.echo-button .ui-button-text-icon .ui-button-text, .echo-button .ui-button-text-icons .ui-button-text { padding: .4em .8em .4em 2.1em; }' +
		'.echo-button .ui-button-text-icons .ui-button-text { padding-left: 1.9em; padding-right: 1.9em; }' +
		'.echo-button input.ui-button { padding: .4em .8em; }' +
		'.echo-button .ui-button-icon-only .ui-icon, .echo-button .ui-button-text-icon .ui-icon, .echo-button .ui-button-text-icons .ui-icon, .echo-button .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }' +
		'.echo-button .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }' +
		'.echo-button .ui-button-text-icon .ui-button-icon-primary, .echo-button .ui-button-text-icons .ui-button-icon-primary, .echo-button .ui-button-icons-only .ui-button-icon-primary { left: .3em; }' +
		'.echo-button .ui-button-text-icons .ui-button-icon-secondary, .echo-button .ui-button-icons-only .ui-button-icon-secondary { right: .3em; }' +
		'.echo-button button.ui-button::-moz-focus-inner { border: 0; padding: 0; }' +
		'.echo-button .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6; color: #555555; }' +
		'.echo-button .ui-state-default a, .echo-ui .ui-state-default a:link, .echo-button .ui-state-default a:visited { color: #555555; text-decoration: none; }' +
		'.echo-button .ui-state-hover, .echo-button .ui-state-focus { border: 1px solid #999999; background: #dfebf2; color: #212121; }' +
		'.echo-button .ui-state-active { border: 1px solid #aaaaaa; background: #dfebf2; color: #212121; }' +
		Echo.UI.cornersCss('4px', '.echo-button button')
	, 'ui-buttons');
	if ($.browser.msie) {
		$.addCss('.echo-button .ui-button { zoom: 1; }', 'ui-buttons-ie'); 
	}

	$.addCss(
		'.echo-button .ui-icon-arrow-right { background: no-repeat center url(//c0.echoenabled.com/images/curation/button/apply_normal.png); }' +
		'.echo-button .ui-icon-save { margin-right: 5px; background: no-repeat center url(//c0.echoenabled.com/images/curation/button/save_normal.png); }' +
		'.echo-button .ui-icon-waiting { margin-right: 5px; background: no-repeat center url(//c0.echoenabled.com/images/loading.gif); }'
	, 'ui-buttons-icons');
};





if (!Echo.Localization) Echo.Localization = { labels: {} };

Echo.Localization.key = function(name, namespace) {
	return (namespace ? namespace + "." : "") + name;
};

Echo.Localization.extend = function(labels, namespace) {
	$.each(labels, function(name, value) {
		Echo.Localization.labels[Echo.Localization.key(name, namespace)] = value;
	});
};

Echo.Localization.label = function(name, namespace, data) {
	var label = Echo.Localization.labels[Echo.Localization.key(name, namespace)] || name;
	$.each(data || {}, function(key, value) {
		label = label.replace(new RegExp("{" + key + "}", "g"), value);
	});
	return label;
};


})(jQuery);



(function($) {
Echo.Localization.extend({
	"edit": "Edit",
	"loading": "Loading...",
	"login": "Login",
	"logout": "Logout",
	"loggingOut": "Logging out...",
	"or": "or",
	"signup": "signup"
}, "Auth");

Echo.Auth = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.initConfig(config);
	this.initApplication(function() {
		self.addCss();
		self.listenEvents();
		self.config.get("target").empty().append(self.render());
	});
};

Echo.Auth.prototype = new Echo.Application();

Echo.Auth.prototype.namespace = "Auth";

Echo.Auth.prototype.cssPrefix = "echo-auth-";

Echo.Auth.prototype.renderers = {};

Echo.Auth.prototype.template = function() {
	return this.templates[this.user.logged() ? "logged" : "anonymous"];
};

Echo.Auth.prototype.templates = {};

Echo.Auth.prototype.templates.anonymous =
	'<div class="echo-auth-anonymous echo-primaryFont">' +
		'<span class="echo-auth-login echo-linkColor echo-clickable">' +
			'{Label:login}' +
		'</span>' +
		'<span class="echo-auth-or echo-secondaryColor"> {Label:or} </span>' +
		'<span class="echo-auth-signup echo-linkColor echo-clickable">' +
			'{Label:signup}' +
		'</span>' +
	'</div>';

Echo.Auth.prototype.templates.logged =
	'<div class="echo-auth-logged echo-primaryFont echo-primaryColor">' +
		'<div class="echo-auth-avatar"></div>' +
		'<div class="echo-auth-name"></div>' +
		'<div class="echo-auth-edit echo-linkColor echo-clickable">' +
			'{Label:edit}' +
		'</div>' +
		'<div class="echo-auth-logout echo-linkColor echo-clickable">' +
			'{Label:logout}' +
		'</div>' +
		'<div class="echo-clear"></div>' +
	'</div>';

Echo.Auth.prototype.renderers.logout = function(element) { 
	var self = this;
	element.click(function() {
		element.empty().append(self.label("loggingOut"));
		self.user.logout();
	});
};

Echo.Auth.prototype.renderers.login = function(element) {
	this.assembleIdentityControl("login", element);
};

Echo.Auth.prototype.renderers.edit = function(element) {
	this.assembleIdentityControl("edit", element);
};

Echo.Auth.prototype.renderers.signup = function(element) {
	this.assembleIdentityControl("signup", element);
};

Echo.Auth.prototype.renderers.or = function(element) {
	if (!this.config.get("identityManager.login") ||
		!this.config.get("identityManager.signup") ||
		!this.user.get("sessionID")) {
			element.hide();
	}
};

Echo.Auth.prototype.renderers.avatar = function(element) {
	var self = this;
	var url = this.user.get("avatar", this.user.get("defaultAvatar"));
	element.append(
		$("<img>", { "src": url }).bind({
			"error" : function(){
				$(this).attr("src", self.user.get("defaultAvatar"));
			}
		}));
};

Echo.Auth.prototype.renderers.name = function(element) {
	element.append(this.user.get("name", ""));
};

Echo.Auth.prototype.assembleIdentityControl = function(type, element) {
	var self = this;
	var data = this.config.get("identityManager." + type);
	if (!data || !this.user.get("sessionID")) return element.hide();

	var appendSessionID = function(url) {
		var id = encodeURIComponent(self.user.get("sessionID", ""));
		var parts = $.parseUrl(url);
		var session = parts["query"]
			? parts["query"].match(/=$/) ? id : "&sessionID=" + id
			: "sessionID=" + id;
		return self.substitute("{Data:scheme}://{Data:domain}{Data:path}?{Data:query}{Data:fragment}", {
			"scheme": parts["scheme"] || "http",
			"domain": parts["domain"],
			"path": parts["path"],
			"query": (parts["query"] || "") + session,
			"fragment": parts["fragment"] ? ("#" + parts["fragment"]) : ""
		});
	};
	if (data.type == "script") {
		element.click(function() {
			$.getScript(appendSessionID(data.url));
		});
	} else {
		element.fancybox({
			'autoScale': false,
			'height': data.height,
			'href': appendSessionID(data.url),
			'onClosed': function() {
				// remove dynamic height/width calculations for overlay
				if ($.browser.msie && document.compatMode != 'CSS1Compat') {
					var style = $('#fancybox-overlay').get(0).style;
					style.removeExpression('height');
					style.removeExpression('width');
				}
			},
			'onComplete': function() {
				// set fixed dimensions of the frame (for IE in quirks mode it should be smaller)
				var delta = ($.browser.msie && document.compatMode != 'CSS1Compat' ? 40 : 0);
				$('#fancybox-frame').css({
					"width": data.width - delta,
					"height": data.height - delta
				});
			},
			'onStart': function() {
				Backplane.expectMessages("identity/ack");
				// dynamical calculation of overlay height/width
				if ($.browser.msie && document.compatMode != 'CSS1Compat') {
					var style = $('#fancybox-overlay').get(0).style;
					style.setExpression('height', 'Math.max(document.body.clientHeight, document.body.scrollHeight)');
					style.setExpression('width', 'Math.max(document.body.clientWidth, document.body.scrollWidth)');
				}
			},
			'padding': 0,
			'scrolling': 'no',
			'transitionIn': 'elastic',
			'transitionOut': 'elastic',
			'type': 'iframe',
			'width': data.width
		});
	}
};

Echo.Auth.prototype.listenEvents = function() {
	var self = this;
	this.subscribe("internal.User.onInvalidate", function() {
		$.fancybox.close();
		self.rerender();
	});
};

Echo.Auth.prototype.addCss = function() {
	$.addCss(
		'.echo-auth-logout { float: right; }' +
		'.echo-auth-anonymous { text-align: right; }' +
		'.echo-auth-avatar { float: left; }' +
		'.echo-auth-avatar img { width: 24px; height: 24px; }' +
		'.echo-auth-name { float: left; font-size: 18px; line-height: 24px; margin-left: 5px; font-weight: bold; }' +
		'.echo-auth-edit { float: left; margin: 6px 0px 0px 12px; }'
	, 'auth');
};
})(jQuery);





(function($) {
Echo.Counter = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.data = {};
	this.initConfig(config, {
		"debug": false
	});
	this.messageLayout = "compact";
	this.initApplication(function() {
		self.contextId = self.newContextId();
		self.showMessage({"type": "loading"});
		self.initLiveUpdates(function() {
			return {
				"endpoint": "count",
				"query": {"q": self.config.get("query", "")}
			};
		}, function(data) { self.handleResponse(data); });
		if (self.config.get("data")) {
			self.handleResponse(self.config.get("data"));
		} else {
			self.request();
		}
		self.listenEvents();
	});
};

Echo.Counter.prototype = new Echo.Application();

Echo.Counter.prototype.namespace = "Counter";

Echo.Counter.prototype.request = function() {
	var self = this;
	this.sendAPIRequest({
		"endpoint": "count",
		"query": {"q": self.config.get("query", "")}
	}, function(data) {
		self.handleResponse(data);
	});
};

Echo.Counter.prototype.refresh = function() {
	this.stopLiveUpdates();
	this.data = {};
	this.showMessage({"type": "loading"});
	this.request();
};

Echo.Counter.prototype.listenEvents = function() {
	var self = this;
	$.map(["Submit.onPostComplete", "Submit.onEditComplete"], function(topic) {
		Echo.Broadcast.subscribe(topic, function() {
			self.startLiveUpdates(true);
		});
	});
};

Echo.Counter.prototype.handleResponse = function(data) {
	var self = this;
	var target = this.config.get("target");
	data = data || {};
	if (data.result == "error" && data.errorCode != "more_than") {
		this.handleErrorResponse(data);
		return;
	}
	this.cleanupErrorHandlers(true);
	target.show();
	target.html(data.errorCode == "more_than" ? (data.errorMessage + "+") : data.count);
	if ($.isEmptyObject(this.data) || this.data.count != data.count) {
		this.publish("Counter.onUpdate", {
			"data": data,
			"query": this.config.get("query", ""),
			"target": this.config.get("target").get(0)
		});
	}
	this.data = data;
	this.startLiveUpdates();
};
})(jQuery);





(function($) {
Echo.Localization.extend({
	"apply": "Apply",
	"cancel": "Cancel",
	"delete" : "Delete",
	"deleteQueryConfirmMessage" : "Are you sure you want to delete the \"{Data:name}\" query?",
	"edit" : "Edit",
	"save" : "Save",
	"saving": "Saving...",
	"textFieldEmptyError": "Query field can not be empty!",
	"titleFieldEmptyError": "Title field can not be empty!"
}, "Query");

Echo.Query = function(data) {
	this.vars = {};
	this.mode = "view"; // or "edit"
	this.init(data);
};

Echo.Query.prototype = new Echo.Object();

Echo.Query.prototype.namespace = "Query";

Echo.Query.prototype.cssPrefix = "echo-query-";

Echo.Query.prototype.template = function() {
return '<div class="echo-query-container echo-curation-primary-font">' +
		'<div class="echo-query-quickButton echo-query-applyButton echo-clickable" title="{Label:apply}"></div>' +
		'<div class="echo-query-controls">'+
			'<div class="echo-query-quickButton echo-query-deleteButton echo-clickable" title="{Label:delete}"></div>' +
			'<div class="echo-query-quickButton echo-query-editButton echo-clickable" title="{Label:edit}"></div>' +
			'<div class="echo-clear"></div>' +
		'</div>' +
		(this.mode == "view"
		?
		'<div class="echo-query-content echo-query-content-view">' +
			'<span>{Data:title}</span>' +
		'</div>'
		:
		'<div class="echo-query-content echo-query-content-edit">' +
			'<div class="echo-query-title-container">' +
				'<input class="echo-query-title echo-curation-primary-font echo-curation-input" value="{Data:title}">' +
			'</div>' +
			'<div>' +
				'<textarea class="echo-query-text echo-curation-primary-font echo-curation-input" spellcheck="false">' +
					'{Data:query}' +
				'</textarea>' +
			'</div>' +
		'</div>' +
		'<div class="echo-query-buttons">' +
			'<button type="button" class="echo-query-saveButton echo-curation-secondary-font">{Label:save}</button>' +
			'<button type="button" class="echo-query-cancelButton echo-curation-secondary-font">{Label:cancel}</button>' +
			'<div class="echo-clear"></div>' +
		'</div>'
		) +
		'<div class="echo-clear"></div>' +
	'</div>';
};

Echo.Query.prototype.renderers = {};

Echo.Query.prototype.renderers.container = function(element) {
	var self = this;
	element.bind({
		"mouseleave": function() {
			if (self.mode == "edit") return;
			self.dom.get("controls").hide();
		},
		"mouseenter": function() {
			if (self.mode == "edit") return;
			self.dom.get("controls").show();
		}
	});
	if (this.mode == "view"){
		element.addClass("echo-clickable").click(function() {
			self.publish("QueryPalette.onApply", {
				"title": self.data.title,
				"query": self.data.query
			});
		})
	}
};

Echo.Query.prototype.renderers.editButton = function(element) {
	var self = this;
	element.click(function() {
		self.publish("internal.Query.onEdit", self.data);
		self.mode = "edit";
		self.rerender();
	});
};

Echo.Query.prototype.renderers.deleteButton = function(element) {
	var self = this;
	element.click(function(){
		if (confirm(
			self.substitute(
				self.label("deleteQueryConfirmMessage"), 
				{"name": self.data.title}
			)
		)){
			self.dom.remove("container");
			self.publish("internal.Query.onDelete", self.data);
		}
	})
};

Echo.Query.prototype.renderers.applyButton = function(element) {
	var self = this;
	var get = function(field) {
		return self.mode == "edit"
			? self.dom.get(field == "query" ? "text" : field).val()
			: self.data[field];
	};
	element.click(function(event) {
		self.publish("QueryPalette.onApply", {
			"title": get("title"),
			"query": get("query")
		});
		event.stopPropagation();
	});
};

Echo.Query.prototype.renderers.saveButton = function(element) {
	var self = this;
	var button = new Echo.UI.Button(element, {
		"normal": {
			"icons": {
				"primary": "ui-icon-save"
			},
			"disabled": false
		},
		"saving": {
			"icons": {
				"primary": "ui-icon-waiting"
			},
			"disabled": true,
			"label": self.label('saving')
		}
	});
	element.click(function() {
		var data = {};
		$.each(["title", "text"], function(id, name) {
			var value = $.trim($.stripTags(self.dom.get(name).val()));
			if (!value) {
				alert(self.label(name + "FieldEmptyError"));
				self.dom.get(name).focus();
				return false;
			}
			data[name] = value;
		});
		if (!data.title || !data.text) return false;
		button.setState('saving');
		self.data.title = data.title;
		self.data.query = data.text;
		self.publish("internal.Query.onSave", {
			"query": self.data,
			"callback": function() {
				self.mode = "view";
				self.rerender();
			}
		});
	});
};

Echo.Query.prototype.renderers.cancelButton = function(element) {
	var self = this;
	new Echo.UI.Button(element);
	element.click(function() {
		self.mode = "view";
		self.rerender();
	});
};

Echo.Localization.extend({
	"advancedBuilderSwitch" : "Quick Editor",
	"apply": "Apply",
	"chronological" : "Chronological",
	"editMore": "Edit More...",
	"emptyQueriesList": "No saved queries...",
	"itemsPerPage": "Items per page",
	"help": "Help",
	"loadingQueriesList": "Loading...",
	"path": "Path",
	"query": "Query",
	"queryBuilder": "Query Builder",
	"quickBuilderSwitch" : "Advanced Editor",
	"repliesDescending": "Replies Count (descending)",
	"likesDescending": "Likes Count (descending)",
	"flagsDescending": "Flags Count (descending)",
	"reverseChronological" : "Reverse Chronological",
	"savedQueries": "Saved Queries",
	"saveToList": "Save to list",
	"saving": "Saving...",
	"sortOrder": "Sort Order",
	"states": "States",
	"stateCommunityFlagged": "Flagged by Community",
	"stateModeratorApproved": "Approved by Moderator",
	"stateModeratorDeleted": "Deleted by Moderator",
	"stateModeratorFlagged": "Flagged by Moderator",
	"stateSystemFlagged": "Flagged by System",
	"stateUntouched": "New",
	"textFieldEmptyError": "Query field can not be empty!",
	"viewingOptions": "Viewing Options"
}, "QueryPalette");

Echo.QueryPalette = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.queries = [];
	this.queryById = {};
	this.builders = {};
	this.builderMode = "quick"; // or "advanced"
	this.states = [
		"Untouched",
		"ModeratorApproved",
		"ModeratorDeleted",
		"CommunityFlagged",
		"ModeratorFlagged",
		"SystemFlagged"
	];
	this.initConfig(config, {
		"query": {
			"path": window.location.protocol + "//" + window.location.host + "/*",
			"states": ["Untouched", "SystemFlagged", "CommunityFlagged", "ModeratorFlagged"],
			"itemsPerPage": 12,
			"sortOrder": "reverseChronological"
		},
		"domain": window.location.host,
		"autoRequest": false,
		"queriesAppURL": window.location.protocol + "//apps.echoenabled.com/v2/query"
	});
	this.initApplication(function() {
		self.addCss();
		self.prepareQuery();
		self.listenEvents();
		self.config.get("target").empty().append(self.render());
		if (self.config.get("autoRequest")) {
			self.requestSavedQueries();
		}
	});
};

Echo.QueryPalette.prototype = new Echo.Application();

Echo.QueryPalette.prototype.namespace = "QueryPalette";

Echo.QueryPalette.prototype.cssPrefix = "echo-curation-queries-";

Echo.QueryPalette.prototype.template =
'<div class="echo-curation-queries">' +
	'<div class="echo-curation-queries-header">' +
		'<div class="echo-curation-queries-header-left echo-curation-secondary-font">' +
			'{Label:queryBuilder}' +
		'</div>' +
		'<div class="echo-curation-queries-header-right">' +
			'<a class="echo-curation-queries-builderModeSwitcher echo-clickable echo-linkColor"></a>' +
		'</div>' +
		'<div class="echo-clear"></div>' +
	'</div>' +
	'<div class="echo-curation-queries-builder"></div>' +
	'<div class="echo-curation-queries-buttons">' +
		'<button type="button" class="echo-curation-queries-helpButton echo-curation-secondary-font">{Label:help}</button>' +
		'<button type="button" class="echo-curation-queries-applyButton echo-curation-secondary-font">{Label:apply}</button>' +
		'<button type="button" class="echo-curation-queries-editButton echo-curation-secondary-font">{Label:editMore}</button>' +
		'<button type="button" class="echo-curation-queries-saveButton echo-curation-secondary-font">{Label:saveToList}</button>' +
		'<div class="echo-clear"></div>' +
	'</div>' +
	'<div class="echo-curation-queries-header echo-curation-secondary-font">{Label:savedQueries}</div>' +
	'<div class="echo-curation-queries-savedQueries"></div>'
'</div>';

Echo.QueryPalette.prototype.renderers = {};

Echo.QueryPalette.prototype.renderers.quickEditor = function() {
	var self = this;
	var assembleStates = function(states) {
		var template = 
			'<div class="{Data:prefix}">' + 
				'<input type="checkbox" id="{Data:prefix}{Data:name}" class="{Data:prefix}{Data:name}"{Data:checked}>' +
				'<label for="{Data:prefix}{Data:name}" class="echo-clickable">' +
					'<span class="{Data:prefix}{Data:name}Label echo-curation-primary-font">' +
						'{Data:label}' +
					'</span>' +
				'</label>' +
			'</div>';
		return $.map(states, function(name){
			return self.substitute(template, {
				"checked": self.query.states[name] ? " checked" : "",
				"prefix": "echo-curation-queries-state", 
				"name": name, 
				"label": self.label("state" + name)});
		}).join("\n");
	};
	var template =
	'<div class="echo-curation-queries-wrapper">' +
		'<div class="echo-curation-queries-subheader echo-curation-secondary-font">{Label:path}</div>' +
		'<div>' +
			'<input class="echo-curation-primary-font echo-curation-queries-path echo-curation-input">' +
		'</div>' +
		'<div class="echo-curation-queries-subheader echo-curation-secondary-font">{Label:states}</div>' +
		'<div class="echo-curation-queries-content">' +
			'<div class="echo-curation-queries-block echo-curation-queries-left">' +
				assembleStates(["Untouched", "ModeratorApproved", "ModeratorDeleted"]) +	
			'</div>' +
			'<div class="echo-curation-queries-block">' +
				assembleStates(["CommunityFlagged", "ModeratorFlagged", "SystemFlagged"]) +
			'</div>' +
			'<div class="echo-clear"></div>' +
		'</div>' +
		'<div class="echo-curation-queries-subheader echo-curation-secondary-font">' +
			'{Label:viewingOptions}' +
		'</div>' +
		'<div class="echo-curation-queries-viewOptions-itemsPerPage echo-curation-primary-font">' +
			'<span class="echo-curation-queries-view-option">{Label:itemsPerPage}:</span>' +
			'<input class="echo-curation-queries-itemsPerPage echo-curation-primary-font">' +
		'</div>' +
		'<div class="echo-curation-queries-viewOptions-sortOrder echo-curation-primary-font">' +
			'<span class="echo-curation-queries-view-option">{Label:sortOrder}:</span>' +
			'<select class="echo-curation-queries-sortOrder echo-curation-primary-font">' +
				'<option value="chronological">{Label:chronological}</option>' +
				'<option value="reverseChronological">{Label:reverseChronological}</option>' +
				'<option value="repliesDescending">{Label:repliesDescending}</option>' +
				'<option value="likesDescending">{Label:likesDescending}</option>' +
				'<option value="flagsDescending">{Label:flagsDescending}</option>' +
			'</select>' +
		'</div>' +
	'</div>';
	var descriptors = $.foldl({}, ["path", "itemsPerPage", "sortOrder"], function(name, acc) {
		acc[name] = function(element) {
			element.val(self.query[name]);
		};
	});
	this.builders.quick = $.toDOM(this.substitute(template), "echo-curation-queries-", descriptors);
	return this.builders.quick.content;
};

Echo.QueryPalette.prototype.renderers.advancedEditor = function() {
	var self = this;
	var template = 
	'<div class="echo-curation-queries-wrapper">' +
		'<div class="echo-curation-queries-subheader echo-curation-secondary-font">{Label:query}</div>' +
		'<div class="echo-curation-queries-content">' +
			'<textarea class="echo-curation-queries-query echo-curation-input" spellcheck="false"></textarea>' +
		'</div>' +
	'</div>';
	var descriptors = {
		"query": function(element) {
			element.val(self.query.text);
		}
	};
	this.builders.advanced = $.toDOM(this.substitute(template), "echo-curation-queries-", descriptors);
	return this.builders.advanced.content;
};

Echo.QueryPalette.prototype.renderers.builder = function(element) {
	var content = this.render(this.builderMode + "Editor");
	(element || this.dom.get("builder")).empty().append(content);
};

Echo.QueryPalette.prototype.renderers.builderModeSwitcher = function(element) {
	var self = this;
	(element || this.dom.get("builderModeSwitcher"))
		.empty()
		.append(this.label(this.builderMode + "BuilderSwitch"))
		.unbind("click")
		.one("click", function() {
			self.toggleBuilderView();
		});
};

Echo.QueryPalette.prototype.renderers.helpButton = function(element) {
	new Echo.UI.Button(element);
	element.click(function() {
		window.open('http://wiki.aboutecho.com/API-method-search');
	});
};

Echo.QueryPalette.prototype.renderers.editButton = function(element) {
	var self = this;
	new Echo.UI.Button(element);
	element.click(function() {
		self.toggleBuilderView(true);
	});
};

Echo.QueryPalette.prototype.renderers.saveButton = function(element) {
	var self = this;
	var button = new Echo.UI.Button(element, {
		"normal": {
			"icons": {
				"primary": "ui-icon-save"
			},
			"disabled": false
		},
		"saving": {
			"icons": {
				"primary": "ui-icon-waiting"
			},
			"disabled": true,
			"label": self.label('saving')
		}
	});
	element.hide().click(function() {
		var id = self.config.get("appkey") + "-" +
			window.location.host + "-" +
			(new Date().getTime()) + "-" +
			Math.round(Math.random() * 1000);
		var container = self.dom.get("savedQueries");
		var query = self.initQuery({
			"id": id,
			"title": "Query #" + (self.queries.length + 1),
			"query": self.builders.advanced.get("query").val() || ""
		});
		if (!$.trim(query.data.query)) {
			alert(self.label("textFieldEmptyError"));
			self.builders.advanced.get("query").focus();
			return false;
		}
		button.setState('saving');
		self.queryById[id] = query;
		if (!self.queries.length) {
			container.empty();
		}
		self.queries.unshift(query);

		self.sendRequest({
			"action": "save",
			"id": id,
			"title": query.data.title,
			"query": query.data.query
		}, function() {
			button.setState('normal');
			var content = query.render();
			container.prepend(content);
			content.hide()
				.css({backgroundColor: "#ffff99"})
				.slideDown(700)
				.animate({backgroundColor: "#ffffff"}, 4000, 'easeInOutExpo');
		});
	});
};

Echo.QueryPalette.prototype.renderers.applyButton = function(element) {
	var self = this;
	new Echo.UI.Button(element, {
		"normal": {
			"icons": {
				"primary": "ui-icon-arrow-right"
			}
		}
	});
	element.click(function() {
		self.query.text = self.builderMode == "quick"
			? self.assembleQuery()
			: self.builders.advanced.get("query").val() || "";
		if (self.builderMode == "quick") {
			self.saveQuickView();
		}
		self.publish("QueryPalette.onApply", {"query": self.query.text});
	});
};

Echo.QueryPalette.prototype.prepareQuery = function() {
	this.query = this.config.get("query");
	if (this.query) {
		this.query.states = $.foldl({}, this.query.states || [], function(state, acc) {
			acc[state] = true;
		});
	}
};

Echo.QueryPalette.prototype.listenEvents = function() {
	var self = this;
	this.subscribe("internal.Query.onEdit", function(event, data) {
		self.collapseQueriesExcept(data.id);
	});
	this.subscribe("internal.Query.onDelete", function(event, data) {
		self.deleteQuery(data.id);
		if (!self.queries.length) {
			self.renderQueriesMessage("empty");
		}
		self.sendRequest({
			"id": data.id,
			"action": "delete"
		});
	});
	this.subscribe("internal.Query.onSave", function(event, data) {
		self.sendRequest({
			"action": "save",
			"id": data.query.id,
			"title": data.query.title,
			"query": data.query.query
		}, data.callback);
	});
};

Echo.QueryPalette.prototype.toggleBuilderView = function(assembleQuery) {
	var mode = "quick";
	var buttons = {
		"edit": this.dom.get("editButton"),
		"save": this.dom.get("saveButton")
	};
	if (this.builderMode == "quick") {
		mode = "advanced";
		buttons.edit.hide();
		buttons.save.show();
		if (assembleQuery || !this.query.text) {
			this.query.text = this.assembleQuery();
		}
		this.saveQuickView();
	} else {
		buttons.edit.show();
		buttons.save.hide();
	}
	this.builderMode = mode;
	this.rerender(["builder", "builderModeSwitcher"]);
};

Echo.QueryPalette.prototype.deleteQuery = function(id) {
	if (this.queryById[id]){
		this.queries = $.foldl([], this.queries, function(query, acc){
			if (query.data.id != id) {
				acc.push(query);
			}
		});
	}
};

Echo.QueryPalette.prototype.collapseQueriesExcept = function(id) {
	if (this.queryById[id]){
		$.map(this.queries, function(query) {
			if (query.mode == "edit" && query.data.id != id) {
				query.mode = "view";
				query.rerender();
			}
		});
	}
};

Echo.QueryPalette.prototype.assembleQuery = function() {
	var components = [], form = this.builders.quick;
	if (form.get("path") && $.trim(form.get("path").val()) != "") {
		components.push("scope:" + $.trim(form.get("path").val()));
	}
	var states = $.foldl([], this.states, function(state, acc) {
		if (form.get("state" + state).attr("checked")) {
			acc.push(state);
		}
	});
	if (states.length) {
		components.push("state:" + states.join(','));
	}
	components.push("sortOrder:" + form.get("sortOrder").val());
	if (form.get("itemsPerPage").val() > 0) {
		components.push("itemsPerPage:" + form.get("itemsPerPage").val());
	}
	return components.join(" ");
};

Echo.QueryPalette.prototype.saveQuickView = function() {
	var form = this.builders.quick;
	this.query.path = form.get("path").val();
	this.query.states = $.foldl({}, this.states, function(state, acc) {
		if (form.get("state" + state).attr("checked")) acc[state] = true;
	});
	this.query.sortOrder = form.get("sortOrder").val();
	this.query.itemsPerPage = form.get("itemsPerPage").val() || 0;
};

Echo.QueryPalette.prototype.sendRequest = function(query, callback) {
	query.appkey = this.config.get("appkey");
	query.domain = this.config.get("domain");
	callback = callback || function() {};
	$.get(this.config.get("queriesAppURL"), query, callback, "jsonp");
};

Echo.QueryPalette.prototype.requestSavedQueries = function() {
	var self = this;
	this.renderQueriesMessage("loading");
	this.sendRequest({
		"action": "list"
	}, function(data) {
		self.handleSavedQueriesResponse(data);
	});
};

Echo.QueryPalette.prototype.handleSavedQueriesResponse = function(data) {
	var self = this;
	data = data || [];
	if (!data.length) {
		self.renderQueriesMessage("empty");
		return;
	}
	var container = self.dom.get("savedQueries").empty();
	this.queries = $.foldl([], data, function(item, acc) {
		var query = self.initQuery(item);
		self.queryById[item.id] = query;
		container.append(query.render());
		acc.push(query);
	});
};

Echo.QueryPalette.prototype.refresh = function() {
	this.requestSavedQueries();
};

Echo.QueryPalette.prototype.renderQueriesMessage = function(type) {
	this.showMessage({
		"type": type,
		"message": this.label(type + "QueriesList")
	}, this.dom.get("savedQueries"));
};

Echo.QueryPalette.prototype.initQuery = function(data) {
	return new Echo.Query({
		"data": data,
		"config": new Echo.Config(this.config.getAsHash())
	});
};

Echo.QueryPalette.prototype.addCss = function() {
	var self = this;
	$.addCss(
	'.echo-curation-queries {}' +
	'.echo-curation-queries-wrapper { margin: 0px 5px; }' +
	'.echo-curation-primary-font { font-family: Arial; font-size: 12px; color: #393939; }' +
	'.echo-curation-secondary-font { font-family: Arial; font-weight: bold; font-size: 11px; color: #4a4a4a; }' +
	'.echo-curation-input { width: 100%; border: 1px solid #e1e1e1; }' +
	'.echo-curation-queries-header { height: 25px; line-height: 25px; padding: 0px 5px; background-color: #e8e8e8; }' +
	'.echo-curation-queries-header-left { float: left; }' +
	'.echo-curation-queries-header-right { float: right; }' +
	'.echo-curation-queries-builderModeSwitcher { font-family: Arial; font-size: 11px; text-decoration: underline; }' +
	'input.echo-curation-queries-itemsPerPage { width: 48px; height: 20px; border: 1px solid #e1e1e1; }' +
	'.echo-curation-queries-subheader { margin: 10px 0px; }' +
	'.echo-curation-queries-block { float: left; }' +
	'.echo-curation-queries-left { margin-right: 40px; }' +
	'textarea.echo-curation-queries-query { height: 200px; }' +
	'.echo-curation-queries-state { margin-bottom: 10px; line-height: 18px; }' +
	'.echo-curation-queries-state input { margin: 0px; }' +
	'.echo-curation-queries-state span { display: inline-block; margin-left: 5px; padding-left: 18px; }' +
	'.echo-curation-queries-buttons { margin: 20px 5px; }' +
	'.echo-curation-queries-helpButton { float: left; }' +
	'.echo-curation-queries-editButton, .echo-curation-queries-saveButton { float: right; }' +
	'.echo-curation-queries-applyButton { float: right; margin-left: 10px; }' +
	'.echo-curation-queries-viewOptions-itemsPerPage { margin-bottom: 10px; }' +
	'.echo-curation-queries-view-option { padding-right: 5px; }' +
	'.echo-curation-queries .echo-application-message { border: 0px; }' +
	$.map(self.states, function(name){
		return self.substitute('.echo-curation-queries-state{Data:name}Label { background: url("{Data:img}") no-repeat; }', {"name": name, "img": "//c0.echoenabled.com/images/curation/status/" + name.toLowerCase() + ".png"});
	}).join("\n")

	, 'curation');
	if ($.browser.msie) {
		$.addCss('.echo-curation-input { width: 99%; }', 'curation-ie');
	}

	$.addCss(
		'.echo-query-container { margin: 5px; line-height: 25px; border-bottom: 1px solid #e1e1e1; }' +
		'.echo-query-controls { float: right; width: 40px; display: none; }' +
		'.echo-query-quickButton { height: 16px; width: 16px; margin-top: 4px; }' +
		'.echo-query-applyButton { float: left; margin-right: 5px; background: url(//c0.echoenabled.com/images/curation/apply.png) no-repeat; }' +
		'.echo-query-deleteButton { float: right; background: url(//c0.echoenabled.com/images/curation/delete.png) no-repeat; }' +
		'.echo-query-editButton { float: right; background: url(//c0.echoenabled.com/images/curation/edit.png) no-repeat; margin-right: 5px; }' +
		'.echo-query-content { margin-left: 21px; }' +
		'.echo-query-content-view { margin-right: 40px; }' +
		'.echo-query-buttons { margin: 5px 0px; }' +
		'.echo-query-saveButton { float: right; margin-left: 5px; }' +
		'.echo-query-cancelButton { float: right }' +
		'.echo-query-text { height: 80px; }' +
		'.echo-query-title-container { margin-bottom: 5px; }' +
		'.echo-query-title { margin-top: 4px; }'
	, 'query');
};

Echo.Localization.extend({
	"title": "Bulk Actions",
	"itemsCount": "Apply the following transformation to the <strong>{count}</strong> selected item(s)",
	"actionBlockIP": "Block IP",
	"actionBlockUser": "Block User",
	"actionCommunityFlagged": "Flag",
	"actionModeratorApproved": "Approve",
	"actionModeratorDeleted": "Delete",
	"actionModeratorFlagged": "Spam"
}, "BulkActions");

Echo.BulkActions = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.init({"data": config.data});
	this.initConfig(config);
	this.initApplication(function() {
		self.addCss();
		self.config.get("target").empty().append(self.render());
	});
};

Echo.BulkActions.prototype = new Echo.Application();

Echo.BulkActions.prototype.namespace = "BulkActions";

Echo.BulkActions.prototype.cssPrefix = "echo-bulk-actions-";

Echo.BulkActions.prototype.template =
	'<div class="echo-bulk-actions">' +
		'<div class="echo-bulk-actions-header echo-curation-secondary-font">{Label:title}</div>' +
		'<div class="echo-bulk-actions-info echo-curation-primary-font"></div>' +
		'<div class="echo-bulk-actions-buttons"></div>' +
	'</div>';

Echo.BulkActions.prototype.renderers = {};

Echo.BulkActions.prototype.renderers.info = function(element) {
	(element || this.dom.get("info"))
		.empty()
		.append(this.label("itemsCount", {
			"count": this.data.items.length
		}));
};

Echo.BulkActions.prototype.renderers.buttons = function(element) {
	var self = this;
	var template = '<div class="echo-bulk-actions-button echo-curation-primary-font echo-bulk-actions-{Data:class}">{Data:label}</div>';
	$.map(this.actions(), function(action) {
		var data = {
			"class": action.name,
			"label": self.label("action" + action.name)
		};
		var button = $(self.substitute(template, data))
				.click(function() { action.callback(); });
		element.append(button);
	});
};

Echo.BulkActions.prototype.refresh = function(items) {
	this.data.items = items;
	this.rerender("info");
};

Echo.BulkActions.prototype.actions = function() {
	var self = this;
	var actions = $.map([
		"ModeratorApproved",
		"ModeratorDeleted",
		"CommunityFlagged",
		"ModeratorFlagged"
	], function(state) {
		return {
			"name": state,
			"callback": function() {
				self.publish("BulkActions.onStatusChange", {"state": state});
			}
		};
	});
	/*
	XXX: actions for future usage
	actions.push({
		"name": "BlockUser",
		"callback": function() {
			// block user action
		}
	});
	actions.push({
		"name": "BlockIP",
		"callback": function() {
			// block ip action
		}
	});
	*/
	return actions;
};

Echo.BulkActions.prototype.addCss = function() {
	var self = this;
	$.addCss(
		'.echo-bulk-actions-header { height: 25px; line-height: 25px; padding: 0px 5px; background-color: #e8e8e8; }' +
		'.echo-bulk-actions-info { margin: 20px 0px 10px; }' +
		'.echo-bulk-actions-button { padding-left: 23px; cursor: pointer; margin: 10px 0px 10px 10px; line-height: 18px; }' +
		$.map(self.actions(), function(data) {
			return self.substitute('.echo-bulk-actions-{Data:name} { background: url("//c0.echoenabled.com/images/curation/actions/{Data:img}.png") no-repeat; }', {"name": data.name, "img": data.name.toLowerCase()});
		}).join("\n")
	, 'bulk-actions')
};
})(jQuery);





(function($) {
Echo.Localization.extend({
	"defaultModeSwitchTitle": "Switch to metadata view",
	"guest": "Guest",
	"today": "Today",
	"yesterday": "Yesterday",
	"lastWeek": "Last Week",
	"lastMonth": "Last Month",
	"secondAgo": "Second Ago",
	"secondsAgo": "Seconds Ago",
	"minuteAgo": "Minute Ago",
	"minutesAgo": "Minutes Ago",
	"hourAgo": "Hour Ago",
	"hoursAgo": "Hours Ago",
	"dayAgo": "Day Ago",
	"daysAgo": "Days Ago",
	"weekAgo": "Week Ago",
	"weeksAgo": "Weeks Ago",
	"metadataModeSwitchTitle": "Return to default view",
	"monthAgo": "Month Ago",
	"monthsAgo": "Months Ago",
	"sharedThisOn": "I shared this on {service}...",
	"userID": "User ID:",
	"textToggleTruncatedMore": "more",
	"textToggleTruncatedLess": "less",
	"fromLabel": "from",
	"viaLabel": "via",
	"loading": "Loading...",
	"childrenMoreItems": "View more items"
}, "Item");

Echo.Item = function(data) {
	this.vars = {};
	this.textExpanded = false;
	this.blocked = false;
	this.controlsOrder = [];
	this.controls = {}; 
	this.init(data);
};

Echo.Item.prototype = new Echo.Object();

Echo.Item.prototype.cssPrefix = "echo-item-";

Echo.Item.prototype.namespace = "Item";

Echo.Item.prototype.template = function() {
	var childrenTemplateChunk = this.isChildrenPaginationEnabled()
		? this.config.get("children.sortOrder") == "chronological"
			? '<div class="echo-item-children"></div>' +
			  '<div class="echo-item-expandChildren echo-item-container-child echo-trinaryBackgroundColor echo-clickable">' +
				'<span class="echo-item-expandChildrenLabel echo-message-icon"></span>' +
			  '</div>' +
			  '<div class="echo-item-childrenByCurrentActorLive"></div>'
			: '<div class="echo-item-expandChildren echo-item-container-child echo-trinaryBackgroundColor echo-clickable">' +
				'<span class="echo-item-expandChildrenLabel echo-message-icon"></span>' +
			  '</div>' +
			  '<div class="echo-item-children"></div>' +
			  '<div class="echo-item-childrenByCurrentActorLive"></div>'
		: '<div class="echo-item-children"></div>';
	return '<div class="echo-item-content">' +
		'<div class="echo-item-container">' +
			'<div class="echo-item-avatar-wrapper">' +
				'<div class="echo-item-avatar"></div>' +
			'</div>' +
			'<div class="echo-item-wrapper">' +
				'<div class="echo-item-subwrapper">' +
					'<div class="echo-item-subcontainer">' +
						'<div class="echo-item-frame">' +
							'<div class="echo-item-modeSwitch echo-clickable"></div>' +
							'<div class="echo-item-authorName echo-linkColor"></div>' +
							'<div class="echo-clear"></div>' +
							'<div class="echo-item-data">' +
								'<div class="echo-item-re"></div>' +
								'<div class="echo-item-body echo-primaryColor"> ' + 
									'<span class="echo-item-text"></span>' +
									'<span class="echo-item-textEllipses">...</span>' +
									'<span class="echo-item-textToggleTruncated echo-linkColor echo-clickable"></span>' +
								'</div>' +
								'<div class="echo-item-markers echo-secondaryFont echo-secondaryColor"></div>' +
								'<div class="echo-item-tags echo-secondaryFont echo-secondaryColor"></div>' +
							'</div>' +
							'<div class="echo-item-metadata">' +
								'<div class="echo-item-metadata-userID">' +
									'<span class="echo-item-metadata-title echo-item-metadata-icon echo-item-metadata-userID">' +
										'{Label:userID}' +
									'</span>' +
									'<span class="echo-item-metadata-value">{Data:actor.id}</span>' +
								'</div>' +
							'</div>' +
							'<div class="echo-item-footer echo-secondaryColor echo-secondaryFont">' +
								'<img class="echo-item-sourceIcon echo-clickable">' +
								'<div class="echo-item-date"></div>' +
								'<div class="echo-item-from"></div>' +
								'<div class="echo-item-via"></div>' +
								'<div class="echo-item-controls"></div>' +
								'<div class="echo-clear"></div>' +
							'</div>' +
						'</div>' +
					'</div>' +
					'<div class="echo-clear"></div>' +
				'</div>' +
			'</div>' +
			'<div class="echo-clear"></div>' +
			'<div class="echo-item-childrenMarker"></div>' +
			'</div>' +
		childrenTemplateChunk + 
	'</div>';
};

Echo.Item.prototype.renderers = {};

Echo.Item.prototype.renderers.authorName = function(element) {
	return this.data.actor.title || this.label("guest");
};

Echo.Item.prototype.renderers.markers = function(element, dom) {
	this.render("extraField", element, dom, {"type": "markers"});
};

Echo.Item.prototype.renderers.tags = function(element, dom) {
	this.render("extraField", element, dom, {"type": "tags"});
};

Echo.Item.prototype.renderers.extraField = function(element, dom, extra) {
	var self = this;
	var type = (extra || {}).type;
	if (!this.data.object[type] || !this.user.isAdmin()) {
		dom.remove(element);
		return;
	}
	var limit = this.config.get("limits." + type);
	var items = $.foldl([], this.data.object[type], function(item, acc){
		var template = (item.length > limit)
			? '<span title="{Data:item}">{Data:truncatedItem}</span>'
			: '<span>{Data:item}</span>';
		var truncatedItem = $.htmlTextTruncate(item, limit, "...");
		acc.push(self.substitute(template, {"item": item, "truncatedItem": truncatedItem}));
	});
	element.prepend(items.sort().join(", "));
};

Echo.Item.prototype.renderers.container = function(element, dom) {
	var self = this;
	element.removeClass($.map(["child", "root", "child-thread", "root-thread"],
		function(suffix) { return "echo-item-container-" + suffix; }).join(" "));
	var threadSuffix = this.threading ? '-thread' : '';
	if (this.depth) {
		element.addClass('echo-item-container-child' + threadSuffix);
		element.addClass('echo-trinaryBackgroundColor');
	} else {
		element.addClass('echo-item-container-root' + threadSuffix);
	}
	element.addClass('echo-item-depth-' + this.depth);
	var switchClasses = function(action) {
		$.map(self.controlsOrder, function(name) {
			if (!self.controls[name].element) return;
			self.controls[name].clickableElements[action + "Class"]("echo-linkColor");
		});
	};
	if (!$.isMobileDevice()) {
		element.unbind(["mouseleave", "mouseenter"]).hover(function() {
			if (self.user.isAdmin()) dom.get("modeSwitch").show();
			switchClasses("add");
		}, function() {
			if (self.user.isAdmin()) dom.get("modeSwitch").hide();
			switchClasses("remove");
		});
	}
};

Echo.Item.prototype.renderers.modeSwitch = function(element) {
	var self = this;
	element.hide();
	if (!this.user.isAdmin()) return;
	var mode = "default";
	var setTitle = function(el) {
		el.attr("title", self.label(mode + "ModeSwitchTitle"));
	};
	setTitle(element);
	element.click(function() {
		mode = (mode == "default" ? "metadata" : "default");
		setTitle(element);
		self.dom.get("data").toggle();
		self.dom.get("metadata").toggle();
	});
	if ($.isMobileDevice()) element.show();
};

Echo.Item.prototype.renderers.wrapper = function(element) {
	element.addClass('echo-item-wrapper' + (this.depth ? '-child' : '-root'));
};

Echo.Item.prototype.renderers.avatar = function() {
	var self = this;
	var size = (!this.depth ? 48 : 24);
	var url = this.data.actor.avatar || this.user.get("defaultAvatar");
	return $("<img>", { "src": url }).bind({
			"error" : function(){
				$(this).attr("src", self.user.get("defaultAvatar"));
			}
		})
		.css({
			"width": size,
			"height": size
		});
};

Echo.Item.prototype.renderers.childrenContainer = function(element, dom, config) {
	var self = this;
	// we cannot use element.empty() because it will remove children's event handlers
	$.each(element.children(), function(i, child) {
		$(child).detach();
	});
	$.map(this.children, function(child) {
		if (config && config.filter && !config.filter(child)) return;
		var initialRendering = !child.dom;
		element.append(initialRendering ? child.render() : child.dom.content);
		if (child.deleted) {
			self.publish("internal.Item.onDelete", {"item": child, "config": config});
		} else if (child.added) {
			self.publish("internal.Item.onAdd", {"item": child});
		// don't publish events while rerendering or for Whirlpools
		} else if (initialRendering && child instanceof Echo.Item) {
			self.publish("internal.Item.onRender", {"item": child});
		}
	});
};

Echo.Item.prototype.renderers.children = function(element, dom, config) {
	this.render("childrenContainer", element, dom, {
		"filter": function(item) { return !item.byCurrentUser; },
		"keepChildren": config && config.keepChildren
	});
};

Echo.Item.prototype.renderers.childrenByCurrentActorLive = function(element, dom, config) {
	this.render("childrenContainer", element, dom, {
		"filter": function(item) { return item.byCurrentUser; },
		"keepChildren": config && config.keepChildren
	});
};

Echo.Item.prototype.renderers.control = function(element, dom, extra) {
	if (!extra || !extra.name) return;
	var template = extra.template ||
		'<a class="echo-item-control echo-item-control-{Data:name}">{Data:label}</a>';
	var data = {
		"label": extra.label || "",
		"name": extra.name
	};
	var control = $(this.substitute(template, data));
	var clickables = $('.echo-clickable', control);
	if (!clickables.length) {
		clickables = control;
		control.addClass('echo-clickable');
	}
	clickables[extra.onetime ? "one" : "bind"]({
		"click": function(event) {
			event.stopPropagation();
			if (extra.callback) extra.callback();
		}
	});
	if ($.isMobileDevice()) clickables.addClass("echo-linkColor");
	return control;
};

Echo.Item.prototype.renderers.controlsDelimiter = function() {
	return $('<span class="echo-item-control-delim"> \u00b7 </span>');
};

Echo.Item.prototype.renderers.controls = function(element) {
	var self = this;
	this.assembleControls();
	this.sortControls();
	var container = element.empty();
	var delimiter = this.render("controlsDelimiter");
	$.map(this.controlsOrder, function(name) {
		var data = self.controls[name];
		if (!data || !data.visible()) return;
		var control = data.dom || self.render("control", undefined, undefined, data);
		if (control) {
			self.controls[name].element = control;
			self.controls[name].clickableElements = $('.echo-clickable', control);
			if (!self.controls[name].clickableElements.length) {
				self.controls[name].clickableElements = control;
			}
			container.append(delimiter.clone(true)).append(control);
		}
	});
};

Echo.Item.prototype.renderers.re = function() {
	if (!this.config.get("reTag")) return;
	var self = this;
	var context = this.data.object.context;
	var re = "";
	//XXX use normalized permalink and location instead
	var permalink = this.data.object.permalink;
	var limits = this.config.get("limits");
	var openLinksInNewWindow = this.config.get("openLinksInNewWindow");

	var getDomain = function(url) {
		var parts = $.parseUrl(url);
		return (parts && parts.domain) ? parts.domain : url;
	};

	var reOfContext = function(c) {
		var maxLength = limits.reTitle;
		if (!c.title) {
			maxLength = limits.reLink;
			c.title = c.uri.replace(/^https?:\/\/(.*)/ig, '$1');
		}
		if (c.title.length > maxLength) {
			c.title = c.title.substring(0, maxLength) + "...";
		}
		return "<div>" + self.hyperlink({
			"class": "echo-primaryColor",
			"href": c.uri,
			"caption": "Re: " + $.stripTags(c.title)
		}, {
			"openInNewWindow": openLinksInNewWindow
		}) + "</div>";
	};

	var pageHref = document.location.href;
	var pageDomain = getDomain(pageHref);

	if (permalink == pageHref || this.depth || !context || !context.length) {
		return;
	}
	var mustSkipContext = false;
	$.each(context, function(i, c) {
		//XXX use normalized uri
		if (c.uri == pageHref) {
			mustSkipContext = true;
			return false; //break
		}
	});

	if (mustSkipContext) return;

	if (this.config.get("optimizedContext")) {
		var primaryContext = context[0];
		$.each(context, function(i, c) {
			if (getDomain(c.uri) == pageDomain) {
				primaryContext = c;
				return false; //break
			}
		});
		if (primaryContext) re = reOfContext(primaryContext);
	} else {
		$.each(context, function(i, c) {
			re += reOfContext(c);
		});
	}

	return $(re);
};

Echo.Item.prototype.renderers.sourceIcon = function(element, dom) {
	if (!this.config.get("viaLabel.icon") ||
		this.data.source.name == "jskit" ||
		this.data.source.name == "echo") {
			dom.remove(element);
	}
	element.hide().attr("src", $.htmlize(
		this.data.source.icon ||
		this.config.get("providerIcon")
	))
	.show()
	.one("error", function() {
		dom.remove(element);
	})
	.wrap(this.hyperlink({
		"href": this.data.source.uri || this.data.object.permalink
	}, {
		"openInNewWindow": this.config.get("openLinksInNewWindow")
	}));
};

Echo.Item.prototype.renderers.via = function(element, dom) {
	var self = this;
	var get = function(field) {
		return (self.data[field].name || "").toLowerCase();
	};
	if (get("source") == get("provider")) return;
	this.render("viaText", element, dom, {
		"label": "via",
		"field": "provider"
	});
};

Echo.Item.prototype.renderers.from = function(element, dom) {
	this.render("viaText", element, dom, {
		"label": "from",
		"field": "source"
	});
};

Echo.Item.prototype.renderers.viaText = function(element, dom, extra) {
	extra = extra || {};
	var data = this.data[extra.field];
	if (!this.config.get("viaLabel.text") || !data.name || data.name == "jskit"  || data.name == "echo") return;
	var a = this.hyperlink({
		"class": "echo-secondaryColor",
		"href": data.uri || this.data.object.permalink,
		"caption": data.name
	}, {
		"openInNewWindow": this.config.get("openLinksInNewWindow")
	});
	element.html('&nbsp;' + this.label(extra.label + 'Label') + '&nbsp;').append(a);
};

Echo.Item.prototype.renderers.textToggleTruncated = function(element) {
	var self = this;
	element.unbind("click").click(function() {
		self.textExpanded = !self.textExpanded;
		self.rerender(["body", "textToggleTruncated"]);
	});
	return this.label("textToggleTruncated" + (this.textExpanded ? "Less" : "More"));
};

Echo.Item.prototype.renderers.body = function(element, dom) {
	var self = this;
	var output = function(text, truncated) {
		dom.get("text").empty().append(text);
		dom.get("textEllipses")[!truncated || self.textExpanded ? "hide" : "show"]();
		dom.get("textToggleTruncated")[truncated || self.textExpanded ? "show" : "hide"]();
	};
	// temporary fix because Firefox hides CDATA content
	var text = this.data.object.content.replace(/<!\[CDATA\[(.*?)\]\]>/g, '$1');
	var source = this.data.source.name;
	var openLinksInNewWindow = this.config.get("openLinksInNewWindow");
	var contentTransformations = this.config.get("contentTransformations." +
							this.data.object.content_type, {});
	if (source && source == "Twitter" && this.config.get("aggressiveSanitization")) {
		output(this.label("sharedThisOn", {"service": source}));
		return;
	}

	var limits = this.config.get("limits");
	var wrap = function(tag) {
		var template = 
			(tag.length > limits.tags)
			? '<span class="echo-item-tag" title="{Data:tag}">{Data:truncatedTag}</span>'
			: '<span class="echo-item-tag">{Data:tag}</span>';
		var truncatedTag = tag.substring(0, limits.tags) + "...";
		return (self.substitute(template, {"tag": tag, "truncatedTag": truncatedTag}));	
	};

	if (contentTransformations.hashtags) {
		text = text.replace(/(#|\uff03)(<a[^>]*>[^<]*<\/a>)/ig, function($0, $1, $2){
			return wrap($2);
		});
	}

	var insertHashTags = function(t) {
		if (!contentTransformations.hashtags) return t;
		return t.replace(/(^|[^\w&\/])(?:#|\uff03)([^\s\.,;:'"#@\$%<>!\?\(\)\[\]]+)/ig, function($0, $1, $2) {
			return $1 + wrap($2);
		});
	};
	var tags2meta = function(text) {
		var tags = [];
		text = text.replace(/((<a\s+[^>]*>)(.*?)(<\/a>))|<.*?>/ig, function($0, $1, $2, $3, $4) {
			//we are cutting and pushing <a> tags to acc to avoid potential html issues after autolinking
			if ($1) {
				var content = tags2meta($3);
				content.text = insertHashTags(content.text);
				$0 = $2 + meta2tags(content) + $4;
			}
			tags.push($0);
			return ' %%HTML_TAG%% ';
		});
		return {"text" : text, "tags": tags};
	};
	var meta2tags = function(content) {
		$.each(content.tags, function(i, v) {
			content.text = content.text.replace(' %%HTML_TAG%% ', v);
		});
		return content.text;
	};
	var urlMatcher = "((?:http|ftp|https):\\/\\/(?:[a-z0-9#:\\/\\;\\?\\-\\.\\+,@&=%!\\*\\'(){}\\[\\]$_|^~`](?!gt;|lt;))+)";
	var normalizeLinks = function(content) {
		return content.replace(/(<a\s+[^>]*>)(.*?)(<\/a>)/ig, function($0, $1, $2, $3) {
			if (new RegExp("^" + urlMatcher + "$").test($2)) {
				$2 = $2.length > limits.bodyLink ? $2.substring(0, limits.bodyLink) + "..." : $2;
			}
			if (openLinksInNewWindow && !/\s+target=("[^<>"]*"|'[^<>']*'|\w+)/.test($1)) {
				$1 = $1.replace(/(^<a\s+[^>]*)(>$)/, '$1 target="_blank"$2');
			}
			return $1 + $2 + $3;
		});
	};
	var content = tags2meta(text);
	if (source && source != 'jskit' && source != 'echo') {
		var url = this.depth
			? this.data.target.id
			: this.config.get("reTag")
				? this.data.object.permalink || this.data.target.id
				: undefined;
		if (url) {
			content.text = content.text.replace(new RegExp(url, "g"), "");
			if (!/\S/.test(content.text)) {
				output(this.label("sharedThisOn", {"service": source}));
				return;
			}
		}
	}
	var textBeforeAutoLinking = content.text = insertHashTags(content.text);
	if (contentTransformations.urls) {
		content.text = content.text.replace(new RegExp(urlMatcher, 'ig'), function($0, $1) {
			return self.hyperlink({
				'href': $1,
				'caption': $1
			}, {
				'skipEscaping': true,
				'openInNewWindow': openLinksInNewWindow
			});
		})
	}
	if (contentTransformations.smileys) {
		if (content.text != textBeforeAutoLinking) {
			content = tags2meta(meta2tags(content));
		}
		var smileys = this.initSmileysConfig();
		if (content.text.match(smileys.regexps.test)) {
			$.each(smileys.codes, function(i, code) {
				content.text = content.text.replace(smileys.regexps[code], smileys.tag(smileys.hash[code]));
			});
		}
	}

	if (contentTransformations.newlines) {
		content.text = content.text.replace(/\n\n+/g, '\n\n');
		content.text = content.text.replace(/\n/g, '&nbsp;<br>');
	}
	var result = normalizeLinks(meta2tags(content));
	var truncated = false;
	if ((limits.body || limits.lines) && !self.textExpanded) {
		if (limits.lines) {
			var splitter = contentTransformations.newlines ? "<br>" : "\n";
			var chunks = result.split(splitter);
			if (chunks.length > limits.lines) {
				result = chunks.splice(0, limits.lines).join(splitter);
				truncated = true;
			}
		}
		var limit = limits.body && result.length > limits.body
			? limits.body
			: truncated
				? result.length
				: undefined;
		// we should call $.htmlTextTruncate to close
		// all tags which might remain unclosed after lines truncation
		var truncatedText = $.htmlTextTruncate(result, limit, "", true);
		if (truncatedText.length != result.length) {
			truncated = true;
		}
		result = truncatedText;
	}
	output(result, truncated);
};

Echo.Item.prototype.renderers.date = function(element) {
	var container = element || this.dom && this.dom.get("date");
	this.calcAge();
	if (container) {
		container.html(this.age);
	}
};

Echo.Item.prototype.renderers.expandChildrenLabel = function(element, dom, extra) {
	if (!this.children.length || !this.hasMoreChildren()) return;
	extra = extra || {};
	extra.state = extra.state || "regular";
	var states = {
		"loading": {
			"css": "echo-item-message-loading",
			"label": "loading"
		},
		"regular": {
			"css": "echo-linkColor echo-message-icon",
			"label": "childrenMoreItems"
		}
	};
	element
		.removeClass(states[extra.state == "loading" ? "regular" : "loading"].css)
		.addClass(states[extra.state].css)
		.html(this.label(states[extra.state].label));
};

Echo.Item.prototype.renderers.expandChildren = function(element, dom, extra) {
	if (!this.children.length) return;
	if (!this.hasMoreChildren()) {
		// IE in Quirks mode can't operate with elements with "height: 0px" correctly, 
		// element with "height: 0px" is renderered as though it doesn't have height property at all.
		// Thus we set "height: 1px" as the final value for animate function and simply hide element
		// after the animation is done.
		if ($.browser.msie && document.compatMode != "CSS1Compat") {
			element.animate(
				{
					"height": "1px",
					"marginTop": "hide",
					"marginBottom": "hide",
					"paddingTop": "hide",
					"paddingBottom": "hide"
				},
				{
					"duration": this.config.get("children.moreButtonSlideTimeout"),
					"complete": function() {
						element.hide();
					}
				}
			);
		} else {
			element.slideUp(this.config.get("children.moreButtonSlideTimeout"));
		}
		return;
	}
	var self = this;
	// extra.element is sibling element for more children button
	extra = extra || {};
	// the "show()" jQuery method doesn't work for some reason in Chrome (A:5755)
	element.css("display", "block");
	element.addClass("echo-item-depth-" + (this.depth + 1));
	element.unbind("click").one("click", function() {
		self.render("expandChildrenLabel", dom.get("expandChildrenLabel"), dom, {"state": "loading"});
		self.publish("internal.Item.onChildrenExpand", {"data": self.data});
	});
};

Echo.Item.prototype.isChildrenPaginationEnabled = function() {
	return !!this.config.get("children.itemsPerPage");
};

Echo.Item.prototype.hasMoreChildren = function() {
	return this.data.hasMoreChildren == "true";
};

Echo.Item.prototype.getNextPageAfter = function() {
	var children = $.grep(this.children, function(child) {
		return !child.live;
	});
	var index = this.config.get("children.sortOrder") == "chronological"
		? children.length - 1
		: 0;
	return children.length
		? children[index].data.pageAfter
		: undefined;
};

Echo.Item.prototype.initSmileysConfig = function() {
	if (Echo.Vars.smileys) return Echo.Vars.smileys;
	var esc = function(v) { return v.replace(/([\W])/g, "\\$1"); };
	var smileys = Echo.Vars.smileys = {"codes": [], "regexps": []};
	smileys.hash = {
		':)':		{file: 'smile.png', title: 'Smile'},
		':-)':		{file: 'smile.png', title: 'Smile'},
		';)':		{file: 'wink.png', title: 'Wink'},
		';-)':		{file: 'wink.png', title: 'Wink'},
		':(':		{file: 'unhappy.png', title: 'Frown'},
		':-(':		{file: 'unhappy.png', title: 'Frown'},
		'=-O':		{file: 'surprised.png', title: 'Surprised'},
		':-D':		{file: 'grin.png', title: 'Laughing'},
		':-P':		{file: 'tongue.png', title: 'Tongue out'},
		'=)':		{file: 'happy.png', title: 'Happy'},
		'B-)':		{file: 'evilgrin.png', title: 'Evil grin'}
	};
	var escapedCodes = [];
	$.each(smileys.hash, function(code) {
		var escaped = esc(code);
		escapedCodes.push(escaped);
		smileys.codes.push(code);
		smileys.regexps[code] = new RegExp(escaped, "g");
	});
	smileys.regexps.test = new RegExp(escapedCodes.join("|"));
	smileys.tag = function(smiley) {
		return '<img class="echo-item-smiley-icon" src="//c0.echoenabled.com/images/smileys/emoticon_' + smiley.file + '" title="' + smiley.title + '" alt="' + smiley.title + '" />';
	};
	return smileys;
};

Echo.Item.prototype.assembleControls = function() {
	var self = this;
	var controlsOrder = [];
	$.each(this.config.get("itemControls", {}), function(plugin, controls) {
		$.map(controls, function(control) {
			var data = $.isFunction(control)
				? control.call(self)
				: $.extend({}, control);
			if (!data.name) return;
			var callback = data.callback || function() {};
			data.callback = function() {
				callback.call(self);
				self.publish("internal.Item.onControlClick", {
					"name": data.name,
					"plugin": plugin,
					"item": {
						"data": self.data,
						"target": self.dom.content
					}
				});
			};
			data.label = data.label || data.name;
			data.plugin = plugin;
			if (typeof data.visible == "undefined") {
				data.visible = true;
			}
			var visible = data.visible;
			data.visible = function() {
				return visible && self.config.get("plugins." + plugin + ".enabled");
			}
			var name = plugin + '.' + data.name;
			self.controls[name] = data;
			if ($.inArray(name, self.controlsOrder) < 0) {
				controlsOrder.push(name);
			}
		});
	});
	// keep correct order of plugins and controls
	self.controlsOrder = controlsOrder.concat(self.controlsOrder);
};

Echo.Item.prototype.sortControls = function() {
	var self = this;
	var defaultOrder = this.controlsOrder;
	var requiredOrder = this.config.get("itemControlsOrder");
	// if controls order is not specified in application config, use default order
	if (!requiredOrder) {
		this.config.set("itemControlsOrder", defaultOrder);
	} else if (requiredOrder != defaultOrder) {
		var push = function(name, acc, pos) {
			if (!self.controls[name]) return;
			acc.push(name);
			pos = pos || $.inArray(name, defaultOrder);
			if (pos >= 0) {
				delete defaultOrder[pos];
			}
		};
		var order = $.foldl([], requiredOrder, function(name, acc) {
			if (/^(.*)\./.test(name)) {
				push(name, acc);
			} else {
				var re = new RegExp("^" + name + "\.");
				$.map(defaultOrder, function(n, i) {
					if (n && n.match(re)) {
						push(n, acc, i);
					}
				});
			}
		});
		this.controlsOrder = order;
		this.config.set("itemControlsOrder", order);
	// if application config tells not to use controls
	} else if (!requiredOrder.length) {
		this.controlsOrder = [];
	}
};

Echo.Item.prototype.traverse = function(tree, callback, acc) {
	var self = this;
	$.each(tree || [], function(i, item) {
		acc = self.traverse(item.children, callback, callback(item, acc));
	});
	return acc;
};

Echo.Item.prototype.refreshDate = function() {
	this.rerender("date");
	$.map(this.children || [], function(child) {
		child.refreshDate();
	});
};

Echo.Item.prototype.calcAge = function() {
	if (!this.timestamp) return;
	var self = this;
	var d = new Date(this.timestamp * 1000);
	var now = (new Date()).getTime();
	var when;
	var diff = Math.floor((now - d.getTime()) / 1000);
	var dayDiff = Math.floor(diff / 86400);
	var getAgo = function(ago, period) {
		return ago + " " + self.label(period + (ago == 1 ? "" : "s") + "Ago");
	};

	if (isNaN(dayDiff) || dayDiff < 0 || dayDiff >= 365) {
		when = d.toLocaleDateString() + ', ' + d.toLocaleTimeString();
	} else if (diff < 60) {
		when = getAgo(diff, 'second');
	} else if (diff < 60 * 60) {
		diff = Math.floor(diff / 60);
		when = getAgo(diff, 'minute');
	} else if (diff < 60 * 60 * 24) {
		diff = Math.floor(diff / (60 * 60));
		when = getAgo(diff, 'hour');
	} else if (diff < 60 * 60 * 48) {
		when = this.label("yesterday");
	} else if (dayDiff < 7) {
		when = getAgo(dayDiff, 'day');
	} else if (dayDiff < 14) {
		when = this.label("lastWeek");
	} else if (dayDiff < 30) {
		diff =  Math.floor(dayDiff / 7);
		when = getAgo(diff, 'week');
	} else if (dayDiff < 60) {
		when = this.label("lastMonth");
	} else if (dayDiff < 365) {
		diff =  Math.floor(dayDiff / 31);
		when = getAgo(diff, 'month');
	}
	if (this.age != when) {
		this.age = when;
	}
};

Echo.Item.prototype.block = function(label) {
	if (this.blocked) return;
	this.blocked = true;
	var content = this.dom.get("container");
	var width = content.width();
	//We should take into account that container has a 10px 0px padding value
	var height = content.outerHeight();
	this.blockers = {
		"backdrop": $('<div class="echo-item-blocker-backdrop"></div>').css({
			"width": width, "height": height
		}),
		"message": $(this.substitute('<div class="echo-item-blocker-message">{Data:label}</div>', {"label": label})).css({
			"left": ((parseInt(width) - 200)/2) + 'px',
			"top": ((parseInt(height) - 20)/2) + 'px'
		})
	};
	content.addClass("echo-relative")
		.prepend(this.blockers.backdrop)
		.prepend(this.blockers.message);
};

Echo.Item.prototype.unblock = function() {
	if (!this.blocked) return;
	this.blocked = false;
	this.blockers.backdrop.remove();
	this.blockers.message.remove();
	this.dom.get("container").removeClass("echo-relative");
};

Echo.Item.prototype.getAccumulator = function(type) {
	return this.data.object.accumulators[type];
}; 

Echo.Localization.extend({
	"guest": "Guest",
	"live": "Live",
	"paused": "Paused",
	"more": "More",
	"loading": "Loading...",
	"emptyStream": "No items at this time...",
	"new": "new"
}, "Stream");

Echo.Stream = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {"cache": {}};
	this.initConfig(config, {
		"aggressiveSanitization": false,
		"contentTransformations": {
			"text": ["smileys", "hashtags", "urls", "newlines"],
			"html": ["smileys", "hashtags", "urls", "newlines"],
			"xhtml": ["smileys", "hashtags", "urls"]
		},
		"children": {
			"additionalItemsPerPage": 5,
			"displaySortOrder": "chronological",
			"sortOrder": "reverseChronological",
			"moreButtonSlideTimeout": 600,
			"itemsSlideTimeout": 600,
			"maxDepth": 1
		},
		"fadeTimeout": 2800,
		"flashColor": "#ffff99",
		"itemControlsOrder": undefined,
		"itemsPerPage": 15,
		"maxBodyLinkLength": 50,
		"maxBodyCharacters": undefined,
		"maxBodyLines": undefined,
		"maxReLinkLength": 30,
		"maxReTitleLength": 143,
		"maxTagLength": 16,
		"maxMarkerLength": 16,
		"openLinksInNewWindow": false,
		"optimizedContext": true,
		"providerIcon": "http://c0.echoenabled.com/images/favicons/comments.png",
		"reTag": true,
		"slideTimeout": 700,
		"sortOrder": "reverseChronological",
		"streamStateLabel": {
			"icon": true,
			"text": true
		},
		"submissionProxyURL": window.location.protocol + "//apps.echoenabled.com/v2/esp/activity",
		"streamStateToggleBy": "mouseover", // mouseover | button | none
		"viaLabel": {
			"icon": false,
			"text": false
		}
	}, this.assembleConfigNormalizer());
	this.initVars();
	this.initApplication(function() {
		self.addCss();
		self.config.get("target").empty().append(self.render());
		self.recalcEffectsTimeouts();
		self.initLiveUpdates(function() {
			return {
				"endpoint": "search",
				"query": {
					"q": self.constructSearchQuery(),
					"since": self.nextSince || 0
				}
			};
		}, function(data) { self.handleLiveUpdatesResponse(data); });
		if (self.config.get("data")) {
			self.handleInitialResponse(self.config.get("data"), function(data) {
				self.lastRequest = {
					"initial": true,
					"data": data
				};
				self.render("body");
			});
		} else {
			self.initialItemsRequest();
		}
		self.listenEvents();
		self.publish("Stream.onRender", self.prepareBroadcastParams());
	});
};

Echo.Stream.prototype = new Echo.Application();

Echo.Stream.prototype.namespace = "Stream";

Echo.Stream.prototype.cssPrefix = "echo-stream-";

Echo.Stream.prototype.template = 
	'<div class="echo-stream-container echo-primaryFont echo-primaryBackgroundColor">' +
		'<div class="echo-stream-header">'+
			'<div class="echo-stream-state echo-secondaryColor"></div>' +
			'<div class="echo-clear"></div>' +
		'</div>' +
		'<div class="echo-stream-body"></div>' +
		'<div class="echo-stream-more"></div>' +
		'<div class="echo-stream-brand">'+
			'<a class="echo-stream-brand-link" href="http://aboutecho.com" target="_blank">' +
				'<div class="echo-stream-brand-message">social networking by</div>' +
			'</a>' +
		'</div>' +
	'</div>';

Echo.Stream.prototype.renderers = {};

Echo.Stream.prototype.renderers.body = function(element) {
	var self = this;
	element = element || this.dom.get("body");
	if (!this.lastRequest) {
		this.showMessage({
			"type": "loading",
			"message": this.label(this.isWaitingForData(this.error) ? "error_" + this.error.errorCode : "loading")
		}, element);
		return;
	}

	if (this.lastRequest.data.length) {
		if (this.lastRequest.initial) element.empty();
		this.appendRootItems(this.lastRequest.data, element);
	} else {
		this.showMessage({
			"type": "empty",
			"message": this.label("emptyStream")
		}, element);
	}
	if (this.lastRequest.initial && this.config.get("streamStateToggleBy") == "mouseover" && this.config.get("liveUpdates")) {
		element.bind({
			"mouseleave": function() {
				self.setStreamState("live");
			},
			"mouseenter": function() {
				self.setStreamState("paused");
			}
		});
	}
	this.publish("Stream.onReady", this.prepareBroadcastParams({"initial": this.lastRequest.initial}));
};

Echo.Stream.prototype.renderers.state = function(element) {
	var self = this;
	var label = this.config.get("streamStateLabel");
	if ((!label.icon && !label.text) || !this.config.get("liveUpdates")) return;

	var activitiesCount = 0;
	if (this.activities.state == "paused") {
		activitiesCount = $.foldl(0, self.activities.queue, function(entry, acc) {
			if (entry.affectCounter) {
				return ++acc;
			}
		});
	}
	var currentState = this.activities.state + activitiesCount;
	if (currentState == this.activities.lastState) return;

	element = (element || this.dom.get("state")).empty();
	if (!this.activities.lastState && this.config.get("streamStateToggleBy") == "button") {
		element.addClass("echo-linkColor echo-clickable").click(function(e) {
			self.setStreamState(self.activities.state == "paused" ? "live" : "paused");
		});
	}
	var templates = {
		"picture" : '<span class="echo-stream-state-picture echo-stream-state-picture-' + this.activities.state +'"></span>',
		"message" : this.config.get("streamStateToggleBy") == "button"
			? '<a href="javascript:void(0)" class="echo-stream-state-message">{Label:' + this.activities.state + '}</a>'
			: '<span class="echo-stream-state-message">{Label:' + this.activities.state + '}</span>',
		"count" : ' <span class="echo-stream-state-count">({Data:count} {Label:new})</span>'
	};
	if (label.icon) {
		element.append(templates.picture);
	}
	if (label.text) {
		element.append(this.substitute(templates.message));
		if (activitiesCount && this.activities.state == "paused") {
			element.append(this.substitute(
				templates.count,
				{"count": activitiesCount}
			));
		}
	}
	this.activities.lastState = currentState;
};

Echo.Stream.prototype.renderers.more = function(element, dom) {
	var self = this;
	if (this.isViewComplete || !this.threads.length) {
		element.empty().hide();
		return;
	}
	element.empty()
		.append(this.label("more"))
		.bind({
			'mouseenter': function() {
				element.addClass("echo-stream-more-hover");
			},
			'mouseleave': function() {
				element.removeClass("echo-stream-more-hover");
			}
		})
		.show()
		.unbind('click')
		.one('click', function() {
			self.publish("Stream.onMoreButtonPress", self.prepareBroadcastParams());
			element.html(self.label("loading"));
			self.moreRequestItems(element);
		});
};

Echo.Stream.prototype.initVars = function() {
	this.activities = {
		"queue": [],
		"state": this.config.get("liveUpdates") ? "live" : "paused", // live | paused
		"lastState": "", // live0 | pausedN
		"animations": 0
	};
	this.hasInitialData = false;
	this.items = {};   // items by unique key hash
	this.threads = []; // items tree
	this.cleanupErrorHandlers();
};

Echo.Stream.prototype.actualizeChildrenList = function(parent, entries) {
	var self = this;
	return $.map(entries, function(entry) {
		// we should change entry conversationID in accordance with
		// conversationID of the root item
		entry.targets = $.map(entry.targets, function(target) {
			target.conversationID = parent.conversation;
			return target;
		});
		entry = self.normalizeEntry(entry);
		var item = self.items[entry.unique];
		// drop item from items list if the item already exists
		// in the tree, which means that it was posted by the current user
		// and arrived as a live update
		if (item && item.byCurrentUser) {
			self.applyStructureUpdates("delete", item);
		}
		return entry;
	});
};

Echo.Stream.prototype.createChildrenItemsDomWrapper = function(children, parent) {
	var self = this;
	var wrapper = $("<div class='echo-item-children-wrapper'></div>");
	var getIdx = function(item) { return self.getItemListIndex(item, parent.children); };
	$.each(children, function(i, item) {
		item.render();
		var insertion = i > 0 && getIdx(children[i-1]) < getIdx(item)
			? "append"
			: "prepend";
		wrapper[insertion](item.dom.content);
	});
	return wrapper;
};

Echo.Stream.prototype.listenEvents = function() {
	var self = this;
	this.subscribe("internal.User.onInvalidate", function() {
		self.refresh();
	});
	this.subscribe("internal.Item.onAdd", function(topic, data) {
		data.item.dom.content.hide();
		self.queueActivity({
			"action": "animation",
			"actorID": data.item.data.actor.id,
			"itemUnique": data.item.data.unique,
			"priority": "highest",
			"handler": function() {
				delete data.item.added;
				self.addItemSpotUpdate(data.item);
			}
		});
	});
	this.subscribe("internal.Item.onDelete", function(topic, data) {
		self.queueActivity({
			"action": "animation",
			"itemUnique": data.item.data.unique,
			"actorID": data.item.data.actor.id,
			"priority": "highest",
			"handler": function() {
				delete data.item.deleted;
				self.deleteItemSpotUpdate(data.item, data.config);
			}
		});
	});
	this.subscribe("internal.Item.onRender", function(topic, data) {
		self.publish("Stream.Item.onRender", self.prepareBroadcastParams({
			"item": {
				"data": data.item.data,
				"target": data.item.dom.content
			}
		}));
	});
	this.subscribe("internal.Item.onControlClick", function(topic, data) {
		var topic = self.namespace + ".Item.onControlClick";
		self.publish(topic, self.prepareBroadcastParams(data));
	});
	this.subscribe("internal.Item.onChildrenExpand", function(topic, args) {
		self.childrenRequestItems(args.data.unique);
	});
	$.map(["Submit.onPostComplete", "Submit.onEditComplete"], function(topic) {
		Echo.Broadcast.subscribe(topic, function() {
			self.startLiveUpdates(true);
		});
	});
};

Echo.Stream.prototype.childrenRequestItems = function(unique) {
	var self = this;
	var item = this.items[unique];
	this.sendAPIRequest({
		"endpoint": "search",
		"query": {"q": this.constructChildrenSearchQuery(item)}
	}, function(data) {
		var element = item.dom.get("expandChildren");
		if (data.result == "error") {
			self.handleErrorResponse(data, {
				"messageTarget": element,
				"waitingHandler": function() {
					self.childrenRequestItems(unique);
				}
			});
			if (!self.isWaitingForData(data))  {
				element.removeClass("echo-clickable")
					.delay(3000)
					.slideUp(self.config.get("children.moreButtonSlideTimeout"));
			}
			return;
		}
		if (!data.hasMoreChildren || data.hasMoreChildren == "false") {
			item.data.hasMoreChildren = false;
		}
		item.data.nextPageAfter = data.nextPageAfter;
		data.entries = self.actualizeChildrenList(item, data.entries);
		self.publish("Stream.onDataReceive", self.prepareBroadcastParams({
			"entries": data.entries,
			"initial": false
		}));
		var children = [];
		$.each(data.entries, function(i, entry) {
			var _item = self.initItem(entry);
			self.applyStructureUpdates("add", _item);
			if (entry.parentUnique == item.data.unique) children.push(_item);
		});
		self.placeChildrenItems(item, children, data.entries);
	});	
};

Echo.Stream.prototype.initialItemsRequest = function() {
	var self = this;
	this.requestItems({}, function(data) {
		self.lastRequest = {
			"initial": true,
			"data": data
		};
		self.render("body");
	});
};

Echo.Stream.prototype.moreRequestItems = function(element) {
	var self = this;
	element = element || this.dom.get("more");
	this.lastRequest = {
		"initial": false
	};
	this.requestItems({
		"pageAfter": '"' + (self.nextPageAfter || "0") + '"'
	}, function(items) {
		if (items.length) {
			self.lastRequest.data = items;
			self.render("body");
		} else {
			element.html(self.label("emptyStream")).delay(1000).fadeOut(1000);
		}
	});
};

Echo.Stream.prototype.setStreamState = function(state) {
	this.activities.state = state;
	if (state == "live") this.executeNextActivity();
	this.rerender("state");
};

Echo.Stream.prototype.refresh = function() {
	this.stopLiveUpdates();
	this.initVars();
	delete this.lastRequest;
	this.clearCache();
	this.rerender();
	this.initialItemsRequest();
	this.publish("Stream.onRerender", this.prepareBroadcastParams());
};

Echo.Stream.prototype.extractPresentationConfig = function(data) {
	return $.foldl({}, ["sortOrder", "itemsPerPage", "safeHTML"], function(key, acc) {
		if (typeof data[key] != "undefined") {
			acc[key] = data[key];
		}
	});
};

Echo.Stream.prototype.extractTimeframeConfig = function(data) {
	var getComparator = function(value) {
		var m = value.match(/^(<|>)(.*)$/);
		var op = m[1];
		var v = m[2].match(/^'([0-9]+) seconds ago'$/);
		var getTS = v
			? function() { return Math.floor((new Date()).getTime() / 1000) - v[1]; }
			: function() { return m[2]; };
		var f;
		if (op == '<') {
			f = function(ts) {
				return ts < getTS()
			}
		} else if (op == '>') {
			f = function(ts) {
				return ts > getTS()
			}
		}
		return f;
	};
	var timeframe = $.foldl([], ["before", "after"], function(key, acc) {
		if (!data[key]) return;
		var cmp = getComparator(data[key]);
		if (cmp) acc.push(cmp);
	});
	return {"timeframe": timeframe};
};

Echo.Stream.prototype.assembleConfigNormalizer = function() {
	var self = this;
	var ensurePositiveValue = function(v) { return v < 0 ? 0 : v; };
	var normalizer = {
		"contentTransformations" : function(object) {
			$.each(object, function(contentType, options) {
				object[contentType] = $.foldl({}, options || [],
					function(option, acc) {
						acc[option] = true;
					});
			});
			return object;
		},
		"safeHTML" : function(value) {
			return "off" != value;
		},
		"streamStateToggleBy": function(value) {
			if (value == "mouseover" && $.isMobileDevice()) {
				return "button";
			}
			return value;
		},
		"fadeTimeout": ensurePositiveValue,
		"slideTimeout": ensurePositiveValue
	};
	var limits = {
		"body": "maxBodyCharacters",
		"lines": "maxBodyLines",
		"reLink": "maxReLinkLength",
		"reTitle": "maxReTitleLength",
		"bodyLink": "maxBodyLinkLength",
		"tags": "maxTagLength",
		"markers": "maxMarkerLength"
	};
	$.each(limits, function(configKey, streamKey) {
		normalizer[streamKey] = function(value) {
			this.set("limits." + configKey, value);
			return value;
		};
	});
	return normalizer;
};

Echo.Stream.prototype.getRespectiveAccumulator = function(item, sort) {
	var accBySort = {
		"likesDescending": "likesCount",
		"flagsDescending": "flagsCount",
		"repliesDescending": "repliesCount"
	};
	return item.getAccumulator(accBySort[sort]);
};

Echo.Stream.prototype.appendRootItems = function(items, container) {
	var self = this;
	var fragment = document.createDocumentFragment();
	$.each(items || [], function(i, item) {
		fragment.appendChild(item.render().get(0));
		self.publish("Stream.Item.onRender", self.prepareBroadcastParams({
			"item": {
				"data": item.data,
				"target": item.dom.content
			}
		}));
	});
	container.append(fragment);
	this.rerender("more");
};

Echo.Stream.prototype.prepareBroadcastParams = function(params) {
	params = params || {};
	params.target = this.config.get("target").get(0);
	params.query = this.config.get("query");
	if (params.item && params.item.target) {
		params.item.target = params.item.target.get(0);
	}
	return params;
};

Echo.Stream.prototype.constructSearchQuery = function(extra) {
	var after = extra && extra["pageAfter"] && "pageAfter:" + extra["pageAfter"] || "";
	return [this.config.get("query", ""), after].join(" ");
};

Echo.Stream.prototype.constructChildrenSearchQuery = function(item) {
	// depth for item children request
	var depth = this.config.get("children.maxDepth") - item.depth - 1;
	var additionalItems = parseInt(this.config.get("children.additionalItemsPerPage"));
	var pageAfter = item.getNextPageAfter();
	var filter = this.config.get("children.filter");
	var filterQuery = !filter || filter == "()" ? "" : filter + " ";
	return filterQuery + $.foldl("", {
		"childrenof": item.data.object.id,
		"children": depth,
		"childrenItemsPerPage": depth ? parseInt(this.config.get("children.itemsPerPage")) : 0,
		"itemsPerPage": additionalItems,
		"sortOrder": this.config.get("children.sortOrder"),
		"childrenSortOrder": this.config.get("children.sortOrder"),
		"pageAfter": pageAfter ? '"' + (pageAfter || 0) + '"' : undefined
	}, function(value, acc, predicate) {
		return acc += (typeof value != "undefined"
			? predicate + ":" + value + " " 
			: ""
		); 
	}) + filterQuery;
};

Echo.Stream.prototype.requestItems = function(extra, visualizer) {
	var self = this;
	this.sendAPIRequest({
		"endpoint": "search",
		"query": {"q": this.constructSearchQuery(extra)}
	}, function(data) {
		self.handleInitialResponse(data, visualizer);
	});
};

Echo.Stream.prototype.handleInitialResponse = function(data, visualizer) {
	var self = this, items = [], roots = [];
	var isMoreRequest = this.lastRequest && !this.lastRequest.initial;
	data = data || {};
	if (data.result == 'error') {
		this.handleErrorResponse(data, {
			"messageTarget": isMoreRequest ? self.dom.get("more") : self.dom.get("body"),
			"waitingHandler": function() {
				if (isMoreRequest) {
					self.moreRequestItems();
				} else {
					self.refresh();
				}
			}
		});
		return;
	}
	this.cleanupErrorHandlers(true);
	this.config.get("target").show();
	this.changeLiveUpdatesTimeout(data);
	this.nextSince = data.nextSince || 0;
	this.nextPageAfter = data.nextPageAfter;
	this.config.extend(this.extractPresentationConfig(data));
	data.children.itemsPerPage = +data.children.itemsPerPage;
	this.config.set(
		"children",
		this.config.combine(
			data.children,
			this.config.get("children")
		)
	);
	this.config.extend(this.extractTimeframeConfig(data));
	var sortOrder = this.config.get("sortOrder");
	data.entries = data.entries || [];
	this.publish("Stream.onDataReceive", self.prepareBroadcastParams({
		"entries": data.entries,
		"initial": !this.hasInitialData
	}));
	$.each(data.entries, function(i, entry) {
		entry = self.normalizeEntry(entry);
		var item = self.initItem(entry);
		// avoiding problem when children can go before parents
		self.applyStructureUpdates("add", item);
		if (self.isRootItem(item)) {
			self.addItemToList(roots, item, sortOrder);
		}
	});

	this.hasInitialData = true;
	this.isViewComplete = roots.length != this.config.get("itemsPerPage");
	visualizer(roots);
	this.startLiveUpdates();
};

Echo.Stream.prototype.checkTimeframeSatisfy = function() {
	var self = this;
	var timeframe = this.config.get("timeframe");
	var unsatisfying = $.foldl([], this.threads, function(thread, acc) {
		var satisfy = $.foldl(true, timeframe, function(p, a) {
			return a ? p(thread.timestamp) : false;
		});
		if (!satisfy) acc.push(thread);
	});
	$.map(unsatisfying, function(item) {
		self.applySpotUpdates("delete", item);
	});
};

Echo.Stream.prototype.handleLiveUpdatesResponse = function(data) {
	var self = this;
	data = data || {};
	if (data.result == "error") {
		this.startLiveUpdates();
		return;
	}
	this.nextSince = data.nextSince || 0;
	this.refreshItemsDate();
	this.checkTimeframeSatisfy();
	this.applyLiveUpdates(data.entries);
	this.render("state");
	this.executeNextActivity();
	this.startLiveUpdates();
};

Echo.Stream.prototype.applyLiveUpdates = function(entries) {
	var self = this;
	$.each(entries || [], function(i, entry) {
		entry = self.normalizeEntry(entry);
		var item = self.items[entry.unique];
		var action = self.classifyAction(entry);
		if (!item && action != "post") return;
		switch (action) {
			case "post":
				if (item) {
					self.applySpotUpdates("replace", self.updateItem(entry));
				} else {
					item = self.initItem(entry, true);
					var satisfies = self.isRootItem(item)
						? self.withinVisibleFrame(item)
						: self.withinVisibleChildrenFrame(item);
					// do not filter out items from the current user
					// they should be displayed in a special container
					if (!satisfies && !self.isRootItem(item) &&
						self.user.hasIdentity(item.data.actor.id)) {
							item.byCurrentUser = true;
					};
					if (satisfies || item.byCurrentUser) {
						self.publish("Stream.Item.onReceive",
							self.prepareBroadcastParams({
								"item": {"data": item.data}
							}));
						self.applySpotUpdates("add", item);
					} else {
						delete self.items[entry.unique];
					}
				}
				break;
			case "delete":
				self.applySpotUpdates("delete", item);
				break;
		}
	});
	this.recalcEffectsTimeouts();
};

Echo.Stream.prototype.recalcEffectsTimeouts = function() {
	// recalculating timeouts based on amount of items in activities queue
	var s = this;
	var maxTimeouts = {
		"fade": s.config.get("fadeTimeout"),
		"slide": s.config.get("slideTimeout")
	};
	s.timeouts = s.timeouts || {
		"fade": maxTimeouts.fade,
		"slide": maxTimeouts.slide
	};
	if (maxTimeouts.fade == 0 && maxTimeouts.slide == 0) return;
	s.timeouts.coeff = s.timeouts.coeff || {
		"fade": s.timeouts.fade / (maxTimeouts.fade + maxTimeouts.slide),
		"slide": s.timeouts.slide / (maxTimeouts.fade + maxTimeouts.slide)
	};
	var calc = function(timeout, value) {
		value = Math.round(value * s.timeouts.coeff[timeout]);
		if (value < 100) return 0; // no activities for small timeouts
		if (value > maxTimeouts[timeout]) return maxTimeouts[timeout];
		return value;
	};
	// reserving 80% of time between live updates for activities
	var frame = s.config.get("liveUpdatesTimeout") * 1000 * 0.8;
	var msPerItem = s.activities.queue.length ? frame / s.activities.queue.length : frame;
	s.timeouts.fade = calc("fade", msPerItem);
	s.timeouts.slide = calc("slide", msPerItem);
};

Echo.Stream.prototype.refreshItemsDate = function() {
	$.map(this.threads, function(item) {
		item.refreshDate();
	});
};

Echo.Stream.prototype.executeNextActivity = function() {
	var acts = this.activities;
	if (acts.animations > 0 || !acts.queue.length ||
		this.config.get("liveUpdates") && acts.state == "paused" && acts.queue[0].action != "replace" && !acts.queue[0].byCurrentUser) return;
	acts.queue.shift().handler();
};

Echo.Stream.prototype.applySpotUpdates = function(action, item, options) {
	var self = this;
	options = options || {};
	var handler = function(operation) {
		switch (operation) {
			case "add":
				// if we trying to add already existing item
				// and it was not due to item moving we should replace it
				var _item = self.items[item.data.unique];
				if (_item && _item.dom && options.priority != "high") {
					self.applySpotUpdates("replace", item, {"priority": "highest"});
					return;
				}
				self.applyStructureUpdates(operation, item);
				item.added = true;
				if (self.isRootItem(item)) {
					self.placeRootItem(item);
				} else {
					var parent = self.getParentItem(item);
					if (parent && parent.dom) {
						parent.rerender([
							"container",
							"children",
							"childrenByCurrentActorLive"
						]);
					}
				}
				self.executeNextActivity();
				break;
			case "replace":
				item.unblock();
				if (self.maybeMoveItem(item)) {
					var parent = self.getParentItem(item);
					var sort = self.config.get(parent ? "children.sortOrder" : "sortOrder");
					var items = parent ? parent.children : self.threads;
					var oldIdx = self.getItemListIndex(item, items);
					// We need to calculate the projected index of the item
					// after the "replace" action and compare it with the current one
					// to determine whether the item should be moved to the new place or not:
					//   - create a copy of the items list
					//   - remove the item from the copy
					//   - calculate the new index
					//   - compare the old and new indexes
					var container = $.extend([], items);
					container.splice(oldIdx, 1);
					var newIdx = self.getItemProjectedIndex(item, container, sort);
					if (oldIdx != newIdx) {
						self.applySpotUpdates("delete", item, {
							"keepChildren": true,
							"priority": "high"
						});
						self.applySpotUpdates("add", item, {"priority": "high"});
					}
				}
				if (item && item.dom) {
					item.rerender("container", true);
				}
				self.executeNextActivity();
				break;
			case "delete":
				item.deleted = true;
				// keepChildren flag is required to detect the case when item is being moved
				if (self.isRootItem(item)) {
					self.publish("internal.Item.onDelete", {"item": item, "config": options});
					self.applyStructureUpdates(operation, item, options);
				} else {
					var parent = self.getParentItem(item);
					if (parent) {
						parent.render("children", parent.dom.get("children"), parent.dom, options);
						if (self.isChildrenPaginationEnabled()) {
							parent.render("childrenByCurrentActorLive", parent.dom.get("childrenByCurrentActorLive"), parent.dom, options);
						}
						self.applyStructureUpdates(operation, item, options);
						parent.rerender("container");
					}
				}
				self.executeNextActivity();
				break;
		}
	};
	this.queueActivity({
		"action": action,
		"itemUnique": item.data.unique,
		"actorID": item.data.actor.id,
		"priority": options.priority,
		"handler": function() { handler(action); }
	});
};

Echo.Stream.prototype.queueActivity = function(params) {
	var item = this.items[params.itemUnique];
	if (!item) return;
	// we consider activity related to the current user if:
	//  - the corresponding item is blocked (moderation action in progress)
	//  - or the activity was performed by the current user
	var byCurrentUser = item.blocked || params.actorID && this.user.hasIdentity(params.actorID);
	var index = this.getActivityProjectedIndex(byCurrentUser, params);
	var data = {
		"action": params.action,
		"type": params.type || "",
		"affectCounter": params.action == "add",
		"itemUnique": params.itemUnique,
		"priority": params.priority,
		"byCurrentUser": byCurrentUser,
		"handler": function() { params.handler(); }
	};
	if (typeof index != "undefined") {
		this.activities.queue.splice(index, 0, data);
	} else {
		this.activities.queue.push(data);
	}
};

Echo.Stream.prototype.getActivityProjectedIndex = function(byCurrentUser, params) {
	var priorityWeights = {
		"highest": 0,
		"high": 10,
		"medium": 20,
		"low": 30,
		"lowest": 40
	};
	params.priority = params.priority == "highest" && "highest"
		|| byCurrentUser && "high"
		|| params.action == "replace" && "medium"
		|| params.priority
		|| "lowest";
	var index;
	if (params.action == "replace") {
		// in case we have "replace" activity for the item which was not added
		// to the stream yet but queued only we should set its priority the same
		// as that "add" activity so that to queue them in the right order
		$.each(this.activities.queue, function(i, activity) {
			if (activity.action == "add" && activity.itemUnique == params.itemUnique) {
				params.priority = activity.priority;
				return false; // break
			}
		});
	}
	$.each(this.activities.queue, function(i, activity) {
		if (priorityWeights[params.priority] < priorityWeights[activity.priority]) {
			index = i;
			return false; // break
		}
	});
	return index;
};

Echo.Stream.prototype.addItemSpotUpdate = function(item) {
	var self = this;
	this.activities.animations++;
	if (this.timeouts.slide) {
		//We should specify the element height explicitly to avoid element jumping during the animation effect
		var currentHeight = item.dom.content.show().css("height");
		item.dom.content.css("height", currentHeight).hide().animate({
			"height": "show", 
			"marginTop": "show", 
			"marginBottom": "show", 
			"paddingTop": "show", 
			"paddingBottom": "show"
		},
		this.timeouts.slide,
		function(){
			//After the animation effect we should remove explicitly set height
			if (!item.dom || !item.dom.content) return;
			item.dom.content.css("height", "");
		});
	} else {
		item.dom.content.show();
	}
	var publish = function() {
		if (!item.dom || !item.dom.content) return;
		self.publish("Stream.Item.onRender", self.prepareBroadcastParams({
			"item": {
				"data": item.data,
				"target": item.dom.content
			}
		}));
	};
	if (this.timeouts.fade) {
		var container = item.dom.get("container");
		var originalBGColor = $.getVisibleColor(container);
		container
		// delay fading out until content sliding is finished
		.delay(this.timeouts.slide)
		.css({"backgroundColor": this.config.get("flashColor")})
		// Fading out
		.animate(
			{"backgroundColor": originalBGColor},
			this.timeouts.fade,
			"linear",
			function() {
				container.css("backgroundColor", "");
				publish();
				self.activities.animations--;
				self.executeNextActivity();
			}
		);
	} else {
		publish();
		this.activities.animations--;
		this.executeNextActivity();
	}
};

Echo.Stream.prototype.deleteItemSpotUpdate = function(item, config) {
	var self = this;
	this.activities.animations++;
	config = config || {};
	var callback = $.isFunction(config) ? config : config.callback || function() {
		if (!item.dom || !item.dom.content) return;
		// if the item is being moved, we should keep all jQuery handlers
		// for the nested elements (children), thus we use "detach" instead of "remove"
		config.keepChildren ? item.dom.content.detach() : item.dom.remove("content");
		delete item.dom;
		item.vars = {};
		var itemsCount = $.foldl(0, self.items, function(_item, acc) {
			return acc + 1;
		});
		if (!itemsCount) {
			self.showMessage({
				"type": "empty",
				"message": self.label("emptyStream")
			}, self.dom.get('body'));
		}
		self.activities.animations--;
		self.executeNextActivity();
	};
	if (this.timeouts.slide) {
		item.dom.content.slideUp(this.timeouts.slide, callback);
	} else {
		callback();
	}
};

Echo.Stream.prototype.classifyAction = function(entry) {
	return (entry.verbs[0] == "http://activitystrea.ms/schema/1.0/delete") ? "delete" : "post";
};

Echo.Stream.prototype.isRootItem = function(item) {
	return !this.config.get("children.maxDepth") || item.id == item.conversation;
};

Echo.Stream.prototype.hasParentItem = function(item) {
	return !!this.getParentItem(item);
};

Echo.Stream.prototype.maybeMoveItem = function(item) {
	return item.forceInject;
};

Echo.Stream.prototype.withinVisibleFrame = function(item, items, isViewComplete, sortOrder) {
	items = items || this.threads;
	isViewComplete = typeof isViewComplete == "undefined"
		? this.isViewComplete
		: isViewComplete;
	sortOrder = sortOrder || this.config.get("sortOrder");
	var last = items.length
		? items[items.length - 1]
		: undefined;
	if (isViewComplete || last == undefined) return true;
	return this.compareItems(last, item, sortOrder);
};

Echo.Stream.prototype.withinVisibleChildrenFrame = function(item) {
	var parent = this.getParentItem(item);
	if (!this.isChildrenPaginationEnabled() || !parent) return this.hasParentItem(item);
	return this.withinVisibleFrame(item, parent.children,
			!parent.hasMoreChildren(), this.config.get("children.sortOrder"));
};

Echo.Stream.prototype.getParentItem = function(item) {
	return this.isRootItem(item) ? undefined : this.items[item.data.parentUnique];
};

Echo.Stream.prototype.compareItems = function(a, b, sort) {
	var self = this;
	switch (sort) {
		case "chronological":
			return a.timestamp > b.timestamp;
		case "reverseChronological":
			return a.timestamp <= b.timestamp;
		case "likesDescending":
		case "repliesDescending":
		case "flagsDescending":
			var getCount = function(entry) {
				return self.getRespectiveAccumulator(entry, sort);
			};
			return (getCount(a) < getCount(b) ||
					(getCount(a) == getCount(b) &&
						this.compareItems(a, b, "reverseChronological")));
	};
};

Echo.Stream.prototype.placeRootItem = function(item) {
	var content = item.render();
	if (this.threads.length > 1) {
		var id = this.getItemListIndex(item, this.threads);
		var next = this.threads[id + 1], prev = this.threads[id - 1];
		if (next) {
			next.dom.content.before(content);
		} else {
			prev.dom.content.after(content);
		}
	} else {
		this.dom.get("body").empty().append(content);
	}
	this.publish("internal.Item.onAdd", {"item": item});
};

Echo.Stream.prototype.placeChildrenItems = function(parent, children, entries) {
	var self = this;
	var itemsWrapper = this.createChildrenItemsDomWrapper(children, parent);
	// we should calculate index of the sibling item for the responsed items
	var targetItemIdx = -1;
	$.each(parent.children, function(i,_item) {
		if (self.isItemInList(_item.data, entries)) {
			targetItemIdx = i - 1;
			return false;
		}
	});
	var targetItemDom = targetItemIdx >= 0
		? parent.children[targetItemIdx].dom.content
		: parent.dom.get("children");
	var action = targetItemIdx >= 0
		? "insertAfter"
		: this.config.get("children.sortOrder") != "chronological" 
			? "prependTo"
			: "appendTo";
	itemsWrapper[action]($(targetItemDom));
	parent.rerender("childrenByCurrentActorLive");
	// we should specify the element height explicitly
	// to avoid element jumping during the animation effect
	itemsWrapper
		.css("height", itemsWrapper.show().css("height"))
		.hide()
		.animate(
			{
				"height": "show",
				"marginTop": "show",
				"marginBottom": "show",
				"paddingTop": "show", 
				"paddingBottom": "show"
			},
			{
				"duration": this.config.get("children.itemsSlideTimeout"),
				"complete": function() {
					itemsWrapper.css("height", "");
					parent.rerender(["expandChildren", "expandChildrenLabel"]);
					itemsWrapper.children().unwrap();
				}
			}
		);
};

Echo.Stream.prototype.getItemListIndex = function(item, items) {
	var idx = -1;
	$.each(items || [], function(i, entry) {
		if (entry == item || (entry.unique && item.unique && entry.unique == item.unique)) {
			idx = i;
			return false;
		}
	});
	return idx;
};

Echo.Stream.prototype.isItemInList = function(item, items) {
	return this.getItemListIndex(item, items) >= 0;
};

Echo.Stream.prototype.isChildrenPaginationEnabled = function() {
	return !!this.config.get("children.itemsPerPage");
};

Echo.Stream.prototype.initItem = function(entry, isLive) {
	var self = this;
	var item = new Echo.Item({
		"children": [],
		"config": new Echo.Config(this.config.getAsHash()),
		"conversation": entry.target.conversationID, // short cut for "conversationID" field
		"data": entry,
		"depth": 0,
		"id": entry.object.id, // short cut for "id" item field
		"live": isLive,
		"threading": false,
		"timestamp": $.timestampFromW3CDTF(entry.object.published),
		"user": this.user
	});
	// caching item template to avoid unnecessary work
	var template = item.template;
	item.template = function() {
		if (!self.vars.cache.itemTemplate) {
			self.vars.cache.itemTemplate = $.isFunction(template)
				? template.apply(this, arguments)
				: template;
		}
		return self.vars.cache.itemTemplate;
	};
	this.items[item.data.unique] = item;
	return item;
};

Echo.Stream.prototype.updateItem = function(entry) {
	var item = this.items[entry.unique];
	// forcing item re-injection if the published date or the respective accumulator was changed
	var sortOrder = this.config.get(this.isRootItem(item) ? "sortOrder" : "children.sortOrder");
	var accRelatedSortOrder = sortOrder.match(/replies|likes|flags/);
	var acc = accRelatedSortOrder && this.getRespectiveAccumulator(item, sortOrder);
	if (item.data.object.published != entry.object.published) {
		item.timestamp = $.timestampFromW3CDTF(entry.object.published);
		item.forceInject = true;
	}
	$.extend(item.data, entry);
	if (accRelatedSortOrder) {
		if (this.getRespectiveAccumulator(item, sortOrder) != acc) {
			item.forceInject = true;
		}
	}
	return item;
};

Echo.Stream.prototype.getItemProjectedIndex = function(item, items, sort) {
	var self = this;
	var index;
	if (item.live || item.forceInject) {
		$.each(items || [], function(i, entry) {
			if (self.compareItems(entry, item, sort)) {
				index = i;
				return false;
			}
		});
	}
	return typeof index != "undefined" ? index : items.length;
};

Echo.Stream.prototype.addItemToList = function(items, item, sort) {
	items.splice(this.getItemProjectedIndex(item, items, sort), 0, item);
	delete item.forceInject;
	this.items[item.data.unique] = item;
};

Echo.Stream.prototype.applyStructureUpdates = function(action, item, options) {
	var self = this;
	options = options || {};
	switch (action) {
		case "add":
			if (!this.isRootItem(item)) {
				var parent = this.getParentItem(item);
				// avoiding problem with missing parent
				if (!parent) {
					delete this.items[item.data.unique];
					return;
				}
				item.depth = parent.depth + 1;
				// backwards compatibility in case children pagination is off
				if (!this.isChildrenPaginationEnabled() && item.depth > 1) {
					item.depth = 1;
					// replace parent of the item
					item.data.parentUnique = parent.data.parentUnique;
					item.data.target.id = parent.data.target.id;
					item.forceInject = true;
					this.applyStructureUpdates("add", item);
					return;
				}
				parent.threading = true;
				item.forceInject = true;
				this.addItemToList(
					parent.children,
					item,
					this.isChildrenPaginationEnabled()
						? this.config.get("children.displaySortOrder")
						: this.config.get("children.sortOrder")
				);
			} else {
				this.addItemToList(this.threads, item, this.config.get("sortOrder"));
			}
			break;
		case "delete":
			var container = null;
			if (this.isRootItem(item)) {
				container = this.threads;
			} else {
				container = this.items[item.data.parentUnique].children;
				if (container.length == 1) {
					var parent = this.getParentItem(item);
					if (parent) parent.threading = false;
				}
			}
			container.splice(this.getItemListIndex(item, container), 1);
			if (!options.keepChildren) {
				item.traverse(item.children, function(child) {
					delete self.items[child.data.unique];
				});
				delete item.children;
			}
			delete this.items[item.data.unique];
			break;
	};
};

Echo.Stream.prototype.normalizeEntry = function(entry) {
	if (entry.normalized) return entry;
	var self = this;
	entry.normalized = true;
	// detecting actual target
	$.each(entry.targets || [], function(i, target) {
		if ((target.id == target.conversationID) ||
			(target.id == entry.object.id) ||
			(self.items[target.id + target.conversationID])) {
				entry.target = target;
		}
	});
	entry.object.content_type = entry.object.content_type || "text";
	entry.object.accumulators = entry.object.accumulators || {};
	entry.object.accumulators.repliesCount =
				parseInt(entry.object.accumulators.repliesCount || "0");
	entry.object.accumulators.flagsCount =
				parseInt(entry.object.accumulators.flagsCount || "0");
	entry.object.accumulators.likesCount =
				parseInt(entry.object.accumulators.likesCount || "0");
	entry.object.context = entry.object.context || [];
	entry.object.flags = entry.object.flags || [];
	entry.object.likes = entry.object.likes || [];
	entry.target = entry.target || entry.targets[0] || {};
	entry.target.conversationID = entry.target.conversationID || entry.object.id;
	entry.source = entry.source || {};
	entry.provider = entry.provider || {};
	entry.unique = entry.object.id + entry.target.conversationID;
	entry.parentUnique = entry.target.id + entry.target.conversationID;
	return entry;
};

Echo.Stream.prototype.addCss = function() {
	var self = this;
	$.addCss(
		'.echo-stream-message-wrapper { padding: 15px 0px; text-align: center; -moz-border-radius: 0.5em; -webkit-border-radius: 0.5em; border: 1px solid #E4E4E4; }' +
		'.echo-stream-message-empty, .echo-stream-message-loading, .echo-stream-message-error { display: inline-block; height: 16px; padding-left: 21px; background: no-repeat left center; }' +
		'.echo-stream-message-empty { background-image: url(//c0.echoenabled.com/images/information.png); }' +
		'.echo-stream-message-loading { background-image: url(//c0.echoenabled.com/images/loading.gif); }' +
		'.echo-stream-message-error { background-image: url(//c0.echoenabled.com/images/warning.gif); }' +
		'.echo-stream-header { margin: 10px 0px 10px 20px; }' +
		'.echo-stream-state { float: right; }' +
		'.echo-stream-state-picture { display: inline-block; height: 9px; width: 8px; }' +
		'.echo-stream-state-picture-paused { background: url("//c0.echoenabled.com/images/control_pause.png") no-repeat center center; }' +
		'.echo-stream-state-picture-live { background: url("//c0.echoenabled.com/images/control_play.png") no-repeat center center; }' +
		'.echo-stream-state-message { margin-left: 5px; text-decoration: none; }' +
		'.echo-clickable a.echo-stream-state-message:hover { text-decoration: underline; }' +
		'.echo-stream-brand { text-align: right; display: none; }' +
		'.echo-stream-brand-message { display: inline-block; height: 17px; line-height: 17px; border: none; padding-right: 48px; background: url(//c0.echoenabled.com/images/echo-brand.png) no-repeat right; font-size: 10px; font-family: Arial; }' +
		'.echo-stream-container a.echo-stream-brand-link { text-decoration: none; color: #666666; } ' +
		'.echo-stream-more-hover { background-color: #E4E4E4; }' +
		'.echo-stream-more { text-align: center; border: solid 1px #E4E4E4; margin-top: 10px; padding: 10px; -moz-border-radius: 0.5em; -webkit-border-radius: 0.5em; cursor: pointer; font-weight: bold; }' +
		'.echo-stream-more .echo-application-message { padding: 0; border: none; border-radius: 0; }'
	, 'stream');

	$.addCss(
		'.echo-item-content { word-wrap: break-word; }' +
		'.echo-item-container-root { padding: 10px 0px; }' +
		'.echo-item-container-root-thread { padding: 10px 0px 0px 0px; }' +
		'.echo-item-container-child { padding: 10px; margin: 0px 20px 2px 0px; }' +
		'.echo-item-container-child-thread { padding: 10px; margin: 0px 20px 2px 0px; }' +
		'.echo-item-avatar-wrapper { margin-right: -58px; float: left; position: relative; }' +
		'.echo-item-children .echo-item-avatar-wrapper, .echo-item-childrenByCurrentActorLive .echo-item-avatar-wrapper { margin-right: -34px; }' +
		'.echo-item-children .echo-item-subwrapper, .echo-item-childrenByCurrentActorLive .echo-item-subwrapper { margin-left: 34px; }' +
		'.echo-item-wrapper { float: left; width: 100%; }' +
		'.echo-item-subwrapper { margin-left: 58px; }' +
		'.echo-item-subcontainer { float: left; width: 100%; }' +
		'.echo-item-markers { line-height: 16px; background: url(//c0.echoenabled.com/images/curation/metadata/marker.png) no-repeat; padding: 0px 0px 4px 21px; margin-top: 7px; }' +
		'.echo-item-tags { line-height: 16px; background: url(//c0.echoenabled.com/images/tag_blue.png) no-repeat; padding: 0px 0px 4px 21px; }' +
		'.echo-item-metadata { display: none; }' +
		'.echo-item-metadata-title { font-weight: bold; line-height: 25px; height: 25px; margin-right: 5px; }' +
		'.echo-item-metadata-icon { display: inline-block; padding-left: 26px; }' +
		'div.echo-item-metadata-userID { border-bottom: 1px solid #e1e1e1; border-top: 1px solid #e1e1e1;}' +
		'span.echo-item-metadata-userID { background: url("//c0.echoenabled.com/images/curation/metadata/user.png") no-repeat left center; }' +
		'.echo-item-modeSwitch { float: right; width: 16px; height: 16px; background:url("//c0.echoenabled.com/images/curation/metadata/flip.png") no-repeat 0px 3px; }' +
		'.echo-item-childrenMarker { border-color: transparent transparent #ECEFF5; border-width: 0px 11px 11px; border-style: solid; margin: 3px 0px 0px 77px; height: 1px; width: 0px; display: none; }' + // This is magic "arrow up". Only color and margins could be changed
		'.echo-item-container-root-thread .echo-item-childrenMarker { display: block; }' +
		'.echo-item-avatar { width: 48px; height: 48px; }' +
		'.echo-item-children .echo-item-avatar, .echo-item-childrenByCurrentActorLive .echo-item-avatar { width: 24px; height: 24px; }' +
		'.echo-item-authorName { float: left; font-size: 15px; font-family: Arial, sans-serif; font-weight: bold; }' +
		'.echo-item-re { font-weight: bold; }' +
		'.echo-item-re a:link, .echo-item-re a:visited, .echo-item-re a:active { text-decoration: none; }' +
		'.echo-item-re a:hover { text-decoration: underline; }' +
		'.echo-item-body { padding-top: 4px; }' +
		'.echo-item-controls { float: left; margin-left: 3px; }' +
		'.echo-item-sourceIcon { float: left; height: 16px; width: 16px; margin-right: 5px; border: 0px; }' +
		'.echo-item-date, .echo-item-from, .echo-item-via { float: left; }' +
		'.echo-item-from a, .echo-item-via a { text-decoration: none; color: #C6C6C6; }' +
		'.echo-item-from a:hover, .echo-item-via a:hover { color: #476CB8; }' +
		'.echo-item-tag { display: inline-block; height: 16px; background: url("//c0.echoenabled.com/images/tag_blue.png") no-repeat; padding-left: 18px; }' +
		'.echo-item-smiley-icon { border: 0px; }' +
		'.echo-item-textToggleTruncated { margin-left: 5px; }' +
		'.echo-item-blocker-backdrop { position: absolute; left: 0px; top: 0px; background: #FFFFFF; opacity: 0.7; z-index: 100; }' +
		'.echo-item-blocker-message { position: absolute; z-index: 200; width: 200px; height: 20px; line-height: 20px; text-align: center; background-color: #FFFF99; border: 1px solid #C6C677; opacity: 0.7; -moz-border-radius: 0.5em 0.5em 0.5em 0.5em; }' +
		'.echo-item-expandChildren { display:none; text-align: center; padding:4px; }' +
		'.echo-item-expandChildren .echo-item-expandChildrenLabel { display: inline-block; padding-left: 22px; }' +
		'.echo-item-expandChildren .echo-message-icon { background: url("//c0.echoenabled.com/images/whirlpool.png") no-repeat 5px 4px; }' +
		'.echo-item-expandChildren .echo-item-message-loading { background: no-repeat left top url(//c0.echoenabled.com/images/loading.gif); }' +
		'.echo-item-expandChildren .echo-application-message { padding: 0; border:none; border-radius: 0; }'
	, 'item');

	var itemDepthRules = [];
	// 100 is a maximum level of children in query, but we can apply styles for ~20
	for (var i = 0; i <= 20; i++) {
		itemDepthRules.push('.echo-item-depth-' + i + ' { margin-left: ' + (i ? 68 + (i - 1) * 44 : 0) + 'px; }');
	}
	$.addCss(itemDepthRules.join("\n"), "item-depths");

	if ($.browser.msie) {
		$.addCss(
			'.echo-item-childrenMarker { font-size: 1px; line-height: 1px; filter: chroma(color=black); }' + // filter:chroma is needed to avoid transparent borders as black in ie6
			'.echo-item-blocker-backdrop, .echo-item-blocker-message { filter:Alpha(Opacity=70); }' +
			'.echo-stream-container { zoom: 1; }' +
			'.echo-item-content { zoom: 1; }' +
			'.echo-item-container { zoom: 1; }' +
			'.echo-item-subwrapper { zoom: 1; }' +
			'.echo-item-avatar-wrapper { position: static; }' +
			'.echo-stream-state-picture { vertical-align: middle; }'
		, 'stream-ie');
	}
};
})(jQuery);





(function($) {
Echo.Localization.extend({
	"createdBy": "Created by",
	"loading": "Loading...",
	"markers": "Markers:",
	"markersHint": "Marker1, marker2, marker3, ...",
	"on": "on",
	"post": "Post",
	"posting": "Posting...",
	"postingFailed": "There was a server error while trying to submit your item. Please try again in a few minutes. <b>Error: \"{error}\"</b>.",
	"postingTimeout": "There was a network issue while trying to submit your item. Please try again in a few minutes.",
	"tagsHint": "Tag1, tag2, tag3, ...",
	"tags": "Tags:",
	"update": "Update",
	"updating": "Updating...",
	"yourName": "Your Name (required)",
	"yourWebsiteOptional": "Your website (optional)"
}, "Submit");

Echo.Submit = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.initConfig(config, {
		"targetURL": document.location.href,
		"submissionProxyURL": window.location.protocol + "//apps.echoenabled.com/v2/esp/activity",
		"markers": [],
		"source": {},
		"tags": [],
		"requestMethod": "GET",
		"mode": "standard",
		"data": {},
		"inReplyTo": {},
		"itemURIPattern": undefined,
		"actionString": "Type your comment here...",
		"postingTimeout": 30,
		"targetQuery": undefined
	});
	this.initialMode = this.config.get("mode");
	this.initApplication(function() {
		self.contextId = self.config.get("contextId", self.newContextId());
		self.addCss();
		self.config.get("target").empty().append(self.render());
		self.listenEvents();
		self.publish("Submit.onRender", self.prepareBroadcastParams());
	});
};

Echo.Submit.prototype = new Echo.Application();

Echo.Submit.prototype.namespace = "Submit";

Echo.Submit.prototype.cssPrefix = "echo-submit-";

Echo.Submit.prototype.template = function() {
	return this.templates[this.config.get("mode")];
};

Echo.Submit.prototype.templates = {};

Echo.Submit.prototype.templates.standard =
	'<div class="echo-submit-container">' +
		'<div class="echo-submit-header"></div>' +
		'<div class="echo-submit-body">' +
			'<div class="echo-submit-content echo-submit-border">' +
				'<textarea class="echo-submit-text echo-submit-text-area echo-primaryFont echo-primaryColor"></textarea>' +
			'</div>' +
			'<div class="echo-submit-markersContainer echo-submit-metadata-container echo-primaryFont echo-primaryColor">' +
				'<div class="echo-submit-metadata-label">{Label:markers}</div>' +
				'<div class="echo-submit-metadata-wrapper">' +
					'<div class="echo-submit-metadata-subwrapper echo-submit-border ">' +
						'<input class="echo-submit-markers echo-primaryFont">' +
					'</div>' +	
				'</div>' +
				'<div class="echo-clear"></div>' +
			'</div>' +
			'<div class="echo-submit-tagsContainer echo-submit-metadata-container echo-primaryFont echo-primaryColor">' +
				'<div class="echo-submit-metadata-label">{Label:tags}</div>' +
				'<div class="echo-submit-metadata-wrapper">' +
					'<div class="echo-submit-metadata-subwrapper echo-submit-border ">' +
						'<input class="echo-submit-tags echo-submit-border echo-primaryFont">' +
					'</div>' +
				'</div>' +
				'<div class="echo-clear"></div>' +
			'</div>' +
		'</div>' +
		'<div class="echo-submit-controls">' +
			'<div class="echo-submit-post-container echo-ui">' +
				'<button type="button" class="echo-submit-postButton echo-primaryFont"></button>' +
			'</div>' +
			'<div class="echo-clear"></div>' +
		'</div>' +
	'</div>';

Echo.Submit.prototype.templates.edit = Echo.Submit.prototype.templates.standard;

Echo.Submit.prototype.templates.compact =
	'<div class="echo-submit-container">' +
		'<div class="echo-submit-content echo-submit-border">' +
			'<input class="echo-submit-text echo-submit-text-input echo-primaryFont echo-primaryColor">' +
		'</div>' +
	'</div>';

Echo.Submit.prototype.renderers = {};

Echo.Submit.prototype.renderers.container = function(element) {
	if (this.initialMode == "compact") {
		element.click(function(event) { event.stopPropagation(); });
	}
};

Echo.Submit.prototype.renderers.tagsContainer = 
Echo.Submit.prototype.renderers.markersContainer = function(element, dom) {
	if (this.user.isAdmin()) {
		element.show();
	} else {
		element.hide();
	}
};

Echo.Submit.prototype.renderers.metaFields = function(element, dom, extra) {
	var type = extra.type;
	var data = this.config.get("data.object." + type, this.config.get(type, []));
	dom.get(type)
		.iHint({
			"text": this.label(type + "Hint"),
			"className": "echo-secondaryColor"
		})
		.val($.trim($.stripTags(data.join(", "))))
		.blur();
};

Echo.Submit.prototype.renderers.markers = function(element, dom) {
	this.render("metaFields", element, dom, {"type": "markers"});
};

Echo.Submit.prototype.renderers.tags = function(element, dom) {
	this.render("metaFields", element, dom, {"type": "tags"});
};

Echo.Submit.prototype.renderers.editModeUserInfo = function(element, dom) {
	var template =
		'<div class="echo-submit-userInfoWrapper echo-primaryFont echo-primaryFont echo-primaryColor">' +
			'{Label:createdBy} ' +
			'<span class="echo-submit-author">{Data:author}</span> ' +
			'{Label:on} {Data:date}' +
		'</div>';
	var descriptors = {};
	var published = this.config.get("data.object.published");
	var date = new Date($.timestampFromW3CDTF(published) * 1000);
	return $.toDOM(this.substitute(template, {
		"date": date.toLocaleDateString() + ', ' + date.toLocaleTimeString(),
		"author": this.config.get("data.actor.title", this.label("guest"))
	}), this.cssPrefix, {}).content;
};

Echo.Submit.prototype.renderers.anonymousModeUserInfo = function(element, dom) {
	var self = this;
	var prefix = "echo-submit-anonymousUserInfo";
	var template = 
		'<div class="echo-submit-userInfoWrapper">' +
			'<div class="{Data:prefix}Avatar"></div>' +
			'<div class="{Data:prefix}Fields">' +
				'<div class="{Data:prefix}FieldsWrapper">' +
					'<div class="{Data:prefix}NameContainer echo-submit-border">' +
						'<input class="{Data:prefix}Name echo-primaryFont echo-primaryColor">' +
					'</div>' +
					'<div class="{Data:prefix}UrlContainer echo-submit-border">' +
						'<input class="{Data:prefix}Url echo-primaryFont echo-primaryColor">' +
					'</div>' +
				'</div>' +
			'</div>' +
			'<div class="echo-clear"></div>' +
		'</div>';
	var descriptors = {
		"Avatar" : function(element){
			var avatar = self.user.get("avatar", self.user.get("defaultAvatar"));
			element.append('<img src="' + avatar + '">');
			// avatars manager will be developed later
		},
		"Name" : function(element) {
			dom.set("anonymousUserInfoName", element);
			element.val(self.user.get("name", "")).iHint({
				"text": self.label("yourName"),
				"className": "echo-secondaryColor"
			});
		},
		"Url" : function(element) {
			dom.set("anonymousUserInfoUrl", element);
			element.val(self.user.get("domain", "")).iHint({
				"text": self.label("yourWebsiteOptional"),
				"className": "echo-secondaryColor"
			});
		}
	};
	var template = this.substitute(template, {"prefix": prefix});
	return $.toDOM(template, prefix, descriptors).content;
};

Echo.Submit.prototype.renderers.header = function(element, dom) {
	var mode = this.config.get("mode") == "edit" ? "edit": "anonymous";
	return this.render(mode + "ModeUserInfo", element, dom);
}

Echo.Submit.prototype.renderers.text = function(element) {
	var self = this, content = this.config.get("data.object.content");
	if (content) {
		element.val(content);
	}
	element.iHint({
		"text": self.config.get("actionString"),
		"className": "echo-secondaryColor"
	});
	if (this.config.get("mode") == "compact") {
		element.focus(function() {
			self.config.set("mode", "standard");
			self.rerender();
			setTimeout(function() {
				self.dom.get("text").focus();
			}, 0);
			self.publish("Submit.onExpand", self.prepareBroadcastParams());
		});
	}
};

Echo.Submit.prototype.renderers.postButton = function(element) {
	var self = this, isEditMode = this.config.get("mode") == "edit";
	var button = new Echo.UI.Button(element, {
		"normal": {
			"icons": false,
			"disabled": false,
			"label": self.label(isEditMode ? "update" : "post")
		},
		"posting": {
			"icons": {
				"primary": "ui-icon-waiting"
			},
			"disabled": true,
			"label": self.label(isEditMode ? "updating" : "posting")
		}
	});

	self.posting = self.posting || {};
	self.posting.subscriptions = self.posting.subscriptions || [];
	var subscribe = function(phase, state, handler) {
		$.each(["Post", "Edit"], function (i, v) {
			var topic = "Submit.on" + v + phase;
			var sub = self.posting.subscriptions;
			if (sub[topic])
				self.unsubscribe(topic, sub[topic]);
			sub[topic] = self.subscribe(topic, function(eventTopic, eventParams) {
				if (self.config.get("target").get(0) != eventParams.target) return;
				button.setState(state);
				if (handler) handler();
			});
		});
	}
	subscribe("Init", "posting");
	subscribe("Complete", "normal", function() {
		self.dom.get("text").val("").trigger("blur");
		self.rerender(["tagsContainer", "markersContainer"]);
	});
	subscribe("Error", "normal");

	this.posting.action = this.posting.action || function() {
		var highlighted = false;
		$.each(["anonymousUserInfoName", "text"], function (i, v) {
			highlighted = self.highlightMandatory(self.dom.get(v));
			return !highlighted;
		});
		if (highlighted) return;
		self.post();
	};
	element.unbind("click", this.posting.action).bind("click", this.posting.action);
};

Echo.Submit.prototype.post = function() {
	var self = this, isEditMode = this.config.get("mode") == "edit";
	var get = function(name) {
		return self.dom.get(name);
	};
	var publish = function(phase, data) {
		var mode = isEditMode ? "Edit" : "Post";
		self.publish("Submit.on" + mode + phase, self.prepareBroadcastParams({
			"postData": data
		}));
	};
	var content;
	if (isEditMode) {
		content = [].concat(
			self.getContentUpdate(get("text").val()),
			self.getMetaDataUpdates("tag", "tags", get("tags").val()),
			self.getMetaDataUpdates("mark", "markers", get("markers").val())
		);
		if (!content.length) {
			publish("Complete", []);
			return;
		}
	} else {
		content = {
			"avatar" : self.user.get("avatar", ""),
			"content" : get("text").val(),
			"markers" : $.trim(get("markers").val()),
			"name" : self.user.get("name", (self.user.logged()
					? ""
					: get("anonymousUserInfoName").val())),
			"source" : self.config.get("source"),
			"tags" : $.trim(get("tags").val()),
			"target" : self.config.get("targetURL"),
			"url" : self.user.get("domain", (self.user.logged()
					? ""
					: get("anonymousUserInfoUrl").val())),
			"verb" : "post"
		};
		if (self.config.get("itemURIPattern")) {
			content.itemURIPattern = self.config.get("itemURIPattern");
		}
	};
	var timer;
	var hasPreviousTimeout = false;
	var callback = function(data) {
		if (timer) clearTimeout(timer);
		data = data || {};
		if (data.result == "error") {
			// we have previous timeout on the client side so we just ignore errors from server side
			if (hasPreviousTimeout) return;
			var isTimeout = hasPreviousTimeout = (data.errorCode == "timeout");
			var message = isTimeout
				? self.label("postingTimeout")
				: self.label("postingFailed", {"error": data.errorMessage || data.errorCode});
			$.fancybox({
				"content": '<div class="echo-submit-error">' + message + '</div>',
				"height": 70,
				"width": isTimeout ? 320 : 390,
				"padding": 15,
				"orig": get("text"),
				"autoDimensions": false,
				"transitionIn": "elastic",
				"transitionOut": "elastic",
				"onComplete": function() {
					// set fixed dimensions of the fancybox-wrap (for IE in quirks mode it should be bigger)
					if ($.browser.msie && document.compatMode != "CSS1Compat") {
						var options = arguments[2];
						var delta = 2 * options.padding + 40;
						$("#fancybox-wrap").css({
							"width": options.width + delta,
							"height": options.height + delta
						});
					}
				}
			});
			publish("Error", data);
		} else {
			publish("Complete", content);
		}
	};
	publish("Init", content);
	var entry = {
		"appkey" : self.config.get("appkey"),
		"content" : $.object2JSON(content),
		"sessionID": self.user.get("sessionID", "")
	};
	if (self.config.get("targetQuery")) entry["target-query"] = self.config.get("targetQuery"); 
	if (this.config.get("requestMethod").toLowerCase() == "post") {
		$.sendPostRequest(this.config.get("submissionProxyURL"), entry, callback);
	} else {
		$.ajax({
			"type": "GET",
			"url": this.config.get("submissionProxyURL"),
			"data": entry,
			"success": callback,
			"error": function() {
				callback({"result": "error", "errorCode": "internal_error"});
			},
			"dataType": "jsonp"
		});
		var postingTimeout = this.config.get("postingTimeout");
		if (postingTimeout) {
			timer = setTimeout(function() {
				callback({"result": "error", "errorCode": "timeout"});
			}, postingTimeout * 1000);
		}
	}
};

Echo.Submit.prototype.highlightMandatory = function(element) {
	if (element && !$.trim(element.val())) {
		element.parent().addClass("echo-submit-mandatory");
		element.focus(function() {
			$(this).parent().removeClass("echo-submit-mandatory");
		});
		return true;
	}
	return false;
};

Echo.Submit.prototype.prepareBroadcastParams = function(params) {
	params = params || {};
	params.data = this.config.get("data");
	params.target = this.config.get("target").get(0);
	params.targetURL = this.config.get("targetURL");
	params.inReplyTo = this.config.get("inReplyTo");
	return params;
};

Echo.Submit.prototype.getContentUpdate = function(content) {
	if (this.config.get("data.object.content", "") == content) {
		return [];
	}
	return [{
		"verb": "update",
		"field": "content",
		"value": content,
		"target": this.config.get("data.object.id")
	}];
};

Echo.Submit.prototype.getMetaDataUpdates = function(verb, type, data) {
	var self = this;
	var extract = function(value) {
		return $.map(value || [], function(item) { return $.trim(item); });
	};
	var items = {
		"modified": extract(data.split(",")),
		"current": extract(this.config.get("data.object." + type, ""))
	};
	var updates = [];
	var diff = function(a, b, verb) {
		$.map(a, function(item) {
			if (item && $.inArray(item, b) == -1) {
				var update = {
					"verb": verb,
					"target": self.config.get("data.object.id")
				};
				update[type] = item
				updates.push(update);
			}
		});
	};
	diff(items.current, items.modified, "un" + verb);
	diff(items.modified, items.current, verb);
	return updates;
};

Echo.Submit.prototype.switchMode = function(mode) {
	if (!mode) {
		mode = (this.config.get("mode") == "standard" ? "compact" : "standard");
	}
	if (this.config.get("mode") != mode) {
		this.config.set("mode", mode);
		this.rerender();
		var topic = "Submit.on" + (mode == "compact" ? "Collapse" : "Expand");
		this.publish(topic, this.prepareBroadcastParams());
	}
};

Echo.Submit.prototype.refresh = function() {
	this.rerender(["container", "header", "markersContainer", "tagsContainer", "postButton"]);
	this.publish("Submit.onRerender", this.prepareBroadcastParams());
};

Echo.Submit.prototype.listenEvents = function() {
	var self = this;
	this.subscribe("internal.User.onInvalidate", function() {
		self.refresh();
	});
	if (this.initialMode == "compact") {
		Echo.Broadcast.subscribe("document.onclick", function() {
			if (self.dom && self.dom.get("text").val()) return;
			self.switchMode("compact");
		});
		if (!Echo.Vars.onClickRegistered) {
			$(document).click(function() {
				Echo.Broadcast.publish("document.onclick");
			});
			Echo.Vars.onClickRegistered = true;
		}
	}
};

Echo.Submit.prototype.addCss = function() {
	$.addCss(
		'.echo-submit-header { margin-bottom: 3px; }' +
		'.echo-submit-anonymousUserInfoAvatar { float: left; margin-right: -48px; }' +
		'.echo-submit-anonymousUserInfoAvatar img { width: 48px; height: 48px; }' +
		'.echo-submit-anonymousUserInfoFields { width: 100%; float: left; }' +
		'.echo-submit-anonymousUserInfoFields input { width: 100%; }' +
		'.echo-submit-anonymousUserInfoFieldsWrapper { margin-left: 53px; }' +
		'.echo-submit-anonymousUserInfoNameContainer { margin: 1px 0px 4px 0px; padding: 0px 2px 1px 3px; background-color: #fff; }' +
		'.echo-submit-anonymousUserInfoName { font-size: 14px; font-weight: bold; border: none; }' +
		'.echo-submit-anonymousUserInfoUrlContainer { padding: 0px 2px 1px 3px; background-color: #fff; }' +
		'.echo-submit-anonymousUserInfoUrl { height: 19px; border: none; }' +
		'.echo-submit-author { font-weight: bold; }' +
		'.echo-submit-content { padding: 5px 5px 5px 6px; background-color: #fff; }' +
		'.echo-submit-text-area { width: 100%; height: 102px; padding: 0px; margin: 0px; border: none; resize:none ; }' +
		'.echo-submit-text-input { width: 100%; border: none; }' +
		'.echo-submit-metadata-container { margin-top: 6px; }' +
		'.echo-submit-metadata-label { float: left; width: 50px; margin-right: -50px; text-align: right; line-height: 22px; }' +
		'.echo-submit-metadata-wrapper { float: left; width: 100%; }' +
		'.echo-submit-metadata-subwrapper { margin-left: 55px; padding: 2px 2px 2px 3px; background-color: #fff; }' +
		'.echo-submit-metadata-subwrapper input { width: 100%; border: none; }' +
		'.echo-submit-controls { margin-top: 5px; }' +
		'.echo-submit-post-container { float: right; }' +
		'.echo-submit-border { border: 1px solid #d2d2d2; }' +
		'.echo-submit-mandatory { border: 1px solid red; }' +
		'.echo-submit-queries-view-option { padding-right: 5px; }' +
		'.echo-submit-error { color: #444444; font: 14px Arial; line-height: 150%; padding-left: 85px; background: no-repeat url(http://c0.echoenabled.com/images/info70.png); height: 70px; }'
	, 'submit');

	if ($.browser.msie) {
		$.addCss(
			'.echo-submit-container { zoom: 1; }' +
			'.echo-submit-body { zoom: 1; }' +
			'.echo-submit-header { zoom: 1; }' +
			'.echo-submit-content { zoom: 1; }' +
			'.echo-submit-markersContainer { zoom: 1; }' +
			'.echo-submit-tagsContainer { zoom: 1; }'
		, 'submit-ie');
	}

	if ($.browser.webkit) {
		$.addCss(
			// get rid of extra gray line inside input elements on iOS
			'.echo-submit-container input, .echo-submit-container textarea { background-position: 0px; }' +
			'.echo-submit-text-area { outline: none; }' +
			'.echo-submit-anonymousUserInfoName { outline: none; }' +
			'.echo-submit-anonymousUserInfoUrl { outline: none; }' +
			'.echo-submit-metadata-subwrapper input { outline: none; }'
		, 'submit-webkit');
	}
};
})(jQuery);





(function($) {
Echo.Localization.extend({
	"you": "You"
}, "UserListItem");

Echo.UserListItem = function(data) {
	this.vars = {};
	this.init(data);
	this.addCss();
};

Echo.UserListItem.prototype = new Echo.Object();

Echo.UserListItem.prototype.namespace = "UserListItem";

Echo.UserListItem.prototype.cssPrefix = "echo-user-list-item-";

Echo.UserListItem.prototype.renderers = {};

Echo.UserListItem.prototype.template =
'<span class="echo-user-list-item-container">' +
	'<img class="echo-user-list-item-avatar">' +
	'<span class="echo-user-list-item-title">{Data:title}</span>' +
'</span>';

Echo.UserListItem.prototype.renderers.avatar = function(element, dom) {
	var self = this;
	var url = this.data.avatar || this.user.get("defaultAvatar");
	if (this.config.get("userLabel.avatar")) {
		element.attr("src", url).bind({
			"error" : function(){
				$(this).attr("src", self.user.get("defaultAvatar"));
			}
		});
		if (!this.config.get("userLabel.text")) {
			element.attr("title", this.data.title);
		}
	} else {
		dom.remove(element);
	}
};

Echo.UserListItem.prototype.renderers.title = function(element, dom) {
	if (this.config.get("userLabel.text")) {
		return this.isYou() ? this.label("you") : this.data.title;
	} else {
		dom.remove(element);
	}
};

Echo.UserListItem.prototype.isYou = function() {
	return this.data.id && this.data.id == this.user.get('id');
};

Echo.UserListItem.prototype.addCss = function() {
	$.addCss(
		'.echo-user-list-item-avatar { width: 16px; height: 16px; margin: 0px 3px 0px 0px; vertical-align: text-top; }' +
		'.echo-user-list-only-avatars .echo-user-list-item-avatar { margin: 0px 2px; }' +
		'.echo-user-list-item-container, .echo-user-list-item-container span { white-space: nowrap; }' +
		'.echo-user-list-only-avatars .echo-user-list-item-container { white-space: normal; }'
	, 'user-list-item');
};

Echo.Localization.extend({
	"and": "and",
	"more": "more"
}, "UserList");

Echo.UserList = function(config) {
	if (!config || !config.target) return;
	var self = this;
	this.vars = {};
	this.initVars();
	this.initConfig(config, {
		"checkViewTimeout": 2,
		"initialUsersCount": undefined,
		"totalUsersCount": undefined,
		"query": "",
		"suffixText": "",
		"userLabel": {
			"avatar": true,
			"text": true
		}
	});
	this.messageLayout = "compact";
	this.initApplication(function() {
		self.addCss();
		self.config.get("target").empty().append(self.render());
		if (self.config.get("query")) {
			self.showMessage({
				"type": "loading"
			}, self.dom.get("container"));
			self.initLiveUpdates(function() {
				return {
					"endpoint": "search",
					"query": {
						"q": self.config.get("query"),
						"since": self.nextSince || 0
					}
				};
			}, function(data) {
				self.handleLiveUpdatesResponse(data);
			});
			self.request();
		} else if (self.config.get("data")) {
			var data = self.config.get("data");
			data.itemsPerPage = data.itemsPerPage || 2;
			self.config.set("liveUpdates", false);
			self.handleInitialResponse(data);
		}
	});
};

Echo.UserList.prototype = new Echo.Application();

Echo.UserList.prototype.namespace = "UserList";

Echo.UserList.prototype.cssPrefix = "echo-user-list-";

Echo.UserList.prototype.template =
	'<span class="echo-user-list-container">' +
		'<span class="echo-user-list-actors"></span>' +
		'<span class="echo-user-list-more"></span>' +
		'<span class="echo-user-list-suffixText"></span>' +
	'</span>';

Echo.UserList.prototype.renderers = {};

Echo.UserList.prototype.renderers.more = function(element) {
	var self = this;
	if (!this.isMoreButtonVisible()) {
		element.hide();
		return;
	}
	element.empty().show();
	var count = this.count.total - this.count.visible;
	var caption = (count > 0 ? count + " " : "") + this.label("more");
	var linkable = !this.fromExternalData() || this.count.visible < this.users.length;
	if (linkable) {
		element.addClass("echo-linkColor").append(this.hyperlink({"caption": caption}));
	} else {
		element.removeClass("echo-linkColor").append(caption);
	}
	this.moreRequestInProgress = false;
	if (linkable) {
		element.one("click", function() {
			self.getMoreUsers();
		});
	}
};

Echo.UserList.prototype.renderers.actors = function(element) {
	var self = this;
	if (!this.users.length) return;
	var usersDOM = [];
	var userLabel = this.config.get("userLabel");
	if (!this.users.length || !userLabel.avatar && !userLabel.text) return;

	var action = (userLabel.avatar && !userLabel.text ? "addClass" : "removeClass");
	element[action]("echo-user-list-only-avatars");
	var wrap = function(text, name) {
		var classAttr = name ? ' class="echo-user-list-' + name + '"' : '';
		return "<span" + classAttr + ">" + text + "</span>";
	};
	$.map(this.users.slice(0, this.count.visible), function(user) {
		usersDOM.push(user.instance.render());
	});
	var delimiter = this.config.get("userLabel.text") ? ", " : "";
	var last;
	if (!this.isMoreButtonVisible()) last = usersDOM.pop();
	if (usersDOM.length) {
		usersDOM = delimiter
			? $.intersperse(usersDOM, wrap(delimiter, "delimiter"))
			: usersDOM;
		// use &nbsp; instead of simple space because IE will cut off simple one after <span>
		usersDOM.push(wrap("&nbsp;" + this.label("and") + " ", "and"));
	}
	if (!this.isMoreButtonVisible()) usersDOM.push(last);
	$.map(usersDOM, function(chunk) {
		element.append(chunk);
	});
};

Echo.UserList.prototype.renderers.suffixText = function() {
	return this.config.get("suffixText", "");
};

Echo.UserList.prototype.initVars = function() {
	this.users = [];
	this.uniqueUsers = {};
	this.isViewComplete = false;
	delete this.nextPageAfter;
	this.count = {
		"total": 0,
		"visible": 0
	};
	this.cleanupErrorHandlers();
};

Echo.UserList.prototype.isMoreButtonVisible = function() {
	return !this.fromExternalData() && !this.isViewComplete || this.count.visible < this.count.total;
};

Echo.UserList.prototype.fromExternalData = function() {
	return !this.config.get("query") && !!this.config.get("data");
};

Echo.UserList.prototype.getMoreUsers = function() {
	if (this.fromExternalData()) {
		this.count.visible += this.config.get("itemsPerPage");
		if (this.count.visible > this.users.length) {
			this.count.visible = this.users.length;
		}
		this.rerender();
	} else {
		if (!this.moreRequestInProgress) {
			this.showMessage({
				"type": "loading"
			}, this.dom.get("more"));
			this.moreRequestInProgress = true;
		}
		this.request();
	}
};

Echo.UserList.prototype.request = function() {
	var self = this;
	var query = this.config.get("query");
	if (typeof this.nextPageAfter != "undefined") {
		query = 'pageAfter:"' + this.nextPageAfter + '" ' + query;
	}
	this.sendAPIRequest({
		"endpoint": "search",
		"query": {"q": query}
	}, function(data) {
		self.changeLiveUpdatesTimeout(data);
		self.handleInitialResponse(data);
	});
};

Echo.UserList.prototype.handleInitialResponse = function(data) {
	if (data.result == "error") {
		this.handleErrorResponse(data);
		return;
	}
	this.cleanupErrorHandlers(true);
	if (data.itemsPerPage && data.itemsPerPage != this.config.get("itemsPerPage")) {
		this.config.set("itemsPerPage", +data.itemsPerPage);
	}
	if (this.fromExternalData()) {
		this.count.total = this.config.get("totalUsersCount", 0);
	}
	this.nextSince = data.nextSince || 0;
	this.nextPageAfter = data.nextPageAfter || 0;
	if (!data.entries.length) {
		if (!this.isViewComplete) {
			this.isViewComplete = true;
			this.rerender();
		}
		this.startLiveUpdates();
		return;
	}
	if (!this.count.visible) {
		if (this.fromExternalData()) {
			this.count.visible = this.config.get("initialUsersCount", this.config.get("itemsPerPage"));
		} else {
			this.count.visible = this.config.get("itemsPerPage");
		}
	}
	this.processResponse(data);
};

Echo.UserList.prototype.handleLiveUpdatesResponse = function(data) {
	var self = this;
	if (data.result == "error") {
		this.startLiveUpdates();
		return;
	}
	this.nextSince = data.nextSince || 0;
	if (!data.entries.length) {
		this.startLiveUpdates();
		return;
	}
	this.processResponse(data, true);
};

Echo.UserList.prototype.processResponse = function(data, isLive) {
	var self = this;
	var config = new Echo.Config(this.config.getAsHash());
	var usersAdded = false;
	var usersDeleted = false;
	$.each(data.entries, function(i, entry) {
		var isDeleting = (entry.verbs && entry.verbs[0] == "http://activitystrea.ms/schema/1.0/delete");
		var user = self.uniqueUsers[entry.actor.id];
		if (isDeleting && !user) return;
		if (isDeleting) {
			if (!--user.itemsCount) {
				var index;
				$.each(self.users, function(i, u) {
					if (u.instance.data.id == entry.actor.id) {
						index = i;
						return false; // break
					}
				});
				self.users.splice(index, 1);
				delete self.uniqueUsers[entry.actor.id];
				usersDeleted = true;
			}
		} else if (user) {
			user.itemsCount++;
		} else {
			var userInstance = new Echo.UserListItem({
				"data": entry.actor,
				"user": self.user,
				"config": config
			});
			user = {
				"itemsCount": 1,
				"instance": userInstance
			};
			self.users[userInstance.isYou() ? "unshift" : "push"](user);
			self.uniqueUsers[entry.actor.id] = user;
			usersAdded = true;
		}
	});
	if (this.fromExternalData()) {
		this.count.total = Math.max(this.users.length, this.count.total);
	} else {
		this.count.total = this.count.visible = this.users.length;
	}
	this.count.visible = Math.min(this.count.visible, this.users.length);
	if (!this.count.total) this.isViewComplete = false;
	if (usersAdded || usersDeleted) this.rerender();
	if (isLive || usersAdded) {
		this.startLiveUpdates();
	} else {
		this.getMoreUsers();
	}
};

Echo.UserList.prototype.refresh = function() {
	this.stopLiveUpdates();
	this.initVars();
	this.rerender();
	if (this.config.get("query")) {
		this.request();
	} else if (this.config.get("data")) {
		this.handleInitialResponse(this.config.get("data"));
	}
};

Echo.UserList.prototype.getVisibleUsersCount = function() {
	return this.count.visible;
};

Echo.UserList.prototype.addCss = function() {
	$.addCss(
		'.echo-user-list-container { line-height: 20px; vertical-align: middle; }' +
		'.echo-user-list-more { white-space: nowrap; }' +
		'.echo-user-list-more .echo-application-message-icon { display: inline; margin: 0px 5px; }'
	, 'user-list');
};
})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "CommunityFlag",
	"applications": ["Stream"],
	"dependencies": [{
		"application": "UserList",
		"url": "//cdn.echoenabled.com/clientapps/v2/user-list.js"
	}],
	"init": function(plugin, application) {
		// show user list by default
		if (typeof plugin.config.get(application, "showUserList") == "undefined") {
			plugin.config.set(application, "showUserList", true);
		}
		plugin.extendRenderer("Item", "flags", plugin.renderers.Item.users);
		plugin.extendTemplate("Item", plugin.template,
			"insertAsLastChild", "echo-item-data");
		plugin.addItemControl(application, plugin.assembleControl("Flag", application));
		plugin.addItemControl(application, plugin.assembleControl("Unflag", application));
		plugin.addCss(plugin.css);
	}
});

plugin.template = '<div class="echo-item-flags"></div>';

plugin.addLabels({
	"flaggedThis": " flagged this.",
	"flagControl": "Flag",
	"unflagControl": "Unflag",
	"flagProcessing": "Flagging...",
	"unflagProcessing": "Unflagging..."
});

plugin.assembleControl = function(name, application) {
	var callback = function() {
		var item = this;
		item.controls[plugin.name + "." + name].element
			.empty()
			.append(plugin.label(name.toLowerCase() + "Processing"));
		$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON({
				"verb": name.toLowerCase(),
				"target": item.id
			}),
			"target-query": application.config.get("query", ""),
			"sessionID": item.user.get("sessionID", "")
		}, function() {
			var topic = plugin.topic(application, "on" + name + "Complete");
			plugin.publish(application, topic, application.prepareBroadcastParams({
				"item": {
					"data": item.data,
					"target": item.dom.content
				}
			}));
			application.startLiveUpdates(true);
		}, "jsonp");
	};
	return function() {
		var item = this;
		var count = item.data.object.flags.length;
		var action =
			($.map(item.data.object.flags, function(entry) {
				if (item.user.hasIdentity(entry.actor.id)) return entry;
			})).length > 0 ? "Unflag" : "Flag";
		return {
			"name": name,
			"label": '<span class="echo-clickable">' + plugin.label(name.toLowerCase() + "Control") + '</span>' +
				(item.user.isAdmin() && count ? " (" + count + ")" : ""),
			"visible": item.user.logged() && action == name,
			"onetime": true,
			"callback": callback
		};
	};
};

plugin.renderers = {"Item": {}};

plugin.renderers.Item.users = function(element, dom) {
	var item = this;
	if (!item.data.object.flags.length || !item.user.isAdmin() || !plugin.config.get(item, "showUserList")) {
		element.hide();
		return;
	}
	var flagsPerPage = 5;
	var visibleUsersCount = plugin.get(item, "userList")
		? plugin.get(item, "userList").getVisibleUsersCount()
		: flagsPerPage;
	var config = plugin.assembleConfig(item, {
		"target": element.get(0),
		"data": {
			"itemsPerPage": flagsPerPage,
			"entries": item.data.object.flags
		},
		"initialUsersCount": visibleUsersCount,
		"suffixText": plugin.label("flaggedThis")
	});
	plugin.set(item, "userList", new Echo.UserList(config));
	element.show();
};

plugin.css = '.echo-item-flags { background: url(//c0.echoenabled.com/images/curation/status/communityflagged.png) no-repeat 0px 4px; padding: 0px 0px 4px 21px; }';

})(jQuery);






(function($) {

var plugin = Echo.createPlugin({
	"name": "Curation",
	"applications": ["Stream"],
	"dependencies": [{
		"application": "QueryPalette",
		"url": "//cdn.echoenabled.com/clientapps/v2/curation.js"
	}],
	"init": function(plugin, application) {
		plugin.set(application, "queue", []);
		plugin.addCss(plugin.assembleCss());
		plugin.extendRenderer("Item", "status", plugin.renderers.Item.status);
		plugin.extendRenderer("Item", "statusIcon", plugin.renderers.Item.statusIcon);
		plugin.extendRenderer("Item", "statusCheckbox", plugin.renderers.Item.statusCheckbox);
		plugin.extendTemplate("Item", plugin.statusItemTemplate,
			"insertAfter", "echo-item-avatar");
		plugin.extendRenderer("Stream", "curate", plugin.renderers.Stream.curate);
		plugin.extendTemplate("Stream", plugin.curateStreamTemplate,
			"insertAsFirstChild", "echo-stream-header");
		plugin.listenEvents(application);
		plugin.addItemControl(application, plugin.assembleControl("Approve", application));
		plugin.addItemControl(application, plugin.assembleControl("Spam", application));
		plugin.addItemControl(application, plugin.assembleControl("Delete", application));
	}
});

plugin.statusItemTemplate = 
	'<div class="echo-item-status">' +
		'<input type="checkbox" class="echo-item-statusCheckbox">' +
		'<div class="echo-item-statusIcon"></div>' +
		'<div class="echo-clear"></div>' +
	'</div>';

plugin.curateStreamTemplate =
	'<div class="echo-stream-curate echo-linkColor"></div>',

plugin.addLabels({
	"approveControl": "Approve",
	"deleteControl": "Delete",
	"spamControl": "Spam",
	"changingStatusToCommunityFlagged": "Flagging...",
	"changingStatusToModeratorApproved": "Approving...",
	"changingStatusToModeratorDeleted": "Deleting...",
	"changingStatusToModeratorFlagged": "Marking as spam...",
	"queries": "Queries",
	"actions": "Actions",
	"curate": "Curate",
	"curation": "Curation",
	"statusCommunityFlagged": "Flagged by Community",
	"statusModeratorApproved": "Approved by Moderator",
	"statusModeratorDeleted": "Deleted by Moderator",
	"statusModeratorFlagged": "Flagged by Moderator",
	"statusSystemFlagged": "Flagged by System",
	"statusUntouched": "New"
});

plugin.statuses = [
	"Untouched",
	"ModeratorApproved",
	"ModeratorDeleted",
	"CommunityFlagged",
	"ModeratorFlagged",
	"SystemFlagged"
];

plugin.control2status = {
	"Spam": "ModeratorFlagged",
	"Delete": "ModeratorDeleted",
	"Approve": "ModeratorApproved"
};

plugin.renderers = {"Item": {}, "Stream": {}};

plugin.renderers.Item.status = function(element) {
	var item = this;
	if (!item.user.isAdmin()) {
		element.hide();
		return;
	}
	if (item.depth) {
		element.addClass('echo-item-status-child');
	}
	var status = item.data.object.status || "Untouched";
	element.addClass("echo-item-status-" + status);
};

plugin.renderers.Item.statusIcon = function(element) {
	var item = this;
	if (!item.user.isAdmin()) return;
	var status = item.data.object.status || "Untouched";
	var title = plugin.label("status" + status);
	element.addClass("echo-item-status-icon-" + status).attr("title", title);
};

plugin.renderers.Item.statusCheckbox = function(element) {
	var item = this;
	if (!item.user.isAdmin()) return;
	element.click(function() {
		plugin.set(item, "selected", !plugin.get(item, "selected"));
		item.publish(plugin.topic("internal.Item", "onSelect"), {"item": item});
	}).attr("checked", plugin.get(item, "selected"));
};

plugin.renderers.Stream.curate = function(element, dom) {
	var stream = this;
	if (!stream.user.isAdmin() || !Echo.QueryPalette) {
		element.hide();
		return;
	}
	element.empty()
		.append('<span class="echo-stream-curate-label">' + plugin.label("curate") + '</span>')
		.show()
		.click(function() {
			plugin.assembleDialog(stream);
			plugin.get(stream, "dialog").open();
		});
};

plugin.extractURI = function(query) {
	var path = query.match(/(?:url|scope|childrenof):(\S+)(?: |$)/);
	return path ? path[1] : window.location.protocol + "//" + window.location.host + "/*";
};

plugin.assembleDialog = function(application) {
	if (plugin.get(application, "dialog")) return;
	var assembleQueryPalette = function(target) {
		var config = plugin.assembleConfig(application, {
			"target": target,
			"query": {
				"path": plugin.extractURI(application.config.get("query")),
				"states": [
					"Untouched",
					"SystemFlagged",
					"CommunityFlagged",
					"ModeratorFlagged"
				],
				"itemsPerPage": application.config.get("itemsPerPage"),
				"sortOrder": application.config.get("sortOrder")
			}
		});
		plugin.set(application, "palette", new Echo.QueryPalette(config));
		plugin.subscribe(application, "QueryPalette.onApply", function(event, data) {
			application.config.set("query", data.query);
			application.refresh();
		});
	};
	var assembleBulkActions = function(target) {
		var config = plugin.assembleConfig(application, {
			"target": target,
			"data": {
				"items": plugin.get(application, "queue")
			}
		});
		plugin.set(application, "bulk", new Echo.BulkActions(config));
	};
	var assembleTabs = function(target) {
		plugin.set(application, "tabs", new Echo.UI.Tabs({
			"target": $(target),
			"content": $(target),
			"addUIClass": false,
			"idPrefix": "curation-tabs-",
			"tabs": [{
				"id": "queries",
				"label": plugin.label("queries"),
				"icon": true,
				"content": assembleQueryPalette
			}, {
				"id": "actions",
				"label": plugin.label("actions"),
				"icon": true,
				"content": assembleBulkActions
			}]
		}));
	};
	plugin.set(application, "dialog", new Echo.UI.Dialog({
		"content": assembleTabs,
		"hasTabs": true,
		"config": {
			"autoOpen": false,
			"open": function() {
				plugin.get(application, "palette").refresh();
			},
			"title": plugin.label("curation"),
			"width": 500,
			"height": 550,
			"minWidth": 450,
			"minHeight": 415,
			"maxHeight": 600
		}
	}));
};

plugin.listenEvents = function(application) {
	plugin.subscribe(application, application.namespace + ".onRerender", function() {
		application.rerender("curate");
	});
	plugin.subscribe(application, plugin.topic("internal.Item", "onSelect"), function(event, data) {
		var item = data.item;
		if (plugin.get(item, "selected")) {
			plugin.get(application, "queue").push(item);
			plugin.assembleDialog(application);
			plugin.get(application, "dialog").open();
			plugin.get(application, "tabs").select("actions");
		} else {
			var queue = plugin.get(application, "queue");
			plugin.set(application, "queue",
				$.foldl([], queue, function(element, acc) {
					if (element.data.unique != item.data.unique) {
						acc.push(element);
					}
				}));
		}
		if (plugin.get(application, "bulk")) {
			plugin.get(application, "bulk").refresh(plugin.get(application, "queue"));
		}
		var action = plugin.get(item, "selected") ? "Select" : "Unselect";
		plugin.publish(application, plugin.topic(application.namespace + ".Item", "on" + action),
			application.prepareBroadcastParams({
				"item": {
					"data": item.data,
					"target": item.dom.content
				}
			}));	
	});
	plugin.subscribe(application, "BulkActions.onStatusChange", function(event, data) {
		var queue = [];
		$.each(plugin.get(application, "queue"), function(i, item) {
			item.block(plugin.label("changingStatusTo" + data.state));
			plugin.set(item, "selected", false);
			queue.push(item);
		});
		plugin.set(application, "queue", []);
		if (plugin.get(application, "bulk")) {
			plugin.get(application, "bulk").refresh([]);
		}
		if (!queue.length) return;
		var activities = $.map(queue, function(item) {
			return {
				"verb": "update",
				"target": item.id,
				"author": item.data.actor.id,
				"field": "state",
				"value": data.state
			};
		});
		$.sendPostRequest(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON(activities),
			"target-query": application.config.get("query", ""),
			"sessionID": application.user.get("sessionID", "")
		}, function() {
			application.startLiveUpdates(true);
		});
	});
};

plugin.changeItemStatus = function(item, status) {
	plugin.set(item, "selected", false);
	item.data.object.status = status;
	item.rerender("controls");
	// rerender status recursive
	// since it contains other renderers
	item.rerender("status", true);
};

plugin.assembleControl = function(name, application) {
	var callback = function() {
		var item = this;
		var status = plugin.control2status[name];
		item.block(plugin.label("changingStatusTo" + status));
		$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON({
				"verb": "update",
				"target": item.id,
				"author": item.data.actor.id,
				"field": "state",
				"value": status
			}),
			"target-query": application.config.get("query", ""),
			"sessionID": item.user.get("sessionID", "")
		}, function(data) {
			if (data.result == "error") {
				item.unblock();
			} else {
				plugin.changeItemStatus(item, status);
				application.startLiveUpdates(true);
			}
		}, "jsonp");
	};
	return function() {
		var item = this;
		return {
			"name": name,
			"label": plugin.label(name.toLowerCase() + "Control"),
			"visible": item.user.isAdmin() &&
					item.data.object.status != plugin.control2status[name],
			"callback": callback
		};
	};
};

plugin.assembleCss = function() {
	var msieCss = "";
	if ($.browser.msie) {
		msieCss =
			'.echo-item-status { zoom: 1; }' +
			'.echo-item-statusCheckbox { margin: 1px; }';
	};
	return '.echo-item-status { width: 48px; height: 24px; }' +
		'.echo-item-status-child { width: 24px; height: 48px; }' +
		'.echo-item-statusCheckbox { float: left; margin: 4px; }' +
		'.echo-item-status-child .echo-item-statusCheckbox { display: block; }' +
		'.echo-item-statusIcon { float: right; margin: 4px; width: 16px; height: 16px; }' +
		// statuses
		'.echo-item-status-Untouched { background: #00aaff; }' +
		'.echo-item-status-ModeratorApproved { background: #bdfb6d; }' +
		'.echo-item-status-ModeratorDeleted { background: #f20202; }' +
		'.echo-item-status-SystemFlagged, .echo-item-status-CommunityFlagged, .echo-item-status-ModeratorFlagged { background: #ff9e00; }' +
		'.echo-stream-curate { float: right; margin-left: 15px; cursor: pointer; font-family: Arial; font-size: 11px; }' +
		'.echo-curation-tabs-queries span { background: no-repeat center left url("//c0.echoenabled.com/images/curation/tabs/queries.png"); }' +
		'.echo-curation-tabs-actions span { background: no-repeat center left url("//c0.echoenabled.com/images/curation/tabs/actions.png"); }' +
		// status icons
		$.map(plugin.statuses, function(name) {
			return '.echo-item-status-icon-' + name + '{ background: url("//c0.echoenabled.com/images/curation/status/' + name.toLowerCase() + '.png") no-repeat; }';
		}).join("") + msieCss;
};

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "Edit",
	"applications": ["Stream", "Submit"],
	"dependencies": [{
		"application": "Submit",
		"url": "//cdn.echoenabled.com/clientapps/v2/submit.js"
	}],
	"init": function(plugin, application) {
		if (application instanceof Echo.Stream) {
			var layout = plugin.config.get(application, "layout");
			if (!layout || !/^(?:popup|inline)$/.test(layout)) {
				plugin.config.set(application, "layout", "popup");
			}
			plugin.addCss(plugin.css);
			plugin.listenEvents(application);
			plugin.addItemControl(application, plugin.assembleControl(application));
		} else if (application instanceof Echo.Submit) {
			plugin.extendTemplate("Submit", plugin.template,
				"insertAfter", "echo-submit-post-container");
			plugin.extendRenderer("Submit", "cancelButton", function(element) {
				var application = this;
				element.click(function() {
					application.publish("Submit.onEditError",
						application.prepareBroadcastParams());
				});
			});
		}
	}
});

plugin.template =
	'<div class="echo-submit-cancelButton-container">' +
		'<a href="javascript:void(0);" class="echo-submit-cancelButton echo-primaryFont echo-clickable echo-linkColor">' + plugin.label("cancel") + '</a>' +
	'</div>';

plugin.addLabels({
	"edit": "Edit",
	"editControl": "Edit",
	"updating": "Updating...",
	"cancel": "cancel"
});

plugin.popupClose = function(item) {
	if (plugin.get(item, "popup")) {
		plugin.get(item, "popup").close();
	}
};

plugin.submitConfig = function(application, item, target) {
	return plugin.assembleConfig(application, {
		"target": target,
		"data": item.data,
		"mode": "edit",
		"targetURL": item.id
	});
};

plugin.callbacks = {"inline": {}, "popup": {}};

plugin.callbacks.inline = {
	"control": function(application) {
		var item = this;
		var config = plugin.submitConfig(application, item, item.dom.get("subcontainer"));
		config.plugins.push({"name": "Edit"});
		config.targetQuery = application.config.get("query", "");
		new Echo.Submit(config);
		item.dom.content.get(0).scrollIntoView(true);
	},
	"events": {
		"complete": function(item) {
			item.rerender();
		}
	}
		
};

plugin.callbacks.inline.events.error = plugin.callbacks.inline.events.complete;

plugin.callbacks.popup = {
	"control": function(application) {
		var item = this;
		plugin.popupClose(item);
		var popup = new Echo.UI.Dialog({
			"content": function(target) {
				$(target).addClass("echo-edit-item-container");
				var config = plugin.submitConfig(application, item, target);
				config.plugins.push({"name": "Edit"});
				config.targetQuery = application.config.get("query", "");
				new Echo.Submit(config);
			},
			"config": {
				"autoOpen": true,
				"title": plugin.label("edit"),
				"width": 400,
				"height": 320,
				"minWidth": 300,
				"minHeight": 320
			}
		});
		plugin.set(item, "popup", popup);
	},
	"events": {
		"init": function(item) {
			item.block(plugin.label("updating"));
		},
		"complete": function(item) {
			plugin.popupClose(item);
		},
		"error": function(item) {
			plugin.popupClose(item);
			item.unblock();
		}
	}
};

plugin.assembleControl = function(application) {
	return function() {
		var item = this;
		return {
			"name": "Edit",
			"label": plugin.label("editControl"),
			"visible": item.user.isAdmin() || item.user.hasIdentity(item.data.actor.id),
			"callback": function() {
				var layout = plugin.config.get(application, "layout");
				plugin.callbacks[layout].control.call(item, application);
			} 
		};
	};
};

plugin.listenEvents = function(application) {
	var callbacks = plugin.callbacks[plugin.config.get(application, "layout")].events;
	$.each(["Init", "Complete", "Error"], function(i, stage) {
		plugin.subscribe(application, "Submit.onEdit" + stage, function(topic, args) {
			var item = application.items[args.data.unique];
			var handler = callbacks[stage.toLowerCase()];
			if (item && handler) handler(item);
		});
	});
};

plugin.css = 
	'.echo-edit-item-container .echo-submit-container { margin: 10px; }'+
	'.echo-submit-cancelButton { float: right; margin: 6px 15px 0px 0px; }';

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "FormAuth",
	"applications": ["Submit"],
	"dependencies": [{
		"application": "Auth",
		"url": "//cdn.echoenabled.com/clientapps/v2/auth.js"
	}],
	"init": function(plugin, application) {
		plugin.extendTemplate("Submit", "<div class=\"echo-submit-auth\"></div>",
			"insertBefore", "echo-submit-header");
		plugin.extendRenderer("Submit", "auth", plugin.renderers.Submit.auth);
		plugin.extendRenderer("Submit", "header", plugin.renderers.Submit.header);
		plugin.extendRenderer("Submit", "container", plugin.renderers.Submit.container);
		plugin.extendRenderer("Submit", "postButton", plugin.renderers.Submit.postButton);
		plugin.extendRenderer("Submit", "forcedLoginUserInfo",
			plugin.renderers.Submit.forcedLoginUserInfo);
		plugin.addCss(plugin.css);
	}
});

plugin.css = '.echo-submit-forcedLoginUserInfoMessage { font-size: 14px; font-weight: bold; }';

plugin.addLabels({
	"youMustBeLoggedIn": "You must be logged in to comment"
});

plugin.renderers = {"Submit": {}};

plugin.renderers.Submit.auth = function(element, dom) {
	var application = this;
	if (!application.user.get("sessionID") || application.config.get("mode") == "edit") return;
	var identityManager = $.foldl({}, ["Edit", "Login", "Signup"], function(name, acc) {
		acc[name.toLowerCase()] = plugin.config.get(application, "identityManager" + name);
	});
	new Echo.Auth(plugin.assembleConfig(application, {
		"target": element,
		"identityManager": identityManager
	}));
};

plugin.renderers.Submit.container = function(element, dom) {
	var application = this;
	application.parentRenderer("container", arguments);
	element.removeClass("echo-submit-logged echo-submit-anonymous echo-submit-forcedLogin");
	element.addClass("echo-submit-" + plugin.getStatus(application));
};

plugin.renderers.Submit.header = function(element, dom) {
	var application = this;
	var status = plugin.getStatus(application);
	if (status == "forcedLogin") {
		return application.render("forcedLoginUserInfo", element, dom);
	}
	if (status == "logged") {
		element.empty();
		return;
	}
	return application.parentRenderer("header", arguments);
};

plugin.renderers.Submit.postButton = function(element, dom) {
	var application = this;
	var handler = plugin.get(application, "postButtonHandler");
	if (!handler) {
		handler = function(ev) {
			if (application.user.logged()) {
				ev.stopImmediatePropagation();
				if (!application.highlightMandatory(application.dom.get("text"))) {
					application.post();
				}
			} else if (application.config.get("mode") != "edit"
					&& plugin.getPermissions(application) == "forceLogin") {
				ev.stopImmediatePropagation();
				application.dom.get("forcedLoginUserInfoMessage").css({"color": "red"});
			}
		};
		plugin.set(application, "postButtonHandler", handler);
	}
	element.unbind("click", handler).bind("click", handler);
	application.parentRenderer("postButton", arguments);
};

plugin.renderers.Submit.forcedLoginUserInfo = function(element, dom) {
	var prefix = "echo-submit-forcedLoginUserInfo";
	var template = 
		'<div class="echo-submit-userInfoWrapper echo-primaryFont">' +
			'<span class="{Data:prefix}Message echo-secondaryColor">' +
				'{Data:label}' +
			'</span>' +
		'</div>';
	var descriptors = {
		"Message": function(element){
			dom.set("forcedLoginUserInfoMessage", element);
		}
	};
	var template = this.substitute(template, {
		"prefix": prefix,
		"label": plugin.label("youMustBeLoggedIn")
	});
	return $.toDOM(template, prefix, descriptors).content;
};

plugin.getPermissions = function(application) {
	return plugin.config.get(application, "submitPermissions", "allowGuest");
};

plugin.getStatus = function(application) {
	if (application.user.logged()) {
		return "logged";
	}
	if (plugin.getPermissions(application) == "forceLogin") {
		return "forcedLogin";
	}
	return "anonymous";
};

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "ItemAccumulatorDisplay",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		plugin.extendTemplate("Item", plugin.template,
			"insertBefore", "echo-item-modeSwitch");
		plugin.extendRenderer("Item", "accumulatorContainer",
			plugin.renderers.Item.accumulatorContainer);
		plugin.addCss(plugin.css);
		plugin.listenEvents(application);
	}
});

plugin.renderers = {"Item": {}};

plugin.template = '<div class="echo-item-accumulatorContainer"></div>';

plugin.renderers.Item.accumulatorContainer = function(element) {
	var item = this;
	var accName = plugin.config.get(item, "accumulator", "repliesCount");
	var accumulator = item.data.object.accumulators[accName];
	var count = plugin.get(item, "count") || {};
	if (typeof count.current == "undefined") {
		// first-time rendering actions
		var countTickTimeout = plugin.config.get(item, "countTickTimeout", 1);
		plugin.set(item, "countTickTimeout", countTickTimeout * 1000);
		plugin.set(item, "count", {
			"actual": accumulator,
			"current": accumulator
		});
		element.append(accumulator);
		return;
	}

	plugin.stopTimer(item);
	var container = item.dom.get("container");
	container.stop(true, true);
	if (count.actual != accumulator) {
		count.actual = accumulator;
		plugin.set(item, "count", count);
	}
	element.append(count.current);

	// animate counter if necessary
	if (count.current != count.actual) {
		var bgColor = plugin.get(item, "originalBGColor");
		if (typeof bgColor == "undefined") {
			bgColor = $.getVisibleColor(container);
			plugin.set(item, "originalBGColor", bgColor);
		}
		container.css({"backgroundColor": item.config.get("flashColor")});
		plugin.animateCounter(item, bgColor);
	}
};

plugin.listenEvents = function(application) {
	plugin.subscribe(application, "Stream.Item.onRender", function(topic, data) {
		var item = application.items[data.item.data.unique];
		if (!item || !item.dom) return;
		plugin.set(item, "originalBGColor", $.getVisibleColor(item.dom.get("container")));
	});
};

plugin.stopTimer = function(item) {
	var timer = plugin.get(item, "timer");
	if (timer) clearTimeout(timer);
	plugin.set(item, "timer", undefined);
};

plugin.animateCounter = function(item, bgColor) {
	plugin.stopTimer(item);
	var count = plugin.get(item, "count");
	if (typeof count.current != "undefined" && count.current == count.actual &&
			!plugin.get(item, "animationInProgress")) {
		// fading out
		var container = item.dom.get("container");
		plugin.set(item, "animationInProgress", true);
		container.animate(
			{"backgroundColor": bgColor},
			item.config.get("fadeTimeout"),
			"linear",
			function() {
				container.css("backgroundColor", "");
				plugin.set(item, "animationInProgress", false);
			}
		);
		return;
	}
	plugin.set(item, "timer", setTimeout(function() {
		var count = plugin.get(item, "count");
		if (count.current != count.actual) {
			count.current < count.actual ? count.current++ : count.current--;
			plugin.set(item, "count.current", count.current);
			item.dom.get("accumulatorContainer").html(count.current);
			plugin.animateCounter(item, bgColor);
		}
	}, plugin.get(item, "countTickTimeout")));
};

plugin.css = '.echo-item-accumulatorContainer { float: right; margin-right: 7px; }';

})(jQuery);





// http://www.appelsiini.net/download/jquery.viewport.mini.js
(function($){$.belowthefold=function(element,settings){var fold=$(window).height()+$(window).scrollTop();return fold<=$(element).offset().top-settings.threshold;};$.abovethetop=function(element,settings){var top=$(window).scrollTop();return top>=$(element).offset().top+$(element).height()-settings.threshold;};$.rightofscreen=function(element,settings){var fold=$(window).width()+$(window).scrollLeft();return fold<=$(element).offset().left-settings.threshold;};$.leftofscreen=function(element,settings){var left=$(window).scrollLeft();return left>=$(element).offset().left+$(element).width()-settings.threshold;};$.inviewport=function(element,settings){return!$.rightofscreen(element,settings)&&!$.leftofscreen(element,settings)&&!$.belowthefold(element,settings)&&!$.abovethetop(element,settings);};$.extend($.expr[':'],{"below-the-fold":function(a,i,m){return $.belowthefold(a,{threshold:0});},"above-the-top":function(a,i,m){return $.abovethetop(a,{threshold:0});},"left-of-screen":function(a,i,m){return $.leftofscreen(a,{threshold:0});},"right-of-screen":function(a,i,m){return $.rightofscreen(a,{threshold:0});},"in-viewport":function(a,i,m){return $.inviewport(a,{threshold:0});}});})(jQuery);

(function($) {

var plugin = Echo.createPlugin({
	"name": "ItemsAutoRequest",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		$(window).bind("scroll", function(event) {
			if (!application.isPluginEnabled(plugin.name)) return;
			var element = application.dom && application.dom.get("more");
			if (element && !plugin.get(application, "requestInProgress") && $.inviewport(element, {"threshold": 0})) {
				plugin.set(application, "requestInProgress", true);
				element.click();
			}
		});
		plugin.subscribe(application, "Stream.onDataReceive", function() {
			plugin.set(application, "requestInProgress", false);
		});
	}
});

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "JanrainSharing",
	"applications": ["Submit"],
	"init": function(plugin, application) {
		// avoid nonsynchronized scripts cache issue
		if (!Echo.Global) Echo.Global = {};
		if (!plugin.config.get(application, "appId") ||
			!plugin.config.get(application, "xdReceiver")) return;
		plugin.listenEvents(application);
	}
});

// actual limit is 140, reserving some space for ellipses and shortened link to the page
plugin.contentMaxLength = 120;

plugin.addLabels({
	"sharePrompt": "Share your comment:"
});

plugin.isReplyToTweet = function(item) {
	return !!(item && item.source && item.source.name == "Twitter");
};

plugin.getTweetAuthor = function(item) {
	return item.actor.id.replace(/http\:\/\/twitter.com\//, "");
};

plugin.truncate = function(text, limit) {
	return limit > 0 && text.length > limit ? text.substring(0, limit) + "..." : text;
};

plugin.prepareContent = function(args, application) {
	var text = $.stripTags(args.postData.content);
	var customShareMessagePattern = plugin.config.get(application, "activity.shareContent");
	if (customShareMessagePattern) {
		return plugin.label(customShareMessagePattern, {
			"domain": window.location.host,
			"content": plugin.truncate(text, 30)
		});
	}
	// if a reply to a tweet was posted
	if (plugin.isReplyToTweet(args.inReplyTo)) {
		var author = plugin.getTweetAuthor(args.inReplyTo);
		return plugin.label("@{author} {content}", {
			"author": author,
			"content": plugin.truncate(text, plugin.contentMaxLength - author.length - 2)
		});
	}
	return plugin.truncate(text, plugin.contentMaxLength);
};

plugin.listenEvents = function(application) {
	var key = "subscriptionID-" + application.getContextId();
	if (plugin.get(Echo.Global, key)) return;
	var subscriptionID = plugin.subscribe(application, "Submit.onPostComplete", function(topic, args) {
		var config = function(key, defaults) {
			return plugin.config.get(application, key, defaults);
		};
		var rpxJsHost = ("https:" == document.location.protocol)
			? "https://"
			: "http://static.";
		$.loadScriptContent(rpxJsHost + "rpxnow.com/js/lib/rpx.js", function() {
			RPXNOW.init({
				"appId": config("appId"),
				"xdReceiver": config("xdReceiver")
			});
			RPXNOW.loadAndRun(["Social"], function () {
				var activity = new RPXNOW.Social.Activity(
					config("activity.sharePrompt", plugin.label("sharePrompt")),
					plugin.prepareContent(args, application),
					config("activity.itemURL", args.targetURL)
				);
				if (config("activity.pageDescription")) {
					activity.setDescription(config("activity.pageDescription"));
				}
				if (config("activity.pageTitle")) { 
					activity.setTitle(config("activity.pageTitle"));
				}
				RPXNOW.Social.publishActivity(activity);
			});
		});
	});
	plugin.set(Echo.Global, key, subscriptionID);
};

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "Like",
	"applications": ["Stream", "UserList"],
	"dependencies": [{
		"application": "UserList",
		"url": "//cdn.echoenabled.com/clientapps/v2/user-list.js"
	}],
	"init": function(plugin, application) {
		if (application instanceof Echo.Stream) {
			plugin.extendRenderer("Item", "likes", plugin.renderers.Item.likes);
			plugin.extendTemplate("Item", plugin.templates.likeList,
				"insertAsLastChild", "echo-item-data");
			plugin.addItemControl(application, plugin.assembleControl("Like", application));
			plugin.addItemControl(application, plugin.assembleControl("Unlike", application));
			plugin.subscribe(application, plugin.topic("internal.Item", "onUnlike"), function(topic, data) {
				plugin.sendRequest(application, {
					"verb": "unlike",
					"target": data.item.object.id,
					"author": data.actor.id
				}, function() {
					application.startLiveUpdates(true);
				});
			});
		} else if (application instanceof Echo.UserList) {
			plugin.extendRenderer("UserList", "container",
				plugin.renderers.UserList.container);
			plugin.extendRenderer("UserListItem", "adminUnlike",
				plugin.renderers.UserListItem.adminUnlike);
			plugin.extendTemplate("UserListItem", plugin.templates.adminUnlike,
				"insertAsLastChild", "echo-user-list-item-container");
		}
		plugin.addCss(plugin.css);
	}
});

plugin.addLabels({
	"likeThis": " like this.",
	"likesThis": " likes this.",
	"likeControl": "Like",
	"unlikeControl": "Unlike",
	"unlikeOnBehalf": "Unlike on behalf of this user",
	"likeProcessing": "Liking...",
	"unlikeProcessing": "Unliking..."
});

plugin.templates = {
	"likeList": '<div class="echo-item-likes"></div>',
	"adminUnlike": '<img class="echo-user-list-item-adminUnlike" src="//cdn.echoenabled.com/images/container/closeWindow.png" title="' + plugin.label("unlikeOnBehalf") + '" width="10" height="9">'
};

plugin.sendRequest = function(application, data, callback) {
	$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
		"appkey": application.config.get("appkey"),
		"content": $.object2JSON(data),
		"target-query": application.config.get("query", ""),
		"sessionID": application.user.get("sessionID", "")
	}, callback, "jsonp");
};

plugin.assembleControl = function(name, application) {
	var callback = function() {
		var item = this;
		item.controls[plugin.name + "." + name].element
			.empty()
			.append(plugin.label(name.toLowerCase() + "Processing"));
		plugin.sendRequest(application, {
			"verb": name.toLowerCase(),
			"target": item.id
		}, function() {
			var topic = plugin.topic(application, "on" + name + "Complete");
			plugin.publish(application, topic, application.prepareBroadcastParams({
				"item": {
					"data": item.data,
					"target": item.dom.content
				}
			}));
			application.startLiveUpdates(true);
		});
	};
	return function() {
		var item = this;
		var action =
			($.map(item.data.object.likes, function(entry) {
				if (item.user.hasIdentity(entry.actor.id)) return entry;
			})).length > 0 ? "Unlike" : "Like";
		return {
			"name": name,
			"label": plugin.label(name.toLowerCase() + "Control"),
			"visible": item.user.logged() && action == name,
			"onetime": true,
			"callback": callback
		};
	};
};

plugin.renderers = {"Item": {}, "UserList": {}, "UserListItem": {}};

plugin.renderers.Item.likes = function(element) {
	var item = this;
	if (!item.data.object.likes.length) {
		element.hide();
		return;
	}
	var likesPerPage = 5;
	var visibleUsersCount = plugin.get(item, "userList")
		? plugin.get(item, "userList").getVisibleUsersCount()
		: likesPerPage;
	var youLike = false;
	var userId = item.user.get("id");
	var users = item.data.object.likes;
	$.each(users, function(i, like) {
		if (like.actor.id == userId) {
			youLike = true;
			return false; // break
		}
	});
	var config = plugin.assembleConfig(item, {
		"target": element.get(0),
		"data": {
			"itemsPerPage": likesPerPage,
			"entries": users
		},
		"initialUsersCount": visibleUsersCount,
		"totalUsersCount": item.data.object.accumulators.likesCount,
		"suffixText": plugin.label(users.length > 1 || youLike ? "likeThis" : "likesThis")
	});
	config.plugins.push({"name": "Like"});
	var userList = new Echo.UserList(config);
	plugin.set(item, "userList", userList);
	element.show();
	item.subscribe(plugin.topic("internal.UserListItem", "onUnlike"), function(topic, data) {
		if (data.target != element.get(0)) return;
		item.publish(plugin.topic("internal.Item", "onUnlike"), {
			"actor": data.actor,
			"item": item.data
		});
	});
};

plugin.renderers.UserList.container = function(element) {
	var item = this;
	item.parentRenderer("container", arguments);
	if (!item.user.isAdmin()) return;
	element.addClass("echo-user-list-highlight");
};

plugin.renderers.UserListItem.adminUnlike = function(element) {
	var item = this;
	if (!item.user.isAdmin()) {
		element.remove();
		return;
	}
	element.one("click", function() {
		item.dom.get("container").css("opacity", 0.3);
		plugin.publish(item, plugin.topic("internal.UserListItem", "onUnlike"), {
			"actor": item.data,
			"target": item.config.get("target").get(0)
		});
	});
};

plugin.css = '.echo-item-likes { background: url(//c0.echoenabled.com/images/likes.png) no-repeat 0px 4px; padding: 0px 0px 4px 21px; }' +
	'.echo-item-likes .echo-user-list-highlight { line-height: 23px; }' +
	'.echo-item-likes .echo-user-list-highlight .echo-user-list-item-container { display: inline-block; line-height: 16px; background-color: #EEEEEE; padding: 1px 3px; border: 1px solid #D2D2D2; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; margin: 0px 2px; }' +
	'.echo-item-likes .echo-user-list-highlight .echo-user-list-delimiter { display: none; }' +
	'.echo-item-likes .echo-user-list-item-adminUnlike { cursor: pointer; margin-left: 3px; }' +
	($.browser.msie ?
		'.echo-item-likes .echo-user-list-highlight span { vertical-align: middle; }' +
		'.echo-item-likes { background-position: 0px 2px; }'
		: ''
	);

})(jQuery);






(function($) {

var plugin = Echo.createPlugin({
	"name": "MetadataManager",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		var controls = plugin.config.get(application, "controls");
		$.each(controls, function(i, control) {
			plugin.addItemControl(application, plugin.assembleControl("Mark", control, application));
			plugin.addItemControl(application, plugin.assembleControl("Unmark", control, application));
		});
	}
});

plugin.addLabels({
	"markProcessing": "Adding {type} {marker}...",
	"unmarkProcessing": "Removing {type} {marker}..."
});

plugin.assembleControl = function(action, control, application) {
	var type = control.marker ? "marker" : "tag";
	var marker = (control.marker || control.tag);
	var name = action + "As" + marker.replace(/[^a-z0-9_-]/ig, '');
	var callback = function() {
		var item = this;
		var operation = action.toLowerCase();
		item.controls[plugin.name + "." + name].element
			.empty()
			.append(plugin.label(operation + "Processing", {"type": type, "marker": marker}));
		var data = {
			// translate mark/unmark operations into tag/untag/mark/unmark verbs
			"verb": type == "tag" ? operation.replace(/mark/g, "tag") : operation,
			"target": item.id
		};
		data[type + "s"] = marker;
		$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON(data),
			"target-query": application.config.get("query", ""),
			"sessionID": item.user.get("sessionID", "")
		}, function() {
			application.startLiveUpdates(true);
		}, "jsonp");
	};
	return function() {
		var item = this;
		return {
			"name": name,
			"label": control["label" + action],
			"visible": plugin.isControlVisible(application, item, control, marker, action, type),
			"onetime": true,
			"callback": callback
		};
	};
};

plugin.isControlVisible = function(application, item, control, marker, action, type) {
	var visible = ($.inArray(marker, item.data.object[type + "s"] || []) == -1) ^ (action == "Unmark");
	if (!visible || !item.user.logged()) return false;
	if (item.user.isAdmin()) return true;
	var customProxyURL = plugin.config.get(application, "submissionProxyURL");
	if (type == "marker" && !customProxyURL) return false;
	control.visible = control.visible || function() { return false; };
	if ($.isFunction(control.visible)) {
		return control.visible(application, item);
	}
	if ($.isEmptyObject(control.visible)) return false;
	var isVisible = true;
	$.each(["state", "roles", "markers"], function(i, field) {
		var values = control.visible["user." + field];
		if (values) {
			values = typeof values == "string" ? [values] : values;
			if (!item.user.hasAny(field, values)) {
				isVisible = false;
				return false; // break
			}
		}
	});
	return isVisible;
};

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "Reply",
	"applications": ["Stream"],
	"dependencies": [{
		"application": "Submit",
		"url": "//cdn.echoenabled.com/clientapps/v2/submit.js"
	}],
	"init": function(plugin, application) {
		// avoid nonsynchronized scripts cache issue
		if (!Echo.Global) Echo.Global = {};
		plugin.extendRenderer("Item", "children", plugin.renderers.Item.children);
		plugin.extendRenderer("Item", "replyForm", plugin.renderers.Item.replyForm);
		plugin.extendRenderer("Item", "container", plugin.renderers.Item.container);
		plugin.extendTemplate("Item", plugin.template, "insertAsLastChild", "echo-item-content");
		plugin.listenEvents(application);
		plugin.addItemControl(application, plugin.assembleControl("Reply", application));
	}
});

plugin.template = '<div class="echo-item-replyForm"></div>';

plugin.addLabels({
	"replyControl": "Reply"
});

plugin.assembleControl = function(name, application) {
	var callback = function() {
		var item = this;
		var target = item.dom.get("replyForm");
		if (!plugin.get(item, "form")) {
			plugin.createForm(item, target);
		}
		if (plugin.get(item, "form.initialized")) {
			if (item.depth || !item.children.length) {
				plugin.view(item, "toggle");
				item.rerender("container");
			}
		} else {
			item.rerender("replyForm");
		}
		var form = plugin.get(item, "form");
		form.instance.switchMode();
		if (form.visible) {
			if (form.instance.dom) {
				text = form.instance.dom.get("text");
				if (text && text.is(":visible")) {
					text.focus();
					return;
				}
			}
			target.get(0).scrollIntoView(false);
		}
	};
	return function() {
		var item = this;
		return {
			"name": "Reply",
			"label": plugin.label("replyControl"),
			"visible": item.depth < item.config.get("children.maxDepth"),
			"callback": callback
		};
	};
};

plugin.renderers = {"Item": {}};

plugin.renderers.Item.children = function(element) {
	var item = this;
	// perform reply form rerendering *only* when we have exactly 1 item
	// (the first item is being added or the last one is being deleted)
	if (item.children.length == 1) {
		var form = plugin.get(item, "form");
		var child = item.children[0];
		var rerenderAfterAdding = child.added && !(form && form.visible);
		var rerenderAfterDeleting = child.deleted &&
			!(form && form.instance && form.instance.config.get("mode") != "compact");
		if (rerenderAfterDeleting || rerenderAfterAdding && !item.depth) {
			item.rerender("replyForm");
		}
	}
	item.parentRenderer("children", arguments);
};

plugin.renderers.Item.replyForm = function(element) {
	var item = this;
	if (item.depth == item.config.get("children.maxDepth")) return;
	var hasChildren = !!item.children.length;
	if (!item.depth && hasChildren && !plugin.get(item, "form") ||
		plugin.get(Echo.Global, plugin.getFormKey(item))) {
			plugin.createForm(item, element);
	} else if (!plugin.get(item, "form")) return;
	if (!plugin.get(item, "form.initialized")) {
		plugin.set(item, "form.initialized", true);
		element.addClass("echo-item-container echo-item-container-child " +
			"echo-trinaryBackgroundColor echo-item-depth-" + (item.depth + 1));
		if (!hasChildren) {
			item.rerender("container");
		} else if (item.children.length == 1 && item.children[0].deleted) {
			plugin.view(item, "hide");
		} else if (plugin.get(item, "form.visible")) {
			plugin.view(item, "show");
		}
	} else {
		if (plugin.get(item, "form.visible") &&
			(!hasChildren || item.children.length == 1 && item.children[0].deleted)) {
				plugin.view(item, "hide");
		} else if (hasChildren) {
			plugin.view(item, "show");
		}
	}
};

plugin.renderers.Item.container = function(element) {
	var item = this;
	var threading = item.threading;
	if (plugin.get(item, "form.visible")) {
		item.threading = true;
	}
	item.parentRenderer("container", arguments);
	item.threading = threading;
};

plugin.prepareParams = function(application, item) {
	return application.prepareBroadcastParams({
		"plugin": plugin.name,
		"form": plugin.get(item, "form"),
		"item": {
			"data": item.data,
			"target": item.dom.content
		}
	});
};

plugin.listenEvents = function(application) {
	$.map(["Expand", "Collapse"], function(action) {
		plugin.subscribe(application, "Submit.on" + action, function(event, args) {
			var item = application.items[args.data.unique];
			if (!item || !plugin.get(item, "form")) return;
			if (action == "Collapse" && (item.depth || !item.children.length)) {
				plugin.view(item, "hide");
				item.rerender("container");
			}
			var topic = plugin.topic(application, "onForm" + action);
			plugin.publish(application, topic, plugin.prepareParams(application, item));
		});
	});
	plugin.subscribe(application, "Submit.onPostComplete", function(topic, args) {
		var item = application.items[args.data.unique];
		if (!item) return;
		plugin.get(item, "form.instance").switchMode("compact");
	});
};

plugin.createForm = function(item, target) {
	var config = plugin.assembleConfig(item, {
		"target": target.get(0),
		"inReplyTo": item.data,
		"data":  {"unique": item.data.unique},
		"mode": "compact",
		"targetURL": item.id,
		"targetQuery": item.config.get("query", "")
	});
	var key = plugin.getFormKey(item);
	var form = (plugin.get(Echo.Global, key) || {}).instance;
	if (form) {
		var text = form.dom.get("text").val();
		form.config.set("target", target);
		target.empty().append(form.render());
		if (text) {
			form.dom.get("text").val(text);
		}
	} else {
		form = new Echo.Submit(config);
	}
	var data = {
		"instance": form,
		"initialized": false,
		"visible": true
	};
	plugin.set(Echo.Global, key, data);
	plugin.set(item, "form", data);
};

plugin.view = function(item, action) {
	var visibility = action == "toggle"
		? !plugin.get(item, "form.visible")
		: action == "show";
	plugin.set(item, "form.visible", visibility);
	plugin.get(item, "form.instance").config.get("target")[action]();
};

plugin.getFormKey = function(item) {
	return "forms." + item.data.unique + "-" + item.getContextId();
};

})(jQuery);






(function($) {
 
var plugin = Echo.createPlugin({
	"name": "SubmitTextCounter",
	"applications": ["Submit"],
	"init": function(plugin, application) {
		plugin.extendRenderer("Submit", "text",
			plugin.renderers.Submit.text);
		plugin.extendRenderer("Submit", "counterLabel",
			plugin.renderers.Submit.counterLabel);
		plugin.extendTemplate("Submit",
			plugin.counterTemplate, "insertAfter", "echo-submit-content");
		plugin.listenEvents(application);
	}
});
 
plugin.addLabels({
	"limited": "{typed}/{left} characters",
	"unlimited": "{typed} characters"
});
 
plugin.counterTemplate = '<div class="echo-submit-counterLabel echo-primaryFont echo-primaryColor"></div>';

plugin.renderers = {"Submit": {}};
 
plugin.renderers.Submit.text = function(element, dom) {
	var application = this;
	application.parentRenderer("text", arguments);
	var limit = plugin.config.get(application, "limit", 0);
	var handler = plugin.get(application, "keyPressHandler");
	if (!handler) {
		handler = function() {
			if (limit) {
				var text = element.val();
				if (text.length <= limit) {
					plugin.set(application, "text", text);
				} else if (text.length > limit) {
					element.val(plugin.get(application, "text"));
					return;
				}
			}
			application.rerender("counterLabel");
		};
		plugin.set(application, "keyPressHandler", handler);
	}
	element.unbind("blur focus keyup keypress", handler).bind("blur focus keyup keypress", handler);
};
 
plugin.renderers.Submit.counterLabel = function(element, dom) {
	var application = this;
	if (application.config.get("mode") == "compact") {
		element.hide();
		return;
	}
	var typed = dom.get("text").val().length;
	var limit = plugin.config.get(application, "limit", 0);
	var label = plugin.label(
		plugin.config.get(application, "label", limit ? "limited" : "unlimited"),
		{"typed": typed, "left": Math.max(limit - typed, 0), "limit": limit}
	);
	element.text(label);
};

plugin.listenEvents = function(application) {
	plugin.subscribe(application, "Submit.onPostComplete", function() {
		application.rerender("counterLabel");
	});
};
 
})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "TwitterIntents",
	"applications": ["Stream"],
	"dependencies": [{
		"loaded": function() { return !!window.twttr; },
		"url": "//platform.twitter.com/widgets.js"
	}],
	"init": function(plugin, application) {
		plugin.wrapPluginRenderers();
		// rename "Reply" -> "Comment"
		Echo.Localization.extend({"Plugins.Reply.replyControl": "Comment"});
		plugin.extendTemplate("Item", '<span class="echo-item-tweetUserName echo-linkColor"></span>',
			"insertBefore", "echo-item-authorName");
		plugin.extendRenderer("Item", "body",
			plugin.renderers.Item.body);
		plugin.extendRenderer("Item", "controls",
			plugin.renderers.Item.controls);
		plugin.extendRenderer("Item", "controlsDelimiter",
			plugin.renderers.Item.controlsDelimiter);
		plugin.extendRenderer("Item", "date",
			plugin.renderers.Item.date);
		plugin.extendRenderer("Item", "tweetUserName",
			plugin.renderers.Item.tweetUserName);
		plugin.extendRenderer("Item", "authorName",
			plugin.renderers.Item.authorName);
		plugin.extendRenderer("Item", "avatar",
			plugin.renderers.Item.avatar);
		plugin.addItemControl(application,
			plugin.assembleControl("Reply", "tweet", application));
		plugin.addItemControl(application,
			plugin.assembleControl("Retweet", "retweet", application));
		plugin.addItemControl(application,
			plugin.assembleControl("Favorite", "favorite", application));
		plugin.addCss(plugin.css);
	}
});

plugin.renderers = {"Item": {}};

plugin.addLabels({
	"reply": "Reply",
	"retweet": "Retweet",
	"favorite": "Favorite"
});

plugin.renderers.Item.body = function() {
	var item = this;
	// disable hashtag icons for tweets even if defined by the user
	var key = "contentTransformations." + item.data.object.content_type + ".hashtags";
	if (item.config.get(key)) {
		item.config.set(key, false);
		item.parentRenderer("body", arguments);
		item.config.set(key, true);
	} else {
		item.parentRenderer("body", arguments);
	}
};

plugin.renderers.Item.controlsDelimiter = function(element, dom, extra) {
	var item = this;
	extra = extra || {};
	if (!extra.previousControl) return;
	if (extra.previousControl.plugin == plugin.name
		&& extra.nextControl.plugin != plugin.name) {
			return $('<span class="echo-item-control-delim"> | </span>');
	}
	return item.parentRenderer("controlsDelimiter", arguments);
};

plugin.renderers.Item.controls = function(element, dom) {
	var item = this;
	// almost copy of original renderer
	item.assembleControls();
	item.sortControls();
	var container = element.empty();
	$.each(item.controlsOrder, function(i, name) {
		var data = item.controls[name];
		if (!data || !data.visible()
			// disabling controls from Reply and Like plugins
			|| data.plugin == "Reply" || data.plugin == "Like") {
				return;
		}
		var control = data.dom || item.render("control", undefined, undefined, data);
		if (control) {
			item.controls[name].element = control;
			item.controls[name].clickableElements = $('.echo-clickable', control);
			if (!item.controls[name].clickableElements.length) {
				item.controls[name].clickableElements = control;
			}
			var delimiter = item.render("controlsDelimiter", undefined, dom, {
				"previousControl": item.controls[item.controlsOrder[i - 1]],
				"nextControl": data
			});
			delimiter && container.append(delimiter);
			container.append(control);
		}
	});

	// reinitialize twitter intents after we have added new controls
	window.twttr.widgets.load();

	var activeClass = "echo-item-intentControlActive";
	$.map(item.controlsOrder, function(name) {
		var data = item.controls[name];
		if (data && data.plugin == plugin.name && data.visible()) {
			data.element
				// unbind click handler so that only twitter handler could work
				.unbind("click")
				.unbind("mouseover mouseout")
				.hover(
					function() { data.element.addClass(activeClass); },
					function() { data.element.removeClass(activeClass); }
				);
		}
	});
};

plugin.renderers.Item.date = function(element) {
	var item = this;
	item.parentRenderer("date", arguments);
	if (plugin.get(item, "wrapped")) return;
	element.wrap(item.hyperlink({
		"href": item.data.object.id,
		"class": "echo-item-twitterPermalink echo-clickable " +
			"echo-secondaryFont echo-item-control echo-secondaryColor"
	}, {
		"openInNewWindow": item.config.get("openLinksInNewWindow"),
		"skipEscaping": true
	}));
	element.unbind("mouseover mouseout").hover(
		function() { element.addClass("echo-linkColor"); },
		function() { element.removeClass("echo-linkColor"); }
	);
	plugin.set(item, "wrapped", true);
};

plugin.renderers.Item.tweetUserName = function(element) {
	var item = this;
	return item.hyperlink({
		"href": item.data.actor.id,
		"caption": plugin.extractTwitterID(item)
	}, {
		"openInNewWindow": item.config.get("openLinksInNewWindow"),
		"skipEscaping": true
	});
};

plugin.renderers.Item.authorName = function(element) {
	var item = this;
	element.removeClass("echo-linkColor")
		.addClass("echo-item-tweetScreenName echo-secondaryFont echo-secondaryColor");
	return item.parentRenderer("authorName", arguments);
};

plugin.renderers.Item.avatar = function(element) {
	var item = this;
	var avatar = item.parentRenderer("avatar", arguments);
	// blocking all previous and future onclick handlers
	avatar.unbind("click").bind("click", function(e) {
		e.stopPropagation();
	});
	return $(item.hyperlink({
		"href": item.data.actor.id
	}, {
		"openInNewWindow": item.config.get("openLinksInNewWindow"),
		"skipEscaping": true
	})).append(avatar);
};

plugin.wrapPluginRenderers = function() {
	// make wrapper functions for renderers to be able to "disable" plugins
	// depending on the item: if it's tweet or not
	$.each(["Reply", "Like", plugin.name], function(i, pluginName) {
		// we should wrap those renderers only once on the page
		if (Echo.isExtended(plugin.name, [pluginName, "renderers"])) return;
		var renderers = Echo.Plugins[pluginName].renderers;
		if (!renderers || !renderers.Item) return;
		$.each(renderers.Item, function(rendererName, renderer) {
			renderers.Item[rendererName] = function() {
				var item = this;
				// we skip renderer from pluginName in two cases:
				//   - it is TwitterIntents plugin but item is not tweet;
				//   - it is Reply or Like plugin and item is tweet.
				if (plugin.isTweet(item) ^ (pluginName == plugin.name)) {
					return item.parentRenderer(rendererName, arguments);
				} else {
					return renderer.apply(item, arguments);
				}
			};
		});
	});
};

plugin.assembleControl = function(name, action, application) {
	return function() {
		var item = this;
		var match = item.data.object.id.match(/\/(\d+)$/);
		var id = match && match[1];
		return {
			"name": name,
			"label": plugin.label(name.toLowerCase()),
			"template": item.hyperlink({
				"href": "https://twitter.com/intent/" +	action + "?in_reply_to=" + id + "&tweet_id=" + id,
				"class": "echo-item-control echo-clickable echo-item-intentControl echo-secondaryColor echo-item-control-{Data:name}",
				"caption":
					'<span class="echo-item-twitterIntentsIcon echo-item-twitterIntentsIcon{Data:name}">&nbsp;</span>' +
					'<span>{Data:label}</span>'
			}, {
				"openInNewWindow": item.config.get("openLinksInNewWindow"),
				"skipEscaping": true
			}),
			"visible": id && plugin.isTweet(item)
		};
	};
};

plugin.isTweet = function(item) {
	return item.data.source.name == "Twitter";
};

plugin.extractTwitterID = function(item) {
	var match = item.data.actor.id.match(/twitter.com\/(.*)/);
	return match ? match[1] : item.data.actor.id;
};

plugin.css =
	".echo-item-avatar a img { border: 0px; }" +
	".echo-item-tweetUserName { float: left; font-size: 15px; font-weight: bold; }" +
	".echo-item-frame .echo-item-tweetScreenName { margin-left: 4px; font-size: 11px; font-weight: normal; padding-top: 1px; }" +
	".echo-item-tweetUserName a, .echo-item-intentControl { text-decoration: none; }" +
	".echo-item-twitterPermalink { float: left; text-decoration: none; }" +
	".echo-item-twitterPermalink .echo-item-date { float: none; }" +
	".echo-item-twitterIntentsIcon { width: 15px; height: 15px; display: inline-block; margin-right: 3px; background: url(https://si0.twimg.com/images/dev/cms/intents/icons/sprites/everything-spritev2.png) no-repeat; }" +
	".echo-item-twitterIntentsIconReply { background-position: 0px -2px; }" +
	".echo-item-twitterIntentsIconRetweet { background-position: -80px -2px; }" +
	".echo-item-twitterIntentsIconFavorite { background-position: -32px -2px; }" +
	".echo-item-intentControlActive .echo-item-twitterIntentsIconReply { background-position: -16px -2px; }" +
	".echo-item-intentControlActive .echo-item-twitterIntentsIconRetweet { background-position: -96px -2px; }" +
	".echo-item-intentControlActive .echo-item-twitterIntentsIconFavorite { background-position: -48px -2px; }";

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "UserBan",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		plugin.addItemControl(application,
			plugin.assembleControl("Ban", application));
		plugin.addItemControl(application,
			plugin.assembleControl("Unban", application));
		plugin.addCss(plugin.css);
	}
});

plugin.addLabels({
	"banUser": "Ban User",
	"unbanUser": "Unban",
	"userBanned": "Banned User",
	"processingAction": "Setting up '{state}' user state..."
});

plugin.controlLabels = {
	"banned": '<span class="echo-item-control-state echo-item-control-state-banned">' +
		plugin.label("userBanned") + '</span>' +
		'(<span class="echo-clickable">' + plugin.label("unbanUser") + '</span>)',
	"unbanned": '<span class="echo-clickable">' + plugin.label("banUser") + '</span>'
};

plugin.assembleControl = function(action, application) {
	var callback = function() {
		var item = this;
		var newState = action == "Ban" ? "ModeratorBanned" : "Untouched";
		item.controls[plugin.name + "." + action].element
			.empty()
			.append(plugin.label("processingAction", {"state": newState}));
		$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON({
				"endpoint": "users/update",
				"field": "state",
				"value": newState,
				"identityURL": item.data.actor.id,
				"username": item.data.actor.title
			}),
			"target-query": application.config.get("query", ""),
			"sessionID": application.user.get("sessionID", "")
		}, function(data) {
			if (!data || data.result == "error") {
				item.rerender();
				return;
			}
			$.map(application.threads, function(thread) {
				thread.traverse(thread.children, function(child) {
					plugin.applyUserStateUpdate(child, item, newState);
				});
				plugin.applyUserStateUpdate(thread, item, newState);
			});
		}, "jsonp");
	};
	return function() {
		var item = this;
		var isBanned = plugin.isUserBanned(item);
		var visible = item.data.actor.id != item.user.get("fakeIdentityURL") &&
			isBanned ^ (action == "Ban");
		return {
			"name": action,
			"label": plugin.controlLabels[isBanned ? "banned" : "unbanned"],
			"visible": visible && item.user.isAdmin(),
			"callback": callback,
			"onetime": true
		};
	};
};

plugin.applyUserStateUpdate = function(target, source, state) {
	if (target.data.actor.id != source.data.actor.id) return;
	target.data.actor.status = state;
	target.rerender();
};

plugin.isUserBanned = function(item) {
	return item.data.actor.status == "ModeratorBanned";
};

plugin.css =
	".echo-item-control-state { margin-right: 3px; }" +
	".echo-item-control-state-banned { color: #FF0000; }";

})(jQuery);





(function($) {
 
var plugin = Echo.createPlugin({
	"name": "UserComments",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		plugin.set(application, "query", application.config.get("query"));
		plugin.extendTemplate("Stream", plugin.restoreQueryControlTemplate,
			"insertAsFirstChild", "echo-stream-header");
		plugin.extendRenderer("Item", "avatar",
			plugin.renderers.Item.avatar);
		plugin.extendRenderer("Item", "authorName",
			plugin.renderers.Item.authorName);
		plugin.extendRenderer("Stream", "restoreQuery",
			plugin.renderers.Stream.restoreQuery);
		plugin.extendRenderer("Stream", "restoreQueryControl",
			plugin.renderers.Stream.restoreQueryControl);
		plugin.listenEvents(application);
		plugin.addCss(plugin.css);
	}
});

plugin.renderers = {"Item": {}, "Stream": {}};
 
plugin.addLabels({
	"allCommentsByUser": "View all comments by {name}",
	"allCommentsByAnonymous": "View all comments by anonymous users",
	"restoreQuery": "Back to original query"
});

plugin.anonymousUserID = "http://js-kit.com/ECHO/user/fake_user";
 
plugin.restoreQueryControlTemplate =
	'<div class="echo-stream-restoreQuery echo-linkColor">' +
		'<a href="javascript:void(0)" class="echo-stream-restoreQueryControl">' +
			plugin.label("restoreQuery") +
		'</a>' +
	'</div>';

plugin.listenEvents = function(application) {
	plugin.subscribe(application, plugin.topic("internal.Item", "updateQuery"), function(event, data) {
		var query = application.substitute("user.id:'{Data:id}' {Data:query}", {
			"id": data.item.data.actor.id,
			"query": application.config.get("query")
		});
		plugin.applyQuery(application, query);
	});
};

plugin.applyQuery = function(application, query) {
	application.config.set("query", query);
	application.refresh();
};

plugin.setClickHandler = function(component, element, name, handler) {
	var callback = plugin.get(component, name);
	if (!callback) {
		callback = handler;
		plugin.set(component, name, handler);
	}
	element.unbind("click", callback).bind("click", callback);
};

plugin.bindHandler = function(item, element) {
	var handler = function() {
		item.publish(plugin.topic("internal.Item", "updateQuery"), {"item": item});
	};
	var title = item.data.actor.id != plugin.anonymousUserID
		? plugin.label("allCommentsByUser", {"name": item.data.actor.title || item.label("guest")})
		: plugin.label("allCommentsByAnonymous");
	plugin.setClickHandler(item, element, "userComments", handler);
	element.attr("title", title).addClass("echo-clickable");
};
 
plugin.renderers.Item.avatar = function(element) {
	var item = this;
	plugin.bindHandler(item, element);
	return item.parentRenderer("avatar", arguments);
};

plugin.renderers.Item.authorName = function(element, dom) {
	var item = this;
	plugin.bindHandler(item, element);
	return item.parentRenderer("authorName", arguments);
};

plugin.renderers.Stream.restoreQuery = function(element, dom) {
	var application = this;
	var visible = plugin.get(application, "query") != application.config.get("query");
	element[visible ? "show" : "hide"]();
};
 
plugin.renderers.Stream.restoreQueryControl = function(element) {
	var application = this;
	plugin.setClickHandler(application, element, "defaultQuery", function() {
		plugin.applyQuery(application, plugin.get(application, "query"));
	});
};

plugin.css = '.echo-stream-restoreQuery { float: left; }';
 
})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "UserPrivileges",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		plugin.addItemControl(application,
			plugin.assembleControl("GrantPermissions", application));
		plugin.addCss(plugin.css);
	}
});

plugin.addLabels({
	"moderatorRole": "Moderator",
	"administratorRole": "Administrator",
	"userControl": "Demote to User",
	"moderatorControl": "Promote to Moderator",
	"administratorControl": "Promote to Admin",
	"setRoleAction": "Setting up '{role}' role...",
	"unsetRoleAction": "Removing '{role}' role..."
});

plugin.roles = ["", "moderator", "administrator"];

plugin.assembleControl = function(action, application) {
	var callback = function() {
		var item = this;
		var role = plugin.getRole(item);
		var next = plugin.getNextRole(role);
		var roles = next != ""
			? (item.data.actor.roles || []).concat(next)
			: $.foldl([], item.data.actor.roles || [], function(_role, acc) {
				if ($.inArray(_role, plugin.roles) < 0) acc.push(_role);
			});
		var label = next == "" ? "unset" : "set";
		item.controls[plugin.name + "." + action].element
			.empty()
			.append(plugin.label(label + "RoleAction", {"role": next || role}));
		$.get(plugin.config.get(application, "submissionProxyURL", "", true), {
			"appkey": application.config.get("appkey"),
			"content": $.object2JSON({
				"endpoint": "users/update",
				"field": "roles",
				"value": roles.length ? roles.join(",") : "-",
				"identityURL": item.data.actor.id,
				"username": item.data.actor.title
			}),
			"target-query": application.config.get("query", ""),
			"sessionID": application.user.get("sessionID", "")
		}, function(data) {
			if (!data || data.result == "error") {
				item.rerender();
				return;
			}
			$.map(application.threads, function(thread) {
				thread.traverse(thread.children, function(child) {
					plugin.applyUserRolesUpdate(child, item, roles);
				});
				plugin.applyUserRolesUpdate(thread, item, roles);
			});
		}, "jsonp");
	};
	return function() {
		var item = this;
		var role = plugin.getRole(item);
		var template = (role
			? '<span class="echo-item-control-role echo-item-control-role-{Data:role}">{Data:label}</span>' +
				'(<span class="echo-clickable">{Data:button}</span>)'
			: '<span class="echo-clickable">{Data:button}</span>'
		);
		var label = item.substitute(template, {
			"role": role,
			"label": role ? plugin.label(role + "Role") : "",
			"button": plugin.label((plugin.getNextRole(role) || "user") + "Control")
		});
		return {
			"name": action,
			"label": label,
			"visible": item.data.actor.id != item.user.get("fakeIdentityURL") &&
				item.user.hasAny("roles", ["administrator"]),
			"callback": callback,
			"onetime": true
		};
	};
};

plugin.getRole = function(item) {
	var result = "";
	$.each(item.data.actor.roles || [], function(id, role) {
		if ($.inArray(role, plugin.roles) > 0) {
			result = role;
			if (role == "administrator") {
				return false; // break;
			}
		}
	});
	return result;
};

plugin.getNextRole = function(role) {
	return plugin.roles[($.inArray(role, plugin.roles) + 1) % plugin.roles.length];
};

plugin.applyUserRolesUpdate = function(target, source, roles) {
	if (target.data.actor.id != source.data.actor.id) return;
	target.data.actor.roles = roles;
	target.rerender();
};

plugin.css =
	".echo-item-control-role { margin-right: 3px; }" +
	".echo-item-control-role-moderator { color: #0000FF; }" +
	".echo-item-control-role-administrator { color: #008000; }";

})(jQuery);





(function($) {

var plugin = Echo.createPlugin({
	"name": "Whirlpools",
	"applications": ["Stream"],
	"init": function(plugin, application) {
		var config = plugin.config.get(application);
		var after = (typeof config.after == "undefined" ? 2 : config.after);
		var count = after / 2;
		application.config.combine({
			"after": after,
			"legacy": Math.floor(count),
			"recent": Math.ceil(count)
		}, config);
		plugin.listenEvents(application);
		plugin.addCss(plugin.css);
		plugin.extendRenderer("Item", "children", plugin.renderers.Item.children);
	}
});

plugin.addLabels({
	"moreExpand": "more (expand)",
	"moreItems": "more items"
});

//we should disable Whirlpools plugin if children pagination feature is "on"
plugin.listenEvents = function(application) {
	plugin.subscribe(application, "Stream.onDataReceive", function(topic, data) {
		if (application.isChildrenPaginationEnabled && application.isChildrenPaginationEnabled()) {
			application.disablePlugin(plugin.name);
		}
	});
};

plugin.initMarker = function(item, collapsedItemsCount) {
	return new plugin.Marker({
		"after": plugin.config.get(item, "after"),
		"count": collapsedItemsCount,
		"depth": item.depth + 1,
		"clickable": plugin.config.get(item, "clickable")
	}, {
		"onexpand": function() {
			plugin.set(item, "expanded", true);
			item.rerender("children");
		}
	});
};

plugin.renderers = {"Item": {}};

plugin.renderers.Item.children = function(element, dom) {
	var item = this;
	var args = arguments;
	var config = plugin.config.get(item);
	var clearFlags = function(item) {
		// we should cleanup the flags for the collapsed items
		// because they are not handled by the rendering engine
		// and therefore remains in the item, but they are not necessary
		// after the children list rendering is complete
		delete item.deleted;
		delete item.added;
	};
	var substitute = function(children) {
		var _children = item.children;
		item.children = children;
		item.parentRenderer("children", args);
		item.children = _children;
	};
	// too few items to be collapsed or list already expanded
	if (!item.children.length ||
		item.children.length <= config.after ||
		plugin.get(item, "expanded")) {
			item.parentRenderer("children", args);
			return;
	}
	// display only expand marker
	if (config.after == 0 && item.children.length) {
		var count = item.traverse(item.children, function(item, acc) {
			clearFlags(item);
			return ++acc; 
		}, 0);
		substitute([plugin.initMarker(item, count)]);
		return;
	}
	// display items & expand marker
	var slice = item.children.slice(config.recent, item.children.length - config.legacy);
	var count = item.traverse(slice, function(item, acc) {
		clearFlags(item);
		return ++acc;
	}, 0);
	var children = [].concat(
		plugin.getRecentChildren(item, config.recent),
		plugin.initMarker(item, count),
		plugin.getLegacyChildren(item, config.legacy)
	);
	substitute(children);
};

plugin.getRecentChildren = function(item, count) {
	var position = count;
	for (var i = 0; i < count; i++) {
		if (item.children[i].added || item.children[i].deleted) {
			var flag = item.children[i].added ? "deleted" : "added";
			item.children[position++][flag] = true;
		}
	}
	return item.children.slice(0, position);
};

plugin.getLegacyChildren = function(item, count) {
	var length = item.children.length;
	var position = length - count;
	for (var i = length - count; i < length; i++) {
		if (item.children[i].added || item.children[i].deleted) {
			var flag = item.children[i].added ? "deleted" : "added";
			item.children[--position][flag] = true;
		}
	}
	return item.children.slice(position);
};

plugin.Marker = function(data, callbacks) {
	data.label = this.label("more" + (data.clickable ? "Expand" : "Items"));
	this.init({
		"data": data,
		"callbacks": callbacks
	});
};

plugin.Marker.prototype = new Echo.Object();

plugin.Marker.prototype.namespace = "Plugins.Whirlpools";

plugin.Marker.prototype.cssPrefix = "echo-whirlpool-";

plugin.Marker.prototype.renderers = {};

plugin.Marker.prototype.template =
	'<div class="echo-whirlpool-container echo-trinaryBackgroundColor echo-item-depth-{Data:depth} echo-item-container-child">' +
		'<span class="echo-whirlpool-message">{Data:count} {Data:label}</span>' +
	'</div>';

plugin.Marker.prototype.renderers.container = function(element) {
	var self = this;
	if (this.data.clickable) {
		element.addClass("echo-clickable").click(function() {
			self.callbacks.onexpand();
		});
	}
	if (this.data.after == 0) {
		element.addClass(this.cssPrefix + "container-collapse-all");
	}
};

plugin.Marker.prototype.renderers.message = function(element) {
	if (this.data.clickable) {
		element.addClass("echo-linkColor");
	}
};

plugin.css =
	'.echo-whirlpool-container { text-align: center; }' +
	'.echo-whirlpool-container-collapse-all { text-align: left; }' +
	'.echo-whirlpool-message { display: inline-block; padding-left: 18px; background: url("//c0.echoenabled.com/images/whirlpool.png") no-repeat center left; }';

})(jQuery);




