/**
 * @preserve jquery.layout 1.3.0 - Release Candidate 30.62
 * $Date: 2012-08-04 08:00:00 (Thu, 23 Aug 2012) $
 * $Rev: 303006 $
 *
 * Copyright (c) 2012 
 *   Fabrizio Balliano (http://www.fabrizioballiano.net)
 *   Kevin Dalman (http://allpro.net)
 *
 * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
 * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
 *
 * Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.62
 * NOTE: This is a short-term release to patch a couple of bugs.
 * These bugs are listed as officially fixed in RC30.7, which will be released shortly.
 *
 * Docs: http://layout.jquery-dev.net/documentation.html
 * Tips: http://layout.jquery-dev.net/tips.html
 * Help: http://groups.google.com/group/jquery-ui-layout
 */

/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html
 * {!Object}	non-nullable type (never NULL)
 * {?string}	nullable type (sometimes NULL) - default for {Object}
 * {number=}	optional parameter
 * {*}			ALL types
 */

// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars

;(function ($) {

// alias Math methods - used a lot!
var	min		= Math.min
,	max		= Math.max
,	round	= Math.floor

,	isStr	=  function (v) { return $.type(v) === "string"; }

,	runPluginCallbacks = function (Instance, a_fn) {
		if ($.isArray(a_fn))
			for (var i=0, c=a_fn.length; i<c; i++) {
				var fn = a_fn[i];
				try {
					if (isStr(fn)) // 'name' of a function
						fn = eval(fn);
					if ($.isFunction(fn))
						fn( Instance );
				} catch (ex) {}
			}
	}

;


/*
 *	GENERIC $.layout METHODS - used by all layouts
 */
$.layout = {

	version:	"1.3.rc30.62"
,	revision:	0.033006 // 1.3.0 final = 1.0300 - major(n+).minor(nn)+patch(nn+)

	// can update code here if $.browser is phased out
,	browser: {
		mozilla:	!!$.browser.mozilla
	,	webkit:		!!$.browser.webkit || !!$.browser.safari // webkit = jQ 1.4
	,	msie:		!!$.browser.msie
	,	isIE6:		$.browser.msie && $.browser.version == 6
	,	boxModel:	$.support.boxModel !== false || !$.browser.msie // ONLY IE reverts to old box-model - update for older jQ onReady
	,	version:	$.browser.version // not used in Layout core, but may be used by plugins
	}

	// *PREDEFINED* EFFECTS & DEFAULTS 
	// MUST list effect here - OR MUST set an fxSettings option (can be an empty hash: {})
,	effects: {

	//	Pane Open/Close Animations
		slide: {
			all:	{ duration:  "fast"	} // eg: duration: 1000, easing: "easeOutBounce"
		,	north:	{ direction: "up"	}
		,	south:	{ direction: "down"	}
		,	east:	{ direction: "right"}
		,	west:	{ direction: "left"	}
		}
	,	drop: {
			all:	{ duration:  "slow"	}
		,	north:	{ direction: "up"	}
		,	south:	{ direction: "down"	}
		,	east:	{ direction: "right"}
		,	west:	{ direction: "left"	}
		}
	,	scale: {
			all:	{ duration:	"fast"	}
		}
	//	these are not recommended, but can be used
	,	blind:		{}
	,	clip:		{}
	,	explode:	{}
	,	fade:		{}
	,	fold:		{}
	,	puff:		{}

	//	Pane Resize Animations
	,	size: {
			all:	{ easing:	"swing"	}
		}
	}

	// INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
,	config: {
		optionRootKeys:	"effects,panes,north,south,west,east,center".split(",")
	,	allPanes:		"north,south,west,east,center".split(",")
	,	borderPanes:	"north,south,west,east".split(",")
	,	oppositeEdge: {
			north:	"south"
		,	south:	"north"
		,	east: 	"west"
		,	west: 	"east"
		}
	//	offscreen data
	,	offscreenCSS:	{ left: "-99999px", right: "auto" } // used by hide/close if useOffscreenClose=true
	,	offscreenReset:	"offscreenReset" // key used for data
	//	CSS used in multiple places
	,	hidden:		{ visibility: "hidden" }
	,	visible:	{ visibility: "visible" }
	//	layout element settings
	,	resizers: {
			cssReq: {
				position: 	"absolute"
			,	padding: 	0
			,	margin: 	0
			,	fontSize:	"1px"
			,	textAlign:	"left"	// to counter-act "center" alignment!
			,	overflow: 	"hidden" // prevent toggler-button from overflowing
			//	SEE $.layout.defaults.zIndexes.resizer_normal
			}
		,	cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
				background: "#DDD"
			,	border:		"none"
			}
		}
	,	togglers: {
			cssReq: {
				position: 	"absolute"
			,	display: 	"block"
			,	padding: 	0
			,	margin: 	0
			,	overflow:	"hidden"
			,	textAlign:	"center"
			,	fontSize:	"1px"
			,	cursor: 	"pointer"
			,	zIndex: 	1
			}
		,	cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
				background: "#AAA"
			}
		}
	,	content: {
			cssReq: {
				position:	"relative" /* contain floated or positioned elements */
			}
		,	cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
				overflow:	"auto"
			,	padding:	"10px"
			}
		,	cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div
				overflow:	"hidden"
			,	padding:	0
			}
		}
	,	panes: { // defaults for ALL panes - overridden by 'per-pane settings' below
			cssReq: {
				position: 	"absolute"
			,	margin:		0
			//	$.layout.defaults.zIndexes.pane_normal
			}
		,	cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
				padding:	"10px"
			,	background:	"#FFF"
			,	border:		"1px solid #BBB"
			,	overflow:	"auto"
			}
		}
	,	north: {
			side:			"Top"
		,	sizeType:		"Height"
		,	dir:			"horz"
		,	cssReq: {
				top: 		0
			,	bottom: 	"auto"
			,	left: 		0
			,	right: 		0
			,	width: 		"auto"
			//	height: 	DYNAMIC
			}
		}
	,	south: {
			side:			"Bottom"
		,	sizeType:		"Height"
		,	dir:			"horz"
		,	cssReq: {
				top: 		"auto"
			,	bottom: 	0
			,	left: 		0
			,	right: 		0
			,	width: 		"auto"
			//	height: 	DYNAMIC
			}
		}
	,	east: {
			side:			"Right"
		,	sizeType:		"Width"
		,	dir:			"vert"
		,	cssReq: {
				left: 		"auto"
			,	right: 		0
			,	top: 		"auto" // DYNAMIC
			,	bottom: 	"auto" // DYNAMIC
			,	height: 	"auto"
			//	width: 		DYNAMIC
			}
		}
	,	west: {
			side:			"Left"
		,	sizeType:		"Width"
		,	dir:			"vert"
		,	cssReq: {
				left: 		0
			,	right: 		"auto"
			,	top: 		"auto" // DYNAMIC
			,	bottom: 	"auto" // DYNAMIC
			,	height: 	"auto"
			//	width: 		DYNAMIC
			}
		}
	,	center: {
			dir:			"center"
		,	cssReq: {
				left: 		"auto" // DYNAMIC
			,	right: 		"auto" // DYNAMIC
			,	top: 		"auto" // DYNAMIC
			,	bottom: 	"auto" // DYNAMIC
			,	height: 	"auto"
			,	width: 		"auto"
			}
		}
	}

	// CALLBACK FUNCTION NAMESPACE - used to store reusable callback functions
,	callbacks: {}

,	getParentPaneElem: function (el) {
		// must pass either a container or pane element
		var $el = $(el)
		,	layout = $el.data("layout") || $el.data("parentLayout");
		if (layout) {
			var $cont = layout.container;
			// see if this container is directly-nested inside an outer-pane
			if ($cont.data("layoutPane")) return $cont;
			var $pane = $cont.closest("."+ $.layout.defaults.panes.paneClass);
			// if a pane was found, return it
			if ($pane.data("layoutPane")) return $pane;
		}
		return null;
	}

,	getParentPaneInstance: function (el) {
		// must pass either a container or pane element
		var $pane = $.layout.getParentPaneElem(el);
		return $pane ? $pane.data("layoutPane") : null;
	}

,	getParentLayoutInstance: function (el) {
		// must pass either a container or pane element
		var $pane = $.layout.getParentPaneElem(el);
		return $pane ? $pane.data("parentLayout") : null;
	}

,	getEventObject: function (evt) {
		return typeof evt === "object" && evt.stopPropagation ? evt : null;
	}
,	parsePaneName: function (evt_or_pane) {
		// getEventObject() automatically calls .stopPropagation(), WHICH MUST BE DONE!
		var evt = $.layout.getEventObject( evt_or_pane );
		if (evt) {
			// ALWAYS stop propagation of events triggered in Layout!
			evt.stopPropagation();
			return $(this).data("layoutEdge");
		}
		else
			return evt_or_pane;
	}


	// LAYOUT-PLUGIN REGISTRATION
	// more plugins can added beyond this default list
,	plugins: {
		draggable:		!!$.fn.draggable // resizing
	,	effects: {
			core:		!!$.effects		// animimations (specific effects tested by initOptions)
		,	slide:		$.effects && $.effects.slide // default effect
		}
	}

//	arrays of plugin or other methods to be triggered for events in *each layout* - will be passed 'Instance'
,	onCreate:	[]	// runs when layout is just starting to be created - right after options are set
,	onLoad:		[]	// runs after layout container and global events init, but before initPanes is called
,	onReady:	[]	// runs after initialization *completes* - ie, after initPanes completes successfully
,	onDestroy:	[]	// runs after layout is destroyed
,	onUnload:	[]	// runs after layout is destroyed OR when page unloads
,	afterOpen:	[]	// runs after setAsOpen() completes
,	afterClose:	[]	// runs after setAsClosed() completes

	/*
	*	GENERIC UTILITY METHODS
	*/

	// calculate and return the scrollbar width, as an integer
,	scrollbarWidth:		function () { return window.scrollbarWidth  || $.layout.getScrollbarSize('width'); }
,	scrollbarHeight:	function () { return window.scrollbarHeight || $.layout.getScrollbarSize('height'); }
,	getScrollbarSize:	function (dim) {
		var $c	= $('<div style="position: absolute; top: -10000px; left: -10000px; width: 100px; height: 100px; overflow: scroll;"></div>').appendTo("body");
		var d	= { width: $c.width() - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight };
		$c.remove();
		window.scrollbarWidth	= d.width;
		window.scrollbarHeight	= d.height;
		return dim.match(/^(width|height)$/) ? d[dim] : d;
	}


	/**
	* Returns hash container 'display' and 'visibility'
	*
	* @see	$.swap() - swaps CSS, runs callback, resets CSS
	*/
,	showInvisibly: function ($E, force) {
		if ($E && $E.length && (force || $E.css('display') === "none")) { // only if not *already hidden*
			var s = $E[0].style
				// save ONLY the 'style' props because that is what we must restore
			,	CSS = { display: s.display || '', visibility: s.visibility || '' };
			// show element 'invisibly' so can be measured
			$E.css({ display: "block", visibility: "hidden" });
			return CSS;
		}
		return {};
	}

	/**
	* Returns data for setting size of an element (container or a pane).
	*
	* @see  _create(), onWindowResize() for container, plus others for pane
	* @return JSON  Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc
	*/
,	getElementDimensions: function ($E) {
		var
			d	= {}			// dimensions hash
		,	x	= d.css = {}	// CSS hash
		,	i	= {}			// TEMP insets
		,	b, p				// TEMP border, padding
		,	N	= $.layout.cssNum
		,	off = $E.offset()
		;
		d.offsetLeft = off.left;
		d.offsetTop  = off.top;

		$.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge
			b = x["border" + e] = $.layout.borderWidth($E, e);
			p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e);
			i[e] = b + p; // total offset of content from outer side
			d["inset"+ e] = p;	// eg: insetLeft = paddingLeft
		});

		d.offsetWidth	= $E.innerWidth();	// offsetWidth is used in calc when doing manual resize
		d.offsetHeight	= $E.innerHeight();	// ditto
		d.outerWidth	= $E.outerWidth();
		d.outerHeight	= $E.outerHeight();
		d.innerWidth	= max(0, d.outerWidth  - i.Left - i.Right);
		d.innerHeight	= max(0, d.outerHeight - i.Top  - i.Bottom);

		x.width		= $E.width();
		x.height	= $E.height();
		x.top		= N($E,"top",true);
		x.bottom	= N($E,"bottom",true);
		x.left		= N($E,"left",true);
		x.right		= N($E,"right",true);

		//d.visible	= $E.is(":visible");// && x.width > 0 && x.height > 0;

		return d;
	}

,	getElementCSS: function ($E, list) {
		var
			CSS	= {}
		,	style	= $E[0].style
		,	props	= list.split(",")
		,	sides	= "Top,Bottom,Left,Right".split(",")
		,	attrs	= "Color,Style,Width".split(",")
		,	p, s, a, i, j, k
		;
		for (i=0; i < props.length; i++) {
			p = props[i];
			if (p.match(/(border|padding|margin)$/))
				for (j=0; j < 4; j++) {
					s = sides[j];
					if (p === "border")
						for (k=0; k < 3; k++) {
							a = attrs[k];
							CSS[p+s+a] = style[p+s+a];
						}
					else
						CSS[p+s] = style[p+s];
				}
			else
				CSS[p] = style[p];
		};
		return CSS
	}

	/**
	* Return the innerWidth for the current browser/doctype
	*
	* @see  initPanes(), sizeMidPanes(), initHandles(), sizeHandles()
	* @param  {Array.<Object>}	$E  Must pass a jQuery object - first element is processed
	* @param  {number=}			outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized
	* @return {number}			Returns the innerWidth of the elem by subtracting padding and borders
	*/
,	cssWidth: function ($E, outerWidth) {
		// a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
		if (outerWidth <= 0) return 0;

		if (!$.layout.browser.boxModel) return outerWidth;

		// strip border and padding from outerWidth to get CSS Width
		var b = $.layout.borderWidth
		,	n = $.layout.cssNum
		,	W = outerWidth
				- b($E, "Left")
				- b($E, "Right")
				- n($E, "paddingLeft")		
				- n($E, "paddingRight");

		return max(0,W);
	}

	/**
	* Return the innerHeight for the current browser/doctype
	*
	* @see  initPanes(), sizeMidPanes(), initHandles(), sizeHandles()
	* @param  {Array.<Object>}	$E  Must pass a jQuery object - first element is processed
	* @param  {number=}			outerHeight  (optional) Can pass a width, allowing calculations BEFORE element is resized
	* @return {number}			Returns the innerHeight of the elem by subtracting padding and borders
	*/
,	cssHeight: function ($E, outerHeight) {
		// a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
		if (outerHeight <= 0) return 0;

		if (!$.layout.browser.boxModel) return outerHeight;

		// strip border and padding from outerHeight to get CSS Height
		var b = $.layout.borderWidth
		,	n = $.layout.cssNum
		,	H = outerHeight
			- b($E, "Top")
			- b($E, "Bottom")
			- n($E, "paddingTop")
			- n($E, "paddingBottom");

		return max(0,H);
	}

	/**
	* Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist
	*
	* @see  Called by many methods
	* @param {Array.<Object>}	$E					Must pass a jQuery object - first element is processed
	* @param {string}			prop				The name of the CSS property, eg: top, width, etc.
	* @param {boolean=}			[allowAuto=false]	true = return 'auto' if that is value; false = return 0
	* @return {(string|number)}						Usually used to get an integer value for position (top, left) or size (height, width)
	*/
,	cssNum: function ($E, prop, allowAuto) {
		if (!$E.jquery) $E = $($E);
		var CSS = $.layout.showInvisibly($E)
		,	p	= $.css($E[0], prop, true)
		,	v	= allowAuto && p=="auto" ? p : (parseInt(p, 10) || 0);
		$E.css( CSS ); // RESET
		return v;
	}

,	borderWidth: function (el, side) {
		if (el.jquery) el = el[0];
		var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left
		return $.css(el, b+"Style", true) === "none" ? 0 : (parseInt($.css(el, b+"Width", true), 10) || 0);
	}

	/**
	* Mouse-tracking utility - FUTURE REFERENCE
	*
	* init: if (!window.mouse) {
	*			window.mouse = { x: 0, y: 0 };
	*			$(document).mousemove( $.layout.trackMouse );
	*		}
	*
	* @param {Object}		evt
	*
,	trackMouse: function (evt) {
		window.mouse = { x: evt.clientX, y: evt.clientY };
	}
	*/

	/**
	* SUBROUTINE for preventPrematureSlideClose option
	*
	* @param {Object}		evt
	* @param {Object=}		el
	*/
,	isMouseOverElem: function (evt, el) {
		var
			$E	= $(el || this)
		,	d	= $E.offset()
		,	T	= d.top
		,	L	= d.left
		,	R	= L + $E.outerWidth()
		,	B	= T + $E.outerHeight()
		,	x	= evt.pageX	// evt.clientX ?
		,	y	= evt.pageY	// evt.clientY ?
		;
		// if X & Y are < 0, probably means is over an open SELECT
		return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B));
	}

	/**
	* Message/Logging Utility
	*
	* @example $.layout.msg("My message");				// log text
	* @example $.layout.msg("My message", true);		// alert text
	* @example $.layout.msg({ foo: "bar" }, "Title");	// log hash-data, with custom title
	* @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR-
	* @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data
	*
	* @param {(Object|string)}			info			String message OR Hash/Array
	* @param {(Boolean|string|Object)=}	[popup=false]	True means alert-box - can be skipped
	* @param {(Object|string)=}			[debugTitle=""]	Title for Hash data - can be skipped
	* @param {Object=}					[debugOpts]		Extra options for debug output
	*/
,	msg: function (info, popup, debugTitle, debugOpts) {
		if ($.isPlainObject(info) && window.debugData) {
			if (typeof popup === "string") {
				debugOpts	= debugTitle;
				debugTitle	= popup;
			}
			else if (typeof debugTitle === "object") {
				debugOpts	= debugTitle;
				debugTitle	= null;
			}
			var t = debugTitle || "log( <object> )"
			,	o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts);
			if (popup === true || o.display)
				debugData( info, t, o );
			else if (window.console)
				console.log(debugData( info, t, o ));
		}
		else if (popup)
			alert(info);
		else if (window.console)
			console.log(info);
		else {
			var id	= "#layoutLogger"
			,	$l = $(id);
			if (!$l.length)
				$l = createLog();
			$l.children("ul").append('<li style="padding: 4px 10px; margin: 0; border-top: 1px solid #CCC;">'+ info.replace(/\</g,"&lt;").replace(/\>/g,"&gt;") +'</li>');
		}

		function createLog () {
			var pos = $.support.fixedPosition ? 'fixed' : 'absolute'
			,	$e = $('<div id="layoutLogger" style="position: '+ pos +'; top: 5px; z-index: 999999; max-width: 25%; overflow: hidden; border: 1px solid #000; border-radius: 5px; background: #FBFBFB; box-shadow: 0 2px 10px rgba(0,0,0,0.3);">'
				+	'<div style="font-size: 13px; font-weight: bold; padding: 5px 10px; background: #F6F6F6; border-radius: 5px 5px 0 0; cursor: move;">'
				+	'<span style="float: right; padding-left: 7px; cursor: pointer;" title="Remove Console" onclick="$(this).closest(\'#layoutLogger\').remove()">X</span>Layout console.log</div>'
				+	'<ul style="font-size: 13px; font-weight: none; list-style: none; margin: 0; padding: 0 0 2px;"></ul>'
				+ '</div>'
				).appendTo("body");
			$e.css('left', $(window).width() - $e.outerWidth() - 5)
			if ($.ui.draggable) $e.draggable({ handle: ':first-child' });
			return $e;
		};
	}

};

