text: var curCSS, iframe, iframeDoc,
  	ralpha = /alpha\([^)]*\)/i,
  	ropacity = /opacity\s*=\s*([^)]*)/,
  	rposition = /^(top|right|bottom|left)$/,
  	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
  	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  	rmargin = /^margin/,
  	rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
  	rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
  	rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
  	elemdisplay = { BODY: "block" },
  
  	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  	cssNormalTransform = {
  		letterSpacing: 0,
  		fontWeight: 400
  	},
  
  	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
  	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
  
  // return a css property mapped to a potentially vendor prefixed property
  function vendorPropName( style, name ) {
  
  	// shortcut for names that are not vendor prefixed
  	if ( name in style ) {
  		return name;
  	}
  
  	// check for vendor prefixed names
  	var capName = name.charAt(0).toUpperCase() + name.slice(1),
  		origName = name,
  		i = cssPrefixes.length;
  
  	while ( i-- ) {
  		name = cssPrefixes[ i ] + capName;
  		if ( name in style ) {
  			return name;
  		}
  	}
  
  	return origName;
  }
  
  function isHidden( elem, el ) {
  	// isHidden might be called from jQuery#filter function;
  	// in that case, element will be second argument
  	elem = el || elem;
  	return curCSS( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
  }
  
  function showHide( elements, show ) {
  	var elem,
  		values = [],
  		index = 0,
  		length = elements.length;
  
  	for ( ; index < length; index++ ) {
  		elem = elements[ index ];
  		if ( !elem.style ) {
  			continue;
  		}
  		values[ index ] = jQuery._data( elem, "olddisplay" );
  		if ( show ) {
  			// Reset the inline display of this element to learn if it is
  			// being hidden by cascaded rules or not
  			if ( !values[ index ] && elem.style.display === "none" ) {
  				elem.style.display = "";
  			}
  
  			// Set elements which have been overridden with display: none
  			// in a stylesheet to whatever the default browser style is
  			// for such an element
  			if ( elem.style.display === "" && isHidden( elem ) ) {
  				values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
  			}
  		} else if ( !values[ index ] && !isHidden( elem ) ) {
  			jQuery._data( elem, "olddisplay", curCSS( elem, "display" ) );
  		}
  	}
  
  	// Set the display of most of the elements in a second loop
  	// to avoid the constant reflow
  	for ( index = 0; index < length; index++ ) {
  		elem = elements[ index ];
  		if ( !elem.style ) {
  			continue;
  		}
  		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  			elem.style.display = show ? values[ index ] || "" : "none";
  		}
  	}
  
  	return elements;
  }
  
  jQuery.fn.extend({
  	css: function( name, value ) {
  		return jQuery.access( this, function( elem, name, value ) {
  			return value !== undefined ?
  				jQuery.style( elem, name, value ) :
  				jQuery.css( elem, name );
  		}, name, value, arguments.length > 1 );
  	},
  	show: function() {
  		return showHide( this, true );
  	},
  	hide: function() {
  		return showHide( this );
  	},
  	toggle: function( state ) {
  		var bool = typeof state === "boolean";
  
  		return this.each(function() {
  			if ( bool ? state : isHidden( this ) ) {
  				jQuery( this ).show();
  			} else {
  				jQuery( this ).hide();
  			}
  		});
  	}
  });
  
  jQuery.extend({
  	// Add in style property hooks for overriding the default
  	// behavior of getting and setting a style property
  	cssHooks: {
  		opacity: {
  			get: function( elem, computed ) {
  				if ( computed ) {
  					// We should always get a number back from opacity
  					var ret = curCSS( elem, "opacity" );
  					return ret === "" ? "1" : ret;
  
  				}
  			}
  		}
  	},
  
  	// Exclude the following css properties to add px
  	cssNumber: {
  		"fillOpacity": true,
  		"fontWeight": true,
  		"lineHeight": true,
  		"opacity": true,
  		"orphans": true,
  		"widows": true,
  		"zIndex": true,
  		"zoom": true
  	},
  
  	// Add in properties whose names you wish to fix before
  	// setting or getting the value
  	cssProps: {
  		// normalize float css property
  		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
  	},
  
  	// Get and set the style property on a DOM Node
  	style: function( elem, name, value, extra ) {
  		// Don't set styles on text and comment nodes
  		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  			return;
  		}
  
  		// Make sure that we're working with the right name
  		var ret, type, hooks,
  			origName = jQuery.camelCase( name ),
  			style = elem.style;
  
  		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
  
  		// gets hook for the prefixed version
  		// followed by the unprefixed version
  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  
  		// Check if we're setting a value
  		if ( value !== undefined ) {
  			type = typeof value;
  
  			// convert relative number strings (+= or -=) to relative numbers. #7345
  			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
  				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
  				// Fixes bug #9237
  				type = "number";
  			}
  
  			// Make sure that NaN and null values aren't set. See: #7116
  			if ( value == null || type === "number" && isNaN( value ) ) {
  				return;
  			}
  
  			// If a number was passed in, add 'px' to the (except for certain CSS properties)
  			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
  				value += "px";
  			}
  
  			// If a hook was provided, use that value, otherwise just set the specified value
  			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
  
  				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
  				// Fixes bug #5509
  				try {
  					style[ name ] = value;
  				} catch(e) {}
  			}
  
  		} else {
  			// If a hook was provided get the non-computed value from there
  			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
  				return ret;
  			}
  
  			// Otherwise just get the value from the style object
  			return style[ name ];
  		}
  	},
  
  	css: function( elem, name, numeric, extra ) {
  		var val, num, hooks,
  			origName = jQuery.camelCase( name );
  
  		// Make sure that we're working with the right name
  		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
  
  		// gets hook for the prefixed version
  		// followed by the unprefixed version
  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  
  		// If a hook was provided get the computed value from there
  		if ( hooks && "get" in hooks ) {
  			val = hooks.get( elem, true, extra );
  		}
  
  		// Otherwise, if a way to get the computed value exists, use that
  		if ( val === undefined ) {
  			val = curCSS( elem, name );
  		}
  
  		//convert "normal" to computed value
  		if ( val === "normal" && name in cssNormalTransform ) {
  			val = cssNormalTransform[ name ];
  		}
  
  		// Return, converting to number if forced or a qualifier was provided and val looks numeric
  		if ( numeric || extra !== undefined ) {
  			num = parseFloat( val );
  			return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
  		}
  		return val;
  	},
  
  	// A method for quickly swapping in/out CSS properties to get correct calculations
  	swap: function( elem, options, callback ) {
  		var ret, name,
  			old = {};
  
  		// Remember the old values, and insert the new ones
  		for ( name in options ) {
  			old[ name ] = elem.style[ name ];
  			elem.style[ name ] = options[ name ];
  		}
  
  		ret = callback.call( elem );
  
  		// Revert the old values
  		for ( name in options ) {
  			elem.style[ name ] = old[ name ];
  		}
  
  		return ret;
  	}
  });
  
  // NOTE: To any future maintainer, we've window.getComputedStyle
  // because jsdom on node.js will break without it.
  if ( window.getComputedStyle ) {
  	curCSS = function( elem, name ) {
  		var ret, width, minWidth, maxWidth,
  			computed = window.getComputedStyle( elem, null ),
  			style = elem.style;
  
  		if ( computed ) {
  
  			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
  			ret = computed.getPropertyValue( name ) || computed[ name ];
  
  			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  				ret = jQuery.style( elem, name );
  			}
  
  			// A tribute to the "awesome hack by Dean Edwards"
  			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
  			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
  			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
  			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  				width = style.width;
  				minWidth = style.minWidth;
  				maxWidth = style.maxWidth;
  
  				style.minWidth = style.maxWidth = style.width = ret;
  				ret = computed.width;
  
  				style.width = width;
  				style.minWidth = minWidth;
  				style.maxWidth = maxWidth;
  			}
  		}
  
  		return ret;
  	};
  } else if ( document.documentElement.currentStyle ) {
  	curCSS = function( elem, name ) {
  		var left, rsLeft,
  			ret = elem.currentStyle && elem.currentStyle[ name ],
  			style = elem.style;
  
  		// Avoid setting ret to empty string here
  		// so we don't default to auto
  		if ( ret == null && style && style[ name ] ) {
  			ret = style[ name ];
  		}
  
  		// From the awesome hack by Dean Edwards
  		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  
  		// If we're not dealing with a regular pixel number
  		// but a number that has a weird ending, we need to convert it to pixels
  		// but not position css attributes, as those are proportional to the parent element instead
  		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
  		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
  
  			// Remember the original values
  			left = style.left;
  			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
  
  			// Put in the new values to get a computed value out
  			if ( rsLeft ) {
  				elem.runtimeStyle.left = elem.currentStyle.left;
  			}
  			style.left = name === "fontSize" ? "1em" : ret;
  			ret = style.pixelLeft + "px";
  
  			// Revert the changed values
  			style.left = left;
  			if ( rsLeft ) {
  				elem.runtimeStyle.left = rsLeft;
  			}
  		}
  
  		return ret === "" ? "auto" : ret;
  	};
  }
  
  function setPositiveNumber( elem, value, subtract ) {
  	var matches = rnumsplit.exec( value );
  	return matches ?
  			Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
  			value;
  }
  
  function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
  	var i = extra === ( isBorderBox ? "border" : "content" ) ?
  		// If we already have the right measurement, avoid augmentation
  		4 :
  		// Otherwise initialize for horizontal or vertical properties
  		name === "width" ? 1 : 0,
  
  		val = 0;
  
  	for ( ; i < 4; i += 2 ) {
  		// both box models exclude margin, so add it if we want it
  		if ( extra === "margin" ) {
  			// we use jQuery.css instead of curCSS here
  			// because of the reliableMarginRight CSS hook!
  			val += jQuery.css( elem, extra + cssExpand[ i ], true );
  		}
  
  		// From this point on we use curCSS for maximum performance (relevant in animations)
  		if ( isBorderBox ) {
  			// border-box includes padding, so remove it if we want content
  			if ( extra === "content" ) {
  				val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
  			}
  
  			// at this point, extra isn't border nor margin, so remove border
  			if ( extra !== "margin" ) {
  				val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
  			}
  		} else {
  			// at this point, extra isn't content, so add padding
  			val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
  
  			// at this point, extra isn't content nor padding, so add border
  			if ( extra !== "padding" ) {
  				val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
  			}
  		}
  	}
  
  	return val;
  }
  
  function getWidthOrHeight( elem, name, extra ) {
  
  	// Start with offset property, which is equivalent to the border-box value
  	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  		valueIsBorderBox = true,
  		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
  
  	// some non-html elements return undefined for offsetWidth, so check for null/undefined
  	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  	if ( val <= 0 || val == null ) {
  		// Fall back to computed then uncomputed css if necessary
  		val = curCSS( elem, name );
  		if ( val < 0 || val == null ) {
  			val = elem.style[ name ];
  		}
  
  		// Computed unit is not pixels. Stop here and return.
  		if ( rnumnonpx.test(val) ) {
  			return val;
  		}
  
  		// we need the check for style in case a browser which returns unreliable values
  		// for getComputedStyle silently falls back to the reliable elem.style
  		valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
  
  		// Normalize "", auto, and prepare for extra
  		val = parseFloat( val ) || 0;
  	}
  
  	// use the active box-sizing model to add/subtract irrelevant styles
  	return ( val +
  		augmentWidthOrHeight(
  			elem,
  			name,
  			extra || ( isBorderBox ? "border" : "content" ),
  			valueIsBorderBox
  		)
  	) + "px";
  }
  
  
  // Try to determine the default display value of an element
  function css_defaultDisplay( nodeName ) {
  	if ( elemdisplay[ nodeName ] ) {
  		return elemdisplay[ nodeName ];
  	}
  
  	var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
  		display = elem.css("display");
  	elem.remove();
  
  	// If the simple way fails,
  	// get element's real default display by attaching it to a temp iframe
  	if ( display === "none" || display === "" ) {
  		// Use the already-created iframe if possible
  		iframe = document.body.appendChild(
  			iframe || jQuery.extend( document.createElement("iframe"), {
  				frameBorder: 0,
  				width: 0,
  				height: 0
  			})
  		);
  
  		// Create a cacheable copy of the iframe document on first call.
  		// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
  		// document to it; WebKit & Firefox won't allow reusing the iframe document.
  		if ( !iframeDoc || !iframe.createElement ) {
  			iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
  			iframeDoc.write("<!doctype html><html><body>");
  			iframeDoc.close();
  		}
  
  		elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
  
  		display = curCSS( elem, "display" );
  		document.body.removeChild( iframe );
  	}
  
  	// Store the correct default display
  	elemdisplay[ nodeName ] = display;
  
  	return display;
  }
  
  jQuery.each([ "height", "width" ], function( i, name ) {
  	jQuery.cssHooks[ name ] = {
  		get: function( elem, computed, extra ) {
  			if ( computed ) {
  				// certain elements can have dimension info if we invisibly show them
  				// however, it must have a current display style that would benefit from this
  				if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
  					return jQuery.swap( elem, cssShow, function() {
  						return getWidthOrHeight( elem, name, extra );
  					});
  				} else {
  					return getWidthOrHeight( elem, name, extra );
  				}
  			}
  		},
  
  		set: function( elem, value, extra ) {
  			return setPositiveNumber( elem, value, extra ?
  				augmentWidthOrHeight(
  					elem,
  					name,
  					extra,
  					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
  				) : 0
  			);
  		}
  	};
  });
  
  if ( !jQuery.support.clearCloneStyle ) {
  	// #8908, this part for IE9 only; see gh-886
  	jQuery.cssHooks.backgroundPosition = {
  		set: function( elem, value ) {
  			return value === "" ? "0% 0%" : value;
  		}
  	};
  }
  
  if ( !jQuery.support.opacity ) {
  	jQuery.cssHooks.opacity = {
  		get: function( elem, computed ) {
  			// IE uses filters for opacity
  			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
  				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
  				computed ? "1" : "";
  		},
  
  		set: function( elem, value ) {
  			var style = elem.style,
  				currentStyle = elem.currentStyle,
  				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
  				filter = currentStyle && currentStyle.filter || style.filter || "";
  
  			// IE has trouble with opacity if it does not have layout
  			// Force it by setting the zoom level
  			style.zoom = 1;
  
  			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
  			// if value === "", then remove inline opacity #12685
  			if ( ( value >= 1 || value === "" ) &&
                  jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
  				style.removeAttribute ) {
  
  				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
  				// if "filter:" is present at all, clearType is disabled, we want to avoid this
  				// style.removeAttribute is IE Only, but so apparently is this code path...
  				style.removeAttribute( "filter" );
  
  				// if there is no filter style applied in a css rule or unset inline opacity, we are done
  				if ( value === "" || currentStyle && !currentStyle.filter ) {
  					return;
  				}
  			}
  
  			// otherwise, set new filter values
  			style.filter = ralpha.test( filter ) ?
  				filter.replace( ralpha, opacity ) :
  				filter + " " + opacity;
  		}
  	};
  }
  
  // These hooks cannot be added until DOM ready because the support test
  // for it is not run until after DOM ready
  jQuery(function() {
  	if ( !jQuery.support.reliableMarginRight ) {
  		jQuery.cssHooks.marginRight = {
  			get: function( elem, computed ) {
  				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  				// Work around by temporarily setting element display to inline-block
  				return jQuery.swap( elem, { "display": "inline-block" }, function() {
  					if ( computed ) {
  						return curCSS( elem, "marginRight" );
  					}
  				});
  			}
  		};
  	}
  
  	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  	// getComputedStyle returns percent when specified for top/left/bottom/right
  	// rather than make the css module depend on the offset module, we just check for it here
  	if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
  		jQuery.each( [ "top", "left" ], function( i, prop ) {
  			jQuery.cssHooks[ prop ] = {
  				get: function( elem, computed ) {
  					if ( computed ) {
  						var ret = curCSS( elem, prop );
  						// if curCSS returns percentage, fallback to offset
  						return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
  					}
  				}
  			};
  		});
  	}
  
  });
  
  if ( jQuery.expr && jQuery.expr.filters ) {
  	jQuery.expr.filters.hidden = function( elem ) {
  		return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
  	};
  
  	jQuery.expr.filters.visible = function( elem ) {
  		return !jQuery.expr.filters.hidden( elem );
  	};
  }
  
  // These hooks are used by animate to expand properties
  jQuery.each({
  	margin: "",
  	padding: "",
  	border: "Width"
  }, function( prefix, suffix ) {
  	jQuery.cssHooks[ prefix + suffix ] = {
  		expand: function( value ) {
  			var i,
  
  				// assumes a single number if not a string
  				parts = typeof value === "string" ? value.split(" ") : [ value ],
  				expanded = {};
  
  			for ( i = 0; i < 4; i++ ) {
  				expanded[ prefix + cssExpand[ i ] + suffix ] =
  					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  			}
  
  			return expanded;
  		}
  	};
  
  	if ( !rmargin.test( prefix ) ) {
  		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  	}
  });
  