/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.3.0
*/
(function () {
	YAHOO.util.Config = function (owner) {
		if (owner) {
			this.init(owner);
		}
		if (!owner) {
		}
	};

	var Lang = YAHOO.lang,
		CustomEvent = YAHOO.util.CustomEvent,
		Config = YAHOO.util.Config;
	Config.CONFIG_CHANGED_EVENT = "configChanged";
	Config.BOOLEAN_TYPE = "boolean";
	Config.prototype = {
		owner: null,
		queueInProgress: false,
		config: null,
		initialConfig: null,
		eventQueue: null,
		configChangedEvent: null,
		init: function (owner) {
			this.owner = owner;
			this.configChangedEvent = this.createEvent(Config.CONFIG_CHANGED_EVENT);
			this.configChangedEvent.signature = CustomEvent.LIST;
			this.queueInProgress = false;
			this.config = {};
			this.initialConfig = {};
			this.eventQueue = [];
		},

		checkBoolean: function (val) {
			return (typeof val == Config.BOOLEAN_TYPE);
		},

		checkNumber: function (val) {
			return (!isNaN(val));
		},

		fireEvent: function ( key, value ) {
			var property = this.config[key];

			if (property && property.event) {
				property.event.fire(value);
			}
		},

		addProperty: function ( key, propertyObject ) {
			key = key.toLowerCase();

			this.config[key] = propertyObject;

			propertyObject.event = this.createEvent(key, { scope: this.owner });
			propertyObject.event.signature = CustomEvent.LIST;

			propertyObject.key = key;

			if (propertyObject.handler) {
				propertyObject.event.subscribe(propertyObject.handler,
					this.owner);
			}

			this.setProperty(key, propertyObject.value, true);

			if (! propertyObject.suppressEvent) {
				this.queueProperty(key, propertyObject.value);
			}
		},

		getConfig: function () {
			var cfg = {},
				prop,
				property;

			for (prop in this.config) {
				property = this.config[prop];
				if (property && property.event) {
					cfg[prop] = property.value;
				}
			}
			return cfg;
		},

		getProperty: function (key) {
			var property = this.config[key.toLowerCase()];
			if (property && property.event) {
				return property.value;
			} else {
				return undefined;
			}
		},

		resetProperty: function (key) {
			key = key.toLowerCase();

			var property = this.config[key];

			if (property && property.event) {
				if (this.initialConfig[key] &&
					!Lang.isUndefined(this.initialConfig[key])) {
					this.setProperty(key, this.initialConfig[key]);

					return true;
				}
			} else {
				return false;
			}
		},

		setProperty: function (key, value, silent) {
			var property;

			key = key.toLowerCase();

			if (this.queueInProgress && ! silent) {
				this.queueProperty(key,value);
				return true;
			} else {
				property = this.config[key];
				if (property && property.event) {
					if (property.validator && !property.validator(value)) {
						return false;
					} else {
						property.value = value;
						if (! silent) {
							this.fireEvent(key, value);
							this.configChangedEvent.fire([key, value]);
						}
						return true;
					}
				} else {
					return false;
				}
			}
		},

		queueProperty: function (key, value) {
			key = key.toLowerCase();

			var property = this.config[key],
				foundDuplicate = false,
				iLen,
				queueItem,
				queueItemKey,
				queueItemValue,
				sLen,
				supercedesCheck,
				qLen,
				queueItemCheck,
				queueItemCheckKey,
				queueItemCheckValue,
				i,
				s,
				q;

			if (property && property.event) {
				if (!Lang.isUndefined(value) && property.validator &&
					!property.validator(value)) {
					return false;
				} else {
					if (!Lang.isUndefined(value)) {
						property.value = value;
					} else {
						value = property.value;
					}

					foundDuplicate = false;
					iLen = this.eventQueue.length;

					for (i = 0; i < iLen; i++) {
						queueItem = this.eventQueue[i];

						if (queueItem) {
							queueItemKey = queueItem[0];
							queueItemValue = queueItem[1];

							if (queueItemKey == key) {
								this.eventQueue[i] = null;

								this.eventQueue.push(
									[key, (!Lang.isUndefined(value) ?
									value : queueItemValue)]);

								foundDuplicate = true;
								break;
							}
						}
					}

					if (! foundDuplicate && !Lang.isUndefined(value)) {
						this.eventQueue.push([key, value]);
					}
				}

				if (property.supercedes) {
					sLen = property.supercedes.length;

					for (s = 0; s < sLen; s++) {
						supercedesCheck = property.supercedes[s];
						qLen = this.eventQueue.length;

						for (q = 0; q < qLen; q++) {
							queueItemCheck = this.eventQueue[q];

							if (queueItemCheck) {
								queueItemCheckKey = queueItemCheck[0];
								queueItemCheckValue = queueItemCheck[1];

								if (queueItemCheckKey ==
									supercedesCheck.toLowerCase() ) {
									this.eventQueue.push([queueItemCheckKey,
										queueItemCheckValue]);

									this.eventQueue[q] = null;
									break;
								}
							}
						}
					}
				}

				return true;
			} else {
				return false;
			}
		},

		refireEvent: function (key) {
			key = key.toLowerCase();

			var property = this.config[key];

			if (property && property.event &&

				!Lang.isUndefined(property.value)) {
				if (this.queueInProgress) {
					this.queueProperty(key);
				} else {
					this.fireEvent(key, property.value);
				}
			}
		},

		applyConfig: function (userConfig, init) {
			var sKey,
				oValue,
				oConfig;

			if (init) {
				oConfig = {};

				for (sKey in userConfig) {
					if (Lang.hasOwnProperty(userConfig, sKey)) {
						oConfig[sKey.toLowerCase()] = userConfig[sKey];
					}
				}

				this.initialConfig = oConfig;
			}

			for (sKey in userConfig) {
				if (Lang.hasOwnProperty(userConfig, sKey)) {
					this.queueProperty(sKey, userConfig[sKey]);
				}
			}
		},

		refresh: function () {
			var prop;

			for (prop in this.config) {
				this.refireEvent(prop);
			}
		},

		fireQueue: function () {
			var i,
				queueItem,
				key,
				value,
				property;

			this.queueInProgress = true;
			for (i = 0;i < this.eventQueue.length; i++) {
				queueItem = this.eventQueue[i];
				if (queueItem) {
					key = queueItem[0];
					value = queueItem[1];
					property = this.config[key];

					property.value = value;

					this.fireEvent(key,value);
				}
			}

			this.queueInProgress = false;
			this.eventQueue = [];
		},

		subscribeToConfigEvent: function (key, handler, obj, override) {
			var property = this.config[key.toLowerCase()];

			if (property && property.event) {
				if (!Config.alreadySubscribed(property.event, handler, obj)) {
					property.event.subscribe(handler, obj, override);
				}

				return true;
			} else {
				return false;
			}
		},

		unsubscribeFromConfigEvent: function (key, handler, obj) {
			var property = this.config[key.toLowerCase()];
			if (property && property.event) {
				return property.event.unsubscribe(handler, obj);
			} else {
				return false;
			}
		},

		toString: function () {
			var output = "Config";
			if (this.owner) {
				output += " [" + this.owner.toString() + "]";
			}
			return output;
		},

		outputEventQueue: function () {
			var output = "",
				queueItem,
				q,
				nQueue = this.eventQueue.length;

			for (q = 0; q < nQueue; q++) {
				queueItem = this.eventQueue[q];
				if (queueItem) {
					output += queueItem[0] + "=" + queueItem[1] + ", ";
				}
			}
			return output;
		},

		destroy: function () {
			var oConfig = this.config,
				sProperty,
				oProperty;

			for (sProperty in oConfig) {
				if (Lang.hasOwnProperty(oConfig, sProperty)) {
					oProperty = oConfig[sProperty];

					oProperty.event.unsubscribeAll();
					oProperty.event = null;
				}
			}

			this.configChangedEvent.unsubscribeAll();

			this.configChangedEvent = null;
			this.owner = null;
			this.config = null;
			this.initialConfig = null;
			this.eventQueue = null;
		}
	};

	Config.alreadySubscribed = function (evt, fn, obj) {
		var nSubscribers = evt.subscribers.length,
			subsc,
			i;

		if (nSubscribers > 0) {
			i = nSubscribers - 1;

			do {
				subsc = evt.subscribers[i];

				if (subsc && subsc.obj == obj && subsc.fn == fn) {
					return true;
				}
			}
			while (i--);
		}

		return false;
	};

	YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);

}());
(function () {
	YAHOO.widget.Module = function (el, userConfig) {
		if (el) {
			this.init(el, userConfig);
		} else {
		}
	};

	var Dom = YAHOO.util.Dom,
		Config = YAHOO.util.Config,
		Event = YAHOO.util.Event,
		CustomEvent = YAHOO.util.CustomEvent,
		Module = YAHOO.widget.Module,

		m_oModuleTemplate,
		m_oHeaderTemplate,
		m_oBodyTemplate,
		m_oFooterTemplate,

		EVENT_TYPES = {
			"BEFORE_INIT": "beforeInit",
			"INIT": "init",
			"APPEND": "append",
			"BEFORE_RENDER": "beforeRender",
			"RENDER": "render",
			"CHANGE_HEADER": "changeHeader",
			"CHANGE_BODY": "changeBody",
			"CHANGE_FOOTER": "changeFooter",
			"CHANGE_CONTENT": "changeContent",
			"DESTORY": "destroy",
			"BEFORE_SHOW": "beforeShow",
			"SHOW": "show",
			"BEFORE_HIDE": "beforeHide",
			"HIDE": "hide"
		},

		DEFAULT_CONFIG = {
			"VISIBLE": {
				key: "visible",
				value: true,
				validator: YAHOO.lang.isBoolean
			},

			"EFFECT": {
				key: "effect",
				suppressEvent: true,
				supercedes: ["visible"]
			},

			"MONITOR_RESIZE": {
				key: "monitorresize",
				value: true
			}
		};

	Module.IMG_ROOT = null;
	Module.IMG_ROOT_SSL = null;
	Module.CSS_MODULE = "yui-module";
	Module.CSS_HEADER = "hd";
	Module.CSS_BODY = "bd";
	Module.CSS_FOOTER = "ft";
	Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;";
	Module.textResizeEvent = new CustomEvent("textResize");

	function createModuleTemplate() {
		if (!m_oModuleTemplate) {
			m_oModuleTemplate = document.createElement("div");

			m_oModuleTemplate.innerHTML = ("<div class=\"" +
				Module.CSS_HEADER + "\"></div>" + "<div class=\"" +
				Module.CSS_BODY + "\"></div><div class=\"" +
				Module.CSS_FOOTER + "\"></div>");

			m_oHeaderTemplate = m_oModuleTemplate.firstChild;
			m_oBodyTemplate = m_oHeaderTemplate.nextSibling;
			m_oFooterTemplate = m_oBodyTemplate.nextSibling;
		}

		return m_oModuleTemplate;
	}

	function createHeader() {
		if (!m_oHeaderTemplate) {
			createModuleTemplate();
		}

		return (m_oHeaderTemplate.cloneNode(false));
	}

	function createBody() {
		if (!m_oBodyTemplate) {
			createModuleTemplate();
		}

		return (m_oBodyTemplate.cloneNode(false));
	}

	function createFooter() {
		if (!m_oFooterTemplate) {
			createModuleTemplate();
		}

		return (m_oFooterTemplate.cloneNode(false));
	}

	Module.prototype = {
		constructor: Module,
		element: null,
		header: null,
		body: null,
		footer: null,
		id: null,
		imageRoot: Module.IMG_ROOT,

		initEvents: function () {
			var SIGNATURE = CustomEvent.LIST;

			this.beforeInitEvent = this.createEvent(EVENT_TYPES.BEFORE_INIT);
			this.beforeInitEvent.signature = SIGNATURE;

			this.initEvent = this.createEvent(EVENT_TYPES.INIT);
			this.initEvent.signature = SIGNATURE;

			this.appendEvent = this.createEvent(EVENT_TYPES.APPEND);
			this.appendEvent.signature = SIGNATURE;

			this.beforeRenderEvent = this.createEvent(EVENT_TYPES.BEFORE_RENDER);
			this.beforeRenderEvent.signature = SIGNATURE;

			this.renderEvent = this.createEvent(EVENT_TYPES.RENDER);
			this.renderEvent.signature = SIGNATURE;

			this.changeHeaderEvent = this.createEvent(EVENT_TYPES.CHANGE_HEADER);
			this.changeHeaderEvent.signature = SIGNATURE;

			this.changeBodyEvent = this.createEvent(EVENT_TYPES.CHANGE_BODY);
			this.changeBodyEvent.signature = SIGNATURE;

			this.changeFooterEvent = this.createEvent(EVENT_TYPES.CHANGE_FOOTER);
			this.changeFooterEvent.signature = SIGNATURE;

			this.changeContentEvent =
				this.createEvent(EVENT_TYPES.CHANGE_CONTENT);
			this.changeContentEvent.signature = SIGNATURE;

			this.destroyEvent = this.createEvent(EVENT_TYPES.DESTORY);
			this.destroyEvent.signature = SIGNATURE;

			this.beforeShowEvent = this.createEvent(EVENT_TYPES.BEFORE_SHOW);
			this.beforeShowEvent.signature = SIGNATURE;

			this.showEvent = this.createEvent(EVENT_TYPES.SHOW);
			this.showEvent.signature = SIGNATURE;

			this.beforeHideEvent = this.createEvent(EVENT_TYPES.BEFORE_HIDE);
			this.beforeHideEvent.signature = SIGNATURE;

			this.hideEvent = this.createEvent(EVENT_TYPES.HIDE);
			this.hideEvent.signature = SIGNATURE;
		},

		platform: function () {
			var ua = navigator.userAgent.toLowerCase();

			if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) {
				return "windows";
			} else if (ua.indexOf("macintosh") != -1) {
				return "mac";
			} else {
				return false;
			}
		}(),

		browser: function () {
			var ua = navigator.userAgent.toLowerCase();

			if (ua.indexOf('opera') != -1) {
				return 'opera';
			} else if (ua.indexOf('msie 7') != -1) {
				return 'ie7';
			} else if (ua.indexOf('msie') != -1) {
				return 'ie';
			} else if (ua.indexOf('safari') != -1) {
				return 'safari';
			} else if (ua.indexOf('gecko') != -1) {
				return 'gecko';
			} else {
				return false;
			}
		}(),

		isSecure: function () {
			if (window.location.href.toLowerCase().indexOf("https") === 0) {
				return true;
			} else {
				return false;
			}
		}(),

		initDefaultConfig: function () {
			this.cfg.addProperty(DEFAULT_CONFIG.VISIBLE.key, {
				handler: this.configVisible,
				value: DEFAULT_CONFIG.VISIBLE.value,
				validator: DEFAULT_CONFIG.VISIBLE.validator
			});

			this.cfg.addProperty(DEFAULT_CONFIG.EFFECT.key, {
				suppressEvent: DEFAULT_CONFIG.EFFECT.suppressEvent,
				supercedes: DEFAULT_CONFIG.EFFECT.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.MONITOR_RESIZE.key, {
				handler: this.configMonitorResize,
				value: DEFAULT_CONFIG.MONITOR_RESIZE.value
			});
		},

		init: function (el, userConfig) {
			var elId, i, child;

			this.initEvents();
			this.beforeInitEvent.fire(Module);
			this.cfg = new Config(this);

			if (this.isSecure) {
				this.imageRoot = Module.IMG_ROOT_SSL;
			}

			if (typeof el == "string") {
				elId = el;

				el = document.getElementById(el);

				if (! el) {
					el = (createModuleTemplate()).cloneNode(false);

					el.id = elId;
				}
			}

			this.element = el;

			if (el.id) {
				this.id = el.id;
			}

			child = this.element.firstChild;

			if (child) {
				do {
					switch (child.className) {
					case Module.CSS_HEADER:
						this.header = child;
						break;

					case Module.CSS_BODY:
						this.body = child;
						break;

					case Module.CSS_FOOTER:
						this.footer = child;
						break;
					}
				} while ((child = child.nextSibling));
			}

			this.initDefaultConfig();

			Dom.addClass(this.element, Module.CSS_MODULE);

			if (userConfig) {
				this.cfg.applyConfig(userConfig, true);
			}

			if (!Config.alreadySubscribed(this.renderEvent,
				this.cfg.fireQueue, this.cfg)) {
				this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
			}

			this.initEvent.fire(Module);
		},

		initResizeMonitor: function () {
			var oDoc,
				oIFrame,
				sHTML;

			function fireTextResize() {
				Module.textResizeEvent.fire();
			}

			if (!YAHOO.env.ua.opera) {
				oIFrame = Dom.get("_yuiResizeMonitor");

				if (!oIFrame) {
					oIFrame = document.createElement("iframe");

					if (this.isSecure && Module.RESIZE_MONITOR_SECURE_URL &&
						YAHOO.env.ua.ie) {
						oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
					}

					if (YAHOO.env.ua.gecko) {
						sHTML = "<html><head><script " +
								"type=\"text/javascript\">" +
								"window.onresize=function(){window.parent." +
								"YAHOO.widget.Module.textResizeEvent." +
								"fire();};window.parent.YAHOO.widget.Module." +
								"textResizeEvent.fire();</script></head>" +
								"<body></body></html>";

						oIFrame.src = "data:text/html;charset=utf-8," +
							encodeURIComponent(sHTML);
					}

					oIFrame.id = "_yuiResizeMonitor";

					oIFrame.style.position = "absolute";
					oIFrame.style.visibility = "hidden";

					document.body.appendChild(oIFrame);

					oIFrame.style.width = "10em";
					oIFrame.style.height = "10em";
					oIFrame.style.top = (-1 * oIFrame.offsetHeight) + "px";
					oIFrame.style.left = (-1 * oIFrame.offsetWidth) + "px";
					oIFrame.style.borderWidth = "0";
					oIFrame.style.visibility = "visible";

					if (YAHOO.env.ua.webkit) {
						oDoc = oIFrame.contentWindow.document;

						oDoc.open();
						oDoc.close();
					}
				}

				if (oIFrame && oIFrame.contentWindow) {
					Module.textResizeEvent.subscribe(this.onDomResize,
						this, true);

					if (!Module.textResizeInitialized) {
						if (!Event.on(oIFrame.contentWindow, "resize",
							fireTextResize)) {
							Event.on(oIFrame, "resize", fireTextResize);
						}

						Module.textResizeInitialized = true;
					}

					this.resizeMonitor = oIFrame;
				}
			}
		},

		onDomResize: function (e, obj) {
			var nLeft = -1 * this.resizeMonitor.offsetWidth,
				nTop = -1 * this.resizeMonitor.offsetHeight;

			this.resizeMonitor.style.top = nTop + "px";
			this.resizeMonitor.style.left = nLeft + "px";
		},

		setHeader: function (headerContent) {
			var oHeader = this.header || (this.header = createHeader());

			if (typeof headerContent == "string") {
				oHeader.innerHTML = headerContent;
			} else {
				oHeader.innerHTML = "";
				oHeader.appendChild(headerContent);
			}

			this.changeHeaderEvent.fire(headerContent);
			this.changeContentEvent.fire();
		},

		appendToHeader: function (element) {
			var oHeader = this.header || (this.header = createHeader());

			oHeader.appendChild(element);

			this.changeHeaderEvent.fire(element);
			this.changeContentEvent.fire();
		},

		setBody: function (bodyContent) {
			var oBody = this.body || (this.body = createBody());

			if (typeof bodyContent == "string") {
				oBody.innerHTML = bodyContent;
			} else {
				oBody.innerHTML = "";
				oBody.appendChild(bodyContent);
			}

			this.changeBodyEvent.fire(bodyContent);
			this.changeContentEvent.fire();
		},

		appendToBody: function (element) {
			var oBody = this.body || (this.body = createBody());

			oBody.appendChild(element);

			this.changeBodyEvent.fire(element);
			this.changeContentEvent.fire();
		},

		setFooter: function (footerContent) {
			var oFooter = this.footer || (this.footer = createFooter());

			if (typeof footerContent == "string") {
				oFooter.innerHTML = footerContent;
			} else {
				oFooter.innerHTML = "";
				oFooter.appendChild(footerContent);
			}

			this.changeFooterEvent.fire(footerContent);
			this.changeContentEvent.fire();
		},

		appendToFooter: function (element) {
			var oFooter = this.footer || (this.footer = createFooter());

			oFooter.appendChild(element);

			this.changeFooterEvent.fire(element);
			this.changeContentEvent.fire();
		},

		render: function (appendToNode, moduleElement) {
			var me = this,
				firstChild;

			function appendTo(element) {
				if (typeof element == "string") {
					element = document.getElementById(element);
				}

				if (element) {
					element.appendChild(me.element);
					me.appendEvent.fire();
				}
			}

			this.beforeRenderEvent.fire();

			if (! moduleElement) {
				moduleElement = this.element;
			}

			if (appendToNode) {
				appendTo(appendToNode);
			} else {
				if (! Dom.inDocument(this.element)) {
					return false;
				}
			}

			if (this.header && ! Dom.inDocument(this.header)) {
				firstChild = moduleElement.firstChild;

				if (firstChild) {
					moduleElement.insertBefore(this.header, firstChild);
				} else {
					moduleElement.appendChild(this.header);
				}
			}

			if (this.body && ! Dom.inDocument(this.body)) {
				if (this.footer && Dom.isAncestor(
					this.moduleElement, this.footer)) {
					moduleElement.insertBefore(this.body, this.footer);
				} else {
					moduleElement.appendChild(this.body);
				}
			}

			if (this.footer && ! Dom.inDocument(this.footer)) {
				moduleElement.appendChild(this.footer);
			}

			this.renderEvent.fire();
			return true;
		},

		destroy: function () {
			var parent,
				e;

			if (this.element) {
				Event.purgeElement(this.element, true);
				parent = this.element.parentNode;
			}

			if (parent) {
				parent.removeChild(this.element);
			}

			this.element = null;
			this.header = null;
			this.body = null;
			this.footer = null;

			Module.textResizeEvent.unsubscribe(this.onDomResize, this);

			this.cfg.destroy();
			this.cfg = null;

			this.destroyEvent.fire();

			for (e in this) {
				if (e instanceof CustomEvent) {
					e.unsubscribeAll();
				}
			}
		},

		show: function () {
			this.cfg.setProperty("visible", true);
		},

		hide: function () {
			this.cfg.setProperty("visible", false);
		},

		configVisible: function (type, args, obj) {
			var visible = args[0];
			if (visible) {
				this.beforeShowEvent.fire();
				Dom.setStyle(this.element, "display", "block");
				this.showEvent.fire();
			} else {
				this.beforeHideEvent.fire();
				Dom.setStyle(this.element, "display", "none");
				this.hideEvent.fire();
			}
		},

		configMonitorResize: function (type, args, obj) {
			var monitor = args[0];

			if (monitor) {
				this.initResizeMonitor();
			} else {
				Module.textResizeEvent.unsubscribe(
					this.onDomResize, this, true);

				this.resizeMonitor = null;
			}
		},

		toString: function () {
			return "Module " + this.id;
		}
	};

	YAHOO.lang.augmentProto(Module, YAHOO.util.EventProvider);

}());
(function () {
	YAHOO.widget.Overlay = function (el, userConfig) {
		YAHOO.widget.Overlay.superclass.constructor.call(this, el, userConfig);
	};

	var Lang = YAHOO.lang,
		CustomEvent = YAHOO.util.CustomEvent,
		Module = YAHOO.widget.Module,
		Event = YAHOO.util.Event,
		Dom = YAHOO.util.Dom,
		Config = YAHOO.util.Config,
		Overlay = YAHOO.widget.Overlay,

		m_oIFrameTemplate,

		EVENT_TYPES = {
			"BEFORE_MOVE": "beforeMove",
			"MOVE": "move"
		},

		DEFAULT_CONFIG = {
			"X": {
				key: "x",
				validator: Lang.isNumber,
				suppressEvent: true,
				supercedes: ["iframe"]
			},

			"Y": {
				key: "y",
				validator: Lang.isNumber,
				suppressEvent: true,
				supercedes: ["iframe"]
			},

			"XY": {
				key: "xy",
				suppressEvent: true,
				supercedes: ["iframe"]
			},

			"CONTEXT": {
				key: "context",
				suppressEvent: true,
				supercedes: ["iframe"]
			},

			"FIXED_CENTER": {
				key: "fixedcenter",
				value: false,
				validator: Lang.isBoolean,
				supercedes: ["iframe", "visible"]
			},

			"WIDTH": {
				key: "width",
				suppressEvent: true,
				supercedes: ["context", "fixedcenter", "iframe"]
			},

			"HEIGHT": {
				key: "height",
				suppressEvent: true,
				supercedes: ["context", "fixedcenter", "iframe"]
			},

			"ZINDEX": {
				key: "zindex",
				value: null
			},

			"CONSTRAIN_TO_VIEWPORT": {
				key: "constraintoviewport",
				value: false,
				validator: Lang.isBoolean,
				supercedes: ["iframe", "x", "y", "xy"]
			},

			"IFRAME": {
				key: "iframe",
				value: (YAHOO.env.ua.ie == 6 ? true : false),
				validator: Lang.isBoolean,
				supercedes: ["zindex"]
			}
		};

	Overlay.IFRAME_SRC = "javascript:false;";
	Overlay.IFRAME_OFFSET = 3;
	Overlay.TOP_LEFT = "tl";
	Overlay.TOP_RIGHT = "tr";
	Overlay.BOTTOM_LEFT = "bl";
	Overlay.BOTTOM_RIGHT = "br";
	Overlay.CSS_OVERLAY = "yui-overlay";
	Overlay.windowScrollEvent = new CustomEvent("windowScroll");
	Overlay.windowResizeEvent = new CustomEvent("windowResize");
	Overlay.windowScrollHandler = function (e) {
		if (YAHOO.env.ua.ie) {
			if (! window.scrollEnd) {
				window.scrollEnd = -1;
			}

			clearTimeout(window.scrollEnd);

			window.scrollEnd = setTimeout(function () {
				Overlay.windowScrollEvent.fire();
			}, 1);
		} else {
			Overlay.windowScrollEvent.fire();
		}
	};

	Overlay.windowResizeHandler = function (e) {
		if (YAHOO.env.ua.ie) {
			if (! window.resizeEnd) {
				window.resizeEnd = -1;
			}

			clearTimeout(window.resizeEnd);

			window.resizeEnd = setTimeout(function () {
				Overlay.windowResizeEvent.fire();
			}, 100);
		} else {
			Overlay.windowResizeEvent.fire();
		}
	};

	Overlay._initialized = null;

	if (Overlay._initialized === null) {
		Event.on(window, "scroll", Overlay.windowScrollHandler);
		Event.on(window, "resize", Overlay.windowResizeHandler);

		Overlay._initialized = true;
	}

	YAHOO.extend(Overlay, Module, {
		init: function (el, userConfig) {
			Overlay.superclass.init.call(this, el/*, userConfig*/);

			this.beforeInitEvent.fire(Overlay);

			Dom.addClass(this.element, Overlay.CSS_OVERLAY);

			if (userConfig) {
				this.cfg.applyConfig(userConfig, true);
			}

			if (this.platform == "mac" && YAHOO.env.ua.gecko) {
				if (! Config.alreadySubscribed(this.showEvent,
					this.showMacGeckoScrollbars, this)) {
					this.showEvent.subscribe(this.showMacGeckoScrollbars,
						this, true);
				}

				if (! Config.alreadySubscribed(this.hideEvent,
					this.hideMacGeckoScrollbars, this)) {
					this.hideEvent.subscribe(this.hideMacGeckoScrollbars,
						this, true);
				}
			}

			this.initEvent.fire(Overlay);
		},

		initEvents: function () {
			Overlay.superclass.initEvents.call(this);

			var SIGNATURE = CustomEvent.LIST;

			this.beforeMoveEvent = this.createEvent(EVENT_TYPES.BEFORE_MOVE);
			this.beforeMoveEvent.signature = SIGNATURE;

			this.moveEvent = this.createEvent(EVENT_TYPES.MOVE);
			this.moveEvent.signature = SIGNATURE;
		},

		initDefaultConfig: function () {
			Overlay.superclass.initDefaultConfig.call(this);

			this.cfg.addProperty(DEFAULT_CONFIG.X.key, {
				handler: this.configX,
				validator: DEFAULT_CONFIG.X.validator,
				suppressEvent: DEFAULT_CONFIG.X.suppressEvent,
				supercedes: DEFAULT_CONFIG.X.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
				handler: this.configY,
				validator: DEFAULT_CONFIG.Y.validator,
				suppressEvent: DEFAULT_CONFIG.Y.suppressEvent,
				supercedes: DEFAULT_CONFIG.Y.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.XY.key, {
				handler: this.configXY,
				suppressEvent: DEFAULT_CONFIG.XY.suppressEvent,
				supercedes: DEFAULT_CONFIG.XY.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.CONTEXT.key, {
				handler: this.configContext,
				suppressEvent: DEFAULT_CONFIG.CONTEXT.suppressEvent,
				supercedes: DEFAULT_CONFIG.CONTEXT.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.FIXED_CENTER.key, {
				handler: this.configFixedCenter,
				value: DEFAULT_CONFIG.FIXED_CENTER.value,
				validator: DEFAULT_CONFIG.FIXED_CENTER.validator,
				supercedes: DEFAULT_CONFIG.FIXED_CENTER.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.WIDTH.key, {
				handler: this.configWidth,
				suppressEvent: DEFAULT_CONFIG.WIDTH.suppressEvent,
				supercedes: DEFAULT_CONFIG.WIDTH.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.HEIGHT.key, {
				handler: this.configHeight,
				suppressEvent: DEFAULT_CONFIG.HEIGHT.suppressEvent,
				supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.ZINDEX.key, {
				handler: this.configzIndex,
				value: DEFAULT_CONFIG.ZINDEX.value
			});

			this.cfg.addProperty(DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, {
				handler: this.configConstrainToViewport,
				value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value,
				validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator,
				supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
			});

			this.cfg.addProperty(DEFAULT_CONFIG.IFRAME.key, {
				handler: this.configIframe,
				value: DEFAULT_CONFIG.IFRAME.value,
				validator: DEFAULT_CONFIG.IFRAME.validator,
				supercedes: DEFAULT_CONFIG.IFRAME.supercedes
			});
		},

		moveTo: function (x, y) {
			this.cfg.setProperty("xy", [x, y]);
		},

		hideMacGeckoScrollbars: function () {
			Dom.removeClass(this.element, "show-scrollbars");
			Dom.addClass(this.element, "hide-scrollbars");
		},

		showMacGeckoScrollbars: function () {
			Dom.removeClass(this.element, "hide-scrollbars");
			Dom.addClass(this.element, "show-scrollbars");
		},

		configVisible: function (type, args, obj) {
			var visible = args[0],
				currentVis = Dom.getStyle(this.element, "visibility"),
				effect = this.cfg.getProperty("effect"),
				effectInstances = [],
				isMacGecko = (this.platform == "mac" && YAHOO.env.ua.gecko),
				alreadySubscribed = Config.alreadySubscribed,
				eff, ei, e, i, j, k, h,
				nEffects,
				nEffectInstances;

			if (currentVis == "inherit") {
				e = this.element.parentNode;

				while (e.nodeType != 9 && e.nodeType != 11) {
					currentVis = Dom.getStyle(e, "visibility");

					if (currentVis != "inherit") {
						break;
					}

					e = e.parentNode;
				}

				if (currentVis == "inherit") {
					currentVis = "visible";
				}
			}

			if (effect) {
				if (effect instanceof Array) {
					nEffects = effect.length;

					for (i = 0; i < nEffects; i++) {
						eff = effect[i];

						effectInstances[effectInstances.length] =
							eff.effect(this, eff.duration);
					}
				} else {
					effectInstances[effectInstances.length] =
						effect.effect(this, effect.duration);
				}
			}

			if (visible) {
				if (isMacGecko) {
					this.showMacGeckoScrollbars();
				}

				if (effect) {
					if (visible) {
						if (currentVis != "visible" || currentVis === "") {
							this.beforeShowEvent.fire();

							nEffectInstances = effectInstances.length;

							for (j = 0; j < nEffectInstances; j++) {
								ei = effectInstances[j];

								if (j === 0 && !alreadySubscribed(
										ei.animateInCompleteEvent,
										this.showEvent.fire, this.showEvent)) {
									ei.animateInCompleteEvent.subscribe(
									this.showEvent.fire, this.showEvent, true);
								}

								ei.animateIn();
							}
						}
					}
				} else {
					if (currentVis != "visible" || currentVis === "") {
						this.beforeShowEvent.fire();

						Dom.setStyle(this.element, "visibility", "visible");

						this.cfg.refireEvent("iframe");
						this.showEvent.fire();
					}
				}
			} else {
				if (isMacGecko) {
					this.hideMacGeckoScrollbars();
				}

				if (effect) {
					if (currentVis == "visible") {
						this.beforeHideEvent.fire();

						nEffectInstances = effectInstances.length;

						for (k = 0; k < nEffectInstances; k++) {
							h = effectInstances[k];

							if (k === 0 && !alreadySubscribed(
								h.animateOutCompleteEvent, this.hideEvent.fire,
								this.hideEvent)) {
								h.animateOutCompleteEvent.subscribe(
									this.hideEvent.fire, this.hideEvent, true);
							}

							h.animateOut();
						}
					} else if (currentVis === "") {
						Dom.setStyle(this.element, "visibility", "hidden");
					}
				} else {
					if (currentVis == "visible" || currentVis === "") {
						this.beforeHideEvent.fire();

						Dom.setStyle(this.element, "visibility", "hidden");

						this.hideEvent.fire();
					}
				}
			}
		},

		doCenterOnDOMEvent: function () {
			if (this.cfg.getProperty("visible")) {
				this.center();
			}
		},

		configFixedCenter: function (type, args, obj) {
			var val = args[0],
				alreadySubscribed = Config.alreadySubscribed,
				windowResizeEvent = Overlay.windowResizeEvent,
				windowScrollEvent = Overlay.windowScrollEvent;

			if (val) {
				this.center();

				if (!alreadySubscribed(this.beforeShowEvent,
					this.center, this)) {
					this.beforeShowEvent.subscribe(this.center);
				}

				if (!alreadySubscribed(windowResizeEvent,
					this.doCenterOnDOMEvent, this)) {
					windowResizeEvent.subscribe(this.doCenterOnDOMEvent,
						this, true);
				}

				if (!alreadySubscribed(windowScrollEvent,
					this.doCenterOnDOMEvent, this)) {
					windowScrollEvent.subscribe(this.doCenterOnDOMEvent,
						this, true);
				}
			} else {
				this.beforeShowEvent.unsubscribe(this.center);

				windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
				windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
			}
		},

		configHeight: function (type, args, obj) {
			var height = args[0],
				el = this.element;

			Dom.setStyle(el, "height", height);
			this.cfg.refireEvent("iframe");
		},

		configWidth: function (type, args, obj) {
			var width = args[0],
				el = this.element;

			Dom.setStyle(el, "width", width);
			this.cfg.refireEvent("iframe");
		},

		configzIndex: function (type, args, obj) {
			var zIndex = args[0],
				el = this.element;

			if (! zIndex) {
				zIndex = Dom.getStyle(el, "zIndex");

				if (! zIndex || isNaN(zIndex)) {
					zIndex = 0;
				}
			}

			if (this.iframe) {
				if (zIndex <= 0) {
					zIndex = 1;
				}

				Dom.setStyle(this.iframe, "zIndex", (zIndex - 1));
			}

			Dom.setStyle(el, "zIndex", zIndex);
			this.cfg.setProperty("zIndex", zIndex, true);
		},

		configXY: function (type, args, obj) {
			var pos = args[0],
				x = pos[0],
				y = pos[1];

			this.cfg.setProperty("x", x);
			this.cfg.setProperty("y", y);

			this.beforeMoveEvent.fire([x, y]);

			x = this.cfg.getProperty("x");
			y = this.cfg.getProperty("y");

			this.cfg.refireEvent("iframe");
			this.moveEvent.fire([x, y]);
		},

		configX: function (type, args, obj) {
			var x = args[0],
				y = this.cfg.getProperty("y");

			this.cfg.setProperty("x", x, true);
			this.cfg.setProperty("y", y, true);

			this.beforeMoveEvent.fire([x, y]);

			x = this.cfg.getProperty("x");
			y = this.cfg.getProperty("y");

			Dom.setX(this.element, x, true);

			this.cfg.setProperty("xy", [x, y], true);

			this.cfg.refireEvent("iframe");
			this.moveEvent.fire([x, y]);
		},

		configY: function (type, args, obj) {
			var x = this.cfg.getProperty("x"),
				y = args[0];

			this.cfg.setProperty("x", x, true);
			this.cfg.setProperty("y", y, true);

			this.beforeMoveEvent.fire([x, y]);

			x = this.cfg.getProperty("x");
			y = this.cfg.getProperty("y");

			Dom.setY(this.element, y, true);

			this.cfg.setProperty("xy", [x, y], true);

			this.cfg.refireEvent("iframe");
			this.moveEvent.fire([x, y]);
		},

		showIframe: function () {
			var oIFrame = this.iframe,
				oParentNode;

			if (oIFrame) {
				oParentNode = this.element.parentNode;

				if (oParentNode != oIFrame.parentNode) {
					oParentNode.appendChild(oIFrame);
				}

				oIFrame.style.display = "block";
			}
		},

		hideIframe: function () {
			if (this.iframe) {
				this.iframe.style.display = "none";
			}
		},

		syncIframe: function () {
			var oIFrame = this.iframe,
				oElement = this.element,
				nOffset = Overlay.IFRAME_OFFSET,
				nDimensionOffset = (nOffset * 2),
				aXY;

			if (oIFrame) {
				oIFrame.style.width =
					(oElement.offsetWidth + nDimensionOffset + "px");

				oIFrame.style.height =
					(oElement.offsetHeight + nDimensionOffset + "px");

				aXY = this.cfg.getProperty("xy");

				if (!Lang.isArray(aXY) || (isNaN(aXY[0]) || isNaN(aXY[1]))) {
					this.syncPosition();

					aXY = this.cfg.getProperty("xy");
				}

				Dom.setXY(oIFrame, [(aXY[0] - nOffset), (aXY[1] - nOffset)]);
			}
		},

		configIframe: function (type, args, obj) {
			var bIFrame = args[0];

			function createIFrame() {
				var oIFrame = this.iframe,
					oElement = this.element,
					oParent,
					aXY;

				if (!oIFrame) {
					if (!m_oIFrameTemplate) {
						m_oIFrameTemplate = document.createElement("iframe");

						if (this.isSecure) {
							m_oIFrameTemplate.src = Overlay.IFRAME_SRC;
						}

						if (YAHOO.env.ua.ie) {
							m_oIFrameTemplate.style.filter = "alpha(opacity=0)";

							m_oIFrameTemplate.frameBorder = 0;
						}
						else {
							m_oIFrameTemplate.style.opacity = "0";
						}

						m_oIFrameTemplate.style.position = "absolute";
						m_oIFrameTemplate.style.border = "none";
						m_oIFrameTemplate.style.margin = "0";
						m_oIFrameTemplate.style.padding = "0";
						m_oIFrameTemplate.style.display = "none";
					}

					oIFrame = m_oIFrameTemplate.cloneNode(false);

					oParent = oElement.parentNode;

					if (oParent) {
						oParent.appendChild(oIFrame);
					} else {
						document.body.appendChild(oIFrame);
					}

					this.iframe = oIFrame;
				}

				this.showIframe();

				this.syncIframe();

				if (!this._hasIframeEventListeners) {
					this.showEvent.subscribe(this.showIframe);
					this.hideEvent.subscribe(this.hideIframe);
					this.changeContentEvent.subscribe(this.syncIframe);

					this._hasIframeEventListeners = true;
				}
			}

			function onBeforeShow() {
				createIFrame.call(this);

				this.beforeShowEvent.unsubscribe(onBeforeShow);

				this._iframeDeferred = false;
			}

			if (bIFrame) {
				if (this.cfg.getProperty("visible")) {
					createIFrame.call(this);
				}
				else {
					if (!this._iframeDeferred) {
						this.beforeShowEvent.subscribe(onBeforeShow);

						this._iframeDeferred = true;
					}
				}
			} else {
				this.hideIframe();

				if (this._hasIframeEventListeners) {
					this.showEvent.unsubscribe(this.showIframe);
					this.hideEvent.unsubscribe(this.hideIframe);
					this.changeContentEvent.unsubscribe(this.syncIframe);

					this._hasIframeEventListeners = false;
				}
			}
		},

		configConstrainToViewport: function (type, args, obj) {
			var val = args[0];

			if (val) {
				if (! Config.alreadySubscribed(this.beforeMoveEvent,
					this.enforceConstraints, this)) {
					this.beforeMoveEvent.subscribe(this.enforceConstraints,
						this, true);
				}
			} else {
				this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
			}
		},

		configContext: function (type, args, obj) {
			var contextArgs = args[0],
				contextEl,
				elementMagnetCorner,
				contextMagnetCorner;

			if (contextArgs) {
				contextEl = contextArgs[0];
				elementMagnetCorner = contextArgs[1];
				contextMagnetCorner = contextArgs[2];

				if (contextEl) {
					if (typeof contextEl == "string") {
						this.cfg.setProperty("context",
							[document.getElementById(contextEl),
								elementMagnetCorner, contextMagnetCorner],
								true);
					}

					if (elementMagnetCorner && contextMagnetCorner) {
						this.align(elementMagnetCorner, contextMagnetCorner);
					}
				}
			}
		},

		align: function (elementAlign, contextAlign) {
			var contextArgs = this.cfg.getProperty("context"),
				me = this,
				context,
				element,
				contextRegion;

			function doAlign(v, h) {
				switch (elementAlign) {
				case Overlay.TOP_LEFT:
					me.moveTo(h, v);
					break;

				case Overlay.TOP_RIGHT:
					me.moveTo((h - element.offsetWidth), v);
					break;

				case Overlay.BOTTOM_LEFT:
					me.moveTo(h, (v - element.offsetHeight));
					break;

				case Overlay.BOTTOM_RIGHT:
					me.moveTo((h - element.offsetWidth),
						(v - element.offsetHeight));
					break;
				}
			}

			if (contextArgs) {
				context = contextArgs[0];
				element = this.element;
				me = this;

				if (! elementAlign) {
					elementAlign = contextArgs[1];
				}

				if (! contextAlign) {
					contextAlign = contextArgs[2];
				}

				if (element && context) {
					contextRegion = Dom.getRegion(context);

					switch (contextAlign) {
					case Overlay.TOP_LEFT:
						doAlign(contextRegion.top, contextRegion.left);
						break;

					case Overlay.TOP_RIGHT:
						doAlign(contextRegion.top, contextRegion.right);
						break;

					case Overlay.BOTTOM_LEFT:
						doAlign(contextRegion.bottom, contextRegion.left);
						break;

					case Overlay.BOTTOM_RIGHT:
						doAlign(contextRegion.bottom, contextRegion.right);
						break;
					}
				}
			}
		},

		enforceConstraints: function (type, args, obj) {
			var pos = args[0],
				x = pos[0],
				y = pos[1],
				offsetHeight = this.element.offsetHeight,
				offsetWidth = this.element.offsetWidth,
				viewPortWidth = Dom.getViewportWidth(),
				viewPortHeight = Dom.getViewportHeight(),
				scrollX = Dom.getDocumentScrollLeft(),
				scrollY = Dom.getDocumentScrollTop(),
				topConstraint = scrollY + 10,
				leftConstraint = scrollX + 10,
				bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10,
				rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;

			if (x < leftConstraint) {
				x = leftConstraint;
			} else if (x > rightConstraint) {
				x = rightConstraint;
			}

			if (y < topConstraint) {
				y = topConstraint;
			} else if (y > bottomConstraint) {
				y = bottomConstraint;
			}

			this.cfg.setProperty("x", x, true);
			this.cfg.setProperty("y", y, true);
			this.cfg.setProperty("xy", [x, y], true);
		},

		center: function () {
			var scrollX = Dom.getDocumentScrollLeft(),
				scrollY = Dom.getDocumentScrollTop(),

				viewPortWidth = Dom.getClientWidth(),
				viewPortHeight = Dom.getClientHeight(),
				elementWidth = this.element.offsetWidth,
				elementHeight = this.element.offsetHeight,
				x = (viewPortWidth / 2) - (elementWidth / 2) + scrollX,
				y = (viewPortHeight / 2) - (elementHeight / 2) + scrollY;

			this.cfg.setProperty("xy", [parseInt(x, 10), parseInt(y, 10)]);

			this.cfg.refireEvent("iframe");
		},

		syncPosition: function () {
			var pos = Dom.getXY(this.element);

			this.cfg.setProperty("x", pos[0], true);
			this.cfg.setProperty("y", pos[1], true);
			this.cfg.setProperty("xy", pos, true);
		},

		onDomResize: function (e, obj) {
			var me = this;

			Overlay.superclass.onDomResize.call(this, e, obj);

			setTimeout(function () {
				me.syncPosition();
				me.cfg.refireEvent("iframe");
				me.cfg.refireEvent("context");
			}, 0);
		},

		bringToTop: function() {
			var aOverlays = [],
				oElement = this.element;

			function compareZIndexDesc(p_oOverlay1, p_oOverlay2) {
				var sZIndex1 = Dom.getStyle(p_oOverlay1, "zIndex"),
					sZIndex2 = Dom.getStyle(p_oOverlay2, "zIndex"),
					nZIndex1 = (!sZIndex1 || isNaN(sZIndex1)) ?
						0 : parseInt(sZIndex1, 10),
					nZIndex2 = (!sZIndex2 || isNaN(sZIndex2)) ?
						0 : parseInt(sZIndex2, 10);

				if (nZIndex1 > nZIndex2) {
					return -1;
				} else if (nZIndex1 < nZIndex2) {
					return 1;
				} else {
					return 0;
				}
			}

			function isOverlayElement(p_oElement) {
				var oOverlay = Dom.hasClass(p_oElement, Overlay.CSS_OVERLAY),
					Panel = YAHOO.widget.Panel;

				if (oOverlay && !Dom.isAncestor(oElement, oOverlay)) {
					if (Panel && Dom.hasClass(p_oElement, Panel.CSS_PANEL)) {
						aOverlays[aOverlays.length] = p_oElement.parentNode;
					}
					else {
						aOverlays[aOverlays.length] = p_oElement;
					}
				}
			}

			Dom.getElementsBy(isOverlayElement, "DIV", document.body);

			aOverlays.sort(compareZIndexDesc);

			var oTopOverlay = aOverlays[0],
				nTopZIndex;

			if (oTopOverlay) {
				nTopZIndex = Dom.getStyle(oTopOverlay, "zIndex");

				if (!isNaN(nTopZIndex) && oTopOverlay != oElement) {
					this.cfg.setProperty("zindex",
						(parseInt(nTopZIndex, 10) + 2));
				}
			}
		},

		destroy: function () {
			if (this.iframe) {
				this.iframe.parentNode.removeChild(this.iframe);
			}

			this.iframe = null;

			Overlay.windowResizeEvent.unsubscribe(
				this.doCenterOnDOMEvent, this);

			Overlay.windowScrollEvent.unsubscribe(
				this.doCenterOnDOMEvent, this);

			Overlay.superclass.destroy.call(this);
		},

		toString: function () {
			return "Overlay " + this.id;
		}
	});

}());
(function () {
	YAHOO.widget.OverlayManager = function (userConfig) {
		this.init(userConfig);
	};

	var Overlay = YAHOO.widget.Overlay,
		Event = YAHOO.util.Event,
		Dom = YAHOO.util.Dom,
		Config = YAHOO.util.Config,
		CustomEvent = YAHOO.util.CustomEvent,
		OverlayManager = YAHOO.widget.OverlayManager;

	OverlayManager.CSS_FOCUSED = "focused";

	OverlayManager.prototype = {
		constructor: OverlayManager,

		overlays: null,

		initDefaultConfig: function () {
			this.cfg.addProperty("overlays", { suppressEvent: true } );

			this.cfg.addProperty("focusevent", { value: "mousedown" } );
		},

		init: function (userConfig) {
			this.cfg = new Config(this);

			this.initDefaultConfig();

			if (userConfig) {
				this.cfg.applyConfig(userConfig, true);
			}
			this.cfg.fireQueue();

			var activeOverlay = null;

			this.getActive = function () {
				return activeOverlay;
			};

			this.focus = function (overlay) {
				var o = this.find(overlay);

				if (o) {
					if (activeOverlay != o) {
						if (activeOverlay) {
							activeOverlay.blur();
						}

						this.bringToTop(o);

						activeOverlay = o;

						Dom.addClass(activeOverlay.element,
							OverlayManager.CSS_FOCUSED);

						o.focusEvent.fire();
					}
				}
			};

			this.remove = function (overlay) {
				var o = this.find(overlay),
					originalZ;

				if (o) {
					if (activeOverlay == o) {
						activeOverlay = null;
					}

					originalZ = Dom.getStyle(o.element, "zIndex");

					o.cfg.setProperty("zIndex", -1000, true);

					this.overlays.sort(this.compareZIndexDesc);

					this.overlays =
						this.overlays.slice(0, (this.overlays.length - 1));

					o.hideEvent.unsubscribe(o.blur);
					o.destroyEvent.unsubscribe(this._onOverlayDestroy, o);

					if (o.element) {
						Event.removeListener(o.element,
							this.cfg.getProperty("focusevent"),
							this._onOverlayElementFocus);
					}

					o.cfg.setProperty("zIndex", originalZ, true);
					o.cfg.setProperty("manager", null);

					o.focusEvent.unsubscribeAll();
					o.blurEvent.unsubscribeAll();

					o.focusEvent = null;
					o.blurEvent = null;

					o.focus = null;
					o.blur = null;
				}
			};

			this.blurAll = function () {
				var nOverlays = this.overlays.length,
					i;

				if (nOverlays > 0) {
					i = nOverlays - 1;

					do {
						this.overlays[i].blur();
					}
					while(i--);
				}
			};

			this._onOverlayBlur = function (p_sType, p_aArgs) {
				activeOverlay = null;
			};

			var overlays = this.cfg.getProperty("overlays");

			if (! this.overlays) {
				this.overlays = [];
			}

			if (overlays) {
				this.register(overlays);
				this.overlays.sort(this.compareZIndexDesc);
			}
		},

		_onOverlayElementFocus: function (p_oEvent) {
			var oTarget = Event.getTarget(p_oEvent),
				oClose = this.close;

			if (oClose && (oTarget == oClose ||
					Dom.isAncestor(oClose, oTarget))) {
				this.blur();
			}
			else {
				this.focus();
			}
		},

		_onOverlayDestroy: function (p_sType, p_aArgs, p_oOverlay) {
			this.remove(p_oOverlay);
		},

		register: function (overlay) {
			var mgr = this,
				zIndex,
				regcount,
				i,
				nOverlays;

			if (overlay instanceof Overlay) {
				overlay.cfg.addProperty("manager", { value: this } );

				overlay.focusEvent = overlay.createEvent("focus");
				overlay.focusEvent.signature = CustomEvent.LIST;

				overlay.blurEvent = overlay.createEvent("blur");
				overlay.blurEvent.signature = CustomEvent.LIST;

				overlay.focus = function () {
					mgr.focus(this);
				};

				overlay.blur = function () {
					if (mgr.getActive() == this) {
						Dom.removeClass(this.element,
							OverlayManager.CSS_FOCUSED);

						this.blurEvent.fire();
					}
				};

				overlay.blurEvent.subscribe(mgr._onOverlayBlur);
				overlay.hideEvent.subscribe(overlay.blur);
				overlay.destroyEvent.subscribe(this._onOverlayDestroy, overlay, this);

				Event.on(overlay.element, this.cfg.getProperty("focusevent"), this._onOverlayElementFocus, null, overlay);

				zIndex = Dom.getStyle(overlay.element, "zIndex");

				if (!isNaN(zIndex)) {
					overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
				} else {
					overlay.cfg.setProperty("zIndex", 0);
				}

				this.overlays.push(overlay);
				this.bringToTop(overlay);

				return true;
			} else if (overlay instanceof Array) {
				regcount = 0;
				nOverlays = overlay.length;

				for (i = 0; i < nOverlays; i++) {
					if (this.register(overlay[i])) {
						regcount++;
					}
				}

				if (regcount > 0) {
					return true;
				}
			} else {
				return false;
			}
		},

		bringToTop: function (p_oOverlay) {
			var oOverlay = this.find(p_oOverlay),
				nTopZIndex,
				oTopOverlay,
				aOverlays;

			if (oOverlay) {
				aOverlays = this.overlays;
				aOverlays.sort(this.compareZIndexDesc);
				oTopOverlay = aOverlays[0];

				if (oTopOverlay) {
					nTopZIndex = Dom.getStyle(oTopOverlay.element, "zIndex");

					if (!isNaN(nTopZIndex) && oTopOverlay != oOverlay) {
						oOverlay.cfg.setProperty("zIndex",
							(parseInt(nTopZIndex, 10) + 2));
					}

					aOverlays.sort(this.compareZIndexDesc);
				}
			}
		},

		find: function (overlay) {
			var aOverlays = this.overlays,
				nOverlays = aOverlays.length,
				i;

			if (nOverlays > 0) {
				i = nOverlays - 1;

				if (overlay instanceof Overlay) {
					do {
						if (aOverlays[i] == overlay) {
							return aOverlays[i];
						}
					}
					while(i--);
				} else if (typeof overlay == "string") {
					do {
						if (aOverlays[i].id == overlay) {
							return aOverlays[i];
						}
					}
					while(i--);
				}

				return null;
			}
		},

		compareZIndexDesc: function (o1, o2) {
			var zIndex1 = o1.cfg.getProperty("zIndex"),
				zIndex2 = o2.cfg.getProperty("zIndex");

			if (zIndex1 > zIndex2) {
				return -1;
			} else if (zIndex1 < zIndex2) {
				return 1;
			} else {
				return 0;
			}
		},

		showAll: function () {
			var aOverlays = this.overlays,
				nOverlays = aOverlays.length,
				i;

			if (nOverlays > 0) {
				i = nOverlays - 1;

				do {
					aOverlays[i].show();
				}
				while(i--);
			}
		},

		hideAll: function () {
			var aOverlays = this.overlays,
				nOverlays = aOverlays.length,
				i;

			if (nOverlays > 0) {
				i = nOverlays - 1;
				do {
					aOverlays[i].hide();
				}
				while(i--);
			}
		},

		toString: function () {
			return "OverlayManager";
		}
	};

}());
(function () {
	YAHOO.widget.ContainerEffect =
		function (overlay, attrIn, attrOut, targetElement, animClass) {
		if (!animClass) {
			animClass = YAHOO.util.Anim;
		}
		this.overlay = overlay;
		this.attrIn = attrIn;
		this.attrOut = attrOut;
		this.targetElement = targetElement || overlay.element;
		this.animClass = animClass;
	};

	var Dom = YAHOO.util.Dom,
		CustomEvent = YAHOO.util.CustomEvent,
		Easing = YAHOO.util.Easing,
		ContainerEffect = YAHOO.widget.ContainerEffect;

	ContainerEffect.FADE = function (overlay, dur) {
		var fade = new ContainerEffect(overlay,
			{ attributes: { opacity: { from: 0, to: 1 } },
				duration: dur,
				method: Easing.easeIn },

			{ attributes: { opacity: { to: 0 } },
				duration: dur,
				method: Easing.easeOut },

			overlay.element);

		fade.handleStartAnimateIn = function (type,args,obj) {
			Dom.addClass(obj.overlay.element, "hide-select");

			if (! obj.overlay.underlay) {
				obj.overlay.cfg.refireEvent("underlay");
			}

			if (obj.overlay.underlay) {
				obj.initialUnderlayOpacity = Dom.getStyle(obj.overlay.underlay, "opacity");
				obj.overlay.underlay.style.filter = null;
			}

			Dom.setStyle(obj.overlay.element, "visibility", "visible");
			Dom.setStyle(obj.overlay.element, "opacity", 0);
		};

		fade.handleCompleteAnimateIn = function (type,args,obj) {
			Dom.removeClass(obj.overlay.element, "hide-select");

			if (obj.overlay.element.style.filter) {
				obj.overlay.element.style.filter = null;
			}

			if (obj.overlay.underlay) {
				Dom.setStyle(obj.overlay.underlay, "opacity",
					obj.initialUnderlayOpacity);
			}

			obj.overlay.cfg.refireEvent("iframe");
			obj.animateInCompleteEvent.fire();
		};

		fade.handleStartAnimateOut = function (type, args, obj) {
			Dom.addClass(obj.overlay.element, "hide-select");

			if (obj.overlay.underlay) {
				obj.overlay.underlay.style.filter = null;
			}
		};

		fade.handleCompleteAnimateOut = function (type, args, obj) {
			Dom.removeClass(obj.overlay.element, "hide-select");
			if (obj.overlay.element.style.filter) {
				obj.overlay.element.style.filter = null;
			}
			Dom.setStyle(obj.overlay.element, "visibility", "hidden");
			Dom.setStyle(obj.overlay.element, "opacity", 1);

			obj.overlay.cfg.refireEvent("iframe");
			obj.animateOutCompleteEvent.fire();
		};

		fade.init();
		return fade;
	};

	ContainerEffect.SLIDE = function (overlay, dur) {
		var x = overlay.cfg.getProperty("x") || Dom.getX(overlay.element),
			y = overlay.cfg.getProperty("y") || Dom.getY(overlay.element),
			clientWidth = Dom.getClientWidth(),
			offsetWidth = overlay.element.offsetWidth,
			slide = new ContainerEffect(overlay,

			{ attributes: { points: { to: [x, y] } },
				duration: dur,
				method: Easing.easeIn },

			{ attributes: { points: { to: [(clientWidth + 25), y] } },
				duration: dur,
				method: Easing.easeOut },

			overlay.element, YAHOO.util.Motion);

		slide.handleStartAnimateIn = function (type,args,obj) {
			obj.overlay.element.style.left = ((-25) - offsetWidth) + "px";
			obj.overlay.element.style.top = y + "px";
		};

		slide.handleTweenAnimateIn = function (type, args, obj) {
			var pos = Dom.getXY(obj.overlay.element),
				currentX = pos[0],
				currentY = pos[1];

			if (Dom.getStyle(obj.overlay.element, "visibility") == "hidden" && currentX < x) {
				Dom.setStyle(obj.overlay.element, "visibility", "visible");
			}

			obj.overlay.cfg.setProperty("xy", [currentX, currentY], true);
			obj.overlay.cfg.refireEvent("iframe");
		};

		slide.handleCompleteAnimateIn = function (type, args, obj) {
			obj.overlay.cfg.setProperty("xy", [x, y], true);
			obj.startX = x;
			obj.startY = y;
			obj.overlay.cfg.refireEvent("iframe");
			obj.animateInCompleteEvent.fire();
		};

		slide.handleStartAnimateOut = function (type, args, obj) {
			var vw = Dom.getViewportWidth(),
				pos = Dom.getXY(obj.overlay.element),
				yso = pos[1],
				currentTo = obj.animOut.attributes.points.to;

			obj.animOut.attributes.points.to = [(vw + 25), yso];
		};

		slide.handleTweenAnimateOut = function (type, args, obj) {
			var pos = Dom.getXY(obj.overlay.element),
				xto = pos[0],
				yto = pos[1];

			obj.overlay.cfg.setProperty("xy", [xto, yto], true);
			obj.overlay.cfg.refireEvent("iframe");
		};

		slide.handleCompleteAnimateOut = function (type, args, obj) {
			Dom.setStyle(obj.overlay.element, "visibility", "hidden");

			obj.overlay.cfg.setProperty("xy", [x, y]);
			obj.animateOutCompleteEvent.fire();
		};

		slide.init();
		return slide;
	};

	ContainerEffect.prototype = {
		init: function () {
			this.beforeAnimateInEvent = this.createEvent("beforeAnimateIn");
			this.beforeAnimateInEvent.signature = CustomEvent.LIST;
			this.beforeAnimateOutEvent = this.createEvent("beforeAnimateOut");
			this.beforeAnimateOutEvent.signature = CustomEvent.LIST;
			this.animateInCompleteEvent = this.createEvent("animateInComplete");
			this.animateInCompleteEvent.signature = CustomEvent.LIST;
			this.animateOutCompleteEvent = this.createEvent("animateOutComplete");
			this.animateOutCompleteEvent.signature = CustomEvent.LIST;
			this.animIn = new this.animClass(this.targetElement, this.attrIn.attributes, this.attrIn.duration, this.attrIn.method);
			this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
			this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
			this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, this);
			this.animOut = new this.animClass(this.targetElement, this.attrOut.attributes, this.attrOut.duration, this.attrOut.method);
			this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
			this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
			this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, this);
		},

		animateIn: function () {
			this.beforeAnimateInEvent.fire();
			this.animIn.animate();
		},

		animateOut: function () {
			this.beforeAnimateOutEvent.fire();
			this.animOut.animate();
		},

		handleStartAnimateIn: function (type, args, obj) { },
		handleTweenAnimateIn: function (type, args, obj) { },
		handleCompleteAnimateIn: function (type, args, obj) { },
		handleStartAnimateOut: function (type, args, obj) { },
		handleTweenAnimateOut: function (type, args, obj) { },
		handleCompleteAnimateOut: function (type, args, obj) { },

		toString: function () {
			var output = "ContainerEffect";
			if (this.overlay) {
				output += " [" + this.overlay.toString() + "]";
			}
			return output;
		}
	};

	YAHOO.lang.augmentProto(ContainerEffect, YAHOO.util.EventProvider);

})();
YAHOO.register("container_core", YAHOO.widget.Module, {version: "2.3.0", build: "442"});