// DEFAULT OPTIONS
$.layout.defaults = {
/*
 *	LAYOUT & LAYOUT-CONTAINER OPTIONS
 *	- none of these options are applicable to individual panes
 */
	name:						""			// Not required, but useful for buttons and used for the state-cookie
,	containerSelector:			""			// ONLY used when specifying a childOptions - to find container-element that is NOT directly-nested
,	containerClass:				"ui-layout-container" // layout-container element
,	scrollToBookmarkOnLoad:		true		// after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark)
,	resizeWithWindow:			true		// bind thisLayout.resizeAll() to the window.resize event
,	resizeWithWindowDelay:		200			// delay calling resizeAll because makes window resizing very jerky
,	resizeWithWindowMaxDelay:	0			// 0 = none - force resize every XX ms while window is being resized
,	onresizeall_start:			null		// CALLBACK when resizeAll() STARTS	- NOT pane-specific
,	onresizeall_end:			null		// CALLBACK when resizeAll() ENDS	- NOT pane-specific
,	onload_start:				null		// CALLBACK when Layout inits - after options initialized, but before elements
,	onload_end:					null		// CALLBACK when Layout inits - after EVERYTHING has been initialized
,	onunload_start:				null		// CALLBACK when Layout is destroyed OR onWindowUnload
,	onunload_end:				null		// CALLBACK when Layout is destroyed OR onWindowUnload
,	initPanes:					true		// false = DO NOT initialize the panes onLoad - will init later
,	showErrorMessages:			true		// enables fatal error messages to warn developers of common errors
,	showDebugMessages:			false		// display console-and-alert debug msgs - IF this Layout version _has_ debugging code!
//	Changing this zIndex value will cause other zIndex values to automatically change
,	zIndex:						null		// the PANE zIndex - resizers and masks will be +1
//	DO NOT CHANGE the zIndex values below unless you clearly understand their relationships
,	zIndexes: {								// set _default_ z-index values here...
		pane_normal:			0			// normal z-index for panes
	,	content_mask:			1			// applied to overlays used to mask content INSIDE panes during resizing
	,	resizer_normal:			2			// normal z-index for resizer-bars
	,	pane_sliding:			100			// applied to *BOTH* the pane and its resizer when a pane is 'slid open'
	,	pane_animate:			1000		// applied to the pane when being animated - not applied to the resizer
	,	resizer_drag:			10000		// applied to the CLONED resizer-bar when being 'dragged'
	}
,	errors: {
		pane:					"pane"		// description of "layout pane element" - used only in error messages
	,	selector:				"selector"	// description of "jQuery-selector" - used only in error messages
	,	addButtonError:			"Error Adding Button \n\nInvalid "
	,	containerMissing:		"UI Layout Initialization Error\n\nThe specified layout-container does not exist."
	,	centerPaneMissing:		"UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element."
	,	noContainerHeight:		"UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!"
	,	callbackError:			"UI Layout Callback Error\n\nThe EVENT callback is not a valid function."
	}
/*
 *	PANE DEFAULT SETTINGS
 *	- settings under the 'panes' key become the default settings for *all panes*
 *	- ALL pane-options can also be set specifically for each panes, which will override these 'default values'
 */
,	panes: { // default options for 'all panes' - will be overridden by 'per-pane settings'
		applyDemoStyles: 		false		// NOTE: renamed from applyDefaultStyles for clarity
	,	closable:				true		// pane can open & close
	,	resizable:				true		// when open, pane can be resized 
	,	slidable:				true		// when closed, pane can 'slide open' over other panes - closes on mouse-out
	,	initClosed:				false		// true = init pane as 'closed'
	,	initHidden: 			false 		// true = init pane as 'hidden' - no resizer-bar/spacing
	//	SELECTORS
	//,	paneSelector:			""			// MUST be pane-specific - jQuery selector for pane
	,	contentSelector:		".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane!
	,	contentIgnoreSelector:	".ui-layout-ignore"	// element(s) to 'ignore' when measuring 'content'
	,	findNestedContent:		false		// true = $P.find(contentSelector), false = $P.children(contentSelector)
	//	GENERIC ROOT-CLASSES - for auto-generated classNames
	,	paneClass:				"ui-layout-pane"	// Layout Pane
	,	resizerClass:			"ui-layout-resizer"	// Resizer Bar
	,	togglerClass:			"ui-layout-toggler"	// Toggler Button
	,	buttonClass:			"ui-layout-button"	// CUSTOM Buttons	- eg: '[ui-layout-button]-toggle/-open/-close/-pin'
	//	ELEMENT SIZE & SPACING
	//,	size:					100			// MUST be pane-specific -initial size of pane
	,	minSize:				0			// when manually resizing a pane
	,	maxSize:				0			// ditto, 0 = no limit
	,	spacing_open:			6			// space between pane and adjacent panes - when pane is 'open'
	,	spacing_closed:			6			// ditto - when pane is 'closed'
	,	togglerLength_open:		50			// Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides
	,	togglerLength_closed: 	50			// 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden'
	,	togglerAlign_open:		"center"	// top/left, bottom/right, center, OR...
	,	togglerAlign_closed:	"center"	// 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right
	,	togglerContent_open:	""			// text or HTML to put INSIDE the toggler
	,	togglerContent_closed:	""			// ditto
	//	RESIZING OPTIONS
	,	resizerDblClickToggle:	true		// 
	,	autoResize:				true		// IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes
	,	autoReopen:				true		// IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed
	,	resizerDragOpacity:		1			// option for ui.draggable
	//,	resizerCursor:			""			// MUST be pane-specific - cursor when over resizer-bar
	,	maskContents:			false		// true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES
	,	maskObjects:			false		// true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask
	,	maskZindex:				null		// will override zIndexes.content_mask if specified - not applicable to iframe-panes
	,	resizingGrid:			false		// grid size that the resizers will snap-to during resizing, eg: [20,20]
	,	livePaneResizing:		false		// true = LIVE Resizing as resizer is dragged
	,	liveContentResizing:	false		// true = re-measure header/footer heights as resizer is dragged
	,	liveResizingTolerance:	1			// how many px change before pane resizes, to control performance
	//	SLIDING OPTIONS
	,	sliderCursor:			"pointer"	// cursor when resizer-bar will trigger 'sliding'
	,	slideTrigger_open:		"click"		// click, dblclick, mouseenter
	,	slideTrigger_close:		"mouseleave"// click, mouseleave
	,	slideDelay_open:		300			// applies only for mouseenter event - 0 = instant open
	,	slideDelay_close:		300			// applies only for mouseleave event (300ms is the minimum!)
	,	hideTogglerOnSlide:		false		// when pane is slid-open, should the toggler show?
	,	preventQuickSlideClose:	$.layout.browser.webkit // Chrome triggers slideClosed as it is opening
	,	preventPrematureSlideClose: false	// handle incorrect mouseleave trigger, like when over a SELECT-list in IE
	//	PANE-SPECIFIC TIPS & MESSAGES
	,	tips: {
			Open:				"Open"		// eg: "Open Pane"
		,	Close:				"Close"
		,	Resize:				"Resize"
		,	Slide:				"Slide Open"
		,	Pin:				"Pin"
		,	Unpin:				"Un-Pin"
		,	noRoomToOpen:		"Not enough room to show this panel."	// alert if user tries to open a pane that cannot
		,	minSizeWarning:		"Panel has reached its minimum size"	// displays in browser statusbar
		,	maxSizeWarning:		"Panel has reached its maximum size"	// ditto
		}
	//	HOT-KEYS & MISC
	,	showOverflowOnHover:	false		// will bind allowOverflow() utility to pane.onMouseOver
	,	enableCursorHotkey:		true		// enabled 'cursor' hotkeys
	//,	customHotkey:			""			// MUST be pane-specific - EITHER a charCode OR a character
	,	customHotkeyModifier:	"SHIFT"		// either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT'
	//	PANE ANIMATION
	//	NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed
	,	fxName:					"slide" 	// ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size'
	,	fxSpeed:				null		// slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration
	,	fxSettings:				{}			// can be passed, eg: { easing: "easeOutBounce", duration: 1500 }
	,	fxOpacityFix:			true		// tries to fix opacity in IE to restore anti-aliasing after animation
	,	animatePaneSizing:		false		// true = animate resizing after dragging resizer-bar OR sizePane() is called
	/*  NOTE: Action-specific FX options are auto-generated from the options above if not specifically set:
		fxName_open:			"slide"		// 'Open' pane animation
		fnName_close:			"slide"		// 'Close' pane animation
		fxName_size:			"slide"		// 'Size' pane animation - when animatePaneSizing = true
		fxSpeed_open:			null
		fxSpeed_close:			null
		fxSpeed_size:			null
		fxSettings_open:		{}
		fxSettings_close:		{}
		fxSettings_size:		{}
	*/
	//	CHILD/NESTED LAYOUTS
	,	childOptions:			null		// Layout-options for nested/child layout - even {} is valid as options
	,	initChildLayout:		true		// true = child layout will be created as soon as _this_ layout completes initialization
	,	destroyChildLayout:		true		// true = destroy child-layout if this pane is destroyed
	,	resizeChildLayout:		true		// true = trigger child-layout.resizeAll() when this pane is resized
	//	EVENT TRIGGERING
	,	triggerEventsOnLoad:	false		// true = trigger onopen OR onclose callbacks when layout initializes
	,	triggerEventsDuringLiveResize: true	// true = trigger onresize callback REPEATEDLY if livePaneResizing==true
	//	PANE CALLBACKS
	,	onshow_start:			null		// CALLBACK when pane STARTS to Show	- BEFORE onopen/onhide_start
	,	onshow_end:				null		// CALLBACK when pane ENDS being Shown	- AFTER  onopen/onhide_end
	,	onhide_start:			null		// CALLBACK when pane STARTS to Close	- BEFORE onclose_start
	,	onhide_end:				null		// CALLBACK when pane ENDS being Closed	- AFTER  onclose_end
	,	onopen_start:			null		// CALLBACK when pane STARTS to Open
	,	onopen_end:				null		// CALLBACK when pane ENDS being Opened
	,	onclose_start:			null		// CALLBACK when pane STARTS to Close
	,	onclose_end:			null		// CALLBACK when pane ENDS being Closed
	,	onresize_start:			null		// CALLBACK when pane STARTS being Resized ***FOR ANY REASON***
	,	onresize_end:			null		// CALLBACK when pane ENDS being Resized ***FOR ANY REASON***
	,	onsizecontent_start:	null		// CALLBACK when sizing of content-element STARTS
	,	onsizecontent_end:		null		// CALLBACK when sizing of content-element ENDS
	,	onswap_start:			null		// CALLBACK when pane STARTS to Swap
	,	onswap_end:				null		// CALLBACK when pane ENDS being Swapped
	,	ondrag_start:			null		// CALLBACK when pane STARTS being ***MANUALLY*** Resized
	,	ondrag_end:				null		// CALLBACK when pane ENDS being ***MANUALLY*** Resized
	}
/*
 *	PANE-SPECIFIC SETTINGS
 *	- options listed below MUST be specified per-pane - they CANNOT be set under 'panes'
 *	- all options under the 'panes' key can also be set specifically for any pane
 *	- most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane
 */
,	north: {
		paneSelector:			".ui-layout-north"
	,	size:					"auto"		// eg: "auto", "30%", .30, 200
	,	resizerCursor:			"n-resize"	// custom = url(myCursor.cur)
	,	customHotkey:			""			// EITHER a charCode (43) OR a character ("o")
	}
,	south: {
		paneSelector:			".ui-layout-south"
	,	size:					"auto"
	,	resizerCursor:			"s-resize"
	,	customHotkey:			""
	}
,	east: {
		paneSelector:			".ui-layout-east"
	,	size:					200
	,	resizerCursor:			"e-resize"
	,	customHotkey:			""
	}
,	west: {
		paneSelector:			".ui-layout-west"
	,	size:					200
	,	resizerCursor:			"w-resize"
	,	customHotkey:			""
	}
,	center: {
		paneSelector:			".ui-layout-center"
	,	minWidth:				0
	,	minHeight:				0
	}
};

$.layout.optionsMap = {
	// layout/global options - NOT pane-options
	layout: ("stateManagement,effects,zIndexes,errors,"
	+	"name,zIndex,scrollToBookmarkOnLoad,showErrorMessages,"
	+	"resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,"
	+	"onresizeall,onresizeall_start,onresizeall_end,onload,onunload").split(",")
//	borderPanes: [ ALL options that are NOT specified as 'layout' ]
	// default.panes options that apply to the center-pane (most options apply _only_ to border-panes)
,	center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad,"
	+	"showOverflowOnHover,maskContents,maskObjects,liveContentResizing,"
	+	"childOptions,initChildLayout,resizeChildLayout,destroyChildLayout,"
	+	"onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",")
	// options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key
,	noDefault: ("paneSelector,resizerCursor,customHotkey").split(",")
};

/**
 * Processes options passed in converts flat-format data into subkey (JSON) format
 * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName
 * Plugins may also call this method so they can transform their own data
 *
 * @param  {!Object}	hash	Data/options passed by user - may be a single level or nested levels
 * @return {Object}				Returns hash of minWidth & minHeight
 */
$.layout.transformData = function (hash) {
	var	json = { panes: {}, center: {} } // init return object
	,	data, branch, optKey, keys, key, val, i, c;

	if (typeof hash !== "object") return json; // no options passed

	// convert all 'flat-keys' to 'sub-key' format
	for (optKey in hash) {
		branch	= json;
		data	= $.layout.optionsMap.layout;
		val		= hash[ optKey ];
		keys	= optKey.split("__"); // eg: west__size or north__fxSettings__duration
		c		= keys.length - 1;
		// convert underscore-delimited to subkeys
		for (i=0; i <= c; i++) {
			key = keys[i];
			if (i === c)
				branch[key] = val;
			else if (!branch[key])
				branch[key] = {}; // create the subkey
			// recurse to sub-key for next loop - if not done
			branch = branch[key];
		}
	}

	return json;
};

// INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
$.layout.backwardCompatibility = {
	// data used by renameOldOptions()
	map: {
	//	OLD Option Name:			NEW Option Name
		applyDefaultStyles:			"applyDemoStyles"
	,	resizeNestedLayout:			"resizeChildLayout"
	,	resizeWhileDragging:		"livePaneResizing"
	,	resizeContentWhileDragging:	"liveContentResizing"
	,	triggerEventsWhileDragging:	"triggerEventsDuringLiveResize"
	,	maskIframesOnResize:		"maskContents"
	,	useStateCookie:				"stateManagement.enabled"
	,	"cookie.autoLoad":			"stateManagement.autoLoad"
	,	"cookie.autoSave":			"stateManagement.autoSave"
	,	"cookie.keys":				"stateManagement.stateKeys"
	,	"cookie.name":				"stateManagement.cookie.name"
	,	"cookie.domain":			"stateManagement.cookie.domain"
	,	"cookie.path":				"stateManagement.cookie.path"
	,	"cookie.expires":			"stateManagement.cookie.expires"
	,	"cookie.secure":			"stateManagement.cookie.secure"
	//	OLD Language options
	,	noRoomToOpenTip:			"tips.noRoomToOpen"
	,	togglerTip_open:			"tips.Close"	// open   = Close
	,	togglerTip_closed:			"tips.Open"		// closed = Open
	,	resizerTip:					"tips.Resize"
	,	sliderTip:					"tips.Slide"
	}

/**
* @param {Object}	opts
*/
,	renameOptions: function (opts) {
		var map = $.layout.backwardCompatibility.map
		,	oldData, newData, value
		;
		for (var itemPath in map) {
			oldData	= getBranch( itemPath );
			value	= oldData.branch[ oldData.key ];
			if (value !== undefined) {
				newData = getBranch( map[itemPath], true );
				newData.branch[ newData.key ] = value;
				delete oldData.branch[ oldData.key ];
			}
		}

		/**
		* @param {string}	path
		* @param {boolean=}	[create=false]	Create path if does not exist
		*/
		function getBranch (path, create) {
			var a = path.split(".") // split keys into array
			,	c = a.length - 1
			,	D = { branch: opts, key: a[c] } // init branch at top & set key (last item)
			,	i = 0, k, undef;
			for (; i<c; i++) { // skip the last key (data)
				k = a[i];
				if (D.branch[ k ] == undefined) { // child-key does not exist
					if (create) {
						D.branch = D.branch[ k ] = {}; // create child-branch
					}
					else // can't go any farther
						D.branch = {}; // branch is undefined
				}
				else
					D.branch = D.branch[ k ]; // get child-branch
			}
			return D;
		};
	}

/**
* @param {Object}	opts
*/
,	renameAllOptions: function (opts) {
		var ren = $.layout.backwardCompatibility.renameOptions;
		// rename root (layout) options
		ren( opts );
		// rename 'defaults' to 'panes'
		if (opts.defaults) {
			if (typeof opts.panes !== "object")
				opts.panes = {};
			$.extend(true, opts.panes, opts.defaults);
			delete opts.defaults;
		}
		// rename options in the the options.panes key
		if (opts.panes) ren( opts.panes );
		// rename options inside *each pane key*, eg: options.west
		$.each($.layout.config.allPanes, function (i, pane) {
			if (opts[pane]) ren( opts[pane] );
		});	
		return opts;
	}
};




/*	============================================================
 *	BEGIN WIDGET: $( selector ).layout( {options} );
 *	============================================================
 */
$.fn.layout = function (opts) {
	var

	// local aliases to global data
	browser	= $.layout.browser
,	_c		= $.layout.config

	// local aliases to utlity methods
,	cssW	= $.layout.cssWidth
,	cssH	= $.layout.cssHeight
,	elDims	= $.layout.getElementDimensions
,	elCSS	= $.layout.getElementCSS
,	evtObj	= $.layout.getEventObject
,	evtPane	= $.layout.parsePaneName

/**
 * options - populated by initOptions()
 */
,	options = $.extend(true, {}, $.layout.defaults)
,	effects	= options.effects = $.extend(true, {}, $.layout.effects)

/**
 * layout-state object
 */
,	state = {
		// generate unique ID to use for event.namespace so can unbind only events added by 'this layout'
		id:			"layout"+ $.now()	// code uses alias: sID
	,	initialized: false
	,	container:	{} // init all keys
	,	north:		{}
	,	south:		{}
	,	east:		{}
	,	west:		{}
	,	center:		{}
	}

/**
 * parent/child-layout pointers
 */
//,	hasParentLayout	= false	- exists ONLY inside Instance so can be set externally
,	children = {
		north:		null
	,	south:		null
	,	east:		null
	,	west:		null
	,	center:		null
	}

/*
 * ###########################
 *  INTERNAL HELPER FUNCTIONS
 * ###########################
 */

	/**
	* Manages all internal timers
	*/
,	timer = {
		data:	{}
	,	set:	function (s, fn, ms) { timer.clear(s); timer.data[s] = setTimeout(fn, ms); }
	,	clear:	function (s) { var t=timer.data; if (t[s]) {clearTimeout(t[s]); delete t[s];} }
	}

	/**
	* Alert or console.log a message - IF option is enabled.
	*
	* @param {(string|!Object)}	msg		Message (or debug-data) to display
	* @param {?boolean}			popup	True by default, means 'alert', false means use console.log
	* @param {?boolean}			debug	True means is a widget debugging message
	*/
,	_log = function (msg, popup, debug) {
		var o = options;
		if ((o.showErrorMessages && !debug) || (debug && o.showDebugMessages))
			$.layout.msg( o.name +' / '+ msg, (popup !== false) );
		return false;
	}

	/**
	* Executes a Callback function after a trigger event, like resize, open or close
	*
	* @param {string}			evtName			Name of the layout callback, eg "onresize_start"
	* @param {?string}			pane			This is passed only so we can pass the 'pane object' to the callback
	* @param {?string|?boolean}	skipBoundEvents	True = do not run events bound to the elements - only the callbacks set in options
	*/
,	_runCallbacks = function (evtName, pane, skipBoundEvents) {
		var	paneCB	= pane && isStr(pane)
		,	s		= paneCB ? state[pane] : state
		,	o		= paneCB ? options[pane] : options
		,	lName	= options.name
			// names like onopen and onopen_end separate are interchangeable in options...
		,	lng		= evtName + (evtName.match(/_/) ? "" : "_end")
		,	shrt	= lng.match(/_end$/) ? lng.substr(0, lng.length - 4) : ""
		,	fn		= o[lng] || o[shrt]
		,	retVal	= "NC" // NC = No Callback
		,	args	= []
		,	$P
		;
		if ( !paneCB && $.type(skipBoundEvents) !== 'boolean' )
			skipBoundEvents = pane; // allow pane param to be skipped for Layout callback

		// first trigger the callback set in the options
		if (fn) {
			try {
				// convert function name (string) to function object
				if (isStr( fn )) {
					if (fn.match(/,/)) {
						// function name cannot contain a comma, 
						// so must be a function name AND a parameter to pass
						args = fn.split(",")
						,	fn = eval(args[0]);
					}
					else // just the name of an external function?
						fn = eval(fn);
				}
				// execute the callback, if exists
				if ($.isFunction( fn )) {
					if (args.length)
						retVal = fn(args[1]); // pass the argument parsed from 'list'
					else if ( paneCB )
						// pass data: pane-name, pane-element, pane-state, pane-options, and layout-name
						retVal = fn( pane, $Ps[pane], s, o, lName );
					else // must be a layout/container callback - pass suitable info
						retVal = fn( Instance, s, o, lName );
				}
			}
			catch (ex) {
				_log( options.errors.callbackError.replace(/EVENT/, $.trim(pane +" "+ lng)), false );
			}
		}

		// trigger additional events bound directly to the pane
		if (!skipBoundEvents && retVal !== false) {
			if ( paneCB ) { // PANE events can be bound to each pane-elements
				$P	= $Ps[pane];
				o	= options[pane];
				s	= state[pane];
				$P.triggerHandler('layoutpane'+ lng, [ pane, $P, s, o, lName ]);
				if (shrt)
					$P.triggerHandler('layoutpane'+ shrt, [ pane, $P, s, o, lName ]);
			}
			else { // LAYOUT events can be bound to the container-element
				$N.triggerHandler('layout'+ lng, [ Instance, s, o, lName ]);
				if (shrt)
					$N.triggerHandler('layout'+ shrt, [ Instance, s, o, lName ]);
			}
		}

		// ALWAYS resizeChildLayout after a resize event - even during initialization
		if (evtName === "onresize_end" || evtName === "onsizecontent_end")
			resizeChildLayout(pane); 

		return retVal;
	}


	/**
	* cure iframe display issues in IE & other browsers
	*/
,	_fixIframe = function (pane) {
		if (browser.mozilla) return; // skip FireFox - it auto-refreshes iframes onShow
		var $P = $Ps[pane];
		// if the 'pane' is an iframe, do it
		if (state[pane].tagName === "IFRAME")
			$P.css(_c.hidden).css(_c.visible); 
		else // ditto for any iframes INSIDE the pane
			$P.find('IFRAME').css(_c.hidden).css(_c.visible);
	}

	/**
	* @param  {string}		pane		Can accept ONLY a 'pane' (east, west, etc)
	* @param  {number=}		outerSize	(optional) Can pass a width, allowing calculations BEFORE element is resized
	* @return {number}		Returns the innerHeight/Width of el by subtracting padding and borders
	*/
,	cssSize = function (pane, outerSize) {
		var fn = _c[pane].dir=="horz" ? cssH : cssW;
		return fn($Ps[pane], outerSize);
	}

	/**
	* @param  {string}		pane		Can accept ONLY a 'pane' (east, west, etc)
	* @return {Object}		Returns hash of minWidth & minHeight
	*/
,	cssMinDims = function (pane) {
		// minWidth/Height means CSS width/height = 1px
		var	$P	= $Ps[pane]
		,	dir	= _c[pane].dir
		,	d	= {
				minWidth:	1001 - cssW($P, 1000)
			,	minHeight:	1001 - cssH($P, 1000)
			}
		;
		if (dir === "horz") d.minSize = d.minHeight;
		if (dir === "vert") d.minSize = d.minWidth;
		return d;
	}

	// TODO: see if these methods can be made more useful...
	// TODO: *maybe* return cssW/H from these so caller can use this info

	/**
	* @param {(string|!Object)}		el
	* @param {number=}				outerWidth
	* @param {boolean=}				[autoHide=false]
	*/
,	setOuterWidth = function (el, outerWidth, autoHide) {
		var $E = el, w;
		if (isStr(el)) $E = $Ps[el]; // west
		else if (!el.jquery) $E = $(el);
		w = cssW($E, outerWidth);
		$E.css({ width: w });
		if (w > 0) {
			if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) {
				$E.show().data('autoHidden', false);
				if (!browser.mozilla) // FireFox refreshes iframes - IE does not
					// make hidden, then visible to 'refresh' display after animation
					$E.css(_c.hidden).css(_c.visible);
			}
		}
		else if (autoHide && !$E.data('autoHidden'))
			$E.hide().data('autoHidden', true);
	}

	/**
	* @param {(string|!Object)}		el
	* @param {number=}				outerHeight
	* @param {boolean=}				[autoHide=false]
	*/
,	setOuterHeight = function (el, outerHeight, autoHide) {
		var $E = el, h;
		if (isStr(el)) $E = $Ps[el]; // west
		else if (!el.jquery) $E = $(el);
		h = cssH($E, outerHeight);
		$E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent
		if (h > 0 && $E.innerWidth() > 0) {
			if (autoHide && $E.data('autoHidden')) {
				$E.show().data('autoHidden', false);
				if (!browser.mozilla) // FireFox refreshes iframes - IE does not
					$E.css(_c.hidden).css(_c.visible);
			}
		}
		else if (autoHide && !$E.data('autoHidden'))
			$E.hide().data('autoHidden', true);
	}

	/**
	* @param {(string|!Object)}		el
	* @param {number=}				outerSize
	* @param {boolean=}				[autoHide=false]
	*/
,	setOuterSize = function (el, outerSize, autoHide) {
		if (_c[pane].dir=="horz") // pane = north or south
			setOuterHeight(el, outerSize, autoHide);
		else // pane = east or west
			setOuterWidth(el, outerSize, autoHide);
	}


	/**
	* Converts any 'size' params to a pixel/integer size, if not already
	* If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated
	*
	/**
	* @param  {string}				pane
	* @param  {(string|number)=}	size
	* @param  {string=}				[dir]
	* @return {number}
	*/
