点击文字显示,点击文字隐藏(2)

简介: 点击文字显示,点击文字隐藏
" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + 
      // Operator (capture 2) 
      "*([*^$|!~]?=)" + whitespace + 
      // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 
      "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 
      "*\\]", 
    pseudos = ":(" + characterEncoding + ")(?:\\((" + 
      // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 
      // 1. quoted (capture 3; capture 4 or capture 5) 
      "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 
      // 2. simple (capture 6) 
      "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 
      // 3. anything else (capture 2) 
      ".*" + 
      ")\\)|)", 
    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 
    rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 
    rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 
    rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 
    rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), 
    rpseudo = new RegExp( pseudos ), 
    ridentifier = new RegExp( "^" + identifier + "$" ), 
    matchExpr = { 
      "ID": new RegExp( "^#(" + characterEncoding + ")" ), 
      "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), 
      "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), 
      "ATTR": new RegExp( "^" + attributes ), 
      "PSEUDO": new RegExp( "^" + pseudos ), 
      "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 
        "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 
        "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 
      "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 
      // For use in libraries implementing .is() 
      // We use this for POS matching in `select` 
      "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 
        whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 
    }, 
    rinputs = /^(?:input|select|textarea|button)$/i, 
    rheader = /^h\d$/i, 
    rnative = /^[^{]+\{\s*\[native \w/, 
    // Easily-parseable/retrievable ID or TAG or CLASS selectors 
    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 
    rsibling = /[+~]/, 
    rescape = /'|\\/g, 
    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 
    runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 
    funescape = function( _, escaped, escapedWhitespace ) { 
      var high = "0x" + escaped - 0x10000; 
      // NaN means non-codepoint 
      // Support: Firefox<24 
      // Workaround erroneous numeric interpretation of +"0x" 
      return high !== high || escapedWhitespace ? 
        escaped : 
        high < 0 ? 
          // BMP codepoint 
          String.fromCharCode( high + 0x10000 ) : 
          // Supplemental Plane codepoint (surrogate pair) 
          String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 
    }; 
  // Optimize for push.apply( _, NodeList ) 
  try { 
    push.apply( 
      (arr = slice.call( preferredDoc.childNodes )), 
      preferredDoc.childNodes 
    ); 
    // Support: Android<4.0 
    // Detect silently failing push.apply 
    arr[ preferredDoc.childNodes.length ].nodeType; 
  } catch ( e ) { 
    push = { apply: arr.length ? 
      // Leverage slice if possible 
      function( target, els ) { 
        push_native.apply( target, slice.call(els) ); 
      } : 
      // Support: IE<9 
      // Otherwise append directly 
      function( target, els ) { 
        var j = target.length, 
          i = 0; 
        // Can't trust NodeList.length 
        while ( (target[j++] = els[i++]) ) {} 
        target.length = j - 1; 
      } 
    }; 
  } 
  function Sizzle( selector, context, results, seed ) { 
    var match, elem, m, nodeType, 
      // QSA vars 
      i, groups, old, nid, newContext, newSelector; 
    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 
      setDocument( context ); 
    } 
    context = context || document; 
    results = results || []; 
    if ( !selector || typeof selector !== "string" ) { 
      return results; 
    } 
    if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { 
      return []; 
    } 
    if ( documentIsHTML && !seed ) { 
      // Shortcuts 
      if ( (match = rquickExpr.exec( selector )) ) { 
        // Speed-up: Sizzle("#ID") 
        if ( (m = match[1]) ) { 
          if ( nodeType === 9 ) { 
            elem = context.getElementById( m ); 
            // Check parentNode to catch when Blackberry 4.6 returns 
            // nodes that are no longer in the document (jQuery #6963) 
            if ( elem && elem.parentNode ) { 
              // Handle the case where IE, Opera, and Webkit return items 
              // by name instead of ID 
              if ( elem.id === m ) { 
                results.push( elem ); 
                return results; 
              } 
            } else { 
              return results; 
            } 
          } else { 
            // Context is not a document 
            if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && 
              contains( context, elem ) && elem.id === m ) { 
              results.push( elem ); 
              return results; 
            } 
          } 
        // Speed-up: Sizzle("TAG") 
        } else if ( match[2] ) { 
          push.apply( results, context.getElementsByTagName( selector ) ); 
          return results; 
        // Speed-up: Sizzle(".CLASS") 
        } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { 
          push.apply( results, context.getElementsByClassName( m ) ); 
          return results; 
        } 
      } 
      // QSA path 
      if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { 
        nid = old = expando; 
        newContext = context; 
        newSelector = nodeType === 9 && selector; 
        // 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 
        if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 
          groups = tokenize( selector ); 
          if ( (old = context.getAttribute("id")) ) { 
            nid = old.replace( rescape, "\\$&" ); 
          } else { 
            context.setAttribute( "id", nid ); 
          } 
          nid = "[id='" + nid + "'] "; 
          i = groups.length; 
          while ( i-- ) { 
            groups[i] = nid + toSelector( groups[i] ); 
          } 
          newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; 
          newSelector = groups.join(","); 
        } 
        if ( newSelector ) { 
          try { 
            push.apply( results, 
              newContext.querySelectorAll( newSelector ) 
            ); 
            return results; 
          } catch(qsaError) { 
          } finally { 
            if ( !old ) { 
              context.removeAttribute("id"); 
            } 
          } 
        } 
      } 
    } 
    // All others 
    return select( selector.replace( rtrim, "$1" ), context, results, seed ); 
  } 
  /** 
   * Create key-value caches of limited size 
   * @returns {Function(string, Object)} Returns the Object data after storing it on itself with 
   *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 
   *  deleting the oldest entry 
   */ 
  function createCache() { 
    var keys = []; 
    function cache( key, value ) { 
      // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 
      if ( keys.push( key + " " ) > Expr.cacheLength ) { 
        // Only keep the most recent entries 
        delete cache[ keys.shift() ]; 
      } 
      return (cache[ key + " " ] = value); 
    } 
    return cache; 
  } 
  /** 
   * Mark a function for special use by Sizzle 
   * @param {Function} fn The function to mark 
   */ 
  function markFunction( fn ) { 
    fn[ expando ] = true; 
    return fn; 
  } 
  /** 
   * Support testing using an element 
   * @param {Function} fn Passed the created div and expects a boolean result 
   */ 
  function assert( fn ) { 
    var div = document.createElement("div"); 
    try { 
      return !!fn( div ); 
    } catch (e) { 
      return false; 
    } finally { 
      // Remove from its parent by default 
      if ( div.parentNode ) { 
        div.parentNode.removeChild( div ); 
      } 
      // release memory in IE 
      div = null; 
    } 
  } 
  /** 
   * Adds the same handler for all of the specified attrs 
   * @param {String} attrs Pipe-separated list of attributes 
   * @param {Function} handler The method that will be applied 
   */ 
  function addHandle( attrs, handler ) { 
    var arr = attrs.split("|"), 
      i = attrs.length; 
    while ( i-- ) { 
      Expr.attrHandle[ arr[i] ] = handler; 
    } 
  } 
  /** 
   * Checks document order of two siblings 
   * @param {Element} a 
   * @param {Element} b 
   * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 
   */ 
  function siblingCheck( a, b ) { 
    var cur = b && a, 
      diff = cur && a.nodeType === 1 && b.nodeType === 1 && 
        ( ~b.sourceIndex || MAX_NEGATIVE ) - 
        ( ~a.sourceIndex || MAX_NEGATIVE ); 
    // Use IE sourceIndex if available on both nodes 
    if ( diff ) { 
      return diff; 
    } 
    // Check if b follows a 
    if ( cur ) { 
      while ( (cur = cur.nextSibling) ) { 
        if ( cur === b ) { 
          return -1; 
        } 
      } 
    } 
    return a ? 1 : -1; 
  } 
  /** 
   * Returns a function to use in pseudos for input types 
   * @param {String} type 
   */ 
  function createInputPseudo( type ) { 
    return function( elem ) { 
      var name = elem.nodeName.toLowerCase(); 
      return name === "input" && elem.type === type; 
    }; 
  } 
  /** 
   * Returns a function to use in pseudos for buttons 
   * @param {String} type 
   */ 
  function createButtonPseudo( type ) { 
    return function( elem ) { 
      var name = elem.nodeName.toLowerCase(); 
      return (name === "input" || name === "button") && elem.type === type; 
    }; 
  } 
  /** 
   * Returns a function to use in pseudos for positionals 
   * @param {Function} fn 
   */ 
  function createPositionalPseudo( fn ) { 
    return markFunction(function( argument ) { 
      argument = +argument; 
      return markFunction(function( seed, matches ) { 
        var j, 
          matchIndexes = fn( [], seed.length, argument ), 
          i = matchIndexes.length; 
        // Match elements found at the specified indexes 
        while ( i-- ) { 
          if ( seed[ (j = matchIndexes[i]) ] ) { 
            seed[j] = !(matches[j] = seed[j]); 
          } 
        } 
      }); 
    }); 
  } 
  /** 
   * Checks a node for validity as a Sizzle context 
   * @param {Element|Object=} context 
   * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 
   */ 
  function testContext( context ) { 
    return context && typeof context.getElementsByTagName !== strundefined && context; 
  } 
  // Expose support vars for convenience 
  support = Sizzle.support = {}; 
  /** 
   * Detects XML nodes 
   * @param {Element|Object} elem An element or a document 
   * @returns {Boolean} True iff elem is a non-HTML XML node 
   */ 
  isXML = 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).documentElement; 
    return documentElement ? documentElement.nodeName !== "HTML" : false; 
  }; 
  /** 
   * Sets document-related variables once based on the current document 
   * @param {Element|Object} [doc] An element or document object to use to set the document 
   * @returns {Object} Returns the current document 
   */ 
  setDocument = Sizzle.setDocument = function( node ) { 
    var hasCompare, 
      doc = node ? node.ownerDocument || node : preferredDoc, 
      parent = doc.defaultView; 
    // If no document and documentElement is available, return 
    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 
      return document; 
    } 
    // Set our document 
    document = doc; 
    docElem = doc.documentElement; 
    // Support tests 
    documentIsHTML = !isXML( doc ); 
    // Support: IE>8 
    // If iframe document is assigned to "document" variable and if iframe has been reloaded, 
    // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 
    // IE6-8 do not support the defaultView property so parent will be undefined 
    if ( parent && parent !== parent.top ) { 
      // IE11 does not have attachEvent, so all must suffer 
      if ( parent.addEventListener ) { 
        parent.addEventListener( "unload", function() { 
          setDocument(); 
        }, false ); 
      } else if ( parent.attachEvent ) { 
        parent.attachEvent( "onunload", function() { 
          setDocument(); 
        }); 
      } 
    } 
    /* Attributes 
    ---------------------------------------------------------------------- */ 
    // Support: IE<8 
    // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) 
    support.attributes = assert(function( div ) { 
      div.className = "i"; 
      return !div.getAttribute("className"); 
    }); 
    /* getElement(s)By* 
    ---------------------------------------------------------------------- */ 
    // Check if getElementsByTagName("*") returns only elements 
    support.getElementsByTagName = assert(function( div ) { 
      div.appendChild( doc.createComment("") ); 
      return !div.getElementsByTagName("*").length; 
    }); 
    // Check if getElementsByClassName can be trusted 
    support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { 
      div.innerHTML = "<div class='a'></div><div class='a i'></div>"; 
      // Support: Safari<4 
      // Catch class over-caching 
      div.firstChild.className = "i"; 
      // Support: Opera<10 
      // Catch gEBCN failure to find non-leading classes 
      return div.getElementsByClassName("i").length === 2; 
    }); 
    // Support: IE<10 
    // Check if getElementById returns elements by name 
    // The broken getElementById methods don't pick up programatically-set names, 
    // so use a roundabout getElementsByName test 
    support.getById = assert(function( div ) { 
      docElem.appendChild( div ).id = expando; 
      return !doc.getElementsByName || !doc.getElementsByName( expando ).length; 
    }); 
    // ID find and filter 
    if ( support.getById ) { 
      Expr.find["ID"] = function( id, context ) { 
        if ( typeof context.getElementById !== strundefined && documentIsHTML ) { 
          var m = context.getElementById( id ); 
          // Check parentNode to catch when Blackberry 4.6 returns 
          // nodes that are no longer in the document #6963 
          return m && m.parentNode ? [ m ] : []; 
        } 
      }; 
      Expr.filter["ID"] = function( id ) { 
        var attrId = id.replace( runescape, funescape ); 
        return function( elem ) { 
          return elem.getAttribute("id") === attrId; 
        }; 
      }; 
    } else { 
      // Support: IE6/7 
      // getElementById is not reliable as a find shortcut 
      delete Expr.find["ID"]; 
      Expr.filter["ID"] =  function( id ) { 
        var attrId = id.replace( runescape, funescape ); 
        return function( elem ) { 
          var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); 
          return node && node.value === attrId; 
        }; 
      }; 
    } 
    // Tag 
    Expr.find["TAG"] = support.getElementsByTagName ? 
      function( tag, context ) { 
        if ( typeof context.getElementsByTagName !== strundefined ) { 
          return context.getElementsByTagName( tag ); 
        } 
      } : 
      function( tag, context ) { 
        var elem, 
          tmp = [], 
          i = 0, 
          results = context.getElementsByTagName( tag ); 
        // Filter out possible comments 
        if ( tag === "*" ) { 
          while ( (elem = results[i++]) ) { 
            if ( elem.nodeType === 1 ) { 
              tmp.push( elem ); 
            } 
          } 
          return tmp; 
        } 
        return results; 
      }; 
    // Class 
    Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 
      if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { 
        return context.getElementsByClassName( className ); 
      } 
    }; 
    /* QSA/matchesSelector 
    ---------------------------------------------------------------------- */ 
    // QSA and matchesSelector support 
    // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 
    rbuggyMatches = []; 
    // qSa(:focus) reports false when true (Chrome 21) 
    // We allow this because of a bug in IE8/9 that throws an error 
    // whenever `document.activeElement` is accessed on an iframe 
    // So, we allow :focus to pass through QSA all the time to avoid the IE error 
    // See http://bugs.jquery.com/ticket/13378 
    rbuggyQSA = []; 
    if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { 
      // Build QSA regex 
      // Regex strategy adopted from Diego Perini 
      assert(function( div ) { 
        // Select is set to empty string on purpose 
        // This is to test IE's treatment of not explicitly 
        // setting a boolean content attribute, 
        // since its presence should be enough 
        // http://bugs.jquery.com/ticket/12359 
        div.innerHTML = "<select msallowclip=''><option selected=''></option></select>"; 
        // Support: IE8, Opera 11-12.16 
        // Nothing should be selected when empty strings follow ^= or $= or *= 
        // The test attribute must be unknown in Opera but "safe" for WinRT 
        // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 
        if ( div.querySelectorAll("[msallowclip^='']").length ) { 
          rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 
        } 
        // Support: IE8 
        // Boolean attributes and "value" are not treated correctly 
        if ( !div.querySelectorAll("[selected]").length ) { 
          rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 
        } 
        // Webkit/Opera - :checked should return selected option elements 
        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 
        // IE8 throws error here and will not see later tests 
        if ( !div.querySelectorAll(":checked").length ) { 
          rbuggyQSA.push(":checked"); 
        } 
      }); 
      assert(function( div ) { 
        // Support: Windows 8 Native Apps 
        // The type and name attributes are restricted during .innerHTML assignment 
        var input = doc.createElement("input"); 
        input.setAttribute( "type", "hidden" ); 
        div.appendChild( input ).setAttribute( "name", "D" ); 
        // Support: IE8 
        // Enforce case-sensitivity of name attribute 
        if ( div.querySelectorAll("[name=d]").length ) { 
          rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 
        } 
        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 
        // IE8 throws error here and will not see later tests 
        if ( !div.querySelectorAll(":enabled").length ) { 
          rbuggyQSA.push( ":enabled", ":disabled" ); 
        } 
        // Opera 10-11 does not throw on post-comma invalid pseudos 
        div.querySelectorAll("*,:x"); 
        rbuggyQSA.push(",.*:"); 
      }); 
    } 
    if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 
      docElem.webkitMatchesSelector || 
      docElem.mozMatchesSelector || 
      docElem.oMatchesSelector || 
      docElem.msMatchesSelector) )) ) { 
      assert(function( div ) { 
        // Check to see if it's possible to do matchesSelector 
        // on a disconnected node (IE 9) 
        support.disconnectedMatch = matches.call( div, "div" ); 
        // This should fail with an exception 
        // Gecko does not error, returns false instead 
        matches.call( div, "[s!='']:x" ); 
        rbuggyMatches.push( "!=", pseudos ); 
      }); 
    } 
    rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 
    rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 
    /* Contains 
    ---------------------------------------------------------------------- */ 
    hasCompare = rnative.test( docElem.compareDocumentPosition ); 
    // Element contains another 
    // Purposefully does not implement inclusive descendent 
    // As in, an element does not contain itself 
    contains = hasCompare || rnative.test( docElem.contains ) ? 
      function( a, b ) { 
        var adown = a.nodeType === 9 ? a.documentElement : a, 
          bup = b && b.parentNode; 
        return a === bup || !!( bup && bup.nodeType === 1 && ( 
          adown.contains ? 
            adown.contains( bup ) : 
            a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 
        )); 
      } : 
      function( a, b ) { 
        if ( b ) { 
          while ( (b = b.parentNode) ) { 
            if ( b === a ) { 
              return true; 
            } 
          } 
        } 
        return false; 
      }; 
    /* Sorting 
    ---------------------------------------------------------------------- */ 
    // Document order sorting 
    sortOrder = hasCompare ? 
    function( a, b ) { 
      // Flag for duplicate removal 
      if ( a === b ) { 
        hasDuplicate = true; 
        return 0; 
      } 
      // Sort on method existence if only one input has compareDocumentPosition 
      var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 
      if ( compare ) { 
        return compare; 
      } 
      // Calculate position if both inputs belong to the same document 
      compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 
        a.compareDocumentPosition( b ) : 
        // Otherwise we know they are disconnected 
        1; 
      // Disconnected nodes 
      if ( compare & 1 || 
        (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 
        // Choose the first element that is related to our preferred document 
        if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 
          return -1; 
        } 
        if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 
          return 1; 
        } 
        // Maintain original order 
        return sortInput ? 
          ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 
          0; 
      } 
      return compare & 4 ? -1 : 1; 
    } : 
    function( a, b ) { 
      // Exit early if the nodes are identical 
      if ( a === b ) { 
        hasDuplicate = true; 
        return 0; 
      } 
      var cur, 
        i = 0, 
        aup = a.parentNode, 
        bup = b.parentNode, 
        ap = [ a ], 
        bp = [ b ]; 
      // Parentless nodes are either documents or disconnected 
      if ( !aup || !bup ) { 
        return a === doc ? -1 : 
          b === doc ? 1 : 
          aup ? -1 : 
          bup ? 1 : 
          sortInput ? 
          ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 
          0; 
      // If the nodes are siblings, we can do a quick check 
      } else if ( aup === bup ) { 
        return siblingCheck( a, b ); 
      } 
      // Otherwise we need full lists of their ancestors for comparison 
      cur = a; 
      while ( (cur = cur.parentNode) ) { 
        ap.unshift( cur ); 
      } 
      cur = b; 
      while ( (cur = cur.parentNode) ) { 
        bp.unshift( cur ); 
      } 
      // Walk down the tree looking for a discrepancy 
      while ( ap[i] === bp[i] ) { 
        i++; 
      } 
      return i ? 
        // Do a sibling check if the nodes have a common ancestor 
        siblingCheck( ap[i], bp[i] ) : 
        // Otherwise nodes in our document sort first 
        ap[i] === preferredDoc ? -1 : 
        bp[i] === preferredDoc ? 1 : 
        0; 
    }; 
    return doc; 
  }; 
  Sizzle.matches = function( expr, elements ) { 
    return Sizzle( expr, null, null, elements ); 
  }; 
  Sizzle.matchesSelector = function( elem, expr ) { 
    // Set document vars if needed 
    if ( ( elem.ownerDocument || elem ) !== document ) { 
      setDocument( elem ); 
    } 
    // Make sure that attribute selectors are quoted 
    expr = expr.replace( rattributeQuotes, "='$1']" ); 
    if ( support.matchesSelector && documentIsHTML && 
      ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 
      ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) { 
      try { 
        var ret = matches.call( elem, expr ); 
        // IE 9's matchesSelector returns false on disconnected nodes 
        if ( ret || support.disconnectedMatch || 
            // As well, disconnected nodes are said to be in a document 
            // fragment in IE 9 
            elem.document && elem.document.nodeType !== 11 ) { 
          return ret; 
        } 
      } catch(e) {} 
    } 
    return Sizzle( expr, document, null, [ elem ] ).length > 0; 
  }; 
  Sizzle.contains = function( context, elem ) { 
    // Set document vars if needed 
    if ( ( context.ownerDocument || context ) !== document ) { 
      setDocument( context ); 
    } 
    return contains( context, elem ); 
  }; 
  Sizzle.attr = function( elem, name ) { 
    // Set document vars if needed 
    if ( ( elem.ownerDocument || elem ) !== document ) { 
      setDocument( elem ); 
    } 
    var fn = Expr.attrHandle[ name.toLowerCase() ], 
      // Don't get fooled by Object.prototype properties (jQuery #13807) 
      val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 
        fn( elem, name, !documentIsHTML ) : 
        undefined; 
    return val !== undefined ? 
      val : 
      support.attributes || !documentIsHTML ? 
        elem.getAttribute( name ) : 
        (val = elem.getAttributeNode(name)) && val.specified ? 
          val.value : 
          null; 
  }; 
  Sizzle.error = function( msg ) { 
    throw new Error( "Syntax error, unrecognized expression: " + msg ); 
  }; 
  /** 
   * Document sorting and removing duplicates 
   * @param {ArrayLike} results 
   */ 
  Sizzle.uniqueSort = function( results ) { 
    var elem, 
      duplicates = [], 
      j = 0, 
      i = 0; 
    // Unless we *know* we can detect duplicates, assume their presence 
    hasDuplicate = !support.detectDuplicates; 
    sortInput = !support.sortStable && results.slice( 0 ); 
    results.sort( sortOrder ); 
    if ( hasDuplicate ) { 
      while ( (elem = results[i++]) ) { 
        if ( elem === results[ i ] ) { 
          j = duplicates.push( i ); 
        } 
      } 
      while ( j-- ) { 
        results.splice( duplicates[ j ], 1 ); 
      } 
    } 
    // Clear input after sorting to release objects 
    // See https://github.com/jquery/sizzle/pull/225 
    sortInput = null; 
    return results; 
  }; 
  /** 
   * Utility function for retrieving the text value of an array of DOM nodes 
   * @param {Array|Element} elem 
   */ 
  getText = Sizzle.getText = function( elem ) { 
    var node, 
      ret = "", 
      i = 0, 
      nodeType = elem.nodeType; 
    if ( !nodeType ) { 
      // If no nodeType, this is expected to be an array 
      while ( (node = elem[i++]) ) { 
        // Do not traverse comment nodes 
        ret += getText( node ); 
      } 
    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 
      // Use textContent for elements 
      // innerText usage removed for consistency of new lines (jQuery #11153) 
      if ( typeof elem.textContent === "string" ) { 
        return elem.textContent; 
      } else { 
        // Traverse its children 
        for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 
          ret += getText( elem ); 
        } 
      } 
    } else if ( nodeType === 3 || nodeType === 4 ) { 
      return elem.nodeValue; 
    } 
    // Do not include comment or processing instruction nodes 
    return ret; 
  }; 
  Expr = Sizzle.selectors = { 
    // Can be adjusted by the user 
    cacheLength: 50, 
    createPseudo: markFunction, 
    match: matchExpr, 
    attrHandle: {}, 
    find: {}, 
    relative: { 
      ">": { dir: "parentNode", first: true }, 
      " ": { dir: "parentNode" }, 
      "+": { dir: "previousSibling", first: true }, 
      "~": { dir: "previousSibling" } 
    }, 
    preFilter: { 
      "ATTR": function( match ) { 
        match[1] = match[1].replace( runescape, funescape ); 
        // Move the given value to match[3] whether quoted or unquoted 
        match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 
        if ( match[2] === "~=" ) { 
          match[3] = " " + match[3] + " "; 
        } 
        return match.slice( 0, 4 ); 
      }, 
      "CHILD": function( match ) { 
        /* matches from matchExpr["CHILD"] 
          1 type (only|nth|...) 
          2 what (child|of-type) 
          3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 
          4 xn-component of xn+y argument ([+-]?\d*n|) 
          5 sign of xn-component 
          6 x of xn-component 
          7 sign of y-component 
          8 y of y-component 
        */ 
        match[1] = match[1].toLowerCase(); 
        if ( match[1].slice( 0, 3 ) === "nth" ) { 
          // nth-* requires argument 
          if ( !match[3] ) { 
            Sizzle.error( match[0] ); 
          } 
          // numeric x and y parameters for Expr.filter.CHILD 
          // remember that false/true cast respectively to 0/1 
          match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 
          match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 
        // other types prohibit arguments 
        } else if ( match[3] ) { 
          Sizzle.error( match[0] ); 
        } 
        return match; 
      }, 
      "PSEUDO": function( match ) { 
        var excess, 
          unquoted = !match[6] && match[2]; 
        if ( matchExpr["CHILD"].test( match[0] ) ) { 
          return null; 
        } 
        // Accept quoted arguments as-is 
        if ( match[3] ) { 
          match[2] = match[4] || match[5] || ""; 
        // Strip excess characters from unquoted arguments 
        } else if ( unquoted && rpseudo.test( unquoted ) && 
          // Get excess from tokenize (recursively) 
          (excess = tokenize( unquoted, true )) && 
          // advance to the next closing parenthesis 
          (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 
          // excess is a negative index 
          match[0] = match[0].slice( 0, excess ); 
          match[2] = unquoted.slice( 0, excess ); 
        } 
        // Return only captures needed by the pseudo filter method (type and argument) 
        return match.slice( 0, 3 ); 
      } 
    }, 
    filter: { 
      "TAG": function( nodeNameSelector ) { 
        var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 
        return nodeNameSelector === "*" ? 
          function() { return true; } : 
          function( elem ) { 
            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 
          }; 
      }, 
      "CLASS": function( className ) { 
        var pattern = classCache[ className + " " ]; 
        return pattern || 
          (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 
          classCache( className, function( elem ) { 
            return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); 
          }); 
      }, 
      "ATTR": function( name, operator, check ) { 
        return function( elem ) { 
          var result = Sizzle.attr( elem, name ); 
          if ( result == null ) { 
            return operator === "!="; 
          } 
          if ( !operator ) { 
            return true; 
          } 
          result += ""; 
          return operator === "=" ? result === check : 
            operator === "!=" ? result !== check : 
            operator === "^=" ? check && result.indexOf( check ) === 0 : 
            operator === "*=" ? check && result.indexOf( check ) > -1 : 
            operator === "$=" ? check && result.slice( -check.length ) === check : 
            operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : 
            operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 
            false; 
        }; 
      }, 
      "CHILD": function( type, what, argument, first, last ) { 
        var simple = type.slice( 0, 3 ) !== "nth", 
          forward = type.slice( -4 ) !== "last", 
          ofType = what === "of-type"; 
        return first === 1 && last === 0 ? 
          // Shortcut for :nth-*(n) 
          function( elem ) { 
            return !!elem.parentNode; 
          } : 
          function( elem, context, xml ) { 
            var cache, outerCache, node, diff, nodeIndex, start, 
              dir = simple !== forward ? "nextSibling" : "previousSibling", 
              parent = elem.parentNode, 
              name = ofType && elem.nodeName.toLowerCase(), 
              useCache = !xml && !ofType; 
            if ( parent ) { 
              // :(first|last|only)-(child|of-type) 
              if ( simple ) { 
                while ( dir ) { 
                  node = elem; 
                  while ( (node = node[ dir ]) ) { 
                    if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { 
                      return false; 
                    } 
                  } 
                  // Reverse direction for :only-* (if we haven't yet done so) 
                  start = dir = type === "only" && !start && "nextSibling"; 
                } 
                return true; 
              } 
              start = [ forward ? parent.firstChild : parent.lastChild ]; 
              // non-xml :nth-child(...) stores cache data on `parent` 
              if ( forward && useCache ) { 
                // Seek `elem` from a previously-cached index 
                outerCache = parent[ expando ] || (parent[ expando ] = {}); 
                cache = outerCache[ type ] || []; 
                nodeIndex = cache[0] === dirruns && cache[1]; 
                diff = cache[0] === dirruns && cache[2]; 
                node = nodeIndex && parent.childNodes[ nodeIndex ]; 
                while ( (node = ++nodeIndex && node && node[ dir ] || 
                  // Fallback to seeking `elem` from the start 
                  (diff = nodeIndex = 0) || start.pop()) ) { 
                  // When found, cache indexes on `parent` and break 
                  if ( node.nodeType === 1 && ++diff && node === elem ) { 
                    outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 
                    break; 
                  } 
                } 
              // Use previously-cached element index if available 
              } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { 
                diff = cache[1]; 
              // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) 
              } else { 
                // Use the same loop as above to seek `elem` from the start 
                while ( (node = ++nodeIndex && node && node[ dir ] || 
                  (diff = nodeIndex = 0) || start.pop()) ) { 
                  if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { 
                    // Cache the index of each encountered element 
                    if ( useCache ) { 
                      (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; 
                    } 
                    if ( node === elem ) { 
                      break; 
                    } 
                  } 
                } 
              } 
              // Incorporate the offset, then check against cycle size 
              diff -= last; 
              return diff === first || ( diff % first === 0 && diff / first >= 0 ); 
            } 
          }; 
      }, 
      "PSEUDO": function( pseudo, argument ) { 
        // pseudo-class names are case-insensitive 
        // http://www.w3.org/TR/selectors/#pseudo-classes 
        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 
        // Remember that setFilters inherits from pseudos 
        var args, 
          fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 
            Sizzle.error( "unsupported pseudo: " + pseudo ); 
        // The user may use createPseudo to indicate that 
        // arguments are needed to create the filter function 
        // just as Sizzle does 
        if ( fn[ expando ] ) { 
          return fn( argument ); 
        } 
        // But maintain support for old signatures 
        if ( fn.length > 1 ) { 
          args = [ pseudo, pseudo, "", argument ]; 
          return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 
            markFunction(function( seed, matches ) { 
              var idx, 
                matched = fn( seed, argument ), 
                i = matched.length; 
              while ( i-- ) { 
                idx = indexOf.call( seed, matched[i] ); 
                seed[ idx ] = !( matches[ idx ] = matched[i] ); 
              } 
            }) : 
            function( elem ) { 
              return fn( elem, 0, args ); 
            }; 
        } 
        return fn; 
      } 
    }, 
    pseudos: { 
      // Potentially complex pseudos 
      "not": markFunction(function( selector ) { 
        // Trim the selector passed to compile 
        // to avoid treating leading and trailing 
        // spaces as combinators 
        var input = [], 
          results = [], 
          matcher = compile( selector.replace( rtrim, "$1" ) ); 
        return matcher[ expando ] ? 
          markFunction(function( seed, matches, context, xml ) { 
            var elem, 
              unmatched = matcher( seed, null, xml, [] ), 
              i = seed.length; 
            // Match elements unmatched by `matcher` 
            while ( i-- ) { 
              if ( (elem = unmatched[i]) ) { 
                seed[i] = !(matches[i] = elem); 
              } 
            } 
          }) : 
          function( elem, context, xml ) { 
            input[0] = elem; 
            matcher( input, null, xml, results ); 
            return !results.pop(); 
          }; 
      }), 
      "has": markFunction(function( selector ) { 
        return function( elem ) { 
          return Sizzle( selector, elem ).length > 0; 
        }; 
      }), 
      "contains": markFunction(function( text ) { 
        return function( elem ) { 
          return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 
        }; 
      }), 
      // "Whether an element is represented by a :lang() selector 
      // is based solely on the element's language value 
      // being equal to the identifier C, 
      // or beginning with the identifier C immediately followed by "-". 
      // The matching of C against the element's language value is performed case-insensitively. 
      // The identifier C does not have to be a valid language name." 
      // http://www.w3.org/TR/selectors/#lang-pseudo 
      "lang": markFunction( function( lang ) { 
        // lang value must be a valid identifier 
        if ( !ridentifier.test(lang || "") ) { 
          Sizzle.error( "unsupported lang: " + lang ); 
        } 
        lang = lang.replace( runescape, funescape ).toLowerCase(); 
        return function( elem ) { 
          var elemLang; 
          do { 
            if ( (elemLang = documentIsHTML ? 
              elem.lang : 
              elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 
              elemLang = elemLang.toLowerCase(); 
              return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 
            } 
          } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 
          return false; 
        }; 
      }), 
      // Miscellaneous 
      "target": function( elem ) { 
        var hash = window.location && window.location.hash; 
        return hash && hash.slice( 1 ) === elem.id; 
      }, 
      "root": function( elem ) { 
        return elem === docElem; 
      }, 
      "focus": function( elem ) { 
        return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 
      }, 
      // Boolean properties 
      "enabled": function( elem ) { 
        return elem.disabled === false; 
      }, 
      "disabled": function( elem ) { 
        return elem.disabled === true; 
      }, 
      "checked": function( elem ) { 
        // In CSS3, :checked should return both checked and selected elements 
        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 
        var nodeName = elem.nodeName.toLowerCase(); 
        return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 
      }, 
      "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; 
      }, 
      // Contents 
      "empty": function( elem ) { 
        // http://www.w3.org/TR/selectors/#empty-pseudo 
        // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 
        //   but not by others (comment: 8; processing instruction: 7; etc.) 
        // nodeType < 6 works because attributes (2) do not appear as children 
        for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 
          if ( elem.nodeType < 6 ) { 
            return false; 
          } 
        } 
        return true; 
      }, 
      "parent": function( elem ) { 
        return !Expr.pseudos["empty"]( elem ); 
      }, 
      // Element/input types 
      "header": function( elem ) { 
        return rheader.test( elem.nodeName ); 
      }, 
      "input": function( elem ) { 
        return rinputs.test( elem.nodeName ); 
      }, 
      "button": function( elem ) { 
        var name = elem.nodeName.toLowerCase(); 
        return name === "input" && elem.type === "button" || name === "button"; 
      }, 
      "text": function( elem ) { 
        var attr; 
        return elem.nodeName.toLowerCase() === "input" && 
          elem.type === "text" && 
          // Support: IE<8 
          // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 
          ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 
      }, 
      // Position-in-collection 
      "first": createPositionalPseudo(function() { 
        return [ 0 ]; 
      }), 
      "last": createPositionalPseudo(function( matchIndexes, length ) { 
        return [ length - 1 ]; 
      }), 
      "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 
        return [ argument < 0 ? argument + length : argument ]; 
      }), 
      "even": createPositionalPseudo(function( matchIndexes, length ) { 
        var i = 0; 
        for ( ; i < length; i += 2 ) { 
          matchIndexes.push( i ); 
        } 
        return matchIndexes; 
      }), 
      "odd": createPositionalPseudo(function( matchIndexes, length ) { 
        var i = 1; 
        for ( ; i < length; i += 2 ) { 
          matchIndexes.push( i ); 
        } 
        return matchIndexes; 
      }), 
      "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 
        var i = argument < 0 ? argument + length : argument; 
        for ( ; --i >= 0; ) { 
          matchIndexes.push( i ); 
        } 
        return matchIndexes; 
      }), 
      "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 
        var i = argument < 0 ? argument + length : argument; 
        for ( ; ++i < length; ) { 
          matchIndexes.push( i ); 
        } 
        return matchIndexes; 
      }) 
    } 
  }; 
  Expr.pseudos["nth"] = Expr.pseudos["eq"]; 
  // Add button/input type pseudos 
  for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 
    Expr.pseudos[ i ] = createInputPseudo( i ); 
  } 
  for ( i in { submit: true, reset: true } ) { 
    Expr.pseudos[ i ] = createButtonPseudo( i ); 
  } 
  // Easy API for creating new setFilters 
  function setFilters() {} 
  setFilters.prototype = Expr.filters = Expr.pseudos; 
  Expr.setFilters = new setFilters(); 
  tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 
    var matched, match, tokens, type, 
      soFar, groups, preFilters, 
      cached = tokenCache[ selector + " " ]; 
    if ( cached ) { 
      return parseOnly ? 0 : cached.slice( 0 ); 
    } 
    soFar = selector; 
    groups = []; 
    preFilters = Expr.preFilter; 
    while ( soFar ) { 
      // Comma and first run 
      if ( !matched || (match = rcomma.exec( soFar )) ) { 
        if ( match ) { 
          // Don't consume trailing commas as valid 
          soFar = soFar.slice( match[0].length ) || soFar; 
        } 
        groups.push( (tokens = []) ); 
      } 
      matched = false; 
      // Combinators 
      if ( (match = rcombinators.exec( soFar )) ) { 
        matched = match.shift(); 
        tokens.push({ 
          value: matched, 
          // Cast descendant combinators to space 
          type: match[0].replace( rtrim, " " ) 
        }); 
        soFar = soFar.slice( matched.length ); 
      } 
      // Filters 
      for ( type in Expr.filter ) { 
        if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 
          (match = preFilters[ type ]( match ))) ) { 
          matched = match.shift(); 
          tokens.push({ 
            value: matched, 
            type: type, 
            matches: match 
          }); 
          soFar = soFar.slice( matched.length ); 
        } 
      } 
      if ( !matched ) { 
        break; 
      } 
    } 
    // Return the length of the invalid excess 
    // if we're just parsing 
    // Otherwise, throw an error or return tokens 
    return parseOnly ? 
      soFar.length : 
      soFar ? 
        Sizzle.error( selector ) : 
        // Cache the tokens 
        tokenCache( selector, groups ).slice( 0 ); 
  }; 
  function toSelector( tokens ) { 
    var i = 0, 
      len = tokens.length, 
      selector = ""; 
    for ( ; i < len; i++ ) { 
      selector += tokens[i].value; 
    } 
    return selector; 
  } 
  function addCombinator( matcher, combinator, base ) { 
    var dir = combinator.dir, 
      checkNonElements = base && dir === "parentNode", 
      doneName = done++; 
    return combinator.first ? 
      // Check against closest ancestor/preceding element 
      function( elem, context, xml ) { 
        while ( (elem = elem[ dir ]) ) { 
          if ( elem.nodeType === 1 || checkNonElements ) { 
            return matcher( elem, context, xml ); 
          } 
        } 
      } : 
      // Check against all ancestor/preceding elements 
      function( elem, context, xml ) { 
        var oldCache, outerCache, 
          newCache = [ dirruns, doneName ]; 
        // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching 
        if ( xml ) { 
          while ( (elem = elem[ dir ]) ) { 
            if ( elem.nodeType === 1 || checkNonElements ) { 
              if ( matcher( elem, context, xml ) ) { 
                return true; 
              } 
            } 
          } 
        } else { 
          while ( (elem = elem[ dir ]) ) { 
            if ( elem.nodeType === 1 || checkNonElements ) { 
              outerCache = elem[ expando ] || (elem[ expando ] = {}); 
              if ( (oldCache = outerCache[ dir ]) && 
                oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 
                // Assign to newCache so results back-propagate to previous elements 
                return (newCache[ 2 ] = oldCache[ 2 ]); 
              } else { 
                // Reuse newcache so results back-propagate to previous elements 
                outerCache[ dir ] = newCache; 
                // A match means we're done; a fail means we have to keep checking 
                if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 
                  return true; 
                } 
              } 
            } 
          } 
        } 
      }; 
  } 
  function elementMatcher( matchers ) { 
    return matchers.length > 1 ? 
      function( elem, context, xml ) { 
        var i = matchers.length; 
        while ( i-- ) { 
          if ( !matchers[i]( elem, context, xml ) ) { 
            return false; 
          } 
        } 
        return true; 
      } : 
      matchers[0]; 
  } 
  function multipleContexts( selector, contexts, results ) { 
    var i = 0, 
      len = contexts.length; 
    for ( ; i < len; i++ ) { 
      Sizzle( selector, contexts[i], results ); 
    } 
    return results; 
  } 
  function condense( unmatched, map, filter, context, xml ) { 
    var elem, 
      newUnmatched = [], 
      i = 0, 
      len = unmatched.length, 
      mapped = map != null; 
    for ( ; i < len; i++ ) { 
      if ( (elem = unmatched[i]) ) { 
        if ( !filter || filter( elem, context, xml ) ) { 
          newUnmatched.push( elem ); 
          if ( mapped ) { 
            map.push( i ); 
          } 
        } 
      } 
    } 
    return newUnmatched; 
  } 
  function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 
    if ( postFilter && !postFilter[ expando ] ) { 
      postFilter = setMatcher( postFilter ); 
    } 
    if ( postFinder && !postFinder[ expando ] ) { 
      postFinder = setMatcher( postFinder, postSelector ); 
    } 
    return markFunction(function( seed, results, context, xml ) { 
      var temp, i, elem, 
        preMap = [], 
        postMap = [], 
        preexisting = results.length, 
        // Get initial elements from seed or context 
        elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 
        // Prefilter to get matcher input, preserving a map for seed-results synchronization 
        matcherIn = preFilter && ( seed || !selector ) ? 
          condense( elems, preMap, preFilter, context, xml ) : 
          elems, 
        matcherOut = matcher ? 
          // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 
          postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 
            // ...intermediate processing is necessary 
            [] : 
            // ...otherwise use results directly 
            results : 
          matcherIn; 
      // Find primary matches 
      if ( matcher ) { 
        matcher( matcherIn, matcherOut, context, xml ); 
      } 
      // Apply postFilter 
      if ( postFilter ) { 
        temp = condense( matcherOut, postMap ); 
        postFilter( temp, [], context, xml ); 
        // Un-match failing elements by moving them back to matcherIn 
        i = temp.length; 
        while ( i-- ) { 
          if ( (elem = temp[i]) ) { 
            matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 
          } 
        } 
      } 
      if ( seed ) { 
        if ( postFinder || preFilter ) { 
          if ( postFinder ) { 
            // Get the final matcherOut by condensing this intermediate into postFinder contexts 
            temp = []; 
            i = matcherOut.length; 
            while ( i-- ) { 
              if ( (elem = matcherOut[i]) ) { 
                // Restore matcherIn since elem is not yet a final match 
                temp.push( (matcherIn[i] = elem) ); 
              } 
            } 
            postFinder( null, (matcherOut = []), temp, xml ); 
          } 
          // Move matched elements from seed to results to keep them synchronized 
          i = matcherOut.length; 
          while ( i-- ) { 
            if ( (elem = matcherOut[i]) && 
              (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { 
              seed[temp] = !(results[temp] = elem); 
            } 
          } 
        } 
      // Add elements to results, through postFinder if defined 
      } else { 
        matcherOut = condense( 
          matcherOut === results ? 
            matcherOut.splice( preexisting, matcherOut.length ) : 
            matcherOut 
        ); 
        if ( postFinder ) { 
          postFinder( null, results, matcherOut, xml ); 
        } else { 
          push.apply( results, matcherOut ); 
        } 
      } 
    }); 
  } 
  function matcherFromTokens( tokens ) { 
    var checkContext, matcher, j, 
      len = tokens.length, 
      leadingRelative = Expr.relative[ tokens[0].type ], 
      implicitRelative = leadingRelative || Expr.relative[" "], 
      i = leadingRelative ? 1 : 0, 
      // The foundational matcher ensures that elements are reachable from top-level context(s) 
      matchContext = addCombinator( function( elem ) { 
        return elem === checkContext; 
      }, implicitRelative, true ), 
      matchAnyContext = addCombinator( function( elem ) { 
        return indexOf.call( checkContext, elem ) > -1; 
      }, implicitRelative, true ), 
      matchers = [ function( elem, context, xml ) { 
        return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 
          (checkContext = context).nodeType ? 
            matchContext( elem, context, xml ) : 
            matchAnyContext( elem, context, xml ) ); 
      } ]; 
    for ( ; i < len; i++ ) { 
      if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 
        matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 
      } else { 
        matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 
        // Return special upon seeing a positional matcher 
        if ( matcher[ expando ] ) { 
          // Find the next relative operator (if any) for proper handling 
          j = ++i; 
          for ( ; j < len; j++ ) { 
            if ( Expr.relative[ tokens[j].type ] ) { 
              break; 
            } 
          } 
          return setMatcher( 
            i > 1 && elementMatcher( matchers ), 
            i > 1 && toSelector( 
              // If the preceding token was a descendant combinator, insert an implicit any-element `*` 
              tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 
            ).replace( rtrim, "$1" ), 
            matcher, 
            i < j && matcherFromTokens( tokens.slice( i, j ) ), 
            j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 
            j < len && toSelector( tokens ) 
          ); 
        } 
        matchers.push( matcher ); 
      } 
    } 
    return elementMatcher( matchers ); 
  } 
  function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 
    var bySet = setMatchers.length > 0, 
      byElement = elementMatchers.length > 0, 
      superMatcher = function( seed, context, xml, results, outermost ) { 
        var elem, j, matcher, 
          matchedCount = 0, 
          i = "0", 
          unmatched = seed && [], 
          setMatched = [], 
          contextBackup = outermostContext, 
          // We must always have either seed elements or outermost context 
          elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 
          // Use integer dirruns iff this is the outermost matcher 
          dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 
          len = elems.length; 
        if ( outermost ) { 
          outermostContext = context !== document && context; 
        } 
        // Add elements passing elementMatchers directly to results 
        // Keep `i` a string if there are no elements so `matchedCount` will be "00" below 
        // Support: IE<9, Safari 
        // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 
        for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 
          if ( byElement && elem ) { 
            j = 0; 
            while ( (matcher = elementMatchers[j++]) ) { 
              if ( matcher( elem, context, xml ) ) { 
                results.push( elem ); 
                break; 
              } 
            } 
            if ( outermost ) { 
              dirruns = dirrunsUnique; 
            } 
          } 
          // Track unmatched elements for set filters 
          if ( bySet ) { 
            // They will have gone through all possible matchers 
            if ( (elem = !matcher && elem) ) { 
              matchedCount--; 
            } 
            // Lengthen the array for every element, matched or not 
            if ( seed ) { 
              unmatched.push( elem ); 
            } 
          } 
        } 
        // Apply set filters to unmatched elements 
        matchedCount += i; 
        if ( bySet && i !== matchedCount ) { 
          j = 0; 
          while ( (matcher = setMatchers[j++]) ) { 
            matcher( unmatched, setMatched, context, xml ); 
          } 
          if ( seed ) { 
            // Reintegrate element matches to eliminate the need for sorting 
            if ( matchedCount > 0 ) { 
              while ( i-- ) { 
                if ( !(unmatched[i] || setMatched[i]) ) { 
                  setMatched[i] = pop.call( results ); 
                } 
              } 
            } 
            // Discard index placeholder values to get only actual matches 
            setMatched = condense( setMatched ); 
          } 
          // Add matches to results 
          push.apply( results, setMatched ); 
          // Seedless set matches succeeding multiple successful matchers stipulate sorting 
          if ( outermost && !seed && setMatched.length > 0 && 
            ( matchedCount + setMatchers.length ) > 1 ) { 
            Sizzle.uniqueSort( results ); 
          } 
        } 
        // Override manipulation of globals by nested matchers 
        if ( outermost ) { 
          dirruns = dirrunsUnique; 
          outermostContext = contextBackup; 
        } 
        return unmatched; 
      }; 
    return bySet ? 
      markFunction( superMatcher ) : 
      superMatcher; 
  } 
  compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 
    var i, 
      setMatchers = [], 
      elementMatchers = [], 
      cached = compilerCache[ selector + " " ]; 
    if ( !cached ) { 
      // Generate a function of recursive functions that can be used to check each element 
      if ( !match ) { 
        match = tokenize( selector ); 
      } 
      i = match.length; 
      while ( i-- ) { 
        cached = matcherFromTokens( match[i] ); 
        if ( cached[ expando ] ) { 
          setMatchers.push( cached ); 
        } else { 
          elementMatchers.push( cached ); 
        } 
      } 
      // Cache the compiled function 
      cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 
      // Save selector and tokenization 
      cached.selector = selector; 
    } 
    return cached; 
  }; 
  /** 
   * A low-level selection function that works with Sizzle's compiled 
   *  selector functions 
   * @param {String|Function} selector A selector or a pre-compiled 
   *  selector function built with Sizzle.compile 
   * @param {Element} context 
   * @param {Array} [results] 
   * @param {Array} [seed] A set of elements to match against 
   */ 
  select = Sizzle.select = function( selector, context, results, seed ) { 
    var i, tokens, token, type, find, 
      compiled = typeof selector === "function" && selector, 
      match = !seed && tokenize( (selector = compiled.selector || selector) ); 
    results = results || []; 
    // Try to minimize operations if there is no seed and only one group 
    if ( match.length === 1 ) { 
      // Take a shortcut and set the context if the root selector is an ID 
      tokens = match[0] = match[0].slice( 0 ); 
      if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 
          support.getById && context.nodeType === 9 && documentIsHTML && 
          Expr.relative[ tokens[1].type ] ) { 
        context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 
        if ( !context ) { 
          return results; 
        // Precompiled matchers will still verify ancestry, so step up a level 
        } else if ( compiled ) { 
          context = context.parentNode; 
        } 
        selector = selector.slice( tokens.shift().value.length ); 
      } 
      // Fetch a seed set for right-to-left matching 
      i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 
      while ( i-- ) { 
        token = tokens[i]; 
        // Abort if we hit a combinator 
        if ( Expr.relative[ (type = token.type) ] ) { 
          break; 
        } 
        if ( (find = Expr.find[ type ]) ) { 
          // Search, expanding context for leading sibling combinators 
          if ( (seed = find( 
            token.matches[0].replace( runescape, funescape ), 
            rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 
          )) ) { 
            // If seed is empty or no tokens remain, we can return early 
            tokens.splice( i, 1 ); 
            selector = seed.length && toSelector( tokens ); 
            if ( !selector ) { 
              push.apply( results, seed ); 
              return results; 
            } 
            break; 
          } 
        } 
      } 
    } 
    // Compile and execute a filtering function if one is not provided 
    // Provide `match` to avoid retokenization if we modified the selector above 
    ( compiled || compile( selector, match ) )( 
      seed, 
      context, 
      !documentIsHTML, 
      results, 
      rsibling.test( selector ) && testContext( context.parentNode ) || context 
    ); 
    return results; 
  }; 
  // One-time assignments 
  // Sort stability 
  support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 
  // Support: Chrome<14 
  // Always assume duplicates if they aren't passed to the comparison function 
  support.detectDuplicates = !!hasDuplicate; 
  // Initialize against the default document 
  setDocument(); 
  // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 
  // Detached nodes confoundingly follow *each other* 
  support.sortDetached = assert(function( div1 ) { 
    // Should return 1, but returns 4 (following) 
    return div1.compareDocumentPosition( document.createElement("div") ) & 1; 
  }); 
  // Support: IE<8 
  // Prevent attribute/property "interpolation" 
  // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 
  if ( !assert(function( div ) { 
    div.innerHTML = "<a href='#'></a>"; 
    return div.firstChild.getAttribute("href") === "#" ; 
  }) ) { 
    addHandle( "type|href|height|width", function( elem, name, isXML ) { 
      if ( !isXML ) { 
        return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 
      } 
    }); 
  } 
  // Support: IE<9 
  // Use defaultValue in place of getAttribute("value") 
  if ( !support.attributes || !assert(function( div ) { 
    div.innerHTML = "<input/>"; 
    div.firstChild.setAttribute( "value", "" ); 
    return div.firstChild.getAttribute( "value" ) === ""; 
  }) ) { 
    addHandle( "value", function( elem, name, isXML ) { 
      if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 
        return elem.defaultValue; 
      } 
    }); 
  } 
  // Support: IE<9 
  // Use getAttributeNode to fetch booleans when getAttribute lies 
  if ( !assert(function( div ) { 
    return div.getAttribute("disabled") == null; 
  }) ) { 
    addHandle( booleans, function( elem, name, isXML ) { 
      var val; 
      if ( !isXML ) { 
        return elem[ name ] === true ? name.toLowerCase() : 
            (val = elem.getAttributeNode( name )) && val.specified ? 
            val.value : 
          null; 
      } 
    }); 
  } 
  return Sizzle; 
  })( window ); 
  jQuery.find = Sizzle; 
  jQuery.expr = Sizzle.selectors; 
  jQuery.expr[":"] = jQuery.expr.pseudos; 
  jQuery.unique = Sizzle.uniqueSort; 
  jQuery.text = Sizzle.getText; 
  jQuery.isXMLDoc = Sizzle.isXML; 
  jQuery.contains = Sizzle.contains; 
  var rneedsContext = jQuery.expr.match.needsContext; 
  var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); 
  var risSimple = /^.[^:#\[\.,]*$/; 
  // Implement the identical functionality for filter and not 
  function winnow( elements, qualifier, not ) { 
    if ( jQuery.isFunction( qualifier ) ) { 
      return jQuery.grep( elements, function( elem, i ) { 
        /* jshint -W018 */ 
        return !!qualifier.call( elem, i, elem ) !== not; 
      }); 
    } 
    if ( qualifier.nodeType ) { 
      return jQuery.grep( elements, function( elem ) { 
        return ( elem === qualifier ) !== not; 
      }); 
    } 
    if ( typeof qualifier === "string" ) { 
      if ( risSimple.test( qualifier ) ) { 
        return jQuery.filter( qualifier, elements, not ); 
      } 
      qualifier = jQuery.filter( qualifier, elements ); 
    } 
    return jQuery.grep( elements, function( elem ) { 
      return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; 
    }); 
  } 
  jQuery.filter = function( expr, elems, not ) { 
    var elem = elems[ 0 ]; 
    if ( not ) { 
      expr = ":not(" + expr + ")"; 
    } 
    return elems.length === 1 && elem.nodeType === 1 ? 
      jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : 
      jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 
        return elem.nodeType === 1; 
      })); 
  }; 
  jQuery.fn.extend({ 
    find: function( selector ) { 
      var i, 
        ret = [], 
        self = this, 
        len = self.length; 
      if ( typeof selector !== "string" ) { 
        return this.pushStack( jQuery( selector ).filter(function() { 
          for ( i = 0; i < len; i++ ) { 
            if ( jQuery.contains( self[ i ], this ) ) { 
              return true; 
            } 
          } 
        }) ); 
      } 
      for ( i = 0; i < len; i++ ) { 
        jQuery.find( selector, self[ i ], ret ); 
      } 
      // Needed because $( selector, context ) becomes $( context ).find( selector ) 
      ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); 
      ret.selector = this.selector ? this.selector + " " + selector : selector; 
      return ret; 
    }, 
    filter: function( selector ) { 
      return this.pushStack( winnow(this, selector || [], false) ); 
    }, 
    not: function( selector ) { 
      return this.pushStack( winnow(this, selector || [], true) ); 
    }, 
    is: function( selector ) { 
      return !!winnow( 
        this, 
        // If this is a positional/relative selector, check membership in the returned set 
        // so $("p:first").is("p:last") won't return true for a doc with two "p". 
        typeof selector === "string" && rneedsContext.test( selector ) ? 
          jQuery( selector ) : 
          selector || [], 
        false 
      ).length; 
    } 
  }); 
  // Initialize a jQuery object 
  // A central reference to the root jQuery(document) 
  var rootjQuery, 
    // Use the correct document accordingly with window argument (sandbox) 
    document = window.document, 
    // A simple way to check for HTML strings 
    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 
    // Strict HTML recognition (#11290: must start with <) 
    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, 
    init = jQuery.fn.init = function( selector, context ) { 
      var match, elem; 
      // HANDLE: $(""), $(null), $(undefined), $(false) 
      if ( !selector ) { 
        return this; 
      } 
      // Handle HTML strings 
      if ( typeof selector === "string" ) { 
        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 = rquickExpr.exec( selector ); 
        } 
        // Match html or make sure no context is specified for #id 
        if ( match && (match[1] || !context) ) { 
          // HANDLE: $(html) -> $(array) 
          if ( match[1] ) { 
            context = context instanceof jQuery ? context[0] : context; 
            // scripts is true for back-compat 
            // Intentionally let the error be thrown if parseHTML is not present 
            jQuery.merge( this, jQuery.parseHTML( 
              match[1], 
              context && context.nodeType ? context.ownerDocument || context : document, 
              true 
            ) ); 
            // HANDLE: $(html, props) 
            if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { 
              for ( match in context ) { 
                // Properties of context are called as methods if possible 
                if ( jQuery.isFunction( this[ match ] ) ) { 
                  this[ match ]( context[ match ] ); 
                // ...and otherwise set as attributes 
                } else { 
                  this.attr( match, context[ match ] ); 
                } 
              } 
            } 
            return this; 
          // 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: $(DOMElement) 
      } else if ( selector.nodeType ) { 
        this.context = this[0] = selector; 
        this.length = 1; 
        return this; 
      // HANDLE: $(function) 
      // Shortcut for document ready 
      } else if ( jQuery.isFunction( selector ) ) { 
        return typeof rootjQuery.ready !== "undefined" ? 
          rootjQuery.ready( selector ) : 
          // Execute immediately if ready is not present 
          selector( jQuery ); 
      } 
      if ( selector.selector !== undefined ) { 
        this.selector = selector.selector; 
        this.context = selector.context; 
      } 
      return jQuery.makeArray( selector, this ); 
    }; 
  // Give the init function the jQuery prototype for later instantiation 
  init.prototype = jQuery.fn; 
  // Initialize central reference 
  rootjQuery = jQuery( document ); 
  var rparentsprev = /^(?:parents|prev(?:Until|All))/, 
    // methods guaranteed to produce a unique set when starting from a unique set 
    guaranteedUnique = { 
      children: true, 
      contents: true, 
      next: true, 
      prev: true 
    }; 
  jQuery.extend({ 
    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; 
    }, 
    sibling: function( n, elem ) { 
      var r = []; 
      for ( ; n; n = n.nextSibling ) { 
        if ( n.nodeType === 1 && n !== elem ) { 
          r.push( n ); 
        } 
      } 
      return r; 
    } 
  }); 
  jQuery.fn.extend({ 
    has: function( target ) { 
      var i, 
        targets = jQuery( target, this ), 
        len = targets.length; 
      return this.filter(function() { 
        for ( i = 0; i < len; i++ ) { 
          if ( jQuery.contains( this, targets[i] ) ) { 
            return true; 
          } 
        } 
      }); 
    }, 
    closest: function( selectors, context ) { 
      var cur, 
        i = 0, 
        l = this.length, 
        matched = [], 
        pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? 
          jQuery( selectors, context || this.context ) : 
          0; 
      for ( ; i < l; i++ ) { 
        for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { 
          // Always skip document fragments 
          if ( cur.nodeType < 11 && (pos ? 
            pos.index(cur) > -1 : 
            // Don't pass non-elements to Sizzle 
            cur.nodeType === 1 && 
              jQuery.find.matchesSelector(cur, selectors)) ) { 
            matched.push( cur ); 
            break; 
          } 
        } 
      } 
      return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); 
    }, 
    // 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.first().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 ) { 
      return this.pushStack( 
        jQuery.unique( 
          jQuery.merge( this.get(), jQuery( selector, context ) ) 
        ) 
      ); 
    }, 
    addBack: function( selector ) { 
      return this.add( selector == null ? 
        this.prevObject : this.prevObject.filter(selector) 
      ); 
    } 
  }); 
  function sibling( cur, dir ) { 
    do { 
      cur = cur[ dir ]; 
    } while ( cur && cur.nodeType !== 1 ); 
    return cur; 
  } 
  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 sibling( elem, "nextSibling" ); 
    }, 
    prev: function( elem ) { 
      return sibling( elem, "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.merge( [], elem.childNodes ); 
    } 
  }, function( name, fn ) { 
    jQuery.fn[ name ] = function( until, selector ) { 
      var ret = jQuery.map( this, fn, until ); 
      if ( name.slice( -5 ) !== "Until" ) { 
        selector = until; 
      } 
      if ( selector && typeof selector === "string" ) { 
        ret = jQuery.filter( selector, ret ); 
      } 
      if ( this.length > 1 ) { 
        // Remove duplicates 
        if ( !guaranteedUnique[ name ] ) { 
          ret = jQuery.unique( ret ); 
        } 
        // Reverse order for parents* and prev-derivatives 
        if ( rparentsprev.test( name ) ) { 
          ret = ret.reverse(); 
        } 
      } 
      return this.pushStack( ret ); 
    }; 
  }); 
  var rnotwhite = (/\S+/g); 
  // String to Object options format cache 
  var optionsCache = {}; 
  // Convert String-formatted options into Object-formatted ones and store in cache 
  function createOptions( options ) { 
    var object = optionsCache[ options ] = {}; 
    jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { 
      object[ flag ] = true; 
    }); 
    return object; 
  } 
  /* 
   * Create a callback list using the following parameters: 
   * 
   *  options: an optional list of space-separated options that will change how 
   *      the callback list behaves or a more traditional option object 
   * 
   * By default a callback list will act like an event callback list and can be 
   * "fired" multiple times. 
   * 
   * Possible options: 
   * 
   *  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( options ) { 
    // Convert options from String-formatted to Object-formatted if needed 
    // (we check in cache first) 
    options = typeof options === "string" ? 
      ( optionsCache[ options ] || createOptions( options ) ) : 
      jQuery.extend( {}, options ); 
    var // Flag to know if list is currently firing 
      firing, 
      // Last fire value (for non-forgettable lists) 
      memory, 
      // Flag to know if list was already fired 
      fired, 
      // End of the loop when firing 
      firingLength, 
      // Index of currently firing callback (modified by remove if needed) 
      firingIndex, 
      // First callback to fire (used internally by add and fireWith) 
      firingStart, 
      // Actual callback list 
      list = [], 
      // Stack of fire calls for repeatable lists 
      stack = !options.once && [], 
      // Fire callbacks 
      fire = function( data ) { 
        memory = options.memory && data; 
        fired = true; 
        firingIndex = firingStart || 0; 
        firingStart = 0; 
        firingLength = list.length; 
        firing = true; 
        for ( ; list && firingIndex < firingLength; firingIndex++ ) { 
          if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { 
            memory = false; // To prevent further calls using add 
            break; 
          } 
        } 
        firing = false; 
        if ( list ) { 
          if ( stack ) { 
            if ( stack.length ) { 
              fire( stack.shift() ); 
            } 
          } else if ( memory ) { 
            list = []; 
          } else { 
            self.disable(); 
          } 
        } 
      }, 
      // Actual Callbacks object 
      self = { 
        // Add a callback or a collection of callbacks to the list 
        add: function() { 
          if ( list ) { 
            // First, we save the current length 
            var start = list.length; 
            (function add( args ) { 
              jQuery.each( args, function( _, arg ) { 
                var type = jQuery.type( arg ); 
                if ( type === "function" ) { 
                  if ( !options.unique || !self.has( arg ) ) { 
                    list.push( arg ); 
                  } 
                } else if ( arg && arg.length && type !== "string" ) { 
                  // Inspect recursively 
                  add( arg ); 
                } 
              }); 
            })( 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 
            } else if ( memory ) { 
              firingStart = start; 
              fire( memory ); 
            } 
          } 
          return this; 
        }, 
        // Remove a callback from the list 
        remove: function() { 
          if ( list ) { 
            jQuery.each( arguments, function( _, arg ) { 
              var index; 
              while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 
                list.splice( index, 1 ); 
                // Handle firing indexes 
                if ( firing ) { 
                  if ( index <= firingLength ) { 
                    firingLength--; 
                  } 
                  if ( index <= firingIndex ) { 
                    firingIndex--; 
                  } 
                } 
              } 
            }); 
          } 
          return this; 
        }, 
        // Check if a given callback is in the list. 
        // If no argument is given, return whether or not list has callbacks attached. 
        has: function( fn ) { 
          return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); 
        }, 
        // Remove all callbacks from the list 
        empty: function() { 
          list = []; 
          firingLength = 0; 
          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 ) { 
            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 ( list && ( !fired || stack ) ) { 
            args = args || []; 
            args = [ context, args.slice ? args.slice() : args ]; 
            if ( firing ) { 
              stack.push( args ); 
            } else { 
              fire( 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 !!fired; 
        } 
      }; 
    return self; 
  }; 
  jQuery.extend({ 
    Deferred: function( func ) { 
      var tuples = [ 
          // action, add listener, listener list, final state 
          [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], 
          [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], 
          [ "notify", "progress", jQuery.Callbacks("memory") ] 
        ], 
        state = "pending", 
        promise = { 
          state: function() { 
            return state; 
          }, 
          always: function() { 
            deferred.done( arguments ).fail( arguments ); 
            return this; 
          }, 
          then: function( /* fnDone, fnFail, fnProgress */ ) { 
            var fns = arguments; 
            return jQuery.Deferred(function( newDefer ) { 
              jQuery.each( tuples, function( i, tuple ) { 
                var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; 
                // deferred[ done | fail | progress ] for forwarding actions to newDefer 
                deferred[ tuple[1] ](function() { 
                  var returned = fn && fn.apply( this, arguments ); 
                  if ( returned && jQuery.isFunction( returned.promise ) ) { 
                    returned.promise() 
                      .done( newDefer.resolve ) 
                      .fail( newDefer.reject ) 
                      .progress( newDefer.notify ); 
                  } else { 
                    newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); 
                  } 
                }); 
              }); 
              fns = null; 
            }).promise(); 
          }, 
          // Get a promise for this deferred 
          // If obj is provided, the promise aspect is added to the object 
          promise: function( obj ) { 
            return obj != null ? jQuery.extend( obj, promise ) : promise; 
          } 
        }, 
        deferred = {}; 
      // Keep pipe for back-compat 
      promise.pipe = promise.then; 
      // Add list-specific methods 
      jQuery.each( tuples, function( i, tuple ) { 
        var list = tuple[ 2 ], 
          stateString = tuple[ 3 ]; 
        // promise[ done | fail | progress ] = list.add 
        promise[ tuple[1] ] = list.add; 
        // Handle state 
        if ( stateString ) { 
          list.add(function() { 
            // state = [ resolved | rejected ] 
            state = stateString; 
          // [ reject_list | resolve_list ].disable; progress_list.lock 
          }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); 
        } 
        // deferred[ resolve | reject | notify ] 
        deferred[ tuple[0] ] = function() { 
          deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); 
          return this; 
        }; 
        deferred[ tuple[0] + "With" ] = list.fireWith; 
      }); 
      // Make the deferred a promise 
      promise.promise( deferred ); 
      // Call given func if any 
      if ( func ) { 
        func.call( deferred, deferred ); 
      } 
      // All done! 
      return deferred; 
    }, 
    // Deferred helper 
    when: function( subordinate /* , ..., subordinateN */ ) { 
      var i = 0, 
        resolveValues = slice.call( arguments ), 
        length = resolveValues.length, 
        // the count of uncompleted subordinates 
        remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, 
        // the master Deferred. If resolveValues consist of only a single Deferred, just use that. 
        deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 
        // Update function for both resolve and progress values 
        updateFunc = function( i, contexts, values ) { 
          return function( value ) { 
            contexts[ i ] = this; 
            values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 
            if ( values === progressValues ) { 
              deferred.notifyWith( contexts, values ); 
            } else if ( !(--remaining) ) { 
              deferred.resolveWith( contexts, values ); 
            } 
          }; 
        }, 
        progressValues, progressContexts, resolveContexts; 
      // add listeners to Deferred subordinates; treat others as resolved 
      if ( length > 1 ) { 
        progressValues = new Array( length ); 
        progressContexts = new Array( length ); 
        resolveContexts = new Array( length ); 
        for ( ; i < length; i++ ) { 
          if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { 
            resolveValues[ i ].promise() 
              .done( updateFunc( i, resolveContexts, resolveValues ) ) 
              .fail( deferred.reject ) 
              .progress( updateFunc( i, progressContexts, progressValues ) ); 
          } else { 
            --remaining; 
          } 
        } 
      } 
      // if we're not waiting on anything, resolve the master 
      if ( !remaining ) { 
        deferred.resolveWith( resolveContexts, resolveValues ); 
      } 
      return deferred.promise(); 
    } 
  }); 
  // The deferred used on DOM ready 
  var readyList; 
  jQuery.fn.ready = function( fn ) { 
    // Add the callback 
    jQuery.ready.promise().done( fn ); 
    return this; 
  }; 
  jQuery.extend({ 
    // 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 ) { 
      // Abort if there are pending holds or we're already ready 
      if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 
        return; 
      } 
      // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 
      if ( !document.body ) { 
        return setTimeout( jQuery.ready ); 
      } 
      // 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.resolveWith( document, [ jQuery ] ); 
      // Trigger any bound ready events 
      if ( jQuery.fn.triggerHandler ) { 
        jQuery( document ).triggerHandler( "ready" ); 
        jQuery( document ).off( "ready" ); 
      } 
    } 
  }); 
  /** 
   * Clean-up method for dom ready events 
   */ 
  function detach() { 
    if ( document.addEventListener ) { 
      document.removeEventListener( "DOMContentLoaded", completed, false ); 
      window.removeEventListener( "load", completed, false ); 
    } else { 
      document.detachEvent( "onreadystatechange", completed ); 
      window.detachEvent( "onload", completed ); 
    } 
  } 
  /** 
   * The ready event handler and self cleanup method 
   */ 
  function completed() { 
    // readyState === "complete" is good enough for us to call the dom ready in oldIE 
    if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { 
      detach(); 
      jQuery.ready(); 
    } 
  } 
  jQuery.ready.promise = function( obj ) { 
    if ( !readyList ) { 
      readyList = jQuery.Deferred(); 
      // Catch cases where $(document).ready() is called after the browser event has already occurred. 
      // we once tried to use readyState "interactive" here, but it caused issues like the one 
      // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 
      if ( document.readyState === "complete" ) { 
        // Handle it asynchronously to allow scripts the opportunity to delay ready 
        setTimeout( jQuery.ready ); 
      // Standards-based browsers support DOMContentLoaded 
      } else if ( document.addEventListener ) { 
        // Use the handy event callback 
        document.addEventListener( "DOMContentLoaded", completed, false ); 
        // A fallback to window.onload, that will always work 
        window.addEventListener( "load", completed, false ); 
      // If IE event model is used 
      } else { 
        // Ensure firing before onload, maybe late but safe also for iframes 
        document.attachEvent( "onreadystatechange", completed ); 
        // A fallback to window.onload, that will always work 
        window.attachEvent( "onload", completed ); 
        // If IE and not a frame 
        // continually check to see if the document is ready 
        var top = false; 
        try { 
          top = window.frameElement == null && document.documentElement; 
        } catch(e) {} 
        if ( top && top.doScroll ) { 
          (function doScrollCheck() { 
            if ( !jQuery.isReady ) { 
              try { 
                // Use the trick by Diego Perini 
                // http://javascript.nwbox.com/IEContentLoaded/ 
                top.doScroll("left"); 
              } catch(e) { 
                return setTimeout( doScrollCheck, 50 ); 
              } 
              // detach all dom ready events 
              detach(); 
              // and execute any waiting functions 
              jQuery.ready(); 
            } 
          })(); 
        } 
      } 
    } 
    return readyList.promise( obj ); 
  }; 
  var strundefined = typeof undefined; 
  // Support: IE<9 
  // Iteration over object's inherited properties before its own 
  var i; 
  for ( i in jQuery( support ) ) { 
    break; 
  } 
  support.ownLast = i !== "0"; 
  // Note: most support tests are defined in their respective modules. 
  // false until the test is run 
  support.inlineBlockNeedsLayout = false; 
  // Execute ASAP in case we need to set body.style.zoom 
  jQuery(function() { 
    // Minified: var a,b,c,d 
    var val, div, body, container; 
    body = document.getElementsByTagName( "body" )[ 0 ]; 
    if ( !body || !body.style ) { 
      // Return for frameset docs that don't have a body 
      return; 
    } 
    // Setup 
    div = document.createElement( "div" ); 
    container = document.createElement( "div" ); 
    container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; 
    body.appendChild( container ).appendChild( div ); 
    if ( typeof div.style.zoom !== strundefined ) { 
      // Support: IE<8 
      // Check if natively block-level elements act like inline-block 
      // elements when setting their display to 'inline' and giving 
      // them layout 
      div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; 
      support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; 
      if ( val ) { 
        // Prevent IE 6 from affecting layout for positioned elements #11048 
        // Prevent IE from shrinking the body in IE 7 mode #12869 
        // Support: IE<8 
        body.style.zoom = 1; 
      } 
    } 
    body.removeChild( container ); 
  }); 
  (function() { 
    var div = document.createElement( "div" ); 
    // Execute the test only if not already executed in another module. 
    if (support.deleteExpando == null) { 
      // Support: IE<9 
      support.deleteExpando = true; 
      try { 
        delete div.test; 
      } catch( e ) { 
        support.deleteExpando = false; 
      } 
    } 
    // Null elements to avoid leaks in IE. 
    div = null; 
  })(); 
  /** 
   * Determines whether an object can have data 
   */ 
  jQuery.acceptData = function( elem ) { 
    var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], 
      nodeType = +elem.nodeType || 1; 
    // Do not set data on non-element DOM nodes because it will not be cleared (#8335). 
    return nodeType !== 1 && nodeType !== 9 ? 
      false : 
      // Nodes accept data unless otherwise specified; rejection can be conditional 
      !noData || noData !== true && elem.getAttribute("classid") === noData; 
  }; 
  var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*
相关文章
|
6月前
|
前端开发 JavaScript
如何在文本域右下角设置字数限制提示
如何在文本域右下角设置字数限制提示
135 3
|
7月前
根据用户是否输入和是否文本框内容为空来决定显示按钮颜色
根据用户是否输入和是否文本框内容为空来决定显示按钮颜色
45 0
|
7月前
点击富文本部分文字跳转功能
点击富文本部分文字跳转功能
98 0
鼠标悬浮显示文字的简单方法
鼠标悬浮显示文字的简单方法
177 0
|
JavaScript
点击文字显示,点击文字隐藏(5)
点击文字显示,点击文字隐藏(5)
点击文字显示,点击文字隐藏(3)
点击文字显示,点击文字隐藏(2)
|
JavaScript 前端开发 API
前端|获取网页中鼠标选中文字
前端|获取网页中鼠标选中文字
256 0