

jQuery.fn.bgIframe = jQuery.fn.bgiframe = function() {
	// This is only for IE6
	if ( !(jQuery.browser.msie && typeof XMLHttpRequest == 'function') ) return this;
	var html = '<iframe class="bgiframe" src="javascript:false;document.write(\'\');" tabindex="-1" '
	 					+'style="display:block; position:absolute; '
						+'top: expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)  || 0) * -1) + \'px\'); '
						+'left:expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth) || 0) * -1) + \'px\'); ' 
						+'z-index:-1; filter:Alpha(Opacity=\'0\'); '
						+'width:expression(this.parentNode.offsetWidth + \'px\'); '
						+'height:expression(this.parentNode.offsetHeight + \'px\')"/>';
	return this.each(function() {
		if ( !jQuery('iframe.bgiframe', this)[0] )
			this.insertBefore( document.createElement(html), this.firstChild );
	});
};


/*
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-03-04 20:15:11 -0600 (Sun, 04 Mar 2007) $
 * $Rev: 1485 $
 */

jQuery.fn._height = jQuery.fn.height;
jQuery.fn._width  = jQuery.fn.width;

/**
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 * See core docs on height() to see what happens when used on an element.
 *
 * @example $("#testdiv").height()
 * @result 200
 *
 * @example $(document).height()
 * @result 800
 *
 * @example $(window).height()
 * @result 400
 *
 * @name height
 * @type Object
 * @cat Plugins/Dimensions
 */
jQuery.fn.height = function() {
	if ( this[0] == window )
		return self.innerHeight ||
			jQuery.boxModel && document.documentElement.clientHeight ||
			document.body.clientHeight;

	if ( this[0] == document )
		return Math.max( document.body.scrollHeight, document.body.offsetHeight );

	return this._height(arguments[0]);
};

/**
 * If used on document, returns the document's width (innerWidth)
 * If used on window, returns the viewport's (window) width
 * See core docs on height() to see what happens when used on an element.
 *
 * @example $("#testdiv").width()
 * @result 200
 *
 * @example $(document).width()
 * @result 800
 *
 * @example $(window).width()
 * @result 400
 *
 * @name width
 * @type Object
 * @cat Plugins/Dimensions
 */
jQuery.fn.width = function() {
	if ( this[0] == window )
		return self.innerWidth ||
			jQuery.boxModel && document.documentElement.clientWidth ||
			document.body.clientWidth;

	if ( this[0] == document )
		return Math.max( document.body.scrollWidth, document.body.offsetWidth );

	return this._width(arguments[0]);
};

/**
 * Returns the inner height value (without border) for the first matched element.
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 *
 * @example $("#testdiv").innerHeight()
 * @result 800
 *
 * @name innerHeight
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.innerHeight = function() {
	return this[0] == window || this[0] == document ?
		this.height() :
		this.css('display') != 'none' ?
		 	this[0].offsetHeight - (parseInt(this.css("borderTopWidth")) || 0) - (parseInt(this.css("borderBottomWidth")) || 0) :
			this.height() + (parseInt(this.css("paddingTop")) || 0) + (parseInt(this.css("paddingBottom")) || 0);
};

/**
 * Returns the inner width value (without border) for the first matched element.
 * If used on document, returns the document's Width (innerWidth)
 * If used on window, returns the viewport's (window) width
 *
 * @example $("#testdiv").innerWidth()
 * @result 1000
 *
 * @name innerWidth
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.innerWidth = function() {
	return this[0] == window || this[0] == document ?
		this.width() :
		this.css('display') != 'none' ?
			this[0].offsetWidth - (parseInt(this.css("borderLeftWidth")) || 0) - (parseInt(this.css("borderRightWidth")) || 0) :
			this.height() + (parseInt(this.css("paddingLeft")) || 0) + (parseInt(this.css("paddingRight")) || 0);
};

/**
 * Returns the outer height value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerHeight()
 * @result 1000
 *
 * @name outerHeight
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.outerHeight = function() {
	return this[0] == window || this[0] == document ?
		this.height() :
		this.css('display') != 'none' ?
			this[0].offsetHeight :
			this.height() + (parseInt(this.css("borderTopWidth")) || 0) + (parseInt(this.css("borderBottomWidth")) || 0)
				+ (parseInt(this.css("paddingTop")) || 0) + (parseInt(this.css("paddingBottom")) || 0);
};

/**
 * Returns the outer width value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerWidth()
 * @result 1000
 *
 * @name outerWidth
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.outerWidth = function() {
	return this[0] == window || this[0] == document ?
		this.width() :
		this.css('display') != 'none' ?
			this[0].offsetWidth :
			this.height() + (parseInt(this.css("borderLeftWidth")) || 0) + (parseInt(this.css("borderRightWidth")) || 0)
				+ (parseInt(this.css("paddingLeft")) || 0) + (parseInt(this.css("paddingRight")) || 0);
};

/**
 * Returns how many pixels the user has scrolled to the right (scrollLeft).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollLeft()
 * @result 100
 *
 * @name scrollLeft
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.scrollLeft = function() {
	if ( this[0] == window || this[0] == document )
		return self.pageXOffset ||
			jQuery.boxModel && document.documentElement.scrollLeft ||
			document.body.scrollLeft;

	return this[0].scrollLeft;
};

/**
 * Returns how many pixels the user has scrolled to the bottom (scrollTop).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollTop()
 * @result 100
 *
 * @name scrollTop
 * @type Number
 * @cat Plugins/Dimensions
 */