,	_parseSize = function (pane, size, dir) {
		if (!dir) dir = _c[pane].dir;

		if (isStr(size) && size.match(/%/))
			size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal

		if (size === 0)
			return 0;
		else if (size >= 1)
			return parseInt(size, 10);

		var o = options, avail = 0;
		if (dir=="horz") // north or south or center.minHeight
			avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0);
		else if (dir=="vert") // east or west or center.minWidth
			avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0);

		if (size === -1) // -1 == 100%
			return avail;
		else if (size > 0) // percentage, eg: .25
			return round(avail * size);
		else if (pane=="center")
			return 0;
		else { // size < 0 || size=='auto' || size==Missing || size==Invalid
			// auto-size the pane
			var	dim	= (dir === "horz" ? "height" : "width")
			,	$P	= $Ps[pane]
			,	$C	= dim === 'height' ? $Cs[pane] : false
			,	vis	= $.layout.showInvisibly($P) // show pane invisibly if hidden
			,	szP	= $P.css(dim) // SAVE current pane size
			,	szC	= $C ? $C.css(dim) : 0 // SAVE current content size
			;
			$P.css(dim, "auto");
			if ($C) $C.css(dim, "auto");
			size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE
			$P.css(dim, szP).css(vis); // RESET size & visibility
			if ($C) $C.css(dim, szC);
			return size;
		}
	}

	/**
	* Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added
	*
	* @param  {(string|!Object)}	pane
	* @param  {boolean=}			[inclSpace=false]
	* @return {number}				Returns EITHER Width for east/west panes OR Height for north/south panes
	*/
,	getPaneSize = function (pane, inclSpace) {
		var 
			$P	= $Ps[pane]
		,	o	= options[pane]
		,	s	= state[pane]
		,	oSp	= (inclSpace ? o.spacing_open : 0)
		,	cSp	= (inclSpace ? o.spacing_closed : 0)
		;
		if (!$P || s.isHidden)
			return 0;
		else if (s.isClosed || (s.isSliding && inclSpace))
			return cSp;
		else if (_c[pane].dir === "horz")
			return $P.outerHeight() + oSp;
		else // dir === "vert"
			return $P.outerWidth() + oSp;
	}

	/**
	* Calculate min/max pane dimensions and limits for resizing
	*
	* @param  {string}		pane
	* @param  {boolean=}	[slide=false]
	*/
,	setSizeLimits = function (pane, slide) {
		if (!isInitialized()) return;
		var 
			o				= options[pane]
		,	s				= state[pane]
		,	c				= _c[pane]
		,	dir				= c.dir
		,	side			= c.side.toLowerCase()
		,	type			= c.sizeType.toLowerCase()
		,	isSliding		= (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param
		,	$P				= $Ps[pane]
		,	paneSpacing		= o.spacing_open
		//	measure the pane on the *opposite side* from this pane
		,	altPane			= _c.oppositeEdge[pane]
		,	altS			= state[altPane]
		,	$altP			= $Ps[altPane]
		,	altPaneSize		= (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth()))
		,	altPaneSpacing	= ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0)
		//	limitSize prevents this pane from 'overlapping' opposite pane
		,	containerSize	= (dir=="horz" ? sC.innerHeight : sC.innerWidth)
		,	minCenterDims	= cssMinDims("center")
		,	minCenterSize	= dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth)
		//	if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them
		,	limitSize		= (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing)))
		,	minSize			= s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize )
		,	maxSize			= s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize )
		,	r				= s.resizerPosition = {} // used to set resizing limits
		,	top				= sC.insetTop
		,	left			= sC.insetLeft
		,	W				= sC.innerWidth
		,	H				= sC.innerHeight
		,	rW				= o.spacing_open // subtract resizer-width to get top/left position for south/east
		;
		switch (pane) {
			case "north":	r.min = top + minSize;
							r.max = top + maxSize;
							break;
			case "west":	r.min = left + minSize;
							r.max = left + maxSize;
							break;
			case "south":	r.min = top + H - maxSize - rW;
							r.max = top + H - minSize - rW;
							break;
			case "east":	r.min = left + W - maxSize - rW;
							r.max = left + W - minSize - rW;
							break;
		};
	}

	/**
	* Returns data for setting the size/position of center pane. Also used to set Height for east/west panes
	*
	* @return JSON  Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height
	*/
,	calcNewCenterPaneDims = function () {
		var d = {
			top:	getPaneSize("north", true) // true = include 'spacing' value for pane
		,	bottom:	getPaneSize("south", true)
		,	left:	getPaneSize("west", true)
		,	right:	getPaneSize("east", true)
		,	width:	0
		,	height:	0
		};

		// NOTE: sC = state.container
		// calc center-pane outer dimensions
		d.width		= sC.innerWidth - d.left - d.right;  // outerWidth
		d.height	= sC.innerHeight - d.bottom - d.top; // outerHeight
		// add the 'container border/padding' to get final positions relative to the container
		d.top		+= sC.insetTop;
		d.bottom	+= sC.insetBottom;
		d.left		+= sC.insetLeft;
		d.right		+= sC.insetRight;

		return d;
	}


	/**
	* @param {!Object}		el
	* @param {boolean=}		[allStates=false]
	*/
,	getHoverClasses = function (el, allStates) {
		var
			$El		= $(el)
		,	type	= $El.data("layoutRole")
		,	pane	= $El.data("layoutEdge")
		,	o		= options[pane]
		,	root	= o[type +"Class"]
		,	_pane	= "-"+ pane // eg: "-west"
		,	_open	= "-open"
		,	_closed	= "-closed"
		,	_slide	= "-sliding"
		,	_hover	= "-hover " // NOTE the trailing space
		,	_state	= $El.hasClass(root+_closed) ? _closed : _open
		,	_alt	= _state === _closed ? _open : _closed
		,	classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover)
		;
		if (allStates) // when 'removing' classes, also remove alternate-state classes
			classes += (root+_alt+_hover) + (root+_pane+_alt+_hover);

		if (type=="resizer" && $El.hasClass(root+_slide))
			classes += (root+_slide+_hover) + (root+_pane+_slide+_hover);

		return $.trim(classes);
	}
,	addHover	= function (evt, el) {
		var $E = $(el || this);
		if (evt && $E.data("layoutRole") === "toggler")
			evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar
		$E.addClass( getHoverClasses($E) );
	}
,	removeHover	= function (evt, el) {
		var $E = $(el || this);
		$E.removeClass( getHoverClasses($E, true) );
	}

,	onResizerEnter	= function (evt) { // ALSO called by toggler.mouseenter
		if ($.fn.disableSelection)
			$("body").disableSelection();
	}
,	onResizerLeave	= function (evt, el) {
		var
			e = el || this // el is only passed when called by the timer
		,	pane = $(e).data("layoutEdge")
		,	name = pane +"ResizerLeave"
		;
		timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set
		timer.clear(name); // cancel enableSelection timer - may re/set below
		// this method calls itself on a timer because it needs to allow
		// enough time for dragging to kick-in and set the isResizing flag
		// dragging has a 100ms delay set, so this delay must be >100
		if (!el) // 1st call - mouseleave event
			timer.set(name, function(){ onResizerLeave(evt, e); }, 200);
		// if user is resizing, then dragStop will enableSelection(), so can skip it here
		else if (!state[pane].isResizing && $.fn.enableSelection) // 2nd call - by timer
			$("body").enableSelection();
	}

/*
 * ###########################
 *   INITIALIZATION METHODS
 * ###########################
 */

	/**
	* Initialize the layout - called automatically whenever an instance of layout is created
	*
	* @see  none - triggered onInit
	* @return  mixed	true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort
	*/
,	_create = function () {
		// initialize config/options
		initOptions();
		var o = options;

		// TEMP state so isInitialized returns true during init process
		state.creatingLayout = true;

		// init plugins for this layout, if there are any (eg: stateManagement)
		runPluginCallbacks( Instance, $.layout.onCreate );

		// options & state have been initialized, so now run beforeLoad callback
		// onload will CANCEL layout creation if it returns false
		if (false === _runCallbacks("onload_start"))
			return 'cancel';

		// initialize the container element
		_initContainer();

		// bind hotkey function - keyDown - if required
		initHotkeys();

		// bind window.onunload
		$(window).bind("unload."+ sID, unload);

		// init plugins for this layout, if there are any (eg: customButtons)
		runPluginCallbacks( Instance, $.layout.onLoad );

		// if layout elements are hidden, then layout WILL NOT complete initialization!
		// initLayoutElements will set initialized=true and run the onload callback IF successful
		if (o.initPanes) _initLayoutElements();

		delete state.creatingLayout;

		return state.initialized;
	}

	/**
	* Initialize the layout IF not already
	*
	* @see  All methods in Instance run this test
	* @return  boolean	true = layoutElements have been initialized | false = panes are not initialized (yet)
	*/
,	isInitialized = function () {
		if (state.initialized || state.creatingLayout) return true;	// already initialized
		else return _initLayoutElements();	// try to init panes NOW
	}

	/**
	* Initialize the layout - called automatically whenever an instance of layout is created
	*
	* @see  _create() & isInitialized
	* @return  An object pointer to the instance created
	*/
,	_initLayoutElements = function (retry) {
		// initialize config/options
		var o = options;

		// CANNOT init panes inside a hidden container!
		if (!$N.is(":visible")) {
			// handle Chrome bug where popup window 'has no height'
			// if layout is BODY element, try again in 50ms
			// SEE: http://layout.jquery-dev.net/samples/test_popup_window.html
			if ( !retry && browser.webkit && $N[0].tagName === "BODY" )
				setTimeout(function(){ _initLayoutElements(true); }, 50);
			return false;
		}

		// a center pane is required, so make sure it exists
		if (!getPane("center").length) {
			return _log( o.errors.centerPaneMissing );
		}

		// TEMP state so isInitialized returns true during init process
		state.creatingLayout = true;

		// update Container dims
		$.extend(sC, elDims( $N ));

		// initialize all layout elements
		initPanes();	// size & position panes - calls initHandles() - which calls initResizable()

		if (o.scrollToBookmarkOnLoad) {
			var l = self.location;
			if (l.hash) l.replace( l.hash ); // scrollTo Bookmark
		}

		// check to see if this layout 'nested' inside a pane
		if (Instance.hasParentLayout)
			o.resizeWithWindow = false;
		// bind resizeAll() for 'this layout instance' to window.resize event
		else if (o.resizeWithWindow)
			$(window).bind("resize."+ sID, windowResize);

		delete state.creatingLayout;
		state.initialized = true;

		// init plugins for this layout, if there are any
		runPluginCallbacks( Instance, $.layout.onReady );

		// now run the onload callback, if exists
		_runCallbacks("onload_end");

		return true; // elements initialized successfully
	}

	/**
	* Initialize nested layouts - called when _initLayoutElements completes
	*
	* NOT CURRENTLY USED
	*
	* @see _initLayoutElements
	* @return  An object pointer to the instance created
	*/
,	_initChildLayouts = function () {
		$.each(_c.allPanes, function (idx, pane) {
			if (options[pane].initChildLayout)
				createChildLayout( pane );
		});
	}

	/**
	* Initialize nested layouts for a specific pane - can optionally pass layout-options
	*
	* @see _initChildLayouts
	* @param {string|Object}	evt_or_pane	The pane being opened, ie: north, south, east, or west
	* @param {Object=}			[opts]		Layout-options - if passed, will OVERRRIDE options[pane].childOptions
	* @return  An object pointer to the layout instance created - or null
	*/
,	createChildLayout = function (evt_or_pane, opts) {
		var	pane = evtPane.call(this, evt_or_pane)
		,	$P	= $Ps[pane]
		,	C	= children
		;
		if ($P) {
			var	$C	= $Cs[pane]
			,	o	= opts || options[pane].childOptions
			,	d	= "layout"
			//	determine which element is supposed to be the 'child container'
			//	if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane
			,	$Cont = o.containerSelector ? $P.find( o.containerSelector ) : ($C || $P)
			,	containerFound = $Cont.length
			//	see if a child-layout ALREADY exists on this element
			,	child = containerFound ? (C[pane] = $Cont.data(d) || null) : null
			;
			// if no layout exists, but childOptions are set, try to create the layout now
			if (!child && containerFound && o)
				child = C[pane] = $Cont.eq(0).layout(o) || null;
			if (child)
				child.hasParentLayout = true;	// set parent-flag in child
		}
		Instance[pane].child = C[pane]; // ALWAYS set pane-object pointer, even if null
	}

,	windowResize = function () {
		var delay = Number(options.resizeWithWindowDelay);
		if (delay < 10) delay = 100; // MUST have a delay!
		// resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway
		timer.clear("winResize"); // if already running
		timer.set("winResize", function(){
			timer.clear("winResize");
			timer.clear("winResizeRepeater");
			var dims = elDims( $N );
			// only trigger resizeAll() if container has changed size
			if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight)
				resizeAll();
		}, delay);
		// ALSO set fixed-delay timer, if not already running
		if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater();
	}

,	setWindowResizeRepeater = function () {
		var delay = Number(options.resizeWithWindowMaxDelay);
		if (delay > 0)
			timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay);
	}

,	unload = function () {
		var o = options;

		_runCallbacks("onunload_start");

		// trigger plugin callabacks for this layout (eg: stateManagement)
		runPluginCallbacks( Instance, $.layout.onUnload );

		_runCallbacks("onunload_end");
	}

	/**
	* Validate and initialize container CSS and events
	*
	* @see  _create()
	*/
,	_initContainer = function () {
		var
			N		= $N[0]
		,	tag		= sC.tagName = N.tagName
		,	id		= sC.id = N.id
		,	cls		= sC.className = N.className
		,	o		= options
		,	name	= o.name
		,	fullPage= (tag === "BODY")
		,	props	= "overflow,position,margin,padding,border"
		,	css		= "layoutCSS"
		,	CSS		= {}
		,	hid		= "hidden" // used A LOT!
		//	see if this container is a 'pane' inside an outer-layout
		,	parent	= $N.data("parentLayout")	// parent-layout Instance
		,	pane	= $N.data("layoutEdge")		// pane-name in parent-layout
		,	isChild	= parent && pane
		;
		// sC -> state.container
		sC.selector = $N.selector.split(".slice")[0];
		sC.ref		= (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages

		$N	.data({
				layout: Instance
			,	layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID
			})
			.addClass(o.containerClass)
		;
		var layoutMethods = {
			destroy:	''
		,	initPanes:	''
		,	resizeAll:	'resizeAll'
		,	resize:		'resizeAll'
		};
		// loop hash and bind all methods - include layoutID namespacing
		for (name in layoutMethods) {
			$N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]);
		}

		// if this container is another layout's 'pane', then set child/parent pointers
		if (isChild) {
			// update parent flag
			Instance.hasParentLayout = true;
			// set pointers to THIS child-layout (Instance) in parent-layout
			// NOTE: parent.PANE.child is an ALIAS to parent.children.PANE
			parent[pane].child = parent.children[pane] = $N.data("layout");
		}

		// SAVE original container CSS for use in destroy()
		if (!$N.data(css)) {
			// handle props like overflow different for BODY & HTML - has 'system default' values
			if (fullPage) {
				CSS = $.extend( elCSS($N, props), {
					height:		$N.css("height")
				,	overflow:	$N.css("overflow")
				,	overflowX:	$N.css("overflowX")
				,	overflowY:	$N.css("overflowY")
				});
				// ALSO SAVE <HTML> CSS
				var $H = $("html");
				$H.data(css, {
					height:		"auto" // FF would return a fixed px-size!
				,	overflow:	$H.css("overflow")
				,	overflowX:	$H.css("overflowX")
				,	overflowY:	$H.css("overflowY")
				});
			}
			else // handle props normally for non-body elements
				CSS = elCSS($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY");

			$N.data(css, CSS);
		}

		try { // format html/body if this is a full page layout
			if (fullPage) {
				$("html").css({
					height:		"100%"
				,	overflow:	hid
				,	overflowX:	hid
				,	overflowY:	hid
				});
				$("body").css({
					position:	"relative"
				,	height:		"100%"
				,	overflow:	hid
				,	overflowX:	hid
				,	overflowY:	hid
				,	margin:		0
				,	padding:	0		// TODO: test whether body-padding could be handled?
				,	border:		"none"	// a body-border creates problems because it cannot be measured!
				});

				// set current layout-container dimensions
				$.extend(sC, elDims( $N ));
			}
			else { // set required CSS for overflow and position
				// ENSURE container will not 'scroll'
				CSS = { overflow: hid, overflowX: hid, overflowY: hid }
				var
					p = $N.css("position")
				,	h = $N.css("height")
				;
				// if this is a NESTED layout, then container/outer-pane ALREADY has position and height
				if (!isChild) {
					if (!p || !p.match(/fixed|absolute|relative/))
						CSS.position = "relative"; // container MUST have a 'position'
					/*
					if (!h || h=="auto")
						CSS.height = "100%"; // container MUST have a 'height'
					*/
				}
				$N.css( CSS );

				// set current layout-container dimensions
				if ( $N.is(":visible") ) {
					$.extend(sC, elDims( $N ));
					if (sC.innerHeight < 1)
						_log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) );
				}
			}
		} catch (ex) {}
	}

	/**
	* Bind layout hotkeys - if options enabled
	*
	* @see  _create() and addPane()
	* @param {string=}	[panes=""]	The edge(s) to process
	*/
,	initHotkeys = function (panes) {
		panes = panes ? panes.split(",") : _c.borderPanes;
		// bind keyDown to capture hotkeys, if option enabled for ANY pane
		$.each(panes, function (i, pane) {
			var o = options[pane];
			if (o.enableCursorHotkey || o.customHotkey) {
				$(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE
				return false; // BREAK - binding was done
			}
		});
	}

	/**
	* Build final OPTIONS data
	*
	* @see  _create()
	*/
,	initOptions = function () {
		var data, d, pane, key, val, i, c, o;

		// reprocess user's layout-options to have correct options sub-key structure
		opts = $.layout.transformData( opts ); // panes = default subkey

		// auto-rename old options for backward compatibility
		opts = $.layout.backwardCompatibility.renameAllOptions( opts );

		// if user-options has 'panes' key (pane-defaults), clean it...
		if (!$.isEmptyObject(opts.panes)) {
			// REMOVE any pane-defaults that MUST be set per-pane
			data = $.layout.optionsMap.noDefault;
			for (i=0, c=data.length; i<c; i++) {
				key = data[i];
				delete opts.panes[key]; // OK if does not exist
			}
			// REMOVE any layout-options specified under opts.panes
			data = $.layout.optionsMap.layout;
			for (i=0, c=data.length; i<c; i++) {
				key = data[i];
				delete opts.panes[key]; // OK if does not exist
			}
		}

		// MOVE any NON-layout-options from opts-root to opts.panes
		data = $.layout.optionsMap.layout;
		var rootKeys = $.layout.config.optionRootKeys;
		for (key in opts) {
			val = opts[key];
			if ($.inArray(key, rootKeys) < 0 && $.inArray(key, data) < 0) {
				if (!opts.panes[key])
					opts.panes[key] = $.isPlainObject(val) ? $.extend(true, {}, val) : val;
				delete opts[key]
			}
		}

		// START by updating ALL options from opts
		$.extend(true, options, opts);

		// CREATE final options (and config) for EACH pane
		$.each(_c.allPanes, function (i, pane) {

			// apply 'pane-defaults' to CONFIG.[PANE]
			_c[pane] = $.extend(true, {}, _c.panes, _c[pane]);

			d = options.panes;
			o = options[pane];

			// center-pane uses SOME keys in defaults.panes branch
			if (pane === 'center') {
				// ONLY copy keys from opts.panes listed in: $.layout.optionsMap.center
				data = $.layout.optionsMap.center;		// list of 'center-pane keys'
				for (i=0, c=data.length; i<c; i++) {	// loop the list...
					key = data[i];
					// only need to use pane-default if pane-specific value not set
					if (!opts.center[key] && (opts.panes[key] || !o[key]))
						o[key] = d[key]; // pane-default
				}
			}
			else {
				// border-panes use ALL keys in defaults.panes branch
				o = options[pane] = $.extend(true, {}, d, o); // re-apply pane-specific opts AFTER pane-defaults
				createFxOptions( pane );
				// ensure all border-pane-specific base-classes exist
				if (!o.resizerClass)	o.resizerClass	= "ui-layout-resizer";
				if (!o.togglerClass)	o.togglerClass	= "ui-layout-toggler";
			}
			// ensure we have base pane-class (ALL panes)
			if (!o.paneClass) o.paneClass = "ui-layout-pane";
		});

		// update options.zIndexes if a zIndex-option specified
		var zo	= opts.zIndex
		,	z	= options.zIndexes;
		if (zo > 0) {
			z.pane_normal		= zo;
			z.content_mask		= max(zo+1, z.content_mask);	// MIN = +1
			z.resizer_normal	= max(zo+2, z.resizer_normal);	// MIN = +2
		}

		// DELETE 'panes' key now that we are done - values were copied to EACH pane
		delete options.panes;


		function createFxOptions ( pane ) {
			var	o = options[pane]
			,	d = options.panes;
			// ensure fxSettings key to avoid errors
			if (!o.fxSettings) o.fxSettings = {};
			if (!d.fxSettings) d.fxSettings = {};

			$.each(["_open","_close","_size"], function (i,n) { 
				var
					sName		= "fxName"+ n
				,	sSpeed		= "fxSpeed"+ n
				,	sSettings	= "fxSettings"+ n
					// recalculate fxName according to specificity rules
				,	fxName = o[sName] =
						o[sName]	// options.west.fxName_open
					||	d[sName]	// options.panes.fxName_open
					||	o.fxName	// options.west.fxName
					||	d.fxName	// options.panes.fxName
					||	"none"		// MEANS $.layout.defaults.panes.fxName == "" || false || null || 0
				;
				// validate fxName to ensure is valid effect - MUST have effect-config data in options.effects
				if (fxName === "none" || !$.effects || !$.effects[fxName] || !options.effects[fxName])
					fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName

				// set vars for effects subkeys to simplify logic
				var	fx		= options.effects[fxName] || {}	// effects.slide
				,	fx_all	= fx.all	|| null				// effects.slide.all
				,	fx_pane	= fx[pane]	|| null				// effects.slide.west
				;
				// create fxSpeed[_open|_close|_size]
				o[sSpeed] =
					o[sSpeed]				// options.west.fxSpeed_open
				||	d[sSpeed]				// options.west.fxSpeed_open
				||	o.fxSpeed				// options.west.fxSpeed
				||	d.fxSpeed				// options.panes.fxSpeed
				||	null					// DEFAULT - let fxSetting.duration control speed
				;
				// create fxSettings[_open|_close|_size]
				o[sSettings] = $.extend(
					true
				,	{}
				,	fx_all					// effects.slide.all
				,	fx_pane					// effects.slide.west
				,	d.fxSettings			// options.panes.fxSettings
				,	o.fxSettings			// options.west.fxSettings
				,	d[sSettings]			// options.panes.fxSettings_open
				,	o[sSettings]			// options.west.fxSettings_open
				);
			});

			// DONE creating action-specific-settings for this pane,
			// so DELETE generic options - are no longer meaningful
			delete o.fxName;
			delete o.fxSpeed;
			delete o.fxSettings;
		}
	}

	/**
	* Initialize module objects, styling, size and position for all panes
	*
	* @see  _initElements()
	* @param {string}	pane		The pane to process
	*/
,	getPane = function (pane) {
		var sel = options[pane].paneSelector
		if (sel.substr(0,1)==="#") // ID selector
			// NOTE: elements selected 'by ID' DO NOT have to be 'children'
			return $N.find(sel).eq(0);
		else { // class or other selector
			var $P = $N.children(sel).eq(0);
			// look for the pane nested inside a 'form' element
			return $P.length ? $P : $N.children("form:first").children(sel).eq(0);
		}
	}

,	initPanes = function (evt) {
		// stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility 
		evtPane(evt);

		// NOTE: do north & south FIRST so we can measure their height - do center LAST
		$.each(_c.allPanes, function (idx, pane) {
			addPane( pane, true );
		});

		// init the pane-handles NOW in case we have to hide or close the pane below
		initHandles();

		// now that all panes have been initialized and initially-sized,
		// make sure there is really enough space available for each pane
		$.each(_c.borderPanes, function (i, pane) {
			if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN
				setSizeLimits(pane);
				makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit()
			}
		});
		// size center-pane AGAIN in case we 'closed' a border-pane in loop above
		sizeMidPanes("center");

		//	Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing!
		//	Before RC30.3, there was a 10ms delay here, but that caused layout 
		//	to load asynchrously, which is BAD, so try skipping delay for now

		// process pane contents and callbacks, and init/resize child-layout if exists
		$.each(_c.allPanes, function (i, pane) {
			var o = options[pane];
			if ($Ps[pane]) {
				if (state[pane].isVisible) { // pane is OPEN
					sizeContent(pane);
					// trigger pane.onResize if triggerEventsOnLoad = true
					if (o.triggerEventsOnLoad)
						_runCallbacks("onresize_end", pane);
				else // automatic if onresize called, otherwise call it specifically
					// resize child - IF inner-layout already exists (created before this layout)
					resizeChildLayout(pane);
				}
				// init childLayout - even if pane is not visible
				if (o.initChildLayout && o.childOptions)
					createChildLayout(pane);
			}
		});
	}

	/**
	* Add a pane to the layout - subroutine of initPanes()
	*
	* @see  initPanes()
	* @param {string}	pane			The pane to process
	* @param {boolean=}	[force=false]	Size content after init
	*/
