packages feed

snaplet-fay 0.3.1.0 → 0.3.1.1

raw patch · 22 files changed

+11187/−16 lines, 22 filesdep ~aesondep ~bytestringdep ~data-defaultPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, bytestring, data-default, directory, fay, filepath, mtl, transformers

API changes (from Hackage documentation)

Files

+ README.md view
@@ -0,0 +1,125 @@+Snaplet Fay+===========++Snaplet Fay integrates [Snap](http://www.snapframework.com) with+[Fay](http://www.fay-lang.org). Snap is a+[Haskell](http://www.haskell.org) web framework and Fay is a compiler+from a proper subset of Haskell to JavaScript. Snaplet Fay integrates+them nicely with each other allowing automatic (re)compilation of Fay+source files. Snap provides this for both static content and haskell+sources preventing web server restarts and here we add Fay to this+list as well. This lets us write both front and back-end code in Haskell.+++Features+--------++* Compile and serve fay files on request, no need to restart the+  snap server.+* Production mode to pre-compile all fay files.+* Uses Fay's pretty print option (js-beautify) to create JS files that+  are easier to debug.+* Writes JS to disk to allow reading the generated source.+* Share Fay source files between Haskell and Fay.+* Automatically encode/decode records shared between Snap and Fay by+  using the fayax functions.+++Changelog+---------++0.3.1.1.:++* Hackage version now includes the example application+* Updated repository location++0.3.1.0:++* Add `packages` flag in the config which lets you use other fay packages without using includeDirs+* On errors in development mode a js file is produced that prints the error to the console (Thanks Daniel Bruegmann)++0.3.0.1:++* Bump to support snap 0.10 and fay 0.11++Installation+------------++You will need Haskell. The simplest way to get up and running with is+to install+[The Haskell Platform](http://hackage.haskell.org/platform/).++Everything else is available on hackage:+```+cabal install snaplet-fay+```+++Example Usage+-------------++Site.hs:+```+import Snap.Snaplet.Fay++routes = [..., ("/fay", with fay fayServe)]++app :: SnapletInit App App+app = makeSnaplet "app" "A snaplet example application." Nothing $ do+  fay' <- nestSnaplet "fay" fay initFay+  return $ App { _fay = fay' }+```++Application.hs:+```+import Snap.Snaplet.Fay++data App = App { _fay :: Snaplet Fay }++makeLens ''App+```++Run your application now.++A snaplet config file will be generated at snaplets/fay/devel.cfg the+first time your application initializes the snaplet. The defaults are+the recommended ones for development.++Place your Fay .hs files in snaplets/fay/src. Note that a default+devel.cfg will not be created if you have already created the fay+directory. If this happens to you, move snaplets/fay, start your+application, and then move the files back into snaplets/fay.++Any requests to the specified directory (in this case /fay/) will+compile the appropriate Fay file and serve it.+++Example Application+-------------------++There is an example available in the `example` directory. It requires+fay-jquery [hackage](http://hackage.haskell.org/package/fay-jquery) [github](http://www.github.com/faylang/fay-jquery).+++Development Status+------------------++Snaplet Fay is functioning and will be updated to keep up with both+Snap and Fay.+++Contributions+-----------++Fork on!++Any enhancements are welcome.++The github master may require the latest fay master, available at+[faylang/fay](https://github.com/faylang/fay/).+++Contact+-------++File an issue, e-mail or visit `#fay @ irc.freenode.net`.
+ example/example.cabal view
@@ -0,0 +1,56 @@+Name:                example+Version:             0.1+Synopsis:            Project Synopsis Here+Description:         Project Description Here+License:             AllRightsReserved+Author:              Author+Maintainer:          maintainer@example.com+Stability:           Experimental+Category:            Web+Build-type:          Simple+Cabal-version:       >=1.2++Flag development+  Description: Whether to build the server in development (interpreted) mode+  Default: False++Executable example+  hs-source-dirs: src, snaplets/fay/src+  main-is: Main.hs++  Build-depends:+      base >= 4+    , MonadCatchIO-transformers >= 0.2.1+    , aeson >= 0.6+    , bytestring >= 0.9+    , fay+    , fay-jquery+    , heist >= 0.8+    , lens >= 3.7+    , mtl >= 2+    , snap >= 0.9+    , snap-core >= 0.9+    , snap-loader-static >= 0.9+    , snap-server >= 0.9+    , snaplet-fay >= 0.3.1.1+    , text >= 0.11+    , time >= 1.1 && < 1.5+    , xmlhtml >= 0.1++  if flag(development)+    build-depends:+      snap-loader-dynamic >= 0.9 && < 0.11+    cpp-options: -DDEVELOPMENT+    -- In development mode, speed is already going to suffer, so skip+    -- the fancy optimization flags.  Additionally, disable all+    -- warnings.  The hint library doesn't give an option to execute+    -- compiled code when there were also warnings, so disabling+    -- warnings allows quicker workflow.+    ghc-options: -threaded -w -Wall+  else+    if impl(ghc >= 6.12.0)+      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2+                   -fno-warn-orphans -fno-warn-unused-do-bind+    else+      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2+                   -fno-warn-orphans
+ example/log/.gitignore view
@@ -0,0 +1,4 @@+# Ignore everything in this directory+*+# Except this file+!.gitignore
+ example/snaplets/fay/devel.cfg view
@@ -0,0 +1,25 @@+# "Development": Compile files on every request.+#+# "Production": Compile all files i snaplets/src/fay when the application is started and then serve them statically.+#+# Both methods will write files to disk for debugging purposes.+# Default is "Development".+compileMode = "Development"+# Print more or less information about what the snaplet is doing.+# Default is on.+verbose = on+# Run js-beautify on the results if it is available in the PATH.+# If it isn't available the compiled file will be used as is.+# Default is on.+prettyPrint = on+# A comma-separated list of directories to look for fay imports in.+# This is useful if you want to share modules between Fay and Snap.+# Paths are relative to the root of the snap application.+# snaplets/fay/src will always be checked for imports.+# Default is "" meaning no additional directories will be checked.+includeDirs = ""+# A comma separated list of Fay package names.+# This gives the same result as using includeDirs,+# except Fay figures out the paths for you.+# Default is "" meaning no other Fay packages will be used.+packages = "fay-jquery"
+ example/snaplets/fay/js/.gitignore view
@@ -0,0 +1,4 @@+# Ignore everything in this directory+*+# Except this file+!.gitignore
+ example/snaplets/fay/src/Application/SharedTypes.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE CPP #-}++module Application.SharedTypes where++import           Prelude+import           Data.Data+#ifdef FAY+import           FFI+#endif+++data Time = Time { time :: String }+            deriving (Read,Data,Typeable,Show)++data UserRegister = UserRegister { user :: String, password :: String, passwordConfirmation :: String }+                    deriving (Read,Data,Typeable,Show)++data UserLogin = UserLogin { ul_user :: String, ul_password :: String, remember :: Bool }+                    deriving (Read,Data,Typeable,Show)++data UserRegisterResponse = Fail | OK+                            deriving (Read,Data,Typeable,Show)++data UserLoginResponse = LoggedIn | BadLogin+                            deriving (Read,Data,Typeable,Show)
+ example/snaplets/fay/src/BrokenFile.hs view
@@ -0,0 +1,2 @@++broken:(
+ example/snaplets/fay/src/Dom.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE EmptyDataDecls    #-}++module Dom where++import FFI+import Prelude+++data Element+data Global+data Document++addOnload :: Fay f -> Fay ()+addOnload = ffi "window.addEventListener(\"load\", %1)"++createElement :: String -> Fay Element+createElement = ffi "document.createElement(%1)"++setInterval :: Double -> Fay () -> Fay Double+setInterval = ffi "setInterval(%2, %1)"
+ example/snaplets/fay/src/Index.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE EmptyDataDecls    #-}+{-# OPTIONS -Wall -fno-warn-name-shadowing -fno-warn-unused-do-bind #-}++module Index where++import FFI+import Prelude++-- | Time is shared between Snap and Fay+-- | Location: snaplets/fay/src/Application/SharedTypes.hs+import Application.SharedTypes+-- | Dom is a Fay only module+-- | Location: snaplets/fay/src+import Dom+-- | The fay-jquery package+import JQuery++void :: Fay f -> Fay ()+void f = f >> return ()++main :: Fay ()+main = mapM_ addOnload [onload, registrationOnload, loginOnload, void (select "#logout" >>= click (const submitLogout))]++(=<<) :: (a -> Fay b) -> Fay a -> Fay b+(=<<) = flip (>>=)++onload :: Fay ()+onload = void $ do+  contents <- select "#content"+  div <- select "<div></div>"+  setHtml "This element was created by Fay through an onload handler!" div+  appendTo contents div++  currentTime+  setInterval 2000 currentTime++currentTime :: Fay ()+currentTime =+  ajaxJson "/ajax/current-time" (\(Time time) -> void $ select "#current-time" >>= setHtml time)++formOnload :: String -> Fay () -> Fay ()+formOnload buttonSel getForm = void $ select buttonSel >>= click (const getForm)++registrationOnload :: Fay ()+registrationOnload = formOnload "#viewRegisterForm" requestRegisterHtml++loginOnload :: Fay ()+loginOnload = formOnload "#viewLoginForm" requestLoginHtml++requestHtml :: String -> Fay () -> Fay ()+requestHtml url submitAction = do+  formContainer <- select "#formContainer"+  hide Slow formContainer+  ajaxHtml url (\h -> do+    setHtml h formContainer+    findSelector "form" formContainer >>= submit (\e -> preventDefault e >> submitAction)+    jshow Slow formContainer+    return ())++typeof :: f -> String+typeof = ffi "typeof %1"++requestRegisterHtml :: Fay ()+requestRegisterHtml = requestHtml "/ajax/register-form" submitRegister++requestLoginHtml :: Fay ()+requestLoginHtml = requestHtml "/ajax/login-form" submitLogin++submitRegister :: Fay ()+submitRegister = do+  json <- select "#formContainer form" >>= formJson :: Fay UserRegister+  jPost "/ajax/register" json (\c -> case c of+    Fail -> select "#loginStatus" >>= showStatus Error "Oops! Username taken or fields have length < 4"+    OK -> do+      select "#loginStatus" >>= showStatus Notice "Account created!"+      select "#formContainer" >>= hide Fast >> requestLoginHtml)++submitLogin :: Fay ()+submitLogin = do+  form <- select "#formContainer form"+  json <- formJson form :: Fay UserLogin+  jPost "/ajax/login" json (\c -> case c of+    BadLogin -> select "#loginStatus" >>= showStatus Error "Oops! Bad login information!"+    LoggedIn -> void $ do+      select "#loginStatus" >>= showStatus Notice "Logged in! Too bad there is no additional functionality for you now."+      select "#formContainer" >>= hide Fast)++submitLogout :: Fay ()+submitLogout = ajaxJson "/ajax/logout" (\_ -> void $ select "#loginStatus" >>= showStatus Notice "You have been logged out.")++data Status = Error | Notice++statusClass :: Status -> String+statusClass Error = "error"+statusClass Notice = "notice"++showStatus :: Status -> String -> JQuery -> Fay ()+showStatus status msg el = void $+  return el >>= hide Fast >>=+    removeClass (statusClass Error) >>= removeClass (statusClass Notice) >>=+      setHtml msg >>=+        addClass (statusClass status) >>=+          jshow Fast >> return ()++formJson :: JQuery -> Fay f+formJson = ffi "Helpers.formJson(%1)"++-- jQuery additions++jPost :: String -> Automatic f -> (Automatic g -> Fay ()) -> Fay ()+jPost = ffi "jQuery.ajax(%1, { data: JSON.stringify(%2), type: 'POST', processData: false, contentType: 'text/json', success: %3 })"++ajaxHtml :: String -> (String -> Fay()) -> Fay ()+ajaxHtml = ffi "jQuery.ajax(%1, { success : %2 })"++ajaxJson :: String -> (Automatic f -> Fay ()) -> Fay ()+ajaxJson = ffi "jQuery.ajax(%1, { success : %2 })"
+ example/snaplets/heist/templates/index.tpl view
@@ -0,0 +1,39 @@+<html>+  <head>+    <title>Snaplet Fay Example Application</title>+    <link rel="stylesheet" type="text/css" href="/static/screen.css"/>+    <script src="/static/jquery.js"></script>+    <script src="/static/underscore.js"></script>+    <script src="/static/index.js"></script>+    <script src="/fay/Index.js"></script>+  </head>+  <body>+    <div id="content">+      <h1>Snaplet Fay Example Application</h1>++      <div>Current time:</div>+      <div id="current-time"><current-time/></div>++      <br>+      <div id="loginStatus" class="status">+        <ifLoggedIn>+          You're logged in.+        </ifLoggedIn>+        <ifLoggedOut>+          You're not logged in.+        </ifLoggedOut>+      </div>+      <input id="viewLoginForm" type="button" value="Log in">+      <input id="viewRegisterForm" type="button" value="Register">+      <input id="logout" type="button" value="Log out">++      <div id="formContainer">+      </div>++      <br>+      <div><a href="/static/broken.html">See what happens when you try to load a html file referencing a Fay file containing Syntax errors.</a></div>++      <br>+    </div>+  </body>+</html>
+ example/snaplets/heist/templates/login-form.tpl view
@@ -0,0 +1,10 @@+<form class="login-form" action="/login">+  <input type="hidden" name="instance" value="UserLogin">+  <label for="ul_user">Username</label>+  <input type="text" name="ul_user">+  <label for="ul_password">Password</label>+  <input type="password" name="ul_password">+  <input type="checkbox" name="remember"> Remember me+  <input class="submit" type="submit" value="Log In">+  <div class="status"></div>+</form>
+ example/snaplets/heist/templates/register-form.tpl view
@@ -0,0 +1,11 @@+<form class="register-form" action="/register">+  <input type="hidden" name="instance" value="UserRegister">+  <label for="user">Username</label>+  <input type="text" name="user">+  <label for="password">Password</label>+  <input type="password" name="password">+  <label for="user">Repeat Password</label>+  <input type="password" name="passwordConfirmation">+  <input class="submit" type="submit" value="Register">+  <div class="status"></div>+</form>
+ example/src/Application.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE TemplateHaskell #-}++module Application where+------------------------------------------------------------------------------+import           Control.Lens+import           Snap.Snaplet+import           Snap.Snaplet.Auth+import           Snap.Snaplet.Fay+import           Snap.Snaplet.Heist+import           Snap.Snaplet.Session+------------------------------------------------------------------------------+data App = App+    { _heist :: Snaplet (Heist App)+    , _fay :: Snaplet Fay+    , _session :: Snaplet SessionManager+    , _auth :: Snaplet (AuthManager App)+    }++makeLenses ''App++instance HasHeist App where+    heistLens = subSnaplet heist++------------------------------------------------------------------------------+type AppHandler = Handler App App
+ example/src/Main.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP             #-}+{-# LANGUAGE TemplateHaskell #-}++module Main where++------------------------------------------------------------------------------+import           Control.Exception (SomeException, try)+import qualified Data.Text as T+import           Snap.Http.Server+import           Snap.Snaplet+import           Snap.Snaplet.Config+import           Snap.Core+import           System.IO+import           Site++#ifdef DEVELOPMENT+import           Snap.Loader.Dynamic+#else+import           Snap.Loader.Static+#endif+++------------------------------------------------------------------------------+-- | This is the entry point for this web server application. It supports+-- easily switching between interpreting source and running statically compiled+-- code.+--+-- In either mode, the generated program should be run from the root of the+-- project tree. When it is run, it locates its templates, static content, and+-- source files in development mode, relative to the current working directory.+--+-- When compiled with the development flag, only changes to the libraries, your+-- cabal file, or this file should require a recompile to be picked up.+-- Everything else is interpreted at runtime. There are a few consequences of+-- this.+--+-- First, this is much slower. Running the interpreter takes a significant+-- chunk of time (a couple tenths of a second on the author's machine, at this+-- time), regardless of the simplicity of the loaded code. In order to+-- recompile and re-load server state as infrequently as possible, the source+-- directories are watched for updates, as are any extra directories specified+-- below.+--+-- Second, the generated server binary is MUCH larger, since it links in the+-- GHC API (via the hint library).+--+-- Third, and the reason you would ever want to actually compile with+-- development mode, is that it enables a faster development cycle. You can+-- simply edit a file, save your changes, and hit reload to see your changes+-- reflected immediately.+--+-- When this is compiled without the development flag, all the actions are+-- statically compiled in. This results in faster execution, a smaller binary+-- size, and having to recompile the server for any code change.+--+main :: IO ()+main = do+    -- Depending on the version of loadSnapTH in scope, this either enables+    -- dynamic reloading, or compiles it without. The last argument to+    -- loadSnapTH is a list of additional directories to watch for changes to+    -- trigger reloads in development mode. It doesn't need to include source+    -- directories, those are picked up automatically by the splice.+    (conf, site, cleanup) <- $(loadSnapTH [| getConf |]+                                          'getActions+                                          ["snaplets/heist/templates"])++    _ <- try $ httpServe conf site :: IO (Either SomeException ())+    cleanup+++------------------------------------------------------------------------------+-- | This action loads the config used by this application. The loaded config+-- is returned as the first element of the tuple produced by the loadSnapTH+-- Splice. The type is not solidly fixed, though it must be an IO action that+-- produces the same type as 'getActions' takes. It also must be an instance of+-- Typeable. If the type of this is changed, a full recompile will be needed to+-- pick up the change, even in development mode.+--+-- This action is only run once, regardless of whether development or+-- production mode is in use.+getConf :: IO (Config Snap AppConfig)+getConf = commandLineAppConfig defaultConfig+++------------------------------------------------------------------------------+-- | This function generates the the site handler and cleanup action from the+-- configuration. In production mode, this action is only run once. In+-- development mode, this action is run whenever the application is reloaded.+--+-- Development mode also makes sure that the cleanup actions are run+-- appropriately before shutdown. The cleanup action returned from loadSnapTH+-- should still be used after the server has stopped handling requests, as the+-- cleanup actions are only automatically run when a reload is triggered.+--+-- This sample doesn't actually use the config passed in, but more+-- sophisticated code might.+getActions :: Config Snap AppConfig -> IO (Snap (), IO ())+getActions conf = do+    (msgs, site, cleanup) <- runSnaplet+        (appEnvironment =<< getOther conf) app+    hPutStrLn stderr $ T.unpack msgs+    return (site, cleanup)
+ example/src/Site.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}++module Site+  ( app+  ) where++------------------------------------------------------------------------------+import           Control.Applicative+import           Control.Monad.Trans+import           Data.ByteString                             (ByteString)+import qualified Data.ByteString.Char8                       as BS+import qualified Data.Text                                   as T+import           Data.Time.Clock+import           Snap.Snaplet+import           Snap.Snaplet.Auth                           hiding (session)+import           Snap.Snaplet.Auth.Backends.JsonFile+import           Snap.Snaplet.Fay+import           Snap.Snaplet.Heist+import           Snap.Snaplet.Session.Backends.CookieSession+import           Snap.Util.FileServe+------------------------------------------------------------------------------+import           Application+import           Application.SharedTypes+++currentTimeAjax :: AppHandler Time+currentTimeAjax = Time . show <$> liftIO getCurrentTime++-- TODO this can be handled automatically by heistServe+registerForm :: AppHandler ()+registerForm = render "register-form"+loginForm :: AppHandler ()+loginForm = render "login-form"++register :: UserRegister -> Handler App (AuthManager App) UserRegisterResponse+register (UserRegister u p pc)+  | length u < 4 || length p < 4 || p /= pc = return Fail+  | otherwise = do+    let u' = T.pack u+    exists <- usernameExists u'+    if exists then return Fail else (createUser u' (BS.pack p) >> return OK)++login :: UserLogin -> Handler App (AuthManager App) UserLoginResponse+login (UserLogin u p r) =+  either (return BadLogin) (return LoggedIn) <$>+    loginByUsername (BS.pack u) (ClearText $ BS.pack p) r++------------------------------------------------------------------------------+-- | The application's routes.+routes :: [(ByteString, Handler App App ())]+routes = [+           ("/ajax/current-time",  toFayax currentTimeAjax)+         , ("/ajax/login",         with auth $ fayax login)+         , ("/ajax/login-form",    loginForm)+         , ("/ajax/logout",        with auth logout)+         , ("/ajax/register",      with auth $ fayax register)+         , ("/ajax/register-form", registerForm)+         , ("/fay",                with fay fayServe)+         , ("/static",             serveDirectory "static")+         ]+++------------------------------------------------------------------------------+-- | The application initializer.+app :: SnapletInit App App+app = makeSnaplet "app" "An snaplet example application." Nothing $ do+    s <- nestSnaplet "sess" session $+           initCookieSessionManager "site_key.txt" "sess" (Just 3600)+    h <- nestSnaplet "" heist $ heistInit "templates"+    f <- nestSnaplet "fay" fay $ initFay+    a <- nestSnaplet "auth" auth $ initJsonFileAuthManager defAuthSettings session "users.json"+    addAuthSplices auth+    addRoutes routes+    return $ App h f s a
+ example/static/broken.html view
@@ -0,0 +1,10 @@+<html>+  <head>+    <title>Page with broken Fay code (development mode).</title>+    <script src="/fay/BrokenFile.js"></script>+  </head>+  <body>+    <h1>Page with broken Fay code (development mode).</h1>+    <p>Check the JS console for the error message.</p>+  </body>+</html>
+ example/static/index.js view
@@ -0,0 +1,21 @@+window.Helpers = {+  formJson : function (form) {+    var o = {};+    $("input, select", form).each(function (_,e) {+      e = $(e);+      var t = e.attr("type");+      var p = e.attr("name");+      if (!p) return;+      var v = e.val();+      v = t === "checkbox" ? v === "on" : v;+      if (p in o && o[p] instanceof Array) {+        o[p].push(v);+      } else if (p in o) {+        o[p] = [o[p], v];+      } else {+        o[p] = v;+      }+    });+    return o;+  }+};
+ example/static/jquery.js view
@@ -0,0 +1,9404 @@+/*!+ * jQuery JavaScript Library v1.7.2+ * http://jquery.com/+ *+ * Copyright 2011, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2011, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Wed Mar 21 12:46:34 2012 -0700+ */+(function( window, undefined ) {++// Use the correct document accordingly with window argument (sandbox)+var document = window.document,+	navigator = window.navigator,+	location = window.location;+var jQuery = (function() {++// Define a local copy of jQuery+var jQuery = function( selector, context ) {+		// The jQuery object is actually just the init constructor 'enhanced'+		return new jQuery.fn.init( selector, context, rootjQuery );+	},++	// Map over jQuery in case of overwrite+	_jQuery = window.jQuery,++	// Map over the $ in case of overwrite+	_$ = window.$,++	// A central reference to the root jQuery(document)+	rootjQuery,++	// A simple way to check for HTML strings or ID strings+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)+	quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,++	// Check if a string has a non-whitespace character in it+	rnotwhite = /\S/,++	// Used for trimming whitespace+	trimLeft = /^\s+/,+	trimRight = /\s+$/,++	// Match a standalone tag+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,++	// JSON RegExp+	rvalidchars = /^[\],:{}\s]*$/,+	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,+	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,++	// Useragent RegExp+	rwebkit = /(webkit)[ \/]([\w.]+)/,+	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,+	rmsie = /(msie) ([\w.]+)/,+	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,++	// Matches dashed string for camelizing+	rdashAlpha = /-([a-z]|[0-9])/ig,+	rmsPrefix = /^-ms-/,++	// Used by jQuery.camelCase as callback to replace()+	fcamelCase = function( all, letter ) {+		return ( letter + "" ).toUpperCase();+	},++	// Keep a UserAgent string for use with jQuery.browser+	userAgent = navigator.userAgent,++	// For matching the engine and version of the browser+	browserMatch,++	// The deferred used on DOM ready+	readyList,++	// The ready event handler+	DOMContentLoaded,++	// Save a reference to some core methods+	toString = Object.prototype.toString,+	hasOwn = Object.prototype.hasOwnProperty,+	push = Array.prototype.push,+	slice = Array.prototype.slice,+	trim = String.prototype.trim,+	indexOf = Array.prototype.indexOf,++	// [[Class]] -> type pairs+	class2type = {};++jQuery.fn = jQuery.prototype = {+	constructor: jQuery,+	init: function( selector, context, rootjQuery ) {+		var match, elem, ret, doc;++		// Handle $(""), $(null), or $(undefined)+		if ( !selector ) {+			return this;+		}++		// Handle $(DOMElement)+		if ( selector.nodeType ) {+			this.context = this[0] = selector;+			this.length = 1;+			return this;+		}++		// The body element only exists once, optimize finding it+		if ( selector === "body" && !context && document.body ) {+			this.context = document;+			this[0] = document.body;+			this.selector = selector;+			this.length = 1;+			return this;+		}++		// Handle HTML strings+		if ( typeof selector === "string" ) {+			// Are we dealing with HTML string or an ID?+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {+				// Assume that strings that start and end with <> are HTML and skip the regex check+				match = [ null, selector, null ];++			} else {+				match = quickExpr.exec( selector );+			}++			// Verify a match, and that no context was specified for #id+			if ( match && (match[1] || !context) ) {++				// HANDLE: $(html) -> $(array)+				if ( match[1] ) {+					context = context instanceof jQuery ? context[0] : context;+					doc = ( context ? context.ownerDocument || context : document );++					// If a single string is passed in and it's a single tag+					// just do a createElement and skip the rest+					ret = rsingleTag.exec( selector );++					if ( ret ) {+						if ( jQuery.isPlainObject( context ) ) {+							selector = [ document.createElement( ret[1] ) ];+							jQuery.fn.attr.call( selector, context, true );++						} else {+							selector = [ doc.createElement( ret[1] ) ];+						}++					} else {+						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );+						selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;+					}++					return jQuery.merge( this, selector );++				// HANDLE: $("#id")+				} else {+					elem = document.getElementById( match[2] );++					// Check parentNode to catch when Blackberry 4.6 returns+					// nodes that are no longer in the document #6963+					if ( elem && elem.parentNode ) {+						// Handle the case where IE and Opera return items+						// by name instead of ID+						if ( elem.id !== match[2] ) {+							return rootjQuery.find( selector );+						}++						// Otherwise, we inject the element directly into the jQuery object+						this.length = 1;+						this[0] = elem;+					}++					this.context = document;+					this.selector = selector;+					return this;+				}++			// HANDLE: $(expr, $(...))+			} else if ( !context || context.jquery ) {+				return ( context || rootjQuery ).find( selector );++			// HANDLE: $(expr, context)+			// (which is just equivalent to: $(context).find(expr)+			} else {+				return this.constructor( context ).find( selector );+			}++		// HANDLE: $(function)+		// Shortcut for document ready+		} else if ( jQuery.isFunction( selector ) ) {+			return rootjQuery.ready( selector );+		}++		if ( selector.selector !== undefined ) {+			this.selector = selector.selector;+			this.context = selector.context;+		}++		return jQuery.makeArray( selector, this );+	},++	// Start with an empty selector+	selector: "",++	// The current version of jQuery being used+	jquery: "1.7.2",++	// The default length of a jQuery object is 0+	length: 0,++	// The number of elements contained in the matched element set+	size: function() {+		return this.length;+	},++	toArray: function() {+		return slice.call( this, 0 );+	},++	// Get the Nth element in the matched element set OR+	// Get the whole matched element set as a clean array+	get: function( num ) {+		return num == null ?++			// Return a 'clean' array+			this.toArray() :++			// Return just the object+			( num < 0 ? this[ this.length + num ] : this[ num ] );+	},++	// Take an array of elements and push it onto the stack+	// (returning the new matched element set)+	pushStack: function( elems, name, selector ) {+		// Build a new jQuery matched element set+		var ret = this.constructor();++		if ( jQuery.isArray( elems ) ) {+			push.apply( ret, elems );++		} else {+			jQuery.merge( ret, elems );+		}++		// Add the old object onto the stack (as a reference)+		ret.prevObject = this;++		ret.context = this.context;++		if ( name === "find" ) {+			ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;+		} else if ( name ) {+			ret.selector = this.selector + "." + name + "(" + selector + ")";+		}++		// Return the newly-formed element set+		return ret;+	},++	// Execute a callback for every element in the matched set.+	// (You can seed the arguments with an array of args, but this is+	// only used internally.)+	each: function( callback, args ) {+		return jQuery.each( this, callback, args );+	},++	ready: function( fn ) {+		// Attach the listeners+		jQuery.bindReady();++		// Add the callback+		readyList.add( fn );++		return this;+	},++	eq: function( i ) {+		i = +i;+		return i === -1 ?+			this.slice( i ) :+			this.slice( i, i + 1 );+	},++	first: function() {+		return this.eq( 0 );+	},++	last: function() {+		return this.eq( -1 );+	},++	slice: function() {+		return this.pushStack( slice.apply( this, arguments ),+			"slice", slice.call(arguments).join(",") );+	},++	map: function( callback ) {+		return this.pushStack( jQuery.map(this, function( elem, i ) {+			return callback.call( elem, i, elem );+		}));+	},++	end: function() {+		return this.prevObject || this.constructor(null);+	},++	// For internal use only.+	// Behaves like an Array's method, not like a jQuery method.+	push: push,+	sort: [].sort,+	splice: [].splice+};++// Give the init function the jQuery prototype for later instantiation+jQuery.fn.init.prototype = jQuery.fn;++jQuery.extend = jQuery.fn.extend = function() {+	var options, name, src, copy, copyIsArray, clone,+		target = arguments[0] || {},+		i = 1,+		length = arguments.length,+		deep = false;++	// Handle a deep copy situation+	if ( typeof target === "boolean" ) {+		deep = target;+		target = arguments[1] || {};+		// skip the boolean and the target+		i = 2;+	}++	// Handle case when target is a string or something (possible in deep copy)+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {+		target = {};+	}++	// extend jQuery itself if only one argument is passed+	if ( length === i ) {+		target = this;+		--i;+	}++	for ( ; i < length; i++ ) {+		// Only deal with non-null/undefined values+		if ( (options = arguments[ i ]) != null ) {+			// Extend the base object+			for ( name in options ) {+				src = target[ name ];+				copy = options[ name ];++				// Prevent never-ending loop+				if ( target === copy ) {+					continue;+				}++				// Recurse if we're merging plain objects or arrays+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {+					if ( copyIsArray ) {+						copyIsArray = false;+						clone = src && jQuery.isArray(src) ? src : [];++					} else {+						clone = src && jQuery.isPlainObject(src) ? src : {};+					}++					// Never move original objects, clone them+					target[ name ] = jQuery.extend( deep, clone, copy );++				// Don't bring in undefined values+				} else if ( copy !== undefined ) {+					target[ name ] = copy;+				}+			}+		}+	}++	// Return the modified object+	return target;+};++jQuery.extend({+	noConflict: function( deep ) {+		if ( window.$ === jQuery ) {+			window.$ = _$;+		}++		if ( deep && window.jQuery === jQuery ) {+			window.jQuery = _jQuery;+		}++		return jQuery;+	},++	// Is the DOM ready to be used? Set to true once it occurs.+	isReady: false,++	// A counter to track how many items to wait for before+	// the ready event fires. See #6781+	readyWait: 1,++	// Hold (or release) the ready event+	holdReady: function( hold ) {+		if ( hold ) {+			jQuery.readyWait++;+		} else {+			jQuery.ready( true );+		}+	},++	// Handle when the DOM is ready+	ready: function( wait ) {+		// Either a released hold or an DOMready/load event and not yet ready+		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+			if ( !document.body ) {+				return setTimeout( jQuery.ready, 1 );+			}++			// Remember that the DOM is ready+			jQuery.isReady = true;++			// If a normal DOM Ready event fired, decrement, and wait if need be+			if ( wait !== true && --jQuery.readyWait > 0 ) {+				return;+			}++			// If there are functions bound, to execute+			readyList.fireWith( document, [ jQuery ] );++			// Trigger any bound ready events+			if ( jQuery.fn.trigger ) {+				jQuery( document ).trigger( "ready" ).off( "ready" );+			}+		}+	},++	bindReady: function() {+		if ( readyList ) {+			return;+		}++		readyList = jQuery.Callbacks( "once memory" );++		// Catch cases where $(document).ready() is called after the+		// browser event has already occurred.+		if ( document.readyState === "complete" ) {+			// Handle it asynchronously to allow scripts the opportunity to delay ready+			return setTimeout( jQuery.ready, 1 );+		}++		// Mozilla, Opera and webkit nightlies currently support this event+		if ( document.addEventListener ) {+			// Use the handy event callback+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );++			// A fallback to window.onload, that will always work+			window.addEventListener( "load", jQuery.ready, false );++		// If IE event model is used+		} else if ( document.attachEvent ) {+			// ensure firing before onload,+			// maybe late but safe also for iframes+			document.attachEvent( "onreadystatechange", DOMContentLoaded );++			// A fallback to window.onload, that will always work+			window.attachEvent( "onload", jQuery.ready );++			// If IE and not a frame+			// continually check to see if the document is ready+			var toplevel = false;++			try {+				toplevel = window.frameElement == null;+			} catch(e) {}++			if ( document.documentElement.doScroll && toplevel ) {+				doScrollCheck();+			}+		}+	},++	// See test/unit/core.js for details concerning isFunction.+	// Since version 1.3, DOM methods and functions like alert+	// aren't supported. They return false on IE (#2968).+	isFunction: function( obj ) {+		return jQuery.type(obj) === "function";+	},++	isArray: Array.isArray || function( obj ) {+		return jQuery.type(obj) === "array";+	},++	isWindow: function( obj ) {+		return obj != null && obj == obj.window;+	},++	isNumeric: function( obj ) {+		return !isNaN( parseFloat(obj) ) && isFinite( obj );+	},++	type: function( obj ) {+		return obj == null ?+			String( obj ) :+			class2type[ toString.call(obj) ] || "object";+	},++	isPlainObject: function( obj ) {+		// Must be an Object.+		// Because of IE, we also have to check the presence of the constructor property.+		// Make sure that DOM nodes and window objects don't pass through, as well+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {+			return false;+		}++		try {+			// Not own constructor property must be Object+			if ( obj.constructor &&+				!hasOwn.call(obj, "constructor") &&+				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {+				return false;+			}+		} catch ( e ) {+			// IE8,9 Will throw exceptions on certain host objects #9897+			return false;+		}++		// Own properties are enumerated firstly, so to speed up,+		// if last one is own, then all properties are own.++		var key;+		for ( key in obj ) {}++		return key === undefined || hasOwn.call( obj, key );+	},++	isEmptyObject: function( obj ) {+		for ( var name in obj ) {+			return false;+		}+		return true;+	},++	error: function( msg ) {+		throw new Error( msg );+	},++	parseJSON: function( data ) {+		if ( typeof data !== "string" || !data ) {+			return null;+		}++		// Make sure leading/trailing whitespace is removed (IE can't handle it)+		data = jQuery.trim( data );++		// Attempt to parse using the native JSON parser first+		if ( window.JSON && window.JSON.parse ) {+			return window.JSON.parse( data );+		}++		// Make sure the incoming data is actual JSON+		// Logic borrowed from http://json.org/json2.js+		if ( rvalidchars.test( data.replace( rvalidescape, "@" )+			.replace( rvalidtokens, "]" )+			.replace( rvalidbraces, "")) ) {++			return ( new Function( "return " + data ) )();++		}+		jQuery.error( "Invalid JSON: " + data );+	},++	// Cross-browser xml parsing+	parseXML: function( data ) {+		if ( typeof data !== "string" || !data ) {+			return null;+		}+		var xml, tmp;+		try {+			if ( window.DOMParser ) { // Standard+				tmp = new DOMParser();+				xml = tmp.parseFromString( data , "text/xml" );+			} else { // IE+				xml = new ActiveXObject( "Microsoft.XMLDOM" );+				xml.async = "false";+				xml.loadXML( data );+			}+		} catch( e ) {+			xml = undefined;+		}+		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {+			jQuery.error( "Invalid XML: " + data );+		}+		return xml;+	},++	noop: function() {},++	// Evaluates a script in a global context+	// Workarounds based on findings by Jim Driscoll+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context+	globalEval: function( data ) {+		if ( data && rnotwhite.test( data ) ) {+			// We use execScript on Internet Explorer+			// We use an anonymous function so that context is window+			// rather than jQuery in Firefox+			( window.execScript || function( data ) {+				window[ "eval" ].call( window, data );+			} )( data );+		}+	},++	// Convert dashed to camelCase; used by the css and data modules+	// Microsoft forgot to hump their vendor prefix (#9572)+	camelCase: function( string ) {+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );+	},++	nodeName: function( elem, name ) {+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();+	},++	// args is for internal usage only+	each: function( object, callback, args ) {+		var name, i = 0,+			length = object.length,+			isObj = length === undefined || jQuery.isFunction( object );++		if ( args ) {+			if ( isObj ) {+				for ( name in object ) {+					if ( callback.apply( object[ name ], args ) === false ) {+						break;+					}+				}+			} else {+				for ( ; i < length; ) {+					if ( callback.apply( object[ i++ ], args ) === false ) {+						break;+					}+				}+			}++		// A special, fast, case for the most common use of each+		} else {+			if ( isObj ) {+				for ( name in object ) {+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {+						break;+					}+				}+			} else {+				for ( ; i < length; ) {+					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {+						break;+					}+				}+			}+		}++		return object;+	},++	// Use native String.trim function wherever possible+	trim: trim ?+		function( text ) {+			return text == null ?+				"" :+				trim.call( text );+		} :++		// Otherwise use our own trimming functionality+		function( text ) {+			return text == null ?+				"" :+				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );+		},++	// results is for internal usage only+	makeArray: function( array, results ) {+		var ret = results || [];++		if ( array != null ) {+			// The window, strings (and functions) also have 'length'+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930+			var type = jQuery.type( array );++			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {+				push.call( ret, array );+			} else {+				jQuery.merge( ret, array );+			}+		}++		return ret;+	},++	inArray: function( elem, array, i ) {+		var len;++		if ( array ) {+			if ( indexOf ) {+				return indexOf.call( array, elem, i );+			}++			len = array.length;+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;++			for ( ; i < len; i++ ) {+				// Skip accessing in sparse arrays+				if ( i in array && array[ i ] === elem ) {+					return i;+				}+			}+		}++		return -1;+	},++	merge: function( first, second ) {+		var i = first.length,+			j = 0;++		if ( typeof second.length === "number" ) {+			for ( var l = second.length; j < l; j++ ) {+				first[ i++ ] = second[ j ];+			}++		} else {+			while ( second[j] !== undefined ) {+				first[ i++ ] = second[ j++ ];+			}+		}++		first.length = i;++		return first;+	},++	grep: function( elems, callback, inv ) {+		var ret = [], retVal;+		inv = !!inv;++		// Go through the array, only saving the items+		// that pass the validator function+		for ( var i = 0, length = elems.length; i < length; i++ ) {+			retVal = !!callback( elems[ i ], i );+			if ( inv !== retVal ) {+				ret.push( elems[ i ] );+			}+		}++		return ret;+	},++	// arg is for internal usage only+	map: function( elems, callback, arg ) {+		var value, key, ret = [],+			i = 0,+			length = elems.length,+			// jquery objects are treated as arrays+			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;++		// Go through the array, translating each of the items to their+		if ( isArray ) {+			for ( ; i < length; i++ ) {+				value = callback( elems[ i ], i, arg );++				if ( value != null ) {+					ret[ ret.length ] = value;+				}+			}++		// Go through every key on the object,+		} else {+			for ( key in elems ) {+				value = callback( elems[ key ], key, arg );++				if ( value != null ) {+					ret[ ret.length ] = value;+				}+			}+		}++		// Flatten any nested arrays+		return ret.concat.apply( [], ret );+	},++	// A global GUID counter for objects+	guid: 1,++	// Bind a function to a context, optionally partially applying any+	// arguments.+	proxy: function( fn, context ) {+		if ( typeof context === "string" ) {+			var tmp = fn[ context ];+			context = fn;+			fn = tmp;+		}++		// Quick check to determine if target is callable, in the spec+		// this throws a TypeError, but we will just return undefined.+		if ( !jQuery.isFunction( fn ) ) {+			return undefined;+		}++		// Simulated bind+		var args = slice.call( arguments, 2 ),+			proxy = function() {+				return fn.apply( context, args.concat( slice.call( arguments ) ) );+			};++		// Set the guid of unique handler to the same of original handler, so it can be removed+		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;++		return proxy;+	},++	// Mutifunctional method to get and set values to a collection+	// The value/s can optionally be executed if it's a function+	access: function( elems, fn, key, value, chainable, emptyGet, pass ) {+		var exec,+			bulk = key == null,+			i = 0,+			length = elems.length;++		// Sets many values+		if ( key && typeof key === "object" ) {+			for ( i in key ) {+				jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );+			}+			chainable = 1;++		// Sets one value+		} else if ( value !== undefined ) {+			// Optionally, function values get executed if exec is true+			exec = pass === undefined && jQuery.isFunction( value );++			if ( bulk ) {+				// Bulk operations only iterate when executing function values+				if ( exec ) {+					exec = fn;+					fn = function( elem, key, value ) {+						return exec.call( jQuery( elem ), value );+					};++				// Otherwise they run against the entire set+				} else {+					fn.call( elems, value );+					fn = null;+				}+			}++			if ( fn ) {+				for (; i < length; i++ ) {+					fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );+				}+			}++			chainable = 1;+		}++		return chainable ?+			elems :++			// Gets+			bulk ?+				fn.call( elems ) :+				length ? fn( elems[0], key ) : emptyGet;+	},++	now: function() {+		return ( new Date() ).getTime();+	},++	// Use of jQuery.browser is frowned upon.+	// More details: http://docs.jquery.com/Utilities/jQuery.browser+	uaMatch: function( ua ) {+		ua = ua.toLowerCase();++		var match = rwebkit.exec( ua ) ||+			ropera.exec( ua ) ||+			rmsie.exec( ua ) ||+			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||+			[];++		return { browser: match[1] || "", version: match[2] || "0" };+	},++	sub: function() {+		function jQuerySub( selector, context ) {+			return new jQuerySub.fn.init( selector, context );+		}+		jQuery.extend( true, jQuerySub, this );+		jQuerySub.superclass = this;+		jQuerySub.fn = jQuerySub.prototype = this();+		jQuerySub.fn.constructor = jQuerySub;+		jQuerySub.sub = this.sub;+		jQuerySub.fn.init = function init( selector, context ) {+			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {+				context = jQuerySub( context );+			}++			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );+		};+		jQuerySub.fn.init.prototype = jQuerySub.fn;+		var rootjQuerySub = jQuerySub(document);+		return jQuerySub;+	},++	browser: {}+});++// Populate the class2type map+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {+	class2type[ "[object " + name + "]" ] = name.toLowerCase();+});++browserMatch = jQuery.uaMatch( userAgent );+if ( browserMatch.browser ) {+	jQuery.browser[ browserMatch.browser ] = true;+	jQuery.browser.version = browserMatch.version;+}++// Deprecated, use jQuery.browser.webkit instead+if ( jQuery.browser.webkit ) {+	jQuery.browser.safari = true;+}++// IE doesn't match non-breaking spaces with \s+if ( rnotwhite.test( "\xA0" ) ) {+	trimLeft = /^[\s\xA0]+/;+	trimRight = /[\s\xA0]+$/;+}++// All jQuery objects should point back to these+rootjQuery = jQuery(document);++// Cleanup functions for the document ready method+if ( document.addEventListener ) {+	DOMContentLoaded = function() {+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );+		jQuery.ready();+	};++} else if ( document.attachEvent ) {+	DOMContentLoaded = function() {+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+		if ( document.readyState === "complete" ) {+			document.detachEvent( "onreadystatechange", DOMContentLoaded );+			jQuery.ready();+		}+	};+}++// The DOM ready check for Internet Explorer+function doScrollCheck() {+	if ( jQuery.isReady ) {+		return;+	}++	try {+		// If IE is used, use the trick by Diego Perini+		// http://javascript.nwbox.com/IEContentLoaded/+		document.documentElement.doScroll("left");+	} catch(e) {+		setTimeout( doScrollCheck, 1 );+		return;+	}++	// and execute any waiting functions+	jQuery.ready();+}++return jQuery;++})();+++// String to Object flags format cache+var flagsCache = {};++// Convert String-formatted flags into Object-formatted ones and store in cache+function createFlags( flags ) {+	var object = flagsCache[ flags ] = {},+		i, length;+	flags = flags.split( /\s+/ );+	for ( i = 0, length = flags.length; i < length; i++ ) {+		object[ flags[i] ] = true;+	}+	return object;+}++/*+ * Create a callback list using the following parameters:+ *+ *	flags:	an optional list of space-separated flags that will change how+ *			the callback list behaves+ *+ * By default a callback list will act like an event callback list and can be+ * "fired" multiple times.+ *+ * Possible flags:+ *+ *	once:			will ensure the callback list can only be fired once (like a Deferred)+ *+ *	memory:			will keep track of previous values and will call any callback added+ *					after the list has been fired right away with the latest "memorized"+ *					values (like a Deferred)+ *+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)+ *+ *	stopOnFalse:	interrupt callings when a callback returns false+ *+ */+jQuery.Callbacks = function( flags ) {++	// Convert flags from String-formatted to Object-formatted+	// (we check in cache first)+	flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};++	var // Actual callback list+		list = [],+		// Stack of fire calls for repeatable lists+		stack = [],+		// Last fire value (for non-forgettable lists)+		memory,+		// Flag to know if list was already fired+		fired,+		// Flag to know if list is currently firing+		firing,+		// First callback to fire (used internally by add and fireWith)+		firingStart,+		// End of the loop when firing+		firingLength,+		// Index of currently firing callback (modified by remove if needed)+		firingIndex,+		// Add one or several callbacks to the list+		add = function( args ) {+			var i,+				length,+				elem,+				type,+				actual;+			for ( i = 0, length = args.length; i < length; i++ ) {+				elem = args[ i ];+				type = jQuery.type( elem );+				if ( type === "array" ) {+					// Inspect recursively+					add( elem );+				} else if ( type === "function" ) {+					// Add if not in unique mode and callback is not in+					if ( !flags.unique || !self.has( elem ) ) {+						list.push( elem );+					}+				}+			}+		},+		// Fire callbacks+		fire = function( context, args ) {+			args = args || [];+			memory = !flags.memory || [ context, args ];+			fired = true;+			firing = true;+			firingIndex = firingStart || 0;+			firingStart = 0;+			firingLength = list.length;+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {+				if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {+					memory = true; // Mark as halted+					break;+				}+			}+			firing = false;+			if ( list ) {+				if ( !flags.once ) {+					if ( stack && stack.length ) {+						memory = stack.shift();+						self.fireWith( memory[ 0 ], memory[ 1 ] );+					}+				} else if ( memory === true ) {+					self.disable();+				} else {+					list = [];+				}+			}+		},+		// Actual Callbacks object+		self = {+			// Add a callback or a collection of callbacks to the list+			add: function() {+				if ( list ) {+					var length = list.length;+					add( arguments );+					// Do we need to add the callbacks to the+					// current firing batch?+					if ( firing ) {+						firingLength = list.length;+					// With memory, if we're not firing then+					// we should call right away, unless previous+					// firing was halted (stopOnFalse)+					} else if ( memory && memory !== true ) {+						firingStart = length;+						fire( memory[ 0 ], memory[ 1 ] );+					}+				}+				return this;+			},+			// Remove a callback from the list+			remove: function() {+				if ( list ) {+					var args = arguments,+						argIndex = 0,+						argLength = args.length;+					for ( ; argIndex < argLength ; argIndex++ ) {+						for ( var i = 0; i < list.length; i++ ) {+							if ( args[ argIndex ] === list[ i ] ) {+								// Handle firingIndex and firingLength+								if ( firing ) {+									if ( i <= firingLength ) {+										firingLength--;+										if ( i <= firingIndex ) {+											firingIndex--;+										}+									}+								}+								// Remove the element+								list.splice( i--, 1 );+								// If we have some unicity property then+								// we only need to do this once+								if ( flags.unique ) {+									break;+								}+							}+						}+					}+				}+				return this;+			},+			// Control if a given callback is in the list+			has: function( fn ) {+				if ( list ) {+					var i = 0,+						length = list.length;+					for ( ; i < length; i++ ) {+						if ( fn === list[ i ] ) {+							return true;+						}+					}+				}+				return false;+			},+			// Remove all callbacks from the list+			empty: function() {+				list = [];+				return this;+			},+			// Have the list do nothing anymore+			disable: function() {+				list = stack = memory = undefined;+				return this;+			},+			// Is it disabled?+			disabled: function() {+				return !list;+			},+			// Lock the list in its current state+			lock: function() {+				stack = undefined;+				if ( !memory || memory === true ) {+					self.disable();+				}+				return this;+			},+			// Is it locked?+			locked: function() {+				return !stack;+			},+			// Call all callbacks with the given context and arguments+			fireWith: function( context, args ) {+				if ( stack ) {+					if ( firing ) {+						if ( !flags.once ) {+							stack.push( [ context, args ] );+						}+					} else if ( !( flags.once && memory ) ) {+						fire( context, args );+					}+				}+				return this;+			},+			// Call all the callbacks with the given arguments+			fire: function() {+				self.fireWith( this, arguments );+				return this;+			},+			// To know if the callbacks have already been called at least once+			fired: function() {+				return !!fired;+			}+		};++	return self;+};+++++var // Static reference to slice+	sliceDeferred = [].slice;++jQuery.extend({++	Deferred: function( func ) {+		var doneList = jQuery.Callbacks( "once memory" ),+			failList = jQuery.Callbacks( "once memory" ),+			progressList = jQuery.Callbacks( "memory" ),+			state = "pending",+			lists = {+				resolve: doneList,+				reject: failList,+				notify: progressList+			},+			promise = {+				done: doneList.add,+				fail: failList.add,+				progress: progressList.add,++				state: function() {+					return state;+				},++				// Deprecated+				isResolved: doneList.fired,+				isRejected: failList.fired,++				then: function( doneCallbacks, failCallbacks, progressCallbacks ) {+					deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );+					return this;+				},+				always: function() {+					deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );+					return this;+				},+				pipe: function( fnDone, fnFail, fnProgress ) {+					return jQuery.Deferred(function( newDefer ) {+						jQuery.each( {+							done: [ fnDone, "resolve" ],+							fail: [ fnFail, "reject" ],+							progress: [ fnProgress, "notify" ]+						}, function( handler, data ) {+							var fn = data[ 0 ],+								action = data[ 1 ],+								returned;+							if ( jQuery.isFunction( fn ) ) {+								deferred[ handler ](function() {+									returned = fn.apply( this, arguments );+									if ( returned && jQuery.isFunction( returned.promise ) ) {+										returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );+									} else {+										newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );+									}+								});+							} else {+								deferred[ handler ]( newDefer[ action ] );+							}+						});+					}).promise();+				},+				// Get a promise for this deferred+				// If obj is provided, the promise aspect is added to the object+				promise: function( obj ) {+					if ( obj == null ) {+						obj = promise;+					} else {+						for ( var key in promise ) {+							obj[ key ] = promise[ key ];+						}+					}+					return obj;+				}+			},+			deferred = promise.promise({}),+			key;++		for ( key in lists ) {+			deferred[ key ] = lists[ key ].fire;+			deferred[ key + "With" ] = lists[ key ].fireWith;+		}++		// Handle state+		deferred.done( function() {+			state = "resolved";+		}, failList.disable, progressList.lock ).fail( function() {+			state = "rejected";+		}, doneList.disable, progressList.lock );++		// Call given func if any+		if ( func ) {+			func.call( deferred, deferred );+		}++		// All done!+		return deferred;+	},++	// Deferred helper+	when: function( firstParam ) {+		var args = sliceDeferred.call( arguments, 0 ),+			i = 0,+			length = args.length,+			pValues = new Array( length ),+			count = length,+			pCount = length,+			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?+				firstParam :+				jQuery.Deferred(),+			promise = deferred.promise();+		function resolveFunc( i ) {+			return function( value ) {+				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;+				if ( !( --count ) ) {+					deferred.resolveWith( deferred, args );+				}+			};+		}+		function progressFunc( i ) {+			return function( value ) {+				pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;+				deferred.notifyWith( promise, pValues );+			};+		}+		if ( length > 1 ) {+			for ( ; i < length; i++ ) {+				if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {+					args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );+				} else {+					--count;+				}+			}+			if ( !count ) {+				deferred.resolveWith( deferred, args );+			}+		} else if ( deferred !== firstParam ) {+			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );+		}+		return promise;+	}+});+++++jQuery.support = (function() {++	var support,+		all,+		a,+		select,+		opt,+		input,+		fragment,+		tds,+		events,+		eventName,+		i,+		isSupported,+		div = document.createElement( "div" ),+		documentElement = document.documentElement;++	// Preliminary tests+	div.setAttribute("className", "t");+	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";++	all = div.getElementsByTagName( "*" );+	a = div.getElementsByTagName( "a" )[ 0 ];++	// Can't get basic test support+	if ( !all || !all.length || !a ) {+		return {};+	}++	// First batch of supports tests+	select = document.createElement( "select" );+	opt = select.appendChild( document.createElement("option") );+	input = div.getElementsByTagName( "input" )[ 0 ];++	support = {+		// IE strips leading whitespace when .innerHTML is used+		leadingWhitespace: ( div.firstChild.nodeType === 3 ),++		// Make sure that tbody elements aren't automatically inserted+		// IE will insert them into empty tables+		tbody: !div.getElementsByTagName("tbody").length,++		// Make sure that link elements get serialized correctly by innerHTML+		// This requires a wrapper element in IE+		htmlSerialize: !!div.getElementsByTagName("link").length,++		// Get the style information from getAttribute+		// (IE uses .cssText instead)+		style: /top/.test( a.getAttribute("style") ),++		// Make sure that URLs aren't manipulated+		// (IE normalizes it by default)+		hrefNormalized: ( a.getAttribute("href") === "/a" ),++		// Make sure that element opacity exists+		// (IE uses filter instead)+		// Use a regex to work around a WebKit issue. See #5145+		opacity: /^0.55/.test( a.style.opacity ),++		// Verify style float existence+		// (IE uses styleFloat instead of cssFloat)+		cssFloat: !!a.style.cssFloat,++		// Make sure that if no value is specified for a checkbox+		// that it defaults to "on".+		// (WebKit defaults to "" instead)+		checkOn: ( input.value === "on" ),++		// Make sure that a selected-by-default option has a working selected property.+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)+		optSelected: opt.selected,++		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)+		getSetAttribute: div.className !== "t",++		// Tests for enctype support on a form(#6743)+		enctype: !!document.createElement("form").enctype,++		// Makes sure cloning an html5 element does not cause problems+		// Where outerHTML is undefined, this still works+		html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",++		// Will be defined later+		submitBubbles: true,+		changeBubbles: true,+		focusinBubbles: false,+		deleteExpando: true,+		noCloneEvent: true,+		inlineBlockNeedsLayout: false,+		shrinkWrapBlocks: false,+		reliableMarginRight: true,+		pixelMargin: true+	};++	// jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead+	jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");++	// Make sure checked status is properly cloned+	input.checked = true;+	support.noCloneChecked = input.cloneNode( true ).checked;++	// Make sure that the options inside disabled selects aren't marked as disabled+	// (WebKit marks them as disabled)+	select.disabled = true;+	support.optDisabled = !opt.disabled;++	// Test to see if it's possible to delete an expando from an element+	// Fails in Internet Explorer+	try {+		delete div.test;+	} catch( e ) {+		support.deleteExpando = false;+	}++	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {+		div.attachEvent( "onclick", function() {+			// Cloning a node shouldn't copy over any+			// bound event handlers (IE does this)+			support.noCloneEvent = false;+		});+		div.cloneNode( true ).fireEvent( "onclick" );+	}++	// Check if a radio maintains its value+	// after being appended to the DOM+	input = document.createElement("input");+	input.value = "t";+	input.setAttribute("type", "radio");+	support.radioValue = input.value === "t";++	input.setAttribute("checked", "checked");++	// #11217 - WebKit loses check when the name is after the checked attribute+	input.setAttribute( "name", "t" );++	div.appendChild( input );+	fragment = document.createDocumentFragment();+	fragment.appendChild( div.lastChild );++	// WebKit doesn't clone checked state correctly in fragments+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;++	// Check if a disconnected checkbox will retain its checked+	// value of true after appended to the DOM (IE6/7)+	support.appendChecked = input.checked;++	fragment.removeChild( input );+	fragment.appendChild( div );++	// Technique from Juriy Zaytsev+	// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/+	// We only care about the case where non-standard event systems+	// are used, namely in IE. Short-circuiting here helps us to+	// avoid an eval call (in setAttribute) which can cause CSP+	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP+	if ( div.attachEvent ) {+		for ( i in {+			submit: 1,+			change: 1,+			focusin: 1+		}) {+			eventName = "on" + i;+			isSupported = ( eventName in div );+			if ( !isSupported ) {+				div.setAttribute( eventName, "return;" );+				isSupported = ( typeof div[ eventName ] === "function" );+			}+			support[ i + "Bubbles" ] = isSupported;+		}+	}++	fragment.removeChild( div );++	// Null elements to avoid leaks in IE+	fragment = select = opt = div = input = null;++	// Run tests that need a body at doc ready+	jQuery(function() {+		var container, outer, inner, table, td, offsetSupport,+			marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,+			paddingMarginBorderVisibility, paddingMarginBorder,+			body = document.getElementsByTagName("body")[0];++		if ( !body ) {+			// Return for frameset docs that don't have a body+			return;+		}++		conMarginTop = 1;+		paddingMarginBorder = "padding:0;margin:0;border:";+		positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";+		paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";+		style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";+		html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" ++			"<table " + style + "' cellpadding='0' cellspacing='0'>" ++			"<tr><td></td></tr></table>";++		container = document.createElement("div");+		container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";+		body.insertBefore( container, body.firstChild );++		// Construct the test element+		div = document.createElement("div");+		container.appendChild( div );++		// Check if table cells still have offsetWidth/Height when they are set+		// to display:none and there are still other visible table cells in a+		// table row; if so, offsetWidth/Height are not reliable for use when+		// determining if an element has been hidden directly using+		// display:none (it is still safe to use offsets if a parent element is+		// hidden; don safety goggles and see bug #4512 for more information).+		// (only IE 8 fails this test)+		div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";+		tds = div.getElementsByTagName( "td" );+		isSupported = ( tds[ 0 ].offsetHeight === 0 );++		tds[ 0 ].style.display = "";+		tds[ 1 ].style.display = "none";++		// Check if empty table cells still have offsetWidth/Height+		// (IE <= 8 fail this test)+		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );++		// Check if div with explicit width and no margin-right incorrectly+		// gets computed margin-right based on width of container. For more+		// info see bug #3333+		// Fails in WebKit before Feb 2011 nightlies+		// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right+		if ( window.getComputedStyle ) {+			div.innerHTML = "";+			marginDiv = document.createElement( "div" );+			marginDiv.style.width = "0";+			marginDiv.style.marginRight = "0";+			div.style.width = "2px";+			div.appendChild( marginDiv );+			support.reliableMarginRight =+				( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;+		}++		if ( typeof div.style.zoom !== "undefined" ) {+			// Check if natively block-level elements act like inline-block+			// elements when setting their display to 'inline' and giving+			// them layout+			// (IE < 8 does this)+			div.innerHTML = "";+			div.style.width = div.style.padding = "1px";+			div.style.border = 0;+			div.style.overflow = "hidden";+			div.style.display = "inline";+			div.style.zoom = 1;+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );++			// Check if elements with layout shrink-wrap their children+			// (IE 6 does this)+			div.style.display = "block";+			div.style.overflow = "visible";+			div.innerHTML = "<div style='width:5px;'></div>";+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );+		}++		div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;+		div.innerHTML = html;++		outer = div.firstChild;+		inner = outer.firstChild;+		td = outer.nextSibling.firstChild.firstChild;++		offsetSupport = {+			doesNotAddBorder: ( inner.offsetTop !== 5 ),+			doesAddBorderForTableAndCells: ( td.offsetTop === 5 )+		};++		inner.style.position = "fixed";+		inner.style.top = "20px";++		// safari subtracts parent border width here which is 5px+		offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );+		inner.style.position = inner.style.top = "";++		outer.style.overflow = "hidden";+		outer.style.position = "relative";++		offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );+		offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );++		if ( window.getComputedStyle ) {+			div.style.marginTop = "1%";+			support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";+		}++		if ( typeof container.style.zoom !== "undefined" ) {+			container.style.zoom = 1;+		}++		body.removeChild( container );+		marginDiv = div = container = null;++		jQuery.extend( support, offsetSupport );+	});++	return support;+})();+++++var rbrace = /^(?:\{.*\}|\[.*\])$/,+	rmultiDash = /([A-Z])/g;++jQuery.extend({+	cache: {},++	// Please use with caution+	uuid: 0,++	// Unique for each copy of jQuery on the page+	// Non-digits removed to match rinlinejQuery+	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),++	// The following elements throw uncatchable exceptions if you+	// attempt to add expando properties to them.+	noData: {+		"embed": true,+		// Ban all objects except for Flash (which handle expandos)+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",+		"applet": true+	},++	hasData: function( elem ) {+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];+		return !!elem && !isEmptyDataObject( elem );+	},++	data: function( elem, name, data, pvt /* Internal Use Only */ ) {+		if ( !jQuery.acceptData( elem ) ) {+			return;+		}++		var privateCache, thisCache, ret,+			internalKey = jQuery.expando,+			getByName = typeof name === "string",++			// We have to handle DOM nodes and JS objects differently because IE6-7+			// can't GC object references properly across the DOM-JS boundary+			isNode = elem.nodeType,++			// Only DOM nodes need the global jQuery cache; JS object data is+			// attached directly to the object so GC can occur automatically+			cache = isNode ? jQuery.cache : elem,++			// Only defining an ID for JS objects if its cache already exists allows+			// the code to shortcut on the same path as a DOM node with no cache+			id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,+			isEvents = name === "events";++		// Avoid doing any more work than we need to when trying to get data on an+		// object that has no data at all+		if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {+			return;+		}++		if ( !id ) {+			// Only DOM nodes need a new unique ID for each element since their data+			// ends up in the global cache+			if ( isNode ) {+				elem[ internalKey ] = id = ++jQuery.uuid;+			} else {+				id = internalKey;+			}+		}++		if ( !cache[ id ] ) {+			cache[ id ] = {};++			// Avoids exposing jQuery metadata on plain JS objects when the object+			// is serialized using JSON.stringify+			if ( !isNode ) {+				cache[ id ].toJSON = jQuery.noop;+			}+		}++		// An object can be passed to jQuery.data instead of a key/value pair; this gets+		// shallow copied over onto the existing cache+		if ( typeof name === "object" || typeof name === "function" ) {+			if ( pvt ) {+				cache[ id ] = jQuery.extend( cache[ id ], name );+			} else {+				cache[ id ].data = jQuery.extend( cache[ id ].data, name );+			}+		}++		privateCache = thisCache = cache[ id ];++		// jQuery data() is stored in a separate object inside the object's internal data+		// cache in order to avoid key collisions between internal data and user-defined+		// data.+		if ( !pvt ) {+			if ( !thisCache.data ) {+				thisCache.data = {};+			}++			thisCache = thisCache.data;+		}++		if ( data !== undefined ) {+			thisCache[ jQuery.camelCase( name ) ] = data;+		}++		// Users should not attempt to inspect the internal events object using jQuery.data,+		// it is undocumented and subject to change. But does anyone listen? No.+		if ( isEvents && !thisCache[ name ] ) {+			return privateCache.events;+		}++		// Check for both converted-to-camel and non-converted data property names+		// If a data property was specified+		if ( getByName ) {++			// First Try to find as-is property data+			ret = thisCache[ name ];++			// Test for null|undefined property data+			if ( ret == null ) {++				// Try to find the camelCased property+				ret = thisCache[ jQuery.camelCase( name ) ];+			}+		} else {+			ret = thisCache;+		}++		return ret;+	},++	removeData: function( elem, name, pvt /* Internal Use Only */ ) {+		if ( !jQuery.acceptData( elem ) ) {+			return;+		}++		var thisCache, i, l,++			// Reference to internal data cache key+			internalKey = jQuery.expando,++			isNode = elem.nodeType,++			// See jQuery.data for more information+			cache = isNode ? jQuery.cache : elem,++			// See jQuery.data for more information+			id = isNode ? elem[ internalKey ] : internalKey;++		// If there is already no cache entry for this object, there is no+		// purpose in continuing+		if ( !cache[ id ] ) {+			return;+		}++		if ( name ) {++			thisCache = pvt ? cache[ id ] : cache[ id ].data;++			if ( thisCache ) {++				// Support array or space separated string names for data keys+				if ( !jQuery.isArray( name ) ) {++					// try the string as a key before any manipulation+					if ( name in thisCache ) {+						name = [ name ];+					} else {++						// split the camel cased version by spaces unless a key with the spaces exists+						name = jQuery.camelCase( name );+						if ( name in thisCache ) {+							name = [ name ];+						} else {+							name = name.split( " " );+						}+					}+				}++				for ( i = 0, l = name.length; i < l; i++ ) {+					delete thisCache[ name[i] ];+				}++				// If there is no data left in the cache, we want to continue+				// and let the cache object itself get destroyed+				if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {+					return;+				}+			}+		}++		// See jQuery.data for more information+		if ( !pvt ) {+			delete cache[ id ].data;++			// Don't destroy the parent cache unless the internal data object+			// had been the only thing left in it+			if ( !isEmptyDataObject(cache[ id ]) ) {+				return;+			}+		}++		// Browsers that fail expando deletion also refuse to delete expandos on+		// the window, but it will allow it on all other JS objects; other browsers+		// don't care+		// Ensure that `cache` is not a window object #10080+		if ( jQuery.support.deleteExpando || !cache.setInterval ) {+			delete cache[ id ];+		} else {+			cache[ id ] = null;+		}++		// We destroyed the cache and need to eliminate the expando on the node to avoid+		// false lookups in the cache for entries that no longer exist+		if ( isNode ) {+			// IE does not allow us to delete expando properties from nodes,+			// nor does it have a removeAttribute function on Document nodes;+			// we must handle all of these cases+			if ( jQuery.support.deleteExpando ) {+				delete elem[ internalKey ];+			} else if ( elem.removeAttribute ) {+				elem.removeAttribute( internalKey );+			} else {+				elem[ internalKey ] = null;+			}+		}+	},++	// For internal use only.+	_data: function( elem, name, data ) {+		return jQuery.data( elem, name, data, true );+	},++	// A method for determining if a DOM node can handle the data expando+	acceptData: function( elem ) {+		if ( elem.nodeName ) {+			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];++			if ( match ) {+				return !(match === true || elem.getAttribute("classid") !== match);+			}+		}++		return true;+	}+});++jQuery.fn.extend({+	data: function( key, value ) {+		var parts, part, attr, name, l,+			elem = this[0],+			i = 0,+			data = null;++		// Gets all values+		if ( key === undefined ) {+			if ( this.length ) {+				data = jQuery.data( elem );++				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {+					attr = elem.attributes;+					for ( l = attr.length; i < l; i++ ) {+						name = attr[i].name;++						if ( name.indexOf( "data-" ) === 0 ) {+							name = jQuery.camelCase( name.substring(5) );++							dataAttr( elem, name, data[ name ] );+						}+					}+					jQuery._data( elem, "parsedAttrs", true );+				}+			}++			return data;+		}++		// Sets multiple values+		if ( typeof key === "object" ) {+			return this.each(function() {+				jQuery.data( this, key );+			});+		}++		parts = key.split( ".", 2 );+		parts[1] = parts[1] ? "." + parts[1] : "";+		part = parts[1] + "!";++		return jQuery.access( this, function( value ) {++			if ( value === undefined ) {+				data = this.triggerHandler( "getData" + part, [ parts[0] ] );++				// Try to fetch any internally stored data first+				if ( data === undefined && elem ) {+					data = jQuery.data( elem, key );+					data = dataAttr( elem, key, data );+				}++				return data === undefined && parts[1] ?+					this.data( parts[0] ) :+					data;+			}++			parts[1] = value;+			this.each(function() {+				var self = jQuery( this );++				self.triggerHandler( "setData" + part, parts );+				jQuery.data( this, key, value );+				self.triggerHandler( "changeData" + part, parts );+			});+		}, null, value, arguments.length > 1, null, false );+	},++	removeData: function( key ) {+		return this.each(function() {+			jQuery.removeData( this, key );+		});+	}+});++function dataAttr( elem, key, data ) {+	// If nothing was found internally, try to fetch any+	// data from the HTML5 data-* attribute+	if ( data === undefined && elem.nodeType === 1 ) {++		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();++		data = elem.getAttribute( name );++		if ( typeof data === "string" ) {+			try {+				data = data === "true" ? true :+				data === "false" ? false :+				data === "null" ? null :+				jQuery.isNumeric( data ) ? +data :+					rbrace.test( data ) ? jQuery.parseJSON( data ) :+					data;+			} catch( e ) {}++			// Make sure we set the data so it isn't changed later+			jQuery.data( elem, key, data );++		} else {+			data = undefined;+		}+	}++	return data;+}++// checks a cache object for emptiness+function isEmptyDataObject( obj ) {+	for ( var name in obj ) {++		// if the public data object is empty, the private is still empty+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {+			continue;+		}+		if ( name !== "toJSON" ) {+			return false;+		}+	}++	return true;+}+++++function handleQueueMarkDefer( elem, type, src ) {+	var deferDataKey = type + "defer",+		queueDataKey = type + "queue",+		markDataKey = type + "mark",+		defer = jQuery._data( elem, deferDataKey );+	if ( defer &&+		( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&+		( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {+		// Give room for hard-coded callbacks to fire first+		// and eventually mark/queue something else on the element+		setTimeout( function() {+			if ( !jQuery._data( elem, queueDataKey ) &&+				!jQuery._data( elem, markDataKey ) ) {+				jQuery.removeData( elem, deferDataKey, true );+				defer.fire();+			}+		}, 0 );+	}+}++jQuery.extend({++	_mark: function( elem, type ) {+		if ( elem ) {+			type = ( type || "fx" ) + "mark";+			jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );+		}+	},++	_unmark: function( force, elem, type ) {+		if ( force !== true ) {+			type = elem;+			elem = force;+			force = false;+		}+		if ( elem ) {+			type = type || "fx";+			var key = type + "mark",+				count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );+			if ( count ) {+				jQuery._data( elem, key, count );+			} else {+				jQuery.removeData( elem, key, true );+				handleQueueMarkDefer( elem, type, "mark" );+			}+		}+	},++	queue: function( elem, type, data ) {+		var q;+		if ( elem ) {+			type = ( type || "fx" ) + "queue";+			q = jQuery._data( elem, type );++			// Speed up dequeue by getting out quickly if this is just a lookup+			if ( data ) {+				if ( !q || jQuery.isArray(data) ) {+					q = jQuery._data( elem, type, jQuery.makeArray(data) );+				} else {+					q.push( data );+				}+			}+			return q || [];+		}+	},++	dequeue: function( elem, type ) {+		type = type || "fx";++		var queue = jQuery.queue( elem, type ),+			fn = queue.shift(),+			hooks = {};++		// If the fx queue is dequeued, always remove the progress sentinel+		if ( fn === "inprogress" ) {+			fn = queue.shift();+		}++		if ( fn ) {+			// Add a progress sentinel to prevent the fx queue from being+			// automatically dequeued+			if ( type === "fx" ) {+				queue.unshift( "inprogress" );+			}++			jQuery._data( elem, type + ".run", hooks );+			fn.call( elem, function() {+				jQuery.dequeue( elem, type );+			}, hooks );+		}++		if ( !queue.length ) {+			jQuery.removeData( elem, type + "queue " + type + ".run", true );+			handleQueueMarkDefer( elem, type, "queue" );+		}+	}+});++jQuery.fn.extend({+	queue: function( type, data ) {+		var setter = 2;++		if ( typeof type !== "string" ) {+			data = type;+			type = "fx";+			setter--;+		}++		if ( arguments.length < setter ) {+			return jQuery.queue( this[0], type );+		}++		return data === undefined ?+			this :+			this.each(function() {+				var queue = jQuery.queue( this, type, data );++				if ( type === "fx" && queue[0] !== "inprogress" ) {+					jQuery.dequeue( this, type );+				}+			});+	},+	dequeue: function( type ) {+		return this.each(function() {+			jQuery.dequeue( this, type );+		});+	},+	// Based off of the plugin by Clint Helfers, with permission.+	// http://blindsignals.com/index.php/2009/07/jquery-delay/+	delay: function( time, type ) {+		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;+		type = type || "fx";++		return this.queue( type, function( next, hooks ) {+			var timeout = setTimeout( next, time );+			hooks.stop = function() {+				clearTimeout( timeout );+			};+		});+	},+	clearQueue: function( type ) {+		return this.queue( type || "fx", [] );+	},+	// Get a promise resolved when queues of a certain type+	// are emptied (fx is the type by default)+	promise: function( type, object ) {+		if ( typeof type !== "string" ) {+			object = type;+			type = undefined;+		}+		type = type || "fx";+		var defer = jQuery.Deferred(),+			elements = this,+			i = elements.length,+			count = 1,+			deferDataKey = type + "defer",+			queueDataKey = type + "queue",+			markDataKey = type + "mark",+			tmp;+		function resolve() {+			if ( !( --count ) ) {+				defer.resolveWith( elements, [ elements ] );+			}+		}+		while( i-- ) {+			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||+					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||+						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&+					jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {+				count++;+				tmp.add( resolve );+			}+		}+		resolve();+		return defer.promise( object );+	}+});+++++var rclass = /[\n\t\r]/g,+	rspace = /\s+/,+	rreturn = /\r/g,+	rtype = /^(?:button|input)$/i,+	rfocusable = /^(?:button|input|object|select|textarea)$/i,+	rclickable = /^a(?:rea)?$/i,+	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,+	getSetAttribute = jQuery.support.getSetAttribute,+	nodeHook, boolHook, fixSpecified;++jQuery.fn.extend({+	attr: function( name, value ) {+		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );+	},++	removeAttr: function( name ) {+		return this.each(function() {+			jQuery.removeAttr( this, name );+		});+	},++	prop: function( name, value ) {+		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );+	},++	removeProp: function( name ) {+		name = jQuery.propFix[ name ] || name;+		return this.each(function() {+			// try/catch handles cases where IE balks (such as removing a property on window)+			try {+				this[ name ] = undefined;+				delete this[ name ];+			} catch( e ) {}+		});+	},++	addClass: function( value ) {+		var classNames, i, l, elem,+			setClass, c, cl;++		if ( jQuery.isFunction( value ) ) {+			return this.each(function( j ) {+				jQuery( this ).addClass( value.call(this, j, this.className) );+			});+		}++		if ( value && typeof value === "string" ) {+			classNames = value.split( rspace );++			for ( i = 0, l = this.length; i < l; i++ ) {+				elem = this[ i ];++				if ( elem.nodeType === 1 ) {+					if ( !elem.className && classNames.length === 1 ) {+						elem.className = value;++					} else {+						setClass = " " + elem.className + " ";++						for ( c = 0, cl = classNames.length; c < cl; c++ ) {+							if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {+								setClass += classNames[ c ] + " ";+							}+						}+						elem.className = jQuery.trim( setClass );+					}+				}+			}+		}++		return this;+	},++	removeClass: function( value ) {+		var classNames, i, l, elem, className, c, cl;++		if ( jQuery.isFunction( value ) ) {+			return this.each(function( j ) {+				jQuery( this ).removeClass( value.call(this, j, this.className) );+			});+		}++		if ( (value && typeof value === "string") || value === undefined ) {+			classNames = ( value || "" ).split( rspace );++			for ( i = 0, l = this.length; i < l; i++ ) {+				elem = this[ i ];++				if ( elem.nodeType === 1 && elem.className ) {+					if ( value ) {+						className = (" " + elem.className + " ").replace( rclass, " " );+						for ( c = 0, cl = classNames.length; c < cl; c++ ) {+							className = className.replace(" " + classNames[ c ] + " ", " ");+						}+						elem.className = jQuery.trim( className );++					} else {+						elem.className = "";+					}+				}+			}+		}++		return this;+	},++	toggleClass: function( value, stateVal ) {+		var type = typeof value,+			isBool = typeof stateVal === "boolean";++		if ( jQuery.isFunction( value ) ) {+			return this.each(function( i ) {+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );+			});+		}++		return this.each(function() {+			if ( type === "string" ) {+				// toggle individual class names+				var className,+					i = 0,+					self = jQuery( this ),+					state = stateVal,+					classNames = value.split( rspace );++				while ( (className = classNames[ i++ ]) ) {+					// check each className given, space seperated list+					state = isBool ? state : !self.hasClass( className );+					self[ state ? "addClass" : "removeClass" ]( className );+				}++			} else if ( type === "undefined" || type === "boolean" ) {+				if ( this.className ) {+					// store className if set+					jQuery._data( this, "__className__", this.className );+				}++				// toggle whole className+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";+			}+		});+	},++	hasClass: function( selector ) {+		var className = " " + selector + " ",+			i = 0,+			l = this.length;+		for ( ; i < l; i++ ) {+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {+				return true;+			}+		}++		return false;+	},++	val: function( value ) {+		var hooks, ret, isFunction,+			elem = this[0];++		if ( !arguments.length ) {+			if ( elem ) {+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];++				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {+					return ret;+				}++				ret = elem.value;++				return typeof ret === "string" ?+					// handle most common string cases+					ret.replace(rreturn, "") :+					// handle cases where value is null/undef or number+					ret == null ? "" : ret;+			}++			return;+		}++		isFunction = jQuery.isFunction( value );++		return this.each(function( i ) {+			var self = jQuery(this), val;++			if ( this.nodeType !== 1 ) {+				return;+			}++			if ( isFunction ) {+				val = value.call( this, i, self.val() );+			} else {+				val = value;+			}++			// Treat null/undefined as ""; convert numbers to string+			if ( val == null ) {+				val = "";+			} else if ( typeof val === "number" ) {+				val += "";+			} else if ( jQuery.isArray( val ) ) {+				val = jQuery.map(val, function ( value ) {+					return value == null ? "" : value + "";+				});+			}++			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];++			// If set returns undefined, fall back to normal setting+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {+				this.value = val;+			}+		});+	}+});++jQuery.extend({+	valHooks: {+		option: {+			get: function( elem ) {+				// attributes.value is undefined in Blackberry 4.7 but+				// uses .value. See #6932+				var val = elem.attributes.value;+				return !val || val.specified ? elem.value : elem.text;+			}+		},+		select: {+			get: function( elem ) {+				var value, i, max, option,+					index = elem.selectedIndex,+					values = [],+					options = elem.options,+					one = elem.type === "select-one";++				// Nothing was selected+				if ( index < 0 ) {+					return null;+				}++				// Loop through all the selected options+				i = one ? index : 0;+				max = one ? index + 1 : options.length;+				for ( ; i < max; i++ ) {+					option = options[ i ];++					// Don't return options that are disabled or in a disabled optgroup+					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&+							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {++						// Get the specific value for the option+						value = jQuery( option ).val();++						// We don't need an array for one selects+						if ( one ) {+							return value;+						}++						// Multi-Selects return an array+						values.push( value );+					}+				}++				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()+				if ( one && !values.length && options.length ) {+					return jQuery( options[ index ] ).val();+				}++				return values;+			},++			set: function( elem, value ) {+				var values = jQuery.makeArray( value );++				jQuery(elem).find("option").each(function() {+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;+				});++				if ( !values.length ) {+					elem.selectedIndex = -1;+				}+				return values;+			}+		}+	},++	attrFn: {+		val: true,+		css: true,+		html: true,+		text: true,+		data: true,+		width: true,+		height: true,+		offset: true+	},++	attr: function( elem, name, value, pass ) {+		var ret, hooks, notxml,+			nType = elem.nodeType;++		// don't get/set attributes on text, comment and attribute nodes+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {+			return;+		}++		if ( pass && name in jQuery.attrFn ) {+			return jQuery( elem )[ name ]( value );+		}++		// Fallback to prop when attributes are not supported+		if ( typeof elem.getAttribute === "undefined" ) {+			return jQuery.prop( elem, name, value );+		}++		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );++		// All attributes are lowercase+		// Grab necessary hook if one is defined+		if ( notxml ) {+			name = name.toLowerCase();+			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );+		}++		if ( value !== undefined ) {++			if ( value === null ) {+				jQuery.removeAttr( elem, name );+				return;++			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {+				return ret;++			} else {+				elem.setAttribute( name, "" + value );+				return value;+			}++		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {+			return ret;++		} else {++			ret = elem.getAttribute( name );++			// Non-existent attributes return null, we normalize to undefined+			return ret === null ?+				undefined :+				ret;+		}+	},++	removeAttr: function( elem, value ) {+		var propName, attrNames, name, l, isBool,+			i = 0;++		if ( value && elem.nodeType === 1 ) {+			attrNames = value.toLowerCase().split( rspace );+			l = attrNames.length;++			for ( ; i < l; i++ ) {+				name = attrNames[ i ];++				if ( name ) {+					propName = jQuery.propFix[ name ] || name;+					isBool = rboolean.test( name );++					// See #9699 for explanation of this approach (setting first, then removal)+					// Do not do this for boolean attributes (see #10870)+					if ( !isBool ) {+						jQuery.attr( elem, name, "" );+					}+					elem.removeAttribute( getSetAttribute ? name : propName );++					// Set corresponding property to false for boolean attributes+					if ( isBool && propName in elem ) {+						elem[ propName ] = false;+					}+				}+			}+		}+	},++	attrHooks: {+		type: {+			set: function( elem, value ) {+				// We can't allow the type property to be changed (since it causes problems in IE)+				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {+					jQuery.error( "type property can't be changed" );+				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {+					// Setting the type on a radio button after the value resets the value in IE6-9+					// Reset value to it's default in case type is set after value+					// This is for element creation+					var val = elem.value;+					elem.setAttribute( "type", value );+					if ( val ) {+						elem.value = val;+					}+					return value;+				}+			}+		},+		// Use the value property for back compat+		// Use the nodeHook for button elements in IE6/7 (#1954)+		value: {+			get: function( elem, name ) {+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {+					return nodeHook.get( elem, name );+				}+				return name in elem ?+					elem.value :+					null;+			},+			set: function( elem, value, name ) {+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {+					return nodeHook.set( elem, value, name );+				}+				// Does not return so that setAttribute is also used+				elem.value = value;+			}+		}+	},++	propFix: {+		tabindex: "tabIndex",+		readonly: "readOnly",+		"for": "htmlFor",+		"class": "className",+		maxlength: "maxLength",+		cellspacing: "cellSpacing",+		cellpadding: "cellPadding",+		rowspan: "rowSpan",+		colspan: "colSpan",+		usemap: "useMap",+		frameborder: "frameBorder",+		contenteditable: "contentEditable"+	},++	prop: function( elem, name, value ) {+		var ret, hooks, notxml,+			nType = elem.nodeType;++		// don't get/set properties on text, comment and attribute nodes+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {+			return;+		}++		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );++		if ( notxml ) {+			// Fix name and attach hooks+			name = jQuery.propFix[ name ] || name;+			hooks = jQuery.propHooks[ name ];+		}++		if ( value !== undefined ) {+			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {+				return ret;++			} else {+				return ( elem[ name ] = value );+			}++		} else {+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {+				return ret;++			} else {+				return elem[ name ];+			}+		}+	},++	propHooks: {+		tabIndex: {+			get: function( elem ) {+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/+				var attributeNode = elem.getAttributeNode("tabindex");++				return attributeNode && attributeNode.specified ?+					parseInt( attributeNode.value, 10 ) :+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?+						0 :+						undefined;+			}+		}+	}+});++// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)+jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;++// Hook for boolean attributes+boolHook = {+	get: function( elem, name ) {+		// Align boolean attributes with corresponding properties+		// Fall back to attribute presence where some booleans are not supported+		var attrNode,+			property = jQuery.prop( elem, name );+		return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?+			name.toLowerCase() :+			undefined;+	},+	set: function( elem, value, name ) {+		var propName;+		if ( value === false ) {+			// Remove boolean attributes when set to false+			jQuery.removeAttr( elem, name );+		} else {+			// value is true since we know at this point it's type boolean and not false+			// Set boolean attributes to the same name and set the DOM property+			propName = jQuery.propFix[ name ] || name;+			if ( propName in elem ) {+				// Only set the IDL specifically if it already exists on the element+				elem[ propName ] = true;+			}++			elem.setAttribute( name, name.toLowerCase() );+		}+		return name;+	}+};++// IE6/7 do not support getting/setting some attributes with get/setAttribute+if ( !getSetAttribute ) {++	fixSpecified = {+		name: true,+		id: true,+		coords: true+	};++	// Use this for any attribute in IE6/7+	// This fixes almost every IE6/7 issue+	nodeHook = jQuery.valHooks.button = {+		get: function( elem, name ) {+			var ret;+			ret = elem.getAttributeNode( name );+			return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?+				ret.nodeValue :+				undefined;+		},+		set: function( elem, value, name ) {+			// Set the existing or create a new attribute node+			var ret = elem.getAttributeNode( name );+			if ( !ret ) {+				ret = document.createAttribute( name );+				elem.setAttributeNode( ret );+			}+			return ( ret.nodeValue = value + "" );+		}+	};++	// Apply the nodeHook to tabindex+	jQuery.attrHooks.tabindex.set = nodeHook.set;++	// Set width and height to auto instead of 0 on empty string( Bug #8150 )+	// This is for removals+	jQuery.each([ "width", "height" ], function( i, name ) {+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {+			set: function( elem, value ) {+				if ( value === "" ) {+					elem.setAttribute( name, "auto" );+					return value;+				}+			}+		});+	});++	// Set contenteditable to false on removals(#10429)+	// Setting to empty string throws an error as an invalid value+	jQuery.attrHooks.contenteditable = {+		get: nodeHook.get,+		set: function( elem, value, name ) {+			if ( value === "" ) {+				value = "false";+			}+			nodeHook.set( elem, value, name );+		}+	};+}+++// Some attributes require a special call on IE+if ( !jQuery.support.hrefNormalized ) {+	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {+			get: function( elem ) {+				var ret = elem.getAttribute( name, 2 );+				return ret === null ? undefined : ret;+			}+		});+	});+}++if ( !jQuery.support.style ) {+	jQuery.attrHooks.style = {+		get: function( elem ) {+			// Return undefined in the case of empty string+			// Normalize to lowercase since IE uppercases css property names+			return elem.style.cssText.toLowerCase() || undefined;+		},+		set: function( elem, value ) {+			return ( elem.style.cssText = "" + value );+		}+	};+}++// Safari mis-reports the default selected property of an option+// Accessing the parent's selectedIndex property fixes it+if ( !jQuery.support.optSelected ) {+	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {+		get: function( elem ) {+			var parent = elem.parentNode;++			if ( parent ) {+				parent.selectedIndex;++				// Make sure that it also works with optgroups, see #5701+				if ( parent.parentNode ) {+					parent.parentNode.selectedIndex;+				}+			}+			return null;+		}+	});+}++// IE6/7 call enctype encoding+if ( !jQuery.support.enctype ) {+	jQuery.propFix.enctype = "encoding";+}++// Radios and checkboxes getter/setter+if ( !jQuery.support.checkOn ) {+	jQuery.each([ "radio", "checkbox" ], function() {+		jQuery.valHooks[ this ] = {+			get: function( elem ) {+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified+				return elem.getAttribute("value") === null ? "on" : elem.value;+			}+		};+	});+}+jQuery.each([ "radio", "checkbox" ], function() {+	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {+		set: function( elem, value ) {+			if ( jQuery.isArray( value ) ) {+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );+			}+		}+	});+});+++++var rformElems = /^(?:textarea|input|select)$/i,+	rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,+	rhoverHack = /(?:^|\s)hover(\.\S+)?\b/,+	rkeyEvent = /^key/,+	rmouseEvent = /^(?:mouse|contextmenu)|click/,+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,+	rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,+	quickParse = function( selector ) {+		var quick = rquickIs.exec( selector );+		if ( quick ) {+			//   0  1    2   3+			// [ _, tag, id, class ]+			quick[1] = ( quick[1] || "" ).toLowerCase();+			quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );+		}+		return quick;+	},+	quickIs = function( elem, m ) {+		var attrs = elem.attributes || {};+		return (+			(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&+			(!m[2] || (attrs.id || {}).value === m[2]) &&+			(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))+		);+	},+	hoverHack = function( events ) {+		return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );+	};++/*+ * Helper functions for managing events -- not part of the public interface.+ * Props to Dean Edwards' addEvent library for many of the ideas.+ */+jQuery.event = {++	add: function( elem, types, handler, data, selector ) {++		var elemData, eventHandle, events,+			t, tns, type, namespaces, handleObj,+			handleObjIn, quick, handlers, special;++		// Don't attach events to noData or text/comment nodes (allow plain objects tho)+		if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {+			return;+		}++		// Caller can pass in an object of custom data in lieu of the handler+		if ( handler.handler ) {+			handleObjIn = handler;+			handler = handleObjIn.handler;+			selector = handleObjIn.selector;+		}++		// Make sure that the handler has a unique ID, used to find/remove it later+		if ( !handler.guid ) {+			handler.guid = jQuery.guid++;+		}++		// Init the element's event structure and main handler, if this is the first+		events = elemData.events;+		if ( !events ) {+			elemData.events = events = {};+		}+		eventHandle = elemData.handle;+		if ( !eventHandle ) {+			elemData.handle = eventHandle = function( e ) {+				// Discard the second event of a jQuery.event.trigger() and+				// when an event is called after a page has unloaded+				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :+					undefined;+			};+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events+			eventHandle.elem = elem;+		}++		// Handle multiple events separated by a space+		// jQuery(...).bind("mouseover mouseout", fn);+		types = jQuery.trim( hoverHack(types) ).split( " " );+		for ( t = 0; t < types.length; t++ ) {++			tns = rtypenamespace.exec( types[t] ) || [];+			type = tns[1];+			namespaces = ( tns[2] || "" ).split( "." ).sort();++			// If event changes its type, use the special event handlers for the changed type+			special = jQuery.event.special[ type ] || {};++			// If selector defined, determine special event api type, otherwise given type+			type = ( selector ? special.delegateType : special.bindType ) || type;++			// Update special based on newly reset type+			special = jQuery.event.special[ type ] || {};++			// handleObj is passed to all event handlers+			handleObj = jQuery.extend({+				type: type,+				origType: tns[1],+				data: data,+				handler: handler,+				guid: handler.guid,+				selector: selector,+				quick: selector && quickParse( selector ),+				namespace: namespaces.join(".")+			}, handleObjIn );++			// Init the event handler queue if we're the first+			handlers = events[ type ];+			if ( !handlers ) {+				handlers = events[ type ] = [];+				handlers.delegateCount = 0;++				// Only use addEventListener/attachEvent if the special events handler returns false+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {+					// Bind the global event handler to the element+					if ( elem.addEventListener ) {+						elem.addEventListener( type, eventHandle, false );++					} else if ( elem.attachEvent ) {+						elem.attachEvent( "on" + type, eventHandle );+					}+				}+			}++			if ( special.add ) {+				special.add.call( elem, handleObj );++				if ( !handleObj.handler.guid ) {+					handleObj.handler.guid = handler.guid;+				}+			}++			// Add to the element's handler list, delegates in front+			if ( selector ) {+				handlers.splice( handlers.delegateCount++, 0, handleObj );+			} else {+				handlers.push( handleObj );+			}++			// Keep track of which events have ever been used, for event optimization+			jQuery.event.global[ type ] = true;+		}++		// Nullify elem to prevent memory leaks in IE+		elem = null;+	},++	global: {},++	// Detach an event or set of events from an element+	remove: function( elem, types, handler, selector, mappedTypes ) {++		var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),+			t, tns, type, origType, namespaces, origCount,+			j, events, special, handle, eventType, handleObj;++		if ( !elemData || !(events = elemData.events) ) {+			return;+		}++		// Once for each type.namespace in types; type may be omitted+		types = jQuery.trim( hoverHack( types || "" ) ).split(" ");+		for ( t = 0; t < types.length; t++ ) {+			tns = rtypenamespace.exec( types[t] ) || [];+			type = origType = tns[1];+			namespaces = tns[2];++			// Unbind all events (on this namespace, if provided) for the element+			if ( !type ) {+				for ( type in events ) {+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );+				}+				continue;+			}++			special = jQuery.event.special[ type ] || {};+			type = ( selector? special.delegateType : special.bindType ) || type;+			eventType = events[ type ] || [];+			origCount = eventType.length;+			namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;++			// Remove matching events+			for ( j = 0; j < eventType.length; j++ ) {+				handleObj = eventType[ j ];++				if ( ( mappedTypes || origType === handleObj.origType ) &&+					 ( !handler || handler.guid === handleObj.guid ) &&+					 ( !namespaces || namespaces.test( handleObj.namespace ) ) &&+					 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {+					eventType.splice( j--, 1 );++					if ( handleObj.selector ) {+						eventType.delegateCount--;+					}+					if ( special.remove ) {+						special.remove.call( elem, handleObj );+					}+				}+			}++			// Remove generic event handler if we removed something and no more handlers exist+			// (avoids potential for endless recursion during removal of special event handlers)+			if ( eventType.length === 0 && origCount !== eventType.length ) {+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {+					jQuery.removeEvent( elem, type, elemData.handle );+				}++				delete events[ type ];+			}+		}++		// Remove the expando if it's no longer used+		if ( jQuery.isEmptyObject( events ) ) {+			handle = elemData.handle;+			if ( handle ) {+				handle.elem = null;+			}++			// removeData also checks for emptiness and clears the expando if empty+			// so use it instead of delete+			jQuery.removeData( elem, [ "events", "handle" ], true );+		}+	},++	// Events that are safe to short-circuit if no handlers are attached.+	// Native DOM events should not be added, they may have inline handlers.+	customEvent: {+		"getData": true,+		"setData": true,+		"changeData": true+	},++	trigger: function( event, data, elem, onlyHandlers ) {+		// Don't do events on text and comment nodes+		if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {+			return;+		}++		// Event object or event type+		var type = event.type || event,+			namespaces = [],+			cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;++		// focus/blur morphs to focusin/out; ensure we're not firing them right now+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {+			return;+		}++		if ( type.indexOf( "!" ) >= 0 ) {+			// Exclusive events trigger only for the exact event (no namespaces)+			type = type.slice(0, -1);+			exclusive = true;+		}++		if ( type.indexOf( "." ) >= 0 ) {+			// Namespaced trigger; create a regexp to match event type in handle()+			namespaces = type.split(".");+			type = namespaces.shift();+			namespaces.sort();+		}++		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {+			// No jQuery handlers for this event type, and it can't have inline handlers+			return;+		}++		// Caller can pass in an Event, Object, or just an event type string+		event = typeof event === "object" ?+			// jQuery.Event object+			event[ jQuery.expando ] ? event :+			// Object literal+			new jQuery.Event( type, event ) :+			// Just the event type (string)+			new jQuery.Event( type );++		event.type = type;+		event.isTrigger = true;+		event.exclusive = exclusive;+		event.namespace = namespaces.join( "." );+		event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;+		ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";++		// Handle a global trigger+		if ( !elem ) {++			// TODO: Stop taunting the data cache; remove global events and always attach to document+			cache = jQuery.cache;+			for ( i in cache ) {+				if ( cache[ i ].events && cache[ i ].events[ type ] ) {+					jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );+				}+			}+			return;+		}++		// Clean up the event in case it is being reused+		event.result = undefined;+		if ( !event.target ) {+			event.target = elem;+		}++		// Clone any incoming data and prepend the event, creating the handler arg list+		data = data != null ? jQuery.makeArray( data ) : [];+		data.unshift( event );++		// Allow special events to draw outside the lines+		special = jQuery.event.special[ type ] || {};+		if ( special.trigger && special.trigger.apply( elem, data ) === false ) {+			return;+		}++		// Determine event propagation path in advance, per W3C events spec (#9951)+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)+		eventPath = [[ elem, special.bindType || type ]];+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {++			bubbleType = special.delegateType || type;+			cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;+			old = null;+			for ( ; cur; cur = cur.parentNode ) {+				eventPath.push([ cur, bubbleType ]);+				old = cur;+			}++			// Only add window if we got to document (e.g., not plain obj or detached DOM)+			if ( old && old === elem.ownerDocument ) {+				eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);+			}+		}++		// Fire handlers on the event path+		for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {++			cur = eventPath[i][0];+			event.type = eventPath[i][1];++			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );+			if ( handle ) {+				handle.apply( cur, data );+			}+			// Note that this is a bare JS function and not a jQuery handler+			handle = ontype && cur[ ontype ];+			if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {+				event.preventDefault();+			}+		}+		event.type = type;++		// If nobody prevented the default action, do it now+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {++			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&+				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {++				// Call a native DOM method on the target with the same name name as the event.+				// Can't use an .isFunction() check here because IE6/7 fails that test.+				// Don't do default actions on window, that's where global variables be (#6170)+				// IE<9 dies on focus/blur to hidden element (#1486)+				if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {++					// Don't re-trigger an onFOO event when we call its FOO() method+					old = elem[ ontype ];++					if ( old ) {+						elem[ ontype ] = null;+					}++					// Prevent re-triggering of the same event, since we already bubbled it above+					jQuery.event.triggered = type;+					elem[ type ]();+					jQuery.event.triggered = undefined;++					if ( old ) {+						elem[ ontype ] = old;+					}+				}+			}+		}++		return event.result;+	},++	dispatch: function( event ) {++		// Make a writable jQuery.Event from the native event object+		event = jQuery.event.fix( event || window.event );++		var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),+			delegateCount = handlers.delegateCount,+			args = [].slice.call( arguments, 0 ),+			run_all = !event.exclusive && !event.namespace,+			special = jQuery.event.special[ event.type ] || {},+			handlerQueue = [],+			i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;++		// Use the fix-ed jQuery.Event rather than the (read-only) native event+		args[0] = event;+		event.delegateTarget = this;++		// Call the preDispatch hook for the mapped type, and let it bail if desired+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {+			return;+		}++		// Determine handlers that should run if there are delegated events+		// Avoid non-left-click bubbling in Firefox (#3861)+		if ( delegateCount && !(event.button && event.type === "click") ) {++			// Pregenerate a single jQuery object for reuse with .is()+			jqcur = jQuery(this);+			jqcur.context = this.ownerDocument || this;++			for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {++				// Don't process events on disabled elements (#6911, #8165)+				if ( cur.disabled !== true ) {+					selMatch = {};+					matches = [];+					jqcur[0] = cur;+					for ( i = 0; i < delegateCount; i++ ) {+						handleObj = handlers[ i ];+						sel = handleObj.selector;++						if ( selMatch[ sel ] === undefined ) {+							selMatch[ sel ] = (+								handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )+							);+						}+						if ( selMatch[ sel ] ) {+							matches.push( handleObj );+						}+					}+					if ( matches.length ) {+						handlerQueue.push({ elem: cur, matches: matches });+					}+				}+			}+		}++		// Add the remaining (directly-bound) handlers+		if ( handlers.length > delegateCount ) {+			handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });+		}++		// Run delegates first; they may want to stop propagation beneath us+		for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {+			matched = handlerQueue[ i ];+			event.currentTarget = matched.elem;++			for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {+				handleObj = matched.matches[ j ];++				// Triggered event must either 1) be non-exclusive and have no namespace, or+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).+				if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {++					event.data = handleObj.data;+					event.handleObj = handleObj;++					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )+							.apply( matched.elem, args );++					if ( ret !== undefined ) {+						event.result = ret;+						if ( ret === false ) {+							event.preventDefault();+							event.stopPropagation();+						}+					}+				}+			}+		}++		// Call the postDispatch hook for the mapped type+		if ( special.postDispatch ) {+			special.postDispatch.call( this, event );+		}++		return event.result;+	},++	// Includes some event props shared by KeyEvent and MouseEvent+	// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***+	props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),++	fixHooks: {},++	keyHooks: {+		props: "char charCode key keyCode".split(" "),+		filter: function( event, original ) {++			// Add which for key events+			if ( event.which == null ) {+				event.which = original.charCode != null ? original.charCode : original.keyCode;+			}++			return event;+		}+	},++	mouseHooks: {+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),+		filter: function( event, original ) {+			var eventDoc, doc, body,+				button = original.button,+				fromElement = original.fromElement;++			// Calculate pageX/Y if missing and clientX/Y available+			if ( event.pageX == null && original.clientX != null ) {+				eventDoc = event.target.ownerDocument || document;+				doc = eventDoc.documentElement;+				body = eventDoc.body;++				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );+			}++			// Add relatedTarget, if necessary+			if ( !event.relatedTarget && fromElement ) {+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;+			}++			// Add which for click: 1 === left; 2 === middle; 3 === right+			// Note: button is not normalized, so don't use it+			if ( !event.which && button !== undefined ) {+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );+			}++			return event;+		}+	},++	fix: function( event ) {+		if ( event[ jQuery.expando ] ) {+			return event;+		}++		// Create a writable copy of the event object and normalize some properties+		var i, prop,+			originalEvent = event,+			fixHook = jQuery.event.fixHooks[ event.type ] || {},+			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;++		event = jQuery.Event( originalEvent );++		for ( i = copy.length; i; ) {+			prop = copy[ --i ];+			event[ prop ] = originalEvent[ prop ];+		}++		// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)+		if ( !event.target ) {+			event.target = originalEvent.srcElement || document;+		}++		// Target should not be a text node (#504, Safari)+		if ( event.target.nodeType === 3 ) {+			event.target = event.target.parentNode;+		}++		// For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)+		if ( event.metaKey === undefined ) {+			event.metaKey = event.ctrlKey;+		}++		return fixHook.filter? fixHook.filter( event, originalEvent ) : event;+	},++	special: {+		ready: {+			// Make sure the ready event is setup+			setup: jQuery.bindReady+		},++		load: {+			// Prevent triggered image.load events from bubbling to window.load+			noBubble: true+		},++		focus: {+			delegateType: "focusin"+		},+		blur: {+			delegateType: "focusout"+		},++		beforeunload: {+			setup: function( data, namespaces, eventHandle ) {+				// We only want to do this special case on windows+				if ( jQuery.isWindow( this ) ) {+					this.onbeforeunload = eventHandle;+				}+			},++			teardown: function( namespaces, eventHandle ) {+				if ( this.onbeforeunload === eventHandle ) {+					this.onbeforeunload = null;+				}+			}+		}+	},++	simulate: function( type, elem, event, bubble ) {+		// Piggyback on a donor event to simulate a different one.+		// Fake originalEvent to avoid donor's stopPropagation, but if the+		// simulated event prevents default then we do the same on the donor.+		var e = jQuery.extend(+			new jQuery.Event(),+			event,+			{ type: type,+				isSimulated: true,+				originalEvent: {}+			}+		);+		if ( bubble ) {+			jQuery.event.trigger( e, null, elem );+		} else {+			jQuery.event.dispatch.call( elem, e );+		}+		if ( e.isDefaultPrevented() ) {+			event.preventDefault();+		}+	}+};++// Some plugins are using, but it's undocumented/deprecated and will be removed.+// The 1.7 special event interface should provide all the hooks needed now.+jQuery.event.handle = jQuery.event.dispatch;++jQuery.removeEvent = document.removeEventListener ?+	function( elem, type, handle ) {+		if ( elem.removeEventListener ) {+			elem.removeEventListener( type, handle, false );+		}+	} :+	function( elem, type, handle ) {+		if ( elem.detachEvent ) {+			elem.detachEvent( "on" + type, handle );+		}+	};++jQuery.Event = function( src, props ) {+	// Allow instantiation without the 'new' keyword+	if ( !(this instanceof jQuery.Event) ) {+		return new jQuery.Event( src, props );+	}++	// Event object+	if ( src && src.type ) {+		this.originalEvent = src;+		this.type = src.type;++		// Events bubbling up the document may have been marked as prevented+		// by a handler lower down the tree; reflect the correct value.+		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||+			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;++	// Event type+	} else {+		this.type = src;+	}++	// Put explicitly provided properties onto the event object+	if ( props ) {+		jQuery.extend( this, props );+	}++	// Create a timestamp if incoming event doesn't have one+	this.timeStamp = src && src.timeStamp || jQuery.now();++	// Mark it as fixed+	this[ jQuery.expando ] = true;+};++function returnFalse() {+	return false;+}+function returnTrue() {+	return true;+}++// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html+jQuery.Event.prototype = {+	preventDefault: function() {+		this.isDefaultPrevented = returnTrue;++		var e = this.originalEvent;+		if ( !e ) {+			return;+		}++		// if preventDefault exists run it on the original event+		if ( e.preventDefault ) {+			e.preventDefault();++		// otherwise set the returnValue property of the original event to false (IE)+		} else {+			e.returnValue = false;+		}+	},+	stopPropagation: function() {+		this.isPropagationStopped = returnTrue;++		var e = this.originalEvent;+		if ( !e ) {+			return;+		}+		// if stopPropagation exists run it on the original event+		if ( e.stopPropagation ) {+			e.stopPropagation();+		}+		// otherwise set the cancelBubble property of the original event to true (IE)+		e.cancelBubble = true;+	},+	stopImmediatePropagation: function() {+		this.isImmediatePropagationStopped = returnTrue;+		this.stopPropagation();+	},+	isDefaultPrevented: returnFalse,+	isPropagationStopped: returnFalse,+	isImmediatePropagationStopped: returnFalse+};++// Create mouseenter/leave events using mouseover/out and event-time checks+jQuery.each({+	mouseenter: "mouseover",+	mouseleave: "mouseout"+}, function( orig, fix ) {+	jQuery.event.special[ orig ] = {+		delegateType: fix,+		bindType: fix,++		handle: function( event ) {+			var target = this,+				related = event.relatedTarget,+				handleObj = event.handleObj,+				selector = handleObj.selector,+				ret;++			// For mousenter/leave call the handler if related is outside the target.+			// NB: No relatedTarget if the mouse left/entered the browser window+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {+				event.type = handleObj.origType;+				ret = handleObj.handler.apply( this, arguments );+				event.type = fix;+			}+			return ret;+		}+	};+});++// IE submit delegation+if ( !jQuery.support.submitBubbles ) {++	jQuery.event.special.submit = {+		setup: function() {+			// Only need this for delegated form submit events+			if ( jQuery.nodeName( this, "form" ) ) {+				return false;+			}++			// Lazy-add a submit handler when a descendant form may potentially be submitted+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {+				// Node name check avoids a VML-related crash in IE (#9807)+				var elem = e.target,+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;+				if ( form && !form._submit_attached ) {+					jQuery.event.add( form, "submit._submit", function( event ) {+						event._submit_bubble = true;+					});+					form._submit_attached = true;+				}+			});+			// return undefined since we don't need an event listener+		},+		+		postDispatch: function( event ) {+			// If form was submitted by the user, bubble the event up the tree+			if ( event._submit_bubble ) {+				delete event._submit_bubble;+				if ( this.parentNode && !event.isTrigger ) {+					jQuery.event.simulate( "submit", this.parentNode, event, true );+				}+			}+		},++		teardown: function() {+			// Only need this for delegated form submit events+			if ( jQuery.nodeName( this, "form" ) ) {+				return false;+			}++			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above+			jQuery.event.remove( this, "._submit" );+		}+	};+}++// IE change delegation and checkbox/radio fix+if ( !jQuery.support.changeBubbles ) {++	jQuery.event.special.change = {++		setup: function() {++			if ( rformElems.test( this.nodeName ) ) {+				// IE doesn't fire change on a check/radio until blur; trigger it on click+				// after a propertychange. Eat the blur-change in special.change.handle.+				// This still fires onchange a second time for check/radio after blur.+				if ( this.type === "checkbox" || this.type === "radio" ) {+					jQuery.event.add( this, "propertychange._change", function( event ) {+						if ( event.originalEvent.propertyName === "checked" ) {+							this._just_changed = true;+						}+					});+					jQuery.event.add( this, "click._change", function( event ) {+						if ( this._just_changed && !event.isTrigger ) {+							this._just_changed = false;+							jQuery.event.simulate( "change", this, event, true );+						}+					});+				}+				return false;+			}+			// Delegated event; lazy-add a change handler on descendant inputs+			jQuery.event.add( this, "beforeactivate._change", function( e ) {+				var elem = e.target;++				if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {+					jQuery.event.add( elem, "change._change", function( event ) {+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {+							jQuery.event.simulate( "change", this.parentNode, event, true );+						}+					});+					elem._change_attached = true;+				}+			});+		},++		handle: function( event ) {+			var elem = event.target;++			// Swallow native change events from checkbox/radio, we already triggered them above+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {+				return event.handleObj.handler.apply( this, arguments );+			}+		},++		teardown: function() {+			jQuery.event.remove( this, "._change" );++			return rformElems.test( this.nodeName );+		}+	};+}++// Create "bubbling" focus and blur events+if ( !jQuery.support.focusinBubbles ) {+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {++		// Attach a single capturing handler while someone wants focusin/focusout+		var attaches = 0,+			handler = function( event ) {+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );+			};++		jQuery.event.special[ fix ] = {+			setup: function() {+				if ( attaches++ === 0 ) {+					document.addEventListener( orig, handler, true );+				}+			},+			teardown: function() {+				if ( --attaches === 0 ) {+					document.removeEventListener( orig, handler, true );+				}+			}+		};+	});+}++jQuery.fn.extend({++	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {+		var origFn, type;++		// Types can be a map of types/handlers+		if ( typeof types === "object" ) {+			// ( types-Object, selector, data )+			if ( typeof selector !== "string" ) { // && selector != null+				// ( types-Object, data )+				data = data || selector;+				selector = undefined;+			}+			for ( type in types ) {+				this.on( type, selector, data, types[ type ], one );+			}+			return this;+		}++		if ( data == null && fn == null ) {+			// ( types, fn )+			fn = selector;+			data = selector = undefined;+		} else if ( fn == null ) {+			if ( typeof selector === "string" ) {+				// ( types, selector, fn )+				fn = data;+				data = undefined;+			} else {+				// ( types, data, fn )+				fn = data;+				data = selector;+				selector = undefined;+			}+		}+		if ( fn === false ) {+			fn = returnFalse;+		} else if ( !fn ) {+			return this;+		}++		if ( one === 1 ) {+			origFn = fn;+			fn = function( event ) {+				// Can use an empty set, since event contains the info+				jQuery().off( event );+				return origFn.apply( this, arguments );+			};+			// Use same guid so caller can remove using origFn+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );+		}+		return this.each( function() {+			jQuery.event.add( this, types, fn, data, selector );+		});+	},+	one: function( types, selector, data, fn ) {+		return this.on( types, selector, data, fn, 1 );+	},+	off: function( types, selector, fn ) {+		if ( types && types.preventDefault && types.handleObj ) {+			// ( event )  dispatched jQuery.Event+			var handleObj = types.handleObj;+			jQuery( types.delegateTarget ).off(+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,+				handleObj.selector,+				handleObj.handler+			);+			return this;+		}+		if ( typeof types === "object" ) {+			// ( types-object [, selector] )+			for ( var type in types ) {+				this.off( type, selector, types[ type ] );+			}+			return this;+		}+		if ( selector === false || typeof selector === "function" ) {+			// ( types [, fn] )+			fn = selector;+			selector = undefined;+		}+		if ( fn === false ) {+			fn = returnFalse;+		}+		return this.each(function() {+			jQuery.event.remove( this, types, fn, selector );+		});+	},++	bind: function( types, data, fn ) {+		return this.on( types, null, data, fn );+	},+	unbind: function( types, fn ) {+		return this.off( types, null, fn );+	},++	live: function( types, data, fn ) {+		jQuery( this.context ).on( types, this.selector, data, fn );+		return this;+	},+	die: function( types, fn ) {+		jQuery( this.context ).off( types, this.selector || "**", fn );+		return this;+	},++	delegate: function( selector, types, data, fn ) {+		return this.on( types, selector, data, fn );+	},+	undelegate: function( selector, types, fn ) {+		// ( namespace ) or ( selector, types [, fn] )+		return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );+	},++	trigger: function( type, data ) {+		return this.each(function() {+			jQuery.event.trigger( type, data, this );+		});+	},+	triggerHandler: function( type, data ) {+		if ( this[0] ) {+			return jQuery.event.trigger( type, data, this[0], true );+		}+	},++	toggle: function( fn ) {+		// Save reference to arguments for access in closure+		var args = arguments,+			guid = fn.guid || jQuery.guid++,+			i = 0,+			toggler = function( event ) {+				// Figure out which function to execute+				var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;+				jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );++				// Make sure that clicks stop+				event.preventDefault();++				// and execute the function+				return args[ lastToggle ].apply( this, arguments ) || false;+			};++		// link all the functions, so any of them can unbind this click handler+		toggler.guid = guid;+		while ( i < args.length ) {+			args[ i++ ].guid = guid;+		}++		return this.click( toggler );+	},++	hover: function( fnOver, fnOut ) {+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );+	}+});++jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " ++	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " ++	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {++	// Handle event binding+	jQuery.fn[ name ] = function( data, fn ) {+		if ( fn == null ) {+			fn = data;+			data = null;+		}++		return arguments.length > 0 ?+			this.on( name, null, data, fn ) :+			this.trigger( name );+	};++	if ( jQuery.attrFn ) {+		jQuery.attrFn[ name ] = true;+	}++	if ( rkeyEvent.test( name ) ) {+		jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;+	}++	if ( rmouseEvent.test( name ) ) {+		jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;+	}+});++++/*!+ * Sizzle CSS Selector Engine+ *  Copyright 2011, The Dojo Foundation+ *  Released under the MIT, BSD, and GPL Licenses.+ *  More information: http://sizzlejs.com/+ */+(function(){++var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,+	expando = "sizcache" + (Math.random() + '').replace('.', ''),+	done = 0,+	toString = Object.prototype.toString,+	hasDuplicate = false,+	baseHasDuplicate = true,+	rBackslash = /\\/g,+	rReturn = /\r\n/g,+	rNonWord = /\W/;++// Here we check if the JavaScript engine is using some sort of+// optimization where it does not always call our comparision+// function. If that is the case, discard the hasDuplicate value.+//   Thus far that includes Google Chrome.+[0, 0].sort(function() {+	baseHasDuplicate = false;+	return 0;+});++var Sizzle = function( selector, context, results, seed ) {+	results = results || [];+	context = context || document;++	var origContext = context;++	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {+		return [];+	}++	if ( !selector || typeof selector !== "string" ) {+		return results;+	}++	var m, set, checkSet, extra, ret, cur, pop, i,+		prune = true,+		contextXML = Sizzle.isXML( context ),+		parts = [],+		soFar = selector;++	// Reset the position of the chunker regexp (start from head)+	do {+		chunker.exec( "" );+		m = chunker.exec( soFar );++		if ( m ) {+			soFar = m[3];++			parts.push( m[1] );++			if ( m[2] ) {+				extra = m[3];+				break;+			}+		}+	} while ( m );++	if ( parts.length > 1 && origPOS.exec( selector ) ) {++		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {+			set = posProcess( parts[0] + parts[1], context, seed );++		} else {+			set = Expr.relative[ parts[0] ] ?+				[ context ] :+				Sizzle( parts.shift(), context );++			while ( parts.length ) {+				selector = parts.shift();++				if ( Expr.relative[ selector ] ) {+					selector += parts.shift();+				}++				set = posProcess( selector, set, seed );+			}+		}++	} else {+		// Take a shortcut and set the context if the root selector is an ID+		// (but not if it'll be faster if the inner selector is an ID)+		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&+				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {++			ret = Sizzle.find( parts.shift(), context, contextXML );+			context = ret.expr ?+				Sizzle.filter( ret.expr, ret.set )[0] :+				ret.set[0];+		}++		if ( context ) {+			ret = seed ?+				{ expr: parts.pop(), set: makeArray(seed) } :+				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );++			set = ret.expr ?+				Sizzle.filter( ret.expr, ret.set ) :+				ret.set;++			if ( parts.length > 0 ) {+				checkSet = makeArray( set );++			} else {+				prune = false;+			}++			while ( parts.length ) {+				cur = parts.pop();+				pop = cur;++				if ( !Expr.relative[ cur ] ) {+					cur = "";+				} else {+					pop = parts.pop();+				}++				if ( pop == null ) {+					pop = context;+				}++				Expr.relative[ cur ]( checkSet, pop, contextXML );+			}++		} else {+			checkSet = parts = [];+		}+	}++	if ( !checkSet ) {+		checkSet = set;+	}++	if ( !checkSet ) {+		Sizzle.error( cur || selector );+	}++	if ( toString.call(checkSet) === "[object Array]" ) {+		if ( !prune ) {+			results.push.apply( results, checkSet );++		} else if ( context && context.nodeType === 1 ) {+			for ( i = 0; checkSet[i] != null; i++ ) {+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {+					results.push( set[i] );+				}+			}++		} else {+			for ( i = 0; checkSet[i] != null; i++ ) {+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {+					results.push( set[i] );+				}+			}+		}++	} else {+		makeArray( checkSet, results );+	}++	if ( extra ) {+		Sizzle( extra, origContext, results, seed );+		Sizzle.uniqueSort( results );+	}++	return results;+};++Sizzle.uniqueSort = function( results ) {+	if ( sortOrder ) {+		hasDuplicate = baseHasDuplicate;+		results.sort( sortOrder );++		if ( hasDuplicate ) {+			for ( var i = 1; i < results.length; i++ ) {+				if ( results[i] === results[ i - 1 ] ) {+					results.splice( i--, 1 );+				}+			}+		}+	}++	return results;+};++Sizzle.matches = function( expr, set ) {+	return Sizzle( expr, null, null, set );+};++Sizzle.matchesSelector = function( node, expr ) {+	return Sizzle( expr, null, null, [node] ).length > 0;+};++Sizzle.find = function( expr, context, isXML ) {+	var set, i, len, match, type, left;++	if ( !expr ) {+		return [];+	}++	for ( i = 0, len = Expr.order.length; i < len; i++ ) {+		type = Expr.order[i];++		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {+			left = match[1];+			match.splice( 1, 1 );++			if ( left.substr( left.length - 1 ) !== "\\" ) {+				match[1] = (match[1] || "").replace( rBackslash, "" );+				set = Expr.find[ type ]( match, context, isXML );++				if ( set != null ) {+					expr = expr.replace( Expr.match[ type ], "" );+					break;+				}+			}+		}+	}++	if ( !set ) {+		set = typeof context.getElementsByTagName !== "undefined" ?+			context.getElementsByTagName( "*" ) :+			[];+	}++	return { set: set, expr: expr };+};++Sizzle.filter = function( expr, set, inplace, not ) {+	var match, anyFound,+		type, found, item, filter, left,+		i, pass,+		old = expr,+		result = [],+		curLoop = set,+		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );++	while ( expr && set.length ) {+		for ( type in Expr.filter ) {+			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {+				filter = Expr.filter[ type ];+				left = match[1];++				anyFound = false;++				match.splice(1,1);++				if ( left.substr( left.length - 1 ) === "\\" ) {+					continue;+				}++				if ( curLoop === result ) {+					result = [];+				}++				if ( Expr.preFilter[ type ] ) {+					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );++					if ( !match ) {+						anyFound = found = true;++					} else if ( match === true ) {+						continue;+					}+				}++				if ( match ) {+					for ( i = 0; (item = curLoop[i]) != null; i++ ) {+						if ( item ) {+							found = filter( item, match, i, curLoop );+							pass = not ^ found;++							if ( inplace && found != null ) {+								if ( pass ) {+									anyFound = true;++								} else {+									curLoop[i] = false;+								}++							} else if ( pass ) {+								result.push( item );+								anyFound = true;+							}+						}+					}+				}++				if ( found !== undefined ) {+					if ( !inplace ) {+						curLoop = result;+					}++					expr = expr.replace( Expr.match[ type ], "" );++					if ( !anyFound ) {+						return [];+					}++					break;+				}+			}+		}++		// Improper expression+		if ( expr === old ) {+			if ( anyFound == null ) {+				Sizzle.error( expr );++			} else {+				break;+			}+		}++		old = expr;+	}++	return curLoop;+};++Sizzle.error = function( msg ) {+	throw new Error( "Syntax error, unrecognized expression: " + msg );+};++/**+ * Utility function for retreiving the text value of an array of DOM nodes+ * @param {Array|Element} elem+ */+var getText = Sizzle.getText = function( elem ) {+    var i, node,+		nodeType = elem.nodeType,+		ret = "";++	if ( nodeType ) {+		if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {+			// Use textContent || innerText for elements+			if ( typeof elem.textContent === 'string' ) {+				return elem.textContent;+			} else if ( typeof elem.innerText === 'string' ) {+				// Replace IE's carriage returns+				return elem.innerText.replace( rReturn, '' );+			} else {+				// Traverse it's children+				for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {+					ret += getText( elem );+				}+			}+		} else if ( nodeType === 3 || nodeType === 4 ) {+			return elem.nodeValue;+		}+	} else {++		// If no nodeType, this is expected to be an array+		for ( i = 0; (node = elem[i]); i++ ) {+			// Do not traverse comment nodes+			if ( node.nodeType !== 8 ) {+				ret += getText( node );+			}+		}+	}+	return ret;+};++var Expr = Sizzle.selectors = {+	order: [ "ID", "NAME", "TAG" ],++	match: {+		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,+		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,+		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,+		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,+		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,+		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,+		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,+		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/+	},++	leftMatch: {},++	attrMap: {+		"class": "className",+		"for": "htmlFor"+	},++	attrHandle: {+		href: function( elem ) {+			return elem.getAttribute( "href" );+		},+		type: function( elem ) {+			return elem.getAttribute( "type" );+		}+	},++	relative: {+		"+": function(checkSet, part){+			var isPartStr = typeof part === "string",+				isTag = isPartStr && !rNonWord.test( part ),+				isPartStrNotTag = isPartStr && !isTag;++			if ( isTag ) {+				part = part.toLowerCase();+			}++			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {+				if ( (elem = checkSet[i]) ) {+					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}++					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?+						elem || false :+						elem === part;+				}+			}++			if ( isPartStrNotTag ) {+				Sizzle.filter( part, checkSet, true );+			}+		},++		">": function( checkSet, part ) {+			var elem,+				isPartStr = typeof part === "string",+				i = 0,+				l = checkSet.length;++			if ( isPartStr && !rNonWord.test( part ) ) {+				part = part.toLowerCase();++				for ( ; i < l; i++ ) {+					elem = checkSet[i];++					if ( elem ) {+						var parent = elem.parentNode;+						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;+					}+				}++			} else {+				for ( ; i < l; i++ ) {+					elem = checkSet[i];++					if ( elem ) {+						checkSet[i] = isPartStr ?+							elem.parentNode :+							elem.parentNode === part;+					}+				}++				if ( isPartStr ) {+					Sizzle.filter( part, checkSet, true );+				}+			}+		},++		"": function(checkSet, part, isXML){+			var nodeCheck,+				doneName = done++,+				checkFn = dirCheck;++			if ( typeof part === "string" && !rNonWord.test( part ) ) {+				part = part.toLowerCase();+				nodeCheck = part;+				checkFn = dirNodeCheck;+			}++			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );+		},++		"~": function( checkSet, part, isXML ) {+			var nodeCheck,+				doneName = done++,+				checkFn = dirCheck;++			if ( typeof part === "string" && !rNonWord.test( part ) ) {+				part = part.toLowerCase();+				nodeCheck = part;+				checkFn = dirNodeCheck;+			}++			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );+		}+	},++	find: {+		ID: function( match, context, isXML ) {+			if ( typeof context.getElementById !== "undefined" && !isXML ) {+				var m = context.getElementById(match[1]);+				// Check parentNode to catch when Blackberry 4.6 returns+				// nodes that are no longer in the document #6963+				return m && m.parentNode ? [m] : [];+			}+		},++		NAME: function( match, context ) {+			if ( typeof context.getElementsByName !== "undefined" ) {+				var ret = [],+					results = context.getElementsByName( match[1] );++				for ( var i = 0, l = results.length; i < l; i++ ) {+					if ( results[i].getAttribute("name") === match[1] ) {+						ret.push( results[i] );+					}+				}++				return ret.length === 0 ? null : ret;+			}+		},++		TAG: function( match, context ) {+			if ( typeof context.getElementsByTagName !== "undefined" ) {+				return context.getElementsByTagName( match[1] );+			}+		}+	},+	preFilter: {+		CLASS: function( match, curLoop, inplace, result, not, isXML ) {+			match = " " + match[1].replace( rBackslash, "" ) + " ";++			if ( isXML ) {+				return match;+			}++			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {+				if ( elem ) {+					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {+						if ( !inplace ) {+							result.push( elem );+						}++					} else if ( inplace ) {+						curLoop[i] = false;+					}+				}+			}++			return false;+		},++		ID: function( match ) {+			return match[1].replace( rBackslash, "" );+		},++		TAG: function( match, curLoop ) {+			return match[1].replace( rBackslash, "" ).toLowerCase();+		},++		CHILD: function( match ) {+			if ( match[1] === "nth" ) {+				if ( !match[2] ) {+					Sizzle.error( match[0] );+				}++				match[2] = match[2].replace(/^\+|\s*/g, '');++				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'+				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(+					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||+					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);++				// calculate the numbers (first)n+(last) including if they are negative+				match[2] = (test[1] + (test[2] || 1)) - 0;+				match[3] = test[3] - 0;+			}+			else if ( match[2] ) {+				Sizzle.error( match[0] );+			}++			// TODO: Move to normal caching system+			match[0] = done++;++			return match;+		},++		ATTR: function( match, curLoop, inplace, result, not, isXML ) {+			var name = match[1] = match[1].replace( rBackslash, "" );++			if ( !isXML && Expr.attrMap[name] ) {+				match[1] = Expr.attrMap[name];+			}++			// Handle if an un-quoted value was used+			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );++			if ( match[2] === "~=" ) {+				match[4] = " " + match[4] + " ";+			}++			return match;+		},++		PSEUDO: function( match, curLoop, inplace, result, not ) {+			if ( match[1] === "not" ) {+				// If we're dealing with a complex expression, or a simple one+				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {+					match[3] = Sizzle(match[3], null, null, curLoop);++				} else {+					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);++					if ( !inplace ) {+						result.push.apply( result, ret );+					}++					return false;+				}++			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {+				return true;+			}++			return match;+		},++		POS: function( match ) {+			match.unshift( true );++			return match;+		}+	},++	filters: {+		enabled: function( elem ) {+			return elem.disabled === false && elem.type !== "hidden";+		},++		disabled: function( elem ) {+			return elem.disabled === true;+		},++		checked: function( elem ) {+			return elem.checked === true;+		},++		selected: function( elem ) {+			// Accessing this property makes selected-by-default+			// options in Safari work properly+			if ( elem.parentNode ) {+				elem.parentNode.selectedIndex;+			}++			return elem.selected === true;+		},++		parent: function( elem ) {+			return !!elem.firstChild;+		},++		empty: function( elem ) {+			return !elem.firstChild;+		},++		has: function( elem, i, match ) {+			return !!Sizzle( match[3], elem ).length;+		},++		header: function( elem ) {+			return (/h\d/i).test( elem.nodeName );+		},++		text: function( elem ) {+			var attr = elem.getAttribute( "type" ), type = elem.type;+			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)+			// use getAttribute instead to test this case+			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );+		},++		radio: function( elem ) {+			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;+		},++		checkbox: function( elem ) {+			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;+		},++		file: function( elem ) {+			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;+		},++		password: function( elem ) {+			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;+		},++		submit: function( elem ) {+			var name = elem.nodeName.toLowerCase();+			return (name === "input" || name === "button") && "submit" === elem.type;+		},++		image: function( elem ) {+			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;+		},++		reset: function( elem ) {+			var name = elem.nodeName.toLowerCase();+			return (name === "input" || name === "button") && "reset" === elem.type;+		},++		button: function( elem ) {+			var name = elem.nodeName.toLowerCase();+			return name === "input" && "button" === elem.type || name === "button";+		},++		input: function( elem ) {+			return (/input|select|textarea|button/i).test( elem.nodeName );+		},++		focus: function( elem ) {+			return elem === elem.ownerDocument.activeElement;+		}+	},+	setFilters: {+		first: function( elem, i ) {+			return i === 0;+		},++		last: function( elem, i, match, array ) {+			return i === array.length - 1;+		},++		even: function( elem, i ) {+			return i % 2 === 0;+		},++		odd: function( elem, i ) {+			return i % 2 === 1;+		},++		lt: function( elem, i, match ) {+			return i < match[3] - 0;+		},++		gt: function( elem, i, match ) {+			return i > match[3] - 0;+		},++		nth: function( elem, i, match ) {+			return match[3] - 0 === i;+		},++		eq: function( elem, i, match ) {+			return match[3] - 0 === i;+		}+	},+	filter: {+		PSEUDO: function( elem, match, i, array ) {+			var name = match[1],+				filter = Expr.filters[ name ];++			if ( filter ) {+				return filter( elem, i, match, array );++			} else if ( name === "contains" ) {+				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;++			} else if ( name === "not" ) {+				var not = match[3];++				for ( var j = 0, l = not.length; j < l; j++ ) {+					if ( not[j] === elem ) {+						return false;+					}+				}++				return true;++			} else {+				Sizzle.error( name );+			}+		},++		CHILD: function( elem, match ) {+			var first, last,+				doneName, parent, cache,+				count, diff,+				type = match[1],+				node = elem;++			switch ( type ) {+				case "only":+				case "first":+					while ( (node = node.previousSibling) ) {+						if ( node.nodeType === 1 ) {+							return false;+						}+					}++					if ( type === "first" ) {+						return true;+					}++					node = elem;++					/* falls through */+				case "last":+					while ( (node = node.nextSibling) ) {+						if ( node.nodeType === 1 ) {+							return false;+						}+					}++					return true;++				case "nth":+					first = match[2];+					last = match[3];++					if ( first === 1 && last === 0 ) {+						return true;+					}++					doneName = match[0];+					parent = elem.parentNode;++					if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {+						count = 0;++						for ( node = parent.firstChild; node; node = node.nextSibling ) {+							if ( node.nodeType === 1 ) {+								node.nodeIndex = ++count;+							}+						}++						parent[ expando ] = doneName;+					}++					diff = elem.nodeIndex - last;++					if ( first === 0 ) {+						return diff === 0;++					} else {+						return ( diff % first === 0 && diff / first >= 0 );+					}+			}+		},++		ID: function( elem, match ) {+			return elem.nodeType === 1 && elem.getAttribute("id") === match;+		},++		TAG: function( elem, match ) {+			return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;+		},++		CLASS: function( elem, match ) {+			return (" " + (elem.className || elem.getAttribute("class")) + " ")+				.indexOf( match ) > -1;+		},++		ATTR: function( elem, match ) {+			var name = match[1],+				result = Sizzle.attr ?+					Sizzle.attr( elem, name ) :+					Expr.attrHandle[ name ] ?+					Expr.attrHandle[ name ]( elem ) :+					elem[ name ] != null ?+						elem[ name ] :+						elem.getAttribute( name ),+				value = result + "",+				type = match[2],+				check = match[4];++			return result == null ?+				type === "!=" :+				!type && Sizzle.attr ?+				result != null :+				type === "=" ?+				value === check :+				type === "*=" ?+				value.indexOf(check) >= 0 :+				type === "~=" ?+				(" " + value + " ").indexOf(check) >= 0 :+				!check ?+				value && result !== false :+				type === "!=" ?+				value !== check :+				type === "^=" ?+				value.indexOf(check) === 0 :+				type === "$=" ?+				value.substr(value.length - check.length) === check :+				type === "|=" ?+				value === check || value.substr(0, check.length + 1) === check + "-" :+				false;+		},++		POS: function( elem, match, i, array ) {+			var name = match[2],+				filter = Expr.setFilters[ name ];++			if ( filter ) {+				return filter( elem, i, match, array );+			}+		}+	}+};++var origPOS = Expr.match.POS,+	fescape = function(all, num){+		return "\\" + (num - 0 + 1);+	};++for ( var type in Expr.match ) {+	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );+	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );+}+// Expose origPOS+// "global" as in regardless of relation to brackets/parens+Expr.match.globalPOS = origPOS;++var makeArray = function( array, results ) {+	array = Array.prototype.slice.call( array, 0 );++	if ( results ) {+		results.push.apply( results, array );+		return results;+	}++	return array;+};++// Perform a simple check to determine if the browser is capable of+// converting a NodeList to an array using builtin methods.+// Also verifies that the returned array holds DOM nodes+// (which is not the case in the Blackberry browser)+try {+	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;++// Provide a fallback method if it does not work+} catch( e ) {+	makeArray = function( array, results ) {+		var i = 0,+			ret = results || [];++		if ( toString.call(array) === "[object Array]" ) {+			Array.prototype.push.apply( ret, array );++		} else {+			if ( typeof array.length === "number" ) {+				for ( var l = array.length; i < l; i++ ) {+					ret.push( array[i] );+				}++			} else {+				for ( ; array[i]; i++ ) {+					ret.push( array[i] );+				}+			}+		}++		return ret;+	};+}++var sortOrder, siblingCheck;++if ( document.documentElement.compareDocumentPosition ) {+	sortOrder = function( a, b ) {+		if ( a === b ) {+			hasDuplicate = true;+			return 0;+		}++		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {+			return a.compareDocumentPosition ? -1 : 1;+		}++		return a.compareDocumentPosition(b) & 4 ? -1 : 1;+	};++} else {+	sortOrder = function( a, b ) {+		// The nodes are identical, we can exit early+		if ( a === b ) {+			hasDuplicate = true;+			return 0;++		// Fallback to using sourceIndex (in IE) if it's available on both nodes+		} else if ( a.sourceIndex && b.sourceIndex ) {+			return a.sourceIndex - b.sourceIndex;+		}++		var al, bl,+			ap = [],+			bp = [],+			aup = a.parentNode,+			bup = b.parentNode,+			cur = aup;++		// If the nodes are siblings (or identical) we can do a quick check+		if ( aup === bup ) {+			return siblingCheck( a, b );++		// If no parents were found then the nodes are disconnected+		} else if ( !aup ) {+			return -1;++		} else if ( !bup ) {+			return 1;+		}++		// Otherwise they're somewhere else in the tree so we need+		// to build up a full list of the parentNodes for comparison+		while ( cur ) {+			ap.unshift( cur );+			cur = cur.parentNode;+		}++		cur = bup;++		while ( cur ) {+			bp.unshift( cur );+			cur = cur.parentNode;+		}++		al = ap.length;+		bl = bp.length;++		// Start walking down the tree looking for a discrepancy+		for ( var i = 0; i < al && i < bl; i++ ) {+			if ( ap[i] !== bp[i] ) {+				return siblingCheck( ap[i], bp[i] );+			}+		}++		// We ended someplace up the tree so do a sibling check+		return i === al ?+			siblingCheck( a, bp[i], -1 ) :+			siblingCheck( ap[i], b, 1 );+	};++	siblingCheck = function( a, b, ret ) {+		if ( a === b ) {+			return ret;+		}++		var cur = a.nextSibling;++		while ( cur ) {+			if ( cur === b ) {+				return -1;+			}++			cur = cur.nextSibling;+		}++		return 1;+	};+}++// Check to see if the browser returns elements by name when+// querying by getElementById (and provide a workaround)+(function(){+	// We're going to inject a fake input element with a specified name+	var form = document.createElement("div"),+		id = "script" + (new Date()).getTime(),+		root = document.documentElement;++	form.innerHTML = "<a name='" + id + "'/>";++	// Inject it into the root element, check its status, and remove it quickly+	root.insertBefore( form, root.firstChild );++	// The workaround has to do additional checks after a getElementById+	// Which slows things down for other browsers (hence the branching)+	if ( document.getElementById( id ) ) {+		Expr.find.ID = function( match, context, isXML ) {+			if ( typeof context.getElementById !== "undefined" && !isXML ) {+				var m = context.getElementById(match[1]);++				return m ?+					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?+						[m] :+						undefined :+					[];+			}+		};++		Expr.filter.ID = function( elem, match ) {+			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");++			return elem.nodeType === 1 && node && node.nodeValue === match;+		};+	}++	root.removeChild( form );++	// release memory in IE+	root = form = null;+})();++(function(){+	// Check to see if the browser returns only elements+	// when doing getElementsByTagName("*")++	// Create a fake element+	var div = document.createElement("div");+	div.appendChild( document.createComment("") );++	// Make sure no comments are found+	if ( div.getElementsByTagName("*").length > 0 ) {+		Expr.find.TAG = function( match, context ) {+			var results = context.getElementsByTagName( match[1] );++			// Filter out possible comments+			if ( match[1] === "*" ) {+				var tmp = [];++				for ( var i = 0; results[i]; i++ ) {+					if ( results[i].nodeType === 1 ) {+						tmp.push( results[i] );+					}+				}++				results = tmp;+			}++			return results;+		};+	}++	// Check to see if an attribute returns normalized href attributes+	div.innerHTML = "<a href='#'></a>";++	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&+			div.firstChild.getAttribute("href") !== "#" ) {++		Expr.attrHandle.href = function( elem ) {+			return elem.getAttribute( "href", 2 );+		};+	}++	// release memory in IE+	div = null;+})();++if ( document.querySelectorAll ) {+	(function(){+		var oldSizzle = Sizzle,+			div = document.createElement("div"),+			id = "__sizzle__";++		div.innerHTML = "<p class='TEST'></p>";++		// Safari can't handle uppercase or unicode characters when+		// in quirks mode.+		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {+			return;+		}++		Sizzle = function( query, context, extra, seed ) {+			context = context || document;++			// Only use querySelectorAll on non-XML documents+			// (ID selectors don't work in non-HTML documents)+			if ( !seed && !Sizzle.isXML(context) ) {+				// See if we find a selector to speed up+				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );++				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {+					// Speed-up: Sizzle("TAG")+					if ( match[1] ) {+						return makeArray( context.getElementsByTagName( query ), extra );++					// Speed-up: Sizzle(".CLASS")+					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {+						return makeArray( context.getElementsByClassName( match[2] ), extra );+					}+				}++				if ( context.nodeType === 9 ) {+					// Speed-up: Sizzle("body")+					// The body element only exists once, optimize finding it+					if ( query === "body" && context.body ) {+						return makeArray( [ context.body ], extra );++					// Speed-up: Sizzle("#ID")+					} else if ( match && match[3] ) {+						var elem = context.getElementById( match[3] );++						// Check parentNode to catch when Blackberry 4.6 returns+						// nodes that are no longer in the document #6963+						if ( elem && elem.parentNode ) {+							// Handle the case where IE and Opera return items+							// by name instead of ID+							if ( elem.id === match[3] ) {+								return makeArray( [ elem ], extra );+							}++						} else {+							return makeArray( [], extra );+						}+					}++					try {+						return makeArray( context.querySelectorAll(query), extra );+					} catch(qsaError) {}++				// qSA works strangely on Element-rooted queries+				// We can work around this by specifying an extra ID on the root+				// and working up from there (Thanks to Andrew Dupont for the technique)+				// IE 8 doesn't work on object elements+				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {+					var oldContext = context,+						old = context.getAttribute( "id" ),+						nid = old || id,+						hasParent = context.parentNode,+						relativeHierarchySelector = /^\s*[+~]/.test( query );++					if ( !old ) {+						context.setAttribute( "id", nid );+					} else {+						nid = nid.replace( /'/g, "\\$&" );+					}+					if ( relativeHierarchySelector && hasParent ) {+						context = context.parentNode;+					}++					try {+						if ( !relativeHierarchySelector || hasParent ) {+							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );+						}++					} catch(pseudoError) {+					} finally {+						if ( !old ) {+							oldContext.removeAttribute( "id" );+						}+					}+				}+			}++			return oldSizzle(query, context, extra, seed);+		};++		for ( var prop in oldSizzle ) {+			Sizzle[ prop ] = oldSizzle[ prop ];+		}++		// release memory in IE+		div = null;+	})();+}++(function(){+	var html = document.documentElement,+		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;++	if ( matches ) {+		// Check to see if it's possible to do matchesSelector+		// on a disconnected node (IE 9 fails this)+		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),+			pseudoWorks = false;++		try {+			// This should fail with an exception+			// Gecko does not error, returns false instead+			matches.call( document.documentElement, "[test!='']:sizzle" );++		} catch( pseudoError ) {+			pseudoWorks = true;+		}++		Sizzle.matchesSelector = function( node, expr ) {+			// Make sure that attribute selectors are quoted+			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");++			if ( !Sizzle.isXML( node ) ) {+				try {+					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {+						var ret = matches.call( node, expr );++						// IE 9's matchesSelector returns false on disconnected nodes+						if ( ret || !disconnectedMatch ||+								// As well, disconnected nodes are said to be in a document+								// fragment in IE 9, so check for that+								node.document && node.document.nodeType !== 11 ) {+							return ret;+						}+					}+				} catch(e) {}+			}++			return Sizzle(expr, null, null, [node]).length > 0;+		};+	}+})();++(function(){+	var div = document.createElement("div");++	div.innerHTML = "<div class='test e'></div><div class='test'></div>";++	// Opera can't find a second classname (in 9.6)+	// Also, make sure that getElementsByClassName actually exists+	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {+		return;+	}++	// Safari caches class attributes, doesn't catch changes (in 3.2)+	div.lastChild.className = "e";++	if ( div.getElementsByClassName("e").length === 1 ) {+		return;+	}++	Expr.order.splice(1, 0, "CLASS");+	Expr.find.CLASS = function( match, context, isXML ) {+		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {+			return context.getElementsByClassName(match[1]);+		}+	};++	// release memory in IE+	div = null;+})();++function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {+		var elem = checkSet[i];++		if ( elem ) {+			var match = false;++			elem = elem[dir];++			while ( elem ) {+				if ( elem[ expando ] === doneName ) {+					match = checkSet[elem.sizset];+					break;+				}++				if ( elem.nodeType === 1 && !isXML ){+					elem[ expando ] = doneName;+					elem.sizset = i;+				}++				if ( elem.nodeName.toLowerCase() === cur ) {+					match = elem;+					break;+				}++				elem = elem[dir];+			}++			checkSet[i] = match;+		}+	}+}++function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {+		var elem = checkSet[i];++		if ( elem ) {+			var match = false;++			elem = elem[dir];++			while ( elem ) {+				if ( elem[ expando ] === doneName ) {+					match = checkSet[elem.sizset];+					break;+				}++				if ( elem.nodeType === 1 ) {+					if ( !isXML ) {+						elem[ expando ] = doneName;+						elem.sizset = i;+					}++					if ( typeof cur !== "string" ) {+						if ( elem === cur ) {+							match = true;+							break;+						}++					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {+						match = elem;+						break;+					}+				}++				elem = elem[dir];+			}++			checkSet[i] = match;+		}+	}+}++if ( document.documentElement.contains ) {+	Sizzle.contains = function( a, b ) {+		return a !== b && (a.contains ? a.contains(b) : true);+	};++} else if ( document.documentElement.compareDocumentPosition ) {+	Sizzle.contains = function( a, b ) {+		return !!(a.compareDocumentPosition(b) & 16);+	};++} else {+	Sizzle.contains = function() {+		return false;+	};+}++Sizzle.isXML = function( elem ) {+	// documentElement is verified for cases where it doesn't yet exist+	// (such as loading iframes in IE - #4833)+	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;++	return documentElement ? documentElement.nodeName !== "HTML" : false;+};++var posProcess = function( selector, context, seed ) {+	var match,+		tmpSet = [],+		later = "",+		root = context.nodeType ? [context] : context;++	// Position selectors must be done after the filter+	// And so must :not(positional) so we move all PSEUDOs to the end+	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {+		later += match[0];+		selector = selector.replace( Expr.match.PSEUDO, "" );+	}++	selector = Expr.relative[selector] ? selector + "*" : selector;++	for ( var i = 0, l = root.length; i < l; i++ ) {+		Sizzle( selector, root[i], tmpSet, seed );+	}++	return Sizzle.filter( later, tmpSet );+};++// EXPOSE+// Override sizzle attribute retrieval+Sizzle.attr = jQuery.attr;+Sizzle.selectors.attrMap = {};+jQuery.find = Sizzle;+jQuery.expr = Sizzle.selectors;+jQuery.expr[":"] = jQuery.expr.filters;+jQuery.unique = Sizzle.uniqueSort;+jQuery.text = Sizzle.getText;+jQuery.isXMLDoc = Sizzle.isXML;+jQuery.contains = Sizzle.contains;+++})();+++var runtil = /Until$/,+	rparentsprev = /^(?:parents|prevUntil|prevAll)/,+	// Note: This RegExp should be improved, or likely pulled from Sizzle+	rmultiselector = /,/,+	isSimple = /^.[^:#\[\.,]*$/,+	slice = Array.prototype.slice,+	POS = jQuery.expr.match.globalPOS,+	// methods guaranteed to produce a unique set when starting from a unique set+	guaranteedUnique = {+		children: true,+		contents: true,+		next: true,+		prev: true+	};++jQuery.fn.extend({+	find: function( selector ) {+		var self = this,+			i, l;++		if ( typeof selector !== "string" ) {+			return jQuery( selector ).filter(function() {+				for ( i = 0, l = self.length; i < l; i++ ) {+					if ( jQuery.contains( self[ i ], this ) ) {+						return true;+					}+				}+			});+		}++		var ret = this.pushStack( "", "find", selector ),+			length, n, r;++		for ( i = 0, l = this.length; i < l; i++ ) {+			length = ret.length;+			jQuery.find( selector, this[i], ret );++			if ( i > 0 ) {+				// Make sure that the results are unique+				for ( n = length; n < ret.length; n++ ) {+					for ( r = 0; r < length; r++ ) {+						if ( ret[r] === ret[n] ) {+							ret.splice(n--, 1);+							break;+						}+					}+				}+			}+		}++		return ret;+	},++	has: function( target ) {+		var targets = jQuery( target );+		return this.filter(function() {+			for ( var i = 0, l = targets.length; i < l; i++ ) {+				if ( jQuery.contains( this, targets[i] ) ) {+					return true;+				}+			}+		});+	},++	not: function( selector ) {+		return this.pushStack( winnow(this, selector, false), "not", selector);+	},++	filter: function( selector ) {+		return this.pushStack( winnow(this, selector, true), "filter", selector );+	},++	is: function( selector ) {+		return !!selector && (+			typeof selector === "string" ?+				// If this is a positional selector, check membership in the returned set+				// so $("p:first").is("p:last") won't return true for a doc with two "p".+				POS.test( selector ) ?+					jQuery( selector, this.context ).index( this[0] ) >= 0 :+					jQuery.filter( selector, this ).length > 0 :+				this.filter( selector ).length > 0 );+	},++	closest: function( selectors, context ) {+		var ret = [], i, l, cur = this[0];++		// Array (deprecated as of jQuery 1.7)+		if ( jQuery.isArray( selectors ) ) {+			var level = 1;++			while ( cur && cur.ownerDocument && cur !== context ) {+				for ( i = 0; i < selectors.length; i++ ) {++					if ( jQuery( cur ).is( selectors[ i ] ) ) {+						ret.push({ selector: selectors[ i ], elem: cur, level: level });+					}+				}++				cur = cur.parentNode;+				level++;+			}++			return ret;+		}++		// String+		var pos = POS.test( selectors ) || typeof selectors !== "string" ?+				jQuery( selectors, context || this.context ) :+				0;++		for ( i = 0, l = this.length; i < l; i++ ) {+			cur = this[i];++			while ( cur ) {+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {+					ret.push( cur );+					break;++				} else {+					cur = cur.parentNode;+					if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {+						break;+					}+				}+			}+		}++		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;++		return this.pushStack( ret, "closest", selectors );+	},++	// Determine the position of an element within+	// the matched set of elements+	index: function( elem ) {++		// No argument, return index in parent+		if ( !elem ) {+			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;+		}++		// index in selector+		if ( typeof elem === "string" ) {+			return jQuery.inArray( this[0], jQuery( elem ) );+		}++		// Locate the position of the desired element+		return jQuery.inArray(+			// If it receives a jQuery object, the first element is used+			elem.jquery ? elem[0] : elem, this );+	},++	add: function( selector, context ) {+		var set = typeof selector === "string" ?+				jQuery( selector, context ) :+				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),+			all = jQuery.merge( this.get(), set );++		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?+			all :+			jQuery.unique( all ) );+	},++	andSelf: function() {+		return this.add( this.prevObject );+	}+});++// A painfully simple check to see if an element is disconnected+// from a document (should be improved, where feasible).+function isDisconnected( node ) {+	return !node || !node.parentNode || node.parentNode.nodeType === 11;+}++jQuery.each({+	parent: function( elem ) {+		var parent = elem.parentNode;+		return parent && parent.nodeType !== 11 ? parent : null;+	},+	parents: function( elem ) {+		return jQuery.dir( elem, "parentNode" );+	},+	parentsUntil: function( elem, i, until ) {+		return jQuery.dir( elem, "parentNode", until );+	},+	next: function( elem ) {+		return jQuery.nth( elem, 2, "nextSibling" );+	},+	prev: function( elem ) {+		return jQuery.nth( elem, 2, "previousSibling" );+	},+	nextAll: function( elem ) {+		return jQuery.dir( elem, "nextSibling" );+	},+	prevAll: function( elem ) {+		return jQuery.dir( elem, "previousSibling" );+	},+	nextUntil: function( elem, i, until ) {+		return jQuery.dir( elem, "nextSibling", until );+	},+	prevUntil: function( elem, i, until ) {+		return jQuery.dir( elem, "previousSibling", until );+	},+	siblings: function( elem ) {+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );+	},+	children: function( elem ) {+		return jQuery.sibling( elem.firstChild );+	},+	contents: function( elem ) {+		return jQuery.nodeName( elem, "iframe" ) ?+			elem.contentDocument || elem.contentWindow.document :+			jQuery.makeArray( elem.childNodes );+	}+}, function( name, fn ) {+	jQuery.fn[ name ] = function( until, selector ) {+		var ret = jQuery.map( this, fn, until );++		if ( !runtil.test( name ) ) {+			selector = until;+		}++		if ( selector && typeof selector === "string" ) {+			ret = jQuery.filter( selector, ret );+		}++		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;++		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {+			ret = ret.reverse();+		}++		return this.pushStack( ret, name, slice.call( arguments ).join(",") );+	};+});++jQuery.extend({+	filter: function( expr, elems, not ) {+		if ( not ) {+			expr = ":not(" + expr + ")";+		}++		return elems.length === 1 ?+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :+			jQuery.find.matches(expr, elems);+	},++	dir: function( elem, dir, until ) {+		var matched = [],+			cur = elem[ dir ];++		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {+			if ( cur.nodeType === 1 ) {+				matched.push( cur );+			}+			cur = cur[dir];+		}+		return matched;+	},++	nth: function( cur, result, dir, elem ) {+		result = result || 1;+		var num = 0;++		for ( ; cur; cur = cur[dir] ) {+			if ( cur.nodeType === 1 && ++num === result ) {+				break;+			}+		}++		return cur;+	},++	sibling: function( n, elem ) {+		var r = [];++		for ( ; n; n = n.nextSibling ) {+			if ( n.nodeType === 1 && n !== elem ) {+				r.push( n );+			}+		}++		return r;+	}+});++// Implement the identical functionality for filter and not+function winnow( elements, qualifier, keep ) {++	// Can't pass null or undefined to indexOf in Firefox 4+	// Set to 0 to skip string check+	qualifier = qualifier || 0;++	if ( jQuery.isFunction( qualifier ) ) {+		return jQuery.grep(elements, function( elem, i ) {+			var retVal = !!qualifier.call( elem, i, elem );+			return retVal === keep;+		});++	} else if ( qualifier.nodeType ) {+		return jQuery.grep(elements, function( elem, i ) {+			return ( elem === qualifier ) === keep;+		});++	} else if ( typeof qualifier === "string" ) {+		var filtered = jQuery.grep(elements, function( elem ) {+			return elem.nodeType === 1;+		});++		if ( isSimple.test( qualifier ) ) {+			return jQuery.filter(qualifier, filtered, !keep);+		} else {+			qualifier = jQuery.filter( qualifier, filtered );+		}+	}++	return jQuery.grep(elements, function( elem, i ) {+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;+	});+}+++++function createSafeFragment( document ) {+	var list = nodeNames.split( "|" ),+	safeFrag = document.createDocumentFragment();++	if ( safeFrag.createElement ) {+		while ( list.length ) {+			safeFrag.createElement(+				list.pop()+			);+		}+	}+	return safeFrag;+}++var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" ++		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",+	rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,+	rleadingWhitespace = /^\s+/,+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,+	rtagName = /<([\w:]+)/,+	rtbody = /<tbody/i,+	rhtml = /<|&#?\w+;/,+	rnoInnerhtml = /<(?:script|style)/i,+	rnocache = /<(?:script|object|embed|option|style)/i,+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),+	// checked="checked" or checked+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,+	rscriptType = /\/(java|ecma)script/i,+	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,+	wrapMap = {+		option: [ 1, "<select multiple='multiple'>", "</select>" ],+		legend: [ 1, "<fieldset>", "</fieldset>" ],+		thead: [ 1, "<table>", "</table>" ],+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],+		area: [ 1, "<map>", "</map>" ],+		_default: [ 0, "", "" ]+	},+	safeFragment = createSafeFragment( document );++wrapMap.optgroup = wrapMap.option;+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;+wrapMap.th = wrapMap.td;++// IE can't serialize <link> and <script> tags normally+if ( !jQuery.support.htmlSerialize ) {+	wrapMap._default = [ 1, "div<div>", "</div>" ];+}++jQuery.fn.extend({+	text: function( value ) {+		return jQuery.access( this, function( value ) {+			return value === undefined ?+				jQuery.text( this ) :+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );+		}, null, value, arguments.length );+	},++	wrapAll: function( html ) {+		if ( jQuery.isFunction( html ) ) {+			return this.each(function(i) {+				jQuery(this).wrapAll( html.call(this, i) );+			});+		}++		if ( this[0] ) {+			// The elements to wrap the target around+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);++			if ( this[0].parentNode ) {+				wrap.insertBefore( this[0] );+			}++			wrap.map(function() {+				var elem = this;++				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {+					elem = elem.firstChild;+				}++				return elem;+			}).append( this );+		}++		return this;+	},++	wrapInner: function( html ) {+		if ( jQuery.isFunction( html ) ) {+			return this.each(function(i) {+				jQuery(this).wrapInner( html.call(this, i) );+			});+		}++		return this.each(function() {+			var self = jQuery( this ),+				contents = self.contents();++			if ( contents.length ) {+				contents.wrapAll( html );++			} else {+				self.append( html );+			}+		});+	},++	wrap: function( html ) {+		var isFunction = jQuery.isFunction( html );++		return this.each(function(i) {+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );+		});+	},++	unwrap: function() {+		return this.parent().each(function() {+			if ( !jQuery.nodeName( this, "body" ) ) {+				jQuery( this ).replaceWith( this.childNodes );+			}+		}).end();+	},++	append: function() {+		return this.domManip(arguments, true, function( elem ) {+			if ( this.nodeType === 1 ) {+				this.appendChild( elem );+			}+		});+	},++	prepend: function() {+		return this.domManip(arguments, true, function( elem ) {+			if ( this.nodeType === 1 ) {+				this.insertBefore( elem, this.firstChild );+			}+		});+	},++	before: function() {+		if ( this[0] && this[0].parentNode ) {+			return this.domManip(arguments, false, function( elem ) {+				this.parentNode.insertBefore( elem, this );+			});+		} else if ( arguments.length ) {+			var set = jQuery.clean( arguments );+			set.push.apply( set, this.toArray() );+			return this.pushStack( set, "before", arguments );+		}+	},++	after: function() {+		if ( this[0] && this[0].parentNode ) {+			return this.domManip(arguments, false, function( elem ) {+				this.parentNode.insertBefore( elem, this.nextSibling );+			});+		} else if ( arguments.length ) {+			var set = this.pushStack( this, "after", arguments );+			set.push.apply( set, jQuery.clean(arguments) );+			return set;+		}+	},++	// keepData is for internal use only--do not document+	remove: function( selector, keepData ) {+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {+				if ( !keepData && elem.nodeType === 1 ) {+					jQuery.cleanData( elem.getElementsByTagName("*") );+					jQuery.cleanData( [ elem ] );+				}++				if ( elem.parentNode ) {+					elem.parentNode.removeChild( elem );+				}+			}+		}++		return this;+	},++	empty: function() {+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+			// Remove element nodes and prevent memory leaks+			if ( elem.nodeType === 1 ) {+				jQuery.cleanData( elem.getElementsByTagName("*") );+			}++			// Remove any remaining nodes+			while ( elem.firstChild ) {+				elem.removeChild( elem.firstChild );+			}+		}++		return this;+	},++	clone: function( dataAndEvents, deepDataAndEvents ) {+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;++		return this.map( function () {+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );+		});+	},++	html: function( value ) {+		return jQuery.access( this, function( value ) {+			var elem = this[0] || {},+				i = 0,+				l = this.length;++			if ( value === undefined ) {+				return elem.nodeType === 1 ?+					elem.innerHTML.replace( rinlinejQuery, "" ) :+					null;+			}+++			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&+				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&+				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {++				value = value.replace( rxhtmlTag, "<$1></$2>" );++				try {+					for (; i < l; i++ ) {+						// Remove element nodes and prevent memory leaks+						elem = this[i] || {};+						if ( elem.nodeType === 1 ) {+							jQuery.cleanData( elem.getElementsByTagName( "*" ) );+							elem.innerHTML = value;+						}+					}++					elem = 0;++				// If using innerHTML throws an exception, use the fallback method+				} catch(e) {}+			}++			if ( elem ) {+				this.empty().append( value );+			}+		}, null, value, arguments.length );+	},++	replaceWith: function( value ) {+		if ( this[0] && this[0].parentNode ) {+			// Make sure that the elements are removed from the DOM before they are inserted+			// this can help fix replacing a parent with child elements+			if ( jQuery.isFunction( value ) ) {+				return this.each(function(i) {+					var self = jQuery(this), old = self.html();+					self.replaceWith( value.call( this, i, old ) );+				});+			}++			if ( typeof value !== "string" ) {+				value = jQuery( value ).detach();+			}++			return this.each(function() {+				var next = this.nextSibling,+					parent = this.parentNode;++				jQuery( this ).remove();++				if ( next ) {+					jQuery(next).before( value );+				} else {+					jQuery(parent).append( value );+				}+			});+		} else {+			return this.length ?+				this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :+				this;+		}+	},++	detach: function( selector ) {+		return this.remove( selector, true );+	},++	domManip: function( args, table, callback ) {+		var results, first, fragment, parent,+			value = args[0],+			scripts = [];++		// We can't cloneNode fragments that contain checked, in WebKit+		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {+			return this.each(function() {+				jQuery(this).domManip( args, table, callback, true );+			});+		}++		if ( jQuery.isFunction(value) ) {+			return this.each(function(i) {+				var self = jQuery(this);+				args[0] = value.call(this, i, table ? self.html() : undefined);+				self.domManip( args, table, callback );+			});+		}++		if ( this[0] ) {+			parent = value && value.parentNode;++			// If we're in a fragment, just use that instead of building a new one+			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {+				results = { fragment: parent };++			} else {+				results = jQuery.buildFragment( args, this, scripts );+			}++			fragment = results.fragment;++			if ( fragment.childNodes.length === 1 ) {+				first = fragment = fragment.firstChild;+			} else {+				first = fragment.firstChild;+			}++			if ( first ) {+				table = table && jQuery.nodeName( first, "tr" );++				for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {+					callback.call(+						table ?+							root(this[i], first) :+							this[i],+						// Make sure that we do not leak memory by inadvertently discarding+						// the original fragment (which might have attached data) instead of+						// using it; in addition, use the original fragment object for the last+						// item instead of first because it can end up being emptied incorrectly+						// in certain situations (Bug #8070).+						// Fragments from the fragment cache must always be cloned and never used+						// in place.+						results.cacheable || ( l > 1 && i < lastIndex ) ?+							jQuery.clone( fragment, true, true ) :+							fragment+					);+				}+			}++			if ( scripts.length ) {+				jQuery.each( scripts, function( i, elem ) {+					if ( elem.src ) {+						jQuery.ajax({+							type: "GET",+							global: false,+							url: elem.src,+							async: false,+							dataType: "script"+						});+					} else {+						jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );+					}++					if ( elem.parentNode ) {+						elem.parentNode.removeChild( elem );+					}+				});+			}+		}++		return this;+	}+});++function root( elem, cur ) {+	return jQuery.nodeName(elem, "table") ?+		(elem.getElementsByTagName("tbody")[0] ||+		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :+		elem;+}++function cloneCopyEvent( src, dest ) {++	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {+		return;+	}++	var type, i, l,+		oldData = jQuery._data( src ),+		curData = jQuery._data( dest, oldData ),+		events = oldData.events;++	if ( events ) {+		delete curData.handle;+		curData.events = {};++		for ( type in events ) {+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {+				jQuery.event.add( dest, type, events[ type ][ i ] );+			}+		}+	}++	// make the cloned public data object a copy from the original+	if ( curData.data ) {+		curData.data = jQuery.extend( {}, curData.data );+	}+}++function cloneFixAttributes( src, dest ) {+	var nodeName;++	// We do not need to do anything for non-Elements+	if ( dest.nodeType !== 1 ) {+		return;+	}++	// clearAttributes removes the attributes, which we don't want,+	// but also removes the attachEvent events, which we *do* want+	if ( dest.clearAttributes ) {+		dest.clearAttributes();+	}++	// mergeAttributes, in contrast, only merges back on the+	// original attributes, not the events+	if ( dest.mergeAttributes ) {+		dest.mergeAttributes( src );+	}++	nodeName = dest.nodeName.toLowerCase();++	// IE6-8 fail to clone children inside object elements that use+	// the proprietary classid attribute value (rather than the type+	// attribute) to identify the type of content to display+	if ( nodeName === "object" ) {+		dest.outerHTML = src.outerHTML;++	} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {+		// IE6-8 fails to persist the checked state of a cloned checkbox+		// or radio button. Worse, IE6-7 fail to give the cloned element+		// a checked appearance if the defaultChecked value isn't also set+		if ( src.checked ) {+			dest.defaultChecked = dest.checked = src.checked;+		}++		// IE6-7 get confused and end up setting the value of a cloned+		// checkbox/radio button to an empty string instead of "on"+		if ( dest.value !== src.value ) {+			dest.value = src.value;+		}++	// IE6-8 fails to return the selected option to the default selected+	// state when cloning options+	} else if ( nodeName === "option" ) {+		dest.selected = src.defaultSelected;++	// IE6-8 fails to set the defaultValue to the correct value when+	// cloning other types of input fields+	} else if ( nodeName === "input" || nodeName === "textarea" ) {+		dest.defaultValue = src.defaultValue;++	// IE blanks contents when cloning scripts+	} else if ( nodeName === "script" && dest.text !== src.text ) {+		dest.text = src.text;+	}++	// Event data gets referenced instead of copied if the expando+	// gets copied too+	dest.removeAttribute( jQuery.expando );++	// Clear flags for bubbling special change/submit events, they must+	// be reattached when the newly cloned events are first activated+	dest.removeAttribute( "_submit_attached" );+	dest.removeAttribute( "_change_attached" );+}++jQuery.buildFragment = function( args, nodes, scripts ) {+	var fragment, cacheable, cacheresults, doc,+	first = args[ 0 ];++	// nodes may contain either an explicit document object,+	// a jQuery collection or context object.+	// If nodes[0] contains a valid object to assign to doc+	if ( nodes && nodes[0] ) {+		doc = nodes[0].ownerDocument || nodes[0];+	}++	// Ensure that an attr object doesn't incorrectly stand in as a document object+	// Chrome and Firefox seem to allow this to occur and will throw exception+	// Fixes #8950+	if ( !doc.createDocumentFragment ) {+		doc = document;+	}++	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document+	// Cloning options loses the selected state, so don't cache them+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache+	// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501+	if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&+		first.charAt(0) === "<" && !rnocache.test( first ) &&+		(jQuery.support.checkClone || !rchecked.test( first )) &&+		(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {++		cacheable = true;++		cacheresults = jQuery.fragments[ first ];+		if ( cacheresults && cacheresults !== 1 ) {+			fragment = cacheresults;+		}+	}++	if ( !fragment ) {+		fragment = doc.createDocumentFragment();+		jQuery.clean( args, doc, fragment, scripts );+	}++	if ( cacheable ) {+		jQuery.fragments[ first ] = cacheresults ? fragment : 1;+	}++	return { fragment: fragment, cacheable: cacheable };+};++jQuery.fragments = {};++jQuery.each({+	appendTo: "append",+	prependTo: "prepend",+	insertBefore: "before",+	insertAfter: "after",+	replaceAll: "replaceWith"+}, function( name, original ) {+	jQuery.fn[ name ] = function( selector ) {+		var ret = [],+			insert = jQuery( selector ),+			parent = this.length === 1 && this[0].parentNode;++		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {+			insert[ original ]( this[0] );+			return this;++		} else {+			for ( var i = 0, l = insert.length; i < l; i++ ) {+				var elems = ( i > 0 ? this.clone(true) : this ).get();+				jQuery( insert[i] )[ original ]( elems );+				ret = ret.concat( elems );+			}++			return this.pushStack( ret, name, insert.selector );+		}+	};+});++function getAll( elem ) {+	if ( typeof elem.getElementsByTagName !== "undefined" ) {+		return elem.getElementsByTagName( "*" );++	} else if ( typeof elem.querySelectorAll !== "undefined" ) {+		return elem.querySelectorAll( "*" );++	} else {+		return [];+	}+}++// Used in clean, fixes the defaultChecked property+function fixDefaultChecked( elem ) {+	if ( elem.type === "checkbox" || elem.type === "radio" ) {+		elem.defaultChecked = elem.checked;+	}+}+// Finds all inputs and passes them to fixDefaultChecked+function findInputs( elem ) {+	var nodeName = ( elem.nodeName || "" ).toLowerCase();+	if ( nodeName === "input" ) {+		fixDefaultChecked( elem );+	// Skip scripts, get other children+	} else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {+		jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );+	}+}++// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js+function shimCloneNode( elem ) {+	var div = document.createElement( "div" );+	safeFragment.appendChild( div );++	div.innerHTML = elem.outerHTML;+	return div.firstChild;+}++jQuery.extend({+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {+		var srcElements,+			destElements,+			i,+			// IE<=8 does not properly clone detached, unknown element nodes+			clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?+				elem.cloneNode( true ) :+				shimCloneNode( elem );++		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {+			// IE copies events bound via attachEvent when using cloneNode.+			// Calling detachEvent on the clone will also remove the events+			// from the original. In order to get around this, we use some+			// proprietary methods to clear the events. Thanks to MooTools+			// guys for this hotness.++			cloneFixAttributes( elem, clone );++			// Using Sizzle here is crazy slow, so we use getElementsByTagName instead+			srcElements = getAll( elem );+			destElements = getAll( clone );++			// Weird iteration because IE will replace the length property+			// with an element if you are cloning the body and one of the+			// elements on the page has a name or id of "length"+			for ( i = 0; srcElements[i]; ++i ) {+				// Ensure that the destination node is not null; Fixes #9587+				if ( destElements[i] ) {+					cloneFixAttributes( srcElements[i], destElements[i] );+				}+			}+		}++		// Copy the events from the original to the clone+		if ( dataAndEvents ) {+			cloneCopyEvent( elem, clone );++			if ( deepDataAndEvents ) {+				srcElements = getAll( elem );+				destElements = getAll( clone );++				for ( i = 0; srcElements[i]; ++i ) {+					cloneCopyEvent( srcElements[i], destElements[i] );+				}+			}+		}++		srcElements = destElements = null;++		// Return the cloned set+		return clone;+	},++	clean: function( elems, context, fragment, scripts ) {+		var checkScriptType, script, j,+				ret = [];++		context = context || document;++		// !context.createElement fails in IE with an error but returns typeof 'object'+		if ( typeof context.createElement === "undefined" ) {+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;+		}++		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+			if ( typeof elem === "number" ) {+				elem += "";+			}++			if ( !elem ) {+				continue;+			}++			// Convert html string into DOM nodes+			if ( typeof elem === "string" ) {+				if ( !rhtml.test( elem ) ) {+					elem = context.createTextNode( elem );+				} else {+					// Fix "XHTML"-style tags in all browsers+					elem = elem.replace(rxhtmlTag, "<$1></$2>");++					// Trim whitespace, otherwise indexOf won't work as expected+					var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),+						wrap = wrapMap[ tag ] || wrapMap._default,+						depth = wrap[0],+						div = context.createElement("div"),+						safeChildNodes = safeFragment.childNodes,+						remove;++					// Append wrapper element to unknown element safe doc fragment+					if ( context === document ) {+						// Use the fragment we've already created for this document+						safeFragment.appendChild( div );+					} else {+						// Use a fragment created with the owner document+						createSafeFragment( context ).appendChild( div );+					}++					// Go to html and back, then peel off extra wrappers+					div.innerHTML = wrap[1] + elem + wrap[2];++					// Move to the right depth+					while ( depth-- ) {+						div = div.lastChild;+					}++					// Remove IE's autoinserted <tbody> from table fragments+					if ( !jQuery.support.tbody ) {++						// String was a <table>, *may* have spurious <tbody>+						var hasBody = rtbody.test(elem),+							tbody = tag === "table" && !hasBody ?+								div.firstChild && div.firstChild.childNodes :++								// String was a bare <thead> or <tfoot>+								wrap[1] === "<table>" && !hasBody ?+									div.childNodes :+									[];++						for ( j = tbody.length - 1; j >= 0 ; --j ) {+							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {+								tbody[ j ].parentNode.removeChild( tbody[ j ] );+							}+						}+					}++					// IE completely kills leading whitespace when innerHTML is used+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {+						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );+					}++					elem = div.childNodes;++					// Clear elements from DocumentFragment (safeFragment or otherwise)+					// to avoid hoarding elements. Fixes #11356+					if ( div ) {+						div.parentNode.removeChild( div );++						// Guard against -1 index exceptions in FF3.6+						if ( safeChildNodes.length > 0 ) {+							remove = safeChildNodes[ safeChildNodes.length - 1 ];++							if ( remove && remove.parentNode ) {+								remove.parentNode.removeChild( remove );+							}+						}+					}+				}+			}++			// Resets defaultChecked for any radios and checkboxes+			// about to be appended to the DOM in IE 6/7 (#8060)+			var len;+			if ( !jQuery.support.appendChecked ) {+				if ( elem[0] && typeof (len = elem.length) === "number" ) {+					for ( j = 0; j < len; j++ ) {+						findInputs( elem[j] );+					}+				} else {+					findInputs( elem );+				}+			}++			if ( elem.nodeType ) {+				ret.push( elem );+			} else {+				ret = jQuery.merge( ret, elem );+			}+		}++		if ( fragment ) {+			checkScriptType = function( elem ) {+				return !elem.type || rscriptType.test( elem.type );+			};+			for ( i = 0; ret[i]; i++ ) {+				script = ret[i];+				if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {+					scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );++				} else {+					if ( script.nodeType === 1 ) {+						var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType );++						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );+					}+					fragment.appendChild( script );+				}+			}+		}++		return ret;+	},++	cleanData: function( elems ) {+		var data, id,+			cache = jQuery.cache,+			special = jQuery.event.special,+			deleteExpando = jQuery.support.deleteExpando;++		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {+				continue;+			}++			id = elem[ jQuery.expando ];++			if ( id ) {+				data = cache[ id ];++				if ( data && data.events ) {+					for ( var type in data.events ) {+						if ( special[ type ] ) {+							jQuery.event.remove( elem, type );++						// This is a shortcut to avoid jQuery.event.remove's overhead+						} else {+							jQuery.removeEvent( elem, type, data.handle );+						}+					}++					// Null the DOM reference to avoid IE6/7/8 leak (#7054)+					if ( data.handle ) {+						data.handle.elem = null;+					}+				}++				if ( deleteExpando ) {+					delete elem[ jQuery.expando ];++				} else if ( elem.removeAttribute ) {+					elem.removeAttribute( jQuery.expando );+				}++				delete cache[ id ];+			}+		}+	}+});+++++var ralpha = /alpha\([^)]*\)/i,+	ropacity = /opacity=([^)]*)/,+	// fixed for IE9, see #8346+	rupper = /([A-Z]|^ms)/g,+	rnum = /^[\-+]?(?:\d*\.)?\d+$/i,+	rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,+	rrelNum = /^([\-+])=([\-+.\de]+)/,+	rmargin = /^margin/,++	cssShow = { position: "absolute", visibility: "hidden", display: "block" },++	// order is important!+	cssExpand = [ "Top", "Right", "Bottom", "Left" ],++	curCSS,++	getComputedStyle,+	currentStyle;++jQuery.fn.css = function( name, value ) {+	return jQuery.access( this, function( elem, name, value ) {+		return value !== undefined ?+			jQuery.style( elem, name, value ) :+			jQuery.css( elem, name );+	}, name, value, arguments.length > 1 );+};++jQuery.extend({+	// Add in style property hooks for overriding the default+	// behavior of getting and setting a style property+	cssHooks: {+		opacity: {+			get: function( elem, computed ) {+				if ( computed ) {+					// We should always get a number back from opacity+					var ret = curCSS( elem, "opacity" );+					return ret === "" ? "1" : ret;++				} else {+					return elem.style.opacity;+				}+			}+		}+	},++	// Exclude the following css properties to add px+	cssNumber: {+		"fillOpacity": true,+		"fontWeight": true,+		"lineHeight": true,+		"opacity": true,+		"orphans": true,+		"widows": true,+		"zIndex": true,+		"zoom": true+	},++	// Add in properties whose names you wish to fix before+	// setting or getting the value+	cssProps: {+		// normalize float css property+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"+	},++	// Get and set the style property on a DOM Node+	style: function( elem, name, value, extra ) {+		// Don't set styles on text and comment nodes+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {+			return;+		}++		// Make sure that we're working with the right name+		var ret, type, origName = jQuery.camelCase( name ),+			style = elem.style, hooks = jQuery.cssHooks[ origName ];++		name = jQuery.cssProps[ origName ] || origName;++		// Check if we're setting a value+		if ( value !== undefined ) {+			type = typeof value;++			// convert relative number strings (+= or -=) to relative numbers. #7345+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {+				value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );+				// Fixes bug #9237+				type = "number";+			}++			// Make sure that NaN and null values aren't set. See: #7116+			if ( value == null || type === "number" && isNaN( value ) ) {+				return;+			}++			// If a number was passed in, add 'px' to the (except for certain CSS properties)+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {+				value += "px";+			}++			// If a hook was provided, use that value, otherwise just set the specified value+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided+				// Fixes bug #5509+				try {+					style[ name ] = value;+				} catch(e) {}+			}++		} else {+			// If a hook was provided get the non-computed value from there+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {+				return ret;+			}++			// Otherwise just get the value from the style object+			return style[ name ];+		}+	},++	css: function( elem, name, extra ) {+		var ret, hooks;++		// Make sure that we're working with the right name+		name = jQuery.camelCase( name );+		hooks = jQuery.cssHooks[ name ];+		name = jQuery.cssProps[ name ] || name;++		// cssFloat needs a special treatment+		if ( name === "cssFloat" ) {+			name = "float";+		}++		// If a hook was provided get the computed value from there+		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {+			return ret;++		// Otherwise, if a way to get the computed value exists, use that+		} else if ( curCSS ) {+			return curCSS( elem, name );+		}+	},++	// A method for quickly swapping in/out CSS properties to get correct calculations+	swap: function( elem, options, callback ) {+		var old = {},+			ret, name;++		// Remember the old values, and insert the new ones+		for ( name in options ) {+			old[ name ] = elem.style[ name ];+			elem.style[ name ] = options[ name ];+		}++		ret = callback.call( elem );++		// Revert the old values+		for ( name in options ) {+			elem.style[ name ] = old[ name ];+		}++		return ret;+	}+});++// DEPRECATED in 1.3, Use jQuery.css() instead+jQuery.curCSS = jQuery.css;++if ( document.defaultView && document.defaultView.getComputedStyle ) {+	getComputedStyle = function( elem, name ) {+		var ret, defaultView, computedStyle, width,+			style = elem.style;++		name = name.replace( rupper, "-$1" ).toLowerCase();++		if ( (defaultView = elem.ownerDocument.defaultView) &&+				(computedStyle = defaultView.getComputedStyle( elem, null )) ) {++			ret = computedStyle.getPropertyValue( name );+			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {+				ret = jQuery.style( elem, name );+			}+		}++		// A tribute to the "awesome hack by Dean Edwards"+		// WebKit uses "computed value (percentage if specified)" instead of "used value" for margins+		// which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values+		if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {+			width = style.width;+			style.width = ret;+			ret = computedStyle.width;+			style.width = width;+		}++		return ret;+	};+}++if ( document.documentElement.currentStyle ) {+	currentStyle = function( elem, name ) {+		var left, rsLeft, uncomputed,+			ret = elem.currentStyle && elem.currentStyle[ name ],+			style = elem.style;++		// Avoid setting ret to empty string here+		// so we don't default to auto+		if ( ret == null && style && (uncomputed = style[ name ]) ) {+			ret = uncomputed;+		}++		// From the awesome hack by Dean Edwards+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291++		// If we're not dealing with a regular pixel number+		// but a number that has a weird ending, we need to convert it to pixels+		if ( rnumnonpx.test( ret ) ) {++			// Remember the original values+			left = style.left;+			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;++			// Put in the new values to get a computed value out+			if ( rsLeft ) {+				elem.runtimeStyle.left = elem.currentStyle.left;+			}+			style.left = name === "fontSize" ? "1em" : ret;+			ret = style.pixelLeft + "px";++			// Revert the changed values+			style.left = left;+			if ( rsLeft ) {+				elem.runtimeStyle.left = rsLeft;+			}+		}++		return ret === "" ? "auto" : ret;+	};+}++curCSS = getComputedStyle || currentStyle;++function getWidthOrHeight( elem, name, extra ) {++	// Start with offset property+	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,+		i = name === "width" ? 1 : 0,+		len = 4;++	if ( val > 0 ) {+		if ( extra !== "border" ) {+			for ( ; i < len; i += 2 ) {+				if ( !extra ) {+					val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;+				}+				if ( extra === "margin" ) {+					val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;+				} else {+					val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;+				}+			}+		}++		return val + "px";+	}++	// Fall back to computed then uncomputed css if necessary+	val = curCSS( elem, name );+	if ( val < 0 || val == null ) {+		val = elem.style[ name ];+	}++	// Computed unit is not pixels. Stop here and return.+	if ( rnumnonpx.test(val) ) {+		return val;+	}++	// Normalize "", auto, and prepare for extra+	val = parseFloat( val ) || 0;++	// Add padding, border, margin+	if ( extra ) {+		for ( ; i < len; i += 2 ) {+			val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;+			if ( extra !== "padding" ) {+				val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;+			}+			if ( extra === "margin" ) {+				val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;+			}+		}+	}++	return val + "px";+}++jQuery.each([ "height", "width" ], function( i, name ) {+	jQuery.cssHooks[ name ] = {+		get: function( elem, computed, extra ) {+			if ( computed ) {+				if ( elem.offsetWidth !== 0 ) {+					return getWidthOrHeight( elem, name, extra );+				} else {+					return jQuery.swap( elem, cssShow, function() {+						return getWidthOrHeight( elem, name, extra );+					});+				}+			}+		},++		set: function( elem, value ) {+			return rnum.test( value ) ?+				value + "px" :+				value;+		}+	};+});++if ( !jQuery.support.opacity ) {+	jQuery.cssHooks.opacity = {+		get: function( elem, computed ) {+			// IE uses filters for opacity+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?+				( parseFloat( RegExp.$1 ) / 100 ) + "" :+				computed ? "1" : "";+		},++		set: function( elem, value ) {+			var style = elem.style,+				currentStyle = elem.currentStyle,+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",+				filter = currentStyle && currentStyle.filter || style.filter || "";++			// IE has trouble with opacity if it does not have layout+			// Force it by setting the zoom level+			style.zoom = 1;++			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652+			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {++				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText+				// if "filter:" is present at all, clearType is disabled, we want to avoid this+				// style.removeAttribute is IE Only, but so apparently is this code path...+				style.removeAttribute( "filter" );++				// if there there is no filter style applied in a css rule, we are done+				if ( currentStyle && !currentStyle.filter ) {+					return;+				}+			}++			// otherwise, set new filter values+			style.filter = ralpha.test( filter ) ?+				filter.replace( ralpha, opacity ) :+				filter + " " + opacity;+		}+	};+}++jQuery(function() {+	// This hook cannot be added until DOM ready because the support test+	// for it is not run until after DOM ready+	if ( !jQuery.support.reliableMarginRight ) {+		jQuery.cssHooks.marginRight = {+			get: function( elem, computed ) {+				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right+				// Work around by temporarily setting element display to inline-block+				return jQuery.swap( elem, { "display": "inline-block" }, function() {+					if ( computed ) {+						return curCSS( elem, "margin-right" );+					} else {+						return elem.style.marginRight;+					}+				});+			}+		};+	}+});++if ( jQuery.expr && jQuery.expr.filters ) {+	jQuery.expr.filters.hidden = function( elem ) {+		var width = elem.offsetWidth,+			height = elem.offsetHeight;++		return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");+	};++	jQuery.expr.filters.visible = function( elem ) {+		return !jQuery.expr.filters.hidden( elem );+	};+}++// These hooks are used by animate to expand properties+jQuery.each({+	margin: "",+	padding: "",+	border: "Width"+}, function( prefix, suffix ) {++	jQuery.cssHooks[ prefix + suffix ] = {+		expand: function( value ) {+			var i,++				// assumes a single number if not a string+				parts = typeof value === "string" ? value.split(" ") : [ value ],+				expanded = {};++			for ( i = 0; i < 4; i++ ) {+				expanded[ prefix + cssExpand[ i ] + suffix ] =+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];+			}++			return expanded;+		}+	};+});+++++var r20 = /%20/g,+	rbracket = /\[\]$/,+	rCRLF = /\r?\n/g,+	rhash = /#.*$/,+	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL+	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,+	// #7653, #8125, #8152: local protocol detection+	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,+	rnoContent = /^(?:GET|HEAD)$/,+	rprotocol = /^\/\//,+	rquery = /\?/,+	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,+	rselectTextarea = /^(?:select|textarea)/i,+	rspacesAjax = /\s+/,+	rts = /([?&])_=[^&]*/,+	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,++	// Keep a copy of the old load method+	_load = jQuery.fn.load,++	/* Prefilters+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)+	 * 2) These are called:+	 *    - BEFORE asking for a transport+	 *    - AFTER param serialization (s.data is a string if s.processData is true)+	 * 3) key is the dataType+	 * 4) the catchall symbol "*" can be used+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed+	 */+	prefilters = {},++	/* Transports bindings+	 * 1) key is the dataType+	 * 2) the catchall symbol "*" can be used+	 * 3) selection will start with transport dataType and THEN go to "*" if needed+	 */+	transports = {},++	// Document location+	ajaxLocation,++	// Document location segments+	ajaxLocParts,++	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression+	allTypes = ["*/"] + ["*"];++// #8138, IE may throw an exception when accessing+// a field from window.location if document.domain has been set+try {+	ajaxLocation = location.href;+} catch( e ) {+	// Use the href attribute of an A element+	// since IE will modify it given document.location+	ajaxLocation = document.createElement( "a" );+	ajaxLocation.href = "";+	ajaxLocation = ajaxLocation.href;+}++// Segment location into parts+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];++// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport+function addToPrefiltersOrTransports( structure ) {++	// dataTypeExpression is optional and defaults to "*"+	return function( dataTypeExpression, func ) {++		if ( typeof dataTypeExpression !== "string" ) {+			func = dataTypeExpression;+			dataTypeExpression = "*";+		}++		if ( jQuery.isFunction( func ) ) {+			var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),+				i = 0,+				length = dataTypes.length,+				dataType,+				list,+				placeBefore;++			// For each dataType in the dataTypeExpression+			for ( ; i < length; i++ ) {+				dataType = dataTypes[ i ];+				// We control if we're asked to add before+				// any existing element+				placeBefore = /^\+/.test( dataType );+				if ( placeBefore ) {+					dataType = dataType.substr( 1 ) || "*";+				}+				list = structure[ dataType ] = structure[ dataType ] || [];+				// then we add to the structure accordingly+				list[ placeBefore ? "unshift" : "push" ]( func );+			}+		}+	};+}++// Base inspection function for prefilters and transports+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,+		dataType /* internal */, inspected /* internal */ ) {++	dataType = dataType || options.dataTypes[ 0 ];+	inspected = inspected || {};++	inspected[ dataType ] = true;++	var list = structure[ dataType ],+		i = 0,+		length = list ? list.length : 0,+		executeOnly = ( structure === prefilters ),+		selection;++	for ( ; i < length && ( executeOnly || !selection ); i++ ) {+		selection = list[ i ]( options, originalOptions, jqXHR );+		// If we got redirected to another dataType+		// we try there if executing only and not done already+		if ( typeof selection === "string" ) {+			if ( !executeOnly || inspected[ selection ] ) {+				selection = undefined;+			} else {+				options.dataTypes.unshift( selection );+				selection = inspectPrefiltersOrTransports(+						structure, options, originalOptions, jqXHR, selection, inspected );+			}+		}+	}+	// If we're only executing or nothing was selected+	// we try the catchall dataType if not done already+	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {+		selection = inspectPrefiltersOrTransports(+				structure, options, originalOptions, jqXHR, "*", inspected );+	}+	// unnecessary when only executing (prefilters)+	// but it'll be ignored by the caller in that case+	return selection;+}++// A special extend for ajax options+// that takes "flat" options (not to be deep extended)+// Fixes #9887+function ajaxExtend( target, src ) {+	var key, deep,+		flatOptions = jQuery.ajaxSettings.flatOptions || {};+	for ( key in src ) {+		if ( src[ key ] !== undefined ) {+			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];+		}+	}+	if ( deep ) {+		jQuery.extend( true, target, deep );+	}+}++jQuery.fn.extend({+	load: function( url, params, callback ) {+		if ( typeof url !== "string" && _load ) {+			return _load.apply( this, arguments );++		// Don't do a request if no elements are being requested+		} else if ( !this.length ) {+			return this;+		}++		var off = url.indexOf( " " );+		if ( off >= 0 ) {+			var selector = url.slice( off, url.length );+			url = url.slice( 0, off );+		}++		// Default to a GET request+		var type = "GET";++		// If the second parameter was provided+		if ( params ) {+			// If it's a function+			if ( jQuery.isFunction( params ) ) {+				// We assume that it's the callback+				callback = params;+				params = undefined;++			// Otherwise, build a param string+			} else if ( typeof params === "object" ) {+				params = jQuery.param( params, jQuery.ajaxSettings.traditional );+				type = "POST";+			}+		}++		var self = this;++		// Request the remote document+		jQuery.ajax({+			url: url,+			type: type,+			dataType: "html",+			data: params,+			// Complete callback (responseText is used internally)+			complete: function( jqXHR, status, responseText ) {+				// Store the response as specified by the jqXHR object+				responseText = jqXHR.responseText;+				// If successful, inject the HTML into all the matched elements+				if ( jqXHR.isResolved() ) {+					// #4825: Get the actual response in case+					// a dataFilter is present in ajaxSettings+					jqXHR.done(function( r ) {+						responseText = r;+					});+					// See if a selector was specified+					self.html( selector ?+						// Create a dummy div to hold the results+						jQuery("<div>")+							// inject the contents of the document in, removing the scripts+							// to avoid any 'Permission Denied' errors in IE+							.append(responseText.replace(rscript, ""))++							// Locate the specified elements+							.find(selector) :++						// If not, just inject the full result+						responseText );+				}++				if ( callback ) {+					self.each( callback, [ responseText, status, jqXHR ] );+				}+			}+		});++		return this;+	},++	serialize: function() {+		return jQuery.param( this.serializeArray() );+	},++	serializeArray: function() {+		return this.map(function(){+			return this.elements ? jQuery.makeArray( this.elements ) : this;+		})+		.filter(function(){+			return this.name && !this.disabled &&+				( this.checked || rselectTextarea.test( this.nodeName ) ||+					rinput.test( this.type ) );+		})+		.map(function( i, elem ){+			var val = jQuery( this ).val();++			return val == null ?+				null :+				jQuery.isArray( val ) ?+					jQuery.map( val, function( val, i ){+						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };+					}) :+					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };+		}).get();+	}+});++// Attach a bunch of functions for handling common AJAX events+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){+	jQuery.fn[ o ] = function( f ){+		return this.on( o, f );+	};+});++jQuery.each( [ "get", "post" ], function( i, method ) {+	jQuery[ method ] = function( url, data, callback, type ) {+		// shift arguments if data argument was omitted+		if ( jQuery.isFunction( data ) ) {+			type = type || callback;+			callback = data;+			data = undefined;+		}++		return jQuery.ajax({+			type: method,+			url: url,+			data: data,+			success: callback,+			dataType: type+		});+	};+});++jQuery.extend({++	getScript: function( url, callback ) {+		return jQuery.get( url, undefined, callback, "script" );+	},++	getJSON: function( url, data, callback ) {+		return jQuery.get( url, data, callback, "json" );+	},++	// Creates a full fledged settings object into target+	// with both ajaxSettings and settings fields.+	// If target is omitted, writes into ajaxSettings.+	ajaxSetup: function( target, settings ) {+		if ( settings ) {+			// Building a settings object+			ajaxExtend( target, jQuery.ajaxSettings );+		} else {+			// Extending ajaxSettings+			settings = target;+			target = jQuery.ajaxSettings;+		}+		ajaxExtend( target, settings );+		return target;+	},++	ajaxSettings: {+		url: ajaxLocation,+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),+		global: true,+		type: "GET",+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",+		processData: true,+		async: true,+		/*+		timeout: 0,+		data: null,+		dataType: null,+		username: null,+		password: null,+		cache: null,+		traditional: false,+		headers: {},+		*/++		accepts: {+			xml: "application/xml, text/xml",+			html: "text/html",+			text: "text/plain",+			json: "application/json, text/javascript",+			"*": allTypes+		},++		contents: {+			xml: /xml/,+			html: /html/,+			json: /json/+		},++		responseFields: {+			xml: "responseXML",+			text: "responseText"+		},++		// List of data converters+		// 1) key format is "source_type destination_type" (a single space in-between)+		// 2) the catchall symbol "*" can be used for source_type+		converters: {++			// Convert anything to text+			"* text": window.String,++			// Text to html (true = no transformation)+			"text html": true,++			// Evaluate text as a json expression+			"text json": jQuery.parseJSON,++			// Parse text as xml+			"text xml": jQuery.parseXML+		},++		// For options that shouldn't be deep extended:+		// you can add your own custom options here if+		// and when you create one that shouldn't be+		// deep extended (see ajaxExtend)+		flatOptions: {+			context: true,+			url: true+		}+	},++	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),+	ajaxTransport: addToPrefiltersOrTransports( transports ),++	// Main method+	ajax: function( url, options ) {++		// If url is an object, simulate pre-1.5 signature+		if ( typeof url === "object" ) {+			options = url;+			url = undefined;+		}++		// Force options to be an object+		options = options || {};++		var // Create the final options object+			s = jQuery.ajaxSetup( {}, options ),+			// Callbacks context+			callbackContext = s.context || s,+			// Context for global events+			// It's the callbackContext if one was provided in the options+			// and if it's a DOM node or a jQuery collection+			globalEventContext = callbackContext !== s &&+				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?+						jQuery( callbackContext ) : jQuery.event,+			// Deferreds+			deferred = jQuery.Deferred(),+			completeDeferred = jQuery.Callbacks( "once memory" ),+			// Status-dependent callbacks+			statusCode = s.statusCode || {},+			// ifModified key+			ifModifiedKey,+			// Headers (they are sent all at once)+			requestHeaders = {},+			requestHeadersNames = {},+			// Response headers+			responseHeadersString,+			responseHeaders,+			// transport+			transport,+			// timeout handle+			timeoutTimer,+			// Cross-domain detection vars+			parts,+			// The jqXHR state+			state = 0,+			// To know if global events are to be dispatched+			fireGlobals,+			// Loop variable+			i,+			// Fake xhr+			jqXHR = {++				readyState: 0,++				// Caches the header+				setRequestHeader: function( name, value ) {+					if ( !state ) {+						var lname = name.toLowerCase();+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;+						requestHeaders[ name ] = value;+					}+					return this;+				},++				// Raw string+				getAllResponseHeaders: function() {+					return state === 2 ? responseHeadersString : null;+				},++				// Builds headers hashtable if needed+				getResponseHeader: function( key ) {+					var match;+					if ( state === 2 ) {+						if ( !responseHeaders ) {+							responseHeaders = {};+							while( ( match = rheaders.exec( responseHeadersString ) ) ) {+								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];+							}+						}+						match = responseHeaders[ key.toLowerCase() ];+					}+					return match === undefined ? null : match;+				},++				// Overrides response content-type header+				overrideMimeType: function( type ) {+					if ( !state ) {+						s.mimeType = type;+					}+					return this;+				},++				// Cancel the request+				abort: function( statusText ) {+					statusText = statusText || "abort";+					if ( transport ) {+						transport.abort( statusText );+					}+					done( 0, statusText );+					return this;+				}+			};++		// Callback for when everything is done+		// It is defined here because jslint complains if it is declared+		// at the end of the function (which would be more logical and readable)+		function done( status, nativeStatusText, responses, headers ) {++			// Called once+			if ( state === 2 ) {+				return;+			}++			// State is "done" now+			state = 2;++			// Clear timeout if it exists+			if ( timeoutTimer ) {+				clearTimeout( timeoutTimer );+			}++			// Dereference transport for early garbage collection+			// (no matter how long the jqXHR object will be used)+			transport = undefined;++			// Cache response headers+			responseHeadersString = headers || "";++			// Set readyState+			jqXHR.readyState = status > 0 ? 4 : 0;++			var isSuccess,+				success,+				error,+				statusText = nativeStatusText,+				response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,+				lastModified,+				etag;++			// If successful, handle type chaining+			if ( status >= 200 && status < 300 || status === 304 ) {++				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.+				if ( s.ifModified ) {++					if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {+						jQuery.lastModified[ ifModifiedKey ] = lastModified;+					}+					if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {+						jQuery.etag[ ifModifiedKey ] = etag;+					}+				}++				// If not modified+				if ( status === 304 ) {++					statusText = "notmodified";+					isSuccess = true;++				// If we have data+				} else {++					try {+						success = ajaxConvert( s, response );+						statusText = "success";+						isSuccess = true;+					} catch(e) {+						// We have a parsererror+						statusText = "parsererror";+						error = e;+					}+				}+			} else {+				// We extract error from statusText+				// then normalize statusText and status for non-aborts+				error = statusText;+				if ( !statusText || status ) {+					statusText = "error";+					if ( status < 0 ) {+						status = 0;+					}+				}+			}++			// Set data for the fake xhr object+			jqXHR.status = status;+			jqXHR.statusText = "" + ( nativeStatusText || statusText );++			// Success/Error+			if ( isSuccess ) {+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );+			} else {+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );+			}++			// Status-dependent callbacks+			jqXHR.statusCode( statusCode );+			statusCode = undefined;++			if ( fireGlobals ) {+				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),+						[ jqXHR, s, isSuccess ? success : error ] );+			}++			// Complete+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );++			if ( fireGlobals ) {+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );+				// Handle the global AJAX counter+				if ( !( --jQuery.active ) ) {+					jQuery.event.trigger( "ajaxStop" );+				}+			}+		}++		// Attach deferreds+		deferred.promise( jqXHR );+		jqXHR.success = jqXHR.done;+		jqXHR.error = jqXHR.fail;+		jqXHR.complete = completeDeferred.add;++		// Status-dependent callbacks+		jqXHR.statusCode = function( map ) {+			if ( map ) {+				var tmp;+				if ( state < 2 ) {+					for ( tmp in map ) {+						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];+					}+				} else {+					tmp = map[ jqXHR.status ];+					jqXHR.then( tmp, tmp );+				}+			}+			return this;+		};++		// Remove hash character (#7531: and string promotion)+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)+		// We also use the url parameter if available+		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );++		// Extract dataTypes list+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );++		// Determine if a cross-domain request is in order+		if ( s.crossDomain == null ) {+			parts = rurl.exec( s.url.toLowerCase() );+			s.crossDomain = !!( parts &&+				( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||+					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=+						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )+			);+		}++		// Convert data if not already a string+		if ( s.data && s.processData && typeof s.data !== "string" ) {+			s.data = jQuery.param( s.data, s.traditional );+		}++		// Apply prefilters+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );++		// If request was aborted inside a prefilter, stop there+		if ( state === 2 ) {+			return false;+		}++		// We can fire global events as of now if asked to+		fireGlobals = s.global;++		// Uppercase the type+		s.type = s.type.toUpperCase();++		// Determine if request has content+		s.hasContent = !rnoContent.test( s.type );++		// Watch for a new set of requests+		if ( fireGlobals && jQuery.active++ === 0 ) {+			jQuery.event.trigger( "ajaxStart" );+		}++		// More options handling for requests with no content+		if ( !s.hasContent ) {++			// If data is available, append data to url+			if ( s.data ) {+				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;+				// #9682: remove data so that it's not used in an eventual retry+				delete s.data;+			}++			// Get ifModifiedKey before adding the anti-cache parameter+			ifModifiedKey = s.url;++			// Add anti-cache in url if needed+			if ( s.cache === false ) {++				var ts = jQuery.now(),+					// try replacing _= if it is there+					ret = s.url.replace( rts, "$1_=" + ts );++				// if nothing was replaced, add timestamp to the end+				s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );+			}+		}++		// Set the correct header, if data is being sent+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {+			jqXHR.setRequestHeader( "Content-Type", s.contentType );+		}++		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.+		if ( s.ifModified ) {+			ifModifiedKey = ifModifiedKey || s.url;+			if ( jQuery.lastModified[ ifModifiedKey ] ) {+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );+			}+			if ( jQuery.etag[ ifModifiedKey ] ) {+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );+			}+		}++		// Set the Accepts header for the server, depending on the dataType+		jqXHR.setRequestHeader(+			"Accept",+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?+				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :+				s.accepts[ "*" ]+		);++		// Check for headers option+		for ( i in s.headers ) {+			jqXHR.setRequestHeader( i, s.headers[ i ] );+		}++		// Allow custom headers/mimetypes and early abort+		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {+				// Abort if not done already+				jqXHR.abort();+				return false;++		}++		// Install callbacks on deferreds+		for ( i in { success: 1, error: 1, complete: 1 } ) {+			jqXHR[ i ]( s[ i ] );+		}++		// Get transport+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );++		// If no transport, we auto-abort+		if ( !transport ) {+			done( -1, "No Transport" );+		} else {+			jqXHR.readyState = 1;+			// Send global event+			if ( fireGlobals ) {+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );+			}+			// Timeout+			if ( s.async && s.timeout > 0 ) {+				timeoutTimer = setTimeout( function(){+					jqXHR.abort( "timeout" );+				}, s.timeout );+			}++			try {+				state = 1;+				transport.send( requestHeaders, done );+			} catch (e) {+				// Propagate exception as error if not done+				if ( state < 2 ) {+					done( -1, e );+				// Simply rethrow otherwise+				} else {+					throw e;+				}+			}+		}++		return jqXHR;+	},++	// Serialize an array of form elements or a set of+	// key/values into a query string+	param: function( a, traditional ) {+		var s = [],+			add = function( key, value ) {+				// If value is a function, invoke it and return its value+				value = jQuery.isFunction( value ) ? value() : value;+				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );+			};++		// Set traditional to true for jQuery <= 1.3.2 behavior.+		if ( traditional === undefined ) {+			traditional = jQuery.ajaxSettings.traditional;+		}++		// If an array was passed in, assume that it is an array of form elements.+		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {+			// Serialize the form elements+			jQuery.each( a, function() {+				add( this.name, this.value );+			});++		} else {+			// If traditional, encode the "old" way (the way 1.3.2 or older+			// did it), otherwise encode params recursively.+			for ( var prefix in a ) {+				buildParams( prefix, a[ prefix ], traditional, add );+			}+		}++		// Return the resulting serialization+		return s.join( "&" ).replace( r20, "+" );+	}+});++function buildParams( prefix, obj, traditional, add ) {+	if ( jQuery.isArray( obj ) ) {+		// Serialize array item.+		jQuery.each( obj, function( i, v ) {+			if ( traditional || rbracket.test( prefix ) ) {+				// Treat each array item as a scalar.+				add( prefix, v );++			} else {+				// If array item is non-scalar (array or object), encode its+				// numeric index to resolve deserialization ambiguity issues.+				// Note that rack (as of 1.0.0) can't currently deserialize+				// nested arrays properly, and attempting to do so may cause+				// a server error. Possible fixes are to modify rack's+				// deserialization algorithm or to provide an option or flag+				// to force array serialization to be shallow.+				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );+			}+		});++	} else if ( !traditional && jQuery.type( obj ) === "object" ) {+		// Serialize object item.+		for ( var name in obj ) {+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );+		}++	} else {+		// Serialize scalar item.+		add( prefix, obj );+	}+}++// This is still on the jQuery object... for now+// Want to move this to jQuery.ajax some day+jQuery.extend({++	// Counter for holding the number of active queries+	active: 0,++	// Last-Modified header cache for next request+	lastModified: {},+	etag: {}++});++/* Handles responses to an ajax request:+ * - sets all responseXXX fields accordingly+ * - finds the right dataType (mediates between content-type and expected dataType)+ * - returns the corresponding response+ */+function ajaxHandleResponses( s, jqXHR, responses ) {++	var contents = s.contents,+		dataTypes = s.dataTypes,+		responseFields = s.responseFields,+		ct,+		type,+		finalDataType,+		firstDataType;++	// Fill responseXXX fields+	for ( type in responseFields ) {+		if ( type in responses ) {+			jqXHR[ responseFields[type] ] = responses[ type ];+		}+	}++	// Remove auto dataType and get content-type in the process+	while( dataTypes[ 0 ] === "*" ) {+		dataTypes.shift();+		if ( ct === undefined ) {+			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );+		}+	}++	// Check if we're dealing with a known content-type+	if ( ct ) {+		for ( type in contents ) {+			if ( contents[ type ] && contents[ type ].test( ct ) ) {+				dataTypes.unshift( type );+				break;+			}+		}+	}++	// Check to see if we have a response for the expected dataType+	if ( dataTypes[ 0 ] in responses ) {+		finalDataType = dataTypes[ 0 ];+	} else {+		// Try convertible dataTypes+		for ( type in responses ) {+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {+				finalDataType = type;+				break;+			}+			if ( !firstDataType ) {+				firstDataType = type;+			}+		}+		// Or just use first one+		finalDataType = finalDataType || firstDataType;+	}++	// If we found a dataType+	// We add the dataType to the list if needed+	// and return the corresponding response+	if ( finalDataType ) {+		if ( finalDataType !== dataTypes[ 0 ] ) {+			dataTypes.unshift( finalDataType );+		}+		return responses[ finalDataType ];+	}+}++// Chain conversions given the request and the original response+function ajaxConvert( s, response ) {++	// Apply the dataFilter if provided+	if ( s.dataFilter ) {+		response = s.dataFilter( response, s.dataType );+	}++	var dataTypes = s.dataTypes,+		converters = {},+		i,+		key,+		length = dataTypes.length,+		tmp,+		// Current and previous dataTypes+		current = dataTypes[ 0 ],+		prev,+		// Conversion expression+		conversion,+		// Conversion function+		conv,+		// Conversion functions (transitive conversion)+		conv1,+		conv2;++	// For each dataType in the chain+	for ( i = 1; i < length; i++ ) {++		// Create converters map+		// with lowercased keys+		if ( i === 1 ) {+			for ( key in s.converters ) {+				if ( typeof key === "string" ) {+					converters[ key.toLowerCase() ] = s.converters[ key ];+				}+			}+		}++		// Get the dataTypes+		prev = current;+		current = dataTypes[ i ];++		// If current is auto dataType, update it to prev+		if ( current === "*" ) {+			current = prev;+		// If no auto and dataTypes are actually different+		} else if ( prev !== "*" && prev !== current ) {++			// Get the converter+			conversion = prev + " " + current;+			conv = converters[ conversion ] || converters[ "* " + current ];++			// If there is no direct converter, search transitively+			if ( !conv ) {+				conv2 = undefined;+				for ( conv1 in converters ) {+					tmp = conv1.split( " " );+					if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {+						conv2 = converters[ tmp[1] + " " + current ];+						if ( conv2 ) {+							conv1 = converters[ conv1 ];+							if ( conv1 === true ) {+								conv = conv2;+							} else if ( conv2 === true ) {+								conv = conv1;+							}+							break;+						}+					}+				}+			}+			// If we found no converter, dispatch an error+			if ( !( conv || conv2 ) ) {+				jQuery.error( "No conversion from " + conversion.replace(" "," to ") );+			}+			// If found converter is not an equivalence+			if ( conv !== true ) {+				// Convert with 1 or 2 converters accordingly+				response = conv ? conv( response ) : conv2( conv1(response) );+			}+		}+	}+	return response;+}+++++var jsc = jQuery.now(),+	jsre = /(\=)\?(&|$)|\?\?/i;++// Default jsonp settings+jQuery.ajaxSetup({+	jsonp: "callback",+	jsonpCallback: function() {+		return jQuery.expando + "_" + ( jsc++ );+	}+});++// Detect, normalize options and install callbacks for jsonp requests+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {++	var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );++	if ( s.dataTypes[ 0 ] === "jsonp" ||+		s.jsonp !== false && ( jsre.test( s.url ) ||+				inspectData && jsre.test( s.data ) ) ) {++		var responseContainer,+			jsonpCallback = s.jsonpCallback =+				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,+			previous = window[ jsonpCallback ],+			url = s.url,+			data = s.data,+			replace = "$1" + jsonpCallback + "$2";++		if ( s.jsonp !== false ) {+			url = url.replace( jsre, replace );+			if ( s.url === url ) {+				if ( inspectData ) {+					data = data.replace( jsre, replace );+				}+				if ( s.data === data ) {+					// Add callback manually+					url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;+				}+			}+		}++		s.url = url;+		s.data = data;++		// Install callback+		window[ jsonpCallback ] = function( response ) {+			responseContainer = [ response ];+		};++		// Clean-up function+		jqXHR.always(function() {+			// Set callback back to previous value+			window[ jsonpCallback ] = previous;+			// Call if it was a function and we have a response+			if ( responseContainer && jQuery.isFunction( previous ) ) {+				window[ jsonpCallback ]( responseContainer[ 0 ] );+			}+		});++		// Use data converter to retrieve json after script execution+		s.converters["script json"] = function() {+			if ( !responseContainer ) {+				jQuery.error( jsonpCallback + " was not called" );+			}+			return responseContainer[ 0 ];+		};++		// force json dataType+		s.dataTypes[ 0 ] = "json";++		// Delegate to script+		return "script";+	}+});+++++// Install script dataType+jQuery.ajaxSetup({+	accepts: {+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"+	},+	contents: {+		script: /javascript|ecmascript/+	},+	converters: {+		"text script": function( text ) {+			jQuery.globalEval( text );+			return text;+		}+	}+});++// Handle cache's special case and global+jQuery.ajaxPrefilter( "script", function( s ) {+	if ( s.cache === undefined ) {+		s.cache = false;+	}+	if ( s.crossDomain ) {+		s.type = "GET";+		s.global = false;+	}+});++// Bind script tag hack transport+jQuery.ajaxTransport( "script", function(s) {++	// This transport only deals with cross domain requests+	if ( s.crossDomain ) {++		var script,+			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;++		return {++			send: function( _, callback ) {++				script = document.createElement( "script" );++				script.async = "async";++				if ( s.scriptCharset ) {+					script.charset = s.scriptCharset;+				}++				script.src = s.url;++				// Attach handlers for all browsers+				script.onload = script.onreadystatechange = function( _, isAbort ) {++					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {++						// Handle memory leak in IE+						script.onload = script.onreadystatechange = null;++						// Remove the script+						if ( head && script.parentNode ) {+							head.removeChild( script );+						}++						// Dereference the script+						script = undefined;++						// Callback if not abort+						if ( !isAbort ) {+							callback( 200, "success" );+						}+					}+				};+				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.+				// This arises when a base node is used (#2709 and #4378).+				head.insertBefore( script, head.firstChild );+			},++			abort: function() {+				if ( script ) {+					script.onload( 0, 1 );+				}+			}+		};+	}+});+++++var // #5280: Internet Explorer will keep connections alive if we don't abort on unload+	xhrOnUnloadAbort = window.ActiveXObject ? function() {+		// Abort all pending requests+		for ( var key in xhrCallbacks ) {+			xhrCallbacks[ key ]( 0, 1 );+		}+	} : false,+	xhrId = 0,+	xhrCallbacks;++// Functions to create xhrs+function createStandardXHR() {+	try {+		return new window.XMLHttpRequest();+	} catch( e ) {}+}++function createActiveXHR() {+	try {+		return new window.ActiveXObject( "Microsoft.XMLHTTP" );+	} catch( e ) {}+}++// Create the request object+// (This is still attached to ajaxSettings for backward compatibility)+jQuery.ajaxSettings.xhr = window.ActiveXObject ?+	/* Microsoft failed to properly+	 * implement the XMLHttpRequest in IE7 (can't request local files),+	 * so we use the ActiveXObject when it is available+	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so+	 * we need a fallback.+	 */+	function() {+		return !this.isLocal && createStandardXHR() || createActiveXHR();+	} :+	// For all other browsers, use the standard XMLHttpRequest object+	createStandardXHR;++// Determine support properties+(function( xhr ) {+	jQuery.extend( jQuery.support, {+		ajax: !!xhr,+		cors: !!xhr && ( "withCredentials" in xhr )+	});+})( jQuery.ajaxSettings.xhr() );++// Create transport if the browser can provide an xhr+if ( jQuery.support.ajax ) {++	jQuery.ajaxTransport(function( s ) {+		// Cross domain only allowed if supported through XMLHttpRequest+		if ( !s.crossDomain || jQuery.support.cors ) {++			var callback;++			return {+				send: function( headers, complete ) {++					// Get a new xhr+					var xhr = s.xhr(),+						handle,+						i;++					// Open the socket+					// Passing null username, generates a login popup on Opera (#2865)+					if ( s.username ) {+						xhr.open( s.type, s.url, s.async, s.username, s.password );+					} else {+						xhr.open( s.type, s.url, s.async );+					}++					// Apply custom fields if provided+					if ( s.xhrFields ) {+						for ( i in s.xhrFields ) {+							xhr[ i ] = s.xhrFields[ i ];+						}+					}++					// Override mime type if needed+					if ( s.mimeType && xhr.overrideMimeType ) {+						xhr.overrideMimeType( s.mimeType );+					}++					// X-Requested-With header+					// For cross-domain requests, seeing as conditions for a preflight are+					// akin to a jigsaw puzzle, we simply never set it to be sure.+					// (it can always be set on a per-request basis or even using ajaxSetup)+					// For same-domain requests, won't change header if already provided.+					if ( !s.crossDomain && !headers["X-Requested-With"] ) {+						headers[ "X-Requested-With" ] = "XMLHttpRequest";+					}++					// Need an extra try/catch for cross domain requests in Firefox 3+					try {+						for ( i in headers ) {+							xhr.setRequestHeader( i, headers[ i ] );+						}+					} catch( _ ) {}++					// Do send the request+					// This may raise an exception which is actually+					// handled in jQuery.ajax (so no try/catch here)+					xhr.send( ( s.hasContent && s.data ) || null );++					// Listener+					callback = function( _, isAbort ) {++						var status,+							statusText,+							responseHeaders,+							responses,+							xml;++						// Firefox throws exceptions when accessing properties+						// of an xhr when a network error occured+						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)+						try {++							// Was never called and is aborted or complete+							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {++								// Only called once+								callback = undefined;++								// Do not keep as active anymore+								if ( handle ) {+									xhr.onreadystatechange = jQuery.noop;+									if ( xhrOnUnloadAbort ) {+										delete xhrCallbacks[ handle ];+									}+								}++								// If it's an abort+								if ( isAbort ) {+									// Abort it manually if needed+									if ( xhr.readyState !== 4 ) {+										xhr.abort();+									}+								} else {+									status = xhr.status;+									responseHeaders = xhr.getAllResponseHeaders();+									responses = {};+									xml = xhr.responseXML;++									// Construct response list+									if ( xml && xml.documentElement /* #4958 */ ) {+										responses.xml = xml;+									}++									// When requesting binary data, IE6-9 will throw an exception+									// on any attempt to access responseText (#11426)+									try {+										responses.text = xhr.responseText;+									} catch( _ ) {+									}++									// Firefox throws an exception when accessing+									// statusText for faulty cross-domain requests+									try {+										statusText = xhr.statusText;+									} catch( e ) {+										// We normalize with Webkit giving an empty statusText+										statusText = "";+									}++									// Filter status for non standard behaviors++									// If the request is local and we have data: assume a success+									// (success with no data won't get notified, that's the best we+									// can do given current implementations)+									if ( !status && s.isLocal && !s.crossDomain ) {+										status = responses.text ? 200 : 404;+									// IE - #1450: sometimes returns 1223 when it should be 204+									} else if ( status === 1223 ) {+										status = 204;+									}+								}+							}+						} catch( firefoxAccessException ) {+							if ( !isAbort ) {+								complete( -1, firefoxAccessException );+							}+						}++						// Call complete if needed+						if ( responses ) {+							complete( status, statusText, responses, responseHeaders );+						}+					};++					// if we're in sync mode or it's in cache+					// and has been retrieved directly (IE6 & IE7)+					// we need to manually fire the callback+					if ( !s.async || xhr.readyState === 4 ) {+						callback();+					} else {+						handle = ++xhrId;+						if ( xhrOnUnloadAbort ) {+							// Create the active xhrs callbacks list if needed+							// and attach the unload handler+							if ( !xhrCallbacks ) {+								xhrCallbacks = {};+								jQuery( window ).unload( xhrOnUnloadAbort );+							}+							// Add to list of active xhrs callbacks+							xhrCallbacks[ handle ] = callback;+						}+						xhr.onreadystatechange = callback;+					}+				},++				abort: function() {+					if ( callback ) {+						callback(0,1);+					}+				}+			};+		}+	});+}+++++var elemdisplay = {},+	iframe, iframeDoc,+	rfxtypes = /^(?:toggle|show|hide)$/,+	rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,+	timerId,+	fxAttrs = [+		// height animations+		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],+		// width animations+		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],+		// opacity animations+		[ "opacity" ]+	],+	fxNow;++jQuery.fn.extend({+	show: function( speed, easing, callback ) {+		var elem, display;++		if ( speed || speed === 0 ) {+			return this.animate( genFx("show", 3), speed, easing, callback );++		} else {+			for ( var i = 0, j = this.length; i < j; i++ ) {+				elem = this[ i ];++				if ( elem.style ) {+					display = elem.style.display;++					// Reset the inline display of this element to learn if it is+					// being hidden by cascaded rules or not+					if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {+						display = elem.style.display = "";+					}++					// Set elements which have been overridden with display: none+					// in a stylesheet to whatever the default browser style is+					// for such an element+					if ( (display === "" && jQuery.css(elem, "display") === "none") ||+						!jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {+						jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );+					}+				}+			}++			// Set the display of most of the elements in a second loop+			// to avoid the constant reflow+			for ( i = 0; i < j; i++ ) {+				elem = this[ i ];++				if ( elem.style ) {+					display = elem.style.display;++					if ( display === "" || display === "none" ) {+						elem.style.display = jQuery._data( elem, "olddisplay" ) || "";+					}+				}+			}++			return this;+		}+	},++	hide: function( speed, easing, callback ) {+		if ( speed || speed === 0 ) {+			return this.animate( genFx("hide", 3), speed, easing, callback);++		} else {+			var elem, display,+				i = 0,+				j = this.length;++			for ( ; i < j; i++ ) {+				elem = this[i];+				if ( elem.style ) {+					display = jQuery.css( elem, "display" );++					if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {+						jQuery._data( elem, "olddisplay", display );+					}+				}+			}++			// Set the display of the elements in a second loop+			// to avoid the constant reflow+			for ( i = 0; i < j; i++ ) {+				if ( this[i].style ) {+					this[i].style.display = "none";+				}+			}++			return this;+		}+	},++	// Save the old toggle function+	_toggle: jQuery.fn.toggle,++	toggle: function( fn, fn2, callback ) {+		var bool = typeof fn === "boolean";++		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {+			this._toggle.apply( this, arguments );++		} else if ( fn == null || bool ) {+			this.each(function() {+				var state = bool ? fn : jQuery(this).is(":hidden");+				jQuery(this)[ state ? "show" : "hide" ]();+			});++		} else {+			this.animate(genFx("toggle", 3), fn, fn2, callback);+		}++		return this;+	},++	fadeTo: function( speed, to, easing, callback ) {+		return this.filter(":hidden").css("opacity", 0).show().end()+					.animate({opacity: to}, speed, easing, callback);+	},++	animate: function( prop, speed, easing, callback ) {+		var optall = jQuery.speed( speed, easing, callback );++		if ( jQuery.isEmptyObject( prop ) ) {+			return this.each( optall.complete, [ false ] );+		}++		// Do not change referenced properties as per-property easing will be lost+		prop = jQuery.extend( {}, prop );++		function doAnimation() {+			// XXX 'this' does not always have a nodeName when running the+			// test suite++			if ( optall.queue === false ) {+				jQuery._mark( this );+			}++			var opt = jQuery.extend( {}, optall ),+				isElement = this.nodeType === 1,+				hidden = isElement && jQuery(this).is(":hidden"),+				name, val, p, e, hooks, replace,+				parts, start, end, unit,+				method;++			// will store per property easing and be used to determine when an animation is complete+			opt.animatedProperties = {};++			// first pass over propertys to expand / normalize+			for ( p in prop ) {+				name = jQuery.camelCase( p );+				if ( p !== name ) {+					prop[ name ] = prop[ p ];+					delete prop[ p ];+				}++				if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) {+					replace = hooks.expand( prop[ name ] );+					delete prop[ name ];++					// not quite $.extend, this wont overwrite keys already present.+					// also - reusing 'p' from above because we have the correct "name"+					for ( p in replace ) {+						if ( ! ( p in prop ) ) {+							prop[ p ] = replace[ p ];+						}+					}+				}+			}++			for ( name in prop ) {+				val = prop[ name ];+				// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)+				if ( jQuery.isArray( val ) ) {+					opt.animatedProperties[ name ] = val[ 1 ];+					val = prop[ name ] = val[ 0 ];+				} else {+					opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';+				}++				if ( val === "hide" && hidden || val === "show" && !hidden ) {+					return opt.complete.call( this );+				}++				if ( isElement && ( name === "height" || name === "width" ) ) {+					// Make sure that nothing sneaks out+					// Record all 3 overflow attributes because IE does not+					// change the overflow attribute when overflowX and+					// overflowY are set to the same value+					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];++					// Set display property to inline-block for height/width+					// animations on inline elements that are having width/height animated+					if ( jQuery.css( this, "display" ) === "inline" &&+							jQuery.css( this, "float" ) === "none" ) {++						// inline-level elements accept inline-block;+						// block-level elements need to be inline with layout+						if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {+							this.style.display = "inline-block";++						} else {+							this.style.zoom = 1;+						}+					}+				}+			}++			if ( opt.overflow != null ) {+				this.style.overflow = "hidden";+			}++			for ( p in prop ) {+				e = new jQuery.fx( this, opt, p );+				val = prop[ p ];++				if ( rfxtypes.test( val ) ) {++					// Tracks whether to show or hide based on private+					// data attached to the element+					method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );+					if ( method ) {+						jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );+						e[ method ]();+					} else {+						e[ val ]();+					}++				} else {+					parts = rfxnum.exec( val );+					start = e.cur();++					if ( parts ) {+						end = parseFloat( parts[2] );+						unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );++						// We need to compute starting value+						if ( unit !== "px" ) {+							jQuery.style( this, p, (end || 1) + unit);+							start = ( (end || 1) / e.cur() ) * start;+							jQuery.style( this, p, start + unit);+						}++						// If a +=/-= token was provided, we're doing a relative animation+						if ( parts[1] ) {+							end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;+						}++						e.custom( start, end, unit );++					} else {+						e.custom( start, val, "" );+					}+				}+			}++			// For JS strict compliance+			return true;+		}++		return optall.queue === false ?+			this.each( doAnimation ) :+			this.queue( optall.queue, doAnimation );+	},++	stop: function( type, clearQueue, gotoEnd ) {+		if ( typeof type !== "string" ) {+			gotoEnd = clearQueue;+			clearQueue = type;+			type = undefined;+		}+		if ( clearQueue && type !== false ) {+			this.queue( type || "fx", [] );+		}++		return this.each(function() {+			var index,+				hadTimers = false,+				timers = jQuery.timers,+				data = jQuery._data( this );++			// clear marker counters if we know they won't be+			if ( !gotoEnd ) {+				jQuery._unmark( true, this );+			}++			function stopQueue( elem, data, index ) {+				var hooks = data[ index ];+				jQuery.removeData( elem, index, true );+				hooks.stop( gotoEnd );+			}++			if ( type == null ) {+				for ( index in data ) {+					if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {+						stopQueue( this, data, index );+					}+				}+			} else if ( data[ index = type + ".run" ] && data[ index ].stop ){+				stopQueue( this, data, index );+			}++			for ( index = timers.length; index--; ) {+				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {+					if ( gotoEnd ) {++						// force the next step to be the last+						timers[ index ]( true );+					} else {+						timers[ index ].saveState();+					}+					hadTimers = true;+					timers.splice( index, 1 );+				}+			}++			// start the next in the queue if the last step wasn't forced+			// timers currently will call their complete callbacks, which will dequeue+			// but only if they were gotoEnd+			if ( !( gotoEnd && hadTimers ) ) {+				jQuery.dequeue( this, type );+			}+		});+	}++});++// Animations created synchronously will run synchronously+function createFxNow() {+	setTimeout( clearFxNow, 0 );+	return ( fxNow = jQuery.now() );+}++function clearFxNow() {+	fxNow = undefined;+}++// Generate parameters to create a standard animation+function genFx( type, num ) {+	var obj = {};++	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {+		obj[ this ] = type;+	});++	return obj;+}++// Generate shortcuts for custom animations+jQuery.each({+	slideDown: genFx( "show", 1 ),+	slideUp: genFx( "hide", 1 ),+	slideToggle: genFx( "toggle", 1 ),+	fadeIn: { opacity: "show" },+	fadeOut: { opacity: "hide" },+	fadeToggle: { opacity: "toggle" }+}, function( name, props ) {+	jQuery.fn[ name ] = function( speed, easing, callback ) {+		return this.animate( props, speed, easing, callback );+	};+});++jQuery.extend({+	speed: function( speed, easing, fn ) {+		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {+			complete: fn || !fn && easing ||+				jQuery.isFunction( speed ) && speed,+			duration: speed,+			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing+		};++		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :+			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;++		// normalize opt.queue - true/undefined/null -> "fx"+		if ( opt.queue == null || opt.queue === true ) {+			opt.queue = "fx";+		}++		// Queueing+		opt.old = opt.complete;++		opt.complete = function( noUnmark ) {+			if ( jQuery.isFunction( opt.old ) ) {+				opt.old.call( this );+			}++			if ( opt.queue ) {+				jQuery.dequeue( this, opt.queue );+			} else if ( noUnmark !== false ) {+				jQuery._unmark( this );+			}+		};++		return opt;+	},++	easing: {+		linear: function( p ) {+			return p;+		},+		swing: function( p ) {+			return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;+		}+	},++	timers: [],++	fx: function( elem, options, prop ) {+		this.options = options;+		this.elem = elem;+		this.prop = prop;++		options.orig = options.orig || {};+	}++});++jQuery.fx.prototype = {+	// Simple function for setting a style value+	update: function() {+		if ( this.options.step ) {+			this.options.step.call( this.elem, this.now, this );+		}++		( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );+	},++	// Get the current size+	cur: function() {+		if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {+			return this.elem[ this.prop ];+		}++		var parsed,+			r = jQuery.css( this.elem, this.prop );+		// Empty strings, null, undefined and "auto" are converted to 0,+		// complex values such as "rotate(1rad)" are returned as is,+		// simple values such as "10px" are parsed to Float.+		return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;+	},++	// Start an animation from one number to another+	custom: function( from, to, unit ) {+		var self = this,+			fx = jQuery.fx;++		this.startTime = fxNow || createFxNow();+		this.end = to;+		this.now = this.start = from;+		this.pos = this.state = 0;+		this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );++		function t( gotoEnd ) {+			return self.step( gotoEnd );+		}++		t.queue = this.options.queue;+		t.elem = this.elem;+		t.saveState = function() {+			if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {+				if ( self.options.hide ) {+					jQuery._data( self.elem, "fxshow" + self.prop, self.start );+				} else if ( self.options.show ) {+					jQuery._data( self.elem, "fxshow" + self.prop, self.end );+				}+			}+		};++		if ( t() && jQuery.timers.push(t) && !timerId ) {+			timerId = setInterval( fx.tick, fx.interval );+		}+	},++	// Simple 'show' function+	show: function() {+		var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );++		// Remember where we started, so that we can go back to it later+		this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );+		this.options.show = true;++		// Begin the animation+		// Make sure that we start at a small width/height to avoid any flash of content+		if ( dataShow !== undefined ) {+			// This show is picking up where a previous hide or show left off+			this.custom( this.cur(), dataShow );+		} else {+			this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );+		}++		// Start by showing the element+		jQuery( this.elem ).show();+	},++	// Simple 'hide' function+	hide: function() {+		// Remember where we started, so that we can go back to it later+		this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );+		this.options.hide = true;++		// Begin the animation+		this.custom( this.cur(), 0 );+	},++	// Each step of an animation+	step: function( gotoEnd ) {+		var p, n, complete,+			t = fxNow || createFxNow(),+			done = true,+			elem = this.elem,+			options = this.options;++		if ( gotoEnd || t >= options.duration + this.startTime ) {+			this.now = this.end;+			this.pos = this.state = 1;+			this.update();++			options.animatedProperties[ this.prop ] = true;++			for ( p in options.animatedProperties ) {+				if ( options.animatedProperties[ p ] !== true ) {+					done = false;+				}+			}++			if ( done ) {+				// Reset the overflow+				if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {++					jQuery.each( [ "", "X", "Y" ], function( index, value ) {+						elem.style[ "overflow" + value ] = options.overflow[ index ];+					});+				}++				// Hide the element if the "hide" operation was done+				if ( options.hide ) {+					jQuery( elem ).hide();+				}++				// Reset the properties, if the item has been hidden or shown+				if ( options.hide || options.show ) {+					for ( p in options.animatedProperties ) {+						jQuery.style( elem, p, options.orig[ p ] );+						jQuery.removeData( elem, "fxshow" + p, true );+						// Toggle data is no longer needed+						jQuery.removeData( elem, "toggle" + p, true );+					}+				}++				// Execute the complete function+				// in the event that the complete function throws an exception+				// we must ensure it won't be called twice. #5684++				complete = options.complete;+				if ( complete ) {++					options.complete = false;+					complete.call( elem );+				}+			}++			return false;++		} else {+			// classical easing cannot be used with an Infinity duration+			if ( options.duration == Infinity ) {+				this.now = t;+			} else {+				n = t - this.startTime;+				this.state = n / options.duration;++				// Perform the easing function, defaults to swing+				this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );+				this.now = this.start + ( (this.end - this.start) * this.pos );+			}+			// Perform the next step of the animation+			this.update();+		}++		return true;+	}+};++jQuery.extend( jQuery.fx, {+	tick: function() {+		var timer,+			timers = jQuery.timers,+			i = 0;++		for ( ; i < timers.length; i++ ) {+			timer = timers[ i ];+			// Checks the timer has not already been removed+			if ( !timer() && timers[ i ] === timer ) {+				timers.splice( i--, 1 );+			}+		}++		if ( !timers.length ) {+			jQuery.fx.stop();+		}+	},++	interval: 13,++	stop: function() {+		clearInterval( timerId );+		timerId = null;+	},++	speeds: {+		slow: 600,+		fast: 200,+		// Default speed+		_default: 400+	},++	step: {+		opacity: function( fx ) {+			jQuery.style( fx.elem, "opacity", fx.now );+		},++		_default: function( fx ) {+			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {+				fx.elem.style[ fx.prop ] = fx.now + fx.unit;+			} else {+				fx.elem[ fx.prop ] = fx.now;+			}+		}+	}+});++// Ensure props that can't be negative don't go there on undershoot easing+jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) {+	// exclude marginTop, marginLeft, marginBottom and marginRight from this list+	if ( prop.indexOf( "margin" ) ) {+		jQuery.fx.step[ prop ] = function( fx ) {+			jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );+		};+	}+});++if ( jQuery.expr && jQuery.expr.filters ) {+	jQuery.expr.filters.animated = function( elem ) {+		return jQuery.grep(jQuery.timers, function( fn ) {+			return elem === fn.elem;+		}).length;+	};+}++// Try to restore the default display value of an element+function defaultDisplay( nodeName ) {++	if ( !elemdisplay[ nodeName ] ) {++		var body = document.body,+			elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),+			display = elem.css( "display" );+		elem.remove();++		// If the simple way fails,+		// get element's real default display by attaching it to a temp iframe+		if ( display === "none" || display === "" ) {+			// No iframe to use yet, so create it+			if ( !iframe ) {+				iframe = document.createElement( "iframe" );+				iframe.frameBorder = iframe.width = iframe.height = 0;+			}++			body.appendChild( iframe );++			// Create a cacheable copy of the iframe document on first call.+			// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML+			// document to it; WebKit & Firefox won't allow reusing the iframe document.+			if ( !iframeDoc || !iframe.createElement ) {+				iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;+				iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );+				iframeDoc.close();+			}++			elem = iframeDoc.createElement( nodeName );++			iframeDoc.body.appendChild( elem );++			display = jQuery.css( elem, "display" );+			body.removeChild( iframe );+		}++		// Store the correct default display+		elemdisplay[ nodeName ] = display;+	}++	return elemdisplay[ nodeName ];+}+++++var getOffset,+	rtable = /^t(?:able|d|h)$/i,+	rroot = /^(?:body|html)$/i;++if ( "getBoundingClientRect" in document.documentElement ) {+	getOffset = function( elem, doc, docElem, box ) {+		try {+			box = elem.getBoundingClientRect();+		} catch(e) {}++		// Make sure we're not dealing with a disconnected DOM node+		if ( !box || !jQuery.contains( docElem, elem ) ) {+			return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };+		}++		var body = doc.body,+			win = getWindow( doc ),+			clientTop  = docElem.clientTop  || body.clientTop  || 0,+			clientLeft = docElem.clientLeft || body.clientLeft || 0,+			scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,+			scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,+			top  = box.top  + scrollTop  - clientTop,+			left = box.left + scrollLeft - clientLeft;++		return { top: top, left: left };+	};++} else {+	getOffset = function( elem, doc, docElem ) {+		var computedStyle,+			offsetParent = elem.offsetParent,+			prevOffsetParent = elem,+			body = doc.body,+			defaultView = doc.defaultView,+			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,+			top = elem.offsetTop,+			left = elem.offsetLeft;++		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {+			if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {+				break;+			}++			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;+			top  -= elem.scrollTop;+			left -= elem.scrollLeft;++			if ( elem === offsetParent ) {+				top  += elem.offsetTop;+				left += elem.offsetLeft;++				if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {+					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;+					left += parseFloat( computedStyle.borderLeftWidth ) || 0;+				}++				prevOffsetParent = offsetParent;+				offsetParent = elem.offsetParent;+			}++			if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {+				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;+				left += parseFloat( computedStyle.borderLeftWidth ) || 0;+			}++			prevComputedStyle = computedStyle;+		}++		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {+			top  += body.offsetTop;+			left += body.offsetLeft;+		}++		if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {+			top  += Math.max( docElem.scrollTop, body.scrollTop );+			left += Math.max( docElem.scrollLeft, body.scrollLeft );+		}++		return { top: top, left: left };+	};+}++jQuery.fn.offset = function( options ) {+	if ( arguments.length ) {+		return options === undefined ?+			this :+			this.each(function( i ) {+				jQuery.offset.setOffset( this, options, i );+			});+	}++	var elem = this[0],+		doc = elem && elem.ownerDocument;++	if ( !doc ) {+		return null;+	}++	if ( elem === doc.body ) {+		return jQuery.offset.bodyOffset( elem );+	}++	return getOffset( elem, doc, doc.documentElement );+};++jQuery.offset = {++	bodyOffset: function( body ) {+		var top = body.offsetTop,+			left = body.offsetLeft;++		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {+			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;+			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;+		}++		return { top: top, left: left };+	},++	setOffset: function( elem, options, i ) {+		var position = jQuery.css( elem, "position" );++		// set position first, in-case top/left are set even on static elem+		if ( position === "static" ) {+			elem.style.position = "relative";+		}++		var curElem = jQuery( elem ),+			curOffset = curElem.offset(),+			curCSSTop = jQuery.css( elem, "top" ),+			curCSSLeft = jQuery.css( elem, "left" ),+			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,+			props = {}, curPosition = {}, curTop, curLeft;++		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed+		if ( calculatePosition ) {+			curPosition = curElem.position();+			curTop = curPosition.top;+			curLeft = curPosition.left;+		} else {+			curTop = parseFloat( curCSSTop ) || 0;+			curLeft = parseFloat( curCSSLeft ) || 0;+		}++		if ( jQuery.isFunction( options ) ) {+			options = options.call( elem, i, curOffset );+		}++		if ( options.top != null ) {+			props.top = ( options.top - curOffset.top ) + curTop;+		}+		if ( options.left != null ) {+			props.left = ( options.left - curOffset.left ) + curLeft;+		}++		if ( "using" in options ) {+			options.using.call( elem, props );+		} else {+			curElem.css( props );+		}+	}+};+++jQuery.fn.extend({++	position: function() {+		if ( !this[0] ) {+			return null;+		}++		var elem = this[0],++		// Get *real* offsetParent+		offsetParent = this.offsetParent(),++		// Get correct offsets+		offset       = this.offset(),+		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();++		// Subtract element margins+		// note: when an element has margin: auto the offsetLeft and marginLeft+		// are the same in Safari causing offset.left to incorrectly be 0+		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;+		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;++		// Add offsetParent borders+		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;+		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;++		// Subtract the two offsets+		return {+			top:  offset.top  - parentOffset.top,+			left: offset.left - parentOffset.left+		};+	},++	offsetParent: function() {+		return this.map(function() {+			var offsetParent = this.offsetParent || document.body;+			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {+				offsetParent = offsetParent.offsetParent;+			}+			return offsetParent;+		});+	}+});+++// Create scrollLeft and scrollTop methods+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {+	var top = /Y/.test( prop );++	jQuery.fn[ method ] = function( val ) {+		return jQuery.access( this, function( elem, method, val ) {+			var win = getWindow( elem );++			if ( val === undefined ) {+				return win ? (prop in win) ? win[ prop ] :+					jQuery.support.boxModel && win.document.documentElement[ method ] ||+						win.document.body[ method ] :+					elem[ method ];+			}++			if ( win ) {+				win.scrollTo(+					!top ? val : jQuery( win ).scrollLeft(),+					 top ? val : jQuery( win ).scrollTop()+				);++			} else {+				elem[ method ] = val;+			}+		}, method, val, arguments.length, null );+	};+});++function getWindow( elem ) {+	return jQuery.isWindow( elem ) ?+		elem :+		elem.nodeType === 9 ?+			elem.defaultView || elem.parentWindow :+			false;+}+++++// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {+	var clientProp = "client" + name,+		scrollProp = "scroll" + name,+		offsetProp = "offset" + name;++	// innerHeight and innerWidth+	jQuery.fn[ "inner" + name ] = function() {+		var elem = this[0];+		return elem ?+			elem.style ?+			parseFloat( jQuery.css( elem, type, "padding" ) ) :+			this[ type ]() :+			null;+	};++	// outerHeight and outerWidth+	jQuery.fn[ "outer" + name ] = function( margin ) {+		var elem = this[0];+		return elem ?+			elem.style ?+			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :+			this[ type ]() :+			null;+	};++	jQuery.fn[ type ] = function( value ) {+		return jQuery.access( this, function( elem, type, value ) {+			var doc, docElemProp, orig, ret;++			if ( jQuery.isWindow( elem ) ) {+				// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat+				doc = elem.document;+				docElemProp = doc.documentElement[ clientProp ];+				return jQuery.support.boxModel && docElemProp ||+					doc.body && doc.body[ clientProp ] || docElemProp;+			}++			// Get document width or height+			if ( elem.nodeType === 9 ) {+				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater+				doc = elem.documentElement;++				// when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]+				// so we can't use max, as it'll choose the incorrect offset[Width/Height]+				// instead we use the correct client[Width/Height]+				// support:IE6+				if ( doc[ clientProp ] >= doc[ scrollProp ] ) {+					return doc[ clientProp ];+				}++				return Math.max(+					elem.body[ scrollProp ], doc[ scrollProp ],+					elem.body[ offsetProp ], doc[ offsetProp ]+				);+			}++			// Get width or height on the element+			if ( value === undefined ) {+				orig = jQuery.css( elem, type );+				ret = parseFloat( orig );+				return jQuery.isNumeric( ret ) ? ret : orig;+			}++			// Set the width or height on the element+			jQuery( elem ).css( type, value );+		}, type, value, arguments.length, null );+	};+});+++++// Expose jQuery to the global object+window.jQuery = window.$ = jQuery;++// Expose jQuery as an AMD module, but only for AMD loaders that+// understand the issues with loading multiple versions of jQuery+// in a page that all might call define(). The loader will indicate+// they have special allowances for multiple jQuery versions by+// specifying define.amd.jQuery = true. Register as a named module,+// since jQuery can be concatenated with other files that may use define,+// but not use a proper concatenation script that understands anonymous+// AMD modules. A named AMD is safest and most robust way to register.+// Lowercase jquery is used because AMD module names are derived from+// file names, and jQuery is normally delivered in a lowercase file name.+// Do this after creating the global so that if an AMD module wants to call+// noConflict to hide this version of jQuery, it will work.+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {+	define( "jquery", [], function () { return jQuery; } );+}++++})( window );
+ example/static/screen.css view
@@ -0,0 +1,42 @@+html {+  padding: 0;+  margin: 0;+  background-color: #dcdccc;+  font-family: Verdana, Helvetica, sans-serif;+  color: #3f3f3f;+}+body {+  padding: 0;+  margin: 0;+}+a {+  color: #5c888b;+  text-decoration: underline;+}+a :hover {+  cursor: pointer;+  text-decoration: underline;+}+img {+  border: none;+}+#content {+  padding-left: 1em;+}++#formContainer {+  display: none;+  padding:1em;+  width:500px;+  border:1px solid #bcbccc;+}++#formContainer label, #formContainer input {+  display: block;+}++.status { display: none; padding: 1em; margin-top: 1em; }+.status.error { background-color: #bc8383; }+.status.notice { background-color: #7f9f7f; }++#loginStatus.status { width: 500px; }
+ example/static/underscore.js view
@@ -0,0 +1,1059 @@+//     Underscore.js 1.3.3+//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.+//     Underscore may be freely distributed under the MIT license.+//     Portions of Underscore are inspired or borrowed from Prototype,+//     Oliver Steele's Functional, and John Resig's Micro-Templating.+//     For all details and documentation:+//     http://documentcloud.github.com/underscore++(function() {++  // Baseline setup+  // --------------++  // Establish the root object, `window` in the browser, or `global` on the server.+  var root = this;++  // Save the previous value of the `_` variable.+  var previousUnderscore = root._;++  // Establish the object that gets returned to break out of a loop iteration.+  var breaker = {};++  // Save bytes in the minified (but not gzipped) version:+  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;++  // Create quick reference variables for speed access to core prototypes.+  var slice            = ArrayProto.slice,+      unshift          = ArrayProto.unshift,+      toString         = ObjProto.toString,+      hasOwnProperty   = ObjProto.hasOwnProperty;++  // All **ECMAScript 5** native function implementations that we hope to use+  // are declared here.+  var+    nativeForEach      = ArrayProto.forEach,+    nativeMap          = ArrayProto.map,+    nativeReduce       = ArrayProto.reduce,+    nativeReduceRight  = ArrayProto.reduceRight,+    nativeFilter       = ArrayProto.filter,+    nativeEvery        = ArrayProto.every,+    nativeSome         = ArrayProto.some,+    nativeIndexOf      = ArrayProto.indexOf,+    nativeLastIndexOf  = ArrayProto.lastIndexOf,+    nativeIsArray      = Array.isArray,+    nativeKeys         = Object.keys,+    nativeBind         = FuncProto.bind;++  // Create a safe reference to the Underscore object for use below.+  var _ = function(obj) { return new wrapper(obj); };++  // Export the Underscore object for **Node.js**, with+  // backwards-compatibility for the old `require()` API. If we're in+  // the browser, add `_` as a global object via a string identifier,+  // for Closure Compiler "advanced" mode.+  if (typeof exports !== 'undefined') {+    if (typeof module !== 'undefined' && module.exports) {+      exports = module.exports = _;+    }+    exports._ = _;+  } else {+    root['_'] = _;+  }++  // Current version.+  _.VERSION = '1.3.3';++  // Collection Functions+  // --------------------++  // The cornerstone, an `each` implementation, aka `forEach`.+  // Handles objects with the built-in `forEach`, arrays, and raw objects.+  // Delegates to **ECMAScript 5**'s native `forEach` if available.+  var each = _.each = _.forEach = function(obj, iterator, context) {+    if (obj == null) return;+    if (nativeForEach && obj.forEach === nativeForEach) {+      obj.forEach(iterator, context);+    } else if (obj.length === +obj.length) {+      for (var i = 0, l = obj.length; i < l; i++) {+        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;+      }+    } else {+      for (var key in obj) {+        if (_.has(obj, key)) {+          if (iterator.call(context, obj[key], key, obj) === breaker) return;+        }+      }+    }+  };++  // Return the results of applying the iterator to each element.+  // Delegates to **ECMAScript 5**'s native `map` if available.+  _.map = _.collect = function(obj, iterator, context) {+    var results = [];+    if (obj == null) return results;+    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);+    each(obj, function(value, index, list) {+      results[results.length] = iterator.call(context, value, index, list);+    });+    if (obj.length === +obj.length) results.length = obj.length;+    return results;+  };++  // **Reduce** builds up a single result from a list of values, aka `inject`,+  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.+  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {+    var initial = arguments.length > 2;+    if (obj == null) obj = [];+    if (nativeReduce && obj.reduce === nativeReduce) {+      if (context) iterator = _.bind(iterator, context);+      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);+    }+    each(obj, function(value, index, list) {+      if (!initial) {+        memo = value;+        initial = true;+      } else {+        memo = iterator.call(context, memo, value, index, list);+      }+    });+    if (!initial) throw new TypeError('Reduce of empty array with no initial value');+    return memo;+  };++  // The right-associative version of reduce, also known as `foldr`.+  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.+  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {+    var initial = arguments.length > 2;+    if (obj == null) obj = [];+    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {+      if (context) iterator = _.bind(iterator, context);+      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);+    }+    var reversed = _.toArray(obj).reverse();+    if (context && !initial) iterator = _.bind(iterator, context);+    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);+  };++  // Return the first value which passes a truth test. Aliased as `detect`.+  _.find = _.detect = function(obj, iterator, context) {+    var result;+    any(obj, function(value, index, list) {+      if (iterator.call(context, value, index, list)) {+        result = value;+        return true;+      }+    });+    return result;+  };++  // Return all the elements that pass a truth test.+  // Delegates to **ECMAScript 5**'s native `filter` if available.+  // Aliased as `select`.+  _.filter = _.select = function(obj, iterator, context) {+    var results = [];+    if (obj == null) return results;+    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);+    each(obj, function(value, index, list) {+      if (iterator.call(context, value, index, list)) results[results.length] = value;+    });+    return results;+  };++  // Return all the elements for which a truth test fails.+  _.reject = function(obj, iterator, context) {+    var results = [];+    if (obj == null) return results;+    each(obj, function(value, index, list) {+      if (!iterator.call(context, value, index, list)) results[results.length] = value;+    });+    return results;+  };++  // Determine whether all of the elements match a truth test.+  // Delegates to **ECMAScript 5**'s native `every` if available.+  // Aliased as `all`.+  _.every = _.all = function(obj, iterator, context) {+    var result = true;+    if (obj == null) return result;+    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);+    each(obj, function(value, index, list) {+      if (!(result = result && iterator.call(context, value, index, list))) return breaker;+    });+    return !!result;+  };++  // Determine if at least one element in the object matches a truth test.+  // Delegates to **ECMAScript 5**'s native `some` if available.+  // Aliased as `any`.+  var any = _.some = _.any = function(obj, iterator, context) {+    iterator || (iterator = _.identity);+    var result = false;+    if (obj == null) return result;+    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);+    each(obj, function(value, index, list) {+      if (result || (result = iterator.call(context, value, index, list))) return breaker;+    });+    return !!result;+  };++  // Determine if a given value is included in the array or object using `===`.+  // Aliased as `contains`.+  _.include = _.contains = function(obj, target) {+    var found = false;+    if (obj == null) return found;+    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;+    found = any(obj, function(value) {+      return value === target;+    });+    return found;+  };++  // Invoke a method (with arguments) on every item in a collection.+  _.invoke = function(obj, method) {+    var args = slice.call(arguments, 2);+    return _.map(obj, function(value) {+      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);+    });+  };++  // Convenience version of a common use case of `map`: fetching a property.+  _.pluck = function(obj, key) {+    return _.map(obj, function(value){ return value[key]; });+  };++  // Return the maximum element or (element-based computation).+  _.max = function(obj, iterator, context) {+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj);+    if (!iterator && _.isEmpty(obj)) return -Infinity;+    var result = {computed : -Infinity};+    each(obj, function(value, index, list) {+      var computed = iterator ? iterator.call(context, value, index, list) : value;+      computed >= result.computed && (result = {value : value, computed : computed});+    });+    return result.value;+  };++  // Return the minimum element (or element-based computation).+  _.min = function(obj, iterator, context) {+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj);+    if (!iterator && _.isEmpty(obj)) return Infinity;+    var result = {computed : Infinity};+    each(obj, function(value, index, list) {+      var computed = iterator ? iterator.call(context, value, index, list) : value;+      computed < result.computed && (result = {value : value, computed : computed});+    });+    return result.value;+  };++  // Shuffle an array.+  _.shuffle = function(obj) {+    var shuffled = [], rand;+    each(obj, function(value, index, list) {+      rand = Math.floor(Math.random() * (index + 1));+      shuffled[index] = shuffled[rand];+      shuffled[rand] = value;+    });+    return shuffled;+  };++  // Sort the object's values by a criterion produced by an iterator.+  _.sortBy = function(obj, val, context) {+    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };+    return _.pluck(_.map(obj, function(value, index, list) {+      return {+        value : value,+        criteria : iterator.call(context, value, index, list)+      };+    }).sort(function(left, right) {+      var a = left.criteria, b = right.criteria;+      if (a === void 0) return 1;+      if (b === void 0) return -1;+      return a < b ? -1 : a > b ? 1 : 0;+    }), 'value');+  };++  // Groups the object's values by a criterion. Pass either a string attribute+  // to group by, or a function that returns the criterion.+  _.groupBy = function(obj, val) {+    var result = {};+    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };+    each(obj, function(value, index) {+      var key = iterator(value, index);+      (result[key] || (result[key] = [])).push(value);+    });+    return result;+  };++  // Use a comparator function to figure out at what index an object should+  // be inserted so as to maintain order. Uses binary search.+  _.sortedIndex = function(array, obj, iterator) {+    iterator || (iterator = _.identity);+    var low = 0, high = array.length;+    while (low < high) {+      var mid = (low + high) >> 1;+      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;+    }+    return low;+  };++  // Safely convert anything iterable into a real, live array.+  _.toArray = function(obj) {+    if (!obj)                                     return [];+    if (_.isArray(obj))                           return slice.call(obj);+    if (_.isArguments(obj))                       return slice.call(obj);+    if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();+    return _.values(obj);+  };++  // Return the number of elements in an object.+  _.size = function(obj) {+    return _.isArray(obj) ? obj.length : _.keys(obj).length;+  };++  // Array Functions+  // ---------------++  // Get the first element of an array. Passing **n** will return the first N+  // values in the array. Aliased as `head` and `take`. The **guard** check+  // allows it to work with `_.map`.+  _.first = _.head = _.take = function(array, n, guard) {+    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];+  };++  // Returns everything but the last entry of the array. Especcialy useful on+  // the arguments object. Passing **n** will return all the values in+  // the array, excluding the last N. The **guard** check allows it to work with+  // `_.map`.+  _.initial = function(array, n, guard) {+    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));+  };++  // Get the last element of an array. Passing **n** will return the last N+  // values in the array. The **guard** check allows it to work with `_.map`.+  _.last = function(array, n, guard) {+    if ((n != null) && !guard) {+      return slice.call(array, Math.max(array.length - n, 0));+    } else {+      return array[array.length - 1];+    }+  };++  // Returns everything but the first entry of the array. Aliased as `tail`.+  // Especially useful on the arguments object. Passing an **index** will return+  // the rest of the values in the array from that index onward. The **guard**+  // check allows it to work with `_.map`.+  _.rest = _.tail = function(array, index, guard) {+    return slice.call(array, (index == null) || guard ? 1 : index);+  };++  // Trim out all falsy values from an array.+  _.compact = function(array) {+    return _.filter(array, function(value){ return !!value; });+  };++  // Return a completely flattened version of an array.+  _.flatten = function(array, shallow) {+    return _.reduce(array, function(memo, value) {+      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));+      memo[memo.length] = value;+      return memo;+    }, []);+  };++  // Return a version of the array that does not contain the specified value(s).+  _.without = function(array) {+    return _.difference(array, slice.call(arguments, 1));+  };++  // Produce a duplicate-free version of the array. If the array has already+  // been sorted, you have the option of using a faster algorithm.+  // Aliased as `unique`.+  _.uniq = _.unique = function(array, isSorted, iterator) {+    var initial = iterator ? _.map(array, iterator) : array;+    var results = [];+    // The `isSorted` flag is irrelevant if the array only contains two elements.+    if (array.length < 3) isSorted = true;+    _.reduce(initial, function (memo, value, index) {+      if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {+        memo.push(value);+        results.push(array[index]);+      }+      return memo;+    }, []);+    return results;+  };++  // Produce an array that contains the union: each distinct element from all of+  // the passed-in arrays.+  _.union = function() {+    return _.uniq(_.flatten(arguments, true));+  };++  // Produce an array that contains every item shared between all the+  // passed-in arrays. (Aliased as "intersect" for back-compat.)+  _.intersection = _.intersect = function(array) {+    var rest = slice.call(arguments, 1);+    return _.filter(_.uniq(array), function(item) {+      return _.every(rest, function(other) {+        return _.indexOf(other, item) >= 0;+      });+    });+  };++  // Take the difference between one array and a number of other arrays.+  // Only the elements present in just the first array will remain.+  _.difference = function(array) {+    var rest = _.flatten(slice.call(arguments, 1), true);+    return _.filter(array, function(value){ return !_.include(rest, value); });+  };++  // Zip together multiple lists into a single array -- elements that share+  // an index go together.+  _.zip = function() {+    var args = slice.call(arguments);+    var length = _.max(_.pluck(args, 'length'));+    var results = new Array(length);+    for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);+    return results;+  };++  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),+  // we need this function. Return the position of the first occurrence of an+  // item in an array, or -1 if the item is not included in the array.+  // Delegates to **ECMAScript 5**'s native `indexOf` if available.+  // If the array is large and already in sort order, pass `true`+  // for **isSorted** to use binary search.+  _.indexOf = function(array, item, isSorted) {+    if (array == null) return -1;+    var i, l;+    if (isSorted) {+      i = _.sortedIndex(array, item);+      return array[i] === item ? i : -1;+    }+    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);+    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;+    return -1;+  };++  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.+  _.lastIndexOf = function(array, item) {+    if (array == null) return -1;+    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);+    var i = array.length;+    while (i--) if (i in array && array[i] === item) return i;+    return -1;+  };++  // Generate an integer Array containing an arithmetic progression. A port of+  // the native Python `range()` function. See+  // [the Python documentation](http://docs.python.org/library/functions.html#range).+  _.range = function(start, stop, step) {+    if (arguments.length <= 1) {+      stop = start || 0;+      start = 0;+    }+    step = arguments[2] || 1;++    var len = Math.max(Math.ceil((stop - start) / step), 0);+    var idx = 0;+    var range = new Array(len);++    while(idx < len) {+      range[idx++] = start;+      start += step;+    }++    return range;+  };++  // Function (ahem) Functions+  // ------------------++  // Reusable constructor function for prototype setting.+  var ctor = function(){};++  // Create a function bound to a given object (assigning `this`, and arguments,+  // optionally). Binding with arguments is also known as `curry`.+  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.+  // We check for `func.bind` first, to fail fast when `func` is undefined.+  _.bind = function bind(func, context) {+    var bound, args;+    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));+    if (!_.isFunction(func)) throw new TypeError;+    args = slice.call(arguments, 2);+    return bound = function() {+      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));+      ctor.prototype = func.prototype;+      var self = new ctor;+      var result = func.apply(self, args.concat(slice.call(arguments)));+      if (Object(result) === result) return result;+      return self;+    };+  };++  // Bind all of an object's methods to that object. Useful for ensuring that+  // all callbacks defined on an object belong to it.+  _.bindAll = function(obj) {+    var funcs = slice.call(arguments, 1);+    if (funcs.length == 0) funcs = _.functions(obj);+    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });+    return obj;+  };++  // Memoize an expensive function by storing its results.+  _.memoize = function(func, hasher) {+    var memo = {};+    hasher || (hasher = _.identity);+    return function() {+      var key = hasher.apply(this, arguments);+      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));+    };+  };++  // Delays a function for the given number of milliseconds, and then calls+  // it with the arguments supplied.+  _.delay = function(func, wait) {+    var args = slice.call(arguments, 2);+    return setTimeout(function(){ return func.apply(null, args); }, wait);+  };++  // Defers a function, scheduling it to run after the current call stack has+  // cleared.+  _.defer = function(func) {+    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));+  };++  // Returns a function, that, when invoked, will only be triggered at most once+  // during a given window of time.+  _.throttle = function(func, wait) {+    var context, args, timeout, throttling, more, result;+    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);+    return function() {+      context = this; args = arguments;+      var later = function() {+        timeout = null;+        if (more) func.apply(context, args);+        whenDone();+      };+      if (!timeout) timeout = setTimeout(later, wait);+      if (throttling) {+        more = true;+      } else {+        result = func.apply(context, args);+      }+      whenDone();+      throttling = true;+      return result;+    };+  };++  // Returns a function, that, as long as it continues to be invoked, will not+  // be triggered. The function will be called after it stops being called for+  // N milliseconds. If `immediate` is passed, trigger the function on the+  // leading edge, instead of the trailing.+  _.debounce = function(func, wait, immediate) {+    var timeout;+    return function() {+      var context = this, args = arguments;+      var later = function() {+        timeout = null;+        if (!immediate) func.apply(context, args);+      };+      if (immediate && !timeout) func.apply(context, args);+      clearTimeout(timeout);+      timeout = setTimeout(later, wait);+    };+  };++  // Returns a function that will be executed at most one time, no matter how+  // often you call it. Useful for lazy initialization.+  _.once = function(func) {+    var ran = false, memo;+    return function() {+      if (ran) return memo;+      ran = true;+      return memo = func.apply(this, arguments);+    };+  };++  // Returns the first function passed as an argument to the second,+  // allowing you to adjust arguments, run code before and after, and+  // conditionally execute the original function.+  _.wrap = function(func, wrapper) {+    return function() {+      var args = [func].concat(slice.call(arguments, 0));+      return wrapper.apply(this, args);+    };+  };++  // Returns a function that is the composition of a list of functions, each+  // consuming the return value of the function that follows.+  _.compose = function() {+    var funcs = arguments;+    return function() {+      var args = arguments;+      for (var i = funcs.length - 1; i >= 0; i--) {+        args = [funcs[i].apply(this, args)];+      }+      return args[0];+    };+  };++  // Returns a function that will only be executed after being called N times.+  _.after = function(times, func) {+    if (times <= 0) return func();+    return function() {+      if (--times < 1) { return func.apply(this, arguments); }+    };+  };++  // Object Functions+  // ----------------++  // Retrieve the names of an object's properties.+  // Delegates to **ECMAScript 5**'s native `Object.keys`+  _.keys = nativeKeys || function(obj) {+    if (obj !== Object(obj)) throw new TypeError('Invalid object');+    var keys = [];+    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;+    return keys;+  };++  // Retrieve the values of an object's properties.+  _.values = function(obj) {+    return _.map(obj, _.identity);+  };++  // Return a sorted list of the function names available on the object.+  // Aliased as `methods`+  _.functions = _.methods = function(obj) {+    var names = [];+    for (var key in obj) {+      if (_.isFunction(obj[key])) names.push(key);+    }+    return names.sort();+  };++  // Extend a given object with all the properties in passed-in object(s).+  _.extend = function(obj) {+    each(slice.call(arguments, 1), function(source) {+      for (var prop in source) {+        obj[prop] = source[prop];+      }+    });+    return obj;+  };++  // Return a copy of the object only containing the whitelisted properties.+  _.pick = function(obj) {+    var result = {};+    each(_.flatten(slice.call(arguments, 1)), function(key) {+      if (key in obj) result[key] = obj[key];+    });+    return result;+  };++  // Fill in a given object with default properties.+  _.defaults = function(obj) {+    each(slice.call(arguments, 1), function(source) {+      for (var prop in source) {+        if (obj[prop] == null) obj[prop] = source[prop];+      }+    });+    return obj;+  };++  // Create a (shallow-cloned) duplicate of an object.+  _.clone = function(obj) {+    if (!_.isObject(obj)) return obj;+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);+  };++  // Invokes interceptor with the obj, and then returns obj.+  // The primary purpose of this method is to "tap into" a method chain, in+  // order to perform operations on intermediate results within the chain.+  _.tap = function(obj, interceptor) {+    interceptor(obj);+    return obj;+  };++  // Internal recursive comparison function.+  function eq(a, b, stack) {+    // Identical objects are equal. `0 === -0`, but they aren't identical.+    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.+    if (a === b) return a !== 0 || 1 / a == 1 / b;+    // A strict comparison is necessary because `null == undefined`.+    if (a == null || b == null) return a === b;+    // Unwrap any wrapped objects.+    if (a._chain) a = a._wrapped;+    if (b._chain) b = b._wrapped;+    // Invoke a custom `isEqual` method if one is provided.+    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);+    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);+    // Compare `[[Class]]` names.+    var className = toString.call(a);+    if (className != toString.call(b)) return false;+    switch (className) {+      // Strings, numbers, dates, and booleans are compared by value.+      case '[object String]':+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is+        // equivalent to `new String("5")`.+        return a == String(b);+      case '[object Number]':+        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for+        // other numeric values.+        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);+      case '[object Date]':+      case '[object Boolean]':+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their+        // millisecond representations. Note that invalid dates with millisecond representations+        // of `NaN` are not equivalent.+        return +a == +b;+      // RegExps are compared by their source patterns and flags.+      case '[object RegExp]':+        return a.source == b.source &&+               a.global == b.global &&+               a.multiline == b.multiline &&+               a.ignoreCase == b.ignoreCase;+    }+    if (typeof a != 'object' || typeof b != 'object') return false;+    // Assume equality for cyclic structures. The algorithm for detecting cyclic+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.+    var length = stack.length;+    while (length--) {+      // Linear search. Performance is inversely proportional to the number of+      // unique nested structures.+      if (stack[length] == a) return true;+    }+    // Add the first object to the stack of traversed objects.+    stack.push(a);+    var size = 0, result = true;+    // Recursively compare objects and arrays.+    if (className == '[object Array]') {+      // Compare array lengths to determine if a deep comparison is necessary.+      size = a.length;+      result = size == b.length;+      if (result) {+        // Deep compare the contents, ignoring non-numeric properties.+        while (size--) {+          // Ensure commutative equality for sparse arrays.+          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;+        }+      }+    } else {+      // Objects with different constructors are not equivalent.+      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;+      // Deep compare objects.+      for (var key in a) {+        if (_.has(a, key)) {+          // Count the expected number of properties.+          size++;+          // Deep compare each member.+          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;+        }+      }+      // Ensure that both objects contain the same number of properties.+      if (result) {+        for (key in b) {+          if (_.has(b, key) && !(size--)) break;+        }+        result = !size;+      }+    }+    // Remove the first object from the stack of traversed objects.+    stack.pop();+    return result;+  }++  // Perform a deep comparison to check if two objects are equal.+  _.isEqual = function(a, b) {+    return eq(a, b, []);+  };++  // Is a given array, string, or object empty?+  // An "empty" object has no enumerable own-properties.+  _.isEmpty = function(obj) {+    if (obj == null) return true;+    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;+    for (var key in obj) if (_.has(obj, key)) return false;+    return true;+  };++  // Is a given value a DOM element?+  _.isElement = function(obj) {+    return !!(obj && obj.nodeType == 1);+  };++  // Is a given value an array?+  // Delegates to ECMA5's native Array.isArray+  _.isArray = nativeIsArray || function(obj) {+    return toString.call(obj) == '[object Array]';+  };++  // Is a given variable an object?+  _.isObject = function(obj) {+    return obj === Object(obj);+  };++  // Is a given variable an arguments object?+  _.isArguments = function(obj) {+    return toString.call(obj) == '[object Arguments]';+  };+  if (!_.isArguments(arguments)) {+    _.isArguments = function(obj) {+      return !!(obj && _.has(obj, 'callee'));+    };+  }++  // Is a given value a function?+  _.isFunction = function(obj) {+    return toString.call(obj) == '[object Function]';+  };++  // Is a given value a string?+  _.isString = function(obj) {+    return toString.call(obj) == '[object String]';+  };++  // Is a given value a number?+  _.isNumber = function(obj) {+    return toString.call(obj) == '[object Number]';+  };++  // Is a given object a finite number?+  _.isFinite = function(obj) {+    return _.isNumber(obj) && isFinite(obj);+  };++  // Is the given value `NaN`?+  _.isNaN = function(obj) {+    // `NaN` is the only value for which `===` is not reflexive.+    return obj !== obj;+  };++  // Is a given value a boolean?+  _.isBoolean = function(obj) {+    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';+  };++  // Is a given value a date?+  _.isDate = function(obj) {+    return toString.call(obj) == '[object Date]';+  };++  // Is the given value a regular expression?+  _.isRegExp = function(obj) {+    return toString.call(obj) == '[object RegExp]';+  };++  // Is a given value equal to null?+  _.isNull = function(obj) {+    return obj === null;+  };++  // Is a given variable undefined?+  _.isUndefined = function(obj) {+    return obj === void 0;+  };++  // Has own property?+  _.has = function(obj, key) {+    return hasOwnProperty.call(obj, key);+  };++  // Utility Functions+  // -----------------++  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its+  // previous owner. Returns a reference to the Underscore object.+  _.noConflict = function() {+    root._ = previousUnderscore;+    return this;+  };++  // Keep the identity function around for default iterators.+  _.identity = function(value) {+    return value;+  };++  // Run a function **n** times.+  _.times = function (n, iterator, context) {+    for (var i = 0; i < n; i++) iterator.call(context, i);+  };++  // Escape a string for HTML interpolation.+  _.escape = function(string) {+    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');+  };++  // If the value of the named property is a function then invoke it;+  // otherwise, return it.+  _.result = function(object, property) {+    if (object == null) return null;+    var value = object[property];+    return _.isFunction(value) ? value.call(object) : value;+  };++  // Add your own custom functions to the Underscore object, ensuring that+  // they're correctly added to the OOP wrapper as well.+  _.mixin = function(obj) {+    each(_.functions(obj), function(name){+      addToWrapper(name, _[name] = obj[name]);+    });+  };++  // Generate a unique integer id (unique within the entire client session).+  // Useful for temporary DOM ids.+  var idCounter = 0;+  _.uniqueId = function(prefix) {+    var id = idCounter++;+    return prefix ? prefix + id : id;+  };++  // By default, Underscore uses ERB-style template delimiters, change the+  // following template settings to use alternative delimiters.+  _.templateSettings = {+    evaluate    : /<%([\s\S]+?)%>/g,+    interpolate : /<%=([\s\S]+?)%>/g,+    escape      : /<%-([\s\S]+?)%>/g+  };++  // When customizing `templateSettings`, if you don't want to define an+  // interpolation, evaluation or escaping regex, we need one that is+  // guaranteed not to match.+  var noMatch = /.^/;++  // Certain characters need to be escaped so that they can be put into a+  // string literal.+  var escapes = {+    '\\': '\\',+    "'": "'",+    'r': '\r',+    'n': '\n',+    't': '\t',+    'u2028': '\u2028',+    'u2029': '\u2029'+  };++  for (var p in escapes) escapes[escapes[p]] = p;+  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;+  var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;++  // Within an interpolation, evaluation, or escaping, remove HTML escaping+  // that had been previously added.+  var unescape = function(code) {+    return code.replace(unescaper, function(match, escape) {+      return escapes[escape];+    });+  };++  // JavaScript micro-templating, similar to John Resig's implementation.+  // Underscore templating handles arbitrary delimiters, preserves whitespace,+  // and correctly escapes quotes within interpolated code.+  _.template = function(text, data, settings) {+    settings = _.defaults(settings || {}, _.templateSettings);++    // Compile the template source, taking care to escape characters that+    // cannot be included in a string literal and then unescape them in code+    // blocks.+    var source = "__p+='" + text+      .replace(escaper, function(match) {+        return '\\' + escapes[match];+      })+      .replace(settings.escape || noMatch, function(match, code) {+        return "'+\n_.escape(" + unescape(code) + ")+\n'";+      })+      .replace(settings.interpolate || noMatch, function(match, code) {+        return "'+\n(" + unescape(code) + ")+\n'";+      })+      .replace(settings.evaluate || noMatch, function(match, code) {+        return "';\n" + unescape(code) + "\n;__p+='";+      }) + "';\n";++    // If a variable is not specified, place data values in local scope.+    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';++    source = "var __p='';" ++      "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" ++      source + "return __p;\n";++    var render = new Function(settings.variable || 'obj', '_', source);+    if (data) return render(data, _);+    var template = function(data) {+      return render.call(this, data, _);+    };++    // Provide the compiled function source as a convenience for build time+    // precompilation.+    template.source = 'function(' + (settings.variable || 'obj') + '){\n' ++      source + '}';++    return template;+  };++  // Add a "chain" function, which will delegate to the wrapper.+  _.chain = function(obj) {+    return _(obj).chain();+  };++  // The OOP Wrapper+  // ---------------++  // If Underscore is called as a function, it returns a wrapped object that+  // can be used OO-style. This wrapper holds altered versions of all the+  // underscore functions. Wrapped objects may be chained.+  var wrapper = function(obj) { this._wrapped = obj; };++  // Expose `wrapper.prototype` as `_.prototype`+  _.prototype = wrapper.prototype;++  // Helper function to continue chaining intermediate results.+  var result = function(obj, chain) {+    return chain ? _(obj).chain() : obj;+  };++  // A method to easily add functions to the OOP wrapper.+  var addToWrapper = function(name, func) {+    wrapper.prototype[name] = function() {+      var args = slice.call(arguments);+      unshift.call(args, this._wrapped);+      return result(func.apply(_, args), this._chain);+    };+  };++  // Add all of the Underscore functions to the wrapper object.+  _.mixin(_);++  // Add all mutator Array functions to the wrapper.+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {+    var method = ArrayProto[name];+    wrapper.prototype[name] = function() {+      var wrapped = this._wrapped;+      method.apply(wrapped, arguments);+      var length = wrapped.length;+      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];+      return result(wrapped, this._chain);+    };+  });++  // Add all accessor Array functions to the wrapper.+  each(['concat', 'join', 'slice'], function(name) {+    var method = ArrayProto[name];+    wrapper.prototype[name] = function() {+      return result(method.apply(this._wrapped, arguments), this._chain);+    };+  });++  // Start chaining a wrapped Underscore object.+  wrapper.prototype.chain = function() {+    this._chain = true;+    return this;+  };++  // Extracts the result from a wrapped and chained object.+  wrapper.prototype.value = function() {+    return this._wrapped;+  };++}).call(this);
snaplet-fay.cabal view
@@ -5,28 +5,28 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.3.1.0+version:             0.3.1.1 synopsis:            Fay integration for Snap with request- and pre-compilation. description:         Fay integration for Snap with request based compilation during development and precompilation in production.-                     For more information, please see <https://github.com/faylang/snaplet-fay>.+                     For more information, please see <https://github.com/bergmark/snaplet-fay>. license:             BSD3 license-file:        LICENSE author:              Adam Bergmark maintainer:          adam@edea.se-homepage:            https://github.com/faylang/snaplet-fay-bug-reports:         https://github.com/faylang/snaplet-fay/issues-category:            Web, Snap+homepage:            https://github.com/bergmark/snaplet-fay+bug-reports:         https://github.com/bergmark/snaplet-fay/issues+category:            Web, Snap, Fay build-type:          Simple cabal-version:       >=1.8 -extra-source-files:  LICENSE+extra-source-files:  LICENSE, README.md example/example.cabal example/snaplets/fay/devel.cfg example/snaplets/fay/js/.gitignore example/snaplets/fay/src/Application/SharedTypes.hs example/snaplets/fay/src/BrokenFile.hs example/snaplets/fay/src/Dom.hs example/snaplets/fay/src/Index.hs example/snaplets/heist/templates/index.tpl example/snaplets/heist/templates/login-form.tpl example/snaplets/heist/templates/register-form.tpl example/log/.gitignore example/src/Application.hs example/src/Main.hs example/src/Site.hs example/static/broken.html example/static/index.js example/static/jquery.js example/static/screen.css example/static/underscore.js  data-files:   resources/devel.cfg  source-repository head   type: git-  location: https://github.com/faylang/snaplet-fay.git+  location: https://github.com/bergmark/snaplet-fay.git  library   ghc-options: -Wall@@ -39,13 +39,13 @@     Snap.Snaplet.Fay.Internal, Paths_snaplet_fay    build-depends:-      base         == 4.*+      base         >= 4 && < 5     , aeson        >= 0.6     , bytestring   >= 0.9     , configurator >= 0.2     , data-default >= 0.5     , directory    >= 1.1-    , fay          >= 0.14.1+    , fay          >= 0.14.2.0     , filepath     >= 1.3     , mtl          >= 2.1     , snap         >= 0.11.1
src/Snap/Snaplet/Fay/Internal.hs view
@@ -52,14 +52,7 @@       putStrLn $ "snaplet-fay: Could not find: " ++ hsRelativePath f       return NotFound     else do-      print config-      putStrLn ""-      let cfg' = F.addConfigPackages (packages config) $ F.addConfigDirectoryIncludePaths (includeDirs config) $ def { F.configPrettyPrint = prettyPrint config }-      print cfg'-      putStrLn ""       f' <- canonicalizePath f-      print f'-      putStrLn ""       res <- flip F.compileFile f' $ F.addConfigPackages (packages config) $                                       F.addConfigDirectoryIncludePaths (includeDirs config) $                                         def { F.configPrettyPrint = prettyPrint config