jQuery.fn.scrollTop = function() {
	if ( this[0] == window || this[0] == document )
		return self.pageYOffset ||
			jQuery.boxModel && document.documentElement.scrollTop ||
			document.body.scrollTop;

	return this[0].scrollTop;
};

/**
 * Returns the location of the element in pixels from the top left corner of the viewport.
 *
 * For accurate readings make sure to use pixel values for margins, borders and padding.
 *
 * @example $("#testdiv").offset()
 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
 *
 * @example $("#testdiv").offset({ scroll: false })
 * @result { top: 90, left: 90 }
 *
 * @example var offset = {}
 * $("#testdiv").offset({ scroll: false }, offset)
 * @result offset = { top: 90, left: 90 }
 *
 * @name offset
 * @param Object options A hash of options describing what should be included in the final calculations of the offset.
 *                       The options include:
 *                           margin: Should the margin of the element be included in the calculations? True by default.
 *                                   If set to false the margin of the element is subtracted from the total offset.
 *                           border: Should the border of the element be included in the calculations? True by default.
 *                                   If set to false the border of the element is subtracted from the total offset.
 *                           padding: Should the padding of the element be included in the calculations? False by default.
 *                                    If set to true the padding of the element is added to the total offset.
 *                           scroll: Should the scroll offsets of the parent elements be included in the calculations?
 *                                   True by default. When true, it adds the total scroll offsets of all parents to the
 *                                   total offset and also adds two properties to the returned object, scrollTop and
 *                                   scrollLeft. If set to false the scroll offsets of parent elements are ignored.
 *                                   If scroll offsets are not needed, set to false to get a performance boost.
 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
 *                            chain will not be broken and the result will be assigned to this object.
 * @type Object
 * @cat Plugins/Dimensions
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
jQuery.fn.offset = function(options, returnObject) {
	var x = 0, y = 0, elem = this[0], parent = this[0], op, sl = 0, st = 0, options = jQuery.extend({ margin: true, border: true, padding: false, scroll: true }, options || {});
	do {
		x += parent.offsetLeft || 0;
		y += parent.offsetTop  || 0;

		// Mozilla and IE do not add the border
		if (jQuery.browser.mozilla || jQuery.browser.msie) {
			// get borders
			var bt = parseInt(jQuery.css(parent, 'borderTopWidth')) || 0;
			var bl = parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;

			// add borders to offset
			x += bl;
			y += bt;

			// Mozilla removes the border if the parent has overflow property other than visible
			if (jQuery.browser.mozilla && parent != elem && jQuery.css(parent, 'overflow') != 'visible') {
				x += bl;
				y += bt;
			}
		}

		if (options.scroll) {
			// Need to get scroll offsets in-between offsetParents
			op = parent.offsetParent;
			do {
				sl += parent.scrollLeft || 0;
				st += parent.scrollTop  || 0;

				parent = parent.parentNode;

				// Mozilla removes the border if the parent has overflow property other than visible
				if (jQuery.browser.mozilla && parent != elem && parent != op && jQuery.css(parent, 'overflow') != 'visible') {
					y += parseInt(jQuery.css(parent, 'borderTopWidth')) || 0;
					x += parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;
				}
			} while (parent != op);
		} else
			parent = parent.offsetParent;

		if (parent && (parent.tagName.toLowerCase() == 'body' || parent.tagName.toLowerCase() == 'html')) {
			// Safari doesn't add the body margin for elments positioned with static or relative
			if ((jQuery.browser.safari || (jQuery.browser.msie && jQuery.boxModel)) && jQuery.css(parent, 'position') != 'absolute') {
				x += parseInt(jQuery.css(op, 'marginLeft')) || 0;
				y += parseInt(jQuery.css(op, 'marginTop'))  || 0;
			}
			break; // Exit the loop
		}
	} while (parent);

	if ( !options.margin) {
		x -= parseInt(jQuery.css(elem, 'marginLeft')) || 0;
		y -= parseInt(jQuery.css(elem, 'marginTop'))  || 0;
	}

	// Safari and Opera do not add the border for the element
	if ( options.border && (jQuery.browser.safari || jQuery.browser.opera) ) {
		x += parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0;
		y += parseInt(jQuery.css(elem, 'borderTopWidth'))  || 0;
	} else if ( !options.border && !(jQuery.browser.safari || jQuery.browser.opera) ) {
		x -= parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0;
		y -= parseInt(jQuery.css(elem, 'borderTopWidth'))  || 0;
	}

	if ( options.padding ) {
		x += parseInt(jQuery.css(elem, 'paddingLeft')) || 0;
		y += parseInt(jQuery.css(elem, 'paddingTop'))  || 0;
	}

	// Opera thinks offset is scroll offset for display: inline elements
	if (options.scroll && jQuery.browser.opera && jQuery.css(elem, 'display') == 'inline') {
		sl -= elem.scrollLeft || 0;
		st -= elem.scrollTop  || 0;
	}

	var returnValue = options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
	                                 : { top: y, left: x };

	if (returnObject) { jQuery.extend(returnObject, returnValue); return this; }
	else              { return returnValue; }
};


/*
 * jdMenu 1.3.beta2 (2007-03-06)
 *
 * Copyright (c) 2006,2007 Jonathan Sharp (http://jdsharp.us)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://jdsharp.us/
 *
 * Built upon jQuery 1.1.1 (http://jquery.com)
 * This also requires the jQuery dimensions plugin
 */