,	addPane = function (pane, force) {
		if (!force && !isInitialized()) return;
		var
			o		= options[pane]
		,	s		= state[pane]
		,	c		= _c[pane]
		,	fx		= s.fx
		,	dir		= c.dir
		,	spacing	= o.spacing_open || 0
		,	isCenter = (pane === "center")
		,	CSS		= {}
		,	$P		= $Ps[pane]
		,	size, minSize, maxSize
		;
		// if pane-pointer already exists, remove the old one first
		if ($P)
			removePane( pane, false, true, false );
		else
			$Cs[pane] = false; // init

		$P = $Ps[pane] = getPane(pane);
		if (!$P.length) {
			$Ps[pane] = false; // logic
			return;
		}

		// SAVE original Pane CSS
		if (!$P.data("layoutCSS")) {
			var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border";
			$P.data("layoutCSS", elCSS($P, props));
		}

		// create alias for pane data in Instance - initHandles will add more
		Instance[pane] = { name: pane, pane: $Ps[pane], content: $Cs[pane], options: options[pane], state: state[pane], child: children[pane] };

		// add classes, attributes & events
		$P	.data({
				parentLayout:	Instance		// pointer to Layout Instance
			,	layoutPane:		Instance[pane]	// NEW pointer to pane-alias-object
			,	layoutEdge:		pane
			,	layoutRole:		"pane"
			})
			.css(c.cssReq).css("zIndex", options.zIndexes.pane_normal)
			.css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles
			.addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector'
			.bind("mouseenter."+ sID, addHover )
			.bind("mouseleave."+ sID, removeHover )
			;
		var paneMethods = {
				hide:				''
			,	show:				''
			,	toggle:				''
			,	close:				''
			,	open:				''
			,	slideOpen:			''
			,	slideClose:			''
			,	slideToggle:		''
			,	size:				'sizePane'
			,	sizePane:			'sizePane'
			,	sizeContent:		''
			,	sizeHandles:		''
			,	enableClosable:		''
			,	disableClosable:	''
			,	enableSlideable:	''
			,	disableSlideable:	''
			,	enableResizable:	''
			,	disableResizable:	''
			,	swapPanes:			'swapPanes'
			,	swap:				'swapPanes'
			,	move:				'swapPanes'
			,	removePane:			'removePane'
			,	remove:				'removePane'
			,	createChildLayout:	''
			,	resizeChildLayout:	''
			,	resizeAll:			'resizeAll'
			,	resizeLayout:		'resizeAll'
			}
		,	name;
		// loop hash and bind all methods - include layoutID namespacing
		for (name in paneMethods) {
			$P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]);
		}

		// see if this pane has a 'scrolling-content element'
		initContent(pane, false); // false = do NOT sizeContent() - called later

		if (!isCenter) {
			// call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden)
			// if o.size is auto or not valid, then MEASURE the pane and use that as its 'size'
			size	= s.size = _parseSize(pane, o.size);
			minSize	= _parseSize(pane,o.minSize) || 1;
			maxSize	= _parseSize(pane,o.maxSize) || 100000;
			if (size > 0) size = max(min(size, maxSize), minSize);

			// state for border-panes
			s.isClosed  = false; // true = pane is closed
			s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes
			s.isResizing= false; // true = pane is in process of being resized
			s.isHidden	= false; // true = pane is hidden - no spacing, resizer or toggler is visible!

			// array for 'pin buttons' whose classNames are auto-updated on pane-open/-close
			if (!s.pins) s.pins = [];
		}
		//	states common to ALL panes
		s.tagName	= $P[0].tagName;
		s.edge		= pane;		// useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going)
		s.noRoom	= false;	// true = pane 'automatically' hidden due to insufficient room - will unhide automatically
		s.isVisible	= true;		// false = pane is invisible - closed OR hidden - simplify logic

		// set css-position to account for container borders & padding
		switch (pane) {
			case "north": 	CSS.top 	= sC.insetTop;
							CSS.left 	= sC.insetLeft;
							CSS.right	= sC.insetRight;
							break;
			case "south": 	CSS.bottom	= sC.insetBottom;
							CSS.left 	= sC.insetLeft;
							CSS.right 	= sC.insetRight;
							break;
			case "west": 	CSS.left 	= sC.insetLeft; // top, bottom & height set by sizeMidPanes()
							break;
			case "east": 	CSS.right 	= sC.insetRight; // ditto
							break;
			case "center":	// top, left, width & height set by sizeMidPanes()
		}

		if (dir === "horz") // north or south pane
			CSS.height = cssH($P, size);
		else if (dir === "vert") // east or west pane
			CSS.width = cssW($P, size);
		//else if (isCenter) {}

		$P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes
		if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback

		// close or hide the pane if specified in settings
		if (o.initClosed && o.closable && !o.initHidden)
			close(pane, true, true); // true, true = force, noAnimation
		else if (o.initHidden || o.initClosed)
			hide(pane); // will be completely invisible - no resizer or spacing
		else if (!s.noRoom)
			// make the pane visible - in case was initially hidden
			$P.css("display","block");
		// ELSE setAsOpen() - called later by initHandles()

		// RESET visibility now - pane will appear IF display:block
		$P.css("visibility","visible");

		// check option for auto-handling of pop-ups & drop-downs
		if (o.showOverflowOnHover)
			$P.hover( allowOverflow, resetOverflow );

		// if manually adding a pane AFTER layout initialization, then...
		if (state.initialized) {
			initHandles( pane );
			initHotkeys( pane );
			resizeAll(); // will sizeContent if pane is visible
			if (s.isVisible) { // pane is OPEN
				if (o.triggerEventsOnLoad)
					_runCallbacks("onresize_end", pane);
				else // automatic if onresize called, otherwise call it specifically
					// resize child - IF inner-layout already exists (created before this layout)
					resizeChildLayout(pane); // a previously existing childLayout
			}
			if (o.initChildLayout && o.childOptions)
				createChildLayout(pane);
		}
	}

	/**
	* Initialize module objects, styling, size and position for all resize bars and toggler buttons
	*
	* @see  _create()
	* @param {string=}	[panes=""]	The edge(s) to process
	*/
,	initHandles = function (panes) {
		panes = panes ? panes.split(",") : _c.borderPanes;

		// create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV
		$.each(panes, function (i, pane) {
			var $P		= $Ps[pane];
			$Rs[pane]	= false; // INIT
			$Ts[pane]	= false;
			if (!$P) return; // pane does not exist - skip

			var 
				o		= options[pane]
			,	s		= state[pane]
			,	c		= _c[pane]
			,	paneId	= o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : ""
			,	rClass	= o.resizerClass
			,	tClass	= o.togglerClass
			,	side	= c.side.toLowerCase()
			,	spacing	= (s.isVisible ? o.spacing_open : o.spacing_closed)
			,	_pane	= "-"+ pane // used for classNames
			,	_state	= (s.isVisible ? "-open" : "-closed") // used for classNames
			,	I		= Instance[pane]
				// INIT RESIZER BAR
			,	$R		= I.resizer = $Rs[pane] = $("<div></div>")
				// INIT TOGGLER BUTTON
			,	$T		= I.toggler = (o.closable ? $Ts[pane] = $("<div></div>") : false)
			;

			//if (s.isVisible && o.resizable) ... handled by initResizable
			if (!s.isVisible && o.slidable)
				$R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor);

			$R	// if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer"
				.attr("id", paneId ? paneId +"-resizer" : "" )
				.data({
					parentLayout:	Instance
				,	layoutPane:		Instance[pane]	// NEW pointer to pane-alias-object
				,	layoutEdge:		pane
				,	layoutRole:		"resizer"
				})
				.css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal)
				.css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles
				.addClass(rClass +" "+ rClass+_pane)
				.hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead
				.hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter
				.appendTo($N) // append DIV to container
			;

			if ($T) {
				$T	// if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler"
					.attr("id", paneId ? paneId +"-toggler" : "" )
					.data({
						parentLayout:	Instance
					,	layoutPane:		Instance[pane]	// NEW pointer to pane-alias-object
					,	layoutEdge:		pane
					,	layoutRole:		"toggler"
					})
					.css(_c.togglers.cssReq) // add base/required styles
					.css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles
					.addClass(tClass +" "+ tClass+_pane)
					.hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead
					.bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer
					.appendTo($R) // append SPAN to resizer DIV
				;
				// ADD INNER-SPANS TO TOGGLER
				if (o.togglerContent_open) // ui-layout-open
					$("<span>"+ o.togglerContent_open +"</span>")
						.data({
							layoutEdge:		pane
						,	layoutRole:		"togglerContent"
						})
						.data("layoutRole", "togglerContent")
						.data("layoutEdge", pane)
						.addClass("content content-open")
						.css("display","none")
						.appendTo( $T )
						//.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead!
					;
				if (o.togglerContent_closed) // ui-layout-closed
					$("<span>"+ o.togglerContent_closed +"</span>")
						.data({
							layoutEdge:		pane
						,	layoutRole:		"togglerContent"
						})
						.addClass("content content-closed")
						.css("display","none")
						.appendTo( $T )
						//.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead!
					;
				// ADD TOGGLER.click/.hover
				enableClosable(pane);
			}

			// add Draggable events
			initResizable(pane);

			// ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open"
			if (s.isVisible)
				setAsOpen(pane);	// onOpen will be called, but NOT onResize
			else {
				setAsClosed(pane);	// onClose will be called
				bindStartSlidingEvent(pane, true); // will enable events IF option is set
			}

		});

		// SET ALL HANDLE DIMENSIONS
		sizeHandles();
	}


	/**
	* Initialize scrolling ui-layout-content div - if exists
	*
	* @see  initPane() - or externally after an Ajax injection
	* @param {string}	[pane]			The pane to process
	* @param {boolean=}	[resize=true]	Size content after init
	*/
,	initContent = function (pane, resize) {
		if (!isInitialized()) return;
		var 
			o	= options[pane]
		,	sel	= o.contentSelector
		,	I	= Instance[pane]
		,	$P	= $Ps[pane]
		,	$C
		;
		if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent)
			? $P.find(sel).eq(0) // match 1-element only
			: $P.children(sel).eq(0)
		;
		if ($C && $C.length) {
			$C.data("layoutRole", "content");
			// SAVE original Pane CSS
			if (!$C.data("layoutCSS"))
				$C.data("layoutCSS", elCSS($C, "height"));
			$C.css( _c.content.cssReq );
			if (o.applyDemoStyles) {
				$C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div
				$P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane
			}
			state[pane].content = {}; // init content state
			if (resize !== false) sizeContent(pane);
			// sizeContent() is called AFTER init of all elements
		}
		else
			I.content = $Cs[pane] = false;
	}


	/**
	* Add resize-bars to all panes that specify it in options
	* -dependancy: $.fn.resizable - will skip if not found
	*
	* @see  _create()
	* @param {string=}	[panes=""]	The edge(s) to process
	*/
,	initResizable = function (panes) {
		var	draggingAvailable = $.layout.plugins.draggable
		,	side // set in start()
		;
		panes = panes ? panes.split(",") : _c.borderPanes;

		$.each(panes, function (idx, pane) {
			var o = options[pane];
			if (!draggingAvailable || !$Ps[pane] || !o.resizable) {
				o.resizable = false;
				return true; // skip to next
			}

			var s		= state[pane]
			,	z		= options.zIndexes
			,	c		= _c[pane]
			,	side	= c.dir=="horz" ? "top" : "left"
			,	opEdge	= _c.oppositeEdge[pane]
			,	masks	=  pane +",center,"+ opEdge + (c.dir=="horz" ? ",west,east" : "")
			,	$P 		= $Ps[pane]
			,	$R		= $Rs[pane]
			,	base	= o.resizerClass
			,	lastPos	= 0 // used when live-resizing
			,	r, live // set in start because may change
			//	'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process
			,	resizerClass		= base+"-drag"				// resizer-drag
			,	resizerPaneClass	= base+"-"+pane+"-drag"		// resizer-north-drag
			//	'helper' class is applied to the CLONED resizer-bar while it is being dragged
			,	helperClass			= base+"-dragging"			// resizer-dragging
			,	helperPaneClass		= base+"-"+pane+"-dragging" // resizer-north-dragging
			,	helperLimitClass	= base+"-dragging-limit"	// resizer-drag
			,	helperPaneLimitClass = base+"-"+pane+"-dragging-limit"	// resizer-north-drag
			,	helperClassesSet	= false 					// logic var
			;

			if (!s.isClosed)
				$R.attr("title", o.tips.Resize)
				  .css("cursor", o.resizerCursor); // n-resize, s-resize, etc

			$R.draggable({
				containment:	$N[0] // limit resizing to layout container
			,	axis:			(c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis
			,	delay:			0
			,	distance:		1
			,	grid:			o.resizingGrid
			//	basic format for helper - style it using class: .ui-draggable-dragging
			,	helper:			"clone"
			,	opacity:		o.resizerDragOpacity
			,	addClasses:		false // avoid ui-state-disabled class when disabled
			//,	iframeFix:		o.draggableIframeFix // TODO: consider using when bug is fixed
			,	zIndex:			z.resizer_drag

			,	start: function (e, ui) {
					// REFRESH options & state pointers in case we used swapPanes
					o = options[pane];
					s = state[pane];
					// re-read options
					live = o.livePaneResizing;

					// ondrag_start callback - will CANCEL hide if returns false
					// TODO: dragging CANNOT be cancelled like this, so see if there is a way?
					if (false === _runCallbacks("ondrag_start", pane)) return false;

					s.isResizing	= true; // prevent pane from closing while resizing
					timer.clear(pane+"_closeSlider"); // just in case already triggered

					// SET RESIZER LIMITS - used in drag()
					setSizeLimits(pane); // update pane/resizer state
					r = s.resizerPosition;
					lastPos = ui.position[ side ]

					$R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes
					helperClassesSet = false; // reset logic var - see drag()

					// DISABLE TEXT SELECTION (probably already done by resizer.mouseOver)
					$('body').disableSelection(); 

					// MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS
					showMasks( masks );
				}

			,	drag: function (e, ui) {
					if (!helperClassesSet) { // can only add classes after clone has been added to the DOM
						//$(".ui-draggable-dragging")
						ui.helper
							.addClass( helperClass +" "+ helperPaneClass ) // add helper classes
							.css({ right: "auto", bottom: "auto" })	// fix dir="rtl" issue
							.children().css("visibility","hidden")	// hide toggler inside dragged resizer-bar
						;
						helperClassesSet = true;
						// draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane!
						if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding);
					}
					// CONTAIN RESIZER-BAR TO RESIZING LIMITS
					var limit = 0;
					if (ui.position[side] < r.min) {
						ui.position[side] = r.min;
						limit = -1;
					}
					else if (ui.position[side] > r.max) {
						ui.position[side] = r.max;
						limit = 1;
					}
					// ADD/REMOVE dragging-limit CLASS
					if (limit) {
						ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit
						window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning;
					}
					else {
						ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit
						window.defaultStatus = "";
					}
					// DYNAMICALLY RESIZE PANES IF OPTION ENABLED
					// won't trigger unless resizer has actually moved!
					if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) {
						lastPos = ui.position[side];
						resizePanes(e, ui, pane)
					}
				}

			,	stop: function (e, ui) {
					$('body').enableSelection(); // RE-ENABLE TEXT SELECTION
					window.defaultStatus = ""; // clear 'resizing limit' message from statusbar
					$R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer
					s.isResizing = false;
					resizePanes(e, ui, pane, true, masks); // true = resizingDone
				}

			});
		});

		/**
		* resizePanes
		*
		* Sub-routine called from stop() - and drag() if livePaneResizing
		*
		* @param {!Object}		evt
		* @param {!Object}		ui
		* @param {string}		pane
		* @param {boolean=}		[resizingDone=false]
		*/
		var resizePanes = function (evt, ui, pane, resizingDone, masks) {
			var	dragPos	= ui.position
			,	c		= _c[pane]
			,	o		= options[pane]
			,	s		= state[pane]
			,	resizerPos
			;
			switch (pane) {
				case "north":	resizerPos = dragPos.top; break;
				case "west":	resizerPos = dragPos.left; break;
				case "south":	resizerPos = sC.offsetHeight - dragPos.top  - o.spacing_open; break;
				case "east":	resizerPos = sC.offsetWidth  - dragPos.left - o.spacing_open; break;
			};
			// remove container margin from resizer position to get the pane size
			var newSize = resizerPos - sC["inset"+ c.side];

			// Disable OR Resize Mask(s) created in drag.start
			if (!resizingDone) {
				// ensure we meet liveResizingTolerance criteria
				if (Math.abs(newSize - s.size) < o.liveResizingTolerance)
					return; // SKIP resize this time
				// resize the pane
				manualSizePane(pane, newSize, false, true); // true = noAnimation
				sizeMasks(); // resize all visible masks
			}
			else { // resizingDone
				// ondrag_end callback
				if (false !== _runCallbacks("ondrag_end", pane))
					manualSizePane(pane, newSize, false, true); // true = noAnimation
				hideMasks(); // hide all masks, which include panes with 'content/iframe-masks'
				if (s.isSliding && masks) // RE-SHOW only 'object-masks' so objects won't show through sliding pane
					showMasks( masks, true ); // true = onlyForObjects
			}
		};
	}

	/**
	 *	sizeMask
	 *
	 *	Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane
	 *	Called when mask created, and during livePaneResizing
	 */
,	sizeMask = function () {
		var $M		= $(this)
		,	pane	= $M.data("layoutMask") // eg: "west"
		,	s		= state[pane]
		;
		// only masks over an IFRAME-pane need manual resizing
		if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes
			$M.css({
				top:	s.offsetTop
			,	left:	s.offsetLeft
			,	width:	s.outerWidth
			,	height:	s.outerHeight
			});
		/* ALT Method...
		var $P = $Ps[pane];
		$M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight });
		*/
	}
,	sizeMasks = function () {
		$Ms.each( sizeMask ); // resize all 'visible' masks
	}

,	showMasks = function (panes, onlyForObjects) {
		var a	= panes ? panes.split(",") : $.layout.config.allPanes
		,	z	= options.zIndexes
		,	o, s;
		$.each(a, function(i,p){
			s = state[p];
			o = options[p];
			if (s.isVisible && ( (!onlyForObjects && o.maskContents) || o.maskObjects )) {
				getMasks(p).each(function(){
					sizeMask.call(this);
					this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1
					this.style.display = "block";
				});
			}
		});
	}

,	hideMasks = function () {
		// ensure no pane is resizing - could be a timing issue
		var skip;
		$.each( $.layout.config.borderPanes, function(i,p){
			if (state[p].isResizing) {
				skip = true;
				return false; // BREAK
			}
		});
		if (!skip)
			$Ms.hide(); // hide ALL masks
	}

,	getMasks = function (pane) {
		var $Masks	= $([])
		,	$M, i = 0, c = $Ms.length
		;
		for (; i<c; i++) {
			$M = $Ms.eq(i);
			if ($M.data("layoutMask") === pane)
				$Masks = $Masks.add( $M );
		}
		if ($Masks.length)
			return $Masks;
		else
			return createMasks(pane);
	}

	/**
	 *	createMasks
	 *
	 *	Generates both DIV (ALWAYS used) and IFRAME (optional) elements as masks
	 *	An IFRAME mask is created *under* the DIV when maskObjects=true, because a DIV cannot mask an applet
	 */
,	createMasks = function (pane) {
		var
			$P		= $Ps[pane]
		,	s		= state[pane]
		,	o		= options[pane]
		,	z		= options.zIndexes
		//,	objMask	= o.maskObjects && s.tagName != "IFRAME" // check for option
		,	$Masks	= $([])
		,	isIframe, el, $M, css, i
		;
		if (!o.maskContents && !o.maskObjects) return $Masks;
		// if o.maskObjects=true, then loop TWICE to create BOTH kinds of mask, else only create a DIV
		for (i=0; i < (o.maskObjects ? 2 : 1); i++) {
			isIframe = o.maskObjects && i==0;
			el = document.createElement( isIframe ? "iframe" : "div" );
			$M = $(el).data("layoutMask", pane); // add data to relate mask to pane
			el.className = "ui-layout-mask ui-layout-mask-"+ pane; // for user styling
			css = el.style;
			// styles common to both DIVs and IFRAMES
			css.display		= "block";
			css.position	= "absolute";
			if (isIframe) { // IFRAME-only props
				el.frameborder = 0;
				el.src		= "about:blank";
				css.opacity	= 0;
				css.filter	= "Alpha(Opacity='0')";
				css.border	= 0;
			}
			// if pane is an IFRAME, then must mask the pane itself
			if (s.tagName == "IFRAME") {
				// NOTE sizing done by a subroutine so can be called during live-resizing
				css.zIndex	= z.pane_normal+1; // 1-higher than pane
				$N.append( el ); // append to LAYOUT CONTAINER
			}
			// otherwise put masks *inside the pane* to mask its contents
			else {
				$M.addClass("ui-layout-mask-inside-pane");
				css.zIndex	= o.maskZindex || z.content_mask; // usually 1, but customizable
				css.top		= 0;
				css.left	= 0;
				css.width	= "100%";
				css.height	= "100%";
				$P.append( el ); // append INSIDE pane element
			}
			// add to return object
			$Masks = $Masks.add( el );
			// add Mask to cached array so can be resized & reused
			$Ms = $Ms.add( el );
		}
		return $Masks;
	}


	/**
	* Destroy this layout and reset all elements
	*
	* @param {boolean=}	[destroyChildren=false]		Destory Child-Layouts first?
	*/
