+
+
+
+
+ The system has been shutdown, please wait a
+ moment!
+ <%
+ Exception exception = (Exception) request.getAttribute("exception");
+ //exception.printStackTrace(response.getWriter());
+ %>
+
\ No newline at end of file
diff --git a/WebContent/index.jsp b/WebContent/index.jsp
new file mode 100644
index 0000000..3336cb6
--- /dev/null
+++ b/WebContent/index.jsp
@@ -0,0 +1,3 @@
+<%@ taglib prefix="s" uri="/struts-tags"%>
+1">Show
+manh">Find by name
\ No newline at end of file
diff --git a/WebContent/js/jquery-1.7.1.js b/WebContent/js/jquery-1.7.1.js
new file mode 100644
index 0000000..5a88984
--- /dev/null
+++ b/WebContent/js/jquery-1.7.1.js
@@ -0,0 +1,9806 @@
+/*!
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function(window, undefined) {
+
+ // Use the correct document accordingly with window argument (sandbox)
+ var document = window.document, navigator = window.navigator, location = window.location;
+ var jQuery = (function() {
+
+ // Define a local copy of jQuery
+ var jQuery = function(selector, context) {
+ // The jQuery object is actually just the init constructor
+ // 'enhanced'
+ return new jQuery.fn.init(selector, context, rootjQuery);
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/, trimRight = /\s+$/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/, rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/, ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Matches dashed string for camelizing
+ rdashAlpha = /-([a-z]|[0-9])/ig, rmsPrefix = /^-ms-/,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function(all, letter) {
+ return (letter + "").toUpperCase();
+ },
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // The deferred used on DOM ready
+ readyList,
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString, hasOwn = Object.prototype.hasOwnProperty, push = Array.prototype.push, slice = Array.prototype.slice, trim = String.prototype.trim, indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+ jQuery.fn = jQuery.prototype = {
+ constructor : jQuery,
+ init : function(selector, context, rootjQuery) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if (!selector) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if (selector.nodeType) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if (selector === "body" && !context && document.body) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if (typeof selector === "string") {
+ // Are we dealing with HTML string or an ID?
+ if (selector.charAt(0) === "<"
+ && selector.charAt(selector.length - 1) === ">"
+ && selector.length >= 3) {
+ // Assume that strings that start and end with <> are
+ // HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = quickExpr.exec(selector);
+ }
+
+ // Verify a match, and that no context was specified for #id
+ if (match && (match[1] || !context)) {
+
+ // HANDLE: $(html) -> $(array)
+ if (match[1]) {
+ context = context instanceof jQuery ? context[0]
+ : context;
+ doc = (context ? context.ownerDocument || context
+ : document);
+
+ // If a single string is passed in and it's a single
+ // tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec(selector);
+
+ if (ret) {
+ if (jQuery.isPlainObject(context)) {
+ selector = [ document.createElement(ret[1]) ];
+ jQuery.fn.attr
+ .call(selector, context, true);
+
+ } else {
+ selector = [ doc.createElement(ret[1]) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment([ match[1] ],
+ [ doc ]);
+ selector = (ret.cacheable ? jQuery
+ .clone(ret.fragment) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge(this, selector);
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById(match[2]);
+
+ // Check parentNode to catch when Blackberry 4.6
+ // returns
+ // nodes that are no longer in the document #6963
+ if (elem && elem.parentNode) {
+ // Handle the case where IE and Opera return
+ // items
+ // by name instead of ID
+ if (elem.id !== match[2]) {
+ return rootjQuery.find(selector);
+ }
+
+ // Otherwise, we inject the element directly
+ // into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if (!context || context.jquery) {
+ return (context || rootjQuery).find(selector);
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor(context).find(selector);
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if (jQuery.isFunction(selector)) {
+ return rootjQuery.ready(selector);
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray(selector, this);
+ },
+
+ // Start with an empty selector
+ selector : "",
+
+ // The current version of jQuery being used
+ jquery : "1.7.1",
+
+ // The default length of a jQuery object is 0
+ length : 0,
+
+ // The number of elements contained in the matched element set
+ size : function() {
+ return this.length;
+ },
+
+ toArray : function() {
+ return slice.call(this, 0);
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get : function(num) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ (num < 0 ? this[this.length + num] : this[num]);
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack : function(elems, name, selector) {
+ // Build a new jQuery matched element set
+ var ret = this.constructor();
+
+ if (jQuery.isArray(elems)) {
+ push.apply(ret, elems);
+
+ } else {
+ jQuery.merge(ret, elems);
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if (name === "find") {
+ ret.selector = this.selector + (this.selector ? " " : "")
+ + selector;
+ } else if (name) {
+ ret.selector = this.selector + "." + name + "(" + selector
+ + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each : function(callback, args) {
+ return jQuery.each(this, callback, args);
+ },
+
+ ready : function(fn) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // Add the callback
+ readyList.add(fn);
+
+ return this;
+ },
+
+ eq : function(i) {
+ i = +i;
+ return i === -1 ? this.slice(i) : this.slice(i, i + 1);
+ },
+
+ first : function() {
+ return this.eq(0);
+ },
+
+ last : function() {
+ return this.eq(-1);
+ },
+
+ slice : function() {
+ return this.pushStack(slice.apply(this, arguments), "slice",
+ slice.call(arguments).join(","));
+ },
+
+ map : function(callback) {
+ return this.pushStack(jQuery.map(this, function(elem, i) {
+ return callback.call(elem, i, elem);
+ }));
+ },
+
+ end : function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push : push,
+ sort : [].sort,
+ splice : [].splice
+ };
+
+ // Give the init function the jQuery prototype for later instantiation
+ jQuery.fn.init.prototype = jQuery.fn;
+
+ jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone, target = arguments[0]
+ || {}, i = 1, length = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if (typeof target === "boolean") {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in
+ // deep copy)
+ if (typeof target !== "object" && !jQuery.isFunction(target)) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if (length === i) {
+ target = this;
+ --i;
+ }
+
+ for (; i < length; i++) {
+ // Only deal with non-null/undefined values
+ if ((options = arguments[i]) != null) {
+ // Extend the base object
+ for (name in options) {
+ src = target[name];
+ copy = options[name];
+
+ // Prevent never-ending loop
+ if (target === copy) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if (deep
+ && copy
+ && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery
+ .isArray(copy)))) {
+ if (copyIsArray) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src
+ : {};
+ }
+
+ // Never move original objects, clone them
+ target[name] = jQuery.extend(deep, clone, copy);
+
+ // Don't bring in undefined values
+ } else if (copy !== undefined) {
+ target[name] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+ };
+
+ jQuery
+ .extend({
+ noConflict : function(deep) {
+ if (window.$ === jQuery) {
+ window.$ = _$;
+ }
+
+ if (deep && window.jQuery === jQuery) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady : false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait : 1,
+
+ // Hold (or release) the ready event
+ holdReady : function(hold) {
+ if (hold) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready(true);
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready : function(wait) {
+ // Either a released hold or an DOMready/load event and
+ // not yet ready
+ if ((wait === true && !--jQuery.readyWait)
+ || (wait !== true && !jQuery.isReady)) {
+ // Make sure body exists, at least, in case IE gets
+ // a little overzealous (ticket #5443).
+ if (!document.body) {
+ return setTimeout(jQuery.ready, 1);
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and
+ // wait if need be
+ if (wait !== true && --jQuery.readyWait > 0) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.fireWith(document, [ jQuery ]);
+
+ // Trigger any bound ready events
+ if (jQuery.fn.trigger) {
+ jQuery(document).trigger("ready").off("ready");
+ }
+ }
+ },
+
+ bindReady : function() {
+ if (readyList) {
+ return;
+ }
+
+ readyList = jQuery.Callbacks("once memory");
+
+ // Catch cases where $(document).ready() is called after
+ // the
+ // browser event has already occurred.
+ if (document.readyState === "complete") {
+ // Handle it asynchronously to allow scripts the
+ // opportunity to delay ready
+ return setTimeout(jQuery.ready, 1);
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support
+ // this event
+ if (document.addEventListener) {
+ // Use the handy event callback
+ document.addEventListener("DOMContentLoaded",
+ DOMContentLoaded, false);
+
+ // A fallback to window.onload, that will always
+ // work
+ window
+ .addEventListener("load", jQuery.ready,
+ false);
+
+ // If IE event model is used
+ } else if (document.attachEvent) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange",
+ DOMContentLoaded);
+
+ // A fallback to window.onload, that will always
+ // work
+ window.attachEvent("onload", jQuery.ready);
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch (e) {
+ }
+
+ if (document.documentElement.doScroll && toplevel) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction : function(obj) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray : Array.isArray || function(obj) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow : function(obj) {
+ return obj && typeof obj === "object"
+ && "setInterval" in obj;
+ },
+
+ isNumeric : function(obj) {
+ return !isNaN(parseFloat(obj)) && isFinite(obj);
+ },
+
+ type : function(obj) {
+ return obj == null ? String(obj) : class2type[toString
+ .call(obj)]
+ || "object";
+ },
+
+ isPlainObject : function(obj) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of
+ // the constructor property.
+ // Make sure that DOM nodes and window objects don't
+ // pass through, as well
+ if (!obj || jQuery.type(obj) !== "object"
+ || obj.nodeType || jQuery.isWindow(obj)) {
+ return false;
+ }
+
+ try {
+ // Not own constructor property must be Object
+ if (obj.constructor
+ && !hasOwn.call(obj, "constructor")
+ && !hasOwn.call(obj.constructor.prototype,
+ "isPrototypeOf")) {
+ return false;
+ }
+ } catch (e) {
+ // IE8,9 Will throw exceptions on certain host
+ // objects #9897
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed
+ // up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for (key in obj) {
+ }
+
+ return key === undefined || hasOwn.call(obj, key);
+ },
+
+ isEmptyObject : function(obj) {
+ for ( var name in obj) {
+ return false;
+ }
+ return true;
+ },
+
+ error : function(msg) {
+ throw new Error(msg);
+ },
+
+ parseJSON : function(data) {
+ if (typeof data !== "string" || !data) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE
+ // can't handle it)
+ data = jQuery.trim(data);
+
+ // Attempt to parse using the native JSON parser first
+ if (window.JSON && window.JSON.parse) {
+ return window.JSON.parse(data);
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if (rvalidchars.test(data.replace(rvalidescape, "@")
+ .replace(rvalidtokens, "]").replace(
+ rvalidbraces, ""))) {
+
+ return (new Function("return " + data))();
+
+ }
+ jQuery.error("Invalid JSON: " + data);
+ },
+
+ // Cross-browser xml parsing
+ parseXML : function(data) {
+ var xml, tmp;
+ try {
+ if (window.DOMParser) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString(data, "text/xml");
+ } else { // IE
+ xml = new ActiveXObject("Microsoft.XMLDOM");
+ xml.async = "false";
+ xml.loadXML(data);
+ }
+ } catch (e) {
+ xml = undefined;
+ }
+ if (!xml
+ || !xml.documentElement
+ || xml.getElementsByTagName("parsererror").length) {
+ jQuery.error("Invalid XML: " + data);
+ }
+ return xml;
+ },
+
+ noop : function() {
+ },
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval : function(data) {
+ if (data && rnotwhite.test(data)) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is
+ // window
+ // rather than jQuery in Firefox
+ (window.execScript || function(data) {
+ window["eval"].call(window, data);
+ })(data);
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data
+ // modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase : function(string) {
+ return string.replace(rmsPrefix, "ms-").replace(
+ rdashAlpha, fcamelCase);
+ },
+
+ nodeName : function(elem, name) {
+ return elem.nodeName
+ && elem.nodeName.toUpperCase() === name
+ .toUpperCase();
+ },
+
+ // args is for internal usage only
+ each : function(object, callback, args) {
+ var name, i = 0, length = object.length, isObj = length === undefined
+ || jQuery.isFunction(object);
+
+ if (args) {
+ if (isObj) {
+ for (name in object) {
+ if (callback.apply(object[name], args) === false) {
+ break;
+ }
+ }
+ } else {
+ for (; i < length;) {
+ if (callback.apply(object[i++], args) === false) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of
+ // each
+ } else {
+ if (isObj) {
+ for (name in object) {
+ if (callback.call(object[name], name,
+ object[name]) === false) {
+ break;
+ }
+ }
+ } else {
+ for (; i < length;) {
+ if (callback
+ .call(object[i], i, object[i++]) === false) {
+ break;
+ }
+ }
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim : trim ? function(text) {
+ return text == null ? "" : trim.call(text);
+ } :
+
+ // Otherwise use our own trimming functionality
+ function(text) {
+ return text == null ? "" : text.toString().replace(
+ trimLeft, "").replace(trimRight, "");
+ },
+
+ // results is for internal usage only
+ makeArray : function(array, results) {
+ var ret = results || [];
+
+ if (array != null) {
+ // The window, strings (and functions) also have
+ // 'length'
+ // Tweaked logic slightly to handle Blackberry 4.7
+ // RegExp issues #6930
+ var type = jQuery.type(array);
+
+ if (array.length == null || type === "string"
+ || type === "function" || type === "regexp"
+ || jQuery.isWindow(array)) {
+ push.call(ret, array);
+ } else {
+ jQuery.merge(ret, array);
+ }
+ }
+
+ return ret;
+ },
+
+ inArray : function(elem, array, i) {
+ var len;
+
+ if (array) {
+ if (indexOf) {
+ return indexOf.call(array, elem, i);
+ }
+
+ len = array.length;
+ i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
+
+ for (; i < len; i++) {
+ // Skip accessing in sparse arrays
+ if (i in array && array[i] === elem) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+ },
+
+ merge : function(first, second) {
+ var i = first.length, j = 0;
+
+ if (typeof second.length === "number") {
+ for (var l = second.length; j < l; j++) {
+ first[i++] = second[j];
+ }
+
+ } else {
+ while (second[j] !== undefined) {
+ first[i++] = second[j++];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep : function(elems, callback, inv) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for (var i = 0, length = elems.length; i < length; i++) {
+ retVal = !!callback(elems[i], i);
+ if (inv !== retVal) {
+ ret.push(elems[i]);
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map : function(elems, callback, arg) {
+ var value, key, ret = [], i = 0, length = elems.length,
+ // jquery objects are treated as arrays
+ isArray = elems instanceof jQuery
+ || length !== undefined
+ && typeof length === "number"
+ && ((length > 0 && elems[0] && elems[length - 1])
+ || length === 0 || jQuery
+ .isArray(elems));
+
+ // Go through the array, translating each of the items
+ // to their
+ if (isArray) {
+ for (; i < length; i++) {
+ value = callback(elems[i], i, arg);
+
+ if (value != null) {
+ ret[ret.length] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for (key in elems) {
+ value = callback(elems[key], key, arg);
+
+ if (value != null) {
+ ret[ret.length] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return ret.concat.apply([], ret);
+ },
+
+ // A global GUID counter for objects
+ guid : 1,
+
+ // Bind a function to a context, optionally partially
+ // applying any
+ // arguments.
+ proxy : function(fn, context) {
+ if (typeof context === "string") {
+ var tmp = fn[context];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in
+ // the spec
+ // this throws a TypeError, but we will just return
+ // undefined.
+ if (!jQuery.isFunction(fn)) {
+ return undefined;
+ }
+
+ // Simulated bind
+ var args = slice.call(arguments, 2), proxy = function() {
+ return fn.apply(context, args.concat(slice
+ .call(arguments)));
+ };
+
+ // Set the guid of unique handler to the same of
+ // original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid
+ || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a
+ // collection
+ // The value/s can optionally be executed if it's a function
+ access : function(elems, key, value, exec, fn, pass) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if (typeof key === "object") {
+ for ( var k in key) {
+ jQuery
+ .access(elems, k, key[k], exec, fn,
+ value);
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if (value !== undefined) {
+ // Optionally, function values get executed if exec
+ // is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for (var i = 0; i < length; i++) {
+ fn(elems[i], key, exec ? value.call(elems[i],
+ i, fn(elems[i], key)) : value, pass);
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn(elems[0], key) : undefined;
+ },
+
+ now : function() {
+ return (new Date()).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details:
+ // http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch : function(ua) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec(ua) || ropera.exec(ua)
+ || rmsie.exec(ua)
+ || ua.indexOf("compatible") < 0
+ && rmozilla.exec(ua) || [];
+
+ return {
+ browser : match[1] || "",
+ version : match[2] || "0"
+ };
+ },
+
+ sub : function() {
+ function jQuerySub(selector, context) {
+ return new jQuerySub.fn.init(selector, context);
+ }
+ jQuery.extend(true, jQuerySub, this);
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init(selector, context) {
+ if (context && context instanceof jQuery
+ && !(context instanceof jQuerySub)) {
+ context = jQuerySub(context);
+ }
+
+ return jQuery.fn.init.call(this, selector, context,
+ rootjQuerySub);
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ },
+
+ browser : {}
+ });
+
+ // Populate the class2type map
+ jQuery.each("Boolean Number String Function Array Date RegExp Object"
+ .split(" "), function(i, name) {
+ class2type["[object " + name + "]"] = name.toLowerCase();
+ });
+
+ browserMatch = jQuery.uaMatch(userAgent);
+ if (browserMatch.browser) {
+ jQuery.browser[browserMatch.browser] = true;
+ jQuery.browser.version = browserMatch.version;
+ }
+
+ // Deprecated, use jQuery.browser.webkit instead
+ if (jQuery.browser.webkit) {
+ jQuery.browser.safari = true;
+ }
+
+ // IE doesn't match non-breaking spaces with \s
+ if (rnotwhite.test("\xA0")) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+ }
+
+ // All jQuery objects should point back to these
+ rootjQuery = jQuery(document);
+
+ // Cleanup functions for the document ready method
+ if (document.addEventListener) {
+ DOMContentLoaded = function() {
+ document.removeEventListener("DOMContentLoaded",
+ DOMContentLoaded, false);
+ jQuery.ready();
+ };
+
+ } else if (document.attachEvent) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little
+ // overzealous (ticket #5443).
+ if (document.readyState === "complete") {
+ document
+ .detachEvent("onreadystatechange", DOMContentLoaded);
+ jQuery.ready();
+ }
+ };
+ }
+
+ // The DOM ready check for Internet Explorer
+ function doScrollCheck() {
+ if (jQuery.isReady) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch (e) {
+ setTimeout(doScrollCheck, 1);
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+
+ return jQuery;
+
+ })();
+
+ // String to Object flags format cache
+ var flagsCache = {};
+
+ // Convert String-formatted flags into Object-formatted ones and store in
+ // cache
+ function createFlags(flags) {
+ var object = flagsCache[flags] = {}, i, length;
+ flags = flags.split(/\s+/);
+ for (i = 0, length = flags.length; i < length; i++) {
+ object[flags[i]] = true;
+ }
+ return object;
+ }
+
+ /*
+ * Create a callback list using the following parameters:
+ *
+ * flags: an optional list of space-separated flags that will change how the
+ * callback list behaves
+ *
+ * By default a callback list will act like an event callback list and can
+ * be "fired" multiple times.
+ *
+ * Possible flags:
+ *
+ * once: will ensure the callback list can only be fired once (like a
+ * Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback
+ * added after the list has been fired right away with the latest
+ * "memorized" values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in
+ * the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+ jQuery.Callbacks = function(flags) {
+
+ // Convert flags from String-formatted to Object-formatted
+ // (we check in cache first)
+ flags = flags ? (flagsCache[flags] || createFlags(flags)) : {};
+
+ var // Actual callback list
+ list = [],
+ // Stack of fire calls for repeatable lists
+ stack = [],
+ // Last fire value (for non-forgettable lists)
+ memory,
+ // Flag to know if list is currently firing
+ firing,
+ // First callback to fire (used internally by add and fireWith)
+ firingStart,
+ // End of the loop when firing
+ firingLength,
+ // Index of currently firing callback (modified by remove if needed)
+ firingIndex,
+ // Add one or several callbacks to the list
+ add = function(args) {
+ var i, length, elem, type, actual;
+ for (i = 0, length = args.length; i < length; i++) {
+ elem = args[i];
+ type = jQuery.type(elem);
+ if (type === "array") {
+ // Inspect recursively
+ add(elem);
+ } else if (type === "function") {
+ // Add if not in unique mode and callback is not in
+ if (!flags.unique || !self.has(elem)) {
+ list.push(elem);
+ }
+ }
+ }
+ },
+ // Fire callbacks
+ fire = function(context, args) {
+ args = args || [];
+ memory = !flags.memory || [ context, args ];
+ firing = true;
+ firingIndex = firingStart || 0;
+ firingStart = 0;
+ firingLength = list.length;
+ for (; list && firingIndex < firingLength; firingIndex++) {
+ if (list[firingIndex].apply(context, args) === false
+ && flags.stopOnFalse) {
+ memory = true; // Mark as halted
+ break;
+ }
+ }
+ firing = false;
+ if (list) {
+ if (!flags.once) {
+ if (stack && stack.length) {
+ memory = stack.shift();
+ self.fireWith(memory[0], memory[1]);
+ }
+ } else if (memory === true) {
+ self.disable();
+ } else {
+ list = [];
+ }
+ }
+ },
+ // Actual Callbacks object
+ self = {
+ // Add a callback or a collection of callbacks to the list
+ add : function() {
+ if (list) {
+ var length = list.length;
+ add(arguments);
+ // Do we need to add the callbacks to the
+ // current firing batch?
+ if (firing) {
+ firingLength = list.length;
+ // With memory, if we're not firing then
+ // we should call right away, unless previous
+ // firing was halted (stopOnFalse)
+ } else if (memory && memory !== true) {
+ firingStart = length;
+ fire(memory[0], memory[1]);
+ }
+ }
+ return this;
+ },
+ // Remove a callback from the list
+ remove : function() {
+ if (list) {
+ var args = arguments, argIndex = 0, argLength = args.length;
+ for (; argIndex < argLength; argIndex++) {
+ for (var i = 0; i < list.length; i++) {
+ if (args[argIndex] === list[i]) {
+ // Handle firingIndex and firingLength
+ if (firing) {
+ if (i <= firingLength) {
+ firingLength--;
+ if (i <= firingIndex) {
+ firingIndex--;
+ }
+ }
+ }
+ // Remove the element
+ list.splice(i--, 1);
+ // If we have some unicity property then
+ // we only need to do this once
+ if (flags.unique) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return this;
+ },
+ // Control if a given callback is in the list
+ has : function(fn) {
+ if (list) {
+ var i = 0, length = list.length;
+ for (; i < length; i++) {
+ if (fn === list[i]) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ // Remove all callbacks from the list
+ empty : function() {
+ list = [];
+ return this;
+ },
+ // Have the list do nothing anymore
+ disable : function() {
+ list = stack = memory = undefined;
+ return this;
+ },
+ // Is it disabled?
+ disabled : function() {
+ return !list;
+ },
+ // Lock the list in its current state
+ lock : function() {
+ stack = undefined;
+ if (!memory || memory === true) {
+ self.disable();
+ }
+ return this;
+ },
+ // Is it locked?
+ locked : function() {
+ return !stack;
+ },
+ // Call all callbacks with the given context and arguments
+ fireWith : function(context, args) {
+ if (stack) {
+ if (firing) {
+ if (!flags.once) {
+ stack.push([ context, args ]);
+ }
+ } else if (!(flags.once && memory)) {
+ fire(context, args);
+ }
+ }
+ return this;
+ },
+ // Call all the callbacks with the given arguments
+ fire : function() {
+ self.fireWith(this, arguments);
+ return this;
+ },
+ // To know if the callbacks have already been called at least once
+ fired : function() {
+ return !!memory;
+ }
+ };
+
+ return self;
+ };
+
+ var // Static reference to slice
+ sliceDeferred = [].slice;
+
+ jQuery
+ .extend({
+
+ Deferred : function(func) {
+ var doneList = jQuery.Callbacks("once memory"), failList = jQuery
+ .Callbacks("once memory"), progressList = jQuery
+ .Callbacks("memory"), state = "pending", lists = {
+ resolve : doneList,
+ reject : failList,
+ notify : progressList
+ }, promise = {
+ done : doneList.add,
+ fail : failList.add,
+ progress : progressList.add,
+
+ state : function() {
+ return state;
+ },
+
+ // Deprecated
+ isResolved : doneList.fired,
+ isRejected : failList.fired,
+
+ then : function(doneCallbacks, failCallbacks,
+ progressCallbacks) {
+ deferred.done(doneCallbacks).fail(failCallbacks)
+ .progress(progressCallbacks);
+ return this;
+ },
+ always : function() {
+ deferred.done.apply(deferred, arguments).fail
+ .apply(deferred, arguments);
+ return this;
+ },
+ pipe : function(fnDone, fnFail, fnProgress) {
+ return jQuery
+ .Deferred(
+ function(newDefer) {
+ jQuery
+ .each(
+ {
+ done : [
+ fnDone,
+ "resolve" ],
+ fail : [
+ fnFail,
+ "reject" ],
+ progress : [
+ fnProgress,
+ "notify" ]
+ },
+ function(
+ handler,
+ data) {
+ var fn = data[0], action = data[1], returned;
+ if (jQuery
+ .isFunction(fn)) {
+ deferred[handler]
+ (function() {
+ returned = fn
+ .apply(
+ this,
+ arguments);
+ if (returned
+ && jQuery
+ .isFunction(returned.promise)) {
+ returned
+ .promise()
+ .then(
+ newDefer.resolve,
+ newDefer.reject,
+ newDefer.notify);
+ } else {
+ newDefer[action
+ + "With"]
+ (
+ this === deferred ? newDefer
+ : this,
+ [ returned ]);
+ }
+ });
+ } else {
+ deferred[handler]
+ (newDefer[action]);
+ }
+ });
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to
+ // the object
+ promise : function(obj) {
+ if (obj == null) {
+ obj = promise;
+ } else {
+ for ( var key in promise) {
+ obj[key] = promise[key];
+ }
+ }
+ return obj;
+ }
+ }, deferred = promise.promise({}), key;
+
+ for (key in lists) {
+ deferred[key] = lists[key].fire;
+ deferred[key + "With"] = lists[key].fireWith;
+ }
+
+ // Handle state
+ deferred.done(function() {
+ state = "resolved";
+ }, failList.disable, progressList.lock).fail(function() {
+ state = "rejected";
+ }, doneList.disable, progressList.lock);
+
+ // Call given func if any
+ if (func) {
+ func.call(deferred, deferred);
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when : function(firstParam) {
+ var args = sliceDeferred.call(arguments, 0), i = 0, length = args.length, pValues = new Array(
+ length), count = length, pCount = length, deferred = length <= 1
+ && firstParam
+ && jQuery.isFunction(firstParam.promise) ? firstParam
+ : jQuery.Deferred(), promise = deferred.promise();
+ function resolveFunc(i) {
+ return function(value) {
+ args[i] = arguments.length > 1 ? sliceDeferred
+ .call(arguments, 0) : value;
+ if (!(--count)) {
+ deferred.resolveWith(deferred, args);
+ }
+ };
+ }
+ function progressFunc(i) {
+ return function(value) {
+ pValues[i] = arguments.length > 1 ? sliceDeferred
+ .call(arguments, 0) : value;
+ deferred.notifyWith(promise, pValues);
+ };
+ }
+ if (length > 1) {
+ for (; i < length; i++) {
+ if (args[i] && args[i].promise
+ && jQuery.isFunction(args[i].promise)) {
+ args[i].promise().then(resolveFunc(i),
+ deferred.reject, progressFunc(i));
+ } else {
+ --count;
+ }
+ }
+ if (!count) {
+ deferred.resolveWith(deferred, args);
+ }
+ } else if (deferred !== firstParam) {
+ deferred.resolveWith(deferred, length ? [ firstParam ]
+ : []);
+ }
+ return promise;
+ }
+ });
+
+ jQuery.support = (function() {
+
+ var support, all, a, select, opt, input, marginDiv, fragment, tds, events, eventName, i, isSupported, div = document
+ .createElement("div"), documentElement = document.documentElement;
+
+ // Preliminary tests
+ div.setAttribute("className", "t");
+ div.innerHTML = "
a";
+
+ all = div.getElementsByTagName("*");
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if (!all || !all.length || !a) {
+ return {};
+ }
+
+ // First batch of supports tests
+ select = document.createElement("select");
+ opt = select.appendChild(document.createElement("option"));
+ input = div.getElementsByTagName("input")[0];
+
+ support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace : (div.firstChild.nodeType === 3),
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody : !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by
+ // innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize : !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style : /top/.test(a.getAttribute("style")),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized : (a.getAttribute("href") === "/a"),
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity : /^0.55/.test(a.style.opacity),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat : !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn : (input.value === "on"),
+
+ // Make sure that a selected-by-default option has a working
+ // selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an
+ // optgroup)
+ optSelected : opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need
+ // attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute : div.className !== "t",
+
+ // Tests for enctype support on a form(#6743)
+ enctype : !!document.createElement("form").enctype,
+
+ // Makes sure cloning an html5 element does not cause problems
+ // Where outerHTML is undefined, this still works
+ html5Clone : document.createElement("nav").cloneNode(true).outerHTML !== "<:nav>",
+
+ // Will be defined later
+ submitBubbles : true,
+ changeBubbles : true,
+ focusinBubbles : false,
+ deleteExpando : true,
+ noCloneEvent : true,
+ inlineBlockNeedsLayout : false,
+ shrinkWrapBlocks : false,
+ reliableMarginRight : true
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode(true).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as
+ // disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete div.test;
+ } catch (e) {
+ support.deleteExpando = false;
+ }
+
+ if (!div.addEventListener && div.attachEvent && div.fireEvent) {
+ div.attachEvent("onclick", function() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ support.noCloneEvent = false;
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ // Check if a radio maintains its value
+ // after being appended to the DOM
+ input = document.createElement("input");
+ input.value = "t";
+ input.setAttribute("type", "radio");
+ support.radioValue = input.value === "t";
+
+ input.setAttribute("checked", "checked");
+ div.appendChild(input);
+ fragment = document.createDocumentFragment();
+ fragment.appendChild(div.lastChild);
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ fragment.removeChild(input);
+ fragment.appendChild(div);
+
+ div.innerHTML = "";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for
+ // margin-right
+ if (window.getComputedStyle) {
+ marginDiv = document.createElement("div");
+ marginDiv.style.width = "0";
+ marginDiv.style.marginRight = "0";
+ div.style.width = "2px";
+ div.appendChild(marginDiv);
+ support.reliableMarginRight = (parseInt((window.getComputedStyle(
+ marginDiv, null) || {
+ marginRight : 0
+ }).marginRight, 10) || 0) === 0;
+ }
+
+ // Technique from Juriy Zaytsev
+ // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
+ // We only care about the case where non-standard event systems
+ // are used, namely in IE. Short-circuiting here helps us to
+ // avoid an eval call (in setAttribute) which can cause CSP
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ if (div.attachEvent) {
+ for (i in {
+ submit : 1,
+ change : 1,
+ focusin : 1
+ }) {
+ eventName = "on" + i;
+ isSupported = (eventName in div);
+ if (!isSupported) {
+ div.setAttribute(eventName, "return;");
+ isSupported = (typeof div[eventName] === "function");
+ }
+ support[i + "Bubbles"] = isSupported;
+ }
+ }
+
+ fragment.removeChild(div);
+
+ // Null elements to avoid leaks in IE
+ fragment = select = opt = marginDiv = div = input = null;
+
+ // Run tests that need a body at doc ready
+ jQuery(function() {
+ var container, outer, inner, table, td, offsetSupport, conMarginTop, ptlm, vb, style, html, body = document
+ .getElementsByTagName("body")[0];
+
+ if (!body) {
+ // Return for frameset docs that don't have a body
+ return;
+ }
+
+ conMarginTop = 1;
+ ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";
+ vb = "visibility:hidden;border:0;";
+ style = "style='" + ptlm + "border:5px solid #000;padding:0;'";
+ html = "
" + "
"
+ + "
";
+
+ container = document.createElement("div");
+ container.style.cssText = vb
+ + "width:0;height:0;position:static;top:0;margin-top:"
+ + conMarginTop + "px";
+ body.insertBefore(container, body.firstChild);
+
+ // Construct the test element
+ div = document.createElement("div");
+ container.appendChild(div);
+
+ // Check if table cells still have offsetWidth/Height when they are
+ // set
+ // to display:none and there are still other visible table cells in
+ // a
+ // table row; if so, offsetWidth/Height are not reliable for use
+ // when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element
+ // is
+ // hidden; don safety goggles and see bug #4512 for more
+ // information).
+ // (only IE 8 fails this test)
+ div.innerHTML = "
t
";
+ tds = div.getElementsByTagName("td");
+ isSupported = (tds[0].offsetHeight === 0);
+
+ tds[0].style.display = "";
+ tds[1].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE <= 8 fail this test)
+ support.reliableHiddenOffsets = isSupported
+ && (tds[0].offsetHeight === 0);
+
+ // Figure out if the W3C box model works as expected
+ div.innerHTML = "";
+ div.style.width = div.style.paddingLeft = "1px";
+ jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
+
+ if (typeof div.style.zoom !== "undefined") {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = (div.offsetWidth === 2);
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "";
+ support.shrinkWrapBlocks = (div.offsetWidth !== 2);
+ }
+
+ div.style.cssText = ptlm + vb;
+ div.innerHTML = html;
+
+ outer = div.firstChild;
+ inner = outer.firstChild;
+ td = outer.nextSibling.firstChild.firstChild;
+
+ offsetSupport = {
+ doesNotAddBorder : (inner.offsetTop !== 5),
+ doesAddBorderForTableAndCells : (td.offsetTop === 5)
+ };
+
+ inner.style.position = "fixed";
+ inner.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ offsetSupport.fixedPosition = (inner.offsetTop === 20 || inner.offsetTop === 15);
+ inner.style.position = inner.style.top = "";
+
+ outer.style.overflow = "hidden";
+ outer.style.position = "relative";
+
+ offsetSupport.subtractsBorderForOverflowNotVisible = (inner.offsetTop === -5);
+ offsetSupport.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== conMarginTop);
+
+ body.removeChild(container);
+ div = container = null;
+
+ jQuery.extend(support, offsetSupport);
+ });
+
+ return support;
+ })();
+
+ var rbrace = /^(?:\{.*\}|\[.*\])$/, rmultiDash = /([A-Z])/g;
+
+ jQuery
+ .extend({
+ cache : {},
+
+ // Please use with caution
+ uuid : 0,
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando : "jQuery"
+ + (jQuery.fn.jquery + Math.random()).replace(/\D/g, ""),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData : {
+ "embed" : true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object" : "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet" : true
+ },
+
+ hasData : function(elem) {
+ elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]]
+ : elem[jQuery.expando];
+ return !!elem && !isEmptyDataObject(elem);
+ },
+
+ data : function(elem, name, data, pvt /* Internal Use Only */) {
+ if (!jQuery.acceptData(elem)) {
+ return;
+ }
+
+ var privateCache, thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string",
+
+ // We have to handle DOM nodes and JS objects differently
+ // because IE6-7
+ // can't GC object references properly across the DOM-JS
+ // boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object
+ // data is
+ // attached directly to the object so GC can occur
+ // automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already
+ // exists allows
+ // the code to shortcut on the same path as a DOM node with
+ // no cache
+ id = isNode ? elem[internalKey] : elem[internalKey]
+ && internalKey, isEvents = name === "events";
+
+ // Avoid doing any more work than we need to when trying to
+ // get data on an
+ // object that has no data at all
+ if ((!id || !cache[id] || (!isEvents && !pvt && !cache[id].data))
+ && getByName && data === undefined) {
+ return;
+ }
+
+ if (!id) {
+ // Only DOM nodes need a new unique ID for each element
+ // since their data
+ // ends up in the global cache
+ if (isNode) {
+ elem[internalKey] = id = ++jQuery.uuid;
+ } else {
+ id = internalKey;
+ }
+ }
+
+ if (!cache[id]) {
+ cache[id] = {};
+
+ // Avoids exposing jQuery metadata on plain JS objects
+ // when the object
+ // is serialized using JSON.stringify
+ if (!isNode) {
+ cache[id].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a
+ // key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if (typeof name === "object" || typeof name === "function") {
+ if (pvt) {
+ cache[id] = jQuery.extend(cache[id], name);
+ } else {
+ cache[id].data = jQuery
+ .extend(cache[id].data, name);
+ }
+ }
+
+ privateCache = thisCache = cache[id];
+
+ // jQuery data() is stored in a separate object inside the
+ // object's internal data
+ // cache in order to avoid key collisions between internal
+ // data and user-defined
+ // data.
+ if (!pvt) {
+ if (!thisCache.data) {
+ thisCache.data = {};
+ }
+
+ thisCache = thisCache.data;
+ }
+
+ if (data !== undefined) {
+ thisCache[jQuery.camelCase(name)] = data;
+ }
+
+ // Users should not attempt to inspect the internal events
+ // object using jQuery.data,
+ // it is undocumented and subject to change. But does anyone
+ // listen? No.
+ if (isEvents && !thisCache[name]) {
+ return privateCache.events;
+ }
+
+ // Check for both converted-to-camel and non-converted data
+ // property names
+ // If a data property was specified
+ if (getByName) {
+
+ // First Try to find as-is property data
+ ret = thisCache[name];
+
+ // Test for null|undefined property data
+ if (ret == null) {
+
+ // Try to find the camelCased property
+ ret = thisCache[jQuery.camelCase(name)];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+ },
+
+ removeData : function(elem, name, pvt /* Internal Use Only */) {
+ if (!jQuery.acceptData(elem)) {
+ return;
+ }
+
+ var thisCache, i, l,
+
+ // Reference to internal data cache key
+ internalKey = jQuery.expando,
+
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+
+ // See jQuery.data for more information
+ id = isNode ? elem[internalKey] : internalKey;
+
+ // If there is already no cache entry for this object, there
+ // is no
+ // purpose in continuing
+ if (!cache[id]) {
+ return;
+ }
+
+ if (name) {
+
+ thisCache = pvt ? cache[id] : cache[id].data;
+
+ if (thisCache) {
+
+ // Support array or space separated string names for
+ // data keys
+ if (!jQuery.isArray(name)) {
+
+ // try the string as a key before any
+ // manipulation
+ if (name in thisCache) {
+ name = [ name ];
+ } else {
+
+ // split the camel cased version by spaces
+ // unless a key with the spaces exists
+ name = jQuery.camelCase(name);
+ if (name in thisCache) {
+ name = [ name ];
+ } else {
+ name = name.split(" ");
+ }
+ }
+ }
+
+ for (i = 0, l = name.length; i < l; i++) {
+ delete thisCache[name[i]];
+ }
+
+ // If there is no data left in the cache, we want to
+ // continue
+ // and let the cache object itself get destroyed
+ if (!(pvt ? isEmptyDataObject
+ : jQuery.isEmptyObject)(thisCache)) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if (!pvt) {
+ delete cache[id].data;
+
+ // Don't destroy the parent cache unless the internal
+ // data object
+ // had been the only thing left in it
+ if (!isEmptyDataObject(cache[id])) {
+ return;
+ }
+ }
+
+ // Browsers that fail expando deletion also refuse to delete
+ // expandos on
+ // the window, but it will allow it on all other JS objects;
+ // other browsers
+ // don't care
+ // Ensure that `cache` is not a window object #10080
+ if (jQuery.support.deleteExpando || !cache.setInterval) {
+ delete cache[id];
+ } else {
+ cache[id] = null;
+ }
+
+ // We destroyed the cache and need to eliminate the expando
+ // on the node to avoid
+ // false lookups in the cache for entries that no longer
+ // exist
+ if (isNode) {
+ // IE does not allow us to delete expando properties
+ // from nodes,
+ // nor does it have a removeAttribute function on
+ // Document nodes;
+ // we must handle all of these cases
+ if (jQuery.support.deleteExpando) {
+ delete elem[internalKey];
+ } else if (elem.removeAttribute) {
+ elem.removeAttribute(internalKey);
+ } else {
+ elem[internalKey] = null;
+ }
+ }
+ },
+
+ // For internal use only.
+ _data : function(elem, name, data) {
+ return jQuery.data(elem, name, data, true);
+ },
+
+ // A method for determining if a DOM node can handle the data
+ // expando
+ acceptData : function(elem) {
+ if (elem.nodeName) {
+ var match = jQuery.noData[elem.nodeName.toLowerCase()];
+
+ if (match) {
+ return !(match === true || elem
+ .getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+ });
+
+ jQuery.fn.extend({
+ data : function(key, value) {
+ var parts, attr, name, data = null;
+
+ if (typeof key === "undefined") {
+ if (this.length) {
+ data = jQuery.data(this[0]);
+
+ if (this[0].nodeType === 1
+ && !jQuery._data(this[0], "parsedAttrs")) {
+ attr = this[0].attributes;
+ for (var i = 0, l = attr.length; i < l; i++) {
+ name = attr[i].name;
+
+ if (name.indexOf("data-") === 0) {
+ name = jQuery.camelCase(name.substring(5));
+
+ dataAttr(this[0], name, data[name]);
+ }
+ }
+ jQuery._data(this[0], "parsedAttrs", true);
+ }
+ }
+
+ return data;
+
+ } else if (typeof key === "object") {
+ return this.each(function() {
+ jQuery.data(this, key);
+ });
+ }
+
+ parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if (value === undefined) {
+ data = this.triggerHandler("getData" + parts[1] + "!",
+ [ parts[0] ]);
+
+ // Try to fetch any internally stored data first
+ if (data === undefined && this.length) {
+ data = jQuery.data(this[0], key);
+ data = dataAttr(this[0], key, data);
+ }
+
+ return data === undefined && parts[1] ? this.data(parts[0])
+ : data;
+
+ } else {
+ return this.each(function() {
+ var self = jQuery(this), args = [ parts[0], value ];
+
+ self.triggerHandler("setData" + parts[1] + "!", args);
+ jQuery.data(this, key, value);
+ self.triggerHandler("changeData" + parts[1] + "!", args);
+ });
+ }
+ },
+
+ removeData : function(key) {
+ return this.each(function() {
+ jQuery.removeData(this, key);
+ });
+ }
+ });
+
+ function dataAttr(elem, key, data) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if (data === undefined && elem.nodeType === 1) {
+
+ var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
+
+ data = elem.getAttribute(name);
+
+ if (typeof data === "string") {
+ try {
+ data = data === "true" ? true : data === "false" ? false
+ : data === "null" ? null
+ : jQuery.isNumeric(data) ? parseFloat(data)
+ : rbrace.test(data) ? jQuery
+ .parseJSON(data) : data;
+ } catch (e) {
+ }
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data(elem, key, data);
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+ }
+
+ // checks a cache object for emptiness
+ function isEmptyDataObject(obj) {
+ for ( var name in obj) {
+
+ // if the public data object is empty, the private is still empty
+ if (name === "data" && jQuery.isEmptyObject(obj[name])) {
+ continue;
+ }
+ if (name !== "toJSON") {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ function handleQueueMarkDefer(elem, type, src) {
+ var deferDataKey = type + "defer", queueDataKey = type + "queue", markDataKey = type
+ + "mark", defer = jQuery._data(elem, deferDataKey);
+ if (defer && (src === "queue" || !jQuery._data(elem, queueDataKey))
+ && (src === "mark" || !jQuery._data(elem, markDataKey))) {
+ // Give room for hard-coded callbacks to fire first
+ // and eventually mark/queue something else on the element
+ setTimeout(function() {
+ if (!jQuery._data(elem, queueDataKey)
+ && !jQuery._data(elem, markDataKey)) {
+ jQuery.removeData(elem, deferDataKey, true);
+ defer.fire();
+ }
+ }, 0);
+ }
+ }
+
+ jQuery
+ .extend({
+
+ _mark : function(elem, type) {
+ if (elem) {
+ type = (type || "fx") + "mark";
+ jQuery._data(elem, type,
+ (jQuery._data(elem, type) || 0) + 1);
+ }
+ },
+
+ _unmark : function(force, elem, type) {
+ if (force !== true) {
+ type = elem;
+ elem = force;
+ force = false;
+ }
+ if (elem) {
+ type = type || "fx";
+ var key = type + "mark", count = force ? 0 : ((jQuery
+ ._data(elem, key) || 1) - 1);
+ if (count) {
+ jQuery._data(elem, key, count);
+ } else {
+ jQuery.removeData(elem, key, true);
+ handleQueueMarkDefer(elem, type, "mark");
+ }
+ }
+ },
+
+ queue : function(elem, type, data) {
+ var q;
+ if (elem) {
+ type = (type || "fx") + "queue";
+ q = jQuery._data(elem, type);
+
+ // Speed up dequeue by getting out quickly if this is
+ // just a lookup
+ if (data) {
+ if (!q || jQuery.isArray(data)) {
+ q = jQuery._data(elem, type, jQuery
+ .makeArray(data));
+ } else {
+ q.push(data);
+ }
+ }
+ return q || [];
+ }
+ },
+
+ dequeue : function(elem, type) {
+ type = type || "fx";
+
+ var queue = jQuery.queue(elem, type), fn = queue.shift(), hooks = {};
+
+ // If the fx queue is dequeued, always remove the progress
+ // sentinel
+ if (fn === "inprogress") {
+ fn = queue.shift();
+ }
+
+ if (fn) {
+ // Add a progress sentinel to prevent the fx queue from
+ // being
+ // automatically dequeued
+ if (type === "fx") {
+ queue.unshift("inprogress");
+ }
+
+ jQuery._data(elem, type + ".run", hooks);
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ }, hooks);
+ }
+
+ if (!queue.length) {
+ jQuery.removeData(elem,
+ type + "queue " + type + ".run", true);
+ handleQueueMarkDefer(elem, type, "queue");
+ }
+ }
+ });
+
+ jQuery.fn
+ .extend({
+ queue : function(type, data) {
+ if (typeof type !== "string") {
+ data = type;
+ type = "fx";
+ }
+
+ if (data === undefined) {
+ return jQuery.queue(this[0], type);
+ }
+ return this.each(function() {
+ var queue = jQuery.queue(this, type, data);
+
+ if (type === "fx" && queue[0] !== "inprogress") {
+ jQuery.dequeue(this, type);
+ }
+ });
+ },
+ dequeue : function(type) {
+ return this.each(function() {
+ jQuery.dequeue(this, type);
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay : function(time, type) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue(type, function(next, hooks) {
+ var timeout = setTimeout(next, time);
+ hooks.stop = function() {
+ clearTimeout(timeout);
+ };
+ });
+ },
+ clearQueue : function(type) {
+ return this.queue(type || "fx", []);
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise : function(type, object) {
+ if (typeof type !== "string") {
+ object = type;
+ type = undefined;
+ }
+ type = type || "fx";
+ var defer = jQuery.Deferred(), elements = this, i = elements.length, count = 1, deferDataKey = type
+ + "defer", queueDataKey = type + "queue", markDataKey = type
+ + "mark", tmp;
+ function resolve() {
+ if (!(--count)) {
+ defer.resolveWith(elements, [ elements ]);
+ }
+ }
+ while (i--) {
+ if ((tmp = jQuery.data(elements[i], deferDataKey,
+ undefined, true)
+ || (jQuery.data(elements[i], queueDataKey,
+ undefined, true) || jQuery.data(
+ elements[i], markDataKey, undefined,
+ true))
+ && jQuery.data(elements[i], deferDataKey,
+ jQuery.Callbacks("once memory"), true))) {
+ count++;
+ tmp.add(resolve);
+ }
+ }
+ resolve();
+ return defer.promise();
+ }
+ });
+
+ var rclass = /[\n\t\r]/g, rspace = /\s+/, rreturn = /\r/g, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, nodeHook, boolHook, fixSpecified;
+
+ jQuery.fn
+ .extend({
+ attr : function(name, value) {
+ return jQuery.access(this, name, value, true, jQuery.attr);
+ },
+
+ removeAttr : function(name) {
+ return this.each(function() {
+ jQuery.removeAttr(this, name);
+ });
+ },
+
+ prop : function(name, value) {
+ return jQuery.access(this, name, value, true, jQuery.prop);
+ },
+
+ removeProp : function(name) {
+ name = jQuery.propFix[name] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as
+ // removing a property on window)
+ try {
+ this[name] = undefined;
+ delete this[name];
+ } catch (e) {
+ }
+ });
+ },
+
+ addClass : function(value) {
+ var classNames, i, l, elem, setClass, c, cl;
+
+ if (jQuery.isFunction(value)) {
+ return this.each(function(j) {
+ jQuery(this).addClass(
+ value.call(this, j, this.className));
+ });
+ }
+
+ if (value && typeof value === "string") {
+ classNames = value.split(rspace);
+
+ for (i = 0, l = this.length; i < l; i++) {
+ elem = this[i];
+
+ if (elem.nodeType === 1) {
+ if (!elem.className && classNames.length === 1) {
+ elem.className = value;
+
+ } else {
+ setClass = " " + elem.className + " ";
+
+ for (c = 0, cl = classNames.length; c < cl; c++) {
+ if (!~setClass.indexOf(" "
+ + classNames[c] + " ")) {
+ setClass += classNames[c] + " ";
+ }
+ }
+ elem.className = jQuery.trim(setClass);
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass : function(value) {
+ var classNames, i, l, elem, className, c, cl;
+
+ if (jQuery.isFunction(value)) {
+ return this.each(function(j) {
+ jQuery(this).removeClass(
+ value.call(this, j, this.className));
+ });
+ }
+
+ if ((value && typeof value === "string")
+ || value === undefined) {
+ classNames = (value || "").split(rspace);
+
+ for (i = 0, l = this.length; i < l; i++) {
+ elem = this[i];
+
+ if (elem.nodeType === 1 && elem.className) {
+ if (value) {
+ className = (" " + elem.className + " ")
+ .replace(rclass, " ");
+ for (c = 0, cl = classNames.length; c < cl; c++) {
+ className = className.replace(" "
+ + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim(className);
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass : function(value, stateVal) {
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if (jQuery.isFunction(value)) {
+ return this.each(function(i) {
+ jQuery(this).toggleClass(
+ value.call(this, i, this.className,
+ stateVal), stateVal);
+ });
+ }
+
+ return this
+ .each(function() {
+ if (type === "string") {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this), state = stateVal, classNames = value
+ .split(rspace);
+
+ while ((className = classNames[i++])) {
+ // check each className given, space
+ // seperated list
+ state = isBool ? state : !self
+ .hasClass(className);
+ self[state ? "addClass" : "removeClass"]
+ (className);
+ }
+
+ } else if (type === "undefined"
+ || type === "boolean") {
+ if (this.className) {
+ // store className if set
+ jQuery._data(this, "__className__",
+ this.className);
+ }
+
+ // toggle whole className
+ this.className = this.className
+ || value === false ? "" : jQuery
+ ._data(this, "__className__")
+ || "";
+ }
+ });
+ },
+
+ hasClass : function(selector) {
+ var className = " " + selector + " ", i = 0, l = this.length;
+ for (; i < l; i++) {
+ if (this[i].nodeType === 1
+ && (" " + this[i].className + " ").replace(
+ rclass, " ").indexOf(className) > -1) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val : function(value) {
+ var hooks, ret, isFunction, elem = this[0];
+
+ if (!arguments.length) {
+ if (elem) {
+ hooks = jQuery.valHooks[elem.nodeName.toLowerCase()]
+ || jQuery.valHooks[elem.type];
+
+ if (hooks
+ && "get" in hooks
+ && (ret = hooks.get(elem, "value")) !== undefined) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ return typeof ret === "string" ?
+ // handle most common string cases
+ ret.replace(rreturn, "") :
+ // handle cases where value is null/undef or number
+ ret == null ? "" : ret;
+ }
+
+ return;
+ }
+
+ isFunction = jQuery.isFunction(value);
+
+ return this
+ .each(function(i) {
+ var self = jQuery(this), val;
+
+ if (this.nodeType !== 1) {
+ return;
+ }
+
+ if (isFunction) {
+ val = value.call(this, i, self.val());
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers
+ // to string
+ if (val == null) {
+ val = "";
+ } else if (typeof val === "number") {
+ val += "";
+ } else if (jQuery.isArray(val)) {
+ val = jQuery.map(val, function(value) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[this.nodeName
+ .toLowerCase()]
+ || jQuery.valHooks[this.type];
+
+ // If set returns undefined, fall back to normal
+ // setting
+ if (!hooks
+ || !("set" in hooks)
+ || hooks.set(this, val, "value") === undefined) {
+ this.value = val;
+ }
+ });
+ }
+ });
+
+ jQuery
+ .extend({
+ valHooks : {
+ option : {
+ get : function(elem) {
+ // attributes.value is undefined in Blackberry 4.7
+ // but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value
+ : elem.text;
+ }
+ },
+ select : {
+ get : function(elem) {
+ var value, i, max, option, index = elem.selectedIndex, values = [], options = elem.options, one = elem.type === "select-one";
+
+ // Nothing was selected
+ if (index < 0) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ i = one ? index : 0;
+ max = one ? index + 1 : options.length;
+ for (; i < max; i++) {
+ option = options[i];
+
+ // Don't return options that are disabled or in
+ // a disabled optgroup
+ if (option.selected
+ && (jQuery.support.optDisabled ? !option.disabled
+ : option
+ .getAttribute("disabled") === null)
+ && (!option.parentNode.disabled || !jQuery
+ .nodeName(option.parentNode,
+ "optgroup"))) {
+
+ // Get the specific value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if (one) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push(value);
+ }
+ }
+
+ // Fixes Bug #2551 -- select.val() broken in IE
+ // after form.reset()
+ if (one && !values.length && options.length) {
+ return jQuery(options[index]).val();
+ }
+
+ return values;
+ },
+
+ set : function(elem, value) {
+ var values = jQuery.makeArray(value);
+
+ jQuery(elem).find("option").each(
+ function() {
+ this.selected = jQuery.inArray(jQuery(
+ this).val(), values) >= 0;
+ });
+
+ if (!values.length) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attrFn : {
+ val : true,
+ css : true,
+ html : true,
+ text : true,
+ data : true,
+ width : true,
+ height : true,
+ offset : true
+ },
+
+ attr : function(elem, name, value, pass) {
+ var ret, hooks, notxml, nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute
+ // nodes
+ if (!elem || nType === 3 || nType === 8 || nType === 2) {
+ return;
+ }
+
+ if (pass && name in jQuery.attrFn) {
+ return jQuery(elem)[name](value);
+ }
+
+ // Fallback to prop when attributes are not supported
+ if (typeof elem.getAttribute === "undefined") {
+ return jQuery.prop(elem, name, value);
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
+
+ // All attributes are lowercase
+ // Grab necessary hook if one is defined
+ if (notxml) {
+ name = name.toLowerCase();
+ hooks = jQuery.attrHooks[name]
+ || (rboolean.test(name) ? boolHook : nodeHook);
+ }
+
+ if (value !== undefined) {
+
+ if (value === null) {
+ jQuery.removeAttr(elem, name);
+ return;
+
+ } else if (hooks
+ && "set" in hooks
+ && notxml
+ && (ret = hooks.set(elem, value, name)) !== undefined) {
+ return ret;
+
+ } else {
+ elem.setAttribute(name, "" + value);
+ return value;
+ }
+
+ } else if (hooks && "get" in hooks && notxml
+ && (ret = hooks.get(elem, name)) !== null) {
+ return ret;
+
+ } else {
+
+ ret = elem.getAttribute(name);
+
+ // Non-existent attributes return null, we normalize to
+ // undefined
+ return ret === null ? undefined : ret;
+ }
+ },
+
+ removeAttr : function(elem, value) {
+ var propName, attrNames, name, l, i = 0;
+
+ if (value && elem.nodeType === 1) {
+ attrNames = value.toLowerCase().split(rspace);
+ l = attrNames.length;
+
+ for (; i < l; i++) {
+ name = attrNames[i];
+
+ if (name) {
+ propName = jQuery.propFix[name] || name;
+
+ // See #9699 for explanation of this approach
+ // (setting first, then removal)
+ jQuery.attr(elem, name, "");
+ elem.removeAttribute(getSetAttribute ? name
+ : propName);
+
+ // Set corresponding property to false for
+ // boolean attributes
+ if (rboolean.test(name) && propName in elem) {
+ elem[propName] = false;
+ }
+ }
+ }
+ }
+ },
+
+ attrHooks : {
+ type : {
+ set : function(elem, value) {
+ // We can't allow the type property to be changed
+ // (since it causes problems in IE)
+ if (rtype.test(elem.nodeName) && elem.parentNode) {
+ jQuery.error("type property can't be changed");
+ } else if (!jQuery.support.radioValue
+ && value === "radio"
+ && jQuery.nodeName(elem, "input")) {
+ // Setting the type on a radio button after the
+ // value resets the value in IE6-9
+ // Reset value to it's default in case type is
+ // set after value
+ // This is for element creation
+ var val = elem.value;
+ elem.setAttribute("type", value);
+ if (val) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ },
+ // Use the value property for back compat
+ // Use the nodeHook for button elements in IE6/7 (#1954)
+ value : {
+ get : function(elem, name) {
+ if (nodeHook && jQuery.nodeName(elem, "button")) {
+ return nodeHook.get(elem, name);
+ }
+ return name in elem ? elem.value : null;
+ },
+ set : function(elem, value, name) {
+ if (nodeHook && jQuery.nodeName(elem, "button")) {
+ return nodeHook.set(elem, value, name);
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+ }
+ },
+
+ propFix : {
+ tabindex : "tabIndex",
+ readonly : "readOnly",
+ "for" : "htmlFor",
+ "class" : "className",
+ maxlength : "maxLength",
+ cellspacing : "cellSpacing",
+ cellpadding : "cellPadding",
+ rowspan : "rowSpan",
+ colspan : "colSpan",
+ usemap : "useMap",
+ frameborder : "frameBorder",
+ contenteditable : "contentEditable"
+ },
+
+ prop : function(elem, name, value) {
+ var ret, hooks, notxml, nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute
+ // nodes
+ if (!elem || nType === 3 || nType === 8 || nType === 2) {
+ return;
+ }
+
+ notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
+
+ if (notxml) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[name] || name;
+ hooks = jQuery.propHooks[name];
+ }
+
+ if (value !== undefined) {
+ if (hooks
+ && "set" in hooks
+ && (ret = hooks.set(elem, value, name)) !== undefined) {
+ return ret;
+
+ } else {
+ return (elem[name] = value);
+ }
+
+ } else {
+ if (hooks && "get" in hooks
+ && (ret = hooks.get(elem, name)) !== null) {
+ return ret;
+
+ } else {
+ return elem[name];
+ }
+ }
+ },
+
+ propHooks : {
+ tabIndex : {
+ get : function(elem) {
+ // elem.tabIndex doesn't always return the correct
+ // value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem
+ .getAttributeNode("tabindex");
+
+ return attributeNode && attributeNode.specified ? parseInt(
+ attributeNode.value, 10)
+ : rfocusable.test(elem.nodeName)
+ || rclickable.test(elem.nodeName)
+ && elem.href ? 0 : undefined;
+ }
+ }
+ }
+ });
+
+ // Add the tabIndex propHook to attrHooks for back-compat (different case is
+ // intentional)
+ jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
+
+ // Hook for boolean attributes
+ boolHook = {
+ get : function(elem, name) {
+ // Align boolean attributes with corresponding properties
+ // Fall back to attribute presence where some booleans are not
+ // supported
+ var attrNode, property = jQuery.prop(elem, name);
+ return property === true || typeof property !== "boolean"
+ && (attrNode = elem.getAttributeNode(name))
+ && attrNode.nodeValue !== false ? name.toLowerCase()
+ : undefined;
+ },
+ set : function(elem, value, name) {
+ var propName;
+ if (value === false) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr(elem, name);
+ } else {
+ // value is true since we know at this point it's type boolean
+ // and not false
+ // Set boolean attributes to the same name and set the DOM
+ // property
+ propName = jQuery.propFix[name] || name;
+ if (propName in elem) {
+ // Only set the IDL specifically if it already exists on the
+ // element
+ elem[propName] = true;
+ }
+
+ elem.setAttribute(name, name.toLowerCase());
+ }
+ return name;
+ }
+ };
+
+ // IE6/7 do not support getting/setting some attributes with
+ // get/setAttribute
+ if (!getSetAttribute) {
+
+ fixSpecified = {
+ name : true,
+ id : true
+ };
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get : function(elem, name) {
+ var ret;
+ ret = elem.getAttributeNode(name);
+ return ret
+ && (fixSpecified[name] ? ret.nodeValue !== ""
+ : ret.specified) ? ret.nodeValue : undefined;
+ },
+ set : function(elem, value, name) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode(name);
+ if (!ret) {
+ ret = document.createAttribute(name);
+ elem.setAttributeNode(ret);
+ }
+ return (ret.nodeValue = value + "");
+ }
+ };
+
+ // Apply the nodeHook to tabindex
+ jQuery.attrHooks.tabindex.set = nodeHook.set;
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150
+ // )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function(i, name) {
+ jQuery.attrHooks[name] = jQuery.extend(jQuery.attrHooks[name], {
+ set : function(elem, value) {
+ if (value === "") {
+ elem.setAttribute(name, "auto");
+ return value;
+ }
+ }
+ });
+ });
+
+ // Set contenteditable to false on removals(#10429)
+ // Setting to empty string throws an error as an invalid value
+ jQuery.attrHooks.contenteditable = {
+ get : nodeHook.get,
+ set : function(elem, value, name) {
+ if (value === "") {
+ value = "false";
+ }
+ nodeHook.set(elem, value, name);
+ }
+ };
+ }
+
+ // Some attributes require a special call on IE
+ if (!jQuery.support.hrefNormalized) {
+ jQuery.each([ "href", "src", "width", "height" ], function(i, name) {
+ jQuery.attrHooks[name] = jQuery.extend(jQuery.attrHooks[name], {
+ get : function(elem) {
+ var ret = elem.getAttribute(name, 2);
+ return ret === null ? undefined : ret;
+ }
+ });
+ });
+ }
+
+ if (!jQuery.support.style) {
+ jQuery.attrHooks.style = {
+ get : function(elem) {
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
+ },
+ set : function(elem, value) {
+ return (elem.style.cssText = "" + value);
+ }
+ };
+ }
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if (!jQuery.support.optSelected) {
+ jQuery.propHooks.selected = jQuery.extend(jQuery.propHooks.selected, {
+ get : function(elem) {
+ var parent = elem.parentNode;
+
+ if (parent) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if (parent.parentNode) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ // IE6/7 call enctype encoding
+ if (!jQuery.support.enctype) {
+ jQuery.propFix.enctype = "encoding";
+ }
+
+ // Radios and checkboxes getter/setter
+ if (!jQuery.support.checkOn) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[this] = {
+ get : function(elem) {
+ // Handle the case where in Webkit "" is returned instead of
+ // "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on"
+ : elem.value;
+ }
+ };
+ });
+ }
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[this] = jQuery.extend(jQuery.valHooks[this], {
+ set : function(elem, value) {
+ if (jQuery.isArray(value)) {
+ return (elem.checked = jQuery.inArray(jQuery(elem).val(),
+ value) >= 0);
+ }
+ }
+ });
+ });
+
+ var rformElems = /^(?:textarea|input|select)$/i, rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, rhoverHack = /\bhover(\.\S+)?\b/, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, quickParse = function(
+ selector) {
+ var quick = rquickIs.exec(selector);
+ if (quick) {
+ // 0 1 2 3
+ // [ _, tag, id, class ]
+ quick[1] = (quick[1] || "").toLowerCase();
+ quick[3] = quick[3]
+ && new RegExp("(?:^|\\s)" + quick[3] + "(?:\\s|$)");
+ }
+ return quick;
+ }, quickIs = function(elem, m) {
+ var attrs = elem.attributes || {};
+ return ((!m[1] || elem.nodeName.toLowerCase() === m[1])
+ && (!m[2] || (attrs.id || {}).value === m[2]) && (!m[3] || m[3]
+ .test((attrs["class"] || {}).value)));
+ }, hoverHack = function(events) {
+ return jQuery.event.special.hover ? events : events.replace(rhoverHack,
+ "mouseenter$1 mouseleave$1");
+ };
+
+ /*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+ jQuery.event = {
+
+ add : function(elem, types, handler, data, selector) {
+
+ var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, handleObjIn, quick, handlers, special;
+
+ // Don't attach events to noData or text/comment nodes (allow plain
+ // objects tho)
+ if (elem.nodeType === 3 || elem.nodeType === 8 || !types
+ || !handler || !(elemData = jQuery._data(elem))) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the
+ // handler
+ if (handler.handler) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove
+ // it later
+ if (!handler.guid) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is
+ // the first
+ events = elemData.events;
+ if (!events) {
+ elemData.events = events = {};
+ }
+ eventHandle = elemData.handle;
+ if (!eventHandle) {
+ elemData.handle = eventHandle = function(e) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined"
+ && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch
+ .apply(eventHandle.elem, arguments)
+ : undefined;
+ };
+ // Add elem as a property of the handle fn to prevent a memory
+ // leak with IE non-native events
+ eventHandle.elem = elem;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = jQuery.trim(hoverHack(types)).split(" ");
+ for (t = 0; t < types.length; t++) {
+
+ tns = rtypenamespace.exec(types[t]) || [];
+ type = tns[1];
+ namespaces = (tns[2] || "").split(".").sort();
+
+ // If event changes its type, use the special event handlers for
+ // the changed type
+ special = jQuery.event.special[type] || {};
+
+ // If selector defined, determine special event api type,
+ // otherwise given type
+ type = (selector ? special.delegateType : special.bindType)
+ || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[type] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend({
+ type : type,
+ origType : tns[1],
+ data : data,
+ handler : handler,
+ guid : handler.guid,
+ selector : selector,
+ quick : quickParse(selector),
+ namespace : namespaces.join(".")
+ }, handleObjIn);
+
+ // Init the event handler queue if we're the first
+ handlers = events[type];
+ if (!handlers) {
+ handlers = events[type] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if (!special.setup
+ || special.setup.call(elem, data, namespaces,
+ eventHandle) === false) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener) {
+ elem.addEventListener(type, eventHandle, false);
+
+ } else if (elem.attachEvent) {
+ elem.attachEvent("on" + type, eventHandle);
+ }
+ }
+ }
+
+ if (special.add) {
+ special.add.call(elem, handleObj);
+
+ if (!handleObj.handler.guid) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if (selector) {
+ handlers.splice(handlers.delegateCount++, 0, handleObj);
+ } else {
+ handlers.push(handleObj);
+ }
+
+ // Keep track of which events have ever been used, for event
+ // optimization
+ jQuery.event.global[type] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global : {},
+
+ // Detach an event or set of events from an element
+ remove : function(elem, types, handler, selector, mappedTypes) {
+
+ var elemData = jQuery.hasData(elem) && jQuery._data(elem), t, tns, type, origType, namespaces, origCount, j, events, special, handle, eventType, handleObj;
+
+ if (!elemData || !(events = elemData.events)) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = jQuery.trim(hoverHack(types || "")).split(" ");
+ for (t = 0; t < types.length; t++) {
+ tns = rtypenamespace.exec(types[t]) || [];
+ type = origType = tns[1];
+ namespaces = tns[2];
+
+ // Unbind all events (on this namespace, if provided) for the
+ // element
+ if (!type) {
+ for (type in events) {
+ jQuery.event.remove(elem, type + types[t], handler,
+ selector, true);
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[type] || {};
+ type = (selector ? special.delegateType : special.bindType)
+ || type;
+ eventType = events[type] || [];
+ origCount = eventType.length;
+ namespaces = namespaces ? new RegExp("(^|\\.)"
+ + namespaces.split(".").sort().join("\\.(?:.*\\.)?")
+ + "(\\.|$)") : null;
+
+ // Remove matching events
+ for (j = 0; j < eventType.length; j++) {
+ handleObj = eventType[j];
+
+ if ((mappedTypes || origType === handleObj.origType)
+ && (!handler || handler.guid === handleObj.guid)
+ && (!namespaces || namespaces
+ .test(handleObj.namespace))
+ && (!selector || selector === handleObj.selector || selector === "**"
+ && handleObj.selector)) {
+ eventType.splice(j--, 1);
+
+ if (handleObj.selector) {
+ eventType.delegateCount--;
+ }
+ if (special.remove) {
+ special.remove.call(elem, handleObj);
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no
+ // more handlers exist
+ // (avoids potential for endless recursion during removal of
+ // special event handlers)
+ if (eventType.length === 0 && origCount !== eventType.length) {
+ if (!special.teardown
+ || special.teardown.call(elem, namespaces) === false) {
+ jQuery.removeEvent(elem, type, elemData.handle);
+ }
+
+ delete events[type];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if (jQuery.isEmptyObject(events)) {
+ handle = elemData.handle;
+ if (handle) {
+ handle.elem = null;
+ }
+
+ // removeData also checks for emptiness and clears the expando
+ // if empty
+ // so use it instead of delete
+ jQuery.removeData(elem, [ "events", "handle" ], true);
+ }
+ },
+
+ // Events that are safe to short-circuit if no handlers are attached.
+ // Native DOM events should not be added, they may have inline handlers.
+ customEvent : {
+ "getData" : true,
+ "setData" : true,
+ "changeData" : true
+ },
+
+ trigger : function(event, data, elem, onlyHandlers) {
+ // Don't do events on text and comment nodes
+ if (elem && (elem.nodeType === 3 || elem.nodeType === 8)) {
+ return;
+ }
+
+ // Event object or event type
+ var type = event.type || event, namespaces = [], cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
+
+ // focus/blur morphs to focusin/out; ensure we're not firing them
+ // right now
+ if (rfocusMorph.test(type + jQuery.event.triggered)) {
+ return;
+ }
+
+ if (type.indexOf("!") >= 0) {
+ // Exclusive events trigger only for the exact event (no
+ // namespaces)
+ type = type.slice(0, -1);
+ exclusive = true;
+ }
+
+ if (type.indexOf(".") >= 0) {
+ // Namespaced trigger; create a regexp to match event type in
+ // handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+
+ if ((!elem || jQuery.event.customEvent[type])
+ && !jQuery.event.global[type]) {
+ // No jQuery handlers for this event type, and it can't have
+ // inline handlers
+ return;
+ }
+
+ // Caller can pass in an Event, Object, or just an event type string
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[jQuery.expando] ? event :
+ // Object literal
+ new jQuery.Event(type, event) :
+ // Just the event type (string)
+ new jQuery.Event(type);
+
+ event.type = type;
+ event.isTrigger = true;
+ event.exclusive = exclusive;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = event.namespace ? new RegExp("(^|\\.)"
+ + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
+ ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+ // Handle a global trigger
+ if (!elem) {
+
+ // TODO: Stop taunting the data cache; remove global events and
+ // always attach to document
+ cache = jQuery.cache;
+ for (i in cache) {
+ if (cache[i].events && cache[i].events[type]) {
+ jQuery.event.trigger(event, data, cache[i].handle.elem,
+ true);
+ }
+ }
+ return;
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ if (!event.target) {
+ event.target = elem;
+ }
+
+ // Clone any incoming data and prepend the event, creating the
+ // handler arg list
+ data = data != null ? jQuery.makeArray(data) : [];
+ data.unshift(event);
+
+ // Allow special events to draw outside the lines
+ special = jQuery.event.special[type] || {};
+ if (special.trigger && special.trigger.apply(elem, data) === false) {
+ return;
+ }
+
+ // Determine event propagation path in advance, per W3C events spec
+ // (#9951)
+ // Bubble up to document, then to window; watch for a global
+ // ownerDocument var (#9724)
+ eventPath = [ [ elem, special.bindType || type ] ];
+ if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
+
+ bubbleType = special.delegateType || type;
+ cur = rfocusMorph.test(bubbleType + type) ? elem
+ : elem.parentNode;
+ old = null;
+ for (; cur; cur = cur.parentNode) {
+ eventPath.push([ cur, bubbleType ]);
+ old = cur;
+ }
+
+ // Only add window if we got to document (e.g., not plain obj or
+ // detached DOM)
+ if (old && old === elem.ownerDocument) {
+ eventPath.push([
+ old.defaultView || old.parentWindow || window,
+ bubbleType ]);
+ }
+ }
+
+ // Fire handlers on the event path
+ for (i = 0; i < eventPath.length && !event.isPropagationStopped(); i++) {
+
+ cur = eventPath[i][0];
+ event.type = eventPath[i][1];
+
+ handle = (jQuery._data(cur, "events") || {})[event.type]
+ && jQuery._data(cur, "handle");
+ if (handle) {
+ handle.apply(cur, data);
+ }
+ // Note that this is a bare JS function and not a jQuery handler
+ handle = ontype && cur[ontype];
+ if (handle && jQuery.acceptData(cur)
+ && handle.apply(cur, data) === false) {
+ event.preventDefault();
+ }
+ }
+ event.type = type;
+
+ // If nobody prevented the default action, do it now
+ if (!onlyHandlers && !event.isDefaultPrevented()) {
+
+ if ((!special._default || special._default.apply(
+ elem.ownerDocument, data) === false)
+ && !(type === "click" && jQuery.nodeName(elem, "a"))
+ && jQuery.acceptData(elem)) {
+
+ // Call a native DOM method on the target with the same name
+ // name as the event.
+ // Can't use an .isFunction() check here because IE6/7 fails
+ // that test.
+ // Don't do default actions on window, that's where global
+ // variables be (#6170)
+ // IE<9 dies on focus/blur to hidden element (#1486)
+ if (ontype
+ && elem[type]
+ && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0)
+ && !jQuery.isWindow(elem)) {
+
+ // Don't re-trigger an onFOO event when we call its
+ // FOO() method
+ old = elem[ontype];
+
+ if (old) {
+ elem[ontype] = null;
+ }
+
+ // Prevent re-triggering of the same event, since we
+ // already bubbled it above
+ jQuery.event.triggered = type;
+ elem[type]();
+ jQuery.event.triggered = undefined;
+
+ if (old) {
+ elem[ontype] = old;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ dispatch : function(event) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix(event || window.event);
+
+ var handlers = ((jQuery._data(this, "events") || {})[event.type] || []), delegateCount = handlers.delegateCount, args = [].slice
+ .call(arguments, 0), run_all = !event.exclusive
+ && !event.namespace, handlerQueue = [], i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native
+ // event
+ args[0] = event;
+ event.delegateTarget = this;
+
+ // Determine handlers that should run if there are delegated events
+ // Avoid disabled elements in IE (#6911) and non-left-click bubbling
+ // in Firefox (#3861)
+ if (delegateCount && !event.target.disabled
+ && !(event.button && event.type === "click")) {
+
+ // Pregenerate a single jQuery object for reuse with .is()
+ jqcur = jQuery(this);
+ jqcur.context = this.ownerDocument || this;
+
+ for (cur = event.target; cur != this; cur = cur.parentNode
+ || this) {
+ selMatch = {};
+ matches = [];
+ jqcur[0] = cur;
+ for (i = 0; i < delegateCount; i++) {
+ handleObj = handlers[i];
+ sel = handleObj.selector;
+
+ if (selMatch[sel] === undefined) {
+ selMatch[sel] = (handleObj.quick ? quickIs(cur,
+ handleObj.quick) : jqcur.is(sel));
+ }
+ if (selMatch[sel]) {
+ matches.push(handleObj);
+ }
+ }
+ if (matches.length) {
+ handlerQueue.push({
+ elem : cur,
+ matches : matches
+ });
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ if (handlers.length > delegateCount) {
+ handlerQueue.push({
+ elem : this,
+ matches : handlers.slice(delegateCount)
+ });
+ }
+
+ // Run delegates first; they may want to stop propagation beneath us
+ for (i = 0; i < handlerQueue.length
+ && !event.isPropagationStopped(); i++) {
+ matched = handlerQueue[i];
+ event.currentTarget = matched.elem;
+
+ for (j = 0; j < matched.matches.length
+ && !event.isImmediatePropagationStopped(); j++) {
+ handleObj = matched.matches[j];
+
+ // Triggered event must either 1) be non-exclusive and have
+ // no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the
+ // bound event (both can have no namespace).
+ if (run_all || (!event.namespace && !handleObj.namespace)
+ || event.namespace_re
+ && event.namespace_re.test(handleObj.namespace)) {
+
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
+ .apply(matched.elem, args);
+
+ if (ret !== undefined) {
+ event.result = ret;
+ if (ret === false) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ // Includes some event props shared by KeyEvent and MouseEvent
+ // *** attrChange attrName relatedNode srcElement are not normalized,
+ // non-W3C, deprecated, will be removed in 1.8 ***
+ props : "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which"
+ .split(" "),
+
+ fixHooks : {},
+
+ keyHooks : {
+ props : "char charCode key keyCode".split(" "),
+ filter : function(event, original) {
+
+ // Add which for key events
+ if (event.which == null) {
+ event.which = original.charCode != null ? original.charCode
+ : original.keyCode;
+ }
+
+ return event;
+ }
+ },
+
+ mouseHooks : {
+ props : "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement"
+ .split(" "),
+ filter : function(event, original) {
+ var eventDoc, doc, body, button = original.button, fromElement = original.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if (event.pageX == null && original.clientX != null) {
+ eventDoc = event.target.ownerDocument || document;
+ doc = eventDoc.documentElement;
+ body = eventDoc.body;
+
+ event.pageX = original.clientX
+ + (doc && doc.scrollLeft || body && body.scrollLeft || 0)
+ - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = original.clientY
+ + (doc && doc.scrollTop || body && body.scrollTop || 0)
+ - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add relatedTarget, if necessary
+ if (!event.relatedTarget && fromElement) {
+ event.relatedTarget = fromElement === event.target ? original.toElement
+ : fromElement;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if (!event.which && button !== undefined) {
+ event.which = (button & 1 ? 1 : (button & 2 ? 3
+ : (button & 4 ? 2 : 0)));
+ }
+
+ return event;
+ }
+ },
+
+ fix : function(event) {
+ if (event[jQuery.expando]) {
+ return event;
+ }
+
+ // Create a writable copy of the event object and normalize some
+ // properties
+ var i, prop, originalEvent = event, fixHook = jQuery.event.fixHooks[event.type]
+ || {}, copy = fixHook.props ? this.props
+ .concat(fixHook.props) : this.props;
+
+ event = jQuery.Event(originalEvent);
+
+ for (i = copy.length; i;) {
+ prop = copy[--i];
+ event[prop] = originalEvent[prop];
+ }
+
+ // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
+ if (!event.target) {
+ event.target = originalEvent.srcElement || document;
+ }
+
+ // Target should not be a text node (#504, Safari)
+ if (event.target.nodeType === 3) {
+ event.target = event.target.parentNode;
+ }
+
+ // For mouse/key events; add metaKey if it's not there (#3368,
+ // IE6/7/8)
+ if (event.metaKey === undefined) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ return fixHook.filter ? fixHook.filter(event, originalEvent)
+ : event;
+ },
+
+ special : {
+ ready : {
+ // Make sure the ready event is setup
+ setup : jQuery.bindReady
+ },
+
+ load : {
+ // Prevent triggered image.load events from bubbling to
+ // window.load
+ noBubble : true
+ },
+
+ focus : {
+ delegateType : "focusin"
+ },
+ blur : {
+ delegateType : "focusout"
+ },
+
+ beforeunload : {
+ setup : function(data, namespaces, eventHandle) {
+ // We only want to do this special case on windows
+ if (jQuery.isWindow(this)) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown : function(namespaces, eventHandle) {
+ if (this.onbeforeunload === eventHandle) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ },
+
+ simulate : function(type, elem, event, bubble) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the
+ // donor.
+ var e = jQuery.extend(new jQuery.Event(), event, {
+ type : type,
+ isSimulated : true,
+ originalEvent : {}
+ });
+ if (bubble) {
+ jQuery.event.trigger(e, null, elem);
+ } else {
+ jQuery.event.dispatch.call(elem, e);
+ }
+ if (e.isDefaultPrevented()) {
+ event.preventDefault();
+ }
+ }
+ };
+
+ // Some plugins are using, but it's undocumented/deprecated and will be
+ // removed.
+ // The 1.7 special event interface should provide all the hooks needed now.
+ jQuery.event.handle = jQuery.event.dispatch;
+
+ jQuery.removeEvent = document.removeEventListener ? function(elem, type,
+ handle) {
+ if (elem.removeEventListener) {
+ elem.removeEventListener(type, handle, false);
+ }
+ } : function(elem, type, handle) {
+ if (elem.detachEvent) {
+ elem.detachEvent("on" + type, handle);
+ }
+ };
+
+ jQuery.Event = function(src, props) {
+ // Allow instantiation without the 'new' keyword
+ if (!(this instanceof jQuery.Event)) {
+ return new jQuery.Event(src, props);
+ }
+
+ // Event object
+ if (src && src.type) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = (src.defaultPrevented
+ || src.returnValue === false || src.getPreventDefault
+ && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if (props) {
+ jQuery.extend(this, props);
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || jQuery.now();
+
+ // Mark it as fixed
+ this[jQuery.expando] = true;
+ };
+
+ function returnFalse() {
+ return false;
+ }
+ function returnTrue() {
+ return true;
+ }
+
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript
+ // Language Binding
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+ jQuery.Event.prototype = {
+ preventDefault : function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if (!e) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event
+ // to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation : function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if (!e) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to
+ // true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation : function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented : returnFalse,
+ isPropagationStopped : returnFalse,
+ isImmediatePropagationStopped : returnFalse
+ };
+
+ // Create mouseenter/leave events using mouseover/out and event-time checks
+ jQuery
+ .each(
+ {
+ mouseenter : "mouseover",
+ mouseleave : "mouseout"
+ },
+ function(orig, fix) {
+ jQuery.event.special[orig] = {
+ delegateType : fix,
+ bindType : fix,
+
+ handle : function(event) {
+ var target = this, related = event.relatedTarget, handleObj = event.handleObj, selector = handleObj.selector, ret;
+
+ // For mousenter/leave call the handler if
+ // related is outside the target.
+ // NB: No relatedTarget if the mouse
+ // left/entered the browser window
+ if (!related
+ || (related !== target && !jQuery
+ .contains(target, related))) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply(this,
+ arguments);
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+ });
+
+ // IE submit delegation
+ if (!jQuery.support.submitBubbles) {
+
+ jQuery.event.special.submit = {
+ setup : function() {
+ // Only need this for delegated form submit events
+ if (jQuery.nodeName(this, "form")) {
+ return false;
+ }
+
+ // Lazy-add a submit handler when a descendant form may
+ // potentially be submitted
+ jQuery.event
+ .add(
+ this,
+ "click._submit keypress._submit",
+ function(e) {
+ // Node name check avoids a VML-related
+ // crash in IE (#9807)
+ var elem = e.target, form = jQuery
+ .nodeName(elem, "input")
+ || jQuery.nodeName(elem, "button") ? elem.form
+ : undefined;
+ if (form && !form._submit_attached) {
+ jQuery.event
+ .add(
+ form,
+ "submit._submit",
+ function(event) {
+ // If form was
+ // submitted by the
+ // user, bubble the
+ // event up the tree
+ if (this.parentNode
+ && !event.isTrigger) {
+ jQuery.event
+ .simulate(
+ "submit",
+ this.parentNode,
+ event,
+ true);
+ }
+ });
+ form._submit_attached = true;
+ }
+ });
+ // return undefined since we don't need an event listener
+ },
+
+ teardown : function() {
+ // Only need this for delegated form submit events
+ if (jQuery.nodeName(this, "form")) {
+ return false;
+ }
+
+ // Remove delegated handlers; cleanData eventually reaps submit
+ // handlers attached above
+ jQuery.event.remove(this, "._submit");
+ }
+ };
+ }
+
+ // IE change delegation and checkbox/radio fix
+ if (!jQuery.support.changeBubbles) {
+
+ jQuery.event.special.change = {
+
+ setup : function() {
+
+ if (rformElems.test(this.nodeName)) {
+ // IE doesn't fire change on a check/radio until blur;
+ // trigger it on click
+ // after a propertychange. Eat the blur-change in
+ // special.change.handle.
+ // This still fires onchange a second time for check/radio
+ // after blur.
+ if (this.type === "checkbox" || this.type === "radio") {
+ jQuery.event
+ .add(
+ this,
+ "propertychange._change",
+ function(event) {
+ if (event.originalEvent.propertyName === "checked") {
+ this._just_changed = true;
+ }
+ });
+ jQuery.event
+ .add(this, "click._change",
+ function(event) {
+ if (this._just_changed
+ && !event.isTrigger) {
+ this._just_changed = false;
+ jQuery.event.simulate("change",
+ this, event, true);
+ }
+ });
+ }
+ return false;
+ }
+ // Delegated event; lazy-add a change handler on descendant
+ // inputs
+ jQuery.event.add(this, "beforeactivate._change", function(e) {
+ var elem = e.target;
+
+ if (rformElems.test(elem.nodeName)
+ && !elem._change_attached) {
+ jQuery.event.add(elem, "change._change",
+ function(event) {
+ if (this.parentNode && !event.isSimulated
+ && !event.isTrigger) {
+ jQuery.event.simulate("change",
+ this.parentNode, event, true);
+ }
+ });
+ elem._change_attached = true;
+ }
+ });
+ },
+
+ handle : function(event) {
+ var elem = event.target;
+
+ // Swallow native change events from checkbox/radio, we already
+ // triggered them above
+ if (this !== elem || event.isSimulated || event.isTrigger
+ || (elem.type !== "radio" && elem.type !== "checkbox")) {
+ return event.handleObj.handler.apply(this, arguments);
+ }
+ },
+
+ teardown : function() {
+ jQuery.event.remove(this, "._change");
+
+ return rformElems.test(this.nodeName);
+ }
+ };
+ }
+
+ // Create "bubbling" focus and blur events
+ if (!jQuery.support.focusinBubbles) {
+ jQuery.each({
+ focus : "focusin",
+ blur : "focusout"
+ }, function(orig, fix) {
+
+ // Attach a single capturing handler while someone wants
+ // focusin/focusout
+ var attaches = 0, handler = function(event) {
+ jQuery.event.simulate(fix, event.target, jQuery.event
+ .fix(event), true);
+ };
+
+ jQuery.event.special[fix] = {
+ setup : function() {
+ if (attaches++ === 0) {
+ document.addEventListener(orig, handler, true);
+ }
+ },
+ teardown : function() {
+ if (--attaches === 0) {
+ document.removeEventListener(orig, handler, true);
+ }
+ }
+ };
+ });
+ }
+
+ jQuery.fn
+ .extend({
+
+ on : function(types, selector, data, fn, /* INTERNAL */one) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if (typeof types === "object") {
+ // ( types-Object, selector, data )
+ if (typeof selector !== "string") {
+ // ( types-Object, data )
+ data = selector;
+ selector = undefined;
+ }
+ for (type in types) {
+ this.on(type, selector, data, types[type], one);
+ }
+ return this;
+ }
+
+ if (data == null && fn == null) {
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if (fn == null) {
+ if (typeof selector === "string") {
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if (fn === false) {
+ fn = returnFalse;
+ } else if (!fn) {
+ return this;
+ }
+
+ if (one === 1) {
+ origFn = fn;
+ fn = function(event) {
+ // Can use an empty set, since event contains the
+ // info
+ jQuery().off(event);
+ return origFn.apply(this, arguments);
+ };
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
+ }
+ return this.each(function() {
+ jQuery.event.add(this, types, fn, data, selector);
+ });
+ },
+ one : function(types, selector, data, fn) {
+ return this.on.call(this, types, selector, data, fn, 1);
+ },
+ off : function(types, selector, fn) {
+ if (types && types.preventDefault && types.handleObj) {
+ // ( event ) dispatched jQuery.Event
+ var handleObj = types.handleObj;
+ jQuery(types.delegateTarget).off(
+ handleObj.namespace ? handleObj.type + "."
+ + handleObj.namespace : handleObj.type,
+ handleObj.selector, handleObj.handler);
+ return this;
+ }
+ if (typeof types === "object") {
+ // ( types-object [, selector] )
+ for ( var type in types) {
+ this.off(type, selector, types[type]);
+ }
+ return this;
+ }
+ if (selector === false || typeof selector === "function") {
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if (fn === false) {
+ fn = returnFalse;
+ }
+ return this.each(function() {
+ jQuery.event.remove(this, types, fn, selector);
+ });
+ },
+
+ bind : function(types, data, fn) {
+ return this.on(types, null, data, fn);
+ },
+ unbind : function(types, fn) {
+ return this.off(types, null, fn);
+ },
+
+ live : function(types, data, fn) {
+ jQuery(this.context).on(types, this.selector, data, fn);
+ return this;
+ },
+ die : function(types, fn) {
+ jQuery(this.context).off(types, this.selector || "**", fn);
+ return this;
+ },
+
+ delegate : function(selector, types, data, fn) {
+ return this.on(types, selector, data, fn);
+ },
+ undelegate : function(selector, types, fn) {
+ // ( namespace ) or ( selector, types [, fn] )
+ return arguments.length == 1 ? this.off(selector, "**")
+ : this.off(types, selector, fn);
+ },
+
+ trigger : function(type, data) {
+ return this.each(function() {
+ jQuery.event.trigger(type, data, this);
+ });
+ },
+ triggerHandler : function(type, data) {
+ if (this[0]) {
+ return jQuery.event.trigger(type, data, this[0], true);
+ }
+ },
+
+ toggle : function(fn) {
+ // Save reference to arguments for access in closure
+ var args = arguments, guid = fn.guid || jQuery.guid++, i = 0, toggler = function(
+ event) {
+ // Figure out which function to execute
+ var lastToggle = (jQuery._data(this, "lastToggle"
+ + fn.guid) || 0)
+ % i;
+ jQuery._data(this, "lastToggle" + fn.guid,
+ lastToggle + 1);
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[lastToggle].apply(this, arguments) || false;
+ };
+
+ // link all the functions, so any of them can unbind this
+ // click handler
+ toggler.guid = guid;
+ while (i < args.length) {
+ args[i++].guid = guid;
+ }
+
+ return this.click(toggler);
+ },
+
+ hover : function(fnOver, fnOut) {
+ return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
+ }
+ });
+
+ jQuery
+ .each(
+ ("blur focus focusin focusout load resize scroll unload click dblclick "
+ + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "
+ + "change select submit keydown keypress keyup error contextmenu")
+ .split(" "),
+ function(i, name) {
+
+ // Handle event binding
+ jQuery.fn[name] = function(data, fn) {
+ if (fn == null) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ? this.on(name, null,
+ data, fn) : this.trigger(name);
+ };
+
+ if (jQuery.attrFn) {
+ jQuery.attrFn[name] = true;
+ }
+
+ if (rkeyEvent.test(name)) {
+ jQuery.event.fixHooks[name] = jQuery.event.keyHooks;
+ }
+
+ if (rmouseEvent.test(name)) {
+ jQuery.event.fixHooks[name] = jQuery.event.mouseHooks;
+ }
+ });
+
+ /*
+ * ! Sizzle CSS Selector Engine Copyright 2011, The Dojo Foundation Released
+ * under the MIT, BSD, and GPL Licenses. More information:
+ * http://sizzlejs.com/
+ */
+ (function() {
+
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, expando = "sizcache"
+ + (Math.random() + '').replace('.', ''), done = 0, toString = Object.prototype.toString, hasDuplicate = false, baseHasDuplicate = true, rBackslash = /\\/g, rReturn = /\r\n/g, rNonWord = /\W/;
+
+ // Here we check if the JavaScript engine is using some sort of
+ // optimization where it does not always call our comparision
+ // function. If that is the case, discard the hasDuplicate value.
+ // Thus far that includes Google Chrome.
+ [ 0, 0 ].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+ });
+
+ var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if (context.nodeType !== 1 && context.nodeType !== 9) {
+ return [];
+ }
+
+ if (!selector || typeof selector !== "string") {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i, prune = true, contextXML = Sizzle
+ .isXML(context), parts = [], soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec("");
+ m = chunker.exec(soFar);
+
+ if (m) {
+ soFar = m[3];
+
+ parts.push(m[1]);
+
+ if (m[2]) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while (m);
+
+ if (parts.length > 1 && origPOS.exec(selector)) {
+
+ if (parts.length === 2 && Expr.relative[parts[0]]) {
+ set = posProcess(parts[0] + parts[1], context, seed);
+
+ } else {
+ set = Expr.relative[parts[0]] ? [ context ] : Sizzle(parts
+ .shift(), context);
+
+ while (parts.length) {
+ selector = parts.shift();
+
+ if (Expr.relative[selector]) {
+ selector += parts.shift();
+ }
+
+ set = posProcess(selector, set, seed);
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is
+ // an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if (!seed && parts.length > 1 && context.nodeType === 9
+ && !contextXML && Expr.match.ID.test(parts[0])
+ && !Expr.match.ID.test(parts[parts.length - 1])) {
+
+ ret = Sizzle.find(parts.shift(), context, contextXML);
+ context = ret.expr ? Sizzle.filter(ret.expr, ret.set)[0]
+ : ret.set[0];
+ }
+
+ if (context) {
+ ret = seed ? {
+ expr : parts.pop(),
+ set : makeArray(seed)
+ } : Sizzle.find(parts.pop(), parts.length === 1
+ && (parts[0] === "~" || parts[0] === "+")
+ && context.parentNode ? context.parentNode
+ : context, contextXML);
+
+ set = ret.expr ? Sizzle.filter(ret.expr, ret.set) : ret.set;
+
+ if (parts.length > 0) {
+ checkSet = makeArray(set);
+
+ } else {
+ prune = false;
+ }
+
+ while (parts.length) {
+ cur = parts.pop();
+ pop = cur;
+
+ if (!Expr.relative[cur]) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if (pop == null) {
+ pop = context;
+ }
+
+ Expr.relative[cur](checkSet, pop, contextXML);
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if (!checkSet) {
+ checkSet = set;
+ }
+
+ if (!checkSet) {
+ Sizzle.error(cur || selector);
+ }
+
+ if (toString.call(checkSet) === "[object Array]") {
+ if (!prune) {
+ results.push.apply(results, checkSet);
+
+ } else if (context && context.nodeType === 1) {
+ for (i = 0; checkSet[i] != null; i++) {
+ if (checkSet[i]
+ && (checkSet[i] === true || checkSet[i].nodeType === 1
+ && Sizzle
+ .contains(context, checkSet[i]))) {
+ results.push(set[i]);
+ }
+ }
+
+ } else {
+ for (i = 0; checkSet[i] != null; i++) {
+ if (checkSet[i] && checkSet[i].nodeType === 1) {
+ results.push(set[i]);
+ }
+ }
+ }
+
+ } else {
+ makeArray(checkSet, results);
+ }
+
+ if (extra) {
+ Sizzle(extra, origContext, results, seed);
+ Sizzle.uniqueSort(results);
+ }
+
+ return results;
+ };
+
+ Sizzle.uniqueSort = function(results) {
+ if (sortOrder) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if (hasDuplicate) {
+ for (var i = 1; i < results.length; i++) {
+ if (results[i] === results[i - 1]) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+ };
+
+ Sizzle.matches = function(expr, set) {
+ return Sizzle(expr, null, null, set);
+ };
+
+ Sizzle.matchesSelector = function(node, expr) {
+ return Sizzle(expr, null, null, [ node ]).length > 0;
+ };
+
+ Sizzle.find = function(expr, context, isXML) {
+ var set, i, len, match, type, left;
+
+ if (!expr) {
+ return [];
+ }
+
+ for (i = 0, len = Expr.order.length; i < len; i++) {
+ type = Expr.order[i];
+
+ if ((match = Expr.leftMatch[type].exec(expr))) {
+ left = match[1];
+ match.splice(1, 1);
+
+ if (left.substr(left.length - 1) !== "\\") {
+ match[1] = (match[1] || "").replace(rBackslash, "");
+ set = Expr.find[type](match, context, isXML);
+
+ if (set != null) {
+ expr = expr.replace(Expr.match[type], "");
+ break;
+ }
+ }
+ }
+ }
+
+ if (!set) {
+ set = typeof context.getElementsByTagName !== "undefined" ? context
+ .getElementsByTagName("*")
+ : [];
+ }
+
+ return {
+ set : set,
+ expr : expr
+ };
+ };
+
+ Sizzle.filter = function(expr, set, inplace, not) {
+ var match, anyFound, type, found, item, filter, left, i, pass, old = expr, result = [], curLoop = set, isXMLFilter = set
+ && set[0] && Sizzle.isXML(set[0]);
+
+ while (expr && set.length) {
+ for (type in Expr.filter) {
+ if ((match = Expr.leftMatch[type].exec(expr)) != null
+ && match[2]) {
+ filter = Expr.filter[type];
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1, 1);
+
+ if (left.substr(left.length - 1) === "\\") {
+ continue;
+ }
+
+ if (curLoop === result) {
+ result = [];
+ }
+
+ if (Expr.preFilter[type]) {
+ match = Expr.preFilter[type](match, curLoop,
+ inplace, result, not, isXMLFilter);
+
+ if (!match) {
+ anyFound = found = true;
+
+ } else if (match === true) {
+ continue;
+ }
+ }
+
+ if (match) {
+ for (i = 0; (item = curLoop[i]) != null; i++) {
+ if (item) {
+ found = filter(item, match, i, curLoop);
+ pass = not ^ found;
+
+ if (inplace && found != null) {
+ if (pass) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if (pass) {
+ result.push(item);
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if (found !== undefined) {
+ if (!inplace) {
+ curLoop = result;
+ }
+
+ expr = expr.replace(Expr.match[type], "");
+
+ if (!anyFound) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if (expr === old) {
+ if (anyFound == null) {
+ Sizzle.error(expr);
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+ };
+
+ Sizzle.error = function(msg) {
+ throw new Error("Syntax error, unrecognized expression: " + msg);
+ };
+
+ /**
+ * Utility function for retreiving the text value of an array of DOM
+ * nodes
+ *
+ * @param {Array|Element}
+ * elem
+ */
+ var getText = Sizzle.getText = function(elem) {
+ var i, node, nodeType = elem.nodeType, ret = "";
+
+ if (nodeType) {
+ if (nodeType === 1 || nodeType === 9) {
+ // Use textContent || innerText for elements
+ if (typeof elem.textContent === 'string') {
+ return elem.textContent;
+ } else if (typeof elem.innerText === 'string') {
+ // Replace IE's carriage returns
+ return elem.innerText.replace(rReturn, '');
+ } else {
+ // Traverse it's children
+ for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+ ret += getText(elem);
+ }
+ }
+ } else if (nodeType === 3 || nodeType === 4) {
+ return elem.nodeValue;
+ }
+ } else {
+
+ // If no nodeType, this is expected to be an array
+ for (i = 0; (node = elem[i]); i++) {
+ // Do not traverse comment nodes
+ if (node.nodeType !== 8) {
+ ret += getText(node);
+ }
+ }
+ }
+ return ret;
+ };
+
+ var Expr = Sizzle.selectors = {
+ order : [ "ID", "NAME", "TAG" ],
+
+ match : {
+ ID : /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS : /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME : /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR : /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+ TAG : /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD : /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+ POS : /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO : /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch : {},
+
+ attrMap : {
+ "class" : "className",
+ "for" : "htmlFor"
+ },
+
+ attrHandle : {
+ href : function(elem) {
+ return elem.getAttribute("href");
+ },
+ type : function(elem) {
+ return elem.getAttribute("type");
+ }
+ },
+
+ relative : {
+ "+" : function(checkSet, part) {
+ var isPartStr = typeof part === "string", isTag = isPartStr
+ && !rNonWord.test(part), isPartStrNotTag = isPartStr
+ && !isTag;
+
+ if (isTag) {
+ part = part.toLowerCase();
+ }
+
+ for (var i = 0, l = checkSet.length, elem; i < l; i++) {
+ if ((elem = checkSet[i])) {
+ while ((elem = elem.previousSibling)
+ && elem.nodeType !== 1) {
+ }
+
+ checkSet[i] = isPartStrNotTag || elem
+ && elem.nodeName.toLowerCase() === part ? elem || false
+ : elem === part;
+ }
+ }
+
+ if (isPartStrNotTag) {
+ Sizzle.filter(part, checkSet, true);
+ }
+ },
+
+ ">" : function(checkSet, part) {
+ var elem, isPartStr = typeof part === "string", i = 0, l = checkSet.length;
+
+ if (isPartStr && !rNonWord.test(part)) {
+ part = part.toLowerCase();
+
+ for (; i < l; i++) {
+ elem = checkSet[i];
+
+ if (elem) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent
+ : false;
+ }
+ }
+
+ } else {
+ for (; i < l; i++) {
+ elem = checkSet[i];
+
+ if (elem) {
+ checkSet[i] = isPartStr ? elem.parentNode
+ : elem.parentNode === part;
+ }
+ }
+
+ if (isPartStr) {
+ Sizzle.filter(part, checkSet, true);
+ }
+ }
+ },
+
+ "" : function(checkSet, part, isXML) {
+ var nodeCheck, doneName = done++, checkFn = dirCheck;
+
+ if (typeof part === "string" && !rNonWord.test(part)) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck,
+ isXML);
+ },
+
+ "~" : function(checkSet, part, isXML) {
+ var nodeCheck, doneName = done++, checkFn = dirCheck;
+
+ if (typeof part === "string" && !rNonWord.test(part)) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet,
+ nodeCheck, isXML);
+ }
+ },
+
+ find : {
+ ID : function(match, context, isXML) {
+ if (typeof context.getElementById !== "undefined" && !isXML) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [ m ] : [];
+ }
+ },
+
+ NAME : function(match, context) {
+ if (typeof context.getElementsByName !== "undefined") {
+ var ret = [], results = context
+ .getElementsByName(match[1]);
+
+ for (var i = 0, l = results.length; i < l; i++) {
+ if (results[i].getAttribute("name") === match[1]) {
+ ret.push(results[i]);
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG : function(match, context) {
+ if (typeof context.getElementsByTagName !== "undefined") {
+ return context.getElementsByTagName(match[1]);
+ }
+ }
+ },
+ preFilter : {
+ CLASS : function(match, curLoop, inplace, result, not, isXML) {
+ match = " " + match[1].replace(rBackslash, "") + " ";
+
+ if (isXML) {
+ return match;
+ }
+
+ for (var i = 0, elem; (elem = curLoop[i]) != null; i++) {
+ if (elem) {
+ if (not
+ ^ (elem.className && (" " + elem.className + " ")
+ .replace(/[\t\n\r]/g, " ").indexOf(
+ match) >= 0)) {
+ if (!inplace) {
+ result.push(elem);
+ }
+
+ } else if (inplace) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID : function(match) {
+ return match[1].replace(rBackslash, "");
+ },
+
+ TAG : function(match, curLoop) {
+ return match[1].replace(rBackslash, "").toLowerCase();
+ },
+
+ CHILD : function(match) {
+ if (match[1] === "nth") {
+ if (!match[2]) {
+ Sizzle.error(match[0]);
+ }
+
+ match[2] = match[2].replace(/^\+|\s*/g, '');
+
+ // parse equations like 'even', 'odd', '5', '2n',
+ // '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/
+ .exec(match[2] === "even" && "2n"
+ || match[2] === "odd" && "2n+1"
+ || !/\D/.test(match[2]) && "0n+"
+ + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if
+ // they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ } else if (match[2]) {
+ Sizzle.error(match[0]);
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR : function(match, curLoop, inplace, result, not, isXML) {
+ var name = match[1] = match[1].replace(rBackslash, "");
+
+ if (!isXML && Expr.attrMap[name]) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ // Handle if an un-quoted value was used
+ match[4] = (match[4] || match[5] || "").replace(rBackslash,
+ "");
+
+ if (match[2] === "~=") {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO : function(match, curLoop, inplace, result, not) {
+ if (match[1] === "not") {
+ // If we're dealing with a complex expression, or a
+ // simple one
+ if ((chunker.exec(match[3]) || "").length > 1
+ || /^\w/.test(match[3])) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace,
+ true ^ not);
+
+ if (!inplace) {
+ result.push.apply(result, ret);
+ }
+
+ return false;
+ }
+
+ } else if (Expr.match.POS.test(match[0])
+ || Expr.match.CHILD.test(match[0])) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS : function(match) {
+ match.unshift(true);
+
+ return match;
+ }
+ },
+
+ filters : {
+ enabled : function(elem) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled : function(elem) {
+ return elem.disabled === true;
+ },
+
+ checked : function(elem) {
+ return elem.checked === true;
+ },
+
+ selected : function(elem) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if (elem.parentNode) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ parent : function(elem) {
+ return !!elem.firstChild;
+ },
+
+ empty : function(elem) {
+ return !elem.firstChild;
+ },
+
+ has : function(elem, i, match) {
+ return !!Sizzle(match[3], elem).length;
+ },
+
+ header : function(elem) {
+ return (/h\d/i).test(elem.nodeName);
+ },
+
+ text : function(elem) {
+ var attr = elem.getAttribute("type"), type = elem.type;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5
+ // types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input"
+ && "text" === type
+ && (attr === type || attr === null);
+ },
+
+ radio : function(elem) {
+ return elem.nodeName.toLowerCase() === "input"
+ && "radio" === elem.type;
+ },
+
+ checkbox : function(elem) {
+ return elem.nodeName.toLowerCase() === "input"
+ && "checkbox" === elem.type;
+ },
+
+ file : function(elem) {
+ return elem.nodeName.toLowerCase() === "input"
+ && "file" === elem.type;
+ },
+
+ password : function(elem) {
+ return elem.nodeName.toLowerCase() === "input"
+ && "password" === elem.type;
+ },
+
+ submit : function(elem) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button")
+ && "submit" === elem.type;
+ },
+
+ image : function(elem) {
+ return elem.nodeName.toLowerCase() === "input"
+ && "image" === elem.type;
+ },
+
+ reset : function(elem) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button")
+ && "reset" === elem.type;
+ },
+
+ button : function(elem) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && "button" === elem.type
+ || name === "button";
+ },
+
+ input : function(elem) {
+ return (/input|select|textarea|button/i)
+ .test(elem.nodeName);
+ },
+
+ focus : function(elem) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+ setFilters : {
+ first : function(elem, i) {
+ return i === 0;
+ },
+
+ last : function(elem, i, match, array) {
+ return i === array.length - 1;
+ },
+
+ even : function(elem, i) {
+ return i % 2 === 0;
+ },
+
+ odd : function(elem, i) {
+ return i % 2 === 1;
+ },
+
+ lt : function(elem, i, match) {
+ return i < match[3] - 0;
+ },
+
+ gt : function(elem, i, match) {
+ return i > match[3] - 0;
+ },
+
+ nth : function(elem, i, match) {
+ return match[3] - 0 === i;
+ },
+
+ eq : function(elem, i, match) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter : {
+ PSEUDO : function(elem, match, i, array) {
+ var name = match[1], filter = Expr.filters[name];
+
+ if (filter) {
+ return filter(elem, i, match, array);
+
+ } else if (name === "contains") {
+ return (elem.textContent || elem.innerText
+ || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if (name === "not") {
+ var not = match[3];
+
+ for (var j = 0, l = not.length; j < l; j++) {
+ if (not[j] === elem) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error(name);
+ }
+ },
+
+ CHILD : function(elem, match) {
+ var first, last, doneName, parent, cache, count, diff, type = match[1], node = elem;
+
+ switch (type) {
+ case "only":
+ case "first":
+ while ((node = node.previousSibling)) {
+ if (node.nodeType === 1) {
+ return false;
+ }
+ }
+
+ if (type === "first") {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ((node = node.nextSibling)) {
+ if (node.nodeType === 1) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ first = match[2];
+ last = match[3];
+
+ if (first === 1 && last === 0) {
+ return true;
+ }
+
+ doneName = match[0];
+ parent = elem.parentNode;
+
+ if (parent
+ && (parent[expando] !== doneName || !elem.nodeIndex)) {
+ count = 0;
+
+ for (node = parent.firstChild; node; node = node.nextSibling) {
+ if (node.nodeType === 1) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent[expando] = doneName;
+ }
+
+ diff = elem.nodeIndex - last;
+
+ if (first === 0) {
+ return diff === 0;
+
+ } else {
+ return (diff % first === 0 && diff / first >= 0);
+ }
+ }
+ },
+
+ ID : function(elem, match) {
+ return elem.nodeType === 1
+ && elem.getAttribute("id") === match;
+ },
+
+ TAG : function(elem, match) {
+ return (match === "*" && elem.nodeType === 1)
+ || !!elem.nodeName
+ && elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS : function(elem, match) {
+ return (" "
+ + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf(match) > -1;
+ },
+
+ ATTR : function(elem, match) {
+ var name = match[1], result = Sizzle.attr ? Sizzle.attr(
+ elem, name)
+ : Expr.attrHandle[name] ? Expr.attrHandle[name]
+ (elem) : elem[name] != null ? elem[name]
+ : elem.getAttribute(name), value = result
+ + "", type = match[2], check = match[4];
+
+ return result == null ? type === "!="
+ : !type && Sizzle.attr ? result != null
+ : type === "=" ? value === check
+ : type === "*=" ? value
+ .indexOf(check) >= 0
+ : type === "~=" ? (" "
+ + value + " ")
+ .indexOf(check) >= 0
+ : !check ? value
+ && result !== false
+ : type === "!=" ? value !== check
+ : type === "^=" ? value
+ .indexOf(check) === 0
+ : type === "$=" ? value
+ .substr(value.length
+ - check.length) === check
+ : type === "|=" ? value === check
+ || value
+ .substr(
+ 0,
+ check.length + 1) === check
+ + "-"
+ : false;
+ },
+
+ POS : function(elem, match, i, array) {
+ var name = match[2], filter = Expr.setFilters[name];
+
+ if (filter) {
+ return filter(elem, i, match, array);
+ }
+ }
+ }
+ };
+
+ var origPOS = Expr.match.POS, fescape = function(all, num) {
+ return "\\" + (num - 0 + 1);
+ };
+
+ for ( var type in Expr.match) {
+ Expr.match[type] = new RegExp(Expr.match[type].source
+ + (/(?![^\[]*\])(?![^\(]*\))/.source));
+ Expr.leftMatch[type] = new RegExp(/(^(?:.|\r|\n)*?)/.source
+ + Expr.match[type].source.replace(/\\(\d+)/g, fescape));
+ }
+
+ var makeArray = function(array, results) {
+ array = Array.prototype.slice.call(array, 0);
+
+ if (results) {
+ results.push.apply(results, array);
+ return results;
+ }
+
+ return array;
+ };
+
+ // Perform a simple check to determine if the browser is capable of
+ // converting a NodeList to an array using builtin methods.
+ // Also verifies that the returned array holds DOM nodes
+ // (which is not the case in the Blackberry browser)
+ try {
+ Array.prototype.slice.call(document.documentElement.childNodes, 0)[0].nodeType;
+
+ // Provide a fallback method if it does not work
+ } catch (e) {
+ makeArray = function(array, results) {
+ var i = 0, ret = results || [];
+
+ if (toString.call(array) === "[object Array]") {
+ Array.prototype.push.apply(ret, array);
+
+ } else {
+ if (typeof array.length === "number") {
+ for (var l = array.length; i < l; i++) {
+ ret.push(array[i]);
+ }
+
+ } else {
+ for (; array[i]; i++) {
+ ret.push(array[i]);
+ }
+ }
+ }
+
+ return ret;
+ };
+ }
+
+ var sortOrder, siblingCheck;
+
+ if (document.documentElement.compareDocumentPosition) {
+ sortOrder = function(a, b) {
+ if (a === b) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+ } else {
+ sortOrder = function(a, b) {
+ // The nodes are identical, we can exit early
+ if (a === b) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available
+ // on both nodes
+ } else if (a.sourceIndex && b.sourceIndex) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl, ap = [], bp = [], aup = a.parentNode, bup = b.parentNode, cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick
+ // check
+ if (aup === bup) {
+ return siblingCheck(a, b);
+
+ // If no parents were found then the nodes are disconnected
+ } else if (!aup) {
+ return -1;
+
+ } else if (!bup) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while (cur) {
+ ap.unshift(cur);
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while (cur) {
+ bp.unshift(cur);
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for (var i = 0; i < al && i < bl; i++) {
+ if (ap[i] !== bp[i]) {
+ return siblingCheck(ap[i], bp[i]);
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ? siblingCheck(a, bp[i], -1) : siblingCheck(
+ ap[i], b, 1);
+ };
+
+ siblingCheck = function(a, b, ret) {
+ if (a === b) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while (cur) {
+ if (cur === b) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+ }
+
+ // Check to see if the browser returns elements by name when
+ // querying by getElementById (and provide a workaround)
+ (function() {
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"), id = "script"
+ + (new Date()).getTime(), root = document.documentElement;
+
+ form.innerHTML = "";
+
+ // Inject it into the root element, check its status, and remove it
+ // quickly
+ root.insertBefore(form, root.firstChild);
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if (document.getElementById(id)) {
+ Expr.find.ID = function(match, context, isXML) {
+ if (typeof context.getElementById !== "undefined" && !isXML) {
+ var m = context.getElementById(match[1]);
+
+ return m ? m.id === match[1]
+ || typeof m.getAttributeNode !== "undefined"
+ && m.getAttributeNode("id").nodeValue === match[1] ? [ m ]
+ : undefined
+ : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match) {
+ var node = typeof elem.getAttributeNode !== "undefined"
+ && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node
+ && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild(form);
+
+ // release memory in IE
+ root = form = null;
+ })();
+
+ (function() {
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild(document.createComment(""));
+
+ // Make sure no comments are found
+ if (div.getElementsByTagName("*").length > 0) {
+ Expr.find.TAG = function(match, context) {
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if (match[1] === "*") {
+ var tmp = [];
+
+ for (var i = 0; results[i]; i++) {
+ if (results[i].nodeType === 1) {
+ tmp.push(results[i]);
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "";
+
+ if (div.firstChild
+ && typeof div.firstChild.getAttribute !== "undefined"
+ && div.firstChild.getAttribute("href") !== "#") {
+
+ Expr.attrHandle.href = function(elem) {
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+
+ if (document.querySelectorAll) {
+ (function() {
+ var oldSizzle = Sizzle, div = document.createElement("div"), id = "__sizzle__";
+
+ div.innerHTML = "";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if (div.querySelectorAll
+ && div.querySelectorAll(".TEST").length === 0) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed) {
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if (!seed && !Sizzle.isXML(context)) {
+ // See if we find a selector to speed up
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/
+ .exec(query);
+
+ if (match
+ && (context.nodeType === 1 || context.nodeType === 9)) {
+ // Speed-up: Sizzle("TAG")
+ if (match[1]) {
+ return makeArray(context
+ .getElementsByTagName(query), extra);
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if (match[2] && Expr.find.CLASS
+ && context.getElementsByClassName) {
+ return makeArray(context
+ .getElementsByClassName(match[2]),
+ extra);
+ }
+ }
+
+ if (context.nodeType === 9) {
+ // Speed-up: Sizzle("body")
+ // The body element only exists once, optimize
+ // finding it
+ if (query === "body" && context.body) {
+ return makeArray([ context.body ], extra);
+
+ // Speed-up: Sizzle("#ID")
+ } else if (match && match[3]) {
+ var elem = context.getElementById(match[3]);
+
+ // Check parentNode to catch when Blackberry 4.6
+ // returns
+ // nodes that are no longer in the document
+ // #6963
+ if (elem && elem.parentNode) {
+ // Handle the case where IE and Opera return
+ // items
+ // by name instead of ID
+ if (elem.id === match[3]) {
+ return makeArray([ elem ], extra);
+ }
+
+ } else {
+ return makeArray([], extra);
+ }
+ }
+
+ try {
+ return makeArray(context
+ .querySelectorAll(query), extra);
+ } catch (qsaError) {
+ }
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID
+ // on the root
+ // and working up from there (Thanks to Andrew
+ // Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if (context.nodeType === 1
+ && context.nodeName.toLowerCase() !== "object") {
+ var oldContext = context, old = context
+ .getAttribute("id"), nid = old || id, hasParent = context.parentNode, relativeHierarchySelector = /^\s*[+~]/
+ .test(query);
+
+ if (!old) {
+ context.setAttribute("id", nid);
+ } else {
+ nid = nid.replace(/'/g, "\\$&");
+ }
+ if (relativeHierarchySelector && hasParent) {
+ context = context.parentNode;
+ }
+
+ try {
+ if (!relativeHierarchySelector || hasParent) {
+ return makeArray(context
+ .querySelectorAll("[id='" + nid
+ + "'] " + query), extra);
+ }
+
+ } catch (pseudoError) {
+ } finally {
+ if (!old) {
+ oldContext.removeAttribute("id");
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle) {
+ Sizzle[prop] = oldSizzle[prop];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+ }
+
+ (function() {
+ var html = document.documentElement, matches = html.matchesSelector
+ || html.mozMatchesSelector || html.webkitMatchesSelector
+ || html.msMatchesSelector;
+
+ if (matches) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9 fails this)
+ var disconnectedMatch = !matches.call(document
+ .createElement("div"), "div"), pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call(document.documentElement, "[test!='']:sizzle");
+
+ } catch (pseudoError) {
+ pseudoWorks = true;
+ }
+
+ Sizzle.matchesSelector = function(node, expr) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if (!Sizzle.isXML(node)) {
+ try {
+ if (pseudoWorks || !Expr.match.PSEUDO.test(expr)
+ && !/!=/.test(expr)) {
+ var ret = matches.call(node, expr);
+
+ // IE 9's matchesSelector returns false on
+ // disconnected nodes
+ if (ret || !disconnectedMatch ||
+ // As well, disconnected nodes are said to be in
+ // a document
+ // fragment in IE 9, so check for that
+ node.document && node.document.nodeType !== 11) {
+ return ret;
+ }
+ }
+ } catch (e) {
+ }
+ }
+
+ return Sizzle(expr, null, null, [ node ]).length > 0;
+ };
+ }
+ })();
+
+ (function() {
+ var div = document.createElement("div");
+
+ div.innerHTML = "";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if (!div.getElementsByClassName
+ || div.getElementsByClassName("e").length === 0) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if (div.getElementsByClassName("e").length === 1) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if (typeof context.getElementsByClassName !== "undefined"
+ && !isXML) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+ })();
+
+ function dirNodeCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
+ for (var i = 0, l = checkSet.length; i < l; i++) {
+ var elem = checkSet[i];
+
+ if (elem) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while (elem) {
+ if (elem[expando] === doneName) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if (elem.nodeType === 1 && !isXML) {
+ elem[expando] = doneName;
+ elem.sizset = i;
+ }
+
+ if (elem.nodeName.toLowerCase() === cur) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+ }
+
+ function dirCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
+ for (var i = 0, l = checkSet.length; i < l; i++) {
+ var elem = checkSet[i];
+
+ if (elem) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while (elem) {
+ if (elem[expando] === doneName) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if (elem.nodeType === 1) {
+ if (!isXML) {
+ elem[expando] = doneName;
+ elem.sizset = i;
+ }
+
+ if (typeof cur !== "string") {
+ if (elem === cur) {
+ match = true;
+ break;
+ }
+
+ } else if (Sizzle.filter(cur, [ elem ]).length > 0) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+ }
+
+ if (document.documentElement.contains) {
+ Sizzle.contains = function(a, b) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+ } else if (document.documentElement.compareDocumentPosition) {
+ Sizzle.contains = function(a, b) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+ } else {
+ Sizzle.contains = function() {
+ return false;
+ };
+ }
+
+ Sizzle.isXML = function(elem) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML"
+ : false;
+ };
+
+ var posProcess = function(selector, context, seed) {
+ var match, tmpSet = [], later = "", root = context.nodeType ? [ context ]
+ : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ((match = Expr.match.PSEUDO.exec(selector))) {
+ later += match[0];
+ selector = selector.replace(Expr.match.PSEUDO, "");
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for (var i = 0, l = root.length; i < l; i++) {
+ Sizzle(selector, root[i], tmpSet, seed);
+ }
+
+ return Sizzle.filter(later, tmpSet);
+ };
+
+ // EXPOSE
+ // Override sizzle attribute retrieval
+ Sizzle.attr = jQuery.attr;
+ Sizzle.selectors.attrMap = {};
+ jQuery.find = Sizzle;
+ jQuery.expr = Sizzle.selectors;
+ jQuery.expr[":"] = jQuery.expr.filters;
+ jQuery.unique = Sizzle.uniqueSort;
+ jQuery.text = Sizzle.getText;
+ jQuery.isXMLDoc = Sizzle.isXML;
+ jQuery.contains = Sizzle.contains;
+
+ })();
+
+ var runtil = /Until$/, rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/, isSimple = /^.[^:#\[\.,]*$/, slice = Array.prototype.slice, POS = jQuery.expr.match.POS,
+ // methods guaranteed to produce a unique set when starting from a unique
+ // set
+ guaranteedUnique = {
+ children : true,
+ contents : true,
+ next : true,
+ prev : true
+ };
+
+ jQuery.fn
+ .extend({
+ find : function(selector) {
+ var self = this, i, l;
+
+ if (typeof selector !== "string") {
+ return jQuery(selector).filter(function() {
+ for (i = 0, l = self.length; i < l; i++) {
+ if (jQuery.contains(self[i], this)) {
+ return true;
+ }
+ }
+ });
+ }
+
+ var ret = this.pushStack("", "find", selector), length, n, r;
+
+ for (i = 0, l = this.length; i < l; i++) {
+ length = ret.length;
+ jQuery.find(selector, this[i], ret);
+
+ if (i > 0) {
+ // Make sure that the results are unique
+ for (n = length; n < ret.length; n++) {
+ for (r = 0; r < length; r++) {
+ if (ret[r] === ret[n]) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has : function(target) {
+ var targets = jQuery(target);
+ return this.filter(function() {
+ for (var i = 0, l = targets.length; i < l; i++) {
+ if (jQuery.contains(this, targets[i])) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not : function(selector) {
+ return this.pushStack(winnow(this, selector, false), "not",
+ selector);
+ },
+
+ filter : function(selector) {
+ return this.pushStack(winnow(this, selector, true),
+ "filter", selector);
+ },
+
+ is : function(selector) {
+ return !!selector
+ && (typeof selector === "string" ?
+ // If this is a positional selector, check
+ // membership in the returned set
+ // so $("p:first").is("p:last") won't return true
+ // for a doc with two "p".
+ POS.test(selector) ? jQuery(selector, this.context)
+ .index(this[0]) >= 0 : jQuery.filter(
+ selector, this).length > 0 : this
+ .filter(selector).length > 0);
+ },
+
+ closest : function(selectors, context) {
+ var ret = [], i, l, cur = this[0];
+
+ // Array (deprecated as of jQuery 1.7)
+ if (jQuery.isArray(selectors)) {
+ var level = 1;
+
+ while (cur && cur.ownerDocument && cur !== context) {
+ for (i = 0; i < selectors.length; i++) {
+
+ if (jQuery(cur).is(selectors[i])) {
+ ret.push({
+ selector : selectors[i],
+ elem : cur,
+ level : level
+ });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+
+ return ret;
+ }
+
+ // String
+ var pos = POS.test(selectors)
+ || typeof selectors !== "string" ? jQuery(
+ selectors, context || this.context) : 0;
+
+ for (i = 0, l = this.length; i < l; i++) {
+ cur = this[i];
+
+ while (cur) {
+ if (pos ? pos.index(cur) > -1 : jQuery.find
+ .matchesSelector(cur, selectors)) {
+ ret.push(cur);
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if (!cur || !cur.ownerDocument
+ || cur === context
+ || cur.nodeType === 11) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique(ret) : ret;
+
+ return this.pushStack(ret, "closest", selectors);
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index : function(elem) {
+
+ // No argument, return index in parent
+ if (!elem) {
+ return (this[0] && this[0].parentNode) ? this.prevAll().length
+ : -1;
+ }
+
+ // index in selector
+ if (typeof elem === "string") {
+ return jQuery.inArray(this[0], jQuery(elem));
+ }
+
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this);
+ },
+
+ add : function(selector, context) {
+ var set = typeof selector === "string" ? jQuery(selector,
+ context) : jQuery.makeArray(selector
+ && selector.nodeType ? [ selector ] : selector), all = jQuery
+ .merge(this.get(), set);
+
+ return this.pushStack(isDisconnected(set[0])
+ || isDisconnected(all[0]) ? all : jQuery
+ .unique(all));
+ },
+
+ andSelf : function() {
+ return this.add(this.prevObject);
+ }
+ });
+
+ // A painfully simple check to see if an element is disconnected
+ // from a document (should be improved, where feasible).
+ function isDisconnected(node) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+ }
+
+ jQuery.each({
+ parent : function(elem) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents : function(elem) {
+ return jQuery.dir(elem, "parentNode");
+ },
+ parentsUntil : function(elem, i, until) {
+ return jQuery.dir(elem, "parentNode", until);
+ },
+ next : function(elem) {
+ return jQuery.nth(elem, 2, "nextSibling");
+ },
+ prev : function(elem) {
+ return jQuery.nth(elem, 2, "previousSibling");
+ },
+ nextAll : function(elem) {
+ return jQuery.dir(elem, "nextSibling");
+ },
+ prevAll : function(elem) {
+ return jQuery.dir(elem, "previousSibling");
+ },
+ nextUntil : function(elem, i, until) {
+ return jQuery.dir(elem, "nextSibling", until);
+ },
+ prevUntil : function(elem, i, until) {
+ return jQuery.dir(elem, "previousSibling", until);
+ },
+ siblings : function(elem) {
+ return jQuery.sibling(elem.parentNode.firstChild, elem);
+ },
+ children : function(elem) {
+ return jQuery.sibling(elem.firstChild);
+ },
+ contents : function(elem) {
+ return jQuery.nodeName(elem, "iframe") ? elem.contentDocument
+ || elem.contentWindow.document : jQuery
+ .makeArray(elem.childNodes);
+ }
+ }, function(name, fn) {
+ jQuery.fn[name] = function(until, selector) {
+ var ret = jQuery.map(this, fn, until);
+
+ if (!runtil.test(name)) {
+ selector = until;
+ }
+
+ if (selector && typeof selector === "string") {
+ ret = jQuery.filter(selector, ret);
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[name] ? jQuery
+ .unique(ret) : ret;
+
+ if ((this.length > 1 || rmultiselector.test(selector))
+ && rparentsprev.test(name)) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack(ret, name, slice.call(arguments).join(","));
+ };
+ });
+
+ jQuery.extend({
+ filter : function(expr, elems, not) {
+ if (not) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ? jQuery.find.matchesSelector(elems[0],
+ expr) ? [ elems[0] ] : [] : jQuery.find
+ .matches(expr, elems);
+ },
+
+ dir : function(elem, dir, until) {
+ var matched = [], cur = elem[dir];
+
+ while (cur
+ && cur.nodeType !== 9
+ && (until === undefined || cur.nodeType !== 1 || !jQuery(
+ cur).is(until))) {
+ if (cur.nodeType === 1) {
+ matched.push(cur);
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth : function(cur, result, dir, elem) {
+ result = result || 1;
+ var num = 0;
+
+ for (; cur; cur = cur[dir]) {
+ if (cur.nodeType === 1 && ++num === result) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling : function(n, elem) {
+ var r = [];
+
+ for (; n; n = n.nextSibling) {
+ if (n.nodeType === 1 && n !== elem) {
+ r.push(n);
+ }
+ }
+
+ return r;
+ }
+ });
+
+ // Implement the identical functionality for filter and not
+ function winnow(elements, qualifier, keep) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if (jQuery.isFunction(qualifier)) {
+ return jQuery.grep(elements, function(elem, i) {
+ var retVal = !!qualifier.call(elem, i, elem);
+ return retVal === keep;
+ });
+
+ } else if (qualifier.nodeType) {
+ return jQuery.grep(elements, function(elem, i) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if (typeof qualifier === "string") {
+ var filtered = jQuery.grep(elements, function(elem) {
+ return elem.nodeType === 1;
+ });
+
+ if (isSimple.test(qualifier)) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter(qualifier, filtered);
+ }
+ }
+
+ return jQuery.grep(elements, function(elem, i) {
+ return (jQuery.inArray(elem, qualifier) >= 0) === keep;
+ });
+ }
+
+ function createSafeFragment(document) {
+ var list = nodeNames.split("|"), safeFrag = document
+ .createDocumentFragment();
+
+ if (safeFrag.createElement) {
+ while (list.length) {
+ safeFrag.createElement(list.pop());
+ }
+ }
+ return safeFrag;
+ }
+
+ var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|"
+ + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, rtagName = /<([\w:]+)/, rtbody = /", "" ],
+ legend : [ 1, "" ],
+ thead : [ 1, "