function ElementTree(data) {
	var el;

	if ('string'==typeof data || 'number'==typeof data) {
		el=document.createTextNode(data);
	} else {
		// create the element
		el=new Element(data.tag);
		delete(data.tag);

		// append the children
		if ('undefined'!=typeof data.children) {
			if ('string'==typeof data.children ||
				'undefined'==typeof data.children.length
			) {
				// strings and single elements
				el.appendChild(ElementTree(data.children));
			} else {
				// arrays of elements
				for (var i=0, child=null; 'undefined'!=typeof (child=data.children[i]); i++) {
					el.appendChild(ElementTree(child));
				}
			}
			delete(data.children);
		}

		// Set events, if any.
		if (data.events) {
			el.addEvents(data.events);
			delete(data.events);
		}

		// Set innerHTML, if any.
		if (data.innerHTML) {
			el.innerHTML=data.innerHTML;
			delete(data.innerHTML);
		}

		// Any other data is attributes.
		el.setProperties(data);
	}

	return el;
}


var Configurator=new Class({
	valid: null,

	addRemoveQueue: null,
	busy: null,

	initialize: function() {
		this.valid=false;

		this.addRemoveQueue=[];
		this.busy=false;

		return true;
	},

	addButton: function(button) {
		return false;
	},

	addButtonById: function(id, suppressLog) {
		return false;
	},

	addButtons: function(buttons) {
		return false;
	},

	addToQueue: function(data, action, position) {
		var parameters={
			'data': data,
			'action': action
		}

		if (position) parameters.position=position

		this.addRemoveQueue.push(parameters);

		return true;
	},

	clearAddRemoveQueue: function() {
		this.addRemoveQueue=[];
	},

	clientDataFromSitepass: function() {
		if ($defined(sitepass.camp_id)) gHermes.campId=sitepass.camp_id;
		if ($defined(sitepass.client_id)) gHermes.clientId=sitepass.client_id;
		if ($defined(sitepass.install_time)) gHermes.installTime=sitepass.install_time;
		if ($defined(sitepass.src_id)) gHermes.sourceId=sitepass.src_id;
		if ($defined(sitepass.version)) gHermes.version=sitepass.version;

		return true;
	},

	clientDataFromWidget: function() {
		gHermes.campId=AlotWidget.camp_id;
		gHermes.clientId=AlotWidget.client_id;
		gHermes.installTime=AlotWidget.install_time;
		gHermes.sourceId=AlotWidget.src_id;
		gHermes.version=AlotWidget.tb_version;

		return true;
	},

	attachButtonEvents: function() {
		return false;
	},

	getButtons: function() {
		return false;
	},

	moveButton: function(previousPosition, newPosition) {
		return false;
	},

	processAddRemoveQueue: function(e) {
		if (!e && this.busy) return true;
		this.busy=false;

		if (0==this.addRemoveQueue.length) return true;

		// Pop the first item off of the queue.
		var item=this.addRemoveQueue.splice(0, 1)[0];

		if (!$defined(item.data)) return false;

		this.busy=true;

		if ('add'==item.action) return this.addButton(item.data, true);

		if ('setToolbar'==item.action) return this.setToolbar(item.data);

		return this.removeButton(item.data, item.position, true);
	},

	removeButton: function(button, position, suppressLog) {
		return false;
	},

	removeButtons: function() {
		return false;
	}
});
Configurator.implement(new Events);