,	destroy = function (evt_or_destroyChildren, destroyChildren) {
		// UNBIND layout events and remove global object
		$(window).unbind("."+ sID);		// resize & unload
		$(document).unbind("."+ sID);	// keyDown (hotkeys)

		if (typeof evt_or_destroyChildren === "object")
			// stopPropagation if called by trigger("layoutdestroy") - use evtPane utility 
			evtPane(evt_or_destroyChildren);
		else // no event, so transfer 1st param to destroyChildren param
			destroyChildren = evt_or_destroyChildren;

		// need to look for parent layout BEFORE we remove the container data, else skips a level
		//var parentPane = Instance.hasParentLayout ? $.layout.getParentPaneInstance( $N ) : null;

		// reset layout-container
		$N	.clearQueue()
			.removeData("layout")
			.removeData("layoutContainer")
			.removeClass(options.containerClass)
			.unbind("."+ sID) // remove ALL Layout events
		;

		// remove all mask elements that have been created
		$Ms.remove();

		// loop all panes to remove layout classes, attributes and bindings
		$.each(_c.allPanes, function (i, pane) {
			removePane( pane, false, true, destroyChildren ); // true = skipResize
		});

		// do NOT reset container CSS if is a 'pane' (or 'content') in an outer-layout - ie, THIS layout is 'nested'
		var css = "layoutCSS";
		if ($N.data(css) && !$N.data("layoutRole")) // RESET CSS
			$N.css( $N.data(css) ).removeData(css);

		// for full-page layouts, also reset the <HTML> CSS
		if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET <HTML> CSS
			$N.css( $N.data(css) ).removeData(css);

		// trigger plugins for this layout, if there are any
		runPluginCallbacks( Instance, $.layout.onDestroy );

		// trigger state-management and onunload callback
		unload();

		// clear the Instance of everything except for container & options (so could recreate)
		// RE-CREATE: myLayout = myLayout.container.layout( myLayout.options );
		for (n in Instance)
			if (!n.match(/^(container|options)$/)) delete Instance[ n ];
		// add a 'destroyed' flag to make it easy to check
		Instance.destroyed = true;

		// if this is a child layout, CLEAR the child-pointer in the parent
		/* for now the pointer REMAINS, but with only container, options and destroyed keys
		if (parentPane) {
			var layout = parentPane.pane.data("parentLayout");
			parentPane.child = layout.children[ parentPane.name ] = null;
		}
		*/

		return Instance; // for coding convenience
	}

	/**
	* Remove a pane from the layout - subroutine of destroy()
	*
	* @see  destroy()
	* @param {string|Object}	evt_or_pane			The pane to process
	* @param {boolean=}			[remove=false]		Remove the DOM element?
	* @param {boolean=}			[skipResize=false]	Skip calling resizeAll()?
	* @param {boolean=}			[destroyChild=true]	Destroy Child-layouts? If not passed, obeys options setting
	*/
,	removePane = function (evt_or_pane, remove, skipResize, destroyChild) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$P	= $Ps[pane]
		,	$C	= $Cs[pane]
		,	$R	= $Rs[pane]
		,	$T	= $Ts[pane]
		;
		// NOTE: elements can still exist even after remove()
		//		so check for missing data(), which is cleared by removed()
		if ($P && $.isEmptyObject( $P.data() )) $P = false;
		if ($C && $.isEmptyObject( $C.data() )) $C = false;
		if ($R && $.isEmptyObject( $R.data() )) $R = false;
		if ($T && $.isEmptyObject( $T.data() )) $T = false;

		if ($P) $P.stop(true, true);

		//	check for a child layout
		var	o	= options[pane]
		,	s	= state[pane]
		,	d	= "layout"
		,	css	= "layoutCSS"
		,	child	= children[pane] || ($P ? $P.data(d) : 0) || ($C ? $C.data(d) : 0) || null
		,	destroy	= destroyChild !== undefined ? destroyChild : o.destroyChildLayout
		;

		// FIRST destroy the child-layout(s)
		if (destroy && child && !child.destroyed) {
			child.destroy(true);	// tell child-layout to destroy ALL its child-layouts too
			if (child.destroyed)	// destroy was successful
				child = null;		// clear pointer for logic below 
		}

		if ($P && remove && !child)
			$P.remove();
		else if ($P && $P[0]) {
			//	create list of ALL pane-classes that need to be removed
			var	root	= o.paneClass // default="ui-layout-pane"
			,	pRoot	= root +"-"+ pane // eg: "ui-layout-pane-west"
			,	_open	= "-open"
			,	_sliding= "-sliding"
			,	_closed	= "-closed"
			,	classes	= [	root, root+_open, root+_closed, root+_sliding,		// generic classes
							pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ]	// pane-specific classes
			;
			$.merge(classes, getHoverClasses($P, true)); // ADD hover-classes
			// remove all Layout classes from pane-element
			$P	.removeClass( classes.join(" ") ) // remove ALL pane-classes
				.removeData("parentLayout")
				.removeData("layoutPane")
				.removeData("layoutRole")
				.removeData("layoutEdge")
				.removeData("autoHidden")	// in case set
				.unbind("."+ sID) // remove ALL Layout events
				// TODO: remove these extra unbind commands when jQuery is fixed
				//.unbind("mouseenter"+ sID)
				//.unbind("mouseleave"+ sID)
			;
			// do NOT reset CSS if this pane/content is STILL the container of a nested layout!
			// the nested layout will reset its 'container' CSS when/if it is destroyed
			if ($C && $C.data(d)) {
				// a content-div may not have a specific width, so give it one to contain the Layout
				$C.width( $C.width() );
				child.resizeAll(); // now resize the Layout
			}
			else if ($C)
				$C.css( $C.data(css) ).removeData(css).removeData("layoutRole");
			// remove pane AFTER content in case there was a nested layout
			if (!$P.data(d))
				$P.css( $P.data(css) ).removeData(css);
		}

		// REMOVE pane resizer and toggler elements
		if ($T) $T.remove();
		if ($R) $R.remove();

		// CLEAR all pointers and state data
		Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = children[pane] = false;
		s = { removed: true };

		if (!skipResize)
			resizeAll();
	}


/*
 * ###########################
 *	   ACTION METHODS
 * ###########################
 */

,	_hidePane = function (pane) {
		var $P	= $Ps[pane]
		,	o	= options[pane]
		,	s	= $P[0].style
		;
		if (o.useOffscreenClose) {
			if (!$P.data(_c.offscreenReset))
				$P.data(_c.offscreenReset, { left: s.left, right: s.right });
			$P.css( _c.offscreenCSS );
		}
		else
			$P.hide().removeData(_c.offscreenReset);
	}

,	_showPane = function (pane) {
		var $P	= $Ps[pane]
		,	o	= options[pane]
		,	off	= _c.offscreenCSS
		,	old	= $P.data(_c.offscreenReset)
		,	s	= $P[0].style
		;
		$P	.show() // ALWAYS show, just in case
			.removeData(_c.offscreenReset);
		if (o.useOffscreenClose && old) {
			if (s.left == off.left)
				s.left = old.left;
			if (s.right == off.right)
				s.right = old.right;
		}
	}


	/**
	* Completely 'hides' a pane, including its spacing - as if it does not exist
	* The pane is not actually 'removed' from the source, so can use 'show' to un-hide it
	*
	* @param {string|Object}	evt_or_pane			The pane being hidden, ie: north, south, east, or west
	* @param {boolean=}			[noAnimation=false]	
	*/
,	hide = function (evt_or_pane, noAnimation) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	o	= options[pane]
		,	s	= state[pane]
		,	$P	= $Ps[pane]
		,	$R	= $Rs[pane]
		;
		if (!$P || s.isHidden) return; // pane does not exist OR is already hidden

		// onhide_start callback - will CANCEL hide if returns false
		if (state.initialized && false === _runCallbacks("onhide_start", pane)) return;

		s.isSliding = false; // just in case

		// now hide the elements
		if ($R) $R.hide(); // hide resizer-bar
		if (!state.initialized || s.isClosed) {
			s.isClosed = true; // to trigger open-animation on show()
			s.isHidden  = true;
			s.isVisible = false;
			if (!state.initialized)
				_hidePane(pane); // no animation when loading page
			sizeMidPanes(_c[pane].dir === "horz" ? "" : "center");
			if (state.initialized || o.triggerEventsOnLoad)
				_runCallbacks("onhide_end", pane);
		}
		else {
			s.isHiding = true; // used by onclose
			close(pane, false, noAnimation); // adjust all panes to fit
		}
	}

	/**
	* Show a hidden pane - show as 'closed' by default unless openPane = true
	*
	* @param {string|Object}	evt_or_pane			The pane being opened, ie: north, south, east, or west
	* @param {boolean=}			[openPane=false]
	* @param {boolean=}			[noAnimation=false]
	* @param {boolean=}			[noAlert=false]
	*/
,	show = function (evt_or_pane, openPane, noAnimation, noAlert) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	o	= options[pane]
		,	s	= state[pane]
		,	$P	= $Ps[pane]
		,	$R	= $Rs[pane]
		;
		if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden

		// onshow_start callback - will CANCEL show if returns false
		if (false === _runCallbacks("onshow_start", pane)) return;

		s.isSliding = false; // just in case
		s.isShowing = true; // used by onopen/onclose
		//s.isHidden  = false; - will be set by open/close - if not cancelled

		// now show the elements
		//if ($R) $R.show(); - will be shown by open/close
		if (openPane === false)
			close(pane, true); // true = force
		else
			open(pane, false, noAnimation, noAlert); // adjust all panes to fit
	}


	/**
	* Toggles a pane open/closed by calling either open or close
	*
	* @param {string|Object}	evt_or_pane		The pane being toggled, ie: north, south, east, or west
	* @param {boolean=}			[slide=false]
	*/
,	toggle = function (evt_or_pane, slide) {
		if (!isInitialized()) return;
		var	evt		= evtObj(evt_or_pane)
		,	pane	= evtPane.call(this, evt_or_pane)
		,	s		= state[pane]
		;
		if (evt) // called from to $R.dblclick OR triggerPaneEvent
			evt.stopImmediatePropagation();
		if (s.isHidden)
			show(pane); // will call 'open' after unhiding it
		else if (s.isClosed)
			open(pane, !!slide);
		else
			close(pane);
	}


	/**
	* Utility method used during init or other auto-processes
	*
	* @param {string}	pane   The pane being closed
	* @param {boolean=}	[setHandles=false]
	*/
,	_closePane = function (pane, setHandles) {
		var
			$P	= $Ps[pane]
		,	s	= state[pane]
		;
		_hidePane(pane);
		s.isClosed = true;
		s.isVisible = false;
		// UNUSED: if (setHandles) setAsClosed(pane, true); // true = force
	}

	/**
	* Close the specified pane (animation optional), and resize all other panes as needed
	*
	* @param {string|Object}	evt_or_pane			The pane being closed, ie: north, south, east, or west
	* @param {boolean=}			[force=false]
	* @param {boolean=}			[noAnimation=false]
	* @param {boolean=}			[skipCallback=false]
	*/
,	close = function (evt_or_pane, force, noAnimation, skipCallback) {
		var	pane = evtPane.call(this, evt_or_pane);
		// if pane has been initialized, but NOT the complete layout, close pane instantly
		if (!state.initialized && $Ps[pane]) {
			_closePane(pane); // INIT pane as closed
			return;
		}
		if (!isInitialized()) return;

		var
			$P	= $Ps[pane]
		,	$R	= $Rs[pane]
		,	$T	= $Ts[pane]
		,	o	= options[pane]
		,	s	= state[pane]
		,	c	= _c[pane]
		,	doFX, isShowing, isHiding, wasSliding;

		// QUEUE in case another action/animation is in progress
		$N.queue(function( queueNext ){
	
			if ( !$P
			||	(!o.closable && !s.isShowing && !s.isHiding)	// invalid request // (!o.resizable && !o.closable) ???
			||	(!force && s.isClosed && !s.isShowing)			// already closed
			) return queueNext();

			// onclose_start callback - will CANCEL hide if returns false
			// SKIP if just 'showing' a hidden pane as 'closed'
			var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane);

			// transfer logic vars to temp vars
			isShowing	= s.isShowing;
			isHiding	= s.isHiding;
			wasSliding	= s.isSliding;
			// now clear the logic vars (REQUIRED before aborting)
			delete s.isShowing;
			delete s.isHiding;

			if (abort) return queueNext();

			doFX		= !noAnimation && !s.isClosed && (o.fxName_close != "none");
			s.isMoving	= true;
			s.isClosed	= true;
			s.isVisible	= false;
			// update isHidden BEFORE sizing panes
			if (isHiding) s.isHidden = true;
			else if (isShowing) s.isHidden = false;

			if (s.isSliding) // pane is being closed, so UNBIND trigger events
				bindStopSlidingEvents(pane, false); // will set isSliding=false
			else // resize panes adjacent to this one
				sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback

			// if this pane has a resizer bar, move it NOW - before animation
			setAsClosed(pane);

			// CLOSE THE PANE
			if (doFX) { // animate the close
				// mask panes with objects
				var masks = "center"+ (c.dir=="horz" ? ",west,east" : "");
				showMasks( masks, true );	// true = ONLY mask panes with maskObjects=true
				lockPaneForFX(pane, true);	// need to set left/top so animation will work
				$P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () {
					lockPaneForFX(pane, false); // undo
					if (s.isClosed) close_2();
					queueNext();
				});
			}
			else { // hide the pane without animation
				_hidePane(pane);
				close_2();
				queueNext();
			};
		});

		// SUBROUTINE
		function close_2 () {
			s.isMoving	= false;
			bindStartSlidingEvent(pane, true); // will enable if o.slidable = true

			// if opposite-pane was autoClosed, see if it can be autoOpened now
			var altPane = _c.oppositeEdge[pane];
			if (state[ altPane ].noRoom) {
				setSizeLimits( altPane );
				makePaneFit( altPane );
			}

			// hide any masks shown while closing
			hideMasks();

			if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) {
				// onclose callback - UNLESS just 'showing' a hidden pane as 'closed'
				if (!isShowing)	_runCallbacks("onclose_end", pane);
				// onhide OR onshow callback
				if (isShowing)	_runCallbacks("onshow_end", pane);
				if (isHiding)	_runCallbacks("onhide_end", pane);
			}
		}
	}

	/**
	* @param {string}	pane	The pane just closed, ie: north, south, east, or west
	*/
,	setAsClosed = function (pane) {
		var
			$P		= $Ps[pane]
		,	$R		= $Rs[pane]
		,	$T		= $Ts[pane]
		,	o		= options[pane]
		,	s		= state[pane]
		,	side	= _c[pane].side.toLowerCase()
		,	inset	= "inset"+ _c[pane].side
		,	rClass	= o.resizerClass
		,	tClass	= o.togglerClass
		,	_pane	= "-"+ pane // used for classNames
		,	_open	= "-open"
		,	_sliding= "-sliding"
		,	_closed	= "-closed"
		;
		$R
			.css(side, sC[inset]) // move the resizer
			.removeClass( rClass+_open +" "+ rClass+_pane+_open )
			.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding )
			.addClass( rClass+_closed +" "+ rClass+_pane+_closed )
			.unbind("dblclick."+ sID)
		;
		// DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent?
		if (o.resizable && $.layout.plugins.draggable)
			$R
				.draggable("disable")
				.removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here
				.css("cursor", "default")
				.attr("title","")
			;

		// if pane has a toggler button, adjust that too
		if ($T) {
			$T
				.removeClass( tClass+_open +" "+ tClass+_pane+_open )
				.addClass( tClass+_closed +" "+ tClass+_pane+_closed )
				.attr("title", o.tips.Open) // may be blank
			;
			// toggler-content - if exists
			$T.children(".content-open").hide();
			$T.children(".content-closed").css("display","block");
		}

		// sync any 'pin buttons'
		syncPinBtns(pane, false);

		if (state.initialized) {
			// resize 'length' and position togglers for adjacent panes
			sizeHandles();
		}
	}

	/**
	* Open the specified pane (animation optional), and resize all other panes as needed
	*
	* @param {string|Object}	evt_or_pane			The pane being opened, ie: north, south, east, or west
	* @param {boolean=}			[slide=false]
	* @param {boolean=}			[noAnimation=false]
	* @param {boolean=}			[noAlert=false]
	*/
,	open = function (evt_or_pane, slide, noAnimation, noAlert) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$P	= $Ps[pane]
		,	$R	= $Rs[pane]
		,	$T	= $Ts[pane]
		,	o	= options[pane]
		,	s	= state[pane]
		,	c	= _c[pane]
		,	doFX, isShowing
		;
		// QUEUE in case another action/animation is in progress
		$N.queue(function( queueNext ){

			if ( !$P
			||	(!o.resizable && !o.closable && !s.isShowing)	// invalid request
			||	(s.isVisible && !s.isSliding)					// already open
			) return queueNext();

			// pane can ALSO be unhidden by just calling show(), so handle this scenario
			if (s.isHidden && !s.isShowing) {
				queueNext(); // call before show() because it needs the queue free
				show(pane, true);
				return;
			}

			if (o.autoResize && s.size != o.size) // resize pane to original size set in options
				sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation
			else
				// make sure there is enough space available to open the pane
				setSizeLimits(pane, slide);

			// onopen_start callback - will CANCEL open if returns false
			var cbReturn = _runCallbacks("onopen_start", pane);

			if (cbReturn === "abort")
				return queueNext();

			// update pane-state again in case options were changed in onopen_start
			if (cbReturn !== "NC") // NC = "No Callback"
				setSizeLimits(pane, slide);

			if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN!
				syncPinBtns(pane, false); // make sure pin-buttons are reset
				if (!noAlert && o.tips.noRoomToOpen)
					alert(o.tips.noRoomToOpen);
				return queueNext(); // ABORT
			}

			if (slide) // START Sliding - will set isSliding=true
				bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane
			else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead
				bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false
			else if (o.slidable)
				bindStartSlidingEvent(pane, false); // UNBIND trigger events

			s.noRoom = false; // will be reset by makePaneFit if 'noRoom'
			makePaneFit(pane);

			// transfer logic var to temp var
			isShowing = s.isShowing;
			// now clear the logic var
			delete s.isShowing;

			doFX		= !noAnimation && s.isClosed && (o.fxName_open != "none");
			s.isMoving	= true;
			s.isVisible	= true;
			s.isClosed	= false;
			// update isHidden BEFORE sizing panes - WHY??? Old?
			if (isShowing) s.isHidden = false;

			if (doFX) { // ANIMATE
				// mask panes with objects
				var masks = "center"+ (c.dir=="horz" ? ",west,east" : "");
				if (s.isSliding) masks += ","+ _c.oppositeEdge[pane];
				showMasks( masks, true );	// true = ONLY mask panes with maskObjects=true
				lockPaneForFX(pane, true);	// need to set left/top so animation will work
				$P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() {
					lockPaneForFX(pane, false); // undo
					if (s.isVisible) open_2(); // continue
					queueNext();
				});
			}
			else { // no animation
				_showPane(pane);// just show pane and...
				open_2();		// continue
				queueNext();
			};
		});

		// SUBROUTINE
		function open_2 () {
			s.isMoving	= false;

			// cure iframe display issues
			_fixIframe(pane);

			// NOTE: if isSliding, then other panes are NOT 'resized'
			if (!s.isSliding) { // resize all panes adjacent to this one
				hideMasks(); // remove any masks shown while opening
				sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback
			}

			// set classes, position handles and execute callbacks...
			setAsOpen(pane);
		};
	
	}

	/**
	* @param {string}	pane		The pane just opened, ie: north, south, east, or west
	* @param {boolean=}	[skipCallback=false]
	*/
,	setAsOpen = function (pane, skipCallback) {
		var 
			$P		= $Ps[pane]
		,	$R		= $Rs[pane]
		,	$T		= $Ts[pane]
		,	o		= options[pane]
		,	s		= state[pane]
		,	side	= _c[pane].side.toLowerCase()
		,	inset	= "inset"+ _c[pane].side
		,	rClass	= o.resizerClass
		,	tClass	= o.togglerClass
		,	_pane	= "-"+ pane // used for classNames
		,	_open	= "-open"
		,	_closed	= "-closed"
		,	_sliding= "-sliding"
		;
		$R
			.css(side, sC[inset] + getPaneSize(pane)) // move the resizer
			.removeClass( rClass+_closed +" "+ rClass+_pane+_closed )
			.addClass( rClass+_open +" "+ rClass+_pane+_open )
		;
		if (s.isSliding)
			$R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding )
		else // in case 'was sliding'
			$R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding )

		if (o.resizerDblClickToggle)
			$R.bind("dblclick", toggle );
		removeHover( 0, $R ); // remove hover classes
		if (o.resizable && $.layout.plugins.draggable)
			$R	.draggable("enable")
				.css("cursor", o.resizerCursor)
				.attr("title", o.tips.Resize);
		else if (!s.isSliding)
			$R.css("cursor", "default"); // n-resize, s-resize, etc

		// if pane also has a toggler button, adjust that too
		if ($T) {
			$T	.removeClass( tClass+_closed +" "+ tClass+_pane+_closed )
				.addClass( tClass+_open +" "+ tClass+_pane+_open )
				.attr("title", o.tips.Close); // may be blank
			removeHover( 0, $T ); // remove hover classes
			// toggler-content - if exists
			$T.children(".content-closed").hide();
			$T.children(".content-open").css("display","block");
		}

		// sync any 'pin buttons'
		syncPinBtns(pane, !s.isSliding);

		// update pane-state dimensions - BEFORE resizing content
		$.extend(s, elDims($P));

		if (state.initialized) {
			// resize resizer & toggler sizes for all panes
			sizeHandles();
			// resize content every time pane opens - to be sure
			sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving'
		}

		if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) {
			// onopen callback
			_runCallbacks("onopen_end", pane);
			// onshow callback - TODO: should this be here?
			if (s.isShowing) _runCallbacks("onshow_end", pane);

			// ALSO call onresize because layout-size *may* have changed while pane was closed
			if (state.initialized)
				_runCallbacks("onresize_end", pane);
		}

		// TODO: Somehow sizePane("north") is being called after this point???
	}


	/**
	* slideOpen / slideClose / slideToggle
	*
	* Pass-though methods for sliding
	*/