(function($){
	// This will store an element list of all our menu objects
	var jdMenu = [];
	
	// Public methods
	$.fn.jdMenu = function(inSettings) {
		var settings = $.extend({}, arguments.callee.defaults, inSettings);
		return this.each(function() {
			jdMenu.push(this);
			$(this).addClass('jd_menu_flag_root');
			this.$settings = $.extend({}, settings, {isVerticalMenu: $(this).is('.jd_menu_vertical')});
			addEvents(this);
		});
	};
	$.fn.jdMenuShow = function() {
		return this.each(function() {
			showMenuLI.apply(this);
		});
	};
	$.fn.jdMenuHide = function() {
		return this.each(function() {
			hideMenuUL.apply(this);
		});
	};

	// Private methods and logic
	$(window)
		// Bind a click event to hide all visible menus when the document is clicked
		.bind('click', function(){
			$(jdMenu).find('ul:visible').jdMenuHide();
		})
		// Cleanup after ourself by nulling the $settings object
		.bind('unload', function() {
			$(jdMenu).each(function() {
				this.$settings = null;
			});
		});

	// These are our default settings for this plugin
	$.fn.jdMenu.defaults = {
		// activateDelay: 750,
		activateDelay: 500,
		showDelay: 150,
		hideDelay: 550,
		onShow: null,
		onHideCheck: null,
		onHide: null,
		onAnimate: null,
		onClick: null,
		offsetX: 4,
		offsetY: 2,

		iframe: $.browser.msie
	};
	
	// Our special parentsUntil method to get all parents up to and including the matched element
	$.fn.parentsUntil = function(match) {
		var a = [];
		$(this[0]).parents().each(function() {
			a.push(this);
			return !$(this).is(match);
		});
		return this.pushStack(a, arguments);
	};

	// Returns our settings object for this menu
	function getSettings(el) {
	 return $(el).parents('ul.jd_menu_flag_root')[0].$settings;
	}

	// Unbind any events and then rebind them
	function addEvents(ul) {
		removeEvents(ul);
		$('> li', ul)
			.hover(hoverOverLI, hoverOutLI)
			.bind('click', itemClick)
			.find('> a.accessible')
				.bind('click', accessibleClick);
	};
	
	// Remove all events for this menu
	function removeEvents(ul) {
		$('> li', ul)
			.unbind('mouseover').unbind('mouseout')
			.unbind('click')
			.find('> a.accessible')
				.unbind('click');
	};
	
	function hoverOverLI() {
		var cls = 'jd_menu_hover' + ($(this).parent().is('.jd_menu_flag_root') ? '_menubar' : '');
		$(this).addClass(cls).find('> a').addClass(cls);
		
		if (this.$timer) {
			clearTimeout(this.$timer);
		}

		// Do we have a sub menu?
		if ($('> ul', this).size() > 0) {
			var settings = getSettings(this);
			
			// Which delay to use, the longer activate one or the shorter show delay if a menu is already visible
			var delay = ($(this).parents('ul.jd_menu_flag_root').find('ul:visible').size() == 0) 
							? settings.activateDelay : settings.showDelay;
			var t = this;
			this.$timer = setTimeout(function() {
				showMenuLI.apply(t);
			}, delay);
		}
	};
	
	function hoverOutLI() {
		// Remove both classes so we do not have to test which one we are
		$(this)	.removeClass('jd_menu_hover').removeClass('jd_menu_hover_menubar')
			.find('> a')
				.removeClass('jd_menu_hover').removeClass('jd_menu_hover_menubar');
		
		if (this.$timer) {
			clearTimeout(this.$timer);
		}

		// TODO: Possible bug with our test for visibility in that parent menus are hidden child menus are not

		// If we have a visible menu, hide it
		if ($(this).is(':visible') && $('> ul', this).size() > 0) {
			var settings = getSettings(this);
			var ul = $('> ul', this)[0];
			this.$timer = setTimeout(function() {
				hideMenuUL.apply(ul);
			}, settings.hideDelay);
		}
	};
	
	// "this" is a reference to the LI element that contains 
	// the UL that will be shown
	function showMenuLI() {
		var ul = $('> ul', this).get(0);
		// We are already visible, just return
		if ($(ul).is(':visible')) {
			return false;
		}

		// Clear our timer if it exists
		if (this.$timer) {
			clearTimeout(this.$timer);
		}

		// Get our settings object
		var settings = getSettings(this);

		// Call our callback
		if (settings.onShow != null && settings.onShow.apply(this) == false) {
			return false;
		}

		// Add hover classes, needed for accessible functionality
		var isRoot = $(this).parent().is('.jd_menu_flag_root');
		var c = 'jd_menu_active' + (isRoot ? '_menubar' : '');
		$(this).addClass(c).find('> a').addClass(c);

		if (!isRoot) {
			// Add the active class to the parent list item which maybe our menubar
			var c = 'jd_menu_active' + ($(this).parent().parent().parent().is('.jd_menu_flag_root') ? '_menubar' : '');
			$(this).parent().parent().addClass(c).find('> a').addClass(c);
		}

		// Hide any existing menues at the same level
		$(this).parent().find('> li > ul:visible').not(ul).each(function() {
			hideMenuUL.apply(this);
		});

		addEvents(ul);

		// Our range object is used in calculating menu positions
		var Range = function(x1, x2, y1, y2) {
			this.x1	= x1;
			this.x2 = x2;
			this.y1 = y1;
			this.y2 = y2;
		}
		Range.prototype.contains = function(range) {
			return 	(this.x1 <= range.x1 && range.x2 <= this.x2) 
					&& 
					(this.y1 <= range.y1 && range.y2 <= this.y2);
		}
		Range.prototype.transform = function(x, y) {
			return new Range(this.x1 + x, this.x2 + x, this.y1 + y, this.y2 + y);
		}
		Range.prototype.nudgeX = function(range) {
			if (this.x1 < range.x1) {
				return new Range(range.x1, range.x1 + (this.x2 - this.x1), this.y1, this.y2);
			} else if (this.x2 > range.x2) {
				return new Range(range.x2 - (this.x2 - this.x1), range.x2, this.y1, this.y2);
			}
			return this;
		}
		Range.prototype.nudgeY = function(range) {
			if (this.y1 < range.y1) {
				return new Range(this.x1, this.x2, range.y1, range.y1 + (this.y2 - this.y1));
			} else if (this.y2 > range.y2) {
				return new Range(this.x1, this.x2, range.y2 - (this.y2 - this.y1), range.y2);
			}
			return this;
		}

		// window width & scroll offset
		var sx = $(window).scrollLeft()
		var sy = $(window).scrollTop();
		var ww = $(window).innerWidth();
		var wh = $(window).innerHeight();

		var viewport = new Range(	sx, sx + ww, 
									sy, sy + wh);

		// "Show" our menu so we can calculate its width, set left and top so that it does not accidentally
		// go offscreen and trigger browser scroll bars
		$(ul).css({visibility: 'hidden', left: 0, top: 0}).show();

		var menuWidth		= $(ul).outerWidth();
		var menuHeight		= $(ul).outerHeight();

		// Get the LI parent UL outerwidth in case borders are applied to it
		var tp 				= $(this).parent();
		var thisWidth		= tp.outerWidth();
		var thisBorderWidth	= parseInt(tp.css('borderLeftWidth')) + parseInt(tp.css('borderRightWidth'));
		//var thisBorderTop 	= parseInt(tp.css('borderTopWidth'));
		var thisHeight		= $(this).outerHeight();
		var thisOffset 		= $(this).offset({border: false});

		$(ul).hide().css({visibility: ''});

		// We define a list of valid positions for our menu and then test against them to find one that works best
		var position = [];
	// Bottom Horizontal
		// Menu is directly below and left edges aligned to parent item
		position[0] = new Range(thisOffset.left, thisOffset.left + menuWidth, 
								thisOffset.top + thisHeight, thisOffset.top + thisHeight + menuHeight);
		// Menu is directly below and right edges aligned to parent item
		position[1] = new Range((thisOffset.left + thisWidth) - menuWidth, thisOffset.left + thisWidth,
								position[0].y1, position[0].y2);
		// Menu is "nudged" horizontally below parent item
		position[2] = position[0].nudgeX(viewport);

	// Right vertical
		// Menu is directly right and top edge aligned to parent item
		position[3] = new Range(thisOffset.left + thisWidth - thisBorderWidth, thisOffset.left + thisWidth - thisBorderWidth + menuWidth,
								thisOffset.top, thisOffset.top + menuHeight);
		// Menu is directly right and bottom edges aligned with parent item
		position[4] = new Range(position[3].x1, position[3].x2, 
								position[0].y1 - menuHeight, position[0].y1);
		// Menu is "nudged" vertically to right of parent item
		position[5] = position[3].nudgeY(viewport);

	// Top Horizontal
		// Menu is directly top and left edges aligned to parent item
		position[6] = new Range(thisOffset.left, thisOffset.left + menuWidth, 
								thisOffset.top - menuHeight, thisOffset.top);
		// Menu is directly top and right edges aligned to parent item
		position[7] = new Range((thisOffset.left + thisWidth) - menuWidth, thisOffset.left + thisWidth,
								position[6].y1, position[6].y2);
		// Menu is "nudged" horizontally to the top of parent item
		position[8] = position[6].nudgeX(viewport);
	
	// Left vertical
		// Menu is directly left and top edges aligned to parent item
		position[9] = new Range(thisOffset.left - menuWidth, thisOffset.left, 
								position[3].y1, position[3].y2);
		// Menu is directly left and bottom edges aligned to parent item
		position[10]= new Range(position[9].x1, position[9].x2, 
								position[4].y1 + thisHeight - menuHeight, position[4].y1 + thisHeight);
		// Menu is "nudged" vertically to left of parent item
		position[11]= position[10].nudgeY(viewport);

		// This defines the order in which we test our positions
		var order = [];
		if ($(this).parent().is('.jd_menu_flag_root') && !settings.isVerticalMenu) {
			order = [0, 1, 2, 6, 7, 8, 5, 11];
		} else {
			order = [3, 4, 5, 9, 10, 11, 0, 1, 2, 6, 7, 8];
		}

		// Set our default position (first position) if no others can be found
		var pos = order[0];
		for (var i = 0, j = order.length; i < j; i++) {
			// If this position for our menu is within the viewport of the browser, use this position
			if (viewport.contains(position[order[i]])) {
				pos = order[i];
				break;
			}
		}
		var menuPosition = position[pos];

		// Find if we are absolutely positioned or have an absolutely positioned parent
		$(this).add($(this).parents()).each(function() {
			if ($(this).css('position') == 'absolute') {
				var abs = $(this).offset();
				// Transform our coordinates to be relative to the absolute parent
				menuPosition = menuPosition.transform(-abs.left, -abs.top);
				return false;
			}
		});

		switch (pos) {
			case 3:
				menuPosition.y1 += settings.offsetY;
			case 4:
				menuPosition.x1 -= settings.offsetX;
				break;
			
			case 9:
				menuPosition.y1 += settings.offsetY;
			case 10:
				menuPosition.x1 += settings.offsetX;
				break;
		}

		if (settings.iframe) {
			$(ul).bgiframe();
		}

		if (settings.onAnimate) {
			$(ul).css({left: menuPosition.x1, top: menuPosition.y1});
			// The onAnimate method is expected to "show" the element it is passed
			settings.onAnimate.apply(ul, [true]);
		} else {
			$(ul).css({left: menuPosition.x1, top: menuPosition.y1}).show();
		}

		return true;
	}

	// "this" is a reference to a UL menu to be hidden
	function hideMenuUL(recurse) {
		if (!$(this).is(':visible')) {
			return false;
		}

		// JM added the try/catch
		try {
			var settings = getSettings(this);
		} catch (e){
			var settings = null;
		}

		// Test if this menu should get hidden
		// if (settings.onHideCheck != null && settings.onHideCheck.apply(this) == false) {
		
		// JM changed this from above -- do we even have settings?
		if (settings && settings.onHideCheck != null && settings.onHideCheck.apply(this) == false) {
			return false;
		}
		
		// Hide all of our child menus first
		$('> li ul:visible', this).each(function() {
			hideMenuUL.apply(this, [false]);
		});

		// If we are the root, do not hide ourself
		if ($(this).is('.jd_menu_flag_root')) {
			// JM commented the alert out
			// alert('We are root');
			return false;
		}

		var elms = $('> li', this).add($(this).parent());
		elms.removeClass('jd_menu_hover').removeClass('jd_menu_hover_menubar')
			.removeClass('jd_menu_active').removeClass('jd_menu_active_menubar')
			.find('> a')
				.removeClass('jd_menu_hover').removeClass('jd_menu_hover_menubar')
				.removeClass('jd_menu_active').removeClass('jd_menu_active_menubar');

		removeEvents(this);
		$(this).each(function() {
			if (settings.onAnimate != null) {
				settings.onAnimate.apply(this, [false]);
			} else {
				$(this).hide();
			}
		}).find('> .bgiframe').remove();
		// Our callback for after our menu is hidden
		if (settings.onHide != null) {
			settings.onHide.apply(this);
		}

		// Recursively hide our parent menus
		if (recurse == true) {
			$(this).parentsUntil('ul.jd_menu_flag_root')
					.removeClass('jd_menu_hover').removeClass('jd_menu_hover_menubar')
				.not('.jd_menu_flag_root').filter('ul')
					.each(function() {
						hideMenuUL.apply(this, [false]);
					});
		}

		return true;
	}

	// Prevent the default (usually following a link)
	function accessibleClick(e) {
		if ($(this).is('.accessible')) {
			// Stop the browser from the default link action allowing the 
			// click event to propagate to propagate to our LI (itemClick function)
			e.preventDefault();
		}
	}

	// Trigger a menu click
	function itemClick(e) {
		e.stopPropagation();

		var settings = getSettings(this);
		if (settings.onClick != null && settings.onClick.apply(this) == false) {
			return false;
		}

		if ($('> ul', this).size() > 0) {
			showMenuLI.apply(this);
		} else {
			if (e.target == this) {
				var link = $('> a', e.target).not('.accessible');
				if (link.size() > 0) {
					var a = link.get(0);
					if (!a.onclick) {
						window.open(a.href, a.target || '_self');
					} else {
						$(a).click();
					}
				}
			}
			
			hideMenuUL.apply($(this).parent(), [true]);
		}
	}
})(jQuery);