var ConfiguratorHm=Configurator.extend({
	initialize: function() {
		this.parent();

		this.clientDataFromWidget();

		gHermes.product='home';
		gHermes.browser=window.ie ? 'ie' : 'ff';

		if ('undefine'==typeof addPod || 'function'!=$type(addPod)) return false;

		this.valid=true;

		return true;
	},

	addButton: function(button) {
		if (!this.valid) return false;

		if ('object'==$type(button)) {
			if (!button.id) return false;
			button=button.id;
		}

		try {
			addPod(button);
			gHermes.addDel(1, button);
			gHermes.addDelLog();

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

	getButtons: function() {
		var columns=$ES('div.column[id^=col]');

		var buttons=[];
		for (var col=0, numCol=columns.length; col<numCol; col++) {
			var pods=columns[col].getElements('.pod');

			for (var pod=0, numPod=pods.length; pod<numPod; pod++) {
				if (!pods[pod].id) continue;

				var instanceId=pods[pod].id.replace('p','').toInt();
				var layoutInstance=getByInstance(instanceId);

				buttons.push(layoutInstance);
			}
		}
		return buttons;
	}
});


var ConfiguratorTb=Configurator.extend({
	cookie: null,
	defaultPosition: null,
	originalButtons: null,
	xmlBaseUrl: null,

	supportsSetToolbar: null,

	initialize: function() {
		this.parent();

		this.cookie=0;
		this.defaultPosition=1;
		this.xmlBaseUrl='update.alot.com/1/update/button_configs/button_config_';

		gHermes.product='toolbar';

		return true;
	},

	addButton: function(button, suppressLog) {
		if (!this.valid) return false;

		if ('number'==$type(button)) {
			return this.addButtonById(button, suppressLog);
		}

		if ('object'!=$type(button)) return false;

		if (button.id) {
			return this.addButtonById(button.id, suppressLog);
		}

		if (button.caption && button.hint && button.imageUrl && button.url) {
			return this.addButtonByData(
				button.caption, button.hint, button.imageUrl, button.url, suppressLog
			);
		}

		return false;
	},

	addButtons: function(buttons) {
		if (!this.valid) return false;

		if ('object'==$type(buttons) || 'number'==$type(buttons)) {
			return this.addToQueue(buttons, 'add');
		}

		if ('array'!=$type(buttons)) return false;

		if (0==buttons.length) return true;

		for (var i=0, numButton=buttons.length; i<numButton; i++) {
			if (!this.addToQueue(buttons[i], 'add')) return false;
		}

		this.processAddRemoveQueue();

		return true;
	},

	checkSetToolbar: function() {
		this.supportsSetToolbar=false;
		return false;
	},

	loadConfig: function(buttonIds, name) {
		return false;
	},

	removeButtons: function() {
		if (!this.valid) return false;

		var buttons=this.getButtons();

		if (!buttons) return false;
		if (0==buttons.length) return true;

		for (var i=0, numButton=buttons.length; i<numButton; i++) {
			if (!this.addToQueue(buttons[i].id, 'remove', 1)) return false;
		}

		this.processAddRemoveQueue();

		return true;
	},

	setToolbar: function(buttonIds, name) {
		return false;
	}
});

var ConfiguratorTbIe=ConfiguratorTb.extend({
	api: null,

	version: null,

	initialize: function() {
		this.parent();

		this.xmlBaseUrl='http://'+this.xmlBaseUrl;

		gHermes.browser='ie';

		// Version should always be the current date/time.
		var datetime=new Date();
		var year=datetime.getUTCFullYear();
		var month=datetime.getUTCMonth()+1;
		if (month<10) month='0'+month;
		var day=datetime.getUTCDay();
		if (day<10) day='0'+day;

		var hour=datetime.getUTCHours();
		var minute=datetime.getUTCMinutes();
		var second=datetime.getUTCSeconds();

		this.version=year+'-'+month+'-'+day+'T'+hour+':'+minute+':'+second+'+00:00';

		return true;
	},

	addButtonById: function(id, suppressLog) {
		if (!this.valid) return false;

		try {
			this.api.add(
				id,
				this.version,
				this.xmlBaseUrl+id+'_1.xml',
				this.defaultPosition,
				this.cookie++
			);

			if (!suppressLog) {
				gHermes.addDel(1, id);
				gHermes.addDelLog();
			}

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

	attachButtonEvents: function() {
		try {
			this.api.OnDownloadComplete=function() {gHermes.configurator.fireEvent('buttonAdd', {'detail': arguments});};
			this.api.OnMove=function() {gHermes.configurator.fireEvent('buttonMove', {'detail': arguments});};
			this.api.OnRemove=function() {gHermes.configurator.fireEvent('buttonRemove', {'detail': arguments});};
		} catch (e) {
			return false;
		}

		this.addEvent('buttonAdd', this.processAddRemoveQueue.bindAsEventListener(this));
		this.addEvent('buttonRemove', this.processAddRemoveQueue.bindAsEventListener(this));
	},

	checkSetToolbar: function() {
		if (null!==this.supportsSetToolbar) return this.supportsSetToolbar;

		this.supportsSetToolbar=false;
		try {
			// When the last parameter to setToolbar is the string "-1", the
			// function knows that we are testing for its existence and does
			// nothing but return a true value.
			this.api.setToolbar('', '', '', '-1');
			this.supportsSetToolbar=true;
		} catch(e) {}

		return this.supportsSetToolbar;
	},

	getButtons: function() {
		if (!this.valid) return false;

		try {
			return Json.evaluate(this.api.Buttons, true);
		} catch (e) {
			return false;
		}
	},

	moveButton: function(previousPosition, newPosition) {
		if (!this.valid) return false;

		if ('number'!=$type(previousPosition) || previousPosition<1) return false;
		if ('number'!=$type(newPosition) || newPosition<1) return false;

		try {
			this.api.move(previousPosition, newPosition);

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

	loadConfig: function(buttonIds, name) {
		this.addToQueue({
			buttonIds: buttonIds.join(';'),
			name: name,
			sourceId: ''
		}, 'setToolbar');

		return this.processAddRemoveQueue();
	},

	removeButton: function(button, position, suppressLog) {
		if (!this.valid) return false;

		if ('object'==$type(button)) {
			if (!button.id) return false;
			button=button.id;
		}
		if (!position) position=this.defaultPosition;

		try {
			if (!this.api.remove(button, position)) return false;

			if (!suppressLog) {
				gHermes.addDel(-1, button);
				gHermes.addDelLog();
			}
		} catch (e) {
			return false;
		}

		return true;
	},

	setToolbar: function(parameters) {
		try {
			this.api.setToolbar(
				parameters.buttonIds,
				parameters.name,
				parameters.sourceId,
				this.cookie
			);
		} catch (e) {
			return false;
		}

		return true;
	}
});


var ConfiguratorTbIeSite=ConfiguratorTbIe.extend({
	initialize: function() {
		this.parent();

		if ('undefined'==typeof SHOT$$) return false;
		this.api=SHOT$$;
		this.valid=true;

		this.clientDataFromSitepass();

		this.originalButtons=this.getButtons();

		this.attachButtonEvents();

		return true;
	}
});


var ConfiguratorTbIeWidget=ConfiguratorTbIe.extend({
	initialize: function() {
		this.parent();

		if ('undefined'==typeof SHOT$.Configuration) return false;
		this.api=SHOT$.Configuration;
		this.valid=true;

		this.clientDataFromWidget();

		this.originalButtons=this.getButtons();

		this.attachButtonEvents();

		return true;
	}
});


var ConfiguratorTbFf=ConfiguratorTb.extend({
	initialize: function() {
		this.parent();

		if (!sitepass.api) return false;
		this.valid=true;

		this.xmlBaseUrl='https://'+this.xmlBaseUrl;

		gHermes.browser='ff';

		this.originalButtons=this.getButtons();

		this.attachButtonEvents();

		return true;
	},

	addButtonById: function(id, suppressLog) {
		if (!this.valid) return false;

		try {
			sitepass.api.Custom.add(
				id,
				false,
				this.xmlBaseUrl+id+'_1_plaintext.xml',
				this.defaultPosition,
				this.cookie++
			);

			if (!suppressLog) {
				gHermes.addDel(1, id);
				gHermes.addDelLog();
			}

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

	attachButtonEvents: function() {
		window.addEventListener(
			'AlotButtonAdd',
			function(e) {gHermes.configurator.fireEvent('buttonAdd', e);},
			false
		);
		window.addEventListener(
			'AlotButtonMove',
			function(e) {gHermes.configurator.fireEvent('buttonMove', e);},
			false
		);
		window.addEventListener(
			'AlotButtonRemove',
			function(e) {gHermes.configurator.fireEvent('buttonRemove', e);},
			false
		);

		this.addEvent('buttonAdd', this.processAddRemoveQueue.bindAsEventListener(this));
		this.addEvent('buttonRemove', this.processAddRemoveQueue.bindAsEventListener(this));
	},

	getButtons: function() {
		if (!this.valid) return false;

		try {
			var buttons=[];
			for (var i=0, button=null; button=sitepass.api.Custom.get(i); i++) {
				buttons.push(button);
			}
			return buttons;
		} catch (e) {
			return false;
		}
	},

	moveButton: function(previousPosition, newPosition) {
		if (!this.valid) return false;

		if ('number'!=$type(previousPosition) || previousPosition<1) return false;
		if ('number'!=$type(newPosition) || newPosition<1) return false;

		try {
			sitepass.api.Custom.move(previousPosition, newPosition, this.cookie++);

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

	removeButton: function(button, position, suppressLog) {
		if (!this.valid) return false;

		if ('object'==$type(button)) {
			if (!button.id) return false;
			button=button.id;
		}
		if (!position) position=this.defaultPosition;

		try {
			if (sitepass.api.Custom.remove(button, position, this.cookie++)) {
				return false;
			}

			if (!suppressLog) {
				gHermes.addDel(-1, button);
				gHermes.addDelLog();
			}

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


var ConfiguratorTbFfSite=ConfiguratorTbFf.extend({
	initialize: function() {
		if (!this.parent()) return false;

		this.clientDataFromSitepass();

		return true;
	}
});


var ConfiguratorTbFfWidget=ConfiguratorTbFf.extend({
	initialize: function() {
		if (!this.parent()) return false;

		this.clientDataFromWidget();

		return true;
	}
});


// This is an abstraction layer that allows the web-based and widget-based flavors
// of Hermes to use the same JS.

var Hermes=new Class({
	configurator: null,
	navigation: null,

	browser: null,
	product: null,
	environment: null,

	// These values are set by the configurator.
	campId: null,
	clientId: null,
	installTime: null,
	sourceId: null,
	version: null,

	addDelQueue: null,
	addDelLogUrl: null,

	signOutUrl: null,

	initialize: function() {
		// Defaults.
		this.product='none';
		this.browser='unknown';
		this.environment='unknown';

		this.campId='unknown';
		this.clientId='unknown';
		this.installTime='unknown';
		this.sourceId='unknown';
		this.version='unknown';

		this.addDelQueue=[];
		this.addDelLogUrl='http://custom.alot.com/api/addDelLog';

		this.signOutUrl='http://custom.alot.com/api/accountProxy?signOut=true';
	},

	$E: function(selector) {
		return false;
	},

	$ES: function(selector) {
		return false;
	},

	addDel: function(addDel, buttonId) {
		this.addDelQueue.push({'addDel': addDel, 'id': buttonId});
	},

	addDelLog: function() {
		if (0==this.addDelQueue.length) return true;

		var ids=[];
		var addDels=[];

		for (var i=0, numEvent=this.addDelQueue.length; i<numEvent; ++i) {
			ids.push(this.addDelQueue[i].id);
			addDels.push(this.addDelQueue[i].addDel);
		}

		this.addDelQueue=[];

		this.getJson(
			this.addDelLogUrl,
			function() {},
			{
				'addDel': addDels,
				'button': ids,
				'client': this.clientId,
				'source': this.sourceId
			}
		);

		return true;
	},

	cacheBust: function(url) {
		var pair='cacheBust='+$random(1, 999999);
		if (url.match(/\?/)) return url+'&'+pair;
		return url+'?'+pair;
	},

	getText: function(url, callback, postData, noCache) {
		return false;
	},

	getJson: function(url, callback, postData, noCache) {
		return false;
	},

	loadConfigurator: function() {
		return new Configurator();
	},

	loadNavigation: function() {
		this.navigation=new Navigation();
	},

	onLoad: function(func) {
		return false;
	},

	signOut: function() {
		gHermes.getText(
			this.signOutUrl,
			this.signOutCb.bind(this),
			{'csrf': Cookie.get('csrf')},
			true
		);
	},

	signOutCb: function(response) {
		response=Json.evaluate(response, true);
		var navigation=this.navigation;

		if (!response || 'object'!=$type(response) || response.error) {
			navigation.currentTab.addMessage("We could not sign you out at this time, please try again.");
			return false;
		}

		navigation.signOutHide();

		if ($defined(navigation.tabs.save)) navigation.tabs.save.signOut();

		navigation.currentTab.addMessage(
			"You have been successfully signed out.", true, true
		);
	},

	track: function(tab) {
		if (('undefined'!=typeof pageTracker) && tab) {
			pageTracker._trackPageview(
				'/'+this.environment+'/'+this.product+'/'+tab
			);
		}

		return true;
	}
});


var HermesSite=Hermes.extend({
	initialize: function() {
		this.parent();

		this.environment='site';
	},

	$E: function(selector) {
		return $E(selector);
	},

	$ES: function(selector) {
		return $ES(selector);
	},

	getText: function (url, callback, postData, noCache) {
		if (noCache) url=this.cacheBust(url);
		new Ajax(url, {
			method:$defined(postData) ? 'post' : 'get',
			onComplete:function(str, xml){ callback(str) }
		}).request($defined(postData) ? postData : null);
	},

	getJson: function (url, callback, postData, noCache) {
		if (noCache) url=this.cacheBust(url);
		new Json.Remote(url, {
			method:$defined(postData) ? 'post' : 'get',
			onComplete:callback
		}).send($defined(postData) ? postData : null);
	},

	loadConfigurator: function () {
		if ('undefined'!=typeof sitepass) {
			if (sitepass.passed) {
				if ('ie'==sitepass.platform && 2.2<=parseFloat(sitepass.version, 10)) {
					return new ConfiguratorTbIeSite();
				}
				if ('ff'==sitepass.platform && 2.0<=parseFloat(sitepass.version, 10)) {
					return new ConfiguratorTbFfSite();
				}
			}
		}

		return new Configurator();
	},

	onLoad: function(func) {
		window.addEvent('domready', func);
	}
});


var HermesWidget=Hermes.extend({
	initialize: function() {
		this.parent();

		this.environment='widget';

		AlotWidget.beforeShow(function() {
			gHermes.navigation.refreshContainer();
		});

		AlotWidget.beforeHide(function() {
			gHermes.navigation.hideContainer();
		});
	},

	$E: function(selector) {
		return AlotWidget.$E(selector);
	},

	$ES: function(selector) {
		return AlotWidget.$ES(selector);
	},

	getText: function (url, callback, postData, noCache) {
		if (noCache) url=this.cacheBust(url);
		return AlotWidget.getText(url, callback, postData);
	},

	getJson: function (url, callback, postData, noCache) {
		if (noCache) url=this.cacheBust(url);
		return AlotWidget.getJson(url, callback, postData);
	},

	loadConfigurator: function () {
		if ('hm'==AlotWidget.env) {
			return new ConfiguratorHm();
		}

		if ('tb'==AlotWidget.env) {
			if (SHOT$.Configuration) {
				return new ConfiguratorTbIeWidget();
			}
			if ('undefined'!=sitepass && sitepass.api) {
				return new ConfiguratorTbFfWidget();
			}
		}

		return new Configurator();
	},

	onLoad: function(func) {
		AlotWidget.onLoad(func);
	}
});


var Navigation=new Class({
	tabEls: null,
	separatorEls: null,
	supportEls: null,
	contentEls: null,
	tabs: null,
	currentTab: null,

	initialize: function() {
		this.tabs={};

		if (!this.getElements()) return false;
		if (!this.attachEvents()) return false;

		// Legacy versions of the toolbar load Hermes as a toolbar widget in
		// the background when the browser is loaded. For those versions (IE
		// toolbar up to and including version 2.5.7001 and all versions of the
		// FF toolbar), do not initialize the add tab until the widget button
		// has been clicked.
		if ('widget'==gHermes.environment && 'toolbar'==gHermes.product) {
			if ('ie'==gHermes.browser) {
				if ('2.5.7001'>=gHermes.version) return true;
			} else {
				return true;
			}
		}

		return this.changeTab(null, 'add');
	},

	attachEvents: function() {
		this.tabEls.each(function(linkEl) {
			linkEl.addEvent(
				'click',
				this.changeTab.bindAsEventListener(
					this, linkEl.href.replace(/.*tab=/, '')
				)
			);
		}.bind(this));


		this.supportEls.addEvent('click', function(e) {
			e=new Event(e);

			if ('a'==e.target.getTag() && e.target.hasClass('signOut')) {
				e.stop();
				return gHermes.signOut();
			}

			if ('undefined'!=typeof AlotWidget) {
				if (AlotWidget.setBrowserUrl(this.href)) {
					e.stop();
					AlotWidget.hide();
				}
				this.href=this.href+'tb';
			}
		});

		return true;
	},

	changePage: function(page) {
		if (!this.loadTab(page)) return false;

		this.contentEls.each(function(contentEl) {
			if (contentEl.hasClass(page)) {
				contentEl.removeClass('inactive');
				contentEl.addClass('active');
			} else {
				contentEl.removeClass('active');
				contentEl.addClass('inactive');
			}
		});

		return true;
	},

	changeTab: function(e, tab) {
		if (e) new Event(e).stop();
		if (!tab) return false;

		this.tabEls.each(function(linkEl) {
			var parent=linkEl.getParent();
			if (parent.hasClass(tab+'Tab')) {
				parent.addClass('active');
			} else {
				parent.removeClass('active');
			}
		});

		this.updateSeparators();

		return this.changePage(tab);
	},

	getElements: function() {
		this.tabEls=gHermes.$ES('.tabs li a');
		if (!this.tabEls) return false;

		this.separatorEls=gHermes.$ES('.tabs li.separator');

		this.supportEls=gHermes.$ES('.support a');
		if (!this.supportEls) return false;

		var contentEl=gHermes.$E('ul.content');
		this.contentEls=contentEl.getChildren();
		if (!this.contentEls) return false;

		return true;
	},

	hideContainer: function() {
		gHermes.$E('.mainContainer').setStyle('display', 'none');
		if (this.tabs.add) {
			this.tabs.add.changeCategory('category=0');
			this.tabs.add.closeCategories();
		} else {
			gHermes.navigation.changeTab(null, 'add');
		}
	},

	refreshContainer: function() {
		if (this.tabs.add) {
			this.tabs.add.showMainContainer();

		} else {
			gHermes.navigation.changeTab(null, 'add');
		}
		gHermes.$E('.mainContainer').setStyle('display', 'block');
	},

	signOutHide: function() {
		gHermes.$E('li.signOut').addClass('hidden');
	},

	loadTab: function(name) {
		if (this.tabs[name]) return this.showExistingTab(name);

		var tab=false;

		switch(name) {
		case 'add':
			tab=new TabAdd();
			break;
		case 'remove':
			tab=new TabRemove();
			break;
		case 'save':
			tab=new TabSave();
			break;
		}

		if (this.tabs.add) this.tabs.add.removeMessage();

		// Since the save tab's tracking is dependent on the result of AJAX
		// requests, it handles firing tracking events itself.
		if ('save'!=name) tab.track();

		this.tabs[name]=tab;
		this.currentTab=tab;
		return true;
	},

	showExistingTab: function(name) {
		if ('save'==name) {
			this.tabs.save.resetTracking();
			this.tabs.save.getConfigs();
		} else {
			if ('add'==name) this.tabs.add.clearAdded();

			this.tabs[name].track();
		}
		this.currentTab=this.tabs[name];

		return true;
	},

	signOutShow: function() {
		gHermes.$E('li.signOut').removeClass('hidden');
	},

	updateSeparators: function() {
		if (!this.separatorEls) return false;

		this.separatorEls.each(function(el) {
			if (el.getPrevious().hasClass('active') || el.getNext().hasClass('active')) {
				el.removeClass('separator');
				el.addClass('separatorInvisible');
			} else {
				el.addClass('separator');
				el.removeClass('separatorInvisible');
			}
		});

		return true;
	}
});


var Tab=new Class({
	messageElSelector: null,
	messageEl: null,

	// Takes in the CSS selector to the message element.
	initialize: function(selector) {
		this.messageElSelector=selector;
		this.findMessageEl();
	},

	addMessage: function(message, fadeIn, fadeOut) {
		if (!message) return false;

		if (!this.messageEl) return false;

		message=this.fixupMessageEl(message);

		var currentMessages=this.messageEl.getChildren();
		if (0!=currentMessages.length) {
			// If a message already exists, replace it.
			this.messageEl.adopt(message);
			currentMessages[0].remove();
			fadeIn=false;
		}

		if (fadeIn) message.setOpacity(0);

		this.messageEl.adopt(message);

		if (fadeIn) this.fadeInMessage(message, fadeOut);

		if (!fadeIn && fadeOut) {
			setTimeout(this.fadeOutMessage.bind(this, message), 3000);
		}

		return true;
	},

	fadeInMessage: function(el, fadeOut) {
		if (!el && this.messageEl) {
			el=this.messageEl.getChildren()[0];
		}

		if ('element'!=$type(el)) return false;

		var settings={
			duration: 250,
			wait: false,
			transition: Fx.Transitions.Quad.easeIn
		};

		if (fadeOut) {
			settings.onComplete=function() {
				setTimeout(this.fadeOutMessage.bind(this, el), 3000);
			}.bind(this);
		}

		new Fx.Styles(el, settings).start({opacity: ['0', '1']});
	},

	fadeOutMessage: function(el) {
		if (!el && this.messageEl) {
			el=this.messageEl.getChildren()[0];
		}

		if ('element'!=$type(el)) return false;

		if (1==el.getStyle('opacity')) {
			new Fx.Styles(el, {
				duration: 500,
				wait: false,
				transition: Fx.Transitions.Quad.easeOut,
				onComplete: function() {
					if (el.getParent()) {
						el.remove();
					}
				}.bind(el)
			}).start({opacity: ['1', '0']});
		}
	},

	findMessageEl: function() {
		if (!this.messageElSelector) return false;
		this.messageEl=gHermes.$E(this.messageElSelector);
	},

	fixupMessageEl: function(message) {
		if ('string'==$type(message)) {
			message=ElementTree({
				tag: 'div',
				innerHTML: message
			});
		}

		return this.targetLinks(message);
	},

	removeMessage: function(el) {
		if (!el && this.messageEl) {
			el=this.messageEl.getChildren()[0];
		}

		if ('element'!=$type(el)) return false;

		el.remove();
	},

	targetLinks: function(el) {
		// If this is a toolbar widget, try to open links in error messages in
		// the main browser window. If that fails, open them in a new window.
		if ('widget'==gHermes.environment) {
			el.getElements('a').each(function(linkEl) {
				linkEl.setProperty('target', '_blank');

				linkEl.addEvent('click', function(e) {
					if (AlotWidget.setBrowserUrl(linkEl.href)) {
						new Event(e).stop();
						AlotWidget.hide();
					}
				});
			});
		}

		return el;
	}
});

var TabAdd=Tab.extend({
	baseUrl: null,

	addPageEl: null,
	splashPageEl: null,
	searchEl: null,
	sortEl: null,

	categoryId: null,
	expose: null,
	page: null,
	query: null,
	sort: null,

	buttons: null,
	splashButtons: null,
	splashAds: null,
	categoryEls: null,

	initialize: function() {
		this.parent('.addPage .message');

		this.baseUrl='http://custom.alot.com/api/buttonPage';

		this.addPageEl=gHermes.$E('.addPage');
		if (!this.addPageEl) return false;

		this.splashPageEl=gHermes.$E('.splashPage');
		if (!this.splashPageEl) return false;

		if (!this.initializePage()) return false;

		this.categoryEls=gHermes.$ES('.categories ul li');
		if (!this.attachCategoryEvents()) return false;

		this.resizeCategories();
		if ('site'==gHermes.environment) {
			window.addEvent('resize', this.resizeCategories.bind(this));
		}

		this.showMainContainer();

		return true;
	},

	attachButtonEvents: function() {
		this.buttons=[];

		this.addPageEl.getElements('.buttonList .button').each(function(buttonEl) {
			this.buttons.push( new Button(buttonEl) );
		}.bind(this));

		return true;
	},

	attachCategoryEvents: function() {
		if (!this.categoryEls) return false;

		this.categoryEls.each(function(itemEl) {
			itemEl.addEvent('click', this.clickCategory.bindWithEvent(this, itemEl));
		}.bind(this));

		return true;
	},

	attachEvents: function() {
		gHermes.$ES('.setBar a').each(function(linkEl) {
			linkEl.addEvent(
				'click', this.changePage.bindAsEventListener(this, linkEl.href)
			);
		}.bind(this));

		if (this.sortEl) this.sortEl.addEvent(
			'change',
			this.changeSort.bind(this)
		);

		if (this.searchEl) this.searchEl.addEvent(
			'submit',
			this.changeSearch.bindAsEventListener(this)
		);

		var splashMsg=gHermes.$ES('.splash .footer a');
		if (splashMsg) {
			splashMsg.addEvent(
				'click', function() {
					this.changeCategory('category=0');
					this.closeCategories();
					if ('undefined'!=typeof pageTracker) {
						pageTracker._trackEvent('Splash', 'See all buttons');
					}
				}.bind(this)
			);
		}

		return true;
	},

	clearAdded: function() {
		var buttons=this.buttons;

		for (var i=buttons.length-1; i>=0; --i) {
			buttons[i].hideAdded();
		}

		return true;
	},

	changeCategory: function(category) {
		this.messageElSelector='.addPage .message';
		this.findMessageEl();
		this.clearAdded();

		var categoryId=category.replace(/.*category=/, '').toInt();
		if (categoryId==this.categoryId && !this.page) {
			this.splashPageEl.setStyle('display', 'none');
			this.addPageEl.setStyle('display', 'block');
			return true;
		}

		this.categoryId=categoryId;
		this.query='';
		this.page=0;
		return this.request(false);
	},

	changePage: function(e, page) {
		new Event(e).stop();

		var page=page.replace(/.*page=/, '');
		if (page==this.page) return true;

		this.page=page;
		return this.request(false);
	},

	changeSearch: function(e) {
		new Event(e).stop();
		var query=this.searchEl.getElement('input[type=text]').getValue().trim();

		if ('undefined'!=typeof pageTracker) {
			pageTracker._trackPageview(
				'/'+gHermes.environment+'/'+gHermes.product+'/add?search='+query
			);
		}

		this.query=query;
		this.sort='match';
		this.page=0;
		return this.request(false);
	},

	changeSort: function() {
		var sort=this.sortEl.getValue();
		if (sort==this.sort) return true;

		this.sort=sort;
		this.page=0;
		return this.request(false);
	},

	clickCategory: function(e, itemEl) {
		var target=$(e.target);
		new Event(e).stop();

		if ('a'==target.getTag()) this.changeCategory(target.href);

		if (itemEl.hasClass('open')) {
			return this.closeCategory(itemEl);
		}

		this.closeCategories();
		return this.openCategory(itemEl, true);
	},

	closeCategory: function(itemEl) {
		itemEl.getElement('a').removeClass('active');

		if (!itemEl.hasClass('openable')) return true;

		itemEl.removeClass('open');
		itemEl.addClass('closed');

		var listEl=itemEl.getElement('ul');
		if (!listEl) return false;

		listEl.addClass('hidden');

		return true;
	},

	closeCategories: function() {
		this.categoryEls.each(this.closeCategory.bind(this));
	},

	initializePage: function() {
		this.findMessageEl();

		this.attachButtonEvents();

		this.searchEl=gHermes.$E('.buttonSearch');
		if (this.searchEl) {
			var inputEl=this.searchEl.getElement('.text');
			if (inputEl) this.query=inputEl.getValue().trim();
		}

		this.sortEl=gHermes.$E('.setBar select');
		if (this.sortEl) this.sort=this.sortEl.getValue();

		this.page=0;
		var pageEl=gHermes.$E('li span.current');
		if (pageEl) this.page=pageEl.getText().toInt()-1;

		if (null==this.categoryId) {
			var categoryIdEl=gHermes.$E('input[name=categoryId]');
			if (categoryIdEl) this.categoryId=categoryIdEl.getValue();
		}

		this.expose='';
		var exposeEl=gHermes.$E('input[name=expose]');
		if (exposeEl) this.expose=exposeEl.getValue();

		this.splashAds='';
		var splashAdsEl=gHermes.$E('input[name=splashAds]');
		if (splashAdsEl && splashAdsEl.getValue()) {
			this.splashAds=Json.evaluate(splashAdsEl.getValue());
		}

		return this.attachEvents();
	},

	openCategory: function(itemEl, leaf) {
		if (leaf) itemEl.getElement('a').addClass('active');

		if (itemEl.hasClass('openable')) {
			itemEl.addClass('open');
			itemEl.removeClass('closed');

			var listEl=itemEl.getElement('ul');
			if (!listEl) return false;

			listEl.removeClass('hidden');
		}

		var parent=itemEl.getParent();
		if (!parent.hasClass('hidden')) return true;

		this.openCategory(parent.getParent());
	},

	request: function(noCache) {
		var qsVars={};
		if (null!==this.categoryId) qsVars.category=this.categoryId;
		if (null!==this.expose) qsVars.expose=this.expose;
		if (null!==this.page) qsVars.page=this.page;
		if (null!==this.query) qsVars.search=this.query;
		if (null!==this.sort) qsVars.sort=this.sort;

		var qs=Object.toQueryString(qsVars);
		if (qs) qs='?'+qs;

		gHermes.getText(this.baseUrl+qs, this.requestCallback.bind(this), null, noCache);
	},

	requestCallback: function(result) {
		if (!result) return false;

		this.addPageEl.setHTML(result);
		this.messageElSelector='.addPage .message';
		this.splashPageEl.setStyle('display', 'none');
		this.addPageEl.setStyle('display', 'block');
		this.track();

		return this.initializePage();
	},

	resizeCategories: function() {
		var categoriesEl=gHermes.$E('ul.root');
		var height;

		if ('site'==gHermes.environment) {
			height=window.getHeight()-categoriesEl.getTop();
		} else {
			var hermesEl=gHermes.$E('.hermes');
			var hermesHeight=hermesEl.getSize().size.y;

			// IE6 claims that the hermes element is 105px bigger than it is.
			if ('home'==gHermes.product && window.ie6) hermesHeight-=105;

			height=hermesHeight-(categoriesEl.getTop()-hermesEl.getTop());
		}

		categoriesEl.setStyle('height', height);
	},

	track: function() {
		return gHermes.track('add');
	},

	hideMainContainer: function() {
		this.addPageEl.setStyle('display', 'none');
		this.splashPageEl.setStyle('display', 'none');
	},

	showMainContainer: function() {
		this.clearAdded();
		if (this.buildSplashPage()) {
			this.addPageEl.setStyle('display', 'none');
			this.splashPageEl.setStyle('display', 'block');
			this.messageElSelector='.splashPage .message';
		} else {
			this.splashPageEl.setStyle('display', 'none');
			this.addPageEl.setStyle('display', 'block');
			this.messageElSelector='.addPage .message';
		}
		this.findMessageEl();
	},

	splashButton: function(data, id) {
		return ElementTree({
			'tag': 'div',
			'children': [{
				'tag': 'div',
				'class': 'splashContainer',
				'id': id,
				'children': [{
					'tag': 'form',
					'class': 'button',
					'action': '#',
					'children': [{
						'tag': 'a',
						'href': '#',
						'children': [{
							'tag': 'span',
							'class': 'left',
							'innerHTML': data.addToLabel
						}, {
							'tag': 'span',
							'class': 'right'
						}]
					}, {
						'tag': 'img',
						'src': data.imageUrl
					}, {
						'tag': 'input',
						'type': 'hidden',
						'name': 'id',
						'value': data.id
					}, {
						'tag': 'input',
						'type': 'hidden',
						'name': 'caption',
						'value': data.caption
					}, {
						'tag': 'input',
						'type': 'hidden',
						'name': 'minIeVersion',
						'value': data.minIeVersion
					}, {
						'tag': 'input',
						'type': 'hidden',
						'name': 'minFfVersion',
						'value': data.minFfVersion
					}, {
						'tag': 'input',
						'type': 'hidden',
						'name': 'minDtVersion',
						'value': data.minDtVersion
					}]
				}]
			}]
		});
	},

	buildSplashPage: function() {
		if (null==this.splashAds || this.categoryId) return false;

		// Find ads of buttons that were not already added
		var myButtons=[];
		var splashAds=[];
		var buttons=gHermes.configurator.getButtons();
		for (var i=0; i<this.splashAds.length; i++) {
			var found=false;
			if (buttons && buttons.length) {
				for (var j=0; j<buttons.length; j++) {
					if (this.splashAds[i]['id'] == buttons[j].id) {
						found=true;
						break;
					}
				}
			}
			if (!found) splashAds.push(this.splashAds[i]);
		}

		// Find 2 random image ads
		var imageAds=splashAds.filter(function(item, index){
		    return !splashAds[index]['swfData'];
		});
		if (imageAds.length<2) return false;
		var rand1=Math.floor(Math.random()*imageAds.length);
		var rand2=rand1;
		while (rand2==rand1) {
			rand2=Math.floor(Math.random()*imageAds.length);
		}

		// Build and set the html for the 2 images
		var splash1=this.splashButton(imageAds[rand1], 'splash1');
		var splash2=this.splashButton(imageAds[rand2], 'splash2');

		var first=gHermes.$E('.splashPage .first div');
		var second=gHermes.$E('.splashPage .second div');
		if (first && second) {
			first.replaceWith(splash1);
			second.replaceWith(splash2);
		} else {
			return false;
		}

		// Try to pick 2 swfs and enable with swfobject
		// http://code.google.com/p/swfobject/
		rand1=Math.floor(Math.random()*splashAds.length);
		rand2=rand1;
		while (rand2==rand1) {
			rand2=Math.floor(Math.random()*splashAds.length);
		}
		if (splashAds[rand1]['swfData']) {
			sd=splashAds[rand1]['swfData'];
			swfobject.embedSWF(sd.swf, 'splash1', sd.w, sd.h, sd.ver);
		}
		if (splashAds[rand2]['swfData']) {
			sd=splashAds[rand2]['swfData'];
			swfobject.embedSWF(sd.swf, 'splash2', sd.w, sd.h, sd.ver);
		}

		this.splashButtons=[];
		this.splashPageEl.getElements('.buttonList .button').each(function(buttonEl) {
			this.splashButtons.push( new Button(buttonEl) );
		}.bind(this));

		return true;
	}
});


var TabRemove=Tab.extend({
	buttons: null,
	container: null,
	sortables: null,

	initialize: function() {
		this.container=gHermes.$E('div.tabRemove .buttons');
		if (!this.container) return false;

		this.parent('div.tabRemove .message');

		this.display();

		gHermes.configurator.addEvent('buttonAdd', this.display.bind(this));
		gHermes.configurator.addEvent('buttonMove', this.display.bind(this));
		gHermes.configurator.addEvent('buttonRemove', this.display.bindAsEventListener(this));
	},

	attachEvents: function() {
		this.sortables=new SortablesButton(this.container.getElement('ol'), {
			onComplete: this.moveButton.bind(this)
		});

		// Sortables catches the mousedown event, so we cannot add a click event
		// to an element inside of a Sortables handle. Instead we need to cancel
		// the mousedown event and act upon the mouseup event.
		this.container.getElements('button').each(function(buttonEl, index) {
			buttonEl.addEvent('mousedown', function(e) {
				new Event(e).stop();
			});

			buttonEl.addEvent('mouseup', this.removeButton.bindAsEventListener(
				this, buttonEl
			));
		}.bind(this));
	},

	buttonsTree: function() {
		var buttonEls=[];

		if (!this.buttons) return buttonEls;

		for (var i=0, numButton=this.buttons.length; i<numButton; i++) {
			buttonEls.push({
				'tag': 'li',
				'class': 'removeButton',
				'children': [{
					'tag': 'div',
					'class': 'pill',
					'title': this.buttons[i].hint,
					'children': [{
						'tag': 'img',
						'class': 'icon',
						'src': this.buttons[i].image
					}, {
						'tag': 'div',
						'class': 'title',
						'children': this.buttons[i].caption
					}]
				}, {
					'tag': 'button',
					'name': 'remove',
					'innerHTML': "Remove"
				}, {
					'tag': 'input',
					'type': 'hidden',
					'name': 'guid',
					'value': this.buttons[i].id+'-'+$random(1, 9999999999999)
				}, {
					'tag': 'input',
					'type': 'hidden',
					'name': 'id',
					'value': this.buttons[i].id
				}, {
					'tag': 'input',
					'type': 'hidden',
					'name': 'position',
					'value': this.buttons[i].position
				}, {
					'tag': 'div',
					'class': 'clear'
				}]
			});
		}

		return buttonEls;
	},

	confirm: function(name) {
		this.addMessage(
			"Removed &ldquo;%BUTTON_NAME%&rdquo; button.".replace('%BUTTON_NAME%', name), true, true
		);
	},

	display: function(e) {
		if (!this.container) return false;

		this.container.empty();

		this.buttons=gHermes.configurator.getButtons();

		if (this.buttons && this.buttons.length) {
			this.container.adopt(ElementTree({
				'tag': 'ol',
				'children': this.buttonsTree()
			}));
		} else {
			this.container.adopt(ElementTree({
				'tag': 'p',
				'class': 'noButtons',
				'children': "There are no Buttons on your Toolbar!"
			}));
		}

		this.attachEvents();
	},

	moveButton: function(buttonEl) {
		var positionEl=buttonEl.getElement('input[name=position]');
		var prevPosition=positionEl.getValue().toInt();
		var newPosition=this.positionFromButtonEl(buttonEl);

		if (prevPosition==newPosition) return true;

		if (!gHermes.configurator.moveButton(prevPosition, newPosition)) return false;

		return true;
	},

	positionFromButtonEl: function(buttonEl) {
		var buttonEls=this.container.getElements('li');
		if (0==buttonEls.length) return false;

		var guid=buttonEl.getElement('input[name=guid]').getValue();

		for (var i=0, numButton=buttonEls.length; i<numButton; i++) {
			if (guid==buttonEls[i].getElement('input[name=guid]').getValue()) {
				// JS arrays are base-zero, but positions are stored as base-one.
				return i+1;
			}
		}

		return false;
	},

	removeButton: function(e, buttonEl) {
		var listItemEl=buttonEl.getParent();

		var id=listItemEl.getElement('input[name=id]').getValue().toInt();
		var position=listItemEl.getElement('input[name=position]').getValue().toInt();

		// Get and store the name now, because this element will be replaced when
		// the buttonRemoved event is fired.
		var name=listItemEl.getElement('div.title').getText().trim();
		var caption=listItemEl.getElement('.title').getText().trim();

		if (!gHermes.configurator.removeButton(id, position)) return false;

		this.confirm(name);

		var linkName=id+'_'+caption+' : '+gHermes.product;

		if ('undefined'!=typeof pageTracker) {
			pageTracker._trackEvent('Button', 'Remove', id+'_'+caption);
		}

		return true;
	},

	track: function() {
		gHermes.track('remove');
	}
});


var TabSave=Tab.extend({
	container: null,

	loggedIn: null,

	configs: null,
	loadedConfigName: null,

	signInUrl: null,
	getConfigsUrl: null,
	saveConfigUrl: null,

	// We only want to track the viewing of this tab once, unless the user
	// navigates to another tab and then navigates back.
	trackedLoggedOut: null,
	trackedLoggedIn: null,

	initialize: function() {
		this.container=gHermes.$E('div.tabSave .saveContainer');
		if (!this.container) return false;

		this.parent('.tabSave .message');

		var apiBase='http://custom.alot.com/api/';
		this.signInUrl=apiBase+'accountProxy';
		this.getConfigsUrl=apiBase+'getConfigs';
		this.saveConfigUrl=apiBase+'saveConfig';

		this.loadedConfigName='';
		this.getConfigs();
	},

	// Find out if the current config is the same as any of the saved configs.
	checkLoadedConfig: function() {
		if (0==this.configs.length) return false;

		var current=gHermes.configurator.getButtons();
		var sameConfig=true;

		for (var i=0, numConfig=this.configs.length; i<numConfig; ++i) {
			if (current.length!=this.configs[i].buttonIds.length) continue;

			sameConfig=true;
			for (var j=0, numButton=current.length; j<numButton && sameConfig; ++j) {
				if (current[j].id!=this.configs[i].buttonIds[j]) sameConfig=false;
			}
			if (!sameConfig) continue;

			this.loadedConfigName=this.configs[i].name;
			return true;
		}

		return false;
	},

	configId: function(name) {
		name=name.toLowerCase();
		for (var i=0, numConfig=this.configs.length; i<numConfig; ++i) {
			if (name==this.configs[i].name.toLowerCase()) return i;
		}
		return false;
	},

	confirm: function(name, callback, message) {
		var formEl=ElementTree({
			'tag': 'form',
			'class': 'confirm',
			'action': '#',
			'children': [{
				'tag': 'fieldset',
				'children': [{
					'tag': 'legend',
					'children': message.replace(
						'%CONFIG_NAME%', name
					)
				}, {
					'tag': 'input',
					'type': 'button',
					'value': "Yes",
					'events': {'click': this.confirmClose.bind(this, callback)}
				}, {
					'tag': 'input',
					'type': 'button',
					'value': "No",
					'events': {'click': this.confirmClose.bind(this)}
				}]
			}]
		});

		var currentEl=gHermes.$E('.tabSave form.confirm');

		if (currentEl) {
			currentEl.replaceWith(formEl);
			return true;
		}

		return this.addMessage(formEl, true);
	},

	confirmClose: function(callback) {
		var formEl=gHermes.$E('form.confirm');
		if (!formEl) return true;

		this.fadeOutMessage(formEl);

		if (callback && 'function'==$type(callback)) callback();

		return true;
	},

	display: function(signIn) {
		if (!this.container) return false;

		this.fadeOutMessage();

		this.empty();

		if (signIn) {
			this.container.adopt(ElementTree({
				'tag': 'h3',
				'innerHTML': "You need to register or sign in to save your Toolbar"
			}));
		}

		this.container.adopt(ElementTree({
			'tag': 'table',
			'class': 'saveContainer',
			'children': {
				'tag': 'tbody',
				'children': {
					'tag': 'tr',
					'children': [{
						'tag': 'td',
						'children': (signIn ? this.register() : this.saveForm())
					}, {
						'tag': 'td',
						'children': (signIn ? this.signInForm() : this.listConfigs())
					}]
				}
			}
		}));

		this.track();

		return true;
	},

	// Mootools's Element.empty does not work very well across the board.
	empty: function() {
		this.container.getChildren().each(function(el) {
			el.remove();
		});
	},

	getConfigs: function() {
		if (!this.container) return false;

		if (false===this.loggedIn) return this.display(true);

		gHermes.getText(this.getConfigsUrl, this.getConfigsCb.bind(this), null, true);
	},

	getConfigsCb: function(response) {
		if (!response) return false;

		response=Json.evaluate(response, true);
		if (!response || 'object'!=$type(response)) return false;

		if (response.error) {
			this.addMessage(response.error);
		} else {
			this.fadeOutMessage();
		}

		if (!response.loggedIn) {
			this.loggedIn=false;
			return this.display(true);
		}
		this.loggedIn=true;
		gHermes.navigation.signOutShow();

		this.configs=response.configs;
		this.checkLoadedConfig();
		this.display();
	},

	listConfigs: function() {
		var content={
			'tag': 'div',
			'class': 'container list',
			'children': [{
				'tag': 'h4',
				'innerHTML': "Saved Toolbars:"
			}]
		};
		
		if (0==this.configs.length) {
			content.children.push({
				'tag': 'p',
				'innerHTML': "No Saved Toolbars Yet"
			});
		} else {
			content.children.push({
				'tag': 'em',
				'innerHTML': "Click a Toolbar name to restore it.<br>Click &ldquo;Remove&rdquo; to delete."
			});
			content.children.push({
				'tag': 'ol',
				'class': 'savedConfigs',
				'children': this.savedConfigTree()
			});
		}

		return content;
	},

	loadConfig: function(e, name) {
		new Event(e).stop();

		var id=this.configId(name);
		if (false===id) return false;

		// Since we're about to remove all of the buttons and add all news ones,
		// anything in the Queue will be overwritten anyhow.
		gHermes.configurator.clearAddRemoveQueue();

		if (gHermes.configurator.checkSetToolbar()) {
			// If the configurator supports a function to remove all of the
			// buttons and load a new configuration all at once, use it.
			gHermes.configurator.loadConfig(this.configs[id].buttonIds, name);
		} else {
			if (!gHermes.configurator.removeButtons()) return false;

			var reversedIds=[];
			for (var i=this.configs[id].buttonIds.length-1; i>=0; --i) {
				reversedIds.push(this.configs[id].buttonIds[i]);
			}

			// Add all of the buttons from the config last-first since we add each
			// button to the beginning of the toolbar.
			if (!gHermes.configurator.addButtons(reversedIds)) {
				return false;
			}
		}

		this.fadeOutMessage();

		this.loadedConfigName=name;
		this.populateSaveForm();
	},

	populateSaveForm: function() {
		this.container.getElement('input[name=name]').setProperty(
			'value', this.loadedConfigName
		);
	},

	register: function() {
		var hermesQs='product=hermes&rd=http%3A%2F%2Fcustom.alot.com%2F&name=';
		hermesQs+=encodeURIComponent("Customize ALOT");
		return {
			'tag': 'div',
			'class': 'container register',
			'children': {
				'tag': 'a',
				'href': 'https://account.alot.com/create?'+hermesQs,
				'target': '_blank',
				'innerHTML': "Click here to register at ALOT"
			}
		};
	},

	resetTracking: function() {
		this.trackedLoggedIn=false;
		this.trackedLoggedOut=false;
	},

	saveConfig: function(e, name, remove) {
		new Event(e).stop();

		if (!name) {
			name=this.container.getElement('input[name=name]').getValue().trim();
			if (!name) return false;
		}

		var data={'name': name};

		if (!remove) {
			var current=gHermes.configurator.getButtons();
			data.buttonIds=[];

			for (var i=0, numButton=current.length; i<numButton; ++i) {
				data.buttonIds.push(current[i].id);
			}
		} else {
			data['delete']=true;
		}

		var callback=gHermes.getText.bind(gHermes, [
			this.saveConfigUrl, this.saveConfigCb.bind(this), data, true
		]);

		if (!remove) {
			// If a toolbar with this name already exists, confirm that the user
			// wants to overwrite it.
			if (this.container.getElements('ol.savedConfigs li a').some(function(item) {
				return item.getText().trim().toLowerCase()==name.toLowerCase();
			})) return this.confirm(name, callback, "Toolbar name \"%CONFIG_NAME%\" already exists. Do you want to overwrite it?");
		} else {
			return this.confirm(name, callback, "Are you sure you want to delete your Toolbar named \"%CONFIG_NAME%\"?");
		}

		callback();

		return true;
	},

	saveConfigCb: function(response) {
		if (!response) {
			this.addMessage("An error occurred while attempting to save your Toolbar. Please Try again.");
			return false;
		}

		response=Json.evaluate(response, true);
		if ('object'!=$type(response)) {
			this.addMessage("An error occurred while attempting to save your Toolbar. Please Try again.");
			return false;
		}

		if (response.error) {
			this.addMessage(response.error);
			return false;
		} else {
			this.fadeOutMessage();
		}

		this.configs=response.configs;
		this.checkLoadedConfig();
		this.display();

		return true;
	},

	saveForm: function() {
		return {
			'tag': 'form',
			'class': 'saveConfig',
			'action': '#',
			'events': {
				'submit': this.saveConfig.bindAsEventListener(this)
			},
			'children': [{
				'tag': 'div',
				'class': 'container',
				'children': [{
					'tag': 'ol',
					'class': 'steps',
					'children': [{
						'tag': 'li',
						'innerHTML': "Step 1 - Enter a name for your configuration"
					}, {
						'tag': 'li',
						'innerHTML': "Step 2 - Click &ldquo;Save&rdquo; to save it!"
					}]
				}, {
					'tag': 'input',
					'class': 'text',
					'type': 'text',
					'name': 'name',
					'maxlength': '60',
					'value': this.loadedConfigName
				}, {
					'tag': 'input',
					'type': 'submit',
					'events': {
						'click': this.saveConfig.bindAsEventListener(this)
					},
					'class': 'submit',
					'value': "Save"
				}]
			}]
		};
	},

	savedConfigTree: function() {
		var configEls=[];
		for (var i=0, numConfig=this.configs.length; i<numConfig; ++i) {
			configEls.push({
				'tag': 'li',
				'children': [{
					'tag': 'a',
					'href': '#',
					'events': {
						'click': this.loadConfig.bindAsEventListener(this, this.configs[i].name)
					},
					'children': this.configs[i].name
				}, {
					'tag': 'button',
					'events': {
						'click': this.saveConfig.bindAsEventListener(this, [
							this.configs[i].name, true
						])
					},
					'innerHTML': "Remove"
				}]
			});
		}
		return configEls;
	},

	signIn: function(e) {
		if (e) new Event(e).stop();

		var username=this.container.getElement('input[name=username]').getValue().trim();
		var password=this.container.getElement('input[name=password]').getValue().trim();

		if (!username || !password) return false;

		gHermes.getText(
			this.signInUrl,
			this.signInCb.bind(this),
			{'username': username, 'password': password, 'remember': 'true'},
			true
		);

		return true;
	},

	signInCb: function(response) {
		this.loggedIn=false;

		if (!response) {
			this.addMessage("An error occurred while attempting to sign in to ALOT. Please Try again.");
			return false;
		}

		response=Json.evaluate(response, true);
		if (!response || 'object'!=$type(response)) {
			this.addMessage("An error occurred while attempting to sign in to ALOT. Please Try again.");
			return false;
		}

		if (response.error) {
			this.addMessage(response.error);
			return false;
		}

		this.loggedIn=true;
		gHermes.navigation.signOutShow();

		return this.getConfigs();
	},

	signInForm: function() {
		return {
			'tag': 'form',
			'class': 'signIn',
			'action': '#',
			'method': 'POST',
			'events': {
				'submit': this.signIn.bindAsEventListener(this)
			},
			'children': {
				'tag': 'div',
				'class': 'container',
				'children': [{
					'tag': 'fieldset',
					'children': [{
						'tag': 'label',
						'children': [{
							'tag': 'h4',
							'children': "Username"
						}, {
							'tag': 'input',
							'class': 'text',
							'type': 'text',
							'name': 'username'
						}]
					}, {
						'tag': 'label',
						'children': [{
							'tag': 'h4',
							'children': "Password"
						}, {
							'tag': 'input',
							'class': 'text',
							'type': 'password',
							'name': 'password'
						}]
					}, {
						'tag': 'input',
						'class': 'submit',
						'type': 'submit',
						'value': "Sign in"
					}]
				}, {
					'tag': 'div',
					'class': 'clear'
				}]
			}
		}
	},

	signOut: function() {
		this.loggedIn=false;
		this.display(true);
	},

	track: function() {
		if (this.loggedIn && this.trackedLoggedIn) return true;
		else if (!this.loggedIn && this.trackedLoggedOut) return true;

		gHermes.track('save');
	}
});


var Button=new Class({
	containerEl: null,

	addTab: null,

	id: null,
	caption: null,

	minIeVersion: null,
	minFfVersion: null,
	minDtVersion: null,

	initialize: function(containerEl) {
		this.containerEl=containerEl;

		var idEl=this.containerEl.getElement('input[name=id]');
		if (!idEl) return false;
		this.id=idEl.getValue().trim().toInt();

		var captionEl=this.containerEl.getElement('.title');
		if (captionEl) {
			this.caption=captionEl.getText().trim();
		} else {
			captionEl=this.containerEl.getElement('input[name=caption]');
			if (captionEl) this.caption=captionEl.getValue();
		}

		var minIeVersionEl=this.containerEl.getElement('input[name=minIeVersion]');
		if (minIeVersionEl) this.minIeVersion=minIeVersionEl.getValue();

		var minFfVersionEl=this.containerEl.getElement('input[name=minFfVersion]');
		if (minFfVersionEl) this.minFfVersion=minFfVersionEl.getValue();

		var minDtVersionEl=this.containerEl.getElement('input[name=minDtVersion]');
		if (minDtVersionEl) this.minDtVersion=minDtVersionEl.getValue();

		this.attachEvents();

		return true;
	},

	add: function() {
		this.containerEl.removeClass('active');

		if (!this.addTab) {
			this.addTab=gHermes.navigation.tabs.add;
			if (!this.addTab) return false;
		}

		this.addTab.removeMessage();

		if ('home'!=gHermes.product) {
			var minVersion='ff'==gHermes.browser ? this.minFfVersion : this.minIeVersion;

			if ('all'!=minVersion) {
				if ('none'==minVersion) {
					this.addTab.addMessage("This button is not currently available.");
					return false;
				}

				if (minVersion>gHermes.version) {
					this.addTab.addMessage("This button is not compatible with your existing version. Click <a href=\"http:\/\/www.alot.com\/toolbar\/89-select-alot\" target=\"_blank\">here<\/a> to upgrade to the latest version.");
					return false;
				}
			}
		}

		if (!gHermes.configurator.addButton(this.id)) return false;

		var linkName=this.id+'_'+this.caption+' : '+gHermes.product;

		if ('home'!=gHermes.product && ('undefined'!=typeof pageTracker)) {
			pageTracker._trackEvent('Button', 'Add', this.id+'_'+this.caption);
		}

		return this.showAdded();
	},

	attachEvents: function() {
		this.containerEl.addEvents({
			'mousedown': this.containerEl.addClass.bind(this.containerEl, 'active'),
			'mouseup': this.add.bind(this)
		});

	},

	hideAdded: function() {
		var container=this.containerEl;

		container.removeClass('added');

		var removeEl=container.getElement('.buttonAddedBg');
		if (!removeEl) return true;
		removeEl.remove();

		var removeEl=container.getElement('.buttonAdded');
		if (!removeEl) return true;
		removeEl.remove();

		this.attachEvents();
	},

	showAdded: function() {
		var buttonAddedBg=new Element('div', {'class': 'buttonAddedBg'});
		var buttonAdded=new Element('div', {'class': 'buttonAdded'});
		buttonAdded.innerHTML="Added";

		this.containerEl.adopt(buttonAddedBg);
		this.containerEl.adopt(buttonAdded);

		this.containerEl.removeEvents();
		this.containerEl.addClass('added');

		if ('toolbar'==gHermes.product) {
			this.addTab.addMessage(
				"<div class='saveTbConfig'>Save your toolbar configuration by clicking<div class=\"icon\"><\/div><b>Save changes<\/b> at the top.</div>", true,  true
			);
		}

		return true;
	}
});


// Override mootool's Sortables class to use a different placeholder while
// dragging. Also, do not inject the "ghost" into the document body; instead,
// inject it into the parent of the list (injecting the element directly into
// the document body would mean that we would need CSS that goes beyond the
// scope of the widget). Additionally, since our list is relatively positioned
// (to fix an IE overflow bug), we need to include the scroll offset of the
// list in various calculations.
var SortablesButton=Sortables.extend({
	initialize: function(list, options) {
		if ('object'!=$type(options)) options={};

		options.onDragStart=function(element, ghost) {
			ghost.setStyle('opacity', 0.8);

			this.options.phantom=ElementTree({
				'tag': 'li',
				'class': 'phantom',
				'children': {
					'tag': 'div',
					'class': 'name'
				}
			});

			this.options.phantom.injectBefore(element);

			element.addClass('moveButton');
		};

		options.onDragComplete=function(element, ghost) {
			element.removeClass('moveButton');

			ghost.remove();
			ghost=null;
			this.trash.remove();
			this.trash=null;

			this.options.phantom.remove();
			this.options.phantom=null;
		};

		this.parent(list, options);
	},

	// Include the scroll offset of the list in the current y coordinate.
	move: function(event){
		var now = event.page.y+this.list.getSize().scroll.y;
		this.previous = this.previous || now;
		var up = ((this.previous - now) > 0);
		var prev = this.active.getPrevious();
		var next = this.active.getNext();
		if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev);
		if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next);
		this.previous = now;
	},

	// Position the ghost relative to the top of the list rather than the page.
	moveGhost: function(event){
		var halfGhostHeight=this.ghost.getSize().size.y/2;
		var scrollTop=this.list.getSize().scroll.y;
		var ghostTop;

		if ((event.page.y-halfGhostHeight)<this.coordinates.top && scrollTop!=0) {
			this.list.scrollTo(0, scrollTop-halfGhostHeight);
			ghostTop=this.list.getTop();
		} else if ((event.page.y+halfGhostHeight)>this.coordinates.bottom) {
			this.list.scrollTo(0, scrollTop+halfGhostHeight);
			ghostTop=this.coordinates.bottom;
		} else {
			ghostTop=event.page.y - halfGhostHeight;
		}

		ghostTop=ghostTop.limit(
			this.coordinates.top,
			this.coordinates.bottom-this.ghost.offsetHeight
		);
		this.ghost.setStyle('top', ghostTop);
		event.stop();
	},

	start: function(event, el){
		this.active = el;
		this.coordinates = this.list.getCoordinates();
		if (this.options.ghost){
			var position = el.getPosition();
			this.offset = event.page.y - position.y;
			// Insert the ghost into the parent, rather than the document body.
			this.trash = new Element('div').inject(this.list.getParent());
			this.ghost = el.clone().inject(this.trash).setStyles({
				'position': 'absolute',
				'left': position.x,
				// Use the top of the button list as the offset since it is
				// positioned relatively.
				'top': event.page.y - this.offset - this.list.getSize().scroll.y
			});
			document.addListener('mousemove', this.bound.moveGhost);
			this.fireEvent('onDragStart', [el, this.ghost]);
		}
		document.addListener('mousemove', this.bound.move);
		document.addListener('mouseup', this.bound.end);
		this.fireEvent('onStart', el);
		event.stop();
	}
});


var gHermes;

if ('undefined'!=typeof AlotWidget) {
	gHermes=new HermesWidget();
} else {
	gHermes=new HermesSite();
}

gHermes.onLoad(function() {
	gHermes.configurator=gHermes.loadConfigurator();
	gHermes.loadNavigation();
});


/*	SWFObject v2.2 <http://code.google.com/p/swfobject/>
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();