,	slideOpen = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	evt		= evtObj(evt_or_pane)
		,	pane	= evtPane.call(this, evt_or_pane)
		,	s		= state[pane]
		,	delay	= options[pane].slideDelay_open
		;
		// prevent event from triggering on NEW resizer binding created below
		if (evt) evt.stopImmediatePropagation();

		if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0)
			// trigger = mouseenter - use a delay
			timer.set(pane+"_openSlider", open_NOW, delay);
		else
			open_NOW(); // will unbind events if is already open

		/**
		* SUBROUTINE for timed open
		*/
		function open_NOW () {
			if (!s.isClosed) // skip if no longer closed!
				bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane
			else if (!s.isMoving)
				open(pane, true); // true = slide - open() will handle binding
		};
	}

,	slideClose = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	evt		= evtObj(evt_or_pane)
		,	pane	= evtPane.call(this, evt_or_pane)
		,	o		= options[pane]
		,	s		= state[pane]
		,	delay	= s.isMoving ? 1000 : 300 // MINIMUM delay - option may override
		;
		if (s.isClosed || s.isResizing)
			return; // skip if already closed OR in process of resizing
		else if (o.slideTrigger_close === "click")
			close_NOW(); // close immediately onClick
		else if (o.preventQuickSlideClose && s.isMoving)
			return; // handle Chrome quick-close on slide-open
		else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane]))
			return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE
		else if (evt) // trigger = mouseleave - use a delay
			// 1 sec delay if 'opening', else .3 sec
			timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay));
		else // called programically
			close_NOW();

		/**
		* SUBROUTINE for timed close
		*/
		function close_NOW () {
			if (s.isClosed) // skip 'close' if already closed!
				bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here?
			else if (!s.isMoving)
				close(pane); // close will handle unbinding
		};
	}

	/**
	* @param {string|Object}	evt_or_pane		The pane being opened, ie: north, south, east, or west
	*/
,	slideToggle = function (evt_or_pane) {
		var pane = evtPane.call(this, evt_or_pane);
		toggle(pane, true);
	}


	/**
	* Must set left/top on East/South panes so animation will work properly
	*
	* @param {string}	pane	The pane to lock, 'east' or 'south' - any other is ignored!
	* @param {boolean}	doLock  true = set left/top, false = remove
	*/
,	lockPaneForFX = function (pane, doLock) {
		var $P	= $Ps[pane]
		,	s	= state[pane]
		,	o	= options[pane]
		,	z	= options.zIndexes
		;
		if (doLock) {
			$P.css({ zIndex: z.pane_animate }); // overlay all elements during animation
			if (pane=="south")
				$P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() });
			else if (pane=="east")
				$P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() });
		}
		else { // animation DONE - RESET CSS
			// TODO: see if this can be deleted. It causes a quick-close when sliding in Chrome
			$P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) });
			if (pane=="south")
				$P.css({ top: "auto" });
			// if pane is positioned 'off-screen', then DO NOT screw with it!
			else if (pane=="east" && !$P.css("left").match(/\-99999/))
				$P.css({ left: "auto" });
			// fix anti-aliasing in IE - only needed for animations that change opacity
			if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1)
				$P[0].style.removeAttribute('filter');
		}
	}


	/**
	* Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger
	*
	* @see  open(), close()
	* @param {string}	pane	The pane to enable/disable, 'north', 'south', etc.
	* @param {boolean}	enable	Enable or Disable sliding?
	*/
,	bindStartSlidingEvent = function (pane, enable) {
		var o		= options[pane]
		,	$P		= $Ps[pane]
		,	$R		= $Rs[pane]
		,	evtName	= o.slideTrigger_open.toLowerCase()
		;
		if (!$R || (enable && !o.slidable)) return;

		// make sure we have a valid event
		if (evtName.match(/mouseover/))
			evtName = o.slideTrigger_open = "mouseenter";
		else if (!evtName.match(/(click|dblclick|mouseenter)/)) 
			evtName = o.slideTrigger_open = "click";

		$R
			// add or remove event
			[enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen)
			// set the appropriate cursor & title/tip
			.css("cursor", enable ? o.sliderCursor : "default")
			.attr("title", enable ? o.tips.Slide : "")
		;
	}

	/**
	* Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed
	* Also increases zIndex when pane is sliding open
	* See bindStartSlidingEvent for code to control 'slide open'
	*
	* @see  slideOpen(), slideClose()
	* @param {string}	pane	The pane to process, 'north', 'south', etc.
	* @param {boolean}	enable	Enable or Disable events?
	*/
,	bindStopSlidingEvents = function (pane, enable) {
		var	o		= options[pane]
		,	s		= state[pane]
		,	c		= _c[pane]
		,	z		= options.zIndexes
		,	evtName	= o.slideTrigger_close.toLowerCase()
		,	action	= (enable ? "bind" : "unbind")
		,	$P		= $Ps[pane]
		,	$R		= $Rs[pane]
		;
		s.isSliding = enable; // logic
		timer.clear(pane+"_closeSlider"); // just in case

		// remove 'slideOpen' event from resizer
		// ALSO will raise the zIndex of the pane & resizer
		if (enable) bindStartSlidingEvent(pane, false);

		// RE/SET zIndex - increases when pane is sliding-open, resets to normal when not
		$P.css("zIndex", enable ? z.pane_sliding : z.pane_normal);
		$R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1

		// make sure we have a valid event
		if (!evtName.match(/(click|mouseleave)/))
			evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout'

		// add/remove slide triggers
		$R[action](evtName, slideClose); // base event on resize
		// need extra events for mouseleave
		if (evtName === "mouseleave") {
			// also close on pane.mouseleave
			$P[action]("mouseleave."+ sID, slideClose);
			// cancel timer when mouse moves between 'pane' and 'resizer'
			$R[action]("mouseenter."+ sID, cancelMouseOut);
			$P[action]("mouseenter."+ sID, cancelMouseOut);
		}

		if (!enable)
			timer.clear(pane+"_closeSlider");
		else if (evtName === "click" && !o.resizable) {
			// IF pane is not resizable (which already has a cursor and tip) 
			// then set the a cursor & title/tip on resizer when sliding
			$R.css("cursor", enable ? o.sliderCursor : "default");
			$R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane"
		}

		// SUBROUTINE for mouseleave timer clearing
		function cancelMouseOut (evt) {
			timer.clear(pane+"_closeSlider");
			evt.stopPropagation();
		}
	}


	/**
	* Hides/closes a pane if there is insufficient room - reverses this when there is room again
	* MUST have already called setSizeLimits() before calling this method
	*
	* @param {string}	pane					The pane being resized
	* @param {boolean=}	[isOpening=false]		Called from onOpen?
	* @param {boolean=}	[skipCallback=false]	Should the onresize callback be run?
	* @param {boolean=}	[force=false]
	*/
,	makePaneFit = function (pane, isOpening, skipCallback, force) {
		var
			o	= options[pane]
		,	s	= state[pane]
		,	c	= _c[pane]
		,	$P	= $Ps[pane]
		,	$R	= $Rs[pane]
		,	isSidePane 	= c.dir==="vert"
		,	hasRoom		= false
		;
		// special handling for center & east/west panes
		if (pane === "center" || (isSidePane && s.noVerticalRoom)) {
			// see if there is enough room to display the pane
			// ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth);
			hasRoom = (s.maxHeight >= 0);
			if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now
				_showPane(pane);
				if ($R) $R.show();
				s.isVisible = true;
				s.noRoom = false;
				if (isSidePane) s.noVerticalRoom = false;
				_fixIframe(pane);
			}
			else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now
				_hidePane(pane);
				if ($R) $R.hide();
				s.isVisible = false;
				s.noRoom = true;
			}
		}

		// see if there is enough room to fit the border-pane
		if (pane === "center") {
			// ignore center in this block
		}
		else if (s.minSize <= s.maxSize) { // pane CAN fit
			hasRoom = true;
			if (s.size > s.maxSize) // pane is too big - shrink it
				sizePane(pane, s.maxSize, skipCallback, force, true); // true = noAnimation
			else if (s.size < s.minSize) // pane is too small - enlarge it
				sizePane(pane, s.minSize, skipCallback, force, true);
			// need s.isVisible because new pseudoClose method keeps pane visible, but off-screen
			else if ($R && s.isVisible && $P.is(":visible")) {
				// make sure resizer-bar is positioned correctly
				// handles situation where nested layout was 'hidden' when initialized
				var	side = c.side.toLowerCase()
				,	pos  = s.size + sC["inset"+ c.side]
				;
				if ($.layout.cssNum($R, side) != pos) $R.css( side, pos );
			}

			// if was previously hidden due to noRoom, then RESET because NOW there is room
			if (s.noRoom) {
				// s.noRoom state will be set by open or show
				if (s.wasOpen && o.closable) {
					if (o.autoReopen)
						open(pane, false, true, true); // true = noAnimation, true = noAlert
					else // leave the pane closed, so just update state
						s.noRoom = false;
				}
				else
					show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert
			}
		}
		else { // !hasRoom - pane CANNOT fit
			if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now...
				s.noRoom = true; // update state
				s.wasOpen = !s.isClosed && !s.isSliding;
				if (s.isClosed){} // SKIP
				else if (o.closable) // 'close' if possible
					close(pane, true, true); // true = force, true = noAnimation
				else // 'hide' pane if cannot just be closed
					hide(pane, true); // true = noAnimation
			}
		}
	}


	/**
	* sizePane / manualSizePane
	* sizePane is called only by internal methods whenever a pane needs to be resized
	* manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized'
	*
	* @param {string|Object}	evt_or_pane				The pane being resized
	* @param {number}			size					The *desired* new size for this pane - will be validated
	* @param {boolean=}			[skipCallback=false]	Should the onresize callback be run?
	* @param {boolean=}			[noAnimation=false]
	*/
,	manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	o	= options[pane]
		,	s	= state[pane]
		//	if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete...
		,	forceResize = o.livePaneResizing && !s.isResizing
		;
		// ANY call to manualSizePane disables autoResize - ie, percentage sizing
		o.autoResize = false;
		// flow-through...
		sizePane(pane, size, skipCallback, forceResize, noAnimation); // will animate resize if option enabled
	}

	/**
	* @param {string|Object}	evt_or_pane				The pane being resized
	* @param {number}			size					The *desired* new size for this pane - will be validated
	* @param {boolean=}			[skipCallback=false]	Should the onresize callback be run?
	* @param {boolean=}			[force=false]			Force resizing even if does not seem necessary
	* @param {boolean=}			[noAnimation=false]
	*/
,	sizePane = function (evt_or_pane, size, skipCallback, force, noAnimation) {
		if (!isInitialized()) return;
		var	pane	= evtPane.call(this, evt_or_pane) // probably NEVER called from event?
		,	o		= options[pane]
		,	s		= state[pane]
		,	$P		= $Ps[pane]
		,	$R		= $Rs[pane]
		,	side	= _c[pane].side.toLowerCase()
		,	dimName	= _c[pane].sizeType.toLowerCase()
		,	inset	= "inset"+ _c[pane].side
		,	skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize
		,	doFX	= noAnimation !== true && o.animatePaneSizing
		,	oldSize, newSize
		;
		// QUEUE in case another action/animation is in progress
		$N.queue(function( queueNext ){
			// calculate 'current' min/max sizes
			setSizeLimits(pane); // update pane-state
			oldSize = s.size;
			size = _parseSize(pane, size); // handle percentages & auto
			size = max(size, _parseSize(pane, o.minSize));
			size = min(size, s.maxSize);
			if (size < s.minSize) { // not enough room for pane!
				queueNext(); // call before makePaneFit() because it needs the queue free
				makePaneFit(pane, false, skipCallback);	// will hide or close pane
				return;
			}

			// IF newSize is same as oldSize, then nothing to do - abort
			if (!force && size === oldSize)
				return queueNext();

			// onresize_start callback CANNOT cancel resizing because this would break the layout!
			if (!skipCallback && state.initialized && s.isVisible)
				_runCallbacks("onresize_start", pane);

			// resize the pane, and make sure its visible
			newSize = cssSize(pane, size);

			if (doFX && $P.is(":visible")) { // ANIMATE
				var fx		= $.layout.effects.size[pane] || $.layout.effects.size.all
				,	easing	= o.fxSettings_size.easing || fx.easing
				,	z		= options.zIndexes
				,	props	= {};
				props[ dimName ] = newSize +'px';
				s.isMoving = true;
				// overlay all elements during animation
				$P.css({ zIndex: z.pane_animate })
				  .show().animate( props, o.fxSpeed_size, easing, function(){
					// reset zIndex after animation
					$P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) });
					s.isMoving = false;
					sizePane_2(); // continue
					queueNext();
				});
			}
			else { // no animation
				$P.css( dimName, newSize );	// resize pane
				// if pane is visible, then 
				if ($P.is(":visible"))
					sizePane_2(); // continue
				else {
					// pane is NOT VISIBLE, so just update state data...
					// when pane is *next opened*, it will have the new size
					s.size = size;				// update state.size
					$.extend(s, elDims($P));	// update state dimensions
				}
				queueNext();
			};

		});

		// SUBROUTINE
		function sizePane_2 () {
			/*	Panes are sometimes not sized precisely in some browsers!?
			 *	This code will resize the pane up to 3 times to nudge the pane to the correct size
			 */
			var	actual	= dimName==='width' ? $P.outerWidth() : $P.outerHeight()
			,	tries	= [{
						   	pane:		pane
						,	count:		1
						,	target:		size
						,	actual:		actual
						,	correct:	(size === actual)
						,	attempt:	size
						,	cssSize:	newSize
						}]
			,	lastTry = tries[0]
			,	thisTry	= {}
			,	msg		= 'Inaccurate size after resizing the '+ pane +'-pane.'
			;
			while ( !lastTry.correct ) {
				thisTry = { pane: pane, count: lastTry.count+1, target: size };

				if (lastTry.actual > size)
					thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size));
				else // lastTry.actual < size
					thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual));

				thisTry.cssSize = cssSize(pane, thisTry.attempt);
				$P.css( dimName, thisTry.cssSize );

				thisTry.actual	= dimName=='width' ? $P.outerWidth() : $P.outerHeight();
				thisTry.correct	= (size === thisTry.actual);

				// log attempts and alert the user of this *non-fatal error* (if showDebugMessages)
				if ( tries.length === 1) {
					_log(msg, false, true);
					_log(lastTry, false, true);
				}
				_log(thisTry, false, true);
				// after 4 tries, is as close as its gonna get!
				if (tries.length > 3) break;

				tries.push( thisTry );
				lastTry = tries[ tries.length - 1 ];
			}
			// END TESTING CODE

			// update pane-state dimensions
			s.size	= size;
			$.extend(s, elDims($P));

			if (s.isVisible && $P.is(":visible")) {
				// reposition the resizer-bar
				if ($R) $R.css( side, size + sC[inset] );
				// resize the content-div
				sizeContent(pane);
			}

			if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible)
				_runCallbacks("onresize_end", pane);

			// resize all the adjacent panes, and adjust their toggler buttons
			// when skipCallback passed, it means the controlling method will handle 'other panes'
			if (!skipCallback) {
				// also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize
				if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force);
				sizeHandles();
			}

			// if opposite-pane was autoClosed, see if it can be autoOpened now
			var altPane = _c.oppositeEdge[pane];
			if (size < oldSize && state[ altPane ].noRoom) {
				setSizeLimits( altPane );
				makePaneFit( altPane, false, skipCallback );
			}

			// DEBUG - ALERT user/developer so they know there was a sizing problem
			if (tries.length > 1)
				_log(msg +'\nSee the Error Console for details.', true, true);
		}
	}

	/**
	* @see  initPanes(), sizePane(), resizeAll(), open(), close(), hide()
	* @param {Array.<string>|string} panes					The pane(s) being resized, comma-delmited string
	* @param {boolean=}				[skipCallback=false]	Should the onresize callback be run?
	* @param {boolean=}				[force=false]
	*/
,	sizeMidPanes = function (panes, skipCallback, force) {
		panes = (panes ? panes : "east,west,center").split(",");

		$.each(panes, function (i, pane) {
			if (!$Ps[pane]) return; // NO PANE - skip
			var 
				o		= options[pane]
			,	s		= state[pane]
			,	$P		= $Ps[pane]
			,	$R		= $Rs[pane]
			,	isCenter= (pane=="center")
			,	hasRoom	= true
			,	CSS		= {}
			,	newCenter	= calcNewCenterPaneDims()
			;
			// update pane-state dimensions
			$.extend(s, elDims($P));

			if (pane === "center") {
				if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight)
					return true; // SKIP - pane already the correct size
				// set state for makePaneFit() logic
				$.extend(s, cssMinDims(pane), {
					maxWidth:	newCenter.width
				,	maxHeight:	newCenter.height
				});
				CSS = newCenter;
				// convert OUTER width/height to CSS width/height 
				CSS.width	= cssW($P, CSS.width);
				// NEW - allow pane to extend 'below' visible area rather than hide it
				CSS.height	= cssH($P, CSS.height);
				hasRoom		= CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW
				// during layout init, try to shrink east/west panes to make room for center
				if (!state.initialized && o.minWidth > s.outerWidth) {
					var
						reqPx	= o.minWidth - s.outerWidth
					,	minE	= options.east.minSize || 0
					,	minW	= options.west.minSize || 0
					,	sizeE	= state.east.size
					,	sizeW	= state.west.size
					,	newE	= sizeE
					,	newW	= sizeW
					;
					if (reqPx > 0 && state.east.isVisible && sizeE > minE) {
						newE = max( sizeE-minE, sizeE-reqPx );
						reqPx -= sizeE-newE;
					}
					if (reqPx > 0 && state.west.isVisible && sizeW > minW) {
						newW = max( sizeW-minW, sizeW-reqPx );
						reqPx -= sizeW-newW;
					}
					// IF we found enough extra space, then resize the border panes as calculated
					if (reqPx === 0) {
						if (sizeE && sizeE != minE)
							sizePane('east', newE, true, force, true); // true = skipCallback/noAnimation - initPanes will handle when done
						if (sizeW && sizeW != minW)
							sizePane('west', newW, true, force, true);
						// now start over!
						sizeMidPanes('center', skipCallback, force);
						return; // abort this loop
					}
				}
			}
			else { // for east and west, set only the height, which is same as center height
				// set state.min/maxWidth/Height for makePaneFit() logic
				if (s.isVisible && !s.noVerticalRoom)
					$.extend(s, elDims($P), cssMinDims(pane))
				if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight)
					return true; // SKIP - pane already the correct size
				// east/west have same top, bottom & height as center
				CSS.top		= newCenter.top;
				CSS.bottom	= newCenter.bottom;
				// NEW - allow pane to extend 'below' visible area rather than hide it
				CSS.height	= cssH($P, newCenter.height);
				s.maxHeight	= CSS.height;
				hasRoom		= (s.maxHeight >= 0); // ALWAYS TRUE NOW
				if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic
			}

			if (hasRoom) {
				// resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized
				if (!skipCallback && state.initialized)
					_runCallbacks("onresize_start", pane);

				$P.css(CSS); // apply the CSS to pane
				if (pane !== "center")
					sizeHandles(pane); // also update resizer length
				if (s.noRoom && !s.isClosed && !s.isHidden)
					makePaneFit(pane); // will re-open/show auto-closed/hidden pane
				if (s.isVisible) {
					$.extend(s, elDims($P)); // update pane dimensions
					if (state.initialized) sizeContent(pane); // also resize the contents, if exists
				}
			}
			else if (!s.noRoom && s.isVisible) // no room for pane
				makePaneFit(pane); // will hide or close pane

			if (!s.isVisible)
				return true; // DONE - next pane

			/*
			* Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes
			* Normally these panes have only 'left' & 'right' positions so pane auto-sizes
			* ALSO required when pane is an IFRAME because will NOT default to 'full width'
			*	TODO: Can I use width:100% for a north/south iframe?
			*	TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD
			*/
			if (pane === "center") { // finished processing midPanes
				var fix = browser.isIE6 || !browser.boxModel;
				if ($Ps.north && (fix || state.north.tagName=="IFRAME")) 
					$Ps.north.css("width", cssW($Ps.north, sC.innerWidth));
				if ($Ps.south && (fix || state.south.tagName=="IFRAME"))
					$Ps.south.css("width", cssW($Ps.south, sC.innerWidth));
			}

			// resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized
			if (!skipCallback && state.initialized)
				_runCallbacks("onresize_end", pane);
		});
	}


	/**
	* @see  window.onresize(), callbacks or custom code
	*/
,	resizeAll = function (evt) {
		// stopPropagation if called by trigger("layoutdestroy") - use evtPane utility 
		evtPane(evt);

		if (!state.initialized) {
			_initLayoutElements();
			return; // no need to resize since we just initialized!
		}
		var	oldW	= sC.innerWidth
		,	oldH	= sC.innerHeight
		;
		// cannot size layout when 'container' is hidden or collapsed
		if (!$N.is(":visible") ) return;
		$.extend(state.container, elDims( $N )); // UPDATE container dimensions
		if (!sC.outerHeight) return;

		// onresizeall_start will CANCEL resizing if returns false
		// state.container has already been set, so user can access this info for calcuations
		if (false === _runCallbacks("onresizeall_start")) return false;

		var	// see if container is now 'smaller' than before
			shrunkH	= (sC.innerHeight < oldH)
		,	shrunkW	= (sC.innerWidth < oldW)
		,	$P, o, s, dir
		;
		// NOTE special order for sizing: S-N-E-W
		$.each(["south","north","east","west"], function (i, pane) {
			if (!$Ps[pane]) return; // no pane - SKIP
			s	= state[pane];
			o	= options[pane];
			dir	= _c[pane].dir;

			if (o.autoResize && s.size != o.size) // resize pane to original size set in options
				sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation
			else {
				setSizeLimits(pane);
				makePaneFit(pane, false, true, true); // true=skipCallback/forceResize
			}
		});

		sizeMidPanes("", true, true); // true=skipCallback, true=forceResize
		sizeHandles(); // reposition the toggler elements

		// trigger all individual pane callbacks AFTER layout has finished resizing
		o = options; // reuse alias
		$.each(_c.allPanes, function (i, pane) {
			$P = $Ps[pane];
			if (!$P) return; // SKIP
			if (state[pane].isVisible) // undefined for non-existent panes
				_runCallbacks("onresize_end", pane); // callback - if exists
		});

		_runCallbacks("onresizeall_end");
		//_triggerLayoutEvent(pane, 'resizeall');
	}

	/**
	* Whenever a pane resizes or opens that has a nested layout, trigger resizeAll
	*
	* @param {string|Object}	evt_or_pane		The pane just resized or opened
	*/
,	resizeChildLayout = function (evt_or_pane) {
		var	pane = evtPane.call(this, evt_or_pane);
		if (!options[pane].resizeChildLayout) return;
		var	$P	= $Ps[pane]
		,	$C	= $Cs[pane]
		,	d	= "layout"
		,	P	= Instance[pane]
		,	L	= children[pane]
		;
		// user may have manually set EITHER instance pointer, so handle that
		if (P.child && !L) {
			// have to reverse the pointers!
			var el = P.child.container;
			L = children[pane] = (el ? el.data(d) : 0) || null; // set pointer _directly_ to layout instance
		}

		// if a layout-pointer exists, see if child has been destroyed
		if (L && L.destroyed)
			L = children[pane] = null; // clear child pointers
		// no child layout pointer is set - see if there is a child layout NOW
		if (!L)	L = children[pane] = $P.data(d) || ($C ? $C.data(d) : 0) || null; // set/update child pointers

		// ALWAYS refresh the pane.child alias
		P.child = children[pane];

		if (L) L.resizeAll();
	}


	/**
	* IF pane has a content-div, then resize all elements inside pane to fit pane-height
	*
	* @param {string|Object}	evt_or_panes		The pane(s) being resized
	* @param {boolean=}			[remeasure=false]	Should the content (header/footer) be remeasured?
	*/
,	sizeContent = function (evt_or_panes, remeasure) {
		if (!isInitialized()) return;

		var panes = evtPane.call(this, evt_or_panes);
		panes = panes ? panes.split(",") : _c.allPanes;

		$.each(panes, function (idx, pane) {
			var
				$P	= $Ps[pane]
			,	$C	= $Cs[pane]
			,	o	= options[pane]
			,	s	= state[pane]
			,	m	= s.content // m = measurements
			;
			if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip

			// if content-element was REMOVED, update OR remove the pointer
			if (!$C.length) {
				initContent(pane, false);	// false = do NOT sizeContent() - already there!
				if (!$C) return;			// no replacement element found - pointer have been removed
			}

			// onsizecontent_start will CANCEL resizing if returns false
			if (false === _runCallbacks("onsizecontent_start", pane)) return;

			// skip re-measuring offsets if live-resizing
			if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) {
				_measure();
				// if any footers are below pane-bottom, they may not measure correctly,
				// so allow pane overflow and re-measure
				if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") {
					$P.css("overflow", "visible");
					_measure(); // remeasure while overflowing
					$P.css("overflow", "hidden");
				}
			}
			// NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders
			var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom);

			if (!$C.is(":visible") || m.height != newH) {
				// size the Content element to fit new pane-size - will autoHide if not enough room
				setOuterHeight($C, newH, true); // true=autoHide
				m.height = newH; // save new height
			};

			if (state.initialized)
				_runCallbacks("onsizecontent_end", pane);

			function _below ($E) {
				return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0));
			};

			function _measure () {
				var
					ignore	= options[pane].contentIgnoreSelector
				,	$Fs		= $C.nextAll().not(ignore || ':lt(0)') // not :lt(0) = ALL
				,	$Fs_vis	= $Fs.filter(':visible')
				,	$F		= $Fs_vis.filter(':last')
				;
				m = {
					top:			$C[0].offsetTop
				,	height:			$C.outerHeight()
				,	numFooters:		$Fs.length
				,	hiddenFooters:	$Fs.length - $Fs_vis.length
				,	spaceBelow:		0 // correct if no content footer ($E)
				}
					m.spaceAbove	= m.top; // just for state - not used in calc
					m.bottom		= m.top + m.height;
				if ($F.length)
					//spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom)
					m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F);
				else // no footer - check marginBottom on Content element itself
					m.spaceBelow = _below($C);
			};
		});
	}


	/**
	* Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary
	*
	* @see  initHandles(), open(), close(), resizeAll()
	* @param {string|Object}	evt_or_panes		The pane(s) being resized
	*/
,	sizeHandles = function (evt_or_panes) {
		var panes = evtPane.call(this, evt_or_panes)
		panes = panes ? panes.split(",") : _c.borderPanes;

		$.each(panes, function (i, pane) {
			var 
				o	= options[pane]
			,	s	= state[pane]
			,	$P	= $Ps[pane]
			,	$R	= $Rs[pane]
			,	$T	= $Ts[pane]
			,	$TC
			;
			if (!$P || !$R) return;

			var
				dir			= _c[pane].dir
			,	_state		= (s.isClosed ? "_closed" : "_open")
			,	spacing		= o["spacing"+ _state]
			,	togAlign	= o["togglerAlign"+ _state]
			,	togLen		= o["togglerLength"+ _state]
			,	paneLen
			,	left
			,	offset
			,	CSS = {}
			;

			if (spacing === 0) {
				$R.hide();
				return;
			}
			else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason
				$R.show(); // in case was previously hidden

			// Resizer Bar is ALWAYS same width/height of pane it is attached to
			if (dir === "horz") { // north/south
				//paneLen = $P.outerWidth(); // s.outerWidth || 
				paneLen = sC.innerWidth; // handle offscreen-panes
				s.resizerLength = paneLen;
				left = $.layout.cssNum($P, "left")
				$R.css({
					width:	cssW($R, paneLen) // account for borders & padding
				,	height:	cssH($R, spacing) // ditto
				,	left:	left > -9999 ? left : sC.insetLeft // handle offscreen-panes
				});
			}
			else { // east/west
				paneLen = $P.outerHeight(); // s.outerHeight || 
				s.resizerLength = paneLen;
				$R.css({
					height:	cssH($R, paneLen) // account for borders & padding
				,	width:	cssW($R, spacing) // ditto
				,	top:	sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane?
				//,	top:	$.layout.cssNum($Ps["center"], "top")
				});
			}

			// remove hover classes
			removeHover( o, $R );

			if ($T) {
				if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) {
					$T.hide(); // always HIDE the toggler when 'sliding'
					return;
				}
				else
					$T.show(); // in case was previously hidden

				if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) {
					togLen = paneLen;
					offset = 0;
				}
				else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed
					if (isStr(togAlign)) {
						switch (togAlign) {
							case "top":
							case "left":	offset = 0;
											break;
							case "bottom":
							case "right":	offset = paneLen - togLen;
											break;
							case "middle":
							case "center":
							default:		offset = round((paneLen - togLen) / 2); // 'default' catches typos
						}
					}
					else { // togAlign = number
						var x = parseInt(togAlign, 10); //
						if (togAlign >= 0) offset = x;
						else offset = paneLen - togLen + x; // NOTE: x is negative!
					}
				}

				if (dir === "horz") { // north/south
					var width = cssW($T, togLen);
					$T.css({
						width:	width  // account for borders & padding
					,	height:	cssH($T, spacing) // ditto
					,	left:	offset // TODO: VERIFY that toggler  positions correctly for ALL values
					,	top:	0
					});
					// CENTER the toggler content SPAN
					$T.children(".content").each(function(){
						$TC = $(this);
						$TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative
					});
				}
				else { // east/west
					var height = cssH($T, togLen);
					$T.css({
						height:	height // account for borders & padding
					,	width:	cssW($T, spacing) // ditto
					,	top:	offset // POSITION the toggler
					,	left:	0
					});
					// CENTER the toggler content SPAN
					$T.children(".content").each(function(){
						$TC = $(this);
						$TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative
					});
				}

				// remove ALL hover classes
				removeHover( 0, $T );
			}

			// DONE measuring and sizing this resizer/toggler, so can be 'hidden' now
			if (!state.initialized && (o.initHidden || s.noRoom)) {
				$R.hide();
				if ($T) $T.hide();
			}
		});
	}


	/**
	* @param {string|Object}	evt_or_pane
	*/
,	enableClosable = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$T	= $Ts[pane]
		,	o	= options[pane]
		;
		if (!$T) return;
		o.closable = true;
		$T	.bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); })
			.css("visibility", "visible")
			.css("cursor", "pointer")
			.attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank
			.show();
	}
	/**
	* @param {string|Object}	evt_or_pane
	* @param {boolean=}			[hide=false]
	*/
,	disableClosable = function (evt_or_pane, hide) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$T	= $Ts[pane]
		;
		if (!$T) return;
		options[pane].closable = false;
		// is closable is disable, then pane MUST be open!
		if (state[pane].isClosed) open(pane, false, true);
		$T	.unbind("."+ sID)
			.css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues
			.css("cursor", "default")
			.attr("title", "");
	}


	/**
	* @param {string|Object}	evt_or_pane
	*/
,	enableSlidable = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$R	= $Rs[pane]
		;
		if (!$R || !$R.data('draggable')) return;
		options[pane].slidable = true; 
		if (state[pane].isClosed)
			bindStartSlidingEvent(pane, true);
	}
	/**
	* @param {string|Object}	evt_or_pane
	*/
,	disableSlidable = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$R	= $Rs[pane]
		;
		if (!$R) return;
		options[pane].slidable = false; 
		if (state[pane].isSliding)
			close(pane, false, true);
		else {
			bindStartSlidingEvent(pane, false);
			$R	.css("cursor", "default")
				.attr("title", "");
			removeHover(null, $R[0]); // in case currently hovered
		}
	}


	/**
	* @param {string|Object}	evt_or_pane
	*/
,	enableResizable = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$R	= $Rs[pane]
		,	o	= options[pane]
		;
		if (!$R || !$R.data('draggable')) return;
		o.resizable = true; 
		$R.draggable("enable");
		if (!state[pane].isClosed)
			$R	.css("cursor", o.resizerCursor)
			 	.attr("title", o.tips.Resize);
	}
	/**
	* @param {string|Object}	evt_or_pane
	*/
,	disableResizable = function (evt_or_pane) {
		if (!isInitialized()) return;
		var	pane = evtPane.call(this, evt_or_pane)
		,	$R	= $Rs[pane]
		;
		if (!$R || !$R.data('draggable')) return;
		options[pane].resizable = false; 
		$R	.draggable("disable")
			.css("cursor", "default")
			.attr("title", "");
		removeHover(null, $R[0]); // in case currently hovered
	}


	/**
	* Move a pane from source-side (eg, west) to target-side (eg, east)
	* If pane exists on target-side, move that to source-side, ie, 'swap' the panes
	*
	* @param {string|Object}	evt_or_pane1	The pane/edge being swapped
	* @param {string}			pane2			ditto
	*/
,	swapPanes = function (evt_or_pane1, pane2) {
		if (!isInitialized()) return;
		var pane1 = evtPane.call(this, evt_or_pane1);
		// change state.edge NOW so callbacks can know where pane is headed...
		state[pane1].edge = pane2;
		state[pane2].edge = pane1;
		// run these even if NOT state.initialized
		if (false === _runCallbacks("onswap_start", pane1)
		 ||	false === _runCallbacks("onswap_start", pane2)
		) {
			state[pane1].edge = pane1; // reset
			state[pane2].edge = pane2;
			return;
		}

		var
			oPane1	= copy( pane1 )
		,	oPane2	= copy( pane2 )
		,	sizes	= {}
		;
		sizes[pane1] = oPane1 ? oPane1.state.size : 0;
		sizes[pane2] = oPane2 ? oPane2.state.size : 0;

		// clear pointers & state
		$Ps[pane1] = false; 
		$Ps[pane2] = false;
		state[pane1] = {};
		state[pane2] = {};
		
		// ALWAYS remove the resizer & toggler elements
		if ($Ts[pane1]) $Ts[pane1].remove();
		if ($Ts[pane2]) $Ts[pane2].remove();
		if ($Rs[pane1]) $Rs[pane1].remove();
		if ($Rs[pane2]) $Rs[pane2].remove();
		$Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false;

		// transfer element pointers and data to NEW Layout keys
		move( oPane1, pane2 );
		move( oPane2, pane1 );

		// cleanup objects
		oPane1 = oPane2 = sizes = null;

		// make panes 'visible' again
		if ($Ps[pane1]) $Ps[pane1].css(_c.visible);
		if ($Ps[pane2]) $Ps[pane2].css(_c.visible);

		// fix any size discrepancies caused by swap
		resizeAll();

		// run these even if NOT state.initialized
		_runCallbacks("onswap_end", pane1);
		_runCallbacks("onswap_end", pane2);

		return;

		function copy (n) { // n = pane
			var
				$P	= $Ps[n]
			,	$C	= $Cs[n]
			;
			return !$P ? false : {
				pane:		n
			,	P:			$P ? $P[0] : false
			,	C:			$C ? $C[0] : false
			,	state:		$.extend(true, {}, state[n])
			,	options:	$.extend(true, {}, options[n])
			}
		};

		function move (oPane, pane) {
			if (!oPane) return;
			var
				P		= oPane.P
			,	C		= oPane.C
			,	oldPane = oPane.pane
			,	c		= _c[pane]
			,	side	= c.side.toLowerCase()
			,	inset	= "inset"+ c.side
			//	save pane-options that should be retained
			,	s		= $.extend(true, {}, state[pane])
			,	o		= options[pane]
			//	RETAIN side-specific FX Settings - more below
			,	fx		= { resizerCursor: o.resizerCursor }
			,	re, size, pos
			;
			$.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) {
				fx[k +"_open"]  = o[k +"_open"];
				fx[k +"_close"] = o[k +"_close"];
				fx[k +"_size"]  = o[k +"_size"];
			});

			// update object pointers and attributes
			$Ps[pane] = $(P)
				.data({
					layoutPane:		Instance[pane]	// NEW pointer to pane-alias-object
				,	layoutEdge:		pane
				})
				.css(_c.hidden)
				.css(c.cssReq)
			;
			$Cs[pane] = C ? $(C) : false;

			// set options and state
			options[pane]	= $.extend(true, {}, oPane.options, fx);
			state[pane]		= $.extend(true, {}, oPane.state);

			// change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west
			re = new RegExp(o.paneClass +"-"+ oldPane, "g");
			P.className = P.className.replace(re, o.paneClass +"-"+ pane);

			// ALWAYS regenerate the resizer & toggler elements
			initHandles(pane); // create the required resizer & toggler

			// if moving to different orientation, then keep 'target' pane size
			if (c.dir != _c[oldPane].dir) {
				size = sizes[pane] || 0;
				setSizeLimits(pane); // update pane-state
				size = max(size, state[pane].minSize);
				// use manualSizePane to disable autoResize - not useful after panes are swapped
				manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation
			}
			else // move the resizer here
				$Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0));


			// ADD CLASSNAMES & SLIDE-BINDINGS
			if (oPane.state.isVisible && !s.isVisible)
				setAsOpen(pane, true); // true = skipCallback
			else {
				setAsClosed(pane);
				bindStartSlidingEvent(pane, true); // will enable events IF option is set
			}

			// DESTROY the object
			oPane = null;
		};
	}


	/**
	* INTERNAL method to sync pin-buttons when pane is opened or closed
	* Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes
	*
	* @see  open(), setAsOpen(), setAsClosed()
	* @param {string}	pane   These are the params returned to callbacks by layout()
	* @param {boolean}	doPin  True means set the pin 'down', False means 'up'
	*/
,	syncPinBtns = function (pane, doPin) {
		if ($.layout.plugins.buttons)
			$.each(state[pane].pins, function (i, selector) {
				$.layout.buttons.setPinState(Instance, $(selector), pane, doPin);
			});
	}

;	// END var DECLARATIONS

	/**
	* Capture keys when enableCursorHotkey - toggle pane if hotkey pressed
	*
	* @see  document.keydown()
	*/
	function keyDown (evt) {
		if (!evt) return true;
		var code = evt.keyCode;
		if (code < 33) return true; // ignore special keys: ENTER, TAB, etc

		var
			PANE = {
				38: "north" // Up Cursor	- $.ui.keyCode.UP
			,	40: "south" // Down Cursor	- $.ui.keyCode.DOWN
			,	37: "west"  // Left Cursor	- $.ui.keyCode.LEFT
			,	39: "east"  // Right Cursor	- $.ui.keyCode.RIGHT
			}
		,	ALT		= evt.altKey // no worky!
		,	SHIFT	= evt.shiftKey
		,	CTRL	= evt.ctrlKey
		,	CURSOR	= (CTRL && code >= 37 && code <= 40)
		,	o, k, m, pane
		;

		if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey
			pane = PANE[code];
		else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey
			$.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey
				o = options[p];
				k = o.customHotkey;
				m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT"
				if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches
					if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches
						pane = p;
						return false; // BREAK
					}
				}
			});

		// validate pane
		if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden)
			return true;

		toggle(pane);

		evt.stopPropagation();
		evt.returnValue = false; // CANCEL key
		return false;
	};


/*
 * ######################################
 *	UTILITY METHODS
 *	called externally or by initButtons
 * ######################################
 */

	/**
	* Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work
	*
	* @param {Object=}   [el]	(optional) Can also be 'bound' to a click, mouseOver, or other event
	*/
	function allowOverflow (el) {
		if (!isInitialized()) return;
		if (this && this.tagName) el = this; // BOUND to element
		var $P;
		if (isStr(el))
			$P = $Ps[el];
		else if ($(el).data("layoutRole"))
			$P = $(el);
		else
			$(el).parents().each(function(){
				if ($(this).data("layoutRole")) {
					$P = $(this);
					return false; // BREAK
				}
			});
		if (!$P || !$P.length) return; // INVALID

		var
			pane	= $P.data("layoutEdge")
		,	s		= state[pane]
		;

		// if pane is already raised, then reset it before doing it again!
		// this would happen if allowOverflow is attached to BOTH the pane and an element 
		if (s.cssSaved)
			resetOverflow(pane); // reset previous CSS before continuing

		// if pane is raised by sliding or resizing, or its closed, then abort
		if (s.isSliding || s.isResizing || s.isClosed) {
			s.cssSaved = false;
			return;
		}

		var
			newCSS	= { zIndex: (options.zIndexes.resizer_normal + 1) }
		,	curCSS	= {}
		,	of		= $P.css("overflow")
		,	ofX		= $P.css("overflowX")
		,	ofY		= $P.css("overflowY")
		;
		// determine which, if any, overflow settings need to be changed
		if (of != "visible") {
			curCSS.overflow = of;
			newCSS.overflow = "visible";
		}
		if (ofX && !ofX.match(/(visible|auto)/)) {
			curCSS.overflowX = ofX;
			newCSS.overflowX = "visible";
		}
		if (ofY && !ofY.match(/(visible|auto)/)) {
			curCSS.overflowY = ofX;
			newCSS.overflowY = "visible";
		}

		// save the current overflow settings - even if blank!
		s.cssSaved = curCSS;

		// apply new CSS to raise zIndex and, if necessary, make overflow 'visible'
		$P.css( newCSS );

		// make sure the zIndex of all other panes is normal
		$.each(_c.allPanes, function(i, p) {
			if (p != pane) resetOverflow(p);
		});

	};
	/**
	* @param {Object=}   [el]	(optional) Can also be 'bound' to a click, mouseOver, or other event
	*/
	function resetOverflow (el) {
		if (!isInitialized()) return;
		if (this && this.tagName) el = this; // BOUND to element
		var $P;
		if (isStr(el))
			$P = $Ps[el];
		else if ($(el).data("layoutRole"))
			$P = $(el);
		else
			$(el).parents().each(function(){
				if ($(this).data("layoutRole")) {
					$P = $(this);
					return false; // BREAK
				}
			});
		if (!$P || !$P.length) return; // INVALID

		var
			pane	= $P.data("layoutEdge")
		,	s		= state[pane]
		,	CSS		= s.cssSaved || {}
		;
		// reset the zIndex
		if (!s.isSliding && !s.isResizing)
			$P.css("zIndex", options.zIndexes.pane_normal);

		// reset Overflow - if necessary
		$P.css( CSS );

		// clear var
		s.cssSaved = false;
	};

/*
 * #####################
 * CREATE/RETURN LAYOUT
 * #####################
 */

	// validate that container exists
	var $N = $(this).eq(0); // FIRST matching Container element
	if (!$N.length) {
		return _log( options.errors.containerMissing );
	};

	// Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout")
	// return the Instance-pointer if layout has already been initialized
	if ($N.data("layoutContainer") && $N.data("layout"))
		return $N.data("layout"); // cached pointer

	// init global vars
	var 
		$Ps	= {}	// Panes x5		- set in initPanes()
	,	$Cs	= {}	// Content x5	- set in initPanes()
	,	$Rs	= {}	// Resizers x4	- set in initHandles()
	,	$Ts	= {}	// Togglers x4	- set in initHandles()
	,	$Ms	= $([])	// Masks - up to 2 masks per pane (IFRAME + DIV)
	//	aliases for code brevity
	,	sC	= state.container // alias for easy access to 'container dimensions'
	,	sID	= state.id // alias for unique layout ID/namespace - eg: "layout435"
	;

	// create Instance object to expose data & option Properties, and primary action Methods
	var Instance = {
	//	layout data
		options:			options			// property - options hash
	,	state:				state			// property - dimensions hash
	//	object pointers
	,	container:			$N				// property - object pointers for layout container
	,	panes:				$Ps				// property - object pointers for ALL Panes: panes.north, panes.center
	,	contents:			$Cs				// property - object pointers for ALL Content: contents.north, contents.center
	,	resizers:			$Rs				// property - object pointers for ALL Resizers, eg: resizers.north
	,	togglers:			$Ts				// property - object pointers for ALL Togglers, eg: togglers.north
	//	border-pane open/close
	,	hide:				hide			// method - ditto
	,	show:				show			// method - ditto
	,	toggle:				toggle			// method - pass a 'pane' ("north", "west", etc)
	,	open:				open			// method - ditto
	,	close:				close			// method - ditto
	,	slideOpen:			slideOpen		// method - ditto
	,	slideClose:			slideClose		// method - ditto
	,	slideToggle:		slideToggle		// method - ditto
	//	pane actions
	,	setSizeLimits:		setSizeLimits	// method - pass a 'pane' - update state min/max data
	,	_sizePane:			sizePane		// method -intended for user by plugins only!
	,	sizePane:			manualSizePane	// method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto'
	,	sizeContent:		sizeContent		// method - pass a 'pane'
	,	swapPanes:			swapPanes		// method - pass TWO 'panes' - will swap them
	,	showMasks:			showMasks		// method - pass a 'pane' OR list of panes - default = all panes with mask option set
	,	hideMasks:			hideMasks		// method - ditto'
	//	pane element methods
	,	initContent:		initContent		// method - ditto
	,	addPane:			addPane			// method - pass a 'pane'
	,	removePane:			removePane		// method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem
	,	createChildLayout:	createChildLayout// method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].childOptions
	//	special pane option setting
	,	enableClosable:		enableClosable	// method - pass a 'pane'
	,	disableClosable:	disableClosable	// method - ditto
	,	enableSlidable:		enableSlidable	// method - ditto
	,	disableSlidable:	disableSlidable	// method - ditto
	,	enableResizable:	enableResizable	// method - ditto
	,	disableResizable:	disableResizable// method - ditto
	//	utility methods for panes
	,	allowOverflow:		allowOverflow	// utility - pass calling element (this)
	,	resetOverflow:		resetOverflow	// utility - ditto
	//	layout control
	,	destroy:			destroy			// method - no parameters
	,	initPanes:			isInitialized	// method - no parameters
	,	resizeAll:			resizeAll		// method - no parameters
	//	callback triggering
	,	runCallbacks:		_runCallbacks	// method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west")
	//	alias collections of options, state and children - created in addPane and extended elsewhere
	,	hasParentLayout:	false			// set by initContainer()
	,	children:			children		// pointers to child-layouts, eg: Instance.children["west"]
	,	north:				false			// alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], child: children[pane] }
	,	south:				false			// ditto
	,	west:				false			// ditto
	,	east:				false			// ditto
	,	center:				false			// ditto
	};

	// create the border layout NOW
	if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation
		return null;
	else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later
		return Instance; // return the Instance object

}


/*	OLD versions of jQuery only set $.support.boxModel after page is loaded
 *	so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel).
 */
$(function(){
	var b = $.layout.browser;
	if (b.msie) b.boxModel = $.support.boxModel;
});


/**
 * jquery.layout.state 1.0
 * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $
 *
 * Copyright (c) 2010 
 *   Kevin Dalman (http://allpro.net)
 *
 * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
 * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
 *
 * @dependancies: UI Layout 1.3.0.rc30.1 or higher
 * @dependancies: $.ui.cookie (above)
 *
 * @support: http://groups.google.com/group/jquery-ui-layout
 */
/*
 *	State-management options stored in options.stateManagement, which includes a .cookie hash
 *	Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden
 *
 *	// STATE/COOKIE OPTIONS
 *	@example $(el).layout({
				stateManagement: {
					enabled:	true
				,	stateKeys:	"east.size,west.size,east.isClosed,west.isClosed"
				,	cookie:		{ name: "appLayout", path: "/" }
				}
			})
 *	@example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies
 *	@example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } })
 *	@example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" })
 *
 *	// STATE/COOKIE METHODS
 *	@example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} );
 *	@example myLayout.loadCookie();
 *	@example myLayout.deleteCookie();
 *	@example var JSON = myLayout.readState();	// CURRENT Layout State
 *	@example var JSON = myLayout.readCookie();	// SAVED Layout State (from cookie)
 *	@example var JSON = myLayout.state.stateData;	// LAST LOADED Layout State (cookie saved in layout.state hash)
 *
 *	CUSTOM STATE-MANAGEMENT (eg, saved in a database)
 *	@example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" );
 *	@example myLayout.loadState( JSON );
 */

/**
 *	UI COOKIE UTILITY
 *
 *	A $.cookie OR $.ui.cookie namespace *should be standard*, but until then...
 *	This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin
 *	NOTE: This utility is REQUIRED by the layout.state plugin
 *
 *	Cookie methods in Layout are created as part of State Management 
 */
if (!$.ui) $.ui = {};
$.ui.cookie = {

	// cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6
	acceptsCookies: !!navigator.cookieEnabled

,	read: function (name) {
		var
			c		= document.cookie
		,	cs		= c ? c.split(';') : []
		,	pair	// loop var
		;
		for (var i=0, n=cs.length; i < n; i++) {
			pair = $.trim(cs[i]).split('='); // name=value pair
			if (pair[0] == name) // found the layout cookie
				return decodeURIComponent(pair[1]);

		}
		return null;
	}

,	write: function (name, val, cookieOpts) {
		var
			params	= ''
		,	date	= ''
		,	clear	= false
		,	o		= cookieOpts || {}
		,	x		= o.expires
		;
		if (x && x.toUTCString)
			date = x;
		else if (x === null || typeof x === 'number') {
			date = new Date();
			if (x > 0)
				date.setDate(date.getDate() + x);
			else {
				date.setFullYear(1970);
				clear = true;
			}
		}
		if (date)		params += ';expires='+ date.toUTCString();
		if (o.path)		params += ';path='+ o.path;
		if (o.domain)	params += ';domain='+ o.domain;
		if (o.secure)	params += ';secure';
		document.cookie = name +'='+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie
	}

,	clear: function (name) {
		$.ui.cookie.write(name, '', {expires: -1});
	}

};
// if cookie.jquery.js is not loaded, create an alias to replicate it
// this may be useful to other plugins or code dependent on that plugin
if (!$.cookie) $.cookie = function (k, v, o) {
	var C = $.ui.cookie;
	if (v === null)
		C.clear(k);
	else if (v === undefined)
		return C.read(k);
	else
		C.write(k, v, o);
};


// tell Layout that the state plugin is available
$.layout.plugins.stateManagement = true;

//	Add State-Management options to layout.defaults
$.layout.config.optionRootKeys.push("stateManagement");
$.layout.defaults.stateManagement = {
	enabled:	false	// true = enable state-management, even if not using cookies
,	autoSave:	true	// Save a state-cookie when page exits?
,	autoLoad:	true	// Load the state-cookie when Layout inits?
	// List state-data to save - must be pane-specific
,	stateKeys:	"north.size,south.size,east.size,west.size,"+
				"north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+
				"north.isHidden,south.isHidden,east.isHidden,west.isHidden"
,	cookie: {
		name:	""	// If not specified, will use Layout.name, else just "Layout"
	,	domain:	""	// blank = current domain
	,	path:	""	// blank = current page, '/' = entire website
	,	expires: ""	// 'days' to keep cookie - leave blank for 'session cookie'
	,	secure:	false
	}
};
// Set stateManagement as a layout-option, NOT a pane-option
$.layout.optionsMap.layout.push("stateManagement");

/*
 *	State Management methods
 */
$.layout.state = {

	/**
	 * Get the current layout state and save it to a cookie
	 *
	 * myLayout.saveCookie( keys, cookieOpts )
	 *
	 * @param {Object}			inst
	 * @param {(string|Array)=}	keys
	 * @param {Object=}			cookieOpts
	 */
	saveCookie: function (inst, keys, cookieOpts) {
		var o	= inst.options
		,	oS	= o.stateManagement
		,	oC	= $.extend(true, {}, oS.cookie, cookieOpts || null)
		,	data = inst.state.stateData = inst.readState( keys || oS.stateKeys ) // read current panes-state
		;
		$.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC );
		return $.extend(true, {}, data); // return COPY of state.stateData data
	}

	/**
	 * Remove the state cookie
	 *
	 * @param {Object}	inst
	 */
,	deleteCookie: function (inst) {
		var o = inst.options;
		$.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" );
	}

	/**
	 * Read & return data from the cookie - as JSON
	 *
	 * @param {Object}	inst
	 */
,	readCookie: function (inst) {
		var o = inst.options;
		var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" );
		// convert cookie string back to a hash and return it
		return c ? $.layout.state.decodeJSON(c) : {};
	}

	/**
	 * Get data from the cookie and USE IT to loadState
	 *
	 * @param {Object}	inst
	 */
,	loadCookie: function (inst) {
		var c = $.layout.state.readCookie(inst); // READ the cookie
		if (c) {
			inst.state.stateData = $.extend(true, {}, c); // SET state.stateData
			inst.loadState(c); // LOAD the retrieved state
		}
		return c;
	}
	
	/**
	 * Update layout options from the cookie, if one exists
	 *
	 * @param {Object}		inst
	 * @param {Object=}		stateData
	 * @param {boolean=}	animate
	 */
,	loadState: function (inst, stateData, animate) {
		stateData = $.layout.transformData( stateData ); // panes = default subkey
		if ($.isEmptyObject( stateData )) return;
		$.extend(true, inst.options, stateData); // update layout options
		// if layout has already been initialized, then UPDATE layout state
		if (inst.state.initialized) {
			var pane, vis, o, s, h, c
			,	noAnimate = (animate===false)
			;
			$.each($.layout.config.borderPanes, function (idx, pane) {
				state = inst.state[pane];
				o = stateData[ pane ];
				if (typeof o != 'object') return; // no key, continue
				s	= o.size;
				c	= o.initClosed;
				h	= o.initHidden;
				vis	= state.isVisible;
				// resize BEFORE opening
				if (!vis)
					inst.sizePane(pane, s, false, false);
				if (h === true)			inst.hide(pane, noAnimate);
				else if (c === false)	inst.open (pane, false, noAnimate);
				else if (c === true)	inst.close(pane, false, noAnimate);
				else if (h === false)	inst.show (pane, false, noAnimate);
				// resize AFTER any other actions
				if (vis)
					inst.sizePane(pane, s, false, noAnimate); // animate resize if option passed
			});
		};
	}

	/**
	 * Get the *current layout state* and return it as a hash
	 *
	 * @param {Object=}			inst
	 * @param {(string|Array)=}	keys
	 */
,	readState: function (inst, keys) {
		var
			data	= {}
		,	alt		= { isClosed: 'initClosed', isHidden: 'initHidden' }
		,	state	= inst.state
		,	panes	= $.layout.config.allPanes
		,	pair, pane, key, val
		;
		if (!keys) keys = inst.options.stateManagement.stateKeys; // if called by user
		if ($.isArray(keys)) keys = keys.join(",");
		// convert keys to an array and change delimiters from '__' to '.'
		keys = keys.replace(/__/g, ".").split(',');
		// loop keys and create a data hash
		for (var i=0, n=keys.length; i < n; i++) {
			pair = keys[i].split(".");
			pane = pair[0];
			key  = pair[1];
			if ($.inArray(pane, panes) < 0) continue; // bad pane!
			val = state[ pane ][ key ];
			if (val == undefined) continue;
			if (key=="isClosed" && state[pane]["isSliding"])
				val = true; // if sliding, then *really* isClosed
			( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val;
		}
		return data;
	}

	/**
	 *	Stringify a JSON hash so can save in a cookie or db-field
	 */
,	encodeJSON: function (JSON) {
		return parse(JSON);
		function parse (h) {
			var D=[], i=0, k, v, t; // k = key, v = value
			for (k in h) {
				v = h[k];
				t = typeof v;
				if (t == 'string')		// STRING - add quotes
					v = '"'+ v +'"';
				else if (t == 'object')	// SUB-KEY - recurse into it
					v = parse(v);
				D[i++] = '"'+ k +'":'+ v;
			}
			return '{'+ D.join(',') +'}';
		};
	}

	/**
	 *	Convert stringified JSON back to a hash object
	 *	@see		$.parseJSON(), adding in jQuery 1.4.1
	 */
,	decodeJSON: function (str) {
		try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; }
		catch (e) { return {}; }
	}


,	_create: function (inst) {
		var _	= $.layout.state;
		//	ADD State-Management plugin methods to inst
		 $.extend( inst, {
		//	readCookie - update options from cookie - returns hash of cookie data
			readCookie:		function () { return _.readCookie(inst); }
		//	deleteCookie
		,	deleteCookie:	function () { _.deleteCookie(inst); }
		//	saveCookie - optionally pass keys-list and cookie-options (hash)
		,	saveCookie:		function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); }
		//	loadCookie - readCookie and use to loadState() - returns hash of cookie data
		,	loadCookie:		function () { return _.loadCookie(inst); }
		//	loadState - pass a hash of state to use to update options
		,	loadState:		function (stateData, animate) { _.loadState(inst, stateData, animate); }
		//	readState - returns hash of current layout-state
		,	readState:		function (keys) { return _.readState(inst, keys); }
		//	add JSON utility methods too...
		,	encodeJSON:		_.encodeJSON
		,	decodeJSON:		_.decodeJSON
		});

		// init state.stateData key, even if plugin is initially disabled
		inst.state.stateData = {};

		// read and load cookie-data per options
		var oS = inst.options.stateManagement;
		if (oS.enabled) {
			if (oS.autoLoad) // update the options from the cookie
				inst.loadCookie();
			else // don't modify options - just store cookie data in state.stateData
				inst.state.stateData = inst.readCookie();
		}
	}

,	_unload: function (inst) {
		var oS = inst.options.stateManagement;
		if (oS.enabled) {
			if (oS.autoSave) // save a state-cookie automatically
				inst.saveCookie();
			else // don't save a cookie, but do store state-data in state.stateData key
				inst.state.stateData = inst.readState();
		}
	}

};

// add state initialization method to Layout's onCreate array of functions
$.layout.onCreate.push( $.layout.state._create );
$.layout.onUnload.push( $.layout.state._unload );




/**
 * jquery.layout.buttons 1.0
 * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $
 *
 * Copyright (c) 2010 
 *   Kevin Dalman (http://allpro.net)
 *
 * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
 * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
 *
 * @dependancies: UI Layout 1.3.0.rc30.1 or higher
 *
 * @support: http://groups.google.com/group/jquery-ui-layout
 *
 * Docs: [ to come ]
 * Tips: [ to come ]
 */

// tell Layout that the state plugin is available
$.layout.plugins.buttons = true;

//	Add buttons options to layout.defaults
$.layout.defaults.autoBindCustomButtons = false;
// Specify autoBindCustomButtons as a layout-option, NOT a pane-option
$.layout.optionsMap.layout.push("autoBindCustomButtons");

/*
 *	Button methods
 */
$.layout.buttons = {

	/**
	* Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons
	*
	* @see  _create()
	*
	* @param  {Object}		inst	Layout Instance object
	*/
	init: function (inst) {
		var pre		= "ui-layout-button-"
		,	layout	= inst.options.name || ""
		,	name;
		$.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) {
			$.each($.layout.config.borderPanes, function (ii, pane) {
				$("."+pre+action+"-"+pane).each(function(){
					// if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name'
					name = $(this).data("layoutName") || $(this).attr("layoutName");
					if (name == undefined || name === layout)
						inst.bindButton(this, action, pane);
				});
			});
		});
	}

	/**
	* Helper function to validate params received by addButton utilities
	*
	* Two classes are added to the element, based on the buttonClass...
	* The type of button is appended to create the 2nd className:
	*  - ui-layout-button-pin		// action btnClass
	*  - ui-layout-button-pin-west	// action btnClass + pane
	*  - ui-layout-button-toggle
	*  - ui-layout-button-open
	*  - ui-layout-button-close
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}   		pane 		Name of the pane the button is for: 'north', 'south', etc.
	*
	* @return {Array.<Object>}	If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null
	*/
,	get: function (inst, selector, pane, action) {
		var $E	= $(selector)
		,	o	= inst.options
		,	err	= o.errors.addButtonError
		;
		if (!$E.length) { // element not found
			$.layout.msg(err +" "+ o.errors.selector +": "+ selector, true);
		}
		else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified
			$.layout.msg(err +" "+ o.errors.pane +": "+ pane, true);
			$E = $("");  // NO BUTTON
		}
		else { // VALID
			var btn = o[pane].buttonClass +"-"+ action;
			$E	.addClass( btn +" "+ btn +"-"+ pane )
				.data("layoutName", o.name); // add layout identifier - even if blank!
		}
		return $E;
	}


	/**
	* NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc.
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}			action
	* @param {string}			pane
	*/
,	bind: function (inst, selector, action, pane) {
		var _ = $.layout.buttons;
		switch (action.toLowerCase()) {
			case "toggle":			_.addToggle	(inst, selector, pane); break;	
			case "open":			_.addOpen	(inst, selector, pane); break;
			case "close":			_.addClose	(inst, selector, pane); break;
			case "pin":				_.addPin	(inst, selector, pane); break;
			case "toggle-slide":	_.addToggle	(inst, selector, pane, true); break;	
			case "open-slide":		_.addOpen	(inst, selector, pane, true); break;
		}
		return inst;
	}

	/**
	* Add a custom Toggler button for a pane
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}  			pane 		Name of the pane the button is for: 'north', 'south', etc.
	* @param {boolean=}			slide 		true = slide-open, false = pin-open
	*/
,	addToggle: function (inst, selector, pane, slide) {
		$.layout.buttons.get(inst, selector, pane, "toggle")
			.click(function(evt){
				inst.toggle(pane, !!slide);
				evt.stopPropagation();
			});
		return inst;
	}

	/**
	* Add a custom Open button for a pane
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}			pane 		Name of the pane the button is for: 'north', 'south', etc.
	* @param {boolean=}			slide 		true = slide-open, false = pin-open
	*/
,	addOpen: function (inst, selector, pane, slide) {
		$.layout.buttons.get(inst, selector, pane, "open")
			.attr("title", inst.options[pane].tips.Open)
			.click(function (evt) {
				inst.open(pane, !!slide);
				evt.stopPropagation();
			});
		return inst;
	}

	/**
	* Add a custom Close button for a pane
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}   		pane 		Name of the pane the button is for: 'north', 'south', etc.
	*/
,	addClose: function (inst, selector, pane) {
		$.layout.buttons.get(inst, selector, pane, "close")
			.attr("title", inst.options[pane].tips.Close)
			.click(function (evt) {
				inst.close(pane);
				evt.stopPropagation();
			});
		return inst;
	}

	/**
	* Add a custom Pin button for a pane
	*
	* Four classes are added to the element, based on the paneClass for the associated pane...
	* Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin:
	*  - ui-layout-pane-pin
	*  - ui-layout-pane-west-pin
	*  - ui-layout-pane-pin-up
	*  - ui-layout-pane-west-pin-up
	*
	* @param {Object}			inst		Layout Instance object
	* @param {(string|!Object)}	selector	jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
	* @param {string}   		pane 		Name of the pane the pin is for: 'north', 'south', etc.
	*/
,	addPin: function (inst, selector, pane) {
		var	_	= $.layout.buttons
		,	$E	= _.get(inst, selector, pane, "pin");
		if ($E.length) {
			var s = inst.state[pane];
			$E.click(function (evt) {
				_.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed));
				if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open
				else inst.close( pane ); // slide-closed
				evt.stopPropagation();
			});
			// add up/down pin attributes and classes
			_.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding));
			// add this pin to the pane data so we can 'sync it' automatically
			// PANE.pins key is an array so we can store multiple pins for each pane
			s.pins.push( selector ); // just save the selector string
		}
		return inst;
	}

	/**
	* Change the class of the pin button to make it look 'up' or 'down'
	*
	* @see  addPin(), syncPins()
	*
	* @param {Object}			inst	Layout Instance object
	* @param {Array.<Object>}	$Pin	The pin-span element in a jQuery wrapper
	* @param {string}			pane	These are the params returned to callbacks by layout()
	* @param {boolean}			doPin	true = set the pin 'down', false = set it 'up'
	*/
,	setPinState: function (inst, $Pin, pane, doPin) {
		var updown = $Pin.attr("pin");
		if (updown && doPin === (updown=="down")) return; // already in correct state
		var
			o		= inst.options[pane]
		,	pin		= o.buttonClass +"-pin"
		,	side	= pin +"-"+ pane
		,	UP		= pin +"-up "+	side +"-up"
		,	DN		= pin +"-down "+side +"-down"
		;
		$Pin
			.attr("pin", doPin ? "down" : "up") // logic
			.attr("title", doPin ? o.tips.Unpin : o.tips.Pin)
			.removeClass( doPin ? UP : DN ) 
			.addClass( doPin ? DN : UP ) 
		;
	}

	/**
	* INTERNAL function to sync 'pin buttons' when pane is opened or closed
	* Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes
	*
	* @see  open(), close()
	*
	* @param {Object}			inst	Layout Instance object
	* @param {string}	pane	These are the params returned to callbacks by layout()
	* @param {boolean}	doPin	True means set the pin 'down', False means 'up'
	*/
,	syncPinBtns: function (inst, pane, doPin) {
		// REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE
		$.each(inst.state[pane].pins, function (i, selector) {
			$.layout.buttons.setPinState(inst, $(selector), pane, doPin);
		});
	}


,	_load: function (inst) {
		var	_	= $.layout.buttons;
		// ADD Button methods to Layout Instance
		// Note: sel = jQuery Selector string
		$.extend( inst, {
			bindButton:		function (sel, action, pane) { return _.bind(inst, sel, action, pane); }
		//	DEPRECATED METHODS
		,	addToggleBtn:	function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); }
		,	addOpenBtn:		function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); }
		,	addCloseBtn:	function (sel, pane) { return _.addClose(inst, sel, pane); }
		,	addPinBtn:		function (sel, pane) { return _.addPin(inst, sel, pane); }
		});

		// init state array to hold pin-buttons
		for (var i=0; i<4; i++) {
			var pane = $.layout.config.borderPanes[i];
			inst.state[pane].pins = [];
		}

		// auto-init buttons onLoad if option is enabled
		if ( inst.options.autoBindCustomButtons )
			_.init(inst);
	}

,	_unload: function (inst) {
		// TODO: unbind all buttons???
	}

};

// add initialization method to Layout's onLoad array of functions
$.layout.onLoad.push(  $.layout.buttons._load );
//$.layout.onUnload.push( $.layout.buttons._unload );



/**
 * jquery.layout.browserZoom 1.0
 * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $
 *
 * Copyright (c) 2012 
 *   Kevin Dalman (http://allpro.net)
 *
 * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
 * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
 *
 * @dependancies: UI Layout 1.3.0.rc30.1 or higher
 *
 * @support: http://groups.google.com/group/jquery-ui-layout
 *
 * @todo: Extend logic to handle other problematic zooming in browsers
 * @todo: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event
 */

// tell Layout that the plugin is available
$.layout.plugins.browserZoom = true;

$.layout.defaults.browserZoomCheckInterval = 1000;
$.layout.optionsMap.layout.push("browserZoomCheckInterval");

/*
 *	browserZoom methods
 */
$.layout.browserZoom = {

	_init: function (inst) {
		// abort if browser does not need this check
		if ($.layout.browserZoom.ratio() !== false)
			$.layout.browserZoom._setTimer(inst);
	}

,	_setTimer: function (inst) {
		// abort if layout destroyed or browser does not need this check
		if (inst.destroyed) return;
		var o	= inst.options
		,	s	= inst.state
		//	don't need check if inst has parentLayout, but check occassionally in case parent destroyed!
		//	MINIMUM 100ms interval, for performance
		,	ms	= inst.hasParentLayout ?  5000 : Math.max( o.browserZoomCheckInterval, 100 )
		;
		// set the timer
		setTimeout(function(){
			if (inst.destroyed || !o.resizeWithWindow) return;
			var d = $.layout.browserZoom.ratio();
			if (d !== s.browserZoom) {
				s.browserZoom = d;
				inst.resizeAll();
			}
			// set a NEW timeout
			$.layout.browserZoom._setTimer(inst);
		}
		,	ms );
	}

,	ratio: function () {
		var w	= window
		,	s	= screen
		,	d	= document
		,	dE	= d.documentElement || d.body
		,	b	= $.layout.browser
		,	v	= b.version
		,	r, sW, cW
		;
		// we can ignore all browsers that fire window.resize event onZoom
		if ((b.msie && v > 8)
		||	!b.msie
		) return false; // don't need to track zoom

		if (s.deviceXDPI)
			return calc(s.deviceXDPI, s.systemXDPI);
		// everything below is just for future reference!
		if (b.webkit && (r = d.body.getBoundingClientRect))
			return calc((r.left - r.right), d.body.offsetWidth);
		if (b.webkit && (sW = w.outerWidth))
			return calc(sW, w.innerWidth);
		if ((sW = s.width) && (cW = dE.clientWidth))
			return calc(sW, cW);
		return false; // no match, so cannot - or don't need to - track zoom

		function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); }
	}

};
// add initialization method to Layout's onLoad array of functions
$.layout.onReady.push( $.layout.browserZoom._init );



})( jQuery );