Commit 997885577c3ff3248791790f0b067e904b6c3384

Authored by xwenliang
0 parents

init

README.md 0 → 100644
  1 +++ a/README.md
  1 +## video 视频录制
  2 +
  3 +## 使用方法:
  4 +
  5 +打开chrome浏览器,在地址栏输入`chrome://extensions/`,打开后点击`加载已解压的扩展程序`,选择本项目目录即可安装成功。
  6 +
  7 +## TODO:
  8 +
  9 +1. 同个页面多个 video 处理
  10 +2. 视频暂停时要暂停录制
  11 +3. popup 增加录制提示,各种控制按钮,如静音录制、自动录制等等
  12 +4. 在 client 端转为 MP4 格式的可行性
  13 +5. 经常会失败,或录制不全
  14 +6. 顶多可以同时开3个窗口录制,再多容易失败
  15 +
  16 +## 问题记录
  17 +
  18 +1. 很多视频网站播放完后会刷新页面到下一个播放页面,导致 `content.js` 中对 `video` 标签的 `end` `complete` 事件的监听函数中的动作不能保证成功,同样页面的 `beforeunload` `unload` 事件监听函数中的动作也不能保证成功
  19 +
  20 +2. `MediaRecorder` 只能录制以下几种格式的视频:
  21 +
  22 +```
  23 +Essentially, it looks like the following are (at time of writing) accepted MIME types for video/audio in Chrome:
  24 +
  25 +video/webm
  26 +video/webm;codecs=vp8
  27 +video/webm;codecs=vp9
  28 +video/webm;codecs=vp8.0
  29 +video/webm;codecs=vp9.0
  30 +video/webm;codecs=h264
  31 +video/webm;codecs=H264
  32 +video/webm;codecs=avc1
  33 +video/webm;codecs=vp8,opus
  34 +video/WEBM;codecs=VP8,OPUS
  35 +video/webm;codecs=vp9,opus
  36 +video/webm;codecs=vp8,vp9,opus
  37 +video/webm;codecs=h264,opus
  38 +video/webm;codecs=h264,vp9,opus
  39 +video/x-matroska;codecs=avc1
  40 +
  41 +audio/webm
  42 +
  43 +audio/webm;codecs=opus
  44 +(EDITED 2019-02-10: Updated to include brianchirls' link find)
  45 +```
  46 +
  47 +3. https://github.com/ffmpegwasm/ffmpeg.wasm 不能用于浏览器插件的 background, 报错:
  48 +
  49 +> Uncaught (in promise) RuntimeError: abort(CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder). Build with -s ASSERTIONS=1 for more info.
  50 +
  51 +manifest.json 加上 `"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",` 仍然报错:
  52 +
  53 +> Refused to load the script 'blob:chrome-extension://nnodhmmdmobflnhbigcheclnhdfkidpf/71e2d139-c5f1-4991-bbc0-4748802aec2a' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
  54 +
  55 +4. content 和 background 通信无法直接传递 Blob 类型数据,但可以传递 `URL.createObjectURL` 创建的数据,localStorage 同样。可以使用 `new FileReader().readAsBinaryString` 解决
  56 +
  57 +5. muted video 不会触发 `captureStream()`
  58 +
  59 +> https://bugs.chromium.org/p/chromium/issues/detail?id=1136404
0 60 \ No newline at end of file
... ...
background/background.html 0 → 100644
  1 +++ a/background/background.html
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6 + <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7 + <title>Document</title>
  8 +</head>
  9 +<body>
  10 +
  11 +</body>
  12 +</html>
0 13 \ No newline at end of file
... ...
background/background.js 0 → 100644
  1 +++ a/background/background.js
  1 +// background 虽然天然可以跨域,然而既然是后台就没有 cookie 的概念,即使 fetch 设置了 credentials, cookie 依然不会被保存
  2 +// http://stackoverflow.com/questions/29251842/why-new-js-fetch-standard-forbid-response-header-name-as-set-cookie-1-2
  3 +
  4 +// const { createFFmpeg, fetchFile } = FFmpeg;
  5 +
  6 +// async function test(){
  7 +// const ffmpeg = createFFmpeg({log: true});
  8 +// await ffmpeg.load();
  9 +// console.log(ffmpeg);
  10 +// };
  11 +
  12 +// test();
  13 +
  14 +const videos = {};
  15 +
  16 +/**
  17 + * data: fr.result,
  18 + size: blobData.size,
  19 + mimeType: blobData.type,
  20 + name: document.title,
  21 + action: 'data'
  22 + */
  23 +chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  24 + // console.log("Received %o from %o, frame", msg, sender.tab, sender.frameId);
  25 + sendResponse("Gotcha!");
  26 +
  27 + if(msg.action === 'end'){
  28 + return download(sender.documentId);
  29 + }
  30 +
  31 + if(!msg.data || msg.size !== msg.data.length){
  32 + return console.warn('data received error: ', msg.name);
  33 + }
  34 +
  35 + const blobAsBinString = msg.data;
  36 + const bytes = new Uint8Array(blobAsBinString.length);
  37 + for(let i=0,len=blobAsBinString.length; i<len; i++){
  38 + bytes[i] = blobAsBinString.charCodeAt(i);
  39 + }
  40 + videos[sender.documentId] = videos[sender.documentId] || {};
  41 + videos[sender.documentId].blob = videos[sender.documentId].blob || [];
  42 + videos[sender.documentId].mimeType = msg.mimeType;
  43 + videos[sender.documentId].name = msg.name;
  44 + videos[sender.documentId].blob.push(bytes);
  45 +});
  46 +
  47 +function download(id){
  48 + const tar = videos[id];
  49 + if(!tar){
  50 + return ;
  51 + }
  52 + const blob = new Blob(tar.blob, {type: tar.mimeType});
  53 + chrome.downloads.download({
  54 + url: URL.createObjectURL(blob),
  55 + filename: `${tar.name}.mkv`
  56 + }, resp => {
  57 + delete videos[id];
  58 + });
  59 +};
  60 +
  61 +// chrome.webNavigation.onCompleted
  62 +chrome.webNavigation.onBeforeNavigate.addListener(frame => {
  63 + // chrome.webNavigation.getFrame({
  64 + // frameId: frame.frameId,
  65 + // tabId: frame.tabId
  66 + // }, details => {
  67 + // alert(JSON.stringify(details));
  68 + // });
  69 +});
  70 +
  71 +// chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  72 + // chrome.webNavigation.getAllFrames({tabId: tabId}, function(details) {
  73 + // details.forEach(function(frame) {
  74 + // console.log(tabId);
  75 + // // chrome.tabs.sendMessage(
  76 + // // tabId,
  77 + // // {text: 'hey_cs'},
  78 + // // {frameId: frame.frameId},
  79 + // // function(response) { console.log(response) }
  80 + // // );
  81 + // });
  82 + // });
  83 +// });
0 84 \ No newline at end of file
... ...
content/content.js 0 → 100644
  1 +++ a/content/content.js
  1 +// 这是会插入网页运行的代码
  2 +
  3 +const $videos = [...document.querySelectorAll('video')];
  4 +
  5 +// todo: 支持同一页面多个视频
  6 +// $videos.map(($v, idx) => {
  7 +// const $tag = document.createElement('div');
  8 +// const $par = $v.parentNode;
  9 +// $tag.innerText = `点击 ${idx+1} 录制`;
  10 +// $tag.style = `
  11 +// position: absolute;
  12 +// top: 0;
  13 +// left: 0;
  14 +// z-index: 9999;
  15 +// width: ${$v.offsetWidth}px;
  16 +// height: ${$v.offsetHeight}px;
  17 +// line-height: ${$v.offsetHeight}px;
  18 +// text-align: center;
  19 +// color: red;
  20 +// font-size: ${$v.offsetWidth/10}px;
  21 +// font-weight: bold;
  22 +// border: 5px solid red;
  23 +// box-sizing: border-box;
  24 +// `;
  25 +// $par.style.position = 'relative';
  26 +// $v.parentNode.appendChild($tag);
  27 +// $tag.addEventListener('click', () => {
  28 +// $tag.remove();
  29 +// startRecording($v);
  30 +// return ;
  31 +// });
  32 +// });
  33 +
  34 +const $target = $videos[0];
  35 +$target && $target.addEventListener('playing', () => {
  36 + // muted video 不触发 captureStream
  37 + // $target.muted = true;
  38 + $target.volume = 0.01;
  39 + if($target.isRecording){
  40 + return ;
  41 + }
  42 + $target.isRecording = true;
  43 + // 很多视频开头有小动作,比如帮你拖拽进度条,可能会延迟触发或多次触发,所以我们要加个延时
  44 + setTimeout(() => {
  45 + console.log('Video Recorder started...');
  46 + startRecording($target);
  47 + }, 5000);
  48 +});
  49 +
  50 +function startRecording($tar){
  51 + const mimeType = 'video/webm';
  52 + const recorder = new MediaRecorder($tar.captureStream(), {
  53 + mimeType
  54 + });
  55 + recorder.onstart = function(e){
  56 + // console.log('start', e);
  57 + };
  58 + recorder.ondataavailable = function(e){
  59 + // console.log('ondata', e);
  60 + // const blob = new Blob([e.data], {
  61 + // type: mimeType
  62 + // });
  63 + sendBlobData(e.data);
  64 + };
  65 + recorder.onstop = function(e){
  66 + endBlobData();
  67 + // console.log('stoped', e);
  68 + // 不能成功,因为有些页面视频播完会刷新到下一个视频
  69 + // const blob = new Blob(chunks, {
  70 + // type: mimeType
  71 + // });
  72 + // const url = URL.createObjectURL(blob);
  73 + // const a = document.createElement('a');
  74 + // document.body.appendChild(a);
  75 + // a.style = 'display: none';
  76 + // a.href = url;
  77 + // a.download = document.title;
  78 + // a.click();
  79 + // window.URL.revokeObjectURL(url);
  80 + };
  81 + recorder.onerror = function(e){
  82 + // console.log('errored', e);
  83 + };
  84 + // 重置播放时间
  85 + $tar.currentTime = 0;
  86 + recorder.start(1000);
  87 + $tar.onended = function(e){
  88 + stopRecorder(recorder);
  89 + };
  90 + $tar.oncomplete = function(e){
  91 + stopRecorder(recorder);
  92 + };
  93 + window.onbeforeunload = function(e){
  94 + stopRecorder(recorder);
  95 + };
  96 +};
  97 +
  98 +function sendBlobData(blobData){
  99 + const fr = new FileReader();
  100 + fr.onload = function(ev){
  101 + chrome.runtime.sendMessage({
  102 + data: fr.result,
  103 + size: blobData.size,
  104 + mimeType: blobData.type,
  105 + name: document.title,
  106 + action: 'data'
  107 + }, response => {
  108 + // console.log("Response: ", response);
  109 + });
  110 + };
  111 + fr.onerror = function(ev){
  112 + console.log('FileReader error', ev);
  113 + };
  114 + fr.readAsBinaryString(blobData);
  115 +};
  116 +
  117 +function endBlobData(){
  118 + chrome.runtime.sendMessage({
  119 + data: '',
  120 + size: 0,
  121 + mimeType: '',
  122 + name: '',
  123 + action: 'end'
  124 + }, response => {
  125 + // console.log("Response: ", response);
  126 + });
  127 +};
  128 +
  129 +function stopRecorder(recorder){
  130 + if(recorder.state === 'recording'){
  131 + recorder.stop();
  132 + }
  133 +};
  134 +
... ...
icon.png 0 → 100644

23 KB

lib/ffmpeg.min.js 0 → 100644
  1 +++ a/lib/ffmpeg.min.js
  1 +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FFmpeg=t():e.FFmpeg=t()}(self,(function(){return e={497:(e,t,r)=>{var n=r(72),o=r(306).devDependencies;e.exports={corePath:"undefined"!=typeof process&&"development"===process.env.FFMPEG_ENV?n("/node_modules/@ffmpeg/core/dist/ffmpeg-core.js"):"https://unpkg.com/@ffmpeg/core@".concat(o["@ffmpeg/core"].substring(1),"/dist/ffmpeg-core.js")}},663:(e,t,r)=>{function n(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}var o=r(72),i=function(e){return new Promise((function(t,r){var n=new FileReader;n.onload=function(){t(n.result)},n.onerror=function(e){var t=e.target.error.code;r(Error("File could not be read! Code=".concat(t)))},n.readAsArrayBuffer(e)}))};e.exports=function(){var e,t=(e=regeneratorRuntime.mark((function e(t){var r,n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t,void 0!==t){e.next=3;break}return e.abrupt("return",new Uint8Array);case 3:if("string"!=typeof t){e.next=16;break}if(!/data:_data\/([a-zA-Z]*);base64,([^"]*)/.test(t)){e.next=8;break}r=atob(t.split(",")[1]).split("").map((function(e){return e.charCodeAt(0)})),e.next=14;break;case 8:return e.next=10,fetch(o(t));case 10:return n=e.sent,e.next=13,n.arrayBuffer();case 13:r=e.sent;case 14:e.next=20;break;case 16:if(!(t instanceof File||t instanceof Blob)){e.next=20;break}return e.next=19,i(t);case 19:r=e.sent;case 20:return e.abrupt("return",new Uint8Array(r));case 21:case"end":return e.stop()}}),e)})),function(){var t=this,r=arguments;return new Promise((function(o,i){var a=e.apply(t,r);function c(e){n(a,o,i,c,s,"next",e)}function s(e){n(a,o,i,c,s,"throw",e)}c(void 0)}))});return function(e){return t.apply(this,arguments)}}()},452:(e,t,r)=>{function n(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}function o(e){return function(){var t=this,r=arguments;return new Promise((function(o,i){var a=e.apply(t,r);function c(e){n(a,o,i,c,s,"next",e)}function s(e){n(a,o,i,c,s,"throw",e)}c(void 0)}))}}var i=r(72),a=r(185).log,c=function(){var e=o(regeneratorRuntime.mark((function e(t,r){var n,o,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a("info","fetch ".concat(t)),e.next=3,fetch(t);case 3:return e.next=5,e.sent.arrayBuffer();case 5:return n=e.sent,a("info","".concat(t," file size = ").concat(n.byteLength," bytes")),o=new Blob([n],{type:r}),i=URL.createObjectURL(o),a("info","".concat(t," blob URL = ").concat(i)),e.abrupt("return",i);case 11:case"end":return e.stop()}}),e)})));return function(t,r){return e.apply(this,arguments)}}();e.exports=function(){var e=o(regeneratorRuntime.mark((function e(t){var r,n,o,s,u;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("string"==typeof(r=t.corePath)){e.next=3;break}throw Error("corePath should be a string!");case 3:return n=i(r),e.next=6,c(n,"application/javascript");case 6:return o=e.sent,e.next=9,c(n.replace("ffmpeg-core.js","ffmpeg-core.wasm"),"application/wasm");case 9:return s=e.sent,e.next=12,c(n.replace("ffmpeg-core.js","ffmpeg-core.worker.js"),"application/javascript");case 12:if(u=e.sent,"undefined"!=typeof createFFmpegCore){e.next=15;break}return e.abrupt("return",new Promise((function(e){var t=document.createElement("script");t.src=o,t.type="text/javascript",t.addEventListener("load",(function r(){t.removeEventListener("load",r),a("info","ffmpeg-core.js script loaded"),e({createFFmpegCore,corePath:o,wasmPath:s,workerPath:u})})),document.getElementsByTagName("head")[0].appendChild(t)})));case 15:return a("info","ffmpeg-core.js script is loaded already"),e.abrupt("return",Promise.resolve({createFFmpegCore,corePath:o,wasmPath:s,workerPath:u}));case 17:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()},698:(e,t,r)=>{var n=r(497),o=r(452),i=r(663);e.exports={defaultOptions:n,getCreateFFmpegCore:o,fetchFile:i}},500:e=>{e.exports={defaultArgs:["./ffmpeg","-nostdin","-y"],baseOptions:{log:!1,logger:function(){},progress:function(){},corePath:""}}},906:(e,t,r)=>{function n(e){return function(e){if(Array.isArray(e))return o(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return o(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function i(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}function a(e){return function(){var t=this,r=arguments;return new Promise((function(n,o){var a=e.apply(t,r);function c(e){i(a,n,o,c,s,"next",e)}function s(e){i(a,n,o,c,s,"throw",e)}c(void 0)}))}}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?c(Object(r),!0).forEach((function(t){u(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function u(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function f(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=r(500),p=l.defaultArgs,h=l.baseOptions,m=r(185),g=m.setLogging,d=m.setCustomLogger,y=m.log,v=r(583),b=r(319),w=r(698),x=w.defaultOptions,j=w.getCreateFFmpegCore,E=r(306).version,F=Error("ffmpeg.wasm is not ready, make sure you have completed load().");e.exports=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=s(s(s({},h),x),e),r=t.log,o=t.logger,i=t.progress,c=f(t,["log","logger","progress"]),u=null,l=null,m=null,w=!1,O=i,P=function(e){"FFMPEG_END"===e&&null!==m&&(m(),m=null,w=!1)},L=function(e){var t=e.type,r=e.message;y(t,r),v(r,O),P(r)},k=function(){var e=a(regeneratorRuntime.mark((function e(){var t,r,n,o,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(y("info","load ffmpeg-core"),null!==u){e.next=17;break}return y("info","loading ffmpeg-core"),e.next=5,j(c);case 5:return t=e.sent,r=t.createFFmpegCore,n=t.corePath,o=t.workerPath,i=t.wasmPath,e.next=12,r({mainScriptUrlOrBlob:n,printErr:function(e){return L({type:"fferr",message:e})},print:function(e){return L({type:"ffout",message:e})},locateFile:function(e,t){if("undefined"!=typeof window){if(void 0!==i&&e.endsWith("ffmpeg-core.wasm"))return i;if(void 0!==o&&e.endsWith("ffmpeg-core.worker.js"))return o}return t+e}});case 12:u=e.sent,l=u.cwrap("proxy_main","number",["number","number"]),y("info","ffmpeg-core loaded"),e.next=18;break;case 17:throw Error("ffmpeg.wasm was loaded, you should not load it again, use ffmpeg.isLoaded() to check next time.");case 18:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),S=function(){return null!==u},A=function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];if(y("info","run ffmpeg command: ".concat(t.join(" "))),null===u)throw F;if(w)throw Error("ffmpeg.wasm can only run one command at a time");return w=!0,new Promise((function(e){var r=[].concat(n(p),t).filter((function(e){return 0!==e.length}));m=e,l.apply(void 0,n(b(u,r)))}))},_=function(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];if(y("info","run FS.".concat(e," ").concat(r.map((function(e){return"string"==typeof e?e:"<".concat(e.length," bytes binary file>")})).join(" "))),null===u)throw F;var o=null;try{var i;o=(i=u.FS)[e].apply(i,r)}catch(t){throw"readdir"===e?Error("ffmpeg.FS('readdir', '".concat(r[0],"') error. Check if the path exists, ex: ffmpeg.FS('readdir', '/')")):"readFile"===e?Error("ffmpeg.FS('readFile', '".concat(r[0],"') error. Check if the path exists")):Error("Oops, something went wrong in FS operation.")}return o},C=function(){if(null===u)throw F;w=!1,u.exit(1),u=null,l=null,m=null},R=function(e){O=e},N=function(e){d(e)};return g(r),d(o),y("info","use ffmpeg.wasm v".concat(E)),{setProgress:R,setLogger:N,setLogging:g,load:k,isLoaded:S,run:A,exit:C,FS:_}}},352:(e,t,r)=>{r(666);var n=r(906),o=r(698).fetchFile;e.exports={createFFmpeg:n,fetchFile:o}},185:e=>{var t=!1,r=function(){};e.exports={logging:t,setLogging:function(e){t=e},setCustomLogger:function(e){r=e},log:function(e,n){r({type:e,message:n}),t&&console.log("[".concat(e,"] ").concat(n))}}},319:e=>{e.exports=function(e,t){var r=e._malloc(t.length*Uint32Array.BYTES_PER_ELEMENT);return t.forEach((function(t,n){var o=e._malloc(t.length+1);e.writeAsciiToMemory(t,o),e.setValue(r+Uint32Array.BYTES_PER_ELEMENT*n,o,"i32")})),[t.length,r]}},583:e=>{function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var r=0,n=0,o=function(e){var r,n,o=(r=e.split(":"),n=3,function(e){if(Array.isArray(e))return e}(r)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var r=[],n=!0,o=!1,i=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{n||null==c.return||c.return()}finally{if(o)throw i}}return r}}(r,n)||function(e,r){if(e){if("string"==typeof e)return t(e,r);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(e,r):void 0}}(r,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),i=o[0],a=o[1],c=o[2];return 60*parseFloat(i)*60+60*parseFloat(a)+parseFloat(c)};e.exports=function(e,t){if("string"==typeof e)if(e.startsWith(" Duration")){var i=e.split(", ")[0].split(": ")[1],a=o(i);t({duration:a,ratio:n}),(0===r||r>a)&&(r=a)}else if(e.startsWith("frame")||e.startsWith("size")){var c=e.split("time=")[1].split(" ")[0],s=o(c);t({ratio:n=s/r,time:s})}else e.startsWith("video:")&&(t({ratio:1}),r=0)}},666:e=>{var t=function(e){"use strict";var t,r=Object.prototype,n=r.hasOwnProperty,o="function"==typeof Symbol?Symbol:{},i=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function s(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{s({},"")}catch(e){s=function(e,t,r){return e[t]=r}}function u(e,t,r,n){var o=t&&t.prototype instanceof d?t:d,i=Object.create(o.prototype),a=new k(n||[]);return i._invoke=function(e,t,r){var n=l;return function(o,i){if(n===h)throw new Error("Generator is already running");if(n===m){if("throw"===o)throw i;return A()}for(r.method=o,r.arg=i;;){var a=r.delegate;if(a){var c=O(a,r);if(c){if(c===g)continue;return c}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(n===l)throw n=m,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n=h;var s=f(e,t,r);if("normal"===s.type){if(n=r.done?m:p,s.arg===g)continue;return{value:s.arg,done:r.done}}"throw"===s.type&&(n=m,r.method="throw",r.arg=s.arg)}}}(e,r,a),i}function f(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}e.wrap=u;var l="suspendedStart",p="suspendedYield",h="executing",m="completed",g={};function d(){}function y(){}function v(){}var b={};b[i]=function(){return this};var w=Object.getPrototypeOf,x=w&&w(w(S([])));x&&x!==r&&n.call(x,i)&&(b=x);var j=v.prototype=d.prototype=Object.create(b);function E(e){["next","throw","return"].forEach((function(t){s(e,t,(function(e){return this._invoke(t,e)}))}))}function F(e,t){function r(o,i,a,c){var s=f(e[o],e,i);if("throw"!==s.type){var u=s.arg,l=u.value;return l&&"object"==typeof l&&n.call(l,"__await")?t.resolve(l.__await).then((function(e){r("next",e,a,c)}),(function(e){r("throw",e,a,c)})):t.resolve(l).then((function(e){u.value=e,a(u)}),(function(e){return r("throw",e,a,c)}))}c(s.arg)}var o;this._invoke=function(e,n){function i(){return new t((function(t,o){r(e,n,t,o)}))}return o=o?o.then(i,i):i()}}function O(e,r){var n=e.iterator[r.method];if(n===t){if(r.delegate=null,"throw"===r.method){if(e.iterator.return&&(r.method="return",r.arg=t,O(e,r),"throw"===r.method))return g;r.method="throw",r.arg=new TypeError("The iterator does not provide a 'throw' method")}return g}var o=f(n,e.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,g;var i=o.arg;return i?i.done?(r[e.resultName]=i.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,g):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,g)}function P(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function L(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(P,this),this.reset(!0)}function S(e){if(e){var r=e[i];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,a=function r(){for(;++o<e.length;)if(n.call(e,o))return r.value=e[o],r.done=!1,r;return r.value=t,r.done=!0,r};return a.next=a}}return{next:A}}function A(){return{value:t,done:!0}}return y.prototype=j.constructor=v,v.constructor=y,y.displayName=s(v,c,"GeneratorFunction"),e.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===y||"GeneratorFunction"===(t.displayName||t.name))},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,v):(e.__proto__=v,s(e,c,"GeneratorFunction")),e.prototype=Object.create(j),e},e.awrap=function(e){return{__await:e}},E(F.prototype),F.prototype[a]=function(){return this},e.AsyncIterator=F,e.async=function(t,r,n,o,i){void 0===i&&(i=Promise);var a=new F(u(t,r,n,o),i);return e.isGeneratorFunction(r)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},E(j),s(j,c,"Generator"),j[i]=function(){return this},j.toString=function(){return"[object Generator]"},e.keys=function(e){var t=[];for(var r in e)t.push(r);return t.reverse(),function r(){for(;t.length;){var n=t.pop();if(n in e)return r.value=n,r.done=!1,r}return r.done=!0,r}},e.values=S,k.prototype={constructor:k,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(L),!e)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=t)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var r=this;function o(n,o){return c.type="throw",c.arg=e,r.next=n,o&&(r.method="next",r.arg=t),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],c=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var s=n.call(a,"catchLoc"),u=n.call(a,"finallyLoc");if(s&&u){if(this.prev<a.catchLoc)return o(a.catchLoc,!0);if(this.prev<a.finallyLoc)return o(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return o(a.catchLoc,!0)}else{if(!u)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return o(a.finallyLoc)}}}},abrupt:function(e,t){for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,g):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),g},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),L(r),g}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;L(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:S(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),g}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},72:function(e,t,r){var n,o;void 0===(o="function"==typeof(n=function(){return function(){var e=arguments.length;if(0===e)throw new Error("resolveUrl requires at least one argument; got none.");var t=document.createElement("base");if(t.href=arguments[0],1===e)return t.href;var r=document.getElementsByTagName("head")[0];r.insertBefore(t,r.firstChild);for(var n,o=document.createElement("a"),i=1;i<e;i++)o.href=arguments[i],n=o.href,t.href=n;return r.removeChild(t),n}})?n.call(t,r,t,e):n)||(e.exports=o)},306:e=>{"use strict";e.exports=JSON.parse('{"name":"@ffmpeg/ffmpeg","version":"0.10.0","description":"FFmpeg WebAssembly version","main":"src/index.js","types":"src/index.d.ts","directories":{"example":"examples"},"scripts":{"start":"node scripts/server.js","build":"rimraf dist && webpack --config scripts/webpack.config.prod.js","prepublishOnly":"npm run build","lint":"eslint src","wait":"rimraf dist && wait-on http://localhost:3000/dist/ffmpeg.dev.js","test":"npm-run-all -p -r start test:all","test:all":"npm-run-all wait test:browser:ffmpeg test:node:all","test:node":"node --experimental-wasm-threads --experimental-wasm-bulk-memory node_modules/.bin/_mocha --exit --bail --require ./scripts/test-helper.js","test:node:all":"npm run test:node -- ./tests/*.test.js","test:browser":"mocha-headless-chrome -a allow-file-access-from-files -a incognito -a no-sandbox -a disable-setuid-sandbox -a disable-logging -t 300000","test:browser:ffmpeg":"npm run test:browser -- -f ./tests/ffmpeg.test.html"},"browser":{"./src/node/index.js":"./src/browser/index.js"},"repository":{"type":"git","url":"git+https://github.com/ffmpegwasm/ffmpeg.wasm.git"},"keywords":["ffmpeg","WebAssembly","video"],"author":"Jerome Wu <jeromewus@gmail.com>","license":"MIT","bugs":{"url":"https://github.com/ffmpegwasm/ffmpeg.wasm/issues"},"engines":{"node":">=12.16.1"},"homepage":"https://github.com/ffmpegwasm/ffmpeg.wasm#readme","dependencies":{"is-url":"^1.2.4","node-fetch":"^2.6.1","regenerator-runtime":"^0.13.7","resolve-url":"^0.2.1"},"devDependencies":{"@babel/core":"^7.12.3","@babel/preset-env":"^7.12.1","@ffmpeg/core":"^0.10.0","@types/emscripten":"^1.39.4","babel-loader":"^8.1.0","chai":"^4.2.0","cors":"^2.8.5","eslint":"^7.12.1","eslint-config-airbnb-base":"^14.1.0","eslint-plugin-import":"^2.22.1","express":"^4.17.1","mocha":"^8.2.1","mocha-headless-chrome":"^2.0.3","npm-run-all":"^4.1.5","wait-on":"^5.3.0","webpack":"^5.3.2","webpack-cli":"^4.1.0","webpack-dev-middleware":"^4.0.0"}}')}},t={},function r(n){if(t[n])return t[n].exports;var o=t[n]={exports:{}};return e[n].call(o.exports,o,o.exports,r),o.exports}(352);var e,t}));
  2 +//# sourceMappingURL=ffmpeg.min.js.map
0 3 \ No newline at end of file
... ...
lib/jquery-1.12.1.js 0 → 100644
  1 +++ a/lib/jquery-1.12.1.js
  1 +/*!
  2 + * jQuery JavaScript Library v1.12.1
  3 + * http://jquery.com/
  4 + *
  5 + * Includes Sizzle.js
  6 + * http://sizzlejs.com/
  7 + *
  8 + * Copyright jQuery Foundation and other contributors
  9 + * Released under the MIT license
  10 + * http://jquery.org/license
  11 + *
  12 + * Date: 2016-02-22T19:07Z
  13 + */
  14 +
  15 +(function( global, factory ) {
  16 +
  17 + if ( typeof module === "object" && typeof module.exports === "object" ) {
  18 + // For CommonJS and CommonJS-like environments where a proper `window`
  19 + // is present, execute the factory and get jQuery.
  20 + // For environments that do not have a `window` with a `document`
  21 + // (such as Node.js), expose a factory as module.exports.
  22 + // This accentuates the need for the creation of a real `window`.
  23 + // e.g. var jQuery = require("jquery")(window);
  24 + // See ticket #14549 for more info.
  25 + module.exports = global.document ?
  26 + factory( global, true ) :
  27 + function( w ) {
  28 + if ( !w.document ) {
  29 + throw new Error( "jQuery requires a window with a document" );
  30 + }
  31 + return factory( w );
  32 + };
  33 + } else {
  34 + factory( global );
  35 + }
  36 +
  37 +// Pass this if window is not defined yet
  38 +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
  39 +
  40 +// Support: Firefox 18+
  41 +// Can't be in strict mode, several libs including ASP.NET trace
  42 +// the stack via arguments.caller.callee and Firefox dies if
  43 +// you try to trace through "use strict" call chains. (#13335)
  44 +//"use strict";
  45 +var deletedIds = [];
  46 +
  47 +var document = window.document;
  48 +
  49 +var slice = deletedIds.slice;
  50 +
  51 +var concat = deletedIds.concat;
  52 +
  53 +var push = deletedIds.push;
  54 +
  55 +var indexOf = deletedIds.indexOf;
  56 +
  57 +var class2type = {};
  58 +
  59 +var toString = class2type.toString;
  60 +
  61 +var hasOwn = class2type.hasOwnProperty;
  62 +
  63 +var support = {};
  64 +
  65 +
  66 +
  67 +var
  68 + version = "1.12.1",
  69 +
  70 + // Define a local copy of jQuery
  71 + jQuery = function( selector, context ) {
  72 +
  73 + // The jQuery object is actually just the init constructor 'enhanced'
  74 + // Need init if jQuery is called (just allow error to be thrown if not included)
  75 + return new jQuery.fn.init( selector, context );
  76 + },
  77 +
  78 + // Support: Android<4.1, IE<9
  79 + // Make sure we trim BOM and NBSP
  80 + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  81 +
  82 + // Matches dashed string for camelizing
  83 + rmsPrefix = /^-ms-/,
  84 + rdashAlpha = /-([\da-z])/gi,
  85 +
  86 + // Used by jQuery.camelCase as callback to replace()
  87 + fcamelCase = function( all, letter ) {
  88 + return letter.toUpperCase();
  89 + };
  90 +
  91 +jQuery.fn = jQuery.prototype = {
  92 +
  93 + // The current version of jQuery being used
  94 + jquery: version,
  95 +
  96 + constructor: jQuery,
  97 +
  98 + // Start with an empty selector
  99 + selector: "",
  100 +
  101 + // The default length of a jQuery object is 0
  102 + length: 0,
  103 +
  104 + toArray: function() {
  105 + return slice.call( this );
  106 + },
  107 +
  108 + // Get the Nth element in the matched element set OR
  109 + // Get the whole matched element set as a clean array
  110 + get: function( num ) {
  111 + return num != null ?
  112 +
  113 + // Return just the one element from the set
  114 + ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
  115 +
  116 + // Return all the elements in a clean array
  117 + slice.call( this );
  118 + },
  119 +
  120 + // Take an array of elements and push it onto the stack
  121 + // (returning the new matched element set)
  122 + pushStack: function( elems ) {
  123 +
  124 + // Build a new jQuery matched element set
  125 + var ret = jQuery.merge( this.constructor(), elems );
  126 +
  127 + // Add the old object onto the stack (as a reference)
  128 + ret.prevObject = this;
  129 + ret.context = this.context;
  130 +
  131 + // Return the newly-formed element set
  132 + return ret;
  133 + },
  134 +
  135 + // Execute a callback for every element in the matched set.
  136 + each: function( callback ) {
  137 + return jQuery.each( this, callback );
  138 + },
  139 +
  140 + map: function( callback ) {
  141 + return this.pushStack( jQuery.map( this, function( elem, i ) {
  142 + return callback.call( elem, i, elem );
  143 + } ) );
  144 + },
  145 +
  146 + slice: function() {
  147 + return this.pushStack( slice.apply( this, arguments ) );
  148 + },
  149 +
  150 + first: function() {
  151 + return this.eq( 0 );
  152 + },
  153 +
  154 + last: function() {
  155 + return this.eq( -1 );
  156 + },
  157 +
  158 + eq: function( i ) {
  159 + var len = this.length,
  160 + j = +i + ( i < 0 ? len : 0 );
  161 + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
  162 + },
  163 +
  164 + end: function() {
  165 + return this.prevObject || this.constructor();
  166 + },
  167 +
  168 + // For internal use only.
  169 + // Behaves like an Array's method, not like a jQuery method.
  170 + push: push,
  171 + sort: deletedIds.sort,
  172 + splice: deletedIds.splice
  173 +};
  174 +
  175 +jQuery.extend = jQuery.fn.extend = function() {
  176 + var src, copyIsArray, copy, name, options, clone,
  177 + target = arguments[ 0 ] || {},
  178 + i = 1,
  179 + length = arguments.length,
  180 + deep = false;
  181 +
  182 + // Handle a deep copy situation
  183 + if ( typeof target === "boolean" ) {
  184 + deep = target;
  185 +
  186 + // skip the boolean and the target
  187 + target = arguments[ i ] || {};
  188 + i++;
  189 + }
  190 +
  191 + // Handle case when target is a string or something (possible in deep copy)
  192 + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
  193 + target = {};
  194 + }
  195 +
  196 + // extend jQuery itself if only one argument is passed
  197 + if ( i === length ) {
  198 + target = this;
  199 + i--;
  200 + }
  201 +
  202 + for ( ; i < length; i++ ) {
  203 +
  204 + // Only deal with non-null/undefined values
  205 + if ( ( options = arguments[ i ] ) != null ) {
  206 +
  207 + // Extend the base object
  208 + for ( name in options ) {
  209 + src = target[ name ];
  210 + copy = options[ name ];
  211 +
  212 + // Prevent never-ending loop
  213 + if ( target === copy ) {
  214 + continue;
  215 + }
  216 +
  217 + // Recurse if we're merging plain objects or arrays
  218 + if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
  219 + ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
  220 +
  221 + if ( copyIsArray ) {
  222 + copyIsArray = false;
  223 + clone = src && jQuery.isArray( src ) ? src : [];
  224 +
  225 + } else {
  226 + clone = src && jQuery.isPlainObject( src ) ? src : {};
  227 + }
  228 +
  229 + // Never move original objects, clone them
  230 + target[ name ] = jQuery.extend( deep, clone, copy );
  231 +
  232 + // Don't bring in undefined values
  233 + } else if ( copy !== undefined ) {
  234 + target[ name ] = copy;
  235 + }
  236 + }
  237 + }
  238 + }
  239 +
  240 + // Return the modified object
  241 + return target;
  242 +};
  243 +
  244 +jQuery.extend( {
  245 +
  246 + // Unique for each copy of jQuery on the page
  247 + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
  248 +
  249 + // Assume jQuery is ready without the ready module
  250 + isReady: true,
  251 +
  252 + error: function( msg ) {
  253 + throw new Error( msg );
  254 + },
  255 +
  256 + noop: function() {},
  257 +
  258 + // See test/unit/core.js for details concerning isFunction.
  259 + // Since version 1.3, DOM methods and functions like alert
  260 + // aren't supported. They return false on IE (#2968).
  261 + isFunction: function( obj ) {
  262 + return jQuery.type( obj ) === "function";
  263 + },
  264 +
  265 + isArray: Array.isArray || function( obj ) {
  266 + return jQuery.type( obj ) === "array";
  267 + },
  268 +
  269 + isWindow: function( obj ) {
  270 + /* jshint eqeqeq: false */
  271 + return obj != null && obj == obj.window;
  272 + },
  273 +
  274 + isNumeric: function( obj ) {
  275 +
  276 + // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  277 + // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  278 + // subtraction forces infinities to NaN
  279 + // adding 1 corrects loss of precision from parseFloat (#15100)
  280 + var realStringObj = obj && obj.toString();
  281 + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
  282 + },
  283 +
  284 + isEmptyObject: function( obj ) {
  285 + var name;
  286 + for ( name in obj ) {
  287 + return false;
  288 + }
  289 + return true;
  290 + },
  291 +
  292 + isPlainObject: function( obj ) {
  293 + var key;
  294 +
  295 + // Must be an Object.
  296 + // Because of IE, we also have to check the presence of the constructor property.
  297 + // Make sure that DOM nodes and window objects don't pass through, as well
  298 + if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  299 + return false;
  300 + }
  301 +
  302 + try {
  303 +
  304 + // Not own constructor property must be Object
  305 + if ( obj.constructor &&
  306 + !hasOwn.call( obj, "constructor" ) &&
  307 + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
  308 + return false;
  309 + }
  310 + } catch ( e ) {
  311 +
  312 + // IE8,9 Will throw exceptions on certain host objects #9897
  313 + return false;
  314 + }
  315 +
  316 + // Support: IE<9
  317 + // Handle iteration over inherited properties before own properties.
  318 + if ( !support.ownFirst ) {
  319 + for ( key in obj ) {
  320 + return hasOwn.call( obj, key );
  321 + }
  322 + }
  323 +
  324 + // Own properties are enumerated firstly, so to speed up,
  325 + // if last one is own, then all properties are own.
  326 + for ( key in obj ) {}
  327 +
  328 + return key === undefined || hasOwn.call( obj, key );
  329 + },
  330 +
  331 + type: function( obj ) {
  332 + if ( obj == null ) {
  333 + return obj + "";
  334 + }
  335 + return typeof obj === "object" || typeof obj === "function" ?
  336 + class2type[ toString.call( obj ) ] || "object" :
  337 + typeof obj;
  338 + },
  339 +
  340 + // Workarounds based on findings by Jim Driscoll
  341 + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
  342 + globalEval: function( data ) {
  343 + if ( data && jQuery.trim( data ) ) {
  344 +
  345 + // We use execScript on Internet Explorer
  346 + // We use an anonymous function so that context is window
  347 + // rather than jQuery in Firefox
  348 + ( window.execScript || function( data ) {
  349 + window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
  350 + } )( data );
  351 + }
  352 + },
  353 +
  354 + // Convert dashed to camelCase; used by the css and data modules
  355 + // Microsoft forgot to hump their vendor prefix (#9572)
  356 + camelCase: function( string ) {
  357 + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  358 + },
  359 +
  360 + nodeName: function( elem, name ) {
  361 + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  362 + },
  363 +
  364 + each: function( obj, callback ) {
  365 + var length, i = 0;
  366 +
  367 + if ( isArrayLike( obj ) ) {
  368 + length = obj.length;
  369 + for ( ; i < length; i++ ) {
  370 + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  371 + break;
  372 + }
  373 + }
  374 + } else {
  375 + for ( i in obj ) {
  376 + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  377 + break;
  378 + }
  379 + }
  380 + }
  381 +
  382 + return obj;
  383 + },
  384 +
  385 + // Support: Android<4.1, IE<9
  386 + trim: function( text ) {
  387 + return text == null ?
  388 + "" :
  389 + ( text + "" ).replace( rtrim, "" );
  390 + },
  391 +
  392 + // results is for internal usage only
  393 + makeArray: function( arr, results ) {
  394 + var ret = results || [];
  395 +
  396 + if ( arr != null ) {
  397 + if ( isArrayLike( Object( arr ) ) ) {
  398 + jQuery.merge( ret,
  399 + typeof arr === "string" ?
  400 + [ arr ] : arr
  401 + );
  402 + } else {
  403 + push.call( ret, arr );
  404 + }
  405 + }
  406 +
  407 + return ret;
  408 + },
  409 +
  410 + inArray: function( elem, arr, i ) {
  411 + var len;
  412 +
  413 + if ( arr ) {
  414 + if ( indexOf ) {
  415 + return indexOf.call( arr, elem, i );
  416 + }
  417 +
  418 + len = arr.length;
  419 + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
  420 +
  421 + for ( ; i < len; i++ ) {
  422 +
  423 + // Skip accessing in sparse arrays
  424 + if ( i in arr && arr[ i ] === elem ) {
  425 + return i;
  426 + }
  427 + }
  428 + }
  429 +
  430 + return -1;
  431 + },
  432 +
  433 + merge: function( first, second ) {
  434 + var len = +second.length,
  435 + j = 0,
  436 + i = first.length;
  437 +
  438 + while ( j < len ) {
  439 + first[ i++ ] = second[ j++ ];
  440 + }
  441 +
  442 + // Support: IE<9
  443 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
  444 + if ( len !== len ) {
  445 + while ( second[ j ] !== undefined ) {
  446 + first[ i++ ] = second[ j++ ];
  447 + }
  448 + }
  449 +
  450 + first.length = i;
  451 +
  452 + return first;
  453 + },
  454 +
  455 + grep: function( elems, callback, invert ) {
  456 + var callbackInverse,
  457 + matches = [],
  458 + i = 0,
  459 + length = elems.length,
  460 + callbackExpect = !invert;
  461 +
  462 + // Go through the array, only saving the items
  463 + // that pass the validator function
  464 + for ( ; i < length; i++ ) {
  465 + callbackInverse = !callback( elems[ i ], i );
  466 + if ( callbackInverse !== callbackExpect ) {
  467 + matches.push( elems[ i ] );
  468 + }
  469 + }
  470 +
  471 + return matches;
  472 + },
  473 +
  474 + // arg is for internal usage only
  475 + map: function( elems, callback, arg ) {
  476 + var length, value,
  477 + i = 0,
  478 + ret = [];
  479 +
  480 + // Go through the array, translating each of the items to their new values
  481 + if ( isArrayLike( elems ) ) {
  482 + length = elems.length;
  483 + for ( ; i < length; i++ ) {
  484 + value = callback( elems[ i ], i, arg );
  485 +
  486 + if ( value != null ) {
  487 + ret.push( value );
  488 + }
  489 + }
  490 +
  491 + // Go through every key on the object,
  492 + } else {
  493 + for ( i in elems ) {
  494 + value = callback( elems[ i ], i, arg );
  495 +
  496 + if ( value != null ) {
  497 + ret.push( value );
  498 + }
  499 + }
  500 + }
  501 +
  502 + // Flatten any nested arrays
  503 + return concat.apply( [], ret );
  504 + },
  505 +
  506 + // A global GUID counter for objects
  507 + guid: 1,
  508 +
  509 + // Bind a function to a context, optionally partially applying any
  510 + // arguments.
  511 + proxy: function( fn, context ) {
  512 + var args, proxy, tmp;
  513 +
  514 + if ( typeof context === "string" ) {
  515 + tmp = fn[ context ];
  516 + context = fn;
  517 + fn = tmp;
  518 + }
  519 +
  520 + // Quick check to determine if target is callable, in the spec
  521 + // this throws a TypeError, but we will just return undefined.
  522 + if ( !jQuery.isFunction( fn ) ) {
  523 + return undefined;
  524 + }
  525 +
  526 + // Simulated bind
  527 + args = slice.call( arguments, 2 );
  528 + proxy = function() {
  529 + return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
  530 + };
  531 +
  532 + // Set the guid of unique handler to the same of original handler, so it can be removed
  533 + proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  534 +
  535 + return proxy;
  536 + },
  537 +
  538 + now: function() {
  539 + return +( new Date() );
  540 + },
  541 +
  542 + // jQuery.support is not used in Core but other projects attach their
  543 + // properties to it so it needs to exist.
  544 + support: support
  545 +} );
  546 +
  547 +// JSHint would error on this code due to the Symbol not being defined in ES5.
  548 +// Defining this global in .jshintrc would create a danger of using the global
  549 +// unguarded in another place, it seems safer to just disable JSHint for these
  550 +// three lines.
  551 +/* jshint ignore: start */
  552 +if ( typeof Symbol === "function" ) {
  553 + jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
  554 +}
  555 +/* jshint ignore: end */
  556 +
  557 +// Populate the class2type map
  558 +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
  559 +function( i, name ) {
  560 + class2type[ "[object " + name + "]" ] = name.toLowerCase();
  561 +} );
  562 +
  563 +function isArrayLike( obj ) {
  564 +
  565 + // Support: iOS 8.2 (not reproducible in simulator)
  566 + // `in` check used to prevent JIT error (gh-2145)
  567 + // hasOwn isn't used here due to false negatives
  568 + // regarding Nodelist length in IE
  569 + var length = !!obj && "length" in obj && obj.length,
  570 + type = jQuery.type( obj );
  571 +
  572 + if ( type === "function" || jQuery.isWindow( obj ) ) {
  573 + return false;
  574 + }
  575 +
  576 + return type === "array" || length === 0 ||
  577 + typeof length === "number" && length > 0 && ( length - 1 ) in obj;
  578 +}
  579 +var Sizzle =
  580 +/*!
  581 + * Sizzle CSS Selector Engine v2.2.1
  582 + * http://sizzlejs.com/
  583 + *
  584 + * Copyright jQuery Foundation and other contributors
  585 + * Released under the MIT license
  586 + * http://jquery.org/license
  587 + *
  588 + * Date: 2015-10-17
  589 + */
  590 +(function( window ) {
  591 +
  592 +var i,
  593 + support,
  594 + Expr,
  595 + getText,
  596 + isXML,
  597 + tokenize,
  598 + compile,
  599 + select,
  600 + outermostContext,
  601 + sortInput,
  602 + hasDuplicate,
  603 +
  604 + // Local document vars
  605 + setDocument,
  606 + document,
  607 + docElem,
  608 + documentIsHTML,
  609 + rbuggyQSA,
  610 + rbuggyMatches,
  611 + matches,
  612 + contains,
  613 +
  614 + // Instance-specific data
  615 + expando = "sizzle" + 1 * new Date(),
  616 + preferredDoc = window.document,
  617 + dirruns = 0,
  618 + done = 0,
  619 + classCache = createCache(),
  620 + tokenCache = createCache(),
  621 + compilerCache = createCache(),
  622 + sortOrder = function( a, b ) {
  623 + if ( a === b ) {
  624 + hasDuplicate = true;
  625 + }
  626 + return 0;
  627 + },
  628 +
  629 + // General-purpose constants
  630 + MAX_NEGATIVE = 1 << 31,
  631 +
  632 + // Instance methods
  633 + hasOwn = ({}).hasOwnProperty,
  634 + arr = [],
  635 + pop = arr.pop,
  636 + push_native = arr.push,
  637 + push = arr.push,
  638 + slice = arr.slice,
  639 + // Use a stripped-down indexOf as it's faster than native
  640 + // http://jsperf.com/thor-indexof-vs-for/5
  641 + indexOf = function( list, elem ) {
  642 + var i = 0,
  643 + len = list.length;
  644 + for ( ; i < len; i++ ) {
  645 + if ( list[i] === elem ) {
  646 + return i;
  647 + }
  648 + }
  649 + return -1;
  650 + },
  651 +
  652 + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
  653 +
  654 + // Regular expressions
  655 +
  656 + // http://www.w3.org/TR/css3-selectors/#whitespace
  657 + whitespace = "[\\x20\\t\\r\\n\\f]",
  658 +
  659 + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
  660 + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
  661 +
  662 + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
  663 + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
  664 + // Operator (capture 2)
  665 + "*([*^$|!~]?=)" + whitespace +
  666 + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
  667 + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
  668 + "*\\]",
  669 +
  670 + pseudos = ":(" + identifier + ")(?:\\((" +
  671 + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
  672 + // 1. quoted (capture 3; capture 4 or capture 5)
  673 + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
  674 + // 2. simple (capture 6)
  675 + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
  676 + // 3. anything else (capture 2)
  677 + ".*" +
  678 + ")\\)|)",
  679 +
  680 + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  681 + rwhitespace = new RegExp( whitespace + "+", "g" ),
  682 + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
  683 +
  684 + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  685 + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
  686 +
  687 + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
  688 +
  689 + rpseudo = new RegExp( pseudos ),
  690 + ridentifier = new RegExp( "^" + identifier + "$" ),
  691 +
  692 + matchExpr = {
  693 + "ID": new RegExp( "^#(" + identifier + ")" ),
  694 + "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
  695 + "TAG": new RegExp( "^(" + identifier + "|[*])" ),
  696 + "ATTR": new RegExp( "^" + attributes ),
  697 + "PSEUDO": new RegExp( "^" + pseudos ),
  698 + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
  699 + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
  700 + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  701 + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  702 + // For use in libraries implementing .is()
  703 + // We use this for POS matching in `select`
  704 + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
  705 + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  706 + },
  707 +
  708 + rinputs = /^(?:input|select|textarea|button)$/i,
  709 + rheader = /^h\d$/i,
  710 +
  711 + rnative = /^[^{]+\{\s*\[native \w/,
  712 +
  713 + // Easily-parseable/retrievable ID or TAG or CLASS selectors
  714 + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  715 +
  716 + rsibling = /[+~]/,
  717 + rescape = /'|\\/g,
  718 +
  719 + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  720 + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
  721 + funescape = function( _, escaped, escapedWhitespace ) {
  722 + var high = "0x" + escaped - 0x10000;
  723 + // NaN means non-codepoint
  724 + // Support: Firefox<24
  725 + // Workaround erroneous numeric interpretation of +"0x"
  726 + return high !== high || escapedWhitespace ?
  727 + escaped :
  728 + high < 0 ?
  729 + // BMP codepoint
  730 + String.fromCharCode( high + 0x10000 ) :
  731 + // Supplemental Plane codepoint (surrogate pair)
  732 + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  733 + },
  734 +
  735 + // Used for iframes
  736 + // See setDocument()
  737 + // Removing the function wrapper causes a "Permission Denied"
  738 + // error in IE
  739 + unloadHandler = function() {
  740 + setDocument();
  741 + };
  742 +
  743 +// Optimize for push.apply( _, NodeList )
  744 +try {
  745 + push.apply(
  746 + (arr = slice.call( preferredDoc.childNodes )),
  747 + preferredDoc.childNodes
  748 + );
  749 + // Support: Android<4.0
  750 + // Detect silently failing push.apply
  751 + arr[ preferredDoc.childNodes.length ].nodeType;
  752 +} catch ( e ) {
  753 + push = { apply: arr.length ?
  754 +
  755 + // Leverage slice if possible
  756 + function( target, els ) {
  757 + push_native.apply( target, slice.call(els) );
  758 + } :
  759 +
  760 + // Support: IE<9
  761 + // Otherwise append directly
  762 + function( target, els ) {
  763 + var j = target.length,
  764 + i = 0;
  765 + // Can't trust NodeList.length
  766 + while ( (target[j++] = els[i++]) ) {}
  767 + target.length = j - 1;
  768 + }
  769 + };
  770 +}
  771 +
  772 +function Sizzle( selector, context, results, seed ) {
  773 + var m, i, elem, nid, nidselect, match, groups, newSelector,
  774 + newContext = context && context.ownerDocument,
  775 +
  776 + // nodeType defaults to 9, since context defaults to document
  777 + nodeType = context ? context.nodeType : 9;
  778 +
  779 + results = results || [];
  780 +
  781 + // Return early from calls with invalid selector or context
  782 + if ( typeof selector !== "string" || !selector ||
  783 + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
  784 +
  785 + return results;
  786 + }
  787 +
  788 + // Try to shortcut find operations (as opposed to filters) in HTML documents
  789 + if ( !seed ) {
  790 +
  791 + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
  792 + setDocument( context );
  793 + }
  794 + context = context || document;
  795 +
  796 + if ( documentIsHTML ) {
  797 +
  798 + // If the selector is sufficiently simple, try using a "get*By*" DOM method
  799 + // (excepting DocumentFragment context, where the methods don't exist)
  800 + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
  801 +
  802 + // ID selector
  803 + if ( (m = match[1]) ) {
  804 +
  805 + // Document context
  806 + if ( nodeType === 9 ) {
  807 + if ( (elem = context.getElementById( m )) ) {
  808 +
  809 + // Support: IE, Opera, Webkit
  810 + // TODO: identify versions
  811 + // getElementById can match elements by name instead of ID
  812 + if ( elem.id === m ) {
  813 + results.push( elem );
  814 + return results;
  815 + }
  816 + } else {
  817 + return results;
  818 + }
  819 +
  820 + // Element context
  821 + } else {
  822 +
  823 + // Support: IE, Opera, Webkit
  824 + // TODO: identify versions
  825 + // getElementById can match elements by name instead of ID
  826 + if ( newContext && (elem = newContext.getElementById( m )) &&
  827 + contains( context, elem ) &&
  828 + elem.id === m ) {
  829 +
  830 + results.push( elem );
  831 + return results;
  832 + }
  833 + }
  834 +
  835 + // Type selector
  836 + } else if ( match[2] ) {
  837 + push.apply( results, context.getElementsByTagName( selector ) );
  838 + return results;
  839 +
  840 + // Class selector
  841 + } else if ( (m = match[3]) && support.getElementsByClassName &&
  842 + context.getElementsByClassName ) {
  843 +
  844 + push.apply( results, context.getElementsByClassName( m ) );
  845 + return results;
  846 + }
  847 + }
  848 +
  849 + // Take advantage of querySelectorAll
  850 + if ( support.qsa &&
  851 + !compilerCache[ selector + " " ] &&
  852 + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
  853 +
  854 + if ( nodeType !== 1 ) {
  855 + newContext = context;
  856 + newSelector = selector;
  857 +
  858 + // qSA looks outside Element context, which is not what we want
  859 + // Thanks to Andrew Dupont for this workaround technique
  860 + // Support: IE <=8
  861 + // Exclude object elements
  862 + } else if ( context.nodeName.toLowerCase() !== "object" ) {
  863 +
  864 + // Capture the context ID, setting it first if necessary
  865 + if ( (nid = context.getAttribute( "id" )) ) {
  866 + nid = nid.replace( rescape, "\\$&" );
  867 + } else {
  868 + context.setAttribute( "id", (nid = expando) );
  869 + }
  870 +
  871 + // Prefix every selector in the list
  872 + groups = tokenize( selector );
  873 + i = groups.length;
  874 + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
  875 + while ( i-- ) {
  876 + groups[i] = nidselect + " " + toSelector( groups[i] );
  877 + }
  878 + newSelector = groups.join( "," );
  879 +
  880 + // Expand context for sibling selectors
  881 + newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
  882 + context;
  883 + }
  884 +
  885 + if ( newSelector ) {
  886 + try {
  887 + push.apply( results,
  888 + newContext.querySelectorAll( newSelector )
  889 + );
  890 + return results;
  891 + } catch ( qsaError ) {
  892 + } finally {
  893 + if ( nid === expando ) {
  894 + context.removeAttribute( "id" );
  895 + }
  896 + }
  897 + }
  898 + }
  899 + }
  900 + }
  901 +
  902 + // All others
  903 + return select( selector.replace( rtrim, "$1" ), context, results, seed );
  904 +}
  905 +
  906 +/**
  907 + * Create key-value caches of limited size
  908 + * @returns {function(string, object)} Returns the Object data after storing it on itself with
  909 + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
  910 + * deleting the oldest entry
  911 + */
  912 +function createCache() {
  913 + var keys = [];
  914 +
  915 + function cache( key, value ) {
  916 + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  917 + if ( keys.push( key + " " ) > Expr.cacheLength ) {
  918 + // Only keep the most recent entries
  919 + delete cache[ keys.shift() ];
  920 + }
  921 + return (cache[ key + " " ] = value);
  922 + }
  923 + return cache;
  924 +}
  925 +
  926 +/**
  927 + * Mark a function for special use by Sizzle
  928 + * @param {Function} fn The function to mark
  929 + */
  930 +function markFunction( fn ) {
  931 + fn[ expando ] = true;
  932 + return fn;
  933 +}
  934 +
  935 +/**
  936 + * Support testing using an element
  937 + * @param {Function} fn Passed the created div and expects a boolean result
  938 + */
  939 +function assert( fn ) {
  940 + var div = document.createElement("div");
  941 +
  942 + try {
  943 + return !!fn( div );
  944 + } catch (e) {
  945 + return false;
  946 + } finally {
  947 + // Remove from its parent by default
  948 + if ( div.parentNode ) {
  949 + div.parentNode.removeChild( div );
  950 + }
  951 + // release memory in IE
  952 + div = null;
  953 + }
  954 +}
  955 +
  956 +/**
  957 + * Adds the same handler for all of the specified attrs
  958 + * @param {String} attrs Pipe-separated list of attributes
  959 + * @param {Function} handler The method that will be applied
  960 + */
  961 +function addHandle( attrs, handler ) {
  962 + var arr = attrs.split("|"),
  963 + i = arr.length;
  964 +
  965 + while ( i-- ) {
  966 + Expr.attrHandle[ arr[i] ] = handler;
  967 + }
  968 +}
  969 +
  970 +/**
  971 + * Checks document order of two siblings
  972 + * @param {Element} a
  973 + * @param {Element} b
  974 + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
  975 + */
  976 +function siblingCheck( a, b ) {
  977 + var cur = b && a,
  978 + diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  979 + ( ~b.sourceIndex || MAX_NEGATIVE ) -
  980 + ( ~a.sourceIndex || MAX_NEGATIVE );
  981 +
  982 + // Use IE sourceIndex if available on both nodes
  983 + if ( diff ) {
  984 + return diff;
  985 + }
  986 +
  987 + // Check if b follows a
  988 + if ( cur ) {
  989 + while ( (cur = cur.nextSibling) ) {
  990 + if ( cur === b ) {
  991 + return -1;
  992 + }
  993 + }
  994 + }
  995 +
  996 + return a ? 1 : -1;
  997 +}
  998 +
  999 +/**
  1000 + * Returns a function to use in pseudos for input types
  1001 + * @param {String} type
  1002 + */
  1003 +function createInputPseudo( type ) {
  1004 + return function( elem ) {
  1005 + var name = elem.nodeName.toLowerCase();
  1006 + return name === "input" && elem.type === type;
  1007 + };
  1008 +}
  1009 +
  1010 +/**
  1011 + * Returns a function to use in pseudos for buttons
  1012 + * @param {String} type
  1013 + */
  1014 +function createButtonPseudo( type ) {
  1015 + return function( elem ) {
  1016 + var name = elem.nodeName.toLowerCase();
  1017 + return (name === "input" || name === "button") && elem.type === type;
  1018 + };
  1019 +}
  1020 +
  1021 +/**
  1022 + * Returns a function to use in pseudos for positionals
  1023 + * @param {Function} fn
  1024 + */
  1025 +function createPositionalPseudo( fn ) {
  1026 + return markFunction(function( argument ) {
  1027 + argument = +argument;
  1028 + return markFunction(function( seed, matches ) {
  1029 + var j,
  1030 + matchIndexes = fn( [], seed.length, argument ),
  1031 + i = matchIndexes.length;
  1032 +
  1033 + // Match elements found at the specified indexes
  1034 + while ( i-- ) {
  1035 + if ( seed[ (j = matchIndexes[i]) ] ) {
  1036 + seed[j] = !(matches[j] = seed[j]);
  1037 + }
  1038 + }
  1039 + });
  1040 + });
  1041 +}
  1042 +
  1043 +/**
  1044 + * Checks a node for validity as a Sizzle context
  1045 + * @param {Element|Object=} context
  1046 + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
  1047 + */
  1048 +function testContext( context ) {
  1049 + return context && typeof context.getElementsByTagName !== "undefined" && context;
  1050 +}
  1051 +
  1052 +// Expose support vars for convenience
  1053 +support = Sizzle.support = {};
  1054 +
  1055 +/**
  1056 + * Detects XML nodes
  1057 + * @param {Element|Object} elem An element or a document
  1058 + * @returns {Boolean} True iff elem is a non-HTML XML node
  1059 + */
  1060 +isXML = Sizzle.isXML = function( elem ) {
  1061 + // documentElement is verified for cases where it doesn't yet exist
  1062 + // (such as loading iframes in IE - #4833)
  1063 + var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  1064 + return documentElement ? documentElement.nodeName !== "HTML" : false;
  1065 +};
  1066 +
  1067 +/**
  1068 + * Sets document-related variables once based on the current document
  1069 + * @param {Element|Object} [doc] An element or document object to use to set the document
  1070 + * @returns {Object} Returns the current document
  1071 + */
  1072 +setDocument = Sizzle.setDocument = function( node ) {
  1073 + var hasCompare, parent,
  1074 + doc = node ? node.ownerDocument || node : preferredDoc;
  1075 +
  1076 + // Return early if doc is invalid or already selected
  1077 + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  1078 + return document;
  1079 + }
  1080 +
  1081 + // Update global variables
  1082 + document = doc;
  1083 + docElem = document.documentElement;
  1084 + documentIsHTML = !isXML( document );
  1085 +
  1086 + // Support: IE 9-11, Edge
  1087 + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
  1088 + if ( (parent = document.defaultView) && parent.top !== parent ) {
  1089 + // Support: IE 11
  1090 + if ( parent.addEventListener ) {
  1091 + parent.addEventListener( "unload", unloadHandler, false );
  1092 +
  1093 + // Support: IE 9 - 10 only
  1094 + } else if ( parent.attachEvent ) {
  1095 + parent.attachEvent( "onunload", unloadHandler );
  1096 + }
  1097 + }
  1098 +
  1099 + /* Attributes
  1100 + ---------------------------------------------------------------------- */
  1101 +
  1102 + // Support: IE<8
  1103 + // Verify that getAttribute really returns attributes and not properties
  1104 + // (excepting IE8 booleans)
  1105 + support.attributes = assert(function( div ) {
  1106 + div.className = "i";
  1107 + return !div.getAttribute("className");
  1108 + });
  1109 +
  1110 + /* getElement(s)By*
  1111 + ---------------------------------------------------------------------- */
  1112 +
  1113 + // Check if getElementsByTagName("*") returns only elements
  1114 + support.getElementsByTagName = assert(function( div ) {
  1115 + div.appendChild( document.createComment("") );
  1116 + return !div.getElementsByTagName("*").length;
  1117 + });
  1118 +
  1119 + // Support: IE<9
  1120 + support.getElementsByClassName = rnative.test( document.getElementsByClassName );
  1121 +
  1122 + // Support: IE<10
  1123 + // Check if getElementById returns elements by name
  1124 + // The broken getElementById methods don't pick up programatically-set names,
  1125 + // so use a roundabout getElementsByName test
  1126 + support.getById = assert(function( div ) {
  1127 + docElem.appendChild( div ).id = expando;
  1128 + return !document.getElementsByName || !document.getElementsByName( expando ).length;
  1129 + });
  1130 +
  1131 + // ID find and filter
  1132 + if ( support.getById ) {
  1133 + Expr.find["ID"] = function( id, context ) {
  1134 + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  1135 + var m = context.getElementById( id );
  1136 + return m ? [ m ] : [];
  1137 + }
  1138 + };
  1139 + Expr.filter["ID"] = function( id ) {
  1140 + var attrId = id.replace( runescape, funescape );
  1141 + return function( elem ) {
  1142 + return elem.getAttribute("id") === attrId;
  1143 + };
  1144 + };
  1145 + } else {
  1146 + // Support: IE6/7
  1147 + // getElementById is not reliable as a find shortcut
  1148 + delete Expr.find["ID"];
  1149 +
  1150 + Expr.filter["ID"] = function( id ) {
  1151 + var attrId = id.replace( runescape, funescape );
  1152 + return function( elem ) {
  1153 + var node = typeof elem.getAttributeNode !== "undefined" &&
  1154 + elem.getAttributeNode("id");
  1155 + return node && node.value === attrId;
  1156 + };
  1157 + };
  1158 + }
  1159 +
  1160 + // Tag
  1161 + Expr.find["TAG"] = support.getElementsByTagName ?
  1162 + function( tag, context ) {
  1163 + if ( typeof context.getElementsByTagName !== "undefined" ) {
  1164 + return context.getElementsByTagName( tag );
  1165 +
  1166 + // DocumentFragment nodes don't have gEBTN
  1167 + } else if ( support.qsa ) {
  1168 + return context.querySelectorAll( tag );
  1169 + }
  1170 + } :
  1171 +
  1172 + function( tag, context ) {
  1173 + var elem,
  1174 + tmp = [],
  1175 + i = 0,
  1176 + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
  1177 + results = context.getElementsByTagName( tag );
  1178 +
  1179 + // Filter out possible comments
  1180 + if ( tag === "*" ) {
  1181 + while ( (elem = results[i++]) ) {
  1182 + if ( elem.nodeType === 1 ) {
  1183 + tmp.push( elem );
  1184 + }
  1185 + }
  1186 +
  1187 + return tmp;
  1188 + }
  1189 + return results;
  1190 + };
  1191 +
  1192 + // Class
  1193 + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  1194 + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
  1195 + return context.getElementsByClassName( className );
  1196 + }
  1197 + };
  1198 +
  1199 + /* QSA/matchesSelector
  1200 + ---------------------------------------------------------------------- */
  1201 +
  1202 + // QSA and matchesSelector support
  1203 +
  1204 + // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  1205 + rbuggyMatches = [];
  1206 +
  1207 + // qSa(:focus) reports false when true (Chrome 21)
  1208 + // We allow this because of a bug in IE8/9 that throws an error
  1209 + // whenever `document.activeElement` is accessed on an iframe
  1210 + // So, we allow :focus to pass through QSA all the time to avoid the IE error
  1211 + // See http://bugs.jquery.com/ticket/13378
  1212 + rbuggyQSA = [];
  1213 +
  1214 + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
  1215 + // Build QSA regex
  1216 + // Regex strategy adopted from Diego Perini
  1217 + assert(function( div ) {
  1218 + // Select is set to empty string on purpose
  1219 + // This is to test IE's treatment of not explicitly
  1220 + // setting a boolean content attribute,
  1221 + // since its presence should be enough
  1222 + // http://bugs.jquery.com/ticket/12359
  1223 + docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
  1224 + "<select id='" + expando + "-\r\\' msallowcapture=''>" +
  1225 + "<option selected=''></option></select>";
  1226 +
  1227 + // Support: IE8, Opera 11-12.16
  1228 + // Nothing should be selected when empty strings follow ^= or $= or *=
  1229 + // The test attribute must be unknown in Opera but "safe" for WinRT
  1230 + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
  1231 + if ( div.querySelectorAll("[msallowcapture^='']").length ) {
  1232 + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  1233 + }
  1234 +
  1235 + // Support: IE8
  1236 + // Boolean attributes and "value" are not treated correctly
  1237 + if ( !div.querySelectorAll("[selected]").length ) {
  1238 + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  1239 + }
  1240 +
  1241 + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
  1242 + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
  1243 + rbuggyQSA.push("~=");
  1244 + }
  1245 +
  1246 + // Webkit/Opera - :checked should return selected option elements
  1247 + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1248 + // IE8 throws error here and will not see later tests
  1249 + if ( !div.querySelectorAll(":checked").length ) {
  1250 + rbuggyQSA.push(":checked");
  1251 + }
  1252 +
  1253 + // Support: Safari 8+, iOS 8+
  1254 + // https://bugs.webkit.org/show_bug.cgi?id=136851
  1255 + // In-page `selector#id sibing-combinator selector` fails
  1256 + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
  1257 + rbuggyQSA.push(".#.+[+~]");
  1258 + }
  1259 + });
  1260 +
  1261 + assert(function( div ) {
  1262 + // Support: Windows 8 Native Apps
  1263 + // The type and name attributes are restricted during .innerHTML assignment
  1264 + var input = document.createElement("input");
  1265 + input.setAttribute( "type", "hidden" );
  1266 + div.appendChild( input ).setAttribute( "name", "D" );
  1267 +
  1268 + // Support: IE8
  1269 + // Enforce case-sensitivity of name attribute
  1270 + if ( div.querySelectorAll("[name=d]").length ) {
  1271 + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
  1272 + }
  1273 +
  1274 + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  1275 + // IE8 throws error here and will not see later tests
  1276 + if ( !div.querySelectorAll(":enabled").length ) {
  1277 + rbuggyQSA.push( ":enabled", ":disabled" );
  1278 + }
  1279 +
  1280 + // Opera 10-11 does not throw on post-comma invalid pseudos
  1281 + div.querySelectorAll("*,:x");
  1282 + rbuggyQSA.push(",.*:");
  1283 + });
  1284 + }
  1285 +
  1286 + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
  1287 + docElem.webkitMatchesSelector ||
  1288 + docElem.mozMatchesSelector ||
  1289 + docElem.oMatchesSelector ||
  1290 + docElem.msMatchesSelector) )) ) {
  1291 +
  1292 + assert(function( div ) {
  1293 + // Check to see if it's possible to do matchesSelector
  1294 + // on a disconnected node (IE 9)
  1295 + support.disconnectedMatch = matches.call( div, "div" );
  1296 +
  1297 + // This should fail with an exception
  1298 + // Gecko does not error, returns false instead
  1299 + matches.call( div, "[s!='']:x" );
  1300 + rbuggyMatches.push( "!=", pseudos );
  1301 + });
  1302 + }
  1303 +
  1304 + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  1305 + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  1306 +
  1307 + /* Contains
  1308 + ---------------------------------------------------------------------- */
  1309 + hasCompare = rnative.test( docElem.compareDocumentPosition );
  1310 +
  1311 + // Element contains another
  1312 + // Purposefully self-exclusive
  1313 + // As in, an element does not contain itself
  1314 + contains = hasCompare || rnative.test( docElem.contains ) ?
  1315 + function( a, b ) {
  1316 + var adown = a.nodeType === 9 ? a.documentElement : a,
  1317 + bup = b && b.parentNode;
  1318 + return a === bup || !!( bup && bup.nodeType === 1 && (
  1319 + adown.contains ?
  1320 + adown.contains( bup ) :
  1321 + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  1322 + ));
  1323 + } :
  1324 + function( a, b ) {
  1325 + if ( b ) {
  1326 + while ( (b = b.parentNode) ) {
  1327 + if ( b === a ) {
  1328 + return true;
  1329 + }
  1330 + }
  1331 + }
  1332 + return false;
  1333 + };
  1334 +
  1335 + /* Sorting
  1336 + ---------------------------------------------------------------------- */
  1337 +
  1338 + // Document order sorting
  1339 + sortOrder = hasCompare ?
  1340 + function( a, b ) {
  1341 +
  1342 + // Flag for duplicate removal
  1343 + if ( a === b ) {
  1344 + hasDuplicate = true;
  1345 + return 0;
  1346 + }
  1347 +
  1348 + // Sort on method existence if only one input has compareDocumentPosition
  1349 + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  1350 + if ( compare ) {
  1351 + return compare;
  1352 + }
  1353 +
  1354 + // Calculate position if both inputs belong to the same document
  1355 + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  1356 + a.compareDocumentPosition( b ) :
  1357 +
  1358 + // Otherwise we know they are disconnected
  1359 + 1;
  1360 +
  1361 + // Disconnected nodes
  1362 + if ( compare & 1 ||
  1363 + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  1364 +
  1365 + // Choose the first element that is related to our preferred document
  1366 + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
  1367 + return -1;
  1368 + }
  1369 + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
  1370 + return 1;
  1371 + }
  1372 +
  1373 + // Maintain original order
  1374 + return sortInput ?
  1375 + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1376 + 0;
  1377 + }
  1378 +
  1379 + return compare & 4 ? -1 : 1;
  1380 + } :
  1381 + function( a, b ) {
  1382 + // Exit early if the nodes are identical
  1383 + if ( a === b ) {
  1384 + hasDuplicate = true;
  1385 + return 0;
  1386 + }
  1387 +
  1388 + var cur,
  1389 + i = 0,
  1390 + aup = a.parentNode,
  1391 + bup = b.parentNode,
  1392 + ap = [ a ],
  1393 + bp = [ b ];
  1394 +
  1395 + // Parentless nodes are either documents or disconnected
  1396 + if ( !aup || !bup ) {
  1397 + return a === document ? -1 :
  1398 + b === document ? 1 :
  1399 + aup ? -1 :
  1400 + bup ? 1 :
  1401 + sortInput ?
  1402 + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1403 + 0;
  1404 +
  1405 + // If the nodes are siblings, we can do a quick check
  1406 + } else if ( aup === bup ) {
  1407 + return siblingCheck( a, b );
  1408 + }
  1409 +
  1410 + // Otherwise we need full lists of their ancestors for comparison
  1411 + cur = a;
  1412 + while ( (cur = cur.parentNode) ) {
  1413 + ap.unshift( cur );
  1414 + }
  1415 + cur = b;
  1416 + while ( (cur = cur.parentNode) ) {
  1417 + bp.unshift( cur );
  1418 + }
  1419 +
  1420 + // Walk down the tree looking for a discrepancy
  1421 + while ( ap[i] === bp[i] ) {
  1422 + i++;
  1423 + }
  1424 +
  1425 + return i ?
  1426 + // Do a sibling check if the nodes have a common ancestor
  1427 + siblingCheck( ap[i], bp[i] ) :
  1428 +
  1429 + // Otherwise nodes in our document sort first
  1430 + ap[i] === preferredDoc ? -1 :
  1431 + bp[i] === preferredDoc ? 1 :
  1432 + 0;
  1433 + };
  1434 +
  1435 + return document;
  1436 +};
  1437 +
  1438 +Sizzle.matches = function( expr, elements ) {
  1439 + return Sizzle( expr, null, null, elements );
  1440 +};
  1441 +
  1442 +Sizzle.matchesSelector = function( elem, expr ) {
  1443 + // Set document vars if needed
  1444 + if ( ( elem.ownerDocument || elem ) !== document ) {
  1445 + setDocument( elem );
  1446 + }
  1447 +
  1448 + // Make sure that attribute selectors are quoted
  1449 + expr = expr.replace( rattributeQuotes, "='$1']" );
  1450 +
  1451 + if ( support.matchesSelector && documentIsHTML &&
  1452 + !compilerCache[ expr + " " ] &&
  1453 + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  1454 + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
  1455 +
  1456 + try {
  1457 + var ret = matches.call( elem, expr );
  1458 +
  1459 + // IE 9's matchesSelector returns false on disconnected nodes
  1460 + if ( ret || support.disconnectedMatch ||
  1461 + // As well, disconnected nodes are said to be in a document
  1462 + // fragment in IE 9
  1463 + elem.document && elem.document.nodeType !== 11 ) {
  1464 + return ret;
  1465 + }
  1466 + } catch (e) {}
  1467 + }
  1468 +
  1469 + return Sizzle( expr, document, null, [ elem ] ).length > 0;
  1470 +};
  1471 +
  1472 +Sizzle.contains = function( context, elem ) {
  1473 + // Set document vars if needed
  1474 + if ( ( context.ownerDocument || context ) !== document ) {
  1475 + setDocument( context );
  1476 + }
  1477 + return contains( context, elem );
  1478 +};
  1479 +
  1480 +Sizzle.attr = function( elem, name ) {
  1481 + // Set document vars if needed
  1482 + if ( ( elem.ownerDocument || elem ) !== document ) {
  1483 + setDocument( elem );
  1484 + }
  1485 +
  1486 + var fn = Expr.attrHandle[ name.toLowerCase() ],
  1487 + // Don't get fooled by Object.prototype properties (jQuery #13807)
  1488 + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  1489 + fn( elem, name, !documentIsHTML ) :
  1490 + undefined;
  1491 +
  1492 + return val !== undefined ?
  1493 + val :
  1494 + support.attributes || !documentIsHTML ?
  1495 + elem.getAttribute( name ) :
  1496 + (val = elem.getAttributeNode(name)) && val.specified ?
  1497 + val.value :
  1498 + null;
  1499 +};
  1500 +
  1501 +Sizzle.error = function( msg ) {
  1502 + throw new Error( "Syntax error, unrecognized expression: " + msg );
  1503 +};
  1504 +
  1505 +/**
  1506 + * Document sorting and removing duplicates
  1507 + * @param {ArrayLike} results
  1508 + */
  1509 +Sizzle.uniqueSort = function( results ) {
  1510 + var elem,
  1511 + duplicates = [],
  1512 + j = 0,
  1513 + i = 0;
  1514 +
  1515 + // Unless we *know* we can detect duplicates, assume their presence
  1516 + hasDuplicate = !support.detectDuplicates;
  1517 + sortInput = !support.sortStable && results.slice( 0 );
  1518 + results.sort( sortOrder );
  1519 +
  1520 + if ( hasDuplicate ) {
  1521 + while ( (elem = results[i++]) ) {
  1522 + if ( elem === results[ i ] ) {
  1523 + j = duplicates.push( i );
  1524 + }
  1525 + }
  1526 + while ( j-- ) {
  1527 + results.splice( duplicates[ j ], 1 );
  1528 + }
  1529 + }
  1530 +
  1531 + // Clear input after sorting to release objects
  1532 + // See https://github.com/jquery/sizzle/pull/225
  1533 + sortInput = null;
  1534 +
  1535 + return results;
  1536 +};
  1537 +
  1538 +/**
  1539 + * Utility function for retrieving the text value of an array of DOM nodes
  1540 + * @param {Array|Element} elem
  1541 + */
  1542 +getText = Sizzle.getText = function( elem ) {
  1543 + var node,
  1544 + ret = "",
  1545 + i = 0,
  1546 + nodeType = elem.nodeType;
  1547 +
  1548 + if ( !nodeType ) {
  1549 + // If no nodeType, this is expected to be an array
  1550 + while ( (node = elem[i++]) ) {
  1551 + // Do not traverse comment nodes
  1552 + ret += getText( node );
  1553 + }
  1554 + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  1555 + // Use textContent for elements
  1556 + // innerText usage removed for consistency of new lines (jQuery #11153)
  1557 + if ( typeof elem.textContent === "string" ) {
  1558 + return elem.textContent;
  1559 + } else {
  1560 + // Traverse its children
  1561 + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1562 + ret += getText( elem );
  1563 + }
  1564 + }
  1565 + } else if ( nodeType === 3 || nodeType === 4 ) {
  1566 + return elem.nodeValue;
  1567 + }
  1568 + // Do not include comment or processing instruction nodes
  1569 +
  1570 + return ret;
  1571 +};
  1572 +
  1573 +Expr = Sizzle.selectors = {
  1574 +
  1575 + // Can be adjusted by the user
  1576 + cacheLength: 50,
  1577 +
  1578 + createPseudo: markFunction,
  1579 +
  1580 + match: matchExpr,
  1581 +
  1582 + attrHandle: {},
  1583 +
  1584 + find: {},
  1585 +
  1586 + relative: {
  1587 + ">": { dir: "parentNode", first: true },
  1588 + " ": { dir: "parentNode" },
  1589 + "+": { dir: "previousSibling", first: true },
  1590 + "~": { dir: "previousSibling" }
  1591 + },
  1592 +
  1593 + preFilter: {
  1594 + "ATTR": function( match ) {
  1595 + match[1] = match[1].replace( runescape, funescape );
  1596 +
  1597 + // Move the given value to match[3] whether quoted or unquoted
  1598 + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
  1599 +
  1600 + if ( match[2] === "~=" ) {
  1601 + match[3] = " " + match[3] + " ";
  1602 + }
  1603 +
  1604 + return match.slice( 0, 4 );
  1605 + },
  1606 +
  1607 + "CHILD": function( match ) {
  1608 + /* matches from matchExpr["CHILD"]
  1609 + 1 type (only|nth|...)
  1610 + 2 what (child|of-type)
  1611 + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  1612 + 4 xn-component of xn+y argument ([+-]?\d*n|)
  1613 + 5 sign of xn-component
  1614 + 6 x of xn-component
  1615 + 7 sign of y-component
  1616 + 8 y of y-component
  1617 + */
  1618 + match[1] = match[1].toLowerCase();
  1619 +
  1620 + if ( match[1].slice( 0, 3 ) === "nth" ) {
  1621 + // nth-* requires argument
  1622 + if ( !match[3] ) {
  1623 + Sizzle.error( match[0] );
  1624 + }
  1625 +
  1626 + // numeric x and y parameters for Expr.filter.CHILD
  1627 + // remember that false/true cast respectively to 0/1
  1628 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  1629 + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  1630 +
  1631 + // other types prohibit arguments
  1632 + } else if ( match[3] ) {
  1633 + Sizzle.error( match[0] );
  1634 + }
  1635 +
  1636 + return match;
  1637 + },
  1638 +
  1639 + "PSEUDO": function( match ) {
  1640 + var excess,
  1641 + unquoted = !match[6] && match[2];
  1642 +
  1643 + if ( matchExpr["CHILD"].test( match[0] ) ) {
  1644 + return null;
  1645 + }
  1646 +
  1647 + // Accept quoted arguments as-is
  1648 + if ( match[3] ) {
  1649 + match[2] = match[4] || match[5] || "";
  1650 +
  1651 + // Strip excess characters from unquoted arguments
  1652 + } else if ( unquoted && rpseudo.test( unquoted ) &&
  1653 + // Get excess from tokenize (recursively)
  1654 + (excess = tokenize( unquoted, true )) &&
  1655 + // advance to the next closing parenthesis
  1656 + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  1657 +
  1658 + // excess is a negative index
  1659 + match[0] = match[0].slice( 0, excess );
  1660 + match[2] = unquoted.slice( 0, excess );
  1661 + }
  1662 +
  1663 + // Return only captures needed by the pseudo filter method (type and argument)
  1664 + return match.slice( 0, 3 );
  1665 + }
  1666 + },
  1667 +
  1668 + filter: {
  1669 +
  1670 + "TAG": function( nodeNameSelector ) {
  1671 + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  1672 + return nodeNameSelector === "*" ?
  1673 + function() { return true; } :
  1674 + function( elem ) {
  1675 + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  1676 + };
  1677 + },
  1678 +
  1679 + "CLASS": function( className ) {
  1680 + var pattern = classCache[ className + " " ];
  1681 +
  1682 + return pattern ||
  1683 + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  1684 + classCache( className, function( elem ) {
  1685 + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
  1686 + });
  1687 + },
  1688 +
  1689 + "ATTR": function( name, operator, check ) {
  1690 + return function( elem ) {
  1691 + var result = Sizzle.attr( elem, name );
  1692 +
  1693 + if ( result == null ) {
  1694 + return operator === "!=";
  1695 + }
  1696 + if ( !operator ) {
  1697 + return true;
  1698 + }
  1699 +
  1700 + result += "";
  1701 +
  1702 + return operator === "=" ? result === check :
  1703 + operator === "!=" ? result !== check :
  1704 + operator === "^=" ? check && result.indexOf( check ) === 0 :
  1705 + operator === "*=" ? check && result.indexOf( check ) > -1 :
  1706 + operator === "$=" ? check && result.slice( -check.length ) === check :
  1707 + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
  1708 + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  1709 + false;
  1710 + };
  1711 + },
  1712 +
  1713 + "CHILD": function( type, what, argument, first, last ) {
  1714 + var simple = type.slice( 0, 3 ) !== "nth",
  1715 + forward = type.slice( -4 ) !== "last",
  1716 + ofType = what === "of-type";
  1717 +
  1718 + return first === 1 && last === 0 ?
  1719 +
  1720 + // Shortcut for :nth-*(n)
  1721 + function( elem ) {
  1722 + return !!elem.parentNode;
  1723 + } :
  1724 +
  1725 + function( elem, context, xml ) {
  1726 + var cache, uniqueCache, outerCache, node, nodeIndex, start,
  1727 + dir = simple !== forward ? "nextSibling" : "previousSibling",
  1728 + parent = elem.parentNode,
  1729 + name = ofType && elem.nodeName.toLowerCase(),
  1730 + useCache = !xml && !ofType,
  1731 + diff = false;
  1732 +
  1733 + if ( parent ) {
  1734 +
  1735 + // :(first|last|only)-(child|of-type)
  1736 + if ( simple ) {
  1737 + while ( dir ) {
  1738 + node = elem;
  1739 + while ( (node = node[ dir ]) ) {
  1740 + if ( ofType ?
  1741 + node.nodeName.toLowerCase() === name :
  1742 + node.nodeType === 1 ) {
  1743 +
  1744 + return false;
  1745 + }
  1746 + }
  1747 + // Reverse direction for :only-* (if we haven't yet done so)
  1748 + start = dir = type === "only" && !start && "nextSibling";
  1749 + }
  1750 + return true;
  1751 + }
  1752 +
  1753 + start = [ forward ? parent.firstChild : parent.lastChild ];
  1754 +
  1755 + // non-xml :nth-child(...) stores cache data on `parent`
  1756 + if ( forward && useCache ) {
  1757 +
  1758 + // Seek `elem` from a previously-cached index
  1759 +
  1760 + // ...in a gzip-friendly way
  1761 + node = parent;
  1762 + outerCache = node[ expando ] || (node[ expando ] = {});
  1763 +
  1764 + // Support: IE <9 only
  1765 + // Defend against cloned attroperties (jQuery gh-1709)
  1766 + uniqueCache = outerCache[ node.uniqueID ] ||
  1767 + (outerCache[ node.uniqueID ] = {});
  1768 +
  1769 + cache = uniqueCache[ type ] || [];
  1770 + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1771 + diff = nodeIndex && cache[ 2 ];
  1772 + node = nodeIndex && parent.childNodes[ nodeIndex ];
  1773 +
  1774 + while ( (node = ++nodeIndex && node && node[ dir ] ||
  1775 +
  1776 + // Fallback to seeking `elem` from the start
  1777 + (diff = nodeIndex = 0) || start.pop()) ) {
  1778 +
  1779 + // When found, cache indexes on `parent` and break
  1780 + if ( node.nodeType === 1 && ++diff && node === elem ) {
  1781 + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
  1782 + break;
  1783 + }
  1784 + }
  1785 +
  1786 + } else {
  1787 + // Use previously-cached element index if available
  1788 + if ( useCache ) {
  1789 + // ...in a gzip-friendly way
  1790 + node = elem;
  1791 + outerCache = node[ expando ] || (node[ expando ] = {});
  1792 +
  1793 + // Support: IE <9 only
  1794 + // Defend against cloned attroperties (jQuery gh-1709)
  1795 + uniqueCache = outerCache[ node.uniqueID ] ||
  1796 + (outerCache[ node.uniqueID ] = {});
  1797 +
  1798 + cache = uniqueCache[ type ] || [];
  1799 + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1800 + diff = nodeIndex;
  1801 + }
  1802 +
  1803 + // xml :nth-child(...)
  1804 + // or :nth-last-child(...) or :nth(-last)?-of-type(...)
  1805 + if ( diff === false ) {
  1806 + // Use the same loop as above to seek `elem` from the start
  1807 + while ( (node = ++nodeIndex && node && node[ dir ] ||
  1808 + (diff = nodeIndex = 0) || start.pop()) ) {
  1809 +
  1810 + if ( ( ofType ?
  1811 + node.nodeName.toLowerCase() === name :
  1812 + node.nodeType === 1 ) &&
  1813 + ++diff ) {
  1814 +
  1815 + // Cache the index of each encountered element
  1816 + if ( useCache ) {
  1817 + outerCache = node[ expando ] || (node[ expando ] = {});
  1818 +
  1819 + // Support: IE <9 only
  1820 + // Defend against cloned attroperties (jQuery gh-1709)
  1821 + uniqueCache = outerCache[ node.uniqueID ] ||
  1822 + (outerCache[ node.uniqueID ] = {});
  1823 +
  1824 + uniqueCache[ type ] = [ dirruns, diff ];
  1825 + }
  1826 +
  1827 + if ( node === elem ) {
  1828 + break;
  1829 + }
  1830 + }
  1831 + }
  1832 + }
  1833 + }
  1834 +
  1835 + // Incorporate the offset, then check against cycle size
  1836 + diff -= last;
  1837 + return diff === first || ( diff % first === 0 && diff / first >= 0 );
  1838 + }
  1839 + };
  1840 + },
  1841 +
  1842 + "PSEUDO": function( pseudo, argument ) {
  1843 + // pseudo-class names are case-insensitive
  1844 + // http://www.w3.org/TR/selectors/#pseudo-classes
  1845 + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  1846 + // Remember that setFilters inherits from pseudos
  1847 + var args,
  1848 + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  1849 + Sizzle.error( "unsupported pseudo: " + pseudo );
  1850 +
  1851 + // The user may use createPseudo to indicate that
  1852 + // arguments are needed to create the filter function
  1853 + // just as Sizzle does
  1854 + if ( fn[ expando ] ) {
  1855 + return fn( argument );
  1856 + }
  1857 +
  1858 + // But maintain support for old signatures
  1859 + if ( fn.length > 1 ) {
  1860 + args = [ pseudo, pseudo, "", argument ];
  1861 + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  1862 + markFunction(function( seed, matches ) {
  1863 + var idx,
  1864 + matched = fn( seed, argument ),
  1865 + i = matched.length;
  1866 + while ( i-- ) {
  1867 + idx = indexOf( seed, matched[i] );
  1868 + seed[ idx ] = !( matches[ idx ] = matched[i] );
  1869 + }
  1870 + }) :
  1871 + function( elem ) {
  1872 + return fn( elem, 0, args );
  1873 + };
  1874 + }
  1875 +
  1876 + return fn;
  1877 + }
  1878 + },
  1879 +
  1880 + pseudos: {
  1881 + // Potentially complex pseudos
  1882 + "not": markFunction(function( selector ) {
  1883 + // Trim the selector passed to compile
  1884 + // to avoid treating leading and trailing
  1885 + // spaces as combinators
  1886 + var input = [],
  1887 + results = [],
  1888 + matcher = compile( selector.replace( rtrim, "$1" ) );
  1889 +
  1890 + return matcher[ expando ] ?
  1891 + markFunction(function( seed, matches, context, xml ) {
  1892 + var elem,
  1893 + unmatched = matcher( seed, null, xml, [] ),
  1894 + i = seed.length;
  1895 +
  1896 + // Match elements unmatched by `matcher`
  1897 + while ( i-- ) {
  1898 + if ( (elem = unmatched[i]) ) {
  1899 + seed[i] = !(matches[i] = elem);
  1900 + }
  1901 + }
  1902 + }) :
  1903 + function( elem, context, xml ) {
  1904 + input[0] = elem;
  1905 + matcher( input, null, xml, results );
  1906 + // Don't keep the element (issue #299)
  1907 + input[0] = null;
  1908 + return !results.pop();
  1909 + };
  1910 + }),
  1911 +
  1912 + "has": markFunction(function( selector ) {
  1913 + return function( elem ) {
  1914 + return Sizzle( selector, elem ).length > 0;
  1915 + };
  1916 + }),
  1917 +
  1918 + "contains": markFunction(function( text ) {
  1919 + text = text.replace( runescape, funescape );
  1920 + return function( elem ) {
  1921 + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  1922 + };
  1923 + }),
  1924 +
  1925 + // "Whether an element is represented by a :lang() selector
  1926 + // is based solely on the element's language value
  1927 + // being equal to the identifier C,
  1928 + // or beginning with the identifier C immediately followed by "-".
  1929 + // The matching of C against the element's language value is performed case-insensitively.
  1930 + // The identifier C does not have to be a valid language name."
  1931 + // http://www.w3.org/TR/selectors/#lang-pseudo
  1932 + "lang": markFunction( function( lang ) {
  1933 + // lang value must be a valid identifier
  1934 + if ( !ridentifier.test(lang || "") ) {
  1935 + Sizzle.error( "unsupported lang: " + lang );
  1936 + }
  1937 + lang = lang.replace( runescape, funescape ).toLowerCase();
  1938 + return function( elem ) {
  1939 + var elemLang;
  1940 + do {
  1941 + if ( (elemLang = documentIsHTML ?
  1942 + elem.lang :
  1943 + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  1944 +
  1945 + elemLang = elemLang.toLowerCase();
  1946 + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  1947 + }
  1948 + } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  1949 + return false;
  1950 + };
  1951 + }),
  1952 +
  1953 + // Miscellaneous
  1954 + "target": function( elem ) {
  1955 + var hash = window.location && window.location.hash;
  1956 + return hash && hash.slice( 1 ) === elem.id;
  1957 + },
  1958 +
  1959 + "root": function( elem ) {
  1960 + return elem === docElem;
  1961 + },
  1962 +
  1963 + "focus": function( elem ) {
  1964 + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  1965 + },
  1966 +
  1967 + // Boolean properties
  1968 + "enabled": function( elem ) {
  1969 + return elem.disabled === false;
  1970 + },
  1971 +
  1972 + "disabled": function( elem ) {
  1973 + return elem.disabled === true;
  1974 + },
  1975 +
  1976 + "checked": function( elem ) {
  1977 + // In CSS3, :checked should return both checked and selected elements
  1978 + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1979 + var nodeName = elem.nodeName.toLowerCase();
  1980 + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  1981 + },
  1982 +
  1983 + "selected": function( elem ) {
  1984 + // Accessing this property makes selected-by-default
  1985 + // options in Safari work properly
  1986 + if ( elem.parentNode ) {
  1987 + elem.parentNode.selectedIndex;
  1988 + }
  1989 +
  1990 + return elem.selected === true;
  1991 + },
  1992 +
  1993 + // Contents
  1994 + "empty": function( elem ) {
  1995 + // http://www.w3.org/TR/selectors/#empty-pseudo
  1996 + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
  1997 + // but not by others (comment: 8; processing instruction: 7; etc.)
  1998 + // nodeType < 6 works because attributes (2) do not appear as children
  1999 + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  2000 + if ( elem.nodeType < 6 ) {
  2001 + return false;
  2002 + }
  2003 + }
  2004 + return true;
  2005 + },
  2006 +
  2007 + "parent": function( elem ) {
  2008 + return !Expr.pseudos["empty"]( elem );
  2009 + },
  2010 +
  2011 + // Element/input types
  2012 + "header": function( elem ) {
  2013 + return rheader.test( elem.nodeName );
  2014 + },
  2015 +
  2016 + "input": function( elem ) {
  2017 + return rinputs.test( elem.nodeName );
  2018 + },
  2019 +
  2020 + "button": function( elem ) {
  2021 + var name = elem.nodeName.toLowerCase();
  2022 + return name === "input" && elem.type === "button" || name === "button";
  2023 + },
  2024 +
  2025 + "text": function( elem ) {
  2026 + var attr;
  2027 + return elem.nodeName.toLowerCase() === "input" &&
  2028 + elem.type === "text" &&
  2029 +
  2030 + // Support: IE<8
  2031 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
  2032 + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
  2033 + },
  2034 +
  2035 + // Position-in-collection
  2036 + "first": createPositionalPseudo(function() {
  2037 + return [ 0 ];
  2038 + }),
  2039 +
  2040 + "last": createPositionalPseudo(function( matchIndexes, length ) {
  2041 + return [ length - 1 ];
  2042 + }),
  2043 +
  2044 + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2045 + return [ argument < 0 ? argument + length : argument ];
  2046 + }),
  2047 +
  2048 + "even": createPositionalPseudo(function( matchIndexes, length ) {
  2049 + var i = 0;
  2050 + for ( ; i < length; i += 2 ) {
  2051 + matchIndexes.push( i );
  2052 + }
  2053 + return matchIndexes;
  2054 + }),
  2055 +
  2056 + "odd": createPositionalPseudo(function( matchIndexes, length ) {
  2057 + var i = 1;
  2058 + for ( ; i < length; i += 2 ) {
  2059 + matchIndexes.push( i );
  2060 + }
  2061 + return matchIndexes;
  2062 + }),
  2063 +
  2064 + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2065 + var i = argument < 0 ? argument + length : argument;
  2066 + for ( ; --i >= 0; ) {
  2067 + matchIndexes.push( i );
  2068 + }
  2069 + return matchIndexes;
  2070 + }),
  2071 +
  2072 + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2073 + var i = argument < 0 ? argument + length : argument;
  2074 + for ( ; ++i < length; ) {
  2075 + matchIndexes.push( i );
  2076 + }
  2077 + return matchIndexes;
  2078 + })
  2079 + }
  2080 +};
  2081 +
  2082 +Expr.pseudos["nth"] = Expr.pseudos["eq"];
  2083 +
  2084 +// Add button/input type pseudos
  2085 +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  2086 + Expr.pseudos[ i ] = createInputPseudo( i );
  2087 +}
  2088 +for ( i in { submit: true, reset: true } ) {
  2089 + Expr.pseudos[ i ] = createButtonPseudo( i );
  2090 +}
  2091 +
  2092 +// Easy API for creating new setFilters
  2093 +function setFilters() {}
  2094 +setFilters.prototype = Expr.filters = Expr.pseudos;
  2095 +Expr.setFilters = new setFilters();
  2096 +
  2097 +tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
  2098 + var matched, match, tokens, type,
  2099 + soFar, groups, preFilters,
  2100 + cached = tokenCache[ selector + " " ];
  2101 +
  2102 + if ( cached ) {
  2103 + return parseOnly ? 0 : cached.slice( 0 );
  2104 + }
  2105 +
  2106 + soFar = selector;
  2107 + groups = [];
  2108 + preFilters = Expr.preFilter;
  2109 +
  2110 + while ( soFar ) {
  2111 +
  2112 + // Comma and first run
  2113 + if ( !matched || (match = rcomma.exec( soFar )) ) {
  2114 + if ( match ) {
  2115 + // Don't consume trailing commas as valid
  2116 + soFar = soFar.slice( match[0].length ) || soFar;
  2117 + }
  2118 + groups.push( (tokens = []) );
  2119 + }
  2120 +
  2121 + matched = false;
  2122 +
  2123 + // Combinators
  2124 + if ( (match = rcombinators.exec( soFar )) ) {
  2125 + matched = match.shift();
  2126 + tokens.push({
  2127 + value: matched,
  2128 + // Cast descendant combinators to space
  2129 + type: match[0].replace( rtrim, " " )
  2130 + });
  2131 + soFar = soFar.slice( matched.length );
  2132 + }
  2133 +
  2134 + // Filters
  2135 + for ( type in Expr.filter ) {
  2136 + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  2137 + (match = preFilters[ type ]( match ))) ) {
  2138 + matched = match.shift();
  2139 + tokens.push({
  2140 + value: matched,
  2141 + type: type,
  2142 + matches: match
  2143 + });
  2144 + soFar = soFar.slice( matched.length );
  2145 + }
  2146 + }
  2147 +
  2148 + if ( !matched ) {
  2149 + break;
  2150 + }
  2151 + }
  2152 +
  2153 + // Return the length of the invalid excess
  2154 + // if we're just parsing
  2155 + // Otherwise, throw an error or return tokens
  2156 + return parseOnly ?
  2157 + soFar.length :
  2158 + soFar ?
  2159 + Sizzle.error( selector ) :
  2160 + // Cache the tokens
  2161 + tokenCache( selector, groups ).slice( 0 );
  2162 +};
  2163 +
  2164 +function toSelector( tokens ) {
  2165 + var i = 0,
  2166 + len = tokens.length,
  2167 + selector = "";
  2168 + for ( ; i < len; i++ ) {
  2169 + selector += tokens[i].value;
  2170 + }
  2171 + return selector;
  2172 +}
  2173 +
  2174 +function addCombinator( matcher, combinator, base ) {
  2175 + var dir = combinator.dir,
  2176 + checkNonElements = base && dir === "parentNode",
  2177 + doneName = done++;
  2178 +
  2179 + return combinator.first ?
  2180 + // Check against closest ancestor/preceding element
  2181 + function( elem, context, xml ) {
  2182 + while ( (elem = elem[ dir ]) ) {
  2183 + if ( elem.nodeType === 1 || checkNonElements ) {
  2184 + return matcher( elem, context, xml );
  2185 + }
  2186 + }
  2187 + } :
  2188 +
  2189 + // Check against all ancestor/preceding elements
  2190 + function( elem, context, xml ) {
  2191 + var oldCache, uniqueCache, outerCache,
  2192 + newCache = [ dirruns, doneName ];
  2193 +
  2194 + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
  2195 + if ( xml ) {
  2196 + while ( (elem = elem[ dir ]) ) {
  2197 + if ( elem.nodeType === 1 || checkNonElements ) {
  2198 + if ( matcher( elem, context, xml ) ) {
  2199 + return true;
  2200 + }
  2201 + }
  2202 + }
  2203 + } else {
  2204 + while ( (elem = elem[ dir ]) ) {
  2205 + if ( elem.nodeType === 1 || checkNonElements ) {
  2206 + outerCache = elem[ expando ] || (elem[ expando ] = {});
  2207 +
  2208 + // Support: IE <9 only
  2209 + // Defend against cloned attroperties (jQuery gh-1709)
  2210 + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
  2211 +
  2212 + if ( (oldCache = uniqueCache[ dir ]) &&
  2213 + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
  2214 +
  2215 + // Assign to newCache so results back-propagate to previous elements
  2216 + return (newCache[ 2 ] = oldCache[ 2 ]);
  2217 + } else {
  2218 + // Reuse newcache so results back-propagate to previous elements
  2219 + uniqueCache[ dir ] = newCache;
  2220 +
  2221 + // A match means we're done; a fail means we have to keep checking
  2222 + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
  2223 + return true;
  2224 + }
  2225 + }
  2226 + }
  2227 + }
  2228 + }
  2229 + };
  2230 +}
  2231 +
  2232 +function elementMatcher( matchers ) {
  2233 + return matchers.length > 1 ?
  2234 + function( elem, context, xml ) {
  2235 + var i = matchers.length;
  2236 + while ( i-- ) {
  2237 + if ( !matchers[i]( elem, context, xml ) ) {
  2238 + return false;
  2239 + }
  2240 + }
  2241 + return true;
  2242 + } :
  2243 + matchers[0];
  2244 +}
  2245 +
  2246 +function multipleContexts( selector, contexts, results ) {
  2247 + var i = 0,
  2248 + len = contexts.length;
  2249 + for ( ; i < len; i++ ) {
  2250 + Sizzle( selector, contexts[i], results );
  2251 + }
  2252 + return results;
  2253 +}
  2254 +
  2255 +function condense( unmatched, map, filter, context, xml ) {
  2256 + var elem,
  2257 + newUnmatched = [],
  2258 + i = 0,
  2259 + len = unmatched.length,
  2260 + mapped = map != null;
  2261 +
  2262 + for ( ; i < len; i++ ) {
  2263 + if ( (elem = unmatched[i]) ) {
  2264 + if ( !filter || filter( elem, context, xml ) ) {
  2265 + newUnmatched.push( elem );
  2266 + if ( mapped ) {
  2267 + map.push( i );
  2268 + }
  2269 + }
  2270 + }
  2271 + }
  2272 +
  2273 + return newUnmatched;
  2274 +}
  2275 +
  2276 +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  2277 + if ( postFilter && !postFilter[ expando ] ) {
  2278 + postFilter = setMatcher( postFilter );
  2279 + }
  2280 + if ( postFinder && !postFinder[ expando ] ) {
  2281 + postFinder = setMatcher( postFinder, postSelector );
  2282 + }
  2283 + return markFunction(function( seed, results, context, xml ) {
  2284 + var temp, i, elem,
  2285 + preMap = [],
  2286 + postMap = [],
  2287 + preexisting = results.length,
  2288 +
  2289 + // Get initial elements from seed or context
  2290 + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  2291 +
  2292 + // Prefilter to get matcher input, preserving a map for seed-results synchronization
  2293 + matcherIn = preFilter && ( seed || !selector ) ?
  2294 + condense( elems, preMap, preFilter, context, xml ) :
  2295 + elems,
  2296 +
  2297 + matcherOut = matcher ?
  2298 + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  2299 + postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  2300 +
  2301 + // ...intermediate processing is necessary
  2302 + [] :
  2303 +
  2304 + // ...otherwise use results directly
  2305 + results :
  2306 + matcherIn;
  2307 +
  2308 + // Find primary matches
  2309 + if ( matcher ) {
  2310 + matcher( matcherIn, matcherOut, context, xml );
  2311 + }
  2312 +
  2313 + // Apply postFilter
  2314 + if ( postFilter ) {
  2315 + temp = condense( matcherOut, postMap );
  2316 + postFilter( temp, [], context, xml );
  2317 +
  2318 + // Un-match failing elements by moving them back to matcherIn
  2319 + i = temp.length;
  2320 + while ( i-- ) {
  2321 + if ( (elem = temp[i]) ) {
  2322 + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  2323 + }
  2324 + }
  2325 + }
  2326 +
  2327 + if ( seed ) {
  2328 + if ( postFinder || preFilter ) {
  2329 + if ( postFinder ) {
  2330 + // Get the final matcherOut by condensing this intermediate into postFinder contexts
  2331 + temp = [];
  2332 + i = matcherOut.length;
  2333 + while ( i-- ) {
  2334 + if ( (elem = matcherOut[i]) ) {
  2335 + // Restore matcherIn since elem is not yet a final match
  2336 + temp.push( (matcherIn[i] = elem) );
  2337 + }
  2338 + }
  2339 + postFinder( null, (matcherOut = []), temp, xml );
  2340 + }
  2341 +
  2342 + // Move matched elements from seed to results to keep them synchronized
  2343 + i = matcherOut.length;
  2344 + while ( i-- ) {
  2345 + if ( (elem = matcherOut[i]) &&
  2346 + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
  2347 +
  2348 + seed[temp] = !(results[temp] = elem);
  2349 + }
  2350 + }
  2351 + }
  2352 +
  2353 + // Add elements to results, through postFinder if defined
  2354 + } else {
  2355 + matcherOut = condense(
  2356 + matcherOut === results ?
  2357 + matcherOut.splice( preexisting, matcherOut.length ) :
  2358 + matcherOut
  2359 + );
  2360 + if ( postFinder ) {
  2361 + postFinder( null, results, matcherOut, xml );
  2362 + } else {
  2363 + push.apply( results, matcherOut );
  2364 + }
  2365 + }
  2366 + });
  2367 +}
  2368 +
  2369 +function matcherFromTokens( tokens ) {
  2370 + var checkContext, matcher, j,
  2371 + len = tokens.length,
  2372 + leadingRelative = Expr.relative[ tokens[0].type ],
  2373 + implicitRelative = leadingRelative || Expr.relative[" "],
  2374 + i = leadingRelative ? 1 : 0,
  2375 +
  2376 + // The foundational matcher ensures that elements are reachable from top-level context(s)
  2377 + matchContext = addCombinator( function( elem ) {
  2378 + return elem === checkContext;
  2379 + }, implicitRelative, true ),
  2380 + matchAnyContext = addCombinator( function( elem ) {
  2381 + return indexOf( checkContext, elem ) > -1;
  2382 + }, implicitRelative, true ),
  2383 + matchers = [ function( elem, context, xml ) {
  2384 + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  2385 + (checkContext = context).nodeType ?
  2386 + matchContext( elem, context, xml ) :
  2387 + matchAnyContext( elem, context, xml ) );
  2388 + // Avoid hanging onto element (issue #299)
  2389 + checkContext = null;
  2390 + return ret;
  2391 + } ];
  2392 +
  2393 + for ( ; i < len; i++ ) {
  2394 + if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  2395 + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  2396 + } else {
  2397 + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  2398 +
  2399 + // Return special upon seeing a positional matcher
  2400 + if ( matcher[ expando ] ) {
  2401 + // Find the next relative operator (if any) for proper handling
  2402 + j = ++i;
  2403 + for ( ; j < len; j++ ) {
  2404 + if ( Expr.relative[ tokens[j].type ] ) {
  2405 + break;
  2406 + }
  2407 + }
  2408 + return setMatcher(
  2409 + i > 1 && elementMatcher( matchers ),
  2410 + i > 1 && toSelector(
  2411 + // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  2412 + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  2413 + ).replace( rtrim, "$1" ),
  2414 + matcher,
  2415 + i < j && matcherFromTokens( tokens.slice( i, j ) ),
  2416 + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  2417 + j < len && toSelector( tokens )
  2418 + );
  2419 + }
  2420 + matchers.push( matcher );
  2421 + }
  2422 + }
  2423 +
  2424 + return elementMatcher( matchers );
  2425 +}
  2426 +
  2427 +function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  2428 + var bySet = setMatchers.length > 0,
  2429 + byElement = elementMatchers.length > 0,
  2430 + superMatcher = function( seed, context, xml, results, outermost ) {
  2431 + var elem, j, matcher,
  2432 + matchedCount = 0,
  2433 + i = "0",
  2434 + unmatched = seed && [],
  2435 + setMatched = [],
  2436 + contextBackup = outermostContext,
  2437 + // We must always have either seed elements or outermost context
  2438 + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
  2439 + // Use integer dirruns iff this is the outermost matcher
  2440 + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
  2441 + len = elems.length;
  2442 +
  2443 + if ( outermost ) {
  2444 + outermostContext = context === document || context || outermost;
  2445 + }
  2446 +
  2447 + // Add elements passing elementMatchers directly to results
  2448 + // Support: IE<9, Safari
  2449 + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
  2450 + for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
  2451 + if ( byElement && elem ) {
  2452 + j = 0;
  2453 + if ( !context && elem.ownerDocument !== document ) {
  2454 + setDocument( elem );
  2455 + xml = !documentIsHTML;
  2456 + }
  2457 + while ( (matcher = elementMatchers[j++]) ) {
  2458 + if ( matcher( elem, context || document, xml) ) {
  2459 + results.push( elem );
  2460 + break;
  2461 + }
  2462 + }
  2463 + if ( outermost ) {
  2464 + dirruns = dirrunsUnique;
  2465 + }
  2466 + }
  2467 +
  2468 + // Track unmatched elements for set filters
  2469 + if ( bySet ) {
  2470 + // They will have gone through all possible matchers
  2471 + if ( (elem = !matcher && elem) ) {
  2472 + matchedCount--;
  2473 + }
  2474 +
  2475 + // Lengthen the array for every element, matched or not
  2476 + if ( seed ) {
  2477 + unmatched.push( elem );
  2478 + }
  2479 + }
  2480 + }
  2481 +
  2482 + // `i` is now the count of elements visited above, and adding it to `matchedCount`
  2483 + // makes the latter nonnegative.
  2484 + matchedCount += i;
  2485 +
  2486 + // Apply set filters to unmatched elements
  2487 + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
  2488 + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
  2489 + // no element matchers and no seed.
  2490 + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
  2491 + // case, which will result in a "00" `matchedCount` that differs from `i` but is also
  2492 + // numerically zero.
  2493 + if ( bySet && i !== matchedCount ) {
  2494 + j = 0;
  2495 + while ( (matcher = setMatchers[j++]) ) {
  2496 + matcher( unmatched, setMatched, context, xml );
  2497 + }
  2498 +
  2499 + if ( seed ) {
  2500 + // Reintegrate element matches to eliminate the need for sorting
  2501 + if ( matchedCount > 0 ) {
  2502 + while ( i-- ) {
  2503 + if ( !(unmatched[i] || setMatched[i]) ) {
  2504 + setMatched[i] = pop.call( results );
  2505 + }
  2506 + }
  2507 + }
  2508 +
  2509 + // Discard index placeholder values to get only actual matches
  2510 + setMatched = condense( setMatched );
  2511 + }
  2512 +
  2513 + // Add matches to results
  2514 + push.apply( results, setMatched );
  2515 +
  2516 + // Seedless set matches succeeding multiple successful matchers stipulate sorting
  2517 + if ( outermost && !seed && setMatched.length > 0 &&
  2518 + ( matchedCount + setMatchers.length ) > 1 ) {
  2519 +
  2520 + Sizzle.uniqueSort( results );
  2521 + }
  2522 + }
  2523 +
  2524 + // Override manipulation of globals by nested matchers
  2525 + if ( outermost ) {
  2526 + dirruns = dirrunsUnique;
  2527 + outermostContext = contextBackup;
  2528 + }
  2529 +
  2530 + return unmatched;
  2531 + };
  2532 +
  2533 + return bySet ?
  2534 + markFunction( superMatcher ) :
  2535 + superMatcher;
  2536 +}
  2537 +
  2538 +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
  2539 + var i,
  2540 + setMatchers = [],
  2541 + elementMatchers = [],
  2542 + cached = compilerCache[ selector + " " ];
  2543 +
  2544 + if ( !cached ) {
  2545 + // Generate a function of recursive functions that can be used to check each element
  2546 + if ( !match ) {
  2547 + match = tokenize( selector );
  2548 + }
  2549 + i = match.length;
  2550 + while ( i-- ) {
  2551 + cached = matcherFromTokens( match[i] );
  2552 + if ( cached[ expando ] ) {
  2553 + setMatchers.push( cached );
  2554 + } else {
  2555 + elementMatchers.push( cached );
  2556 + }
  2557 + }
  2558 +
  2559 + // Cache the compiled function
  2560 + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  2561 +
  2562 + // Save selector and tokenization
  2563 + cached.selector = selector;
  2564 + }
  2565 + return cached;
  2566 +};
  2567 +
  2568 +/**
  2569 + * A low-level selection function that works with Sizzle's compiled
  2570 + * selector functions
  2571 + * @param {String|Function} selector A selector or a pre-compiled
  2572 + * selector function built with Sizzle.compile
  2573 + * @param {Element} context
  2574 + * @param {Array} [results]
  2575 + * @param {Array} [seed] A set of elements to match against
  2576 + */
  2577 +select = Sizzle.select = function( selector, context, results, seed ) {
  2578 + var i, tokens, token, type, find,
  2579 + compiled = typeof selector === "function" && selector,
  2580 + match = !seed && tokenize( (selector = compiled.selector || selector) );
  2581 +
  2582 + results = results || [];
  2583 +
  2584 + // Try to minimize operations if there is only one selector in the list and no seed
  2585 + // (the latter of which guarantees us context)
  2586 + if ( match.length === 1 ) {
  2587 +
  2588 + // Reduce context if the leading compound selector is an ID
  2589 + tokens = match[0] = match[0].slice( 0 );
  2590 + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  2591 + support.getById && context.nodeType === 9 && documentIsHTML &&
  2592 + Expr.relative[ tokens[1].type ] ) {
  2593 +
  2594 + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  2595 + if ( !context ) {
  2596 + return results;
  2597 +
  2598 + // Precompiled matchers will still verify ancestry, so step up a level
  2599 + } else if ( compiled ) {
  2600 + context = context.parentNode;
  2601 + }
  2602 +
  2603 + selector = selector.slice( tokens.shift().value.length );
  2604 + }
  2605 +
  2606 + // Fetch a seed set for right-to-left matching
  2607 + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  2608 + while ( i-- ) {
  2609 + token = tokens[i];
  2610 +
  2611 + // Abort if we hit a combinator
  2612 + if ( Expr.relative[ (type = token.type) ] ) {
  2613 + break;
  2614 + }
  2615 + if ( (find = Expr.find[ type ]) ) {
  2616 + // Search, expanding context for leading sibling combinators
  2617 + if ( (seed = find(
  2618 + token.matches[0].replace( runescape, funescape ),
  2619 + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
  2620 + )) ) {
  2621 +
  2622 + // If seed is empty or no tokens remain, we can return early
  2623 + tokens.splice( i, 1 );
  2624 + selector = seed.length && toSelector( tokens );
  2625 + if ( !selector ) {
  2626 + push.apply( results, seed );
  2627 + return results;
  2628 + }
  2629 +
  2630 + break;
  2631 + }
  2632 + }
  2633 + }
  2634 + }
  2635 +
  2636 + // Compile and execute a filtering function if one is not provided
  2637 + // Provide `match` to avoid retokenization if we modified the selector above
  2638 + ( compiled || compile( selector, match ) )(
  2639 + seed,
  2640 + context,
  2641 + !documentIsHTML,
  2642 + results,
  2643 + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
  2644 + );
  2645 + return results;
  2646 +};
  2647 +
  2648 +// One-time assignments
  2649 +
  2650 +// Sort stability
  2651 +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  2652 +
  2653 +// Support: Chrome 14-35+
  2654 +// Always assume duplicates if they aren't passed to the comparison function
  2655 +support.detectDuplicates = !!hasDuplicate;
  2656 +
  2657 +// Initialize against the default document
  2658 +setDocument();
  2659 +
  2660 +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  2661 +// Detached nodes confoundingly follow *each other*
  2662 +support.sortDetached = assert(function( div1 ) {
  2663 + // Should return 1, but returns 4 (following)
  2664 + return div1.compareDocumentPosition( document.createElement("div") ) & 1;
  2665 +});
  2666 +
  2667 +// Support: IE<8
  2668 +// Prevent attribute/property "interpolation"
  2669 +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  2670 +if ( !assert(function( div ) {
  2671 + div.innerHTML = "<a href='#'></a>";
  2672 + return div.firstChild.getAttribute("href") === "#" ;
  2673 +}) ) {
  2674 + addHandle( "type|href|height|width", function( elem, name, isXML ) {
  2675 + if ( !isXML ) {
  2676 + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  2677 + }
  2678 + });
  2679 +}
  2680 +
  2681 +// Support: IE<9
  2682 +// Use defaultValue in place of getAttribute("value")
  2683 +if ( !support.attributes || !assert(function( div ) {
  2684 + div.innerHTML = "<input/>";
  2685 + div.firstChild.setAttribute( "value", "" );
  2686 + return div.firstChild.getAttribute( "value" ) === "";
  2687 +}) ) {
  2688 + addHandle( "value", function( elem, name, isXML ) {
  2689 + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  2690 + return elem.defaultValue;
  2691 + }
  2692 + });
  2693 +}
  2694 +
  2695 +// Support: IE<9
  2696 +// Use getAttributeNode to fetch booleans when getAttribute lies
  2697 +if ( !assert(function( div ) {
  2698 + return div.getAttribute("disabled") == null;
  2699 +}) ) {
  2700 + addHandle( booleans, function( elem, name, isXML ) {
  2701 + var val;
  2702 + if ( !isXML ) {
  2703 + return elem[ name ] === true ? name.toLowerCase() :
  2704 + (val = elem.getAttributeNode( name )) && val.specified ?
  2705 + val.value :
  2706 + null;
  2707 + }
  2708 + });
  2709 +}
  2710 +
  2711 +return Sizzle;
  2712 +
  2713 +})( window );
  2714 +
  2715 +
  2716 +
  2717 +jQuery.find = Sizzle;
  2718 +jQuery.expr = Sizzle.selectors;
  2719 +jQuery.expr[ ":" ] = jQuery.expr.pseudos;
  2720 +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
  2721 +jQuery.text = Sizzle.getText;
  2722 +jQuery.isXMLDoc = Sizzle.isXML;
  2723 +jQuery.contains = Sizzle.contains;
  2724 +
  2725 +
  2726 +
  2727 +var dir = function( elem, dir, until ) {
  2728 + var matched = [],
  2729 + truncate = until !== undefined;
  2730 +
  2731 + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
  2732 + if ( elem.nodeType === 1 ) {
  2733 + if ( truncate && jQuery( elem ).is( until ) ) {
  2734 + break;
  2735 + }
  2736 + matched.push( elem );
  2737 + }
  2738 + }
  2739 + return matched;
  2740 +};
  2741 +
  2742 +
  2743 +var siblings = function( n, elem ) {
  2744 + var matched = [];
  2745 +
  2746 + for ( ; n; n = n.nextSibling ) {
  2747 + if ( n.nodeType === 1 && n !== elem ) {
  2748 + matched.push( n );
  2749 + }
  2750 + }
  2751 +
  2752 + return matched;
  2753 +};
  2754 +
  2755 +
  2756 +var rneedsContext = jQuery.expr.match.needsContext;
  2757 +
  2758 +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
  2759 +
  2760 +
  2761 +
  2762 +var risSimple = /^.[^:#\[\.,]*$/;
  2763 +
  2764 +// Implement the identical functionality for filter and not
  2765 +function winnow( elements, qualifier, not ) {
  2766 + if ( jQuery.isFunction( qualifier ) ) {
  2767 + return jQuery.grep( elements, function( elem, i ) {
  2768 + /* jshint -W018 */
  2769 + return !!qualifier.call( elem, i, elem ) !== not;
  2770 + } );
  2771 +
  2772 + }
  2773 +
  2774 + if ( qualifier.nodeType ) {
  2775 + return jQuery.grep( elements, function( elem ) {
  2776 + return ( elem === qualifier ) !== not;
  2777 + } );
  2778 +
  2779 + }
  2780 +
  2781 + if ( typeof qualifier === "string" ) {
  2782 + if ( risSimple.test( qualifier ) ) {
  2783 + return jQuery.filter( qualifier, elements, not );
  2784 + }
  2785 +
  2786 + qualifier = jQuery.filter( qualifier, elements );
  2787 + }
  2788 +
  2789 + return jQuery.grep( elements, function( elem ) {
  2790 + return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
  2791 + } );
  2792 +}
  2793 +
  2794 +jQuery.filter = function( expr, elems, not ) {
  2795 + var elem = elems[ 0 ];
  2796 +
  2797 + if ( not ) {
  2798 + expr = ":not(" + expr + ")";
  2799 + }
  2800 +
  2801 + return elems.length === 1 && elem.nodeType === 1 ?
  2802 + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
  2803 + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  2804 + return elem.nodeType === 1;
  2805 + } ) );
  2806 +};
  2807 +
  2808 +jQuery.fn.extend( {
  2809 + find: function( selector ) {
  2810 + var i,
  2811 + ret = [],
  2812 + self = this,
  2813 + len = self.length;
  2814 +
  2815 + if ( typeof selector !== "string" ) {
  2816 + return this.pushStack( jQuery( selector ).filter( function() {
  2817 + for ( i = 0; i < len; i++ ) {
  2818 + if ( jQuery.contains( self[ i ], this ) ) {
  2819 + return true;
  2820 + }
  2821 + }
  2822 + } ) );
  2823 + }
  2824 +
  2825 + for ( i = 0; i < len; i++ ) {
  2826 + jQuery.find( selector, self[ i ], ret );
  2827 + }
  2828 +
  2829 + // Needed because $( selector, context ) becomes $( context ).find( selector )
  2830 + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
  2831 + ret.selector = this.selector ? this.selector + " " + selector : selector;
  2832 + return ret;
  2833 + },
  2834 + filter: function( selector ) {
  2835 + return this.pushStack( winnow( this, selector || [], false ) );
  2836 + },
  2837 + not: function( selector ) {
  2838 + return this.pushStack( winnow( this, selector || [], true ) );
  2839 + },
  2840 + is: function( selector ) {
  2841 + return !!winnow(
  2842 + this,
  2843 +
  2844 + // If this is a positional/relative selector, check membership in the returned set
  2845 + // so $("p:first").is("p:last") won't return true for a doc with two "p".
  2846 + typeof selector === "string" && rneedsContext.test( selector ) ?
  2847 + jQuery( selector ) :
  2848 + selector || [],
  2849 + false
  2850 + ).length;
  2851 + }
  2852 +} );
  2853 +
  2854 +
  2855 +// Initialize a jQuery object
  2856 +
  2857 +
  2858 +// A central reference to the root jQuery(document)
  2859 +var rootjQuery,
  2860 +
  2861 + // A simple way to check for HTML strings
  2862 + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  2863 + // Strict HTML recognition (#11290: must start with <)
  2864 + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  2865 +
  2866 + init = jQuery.fn.init = function( selector, context, root ) {
  2867 + var match, elem;
  2868 +
  2869 + // HANDLE: $(""), $(null), $(undefined), $(false)
  2870 + if ( !selector ) {
  2871 + return this;
  2872 + }
  2873 +
  2874 + // init accepts an alternate rootjQuery
  2875 + // so migrate can support jQuery.sub (gh-2101)
  2876 + root = root || rootjQuery;
  2877 +
  2878 + // Handle HTML strings
  2879 + if ( typeof selector === "string" ) {
  2880 + if ( selector.charAt( 0 ) === "<" &&
  2881 + selector.charAt( selector.length - 1 ) === ">" &&
  2882 + selector.length >= 3 ) {
  2883 +
  2884 + // Assume that strings that start and end with <> are HTML and skip the regex check
  2885 + match = [ null, selector, null ];
  2886 +
  2887 + } else {
  2888 + match = rquickExpr.exec( selector );
  2889 + }
  2890 +
  2891 + // Match html or make sure no context is specified for #id
  2892 + if ( match && ( match[ 1 ] || !context ) ) {
  2893 +
  2894 + // HANDLE: $(html) -> $(array)
  2895 + if ( match[ 1 ] ) {
  2896 + context = context instanceof jQuery ? context[ 0 ] : context;
  2897 +
  2898 + // scripts is true for back-compat
  2899 + // Intentionally let the error be thrown if parseHTML is not present
  2900 + jQuery.merge( this, jQuery.parseHTML(
  2901 + match[ 1 ],
  2902 + context && context.nodeType ? context.ownerDocument || context : document,
  2903 + true
  2904 + ) );
  2905 +
  2906 + // HANDLE: $(html, props)
  2907 + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
  2908 + for ( match in context ) {
  2909 +
  2910 + // Properties of context are called as methods if possible
  2911 + if ( jQuery.isFunction( this[ match ] ) ) {
  2912 + this[ match ]( context[ match ] );
  2913 +
  2914 + // ...and otherwise set as attributes
  2915 + } else {
  2916 + this.attr( match, context[ match ] );
  2917 + }
  2918 + }
  2919 + }
  2920 +
  2921 + return this;
  2922 +
  2923 + // HANDLE: $(#id)
  2924 + } else {
  2925 + elem = document.getElementById( match[ 2 ] );
  2926 +
  2927 + // Check parentNode to catch when Blackberry 4.6 returns
  2928 + // nodes that are no longer in the document #6963
  2929 + if ( elem && elem.parentNode ) {
  2930 +
  2931 + // Handle the case where IE and Opera return items
  2932 + // by name instead of ID
  2933 + if ( elem.id !== match[ 2 ] ) {
  2934 + return rootjQuery.find( selector );
  2935 + }
  2936 +
  2937 + // Otherwise, we inject the element directly into the jQuery object
  2938 + this.length = 1;
  2939 + this[ 0 ] = elem;
  2940 + }
  2941 +
  2942 + this.context = document;
  2943 + this.selector = selector;
  2944 + return this;
  2945 + }
  2946 +
  2947 + // HANDLE: $(expr, $(...))
  2948 + } else if ( !context || context.jquery ) {
  2949 + return ( context || root ).find( selector );
  2950 +
  2951 + // HANDLE: $(expr, context)
  2952 + // (which is just equivalent to: $(context).find(expr)
  2953 + } else {
  2954 + return this.constructor( context ).find( selector );
  2955 + }
  2956 +
  2957 + // HANDLE: $(DOMElement)
  2958 + } else if ( selector.nodeType ) {
  2959 + this.context = this[ 0 ] = selector;
  2960 + this.length = 1;
  2961 + return this;
  2962 +
  2963 + // HANDLE: $(function)
  2964 + // Shortcut for document ready
  2965 + } else if ( jQuery.isFunction( selector ) ) {
  2966 + return typeof root.ready !== "undefined" ?
  2967 + root.ready( selector ) :
  2968 +
  2969 + // Execute immediately if ready is not present
  2970 + selector( jQuery );
  2971 + }
  2972 +
  2973 + if ( selector.selector !== undefined ) {
  2974 + this.selector = selector.selector;
  2975 + this.context = selector.context;
  2976 + }
  2977 +
  2978 + return jQuery.makeArray( selector, this );
  2979 + };
  2980 +
  2981 +// Give the init function the jQuery prototype for later instantiation
  2982 +init.prototype = jQuery.fn;
  2983 +
  2984 +// Initialize central reference
  2985 +rootjQuery = jQuery( document );
  2986 +
  2987 +
  2988 +var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  2989 +
  2990 + // methods guaranteed to produce a unique set when starting from a unique set
  2991 + guaranteedUnique = {
  2992 + children: true,
  2993 + contents: true,
  2994 + next: true,
  2995 + prev: true
  2996 + };
  2997 +
  2998 +jQuery.fn.extend( {
  2999 + has: function( target ) {
  3000 + var i,
  3001 + targets = jQuery( target, this ),
  3002 + len = targets.length;
  3003 +
  3004 + return this.filter( function() {
  3005 + for ( i = 0; i < len; i++ ) {
  3006 + if ( jQuery.contains( this, targets[ i ] ) ) {
  3007 + return true;
  3008 + }
  3009 + }
  3010 + } );
  3011 + },
  3012 +
  3013 + closest: function( selectors, context ) {
  3014 + var cur,
  3015 + i = 0,
  3016 + l = this.length,
  3017 + matched = [],
  3018 + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
  3019 + jQuery( selectors, context || this.context ) :
  3020 + 0;
  3021 +
  3022 + for ( ; i < l; i++ ) {
  3023 + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
  3024 +
  3025 + // Always skip document fragments
  3026 + if ( cur.nodeType < 11 && ( pos ?
  3027 + pos.index( cur ) > -1 :
  3028 +
  3029 + // Don't pass non-elements to Sizzle
  3030 + cur.nodeType === 1 &&
  3031 + jQuery.find.matchesSelector( cur, selectors ) ) ) {
  3032 +
  3033 + matched.push( cur );
  3034 + break;
  3035 + }
  3036 + }
  3037 + }
  3038 +
  3039 + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
  3040 + },
  3041 +
  3042 + // Determine the position of an element within
  3043 + // the matched set of elements
  3044 + index: function( elem ) {
  3045 +
  3046 + // No argument, return index in parent
  3047 + if ( !elem ) {
  3048 + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  3049 + }
  3050 +
  3051 + // index in selector
  3052 + if ( typeof elem === "string" ) {
  3053 + return jQuery.inArray( this[ 0 ], jQuery( elem ) );
  3054 + }
  3055 +
  3056 + // Locate the position of the desired element
  3057 + return jQuery.inArray(
  3058 +
  3059 + // If it receives a jQuery object, the first element is used
  3060 + elem.jquery ? elem[ 0 ] : elem, this );
  3061 + },
  3062 +
  3063 + add: function( selector, context ) {
  3064 + return this.pushStack(
  3065 + jQuery.uniqueSort(
  3066 + jQuery.merge( this.get(), jQuery( selector, context ) )
  3067 + )
  3068 + );
  3069 + },
  3070 +
  3071 + addBack: function( selector ) {
  3072 + return this.add( selector == null ?
  3073 + this.prevObject : this.prevObject.filter( selector )
  3074 + );
  3075 + }
  3076 +} );
  3077 +
  3078 +function sibling( cur, dir ) {
  3079 + do {
  3080 + cur = cur[ dir ];
  3081 + } while ( cur && cur.nodeType !== 1 );
  3082 +
  3083 + return cur;
  3084 +}
  3085 +
  3086 +jQuery.each( {
  3087 + parent: function( elem ) {
  3088 + var parent = elem.parentNode;
  3089 + return parent && parent.nodeType !== 11 ? parent : null;
  3090 + },
  3091 + parents: function( elem ) {
  3092 + return dir( elem, "parentNode" );
  3093 + },
  3094 + parentsUntil: function( elem, i, until ) {
  3095 + return dir( elem, "parentNode", until );
  3096 + },
  3097 + next: function( elem ) {
  3098 + return sibling( elem, "nextSibling" );
  3099 + },
  3100 + prev: function( elem ) {
  3101 + return sibling( elem, "previousSibling" );
  3102 + },
  3103 + nextAll: function( elem ) {
  3104 + return dir( elem, "nextSibling" );
  3105 + },
  3106 + prevAll: function( elem ) {
  3107 + return dir( elem, "previousSibling" );
  3108 + },
  3109 + nextUntil: function( elem, i, until ) {
  3110 + return dir( elem, "nextSibling", until );
  3111 + },
  3112 + prevUntil: function( elem, i, until ) {
  3113 + return dir( elem, "previousSibling", until );
  3114 + },
  3115 + siblings: function( elem ) {
  3116 + return siblings( ( elem.parentNode || {} ).firstChild, elem );
  3117 + },
  3118 + children: function( elem ) {
  3119 + return siblings( elem.firstChild );
  3120 + },
  3121 + contents: function( elem ) {
  3122 + return jQuery.nodeName( elem, "iframe" ) ?
  3123 + elem.contentDocument || elem.contentWindow.document :
  3124 + jQuery.merge( [], elem.childNodes );
  3125 + }
  3126 +}, function( name, fn ) {
  3127 + jQuery.fn[ name ] = function( until, selector ) {
  3128 + var ret = jQuery.map( this, fn, until );
  3129 +
  3130 + if ( name.slice( -5 ) !== "Until" ) {
  3131 + selector = until;
  3132 + }
  3133 +
  3134 + if ( selector && typeof selector === "string" ) {
  3135 + ret = jQuery.filter( selector, ret );
  3136 + }
  3137 +
  3138 + if ( this.length > 1 ) {
  3139 +
  3140 + // Remove duplicates
  3141 + if ( !guaranteedUnique[ name ] ) {
  3142 + ret = jQuery.uniqueSort( ret );
  3143 + }
  3144 +
  3145 + // Reverse order for parents* and prev-derivatives
  3146 + if ( rparentsprev.test( name ) ) {
  3147 + ret = ret.reverse();
  3148 + }
  3149 + }
  3150 +
  3151 + return this.pushStack( ret );
  3152 + };
  3153 +} );
  3154 +var rnotwhite = ( /\S+/g );
  3155 +
  3156 +
  3157 +
  3158 +// Convert String-formatted options into Object-formatted ones
  3159 +function createOptions( options ) {
  3160 + var object = {};
  3161 + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
  3162 + object[ flag ] = true;
  3163 + } );
  3164 + return object;
  3165 +}
  3166 +
  3167 +/*
  3168 + * Create a callback list using the following parameters:
  3169 + *
  3170 + * options: an optional list of space-separated options that will change how
  3171 + * the callback list behaves or a more traditional option object
  3172 + *
  3173 + * By default a callback list will act like an event callback list and can be
  3174 + * "fired" multiple times.
  3175 + *
  3176 + * Possible options:
  3177 + *
  3178 + * once: will ensure the callback list can only be fired once (like a Deferred)
  3179 + *
  3180 + * memory: will keep track of previous values and will call any callback added
  3181 + * after the list has been fired right away with the latest "memorized"
  3182 + * values (like a Deferred)
  3183 + *
  3184 + * unique: will ensure a callback can only be added once (no duplicate in the list)
  3185 + *
  3186 + * stopOnFalse: interrupt callings when a callback returns false
  3187 + *
  3188 + */
  3189 +jQuery.Callbacks = function( options ) {
  3190 +
  3191 + // Convert options from String-formatted to Object-formatted if needed
  3192 + // (we check in cache first)
  3193 + options = typeof options === "string" ?
  3194 + createOptions( options ) :
  3195 + jQuery.extend( {}, options );
  3196 +
  3197 + var // Flag to know if list is currently firing
  3198 + firing,
  3199 +
  3200 + // Last fire value for non-forgettable lists
  3201 + memory,
  3202 +
  3203 + // Flag to know if list was already fired
  3204 + fired,
  3205 +
  3206 + // Flag to prevent firing
  3207 + locked,
  3208 +
  3209 + // Actual callback list
  3210 + list = [],
  3211 +
  3212 + // Queue of execution data for repeatable lists
  3213 + queue = [],
  3214 +
  3215 + // Index of currently firing callback (modified by add/remove as needed)
  3216 + firingIndex = -1,
  3217 +
  3218 + // Fire callbacks
  3219 + fire = function() {
  3220 +
  3221 + // Enforce single-firing
  3222 + locked = options.once;
  3223 +
  3224 + // Execute callbacks for all pending executions,
  3225 + // respecting firingIndex overrides and runtime changes
  3226 + fired = firing = true;
  3227 + for ( ; queue.length; firingIndex = -1 ) {
  3228 + memory = queue.shift();
  3229 + while ( ++firingIndex < list.length ) {
  3230 +
  3231 + // Run callback and check for early termination
  3232 + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
  3233 + options.stopOnFalse ) {
  3234 +
  3235 + // Jump to end and forget the data so .add doesn't re-fire
  3236 + firingIndex = list.length;
  3237 + memory = false;
  3238 + }
  3239 + }
  3240 + }
  3241 +
  3242 + // Forget the data if we're done with it
  3243 + if ( !options.memory ) {
  3244 + memory = false;
  3245 + }
  3246 +
  3247 + firing = false;
  3248 +
  3249 + // Clean up if we're done firing for good
  3250 + if ( locked ) {
  3251 +
  3252 + // Keep an empty list if we have data for future add calls
  3253 + if ( memory ) {
  3254 + list = [];
  3255 +
  3256 + // Otherwise, this object is spent
  3257 + } else {
  3258 + list = "";
  3259 + }
  3260 + }
  3261 + },
  3262 +
  3263 + // Actual Callbacks object
  3264 + self = {
  3265 +
  3266 + // Add a callback or a collection of callbacks to the list
  3267 + add: function() {
  3268 + if ( list ) {
  3269 +
  3270 + // If we have memory from a past run, we should fire after adding
  3271 + if ( memory && !firing ) {
  3272 + firingIndex = list.length - 1;
  3273 + queue.push( memory );
  3274 + }
  3275 +
  3276 + ( function add( args ) {
  3277 + jQuery.each( args, function( _, arg ) {
  3278 + if ( jQuery.isFunction( arg ) ) {
  3279 + if ( !options.unique || !self.has( arg ) ) {
  3280 + list.push( arg );
  3281 + }
  3282 + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
  3283 +
  3284 + // Inspect recursively
  3285 + add( arg );
  3286 + }
  3287 + } );
  3288 + } )( arguments );
  3289 +
  3290 + if ( memory && !firing ) {
  3291 + fire();
  3292 + }
  3293 + }
  3294 + return this;
  3295 + },
  3296 +
  3297 + // Remove a callback from the list
  3298 + remove: function() {
  3299 + jQuery.each( arguments, function( _, arg ) {
  3300 + var index;
  3301 + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  3302 + list.splice( index, 1 );
  3303 +
  3304 + // Handle firing indexes
  3305 + if ( index <= firingIndex ) {
  3306 + firingIndex--;
  3307 + }
  3308 + }
  3309 + } );
  3310 + return this;
  3311 + },
  3312 +
  3313 + // Check if a given callback is in the list.
  3314 + // If no argument is given, return whether or not list has callbacks attached.
  3315 + has: function( fn ) {
  3316 + return fn ?
  3317 + jQuery.inArray( fn, list ) > -1 :
  3318 + list.length > 0;
  3319 + },
  3320 +
  3321 + // Remove all callbacks from the list
  3322 + empty: function() {
  3323 + if ( list ) {
  3324 + list = [];
  3325 + }
  3326 + return this;
  3327 + },
  3328 +
  3329 + // Disable .fire and .add
  3330 + // Abort any current/pending executions
  3331 + // Clear all callbacks and values
  3332 + disable: function() {
  3333 + locked = queue = [];
  3334 + list = memory = "";
  3335 + return this;
  3336 + },
  3337 + disabled: function() {
  3338 + return !list;
  3339 + },
  3340 +
  3341 + // Disable .fire
  3342 + // Also disable .add unless we have memory (since it would have no effect)
  3343 + // Abort any pending executions
  3344 + lock: function() {
  3345 + locked = true;
  3346 + if ( !memory ) {
  3347 + self.disable();
  3348 + }
  3349 + return this;
  3350 + },
  3351 + locked: function() {
  3352 + return !!locked;
  3353 + },
  3354 +
  3355 + // Call all callbacks with the given context and arguments
  3356 + fireWith: function( context, args ) {
  3357 + if ( !locked ) {
  3358 + args = args || [];
  3359 + args = [ context, args.slice ? args.slice() : args ];
  3360 + queue.push( args );
  3361 + if ( !firing ) {
  3362 + fire();
  3363 + }
  3364 + }
  3365 + return this;
  3366 + },
  3367 +
  3368 + // Call all the callbacks with the given arguments
  3369 + fire: function() {
  3370 + self.fireWith( this, arguments );
  3371 + return this;
  3372 + },
  3373 +
  3374 + // To know if the callbacks have already been called at least once
  3375 + fired: function() {
  3376 + return !!fired;
  3377 + }
  3378 + };
  3379 +
  3380 + return self;
  3381 +};
  3382 +
  3383 +
  3384 +jQuery.extend( {
  3385 +
  3386 + Deferred: function( func ) {
  3387 + var tuples = [
  3388 +
  3389 + // action, add listener, listener list, final state
  3390 + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
  3391 + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
  3392 + [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
  3393 + ],
  3394 + state = "pending",
  3395 + promise = {
  3396 + state: function() {
  3397 + return state;
  3398 + },
  3399 + always: function() {
  3400 + deferred.done( arguments ).fail( arguments );
  3401 + return this;
  3402 + },
  3403 + then: function( /* fnDone, fnFail, fnProgress */ ) {
  3404 + var fns = arguments;
  3405 + return jQuery.Deferred( function( newDefer ) {
  3406 + jQuery.each( tuples, function( i, tuple ) {
  3407 + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  3408 +
  3409 + // deferred[ done | fail | progress ] for forwarding actions to newDefer
  3410 + deferred[ tuple[ 1 ] ]( function() {
  3411 + var returned = fn && fn.apply( this, arguments );
  3412 + if ( returned && jQuery.isFunction( returned.promise ) ) {
  3413 + returned.promise()
  3414 + .progress( newDefer.notify )
  3415 + .done( newDefer.resolve )
  3416 + .fail( newDefer.reject );
  3417 + } else {
  3418 + newDefer[ tuple[ 0 ] + "With" ](
  3419 + this === promise ? newDefer.promise() : this,
  3420 + fn ? [ returned ] : arguments
  3421 + );
  3422 + }
  3423 + } );
  3424 + } );
  3425 + fns = null;
  3426 + } ).promise();
  3427 + },
  3428 +
  3429 + // Get a promise for this deferred
  3430 + // If obj is provided, the promise aspect is added to the object
  3431 + promise: function( obj ) {
  3432 + return obj != null ? jQuery.extend( obj, promise ) : promise;
  3433 + }
  3434 + },
  3435 + deferred = {};
  3436 +
  3437 + // Keep pipe for back-compat
  3438 + promise.pipe = promise.then;
  3439 +
  3440 + // Add list-specific methods
  3441 + jQuery.each( tuples, function( i, tuple ) {
  3442 + var list = tuple[ 2 ],
  3443 + stateString = tuple[ 3 ];
  3444 +
  3445 + // promise[ done | fail | progress ] = list.add
  3446 + promise[ tuple[ 1 ] ] = list.add;
  3447 +
  3448 + // Handle state
  3449 + if ( stateString ) {
  3450 + list.add( function() {
  3451 +
  3452 + // state = [ resolved | rejected ]
  3453 + state = stateString;
  3454 +
  3455 + // [ reject_list | resolve_list ].disable; progress_list.lock
  3456 + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
  3457 + }
  3458 +
  3459 + // deferred[ resolve | reject | notify ]
  3460 + deferred[ tuple[ 0 ] ] = function() {
  3461 + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
  3462 + return this;
  3463 + };
  3464 + deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
  3465 + } );
  3466 +
  3467 + // Make the deferred a promise
  3468 + promise.promise( deferred );
  3469 +
  3470 + // Call given func if any
  3471 + if ( func ) {
  3472 + func.call( deferred, deferred );
  3473 + }
  3474 +
  3475 + // All done!
  3476 + return deferred;
  3477 + },
  3478 +
  3479 + // Deferred helper
  3480 + when: function( subordinate /* , ..., subordinateN */ ) {
  3481 + var i = 0,
  3482 + resolveValues = slice.call( arguments ),
  3483 + length = resolveValues.length,
  3484 +
  3485 + // the count of uncompleted subordinates
  3486 + remaining = length !== 1 ||
  3487 + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
  3488 +
  3489 + // the master Deferred.
  3490 + // If resolveValues consist of only a single Deferred, just use that.
  3491 + deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  3492 +
  3493 + // Update function for both resolve and progress values
  3494 + updateFunc = function( i, contexts, values ) {
  3495 + return function( value ) {
  3496 + contexts[ i ] = this;
  3497 + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
  3498 + if ( values === progressValues ) {
  3499 + deferred.notifyWith( contexts, values );
  3500 +
  3501 + } else if ( !( --remaining ) ) {
  3502 + deferred.resolveWith( contexts, values );
  3503 + }
  3504 + };
  3505 + },
  3506 +
  3507 + progressValues, progressContexts, resolveContexts;
  3508 +
  3509 + // add listeners to Deferred subordinates; treat others as resolved
  3510 + if ( length > 1 ) {
  3511 + progressValues = new Array( length );
  3512 + progressContexts = new Array( length );
  3513 + resolveContexts = new Array( length );
  3514 + for ( ; i < length; i++ ) {
  3515 + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
  3516 + resolveValues[ i ].promise()
  3517 + .progress( updateFunc( i, progressContexts, progressValues ) )
  3518 + .done( updateFunc( i, resolveContexts, resolveValues ) )
  3519 + .fail( deferred.reject );
  3520 + } else {
  3521 + --remaining;
  3522 + }
  3523 + }
  3524 + }
  3525 +
  3526 + // if we're not waiting on anything, resolve the master
  3527 + if ( !remaining ) {
  3528 + deferred.resolveWith( resolveContexts, resolveValues );
  3529 + }
  3530 +
  3531 + return deferred.promise();
  3532 + }
  3533 +} );
  3534 +
  3535 +
  3536 +// The deferred used on DOM ready
  3537 +var readyList;
  3538 +
  3539 +jQuery.fn.ready = function( fn ) {
  3540 +
  3541 + // Add the callback
  3542 + jQuery.ready.promise().done( fn );
  3543 +
  3544 + return this;
  3545 +};
  3546 +
  3547 +jQuery.extend( {
  3548 +
  3549 + // Is the DOM ready to be used? Set to true once it occurs.
  3550 + isReady: false,
  3551 +
  3552 + // A counter to track how many items to wait for before
  3553 + // the ready event fires. See #6781
  3554 + readyWait: 1,
  3555 +
  3556 + // Hold (or release) the ready event
  3557 + holdReady: function( hold ) {
  3558 + if ( hold ) {
  3559 + jQuery.readyWait++;
  3560 + } else {
  3561 + jQuery.ready( true );
  3562 + }
  3563 + },
  3564 +
  3565 + // Handle when the DOM is ready
  3566 + ready: function( wait ) {
  3567 +
  3568 + // Abort if there are pending holds or we're already ready
  3569 + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  3570 + return;
  3571 + }
  3572 +
  3573 + // Remember that the DOM is ready
  3574 + jQuery.isReady = true;
  3575 +
  3576 + // If a normal DOM Ready event fired, decrement, and wait if need be
  3577 + if ( wait !== true && --jQuery.readyWait > 0 ) {
  3578 + return;
  3579 + }
  3580 +
  3581 + // If there are functions bound, to execute
  3582 + readyList.resolveWith( document, [ jQuery ] );
  3583 +
  3584 + // Trigger any bound ready events
  3585 + if ( jQuery.fn.triggerHandler ) {
  3586 + jQuery( document ).triggerHandler( "ready" );
  3587 + jQuery( document ).off( "ready" );
  3588 + }
  3589 + }
  3590 +} );
  3591 +
  3592 +/**
  3593 + * Clean-up method for dom ready events
  3594 + */
  3595 +function detach() {
  3596 + if ( document.addEventListener ) {
  3597 + document.removeEventListener( "DOMContentLoaded", completed );
  3598 + window.removeEventListener( "load", completed );
  3599 +
  3600 + } else {
  3601 + document.detachEvent( "onreadystatechange", completed );
  3602 + window.detachEvent( "onload", completed );
  3603 + }
  3604 +}
  3605 +
  3606 +/**
  3607 + * The ready event handler and self cleanup method
  3608 + */
  3609 +function completed() {
  3610 +
  3611 + // readyState === "complete" is good enough for us to call the dom ready in oldIE
  3612 + if ( document.addEventListener ||
  3613 + window.event.type === "load" ||
  3614 + document.readyState === "complete" ) {
  3615 +
  3616 + detach();
  3617 + jQuery.ready();
  3618 + }
  3619 +}
  3620 +
  3621 +jQuery.ready.promise = function( obj ) {
  3622 + if ( !readyList ) {
  3623 +
  3624 + readyList = jQuery.Deferred();
  3625 +
  3626 + // Catch cases where $(document).ready() is called
  3627 + // after the browser event has already occurred.
  3628 + // Support: IE6-10
  3629 + // Older IE sometimes signals "interactive" too soon
  3630 + if ( document.readyState === "complete" ||
  3631 + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
  3632 +
  3633 + // Handle it asynchronously to allow scripts the opportunity to delay ready
  3634 + window.setTimeout( jQuery.ready );
  3635 +
  3636 + // Standards-based browsers support DOMContentLoaded
  3637 + } else if ( document.addEventListener ) {
  3638 +
  3639 + // Use the handy event callback
  3640 + document.addEventListener( "DOMContentLoaded", completed );
  3641 +
  3642 + // A fallback to window.onload, that will always work
  3643 + window.addEventListener( "load", completed );
  3644 +
  3645 + // If IE event model is used
  3646 + } else {
  3647 +
  3648 + // Ensure firing before onload, maybe late but safe also for iframes
  3649 + document.attachEvent( "onreadystatechange", completed );
  3650 +
  3651 + // A fallback to window.onload, that will always work
  3652 + window.attachEvent( "onload", completed );
  3653 +
  3654 + // If IE and not a frame
  3655 + // continually check to see if the document is ready
  3656 + var top = false;
  3657 +
  3658 + try {
  3659 + top = window.frameElement == null && document.documentElement;
  3660 + } catch ( e ) {}
  3661 +
  3662 + if ( top && top.doScroll ) {
  3663 + ( function doScrollCheck() {
  3664 + if ( !jQuery.isReady ) {
  3665 +
  3666 + try {
  3667 +
  3668 + // Use the trick by Diego Perini
  3669 + // http://javascript.nwbox.com/IEContentLoaded/
  3670 + top.doScroll( "left" );
  3671 + } catch ( e ) {
  3672 + return window.setTimeout( doScrollCheck, 50 );
  3673 + }
  3674 +
  3675 + // detach all dom ready events
  3676 + detach();
  3677 +
  3678 + // and execute any waiting functions
  3679 + jQuery.ready();
  3680 + }
  3681 + } )();
  3682 + }
  3683 + }
  3684 + }
  3685 + return readyList.promise( obj );
  3686 +};
  3687 +
  3688 +// Kick off the DOM ready check even if the user does not
  3689 +jQuery.ready.promise();
  3690 +
  3691 +
  3692 +
  3693 +
  3694 +// Support: IE<9
  3695 +// Iteration over object's inherited properties before its own
  3696 +var i;
  3697 +for ( i in jQuery( support ) ) {
  3698 + break;
  3699 +}
  3700 +support.ownFirst = i === "0";
  3701 +
  3702 +// Note: most support tests are defined in their respective modules.
  3703 +// false until the test is run
  3704 +support.inlineBlockNeedsLayout = false;
  3705 +
  3706 +// Execute ASAP in case we need to set body.style.zoom
  3707 +jQuery( function() {
  3708 +
  3709 + // Minified: var a,b,c,d
  3710 + var val, div, body, container;
  3711 +
  3712 + body = document.getElementsByTagName( "body" )[ 0 ];
  3713 + if ( !body || !body.style ) {
  3714 +
  3715 + // Return for frameset docs that don't have a body
  3716 + return;
  3717 + }
  3718 +
  3719 + // Setup
  3720 + div = document.createElement( "div" );
  3721 + container = document.createElement( "div" );
  3722 + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
  3723 + body.appendChild( container ).appendChild( div );
  3724 +
  3725 + if ( typeof div.style.zoom !== "undefined" ) {
  3726 +
  3727 + // Support: IE<8
  3728 + // Check if natively block-level elements act like inline-block
  3729 + // elements when setting their display to 'inline' and giving
  3730 + // them layout
  3731 + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
  3732 +
  3733 + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
  3734 + if ( val ) {
  3735 +
  3736 + // Prevent IE 6 from affecting layout for positioned elements #11048
  3737 + // Prevent IE from shrinking the body in IE 7 mode #12869
  3738 + // Support: IE<8
  3739 + body.style.zoom = 1;
  3740 + }
  3741 + }
  3742 +
  3743 + body.removeChild( container );
  3744 +} );
  3745 +
  3746 +
  3747 +( function() {
  3748 + var div = document.createElement( "div" );
  3749 +
  3750 + // Support: IE<9
  3751 + support.deleteExpando = true;
  3752 + try {
  3753 + delete div.test;
  3754 + } catch ( e ) {
  3755 + support.deleteExpando = false;
  3756 + }
  3757 +
  3758 + // Null elements to avoid leaks in IE.
  3759 + div = null;
  3760 +} )();
  3761 +var acceptData = function( elem ) {
  3762 + var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
  3763 + nodeType = +elem.nodeType || 1;
  3764 +
  3765 + // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
  3766 + return nodeType !== 1 && nodeType !== 9 ?
  3767 + false :
  3768 +
  3769 + // Nodes accept data unless otherwise specified; rejection can be conditional
  3770 + !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
  3771 +};
  3772 +
  3773 +
  3774 +
  3775 +
  3776 +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  3777 + rmultiDash = /([A-Z])/g;
  3778 +
  3779 +function dataAttr( elem, key, data ) {
  3780 +
  3781 + // If nothing was found internally, try to fetch any
  3782 + // data from the HTML5 data-* attribute
  3783 + if ( data === undefined && elem.nodeType === 1 ) {
  3784 +
  3785 + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
  3786 +
  3787 + data = elem.getAttribute( name );
  3788 +
  3789 + if ( typeof data === "string" ) {
  3790 + try {
  3791 + data = data === "true" ? true :
  3792 + data === "false" ? false :
  3793 + data === "null" ? null :
  3794 +
  3795 + // Only convert to a number if it doesn't change the string
  3796 + +data + "" === data ? +data :
  3797 + rbrace.test( data ) ? jQuery.parseJSON( data ) :
  3798 + data;
  3799 + } catch ( e ) {}
  3800 +
  3801 + // Make sure we set the data so it isn't changed later
  3802 + jQuery.data( elem, key, data );
  3803 +
  3804 + } else {
  3805 + data = undefined;
  3806 + }
  3807 + }
  3808 +
  3809 + return data;
  3810 +}
  3811 +
  3812 +// checks a cache object for emptiness
  3813 +function isEmptyDataObject( obj ) {
  3814 + var name;
  3815 + for ( name in obj ) {
  3816 +
  3817 + // if the public data object is empty, the private is still empty
  3818 + if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
  3819 + continue;
  3820 + }
  3821 + if ( name !== "toJSON" ) {
  3822 + return false;
  3823 + }
  3824 + }
  3825 +
  3826 + return true;
  3827 +}
  3828 +
  3829 +function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
  3830 + if ( !acceptData( elem ) ) {
  3831 + return;
  3832 + }
  3833 +
  3834 + var ret, thisCache,
  3835 + internalKey = jQuery.expando,
  3836 +
  3837 + // We have to handle DOM nodes and JS objects differently because IE6-7
  3838 + // can't GC object references properly across the DOM-JS boundary
  3839 + isNode = elem.nodeType,
  3840 +
  3841 + // Only DOM nodes need the global jQuery cache; JS object data is
  3842 + // attached directly to the object so GC can occur automatically
  3843 + cache = isNode ? jQuery.cache : elem,
  3844 +
  3845 + // Only defining an ID for JS objects if its cache already exists allows
  3846 + // the code to shortcut on the same path as a DOM node with no cache
  3847 + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
  3848 +
  3849 + // Avoid doing any more work than we need to when trying to get data on an
  3850 + // object that has no data at all
  3851 + if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
  3852 + data === undefined && typeof name === "string" ) {
  3853 + return;
  3854 + }
  3855 +
  3856 + if ( !id ) {
  3857 +
  3858 + // Only DOM nodes need a new unique ID for each element since their data
  3859 + // ends up in the global cache
  3860 + if ( isNode ) {
  3861 + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
  3862 + } else {
  3863 + id = internalKey;
  3864 + }
  3865 + }
  3866 +
  3867 + if ( !cache[ id ] ) {
  3868 +
  3869 + // Avoid exposing jQuery metadata on plain JS objects when the object
  3870 + // is serialized using JSON.stringify
  3871 + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
  3872 + }
  3873 +
  3874 + // An object can be passed to jQuery.data instead of a key/value pair; this gets
  3875 + // shallow copied over onto the existing cache
  3876 + if ( typeof name === "object" || typeof name === "function" ) {
  3877 + if ( pvt ) {
  3878 + cache[ id ] = jQuery.extend( cache[ id ], name );
  3879 + } else {
  3880 + cache[ id ].data = jQuery.extend( cache[ id ].data, name );
  3881 + }
  3882 + }
  3883 +
  3884 + thisCache = cache[ id ];
  3885 +
  3886 + // jQuery data() is stored in a separate object inside the object's internal data
  3887 + // cache in order to avoid key collisions between internal data and user-defined
  3888 + // data.
  3889 + if ( !pvt ) {
  3890 + if ( !thisCache.data ) {
  3891 + thisCache.data = {};
  3892 + }
  3893 +
  3894 + thisCache = thisCache.data;
  3895 + }
  3896 +
  3897 + if ( data !== undefined ) {
  3898 + thisCache[ jQuery.camelCase( name ) ] = data;
  3899 + }
  3900 +
  3901 + // Check for both converted-to-camel and non-converted data property names
  3902 + // If a data property was specified
  3903 + if ( typeof name === "string" ) {
  3904 +
  3905 + // First Try to find as-is property data
  3906 + ret = thisCache[ name ];
  3907 +
  3908 + // Test for null|undefined property data
  3909 + if ( ret == null ) {
  3910 +
  3911 + // Try to find the camelCased property
  3912 + ret = thisCache[ jQuery.camelCase( name ) ];
  3913 + }
  3914 + } else {
  3915 + ret = thisCache;
  3916 + }
  3917 +
  3918 + return ret;
  3919 +}
  3920 +
  3921 +function internalRemoveData( elem, name, pvt ) {
  3922 + if ( !acceptData( elem ) ) {
  3923 + return;
  3924 + }
  3925 +
  3926 + var thisCache, i,
  3927 + isNode = elem.nodeType,
  3928 +
  3929 + // See jQuery.data for more information
  3930 + cache = isNode ? jQuery.cache : elem,
  3931 + id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
  3932 +
  3933 + // If there is already no cache entry for this object, there is no
  3934 + // purpose in continuing
  3935 + if ( !cache[ id ] ) {
  3936 + return;
  3937 + }
  3938 +
  3939 + if ( name ) {
  3940 +
  3941 + thisCache = pvt ? cache[ id ] : cache[ id ].data;
  3942 +
  3943 + if ( thisCache ) {
  3944 +
  3945 + // Support array or space separated string names for data keys
  3946 + if ( !jQuery.isArray( name ) ) {
  3947 +
  3948 + // try the string as a key before any manipulation
  3949 + if ( name in thisCache ) {
  3950 + name = [ name ];
  3951 + } else {
  3952 +
  3953 + // split the camel cased version by spaces unless a key with the spaces exists
  3954 + name = jQuery.camelCase( name );
  3955 + if ( name in thisCache ) {
  3956 + name = [ name ];
  3957 + } else {
  3958 + name = name.split( " " );
  3959 + }
  3960 + }
  3961 + } else {
  3962 +
  3963 + // If "name" is an array of keys...
  3964 + // When data is initially created, via ("key", "val") signature,
  3965 + // keys will be converted to camelCase.
  3966 + // Since there is no way to tell _how_ a key was added, remove
  3967 + // both plain key and camelCase key. #12786
  3968 + // This will only penalize the array argument path.
  3969 + name = name.concat( jQuery.map( name, jQuery.camelCase ) );
  3970 + }
  3971 +
  3972 + i = name.length;
  3973 + while ( i-- ) {
  3974 + delete thisCache[ name[ i ] ];
  3975 + }
  3976 +
  3977 + // If there is no data left in the cache, we want to continue
  3978 + // and let the cache object itself get destroyed
  3979 + if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
  3980 + return;
  3981 + }
  3982 + }
  3983 + }
  3984 +
  3985 + // See jQuery.data for more information
  3986 + if ( !pvt ) {
  3987 + delete cache[ id ].data;
  3988 +
  3989 + // Don't destroy the parent cache unless the internal data object
  3990 + // had been the only thing left in it
  3991 + if ( !isEmptyDataObject( cache[ id ] ) ) {
  3992 + return;
  3993 + }
  3994 + }
  3995 +
  3996 + // Destroy the cache
  3997 + if ( isNode ) {
  3998 + jQuery.cleanData( [ elem ], true );
  3999 +
  4000 + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
  4001 + /* jshint eqeqeq: false */
  4002 + } else if ( support.deleteExpando || cache != cache.window ) {
  4003 + /* jshint eqeqeq: true */
  4004 + delete cache[ id ];
  4005 +
  4006 + // When all else fails, undefined
  4007 + } else {
  4008 + cache[ id ] = undefined;
  4009 + }
  4010 +}
  4011 +
  4012 +jQuery.extend( {
  4013 + cache: {},
  4014 +
  4015 + // The following elements (space-suffixed to avoid Object.prototype collisions)
  4016 + // throw uncatchable exceptions if you attempt to set expando properties
  4017 + noData: {
  4018 + "applet ": true,
  4019 + "embed ": true,
  4020 +
  4021 + // ...but Flash objects (which have this classid) *can* handle expandos
  4022 + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  4023 + },
  4024 +
  4025 + hasData: function( elem ) {
  4026 + elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
  4027 + return !!elem && !isEmptyDataObject( elem );
  4028 + },
  4029 +
  4030 + data: function( elem, name, data ) {
  4031 + return internalData( elem, name, data );
  4032 + },
  4033 +
  4034 + removeData: function( elem, name ) {
  4035 + return internalRemoveData( elem, name );
  4036 + },
  4037 +
  4038 + // For internal use only.
  4039 + _data: function( elem, name, data ) {
  4040 + return internalData( elem, name, data, true );
  4041 + },
  4042 +
  4043 + _removeData: function( elem, name ) {
  4044 + return internalRemoveData( elem, name, true );
  4045 + }
  4046 +} );
  4047 +
  4048 +jQuery.fn.extend( {
  4049 + data: function( key, value ) {
  4050 + var i, name, data,
  4051 + elem = this[ 0 ],
  4052 + attrs = elem && elem.attributes;
  4053 +
  4054 + // Special expections of .data basically thwart jQuery.access,
  4055 + // so implement the relevant behavior ourselves
  4056 +
  4057 + // Gets all values
  4058 + if ( key === undefined ) {
  4059 + if ( this.length ) {
  4060 + data = jQuery.data( elem );
  4061 +
  4062 + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
  4063 + i = attrs.length;
  4064 + while ( i-- ) {
  4065 +
  4066 + // Support: IE11+
  4067 + // The attrs elements can be null (#14894)
  4068 + if ( attrs[ i ] ) {
  4069 + name = attrs[ i ].name;
  4070 + if ( name.indexOf( "data-" ) === 0 ) {
  4071 + name = jQuery.camelCase( name.slice( 5 ) );
  4072 + dataAttr( elem, name, data[ name ] );
  4073 + }
  4074 + }
  4075 + }
  4076 + jQuery._data( elem, "parsedAttrs", true );
  4077 + }
  4078 + }
  4079 +
  4080 + return data;
  4081 + }
  4082 +
  4083 + // Sets multiple values
  4084 + if ( typeof key === "object" ) {
  4085 + return this.each( function() {
  4086 + jQuery.data( this, key );
  4087 + } );
  4088 + }
  4089 +
  4090 + return arguments.length > 1 ?
  4091 +
  4092 + // Sets one value
  4093 + this.each( function() {
  4094 + jQuery.data( this, key, value );
  4095 + } ) :
  4096 +
  4097 + // Gets one value
  4098 + // Try to fetch any internally stored data first
  4099 + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
  4100 + },
  4101 +
  4102 + removeData: function( key ) {
  4103 + return this.each( function() {
  4104 + jQuery.removeData( this, key );
  4105 + } );
  4106 + }
  4107 +} );
  4108 +
  4109 +
  4110 +jQuery.extend( {
  4111 + queue: function( elem, type, data ) {
  4112 + var queue;
  4113 +
  4114 + if ( elem ) {
  4115 + type = ( type || "fx" ) + "queue";
  4116 + queue = jQuery._data( elem, type );
  4117 +
  4118 + // Speed up dequeue by getting out quickly if this is just a lookup
  4119 + if ( data ) {
  4120 + if ( !queue || jQuery.isArray( data ) ) {
  4121 + queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
  4122 + } else {
  4123 + queue.push( data );
  4124 + }
  4125 + }
  4126 + return queue || [];
  4127 + }
  4128 + },
  4129 +
  4130 + dequeue: function( elem, type ) {
  4131 + type = type || "fx";
  4132 +
  4133 + var queue = jQuery.queue( elem, type ),
  4134 + startLength = queue.length,
  4135 + fn = queue.shift(),
  4136 + hooks = jQuery._queueHooks( elem, type ),
  4137 + next = function() {
  4138 + jQuery.dequeue( elem, type );
  4139 + };
  4140 +
  4141 + // If the fx queue is dequeued, always remove the progress sentinel
  4142 + if ( fn === "inprogress" ) {
  4143 + fn = queue.shift();
  4144 + startLength--;
  4145 + }
  4146 +
  4147 + if ( fn ) {
  4148 +
  4149 + // Add a progress sentinel to prevent the fx queue from being
  4150 + // automatically dequeued
  4151 + if ( type === "fx" ) {
  4152 + queue.unshift( "inprogress" );
  4153 + }
  4154 +
  4155 + // clear up the last queue stop function
  4156 + delete hooks.stop;
  4157 + fn.call( elem, next, hooks );
  4158 + }
  4159 +
  4160 + if ( !startLength && hooks ) {
  4161 + hooks.empty.fire();
  4162 + }
  4163 + },
  4164 +
  4165 + // not intended for public consumption - generates a queueHooks object,
  4166 + // or returns the current one
  4167 + _queueHooks: function( elem, type ) {
  4168 + var key = type + "queueHooks";
  4169 + return jQuery._data( elem, key ) || jQuery._data( elem, key, {
  4170 + empty: jQuery.Callbacks( "once memory" ).add( function() {
  4171 + jQuery._removeData( elem, type + "queue" );
  4172 + jQuery._removeData( elem, key );
  4173 + } )
  4174 + } );
  4175 + }
  4176 +} );
  4177 +
  4178 +jQuery.fn.extend( {
  4179 + queue: function( type, data ) {
  4180 + var setter = 2;
  4181 +
  4182 + if ( typeof type !== "string" ) {
  4183 + data = type;
  4184 + type = "fx";
  4185 + setter--;
  4186 + }
  4187 +
  4188 + if ( arguments.length < setter ) {
  4189 + return jQuery.queue( this[ 0 ], type );
  4190 + }
  4191 +
  4192 + return data === undefined ?
  4193 + this :
  4194 + this.each( function() {
  4195 + var queue = jQuery.queue( this, type, data );
  4196 +
  4197 + // ensure a hooks for this queue
  4198 + jQuery._queueHooks( this, type );
  4199 +
  4200 + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
  4201 + jQuery.dequeue( this, type );
  4202 + }
  4203 + } );
  4204 + },
  4205 + dequeue: function( type ) {
  4206 + return this.each( function() {
  4207 + jQuery.dequeue( this, type );
  4208 + } );
  4209 + },
  4210 + clearQueue: function( type ) {
  4211 + return this.queue( type || "fx", [] );
  4212 + },
  4213 +
  4214 + // Get a promise resolved when queues of a certain type
  4215 + // are emptied (fx is the type by default)
  4216 + promise: function( type, obj ) {
  4217 + var tmp,
  4218 + count = 1,
  4219 + defer = jQuery.Deferred(),
  4220 + elements = this,
  4221 + i = this.length,
  4222 + resolve = function() {
  4223 + if ( !( --count ) ) {
  4224 + defer.resolveWith( elements, [ elements ] );
  4225 + }
  4226 + };
  4227 +
  4228 + if ( typeof type !== "string" ) {
  4229 + obj = type;
  4230 + type = undefined;
  4231 + }
  4232 + type = type || "fx";
  4233 +
  4234 + while ( i-- ) {
  4235 + tmp = jQuery._data( elements[ i ], type + "queueHooks" );
  4236 + if ( tmp && tmp.empty ) {
  4237 + count++;
  4238 + tmp.empty.add( resolve );
  4239 + }
  4240 + }
  4241 + resolve();
  4242 + return defer.promise( obj );
  4243 + }
  4244 +} );
  4245 +
  4246 +
  4247 +( function() {
  4248 + var shrinkWrapBlocksVal;
  4249 +
  4250 + support.shrinkWrapBlocks = function() {
  4251 + if ( shrinkWrapBlocksVal != null ) {
  4252 + return shrinkWrapBlocksVal;
  4253 + }
  4254 +
  4255 + // Will be changed later if needed.
  4256 + shrinkWrapBlocksVal = false;
  4257 +
  4258 + // Minified: var b,c,d
  4259 + var div, body, container;
  4260 +
  4261 + body = document.getElementsByTagName( "body" )[ 0 ];
  4262 + if ( !body || !body.style ) {
  4263 +
  4264 + // Test fired too early or in an unsupported environment, exit.
  4265 + return;
  4266 + }
  4267 +
  4268 + // Setup
  4269 + div = document.createElement( "div" );
  4270 + container = document.createElement( "div" );
  4271 + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
  4272 + body.appendChild( container ).appendChild( div );
  4273 +
  4274 + // Support: IE6
  4275 + // Check if elements with layout shrink-wrap their children
  4276 + if ( typeof div.style.zoom !== "undefined" ) {
  4277 +
  4278 + // Reset CSS: box-sizing; display; margin; border
  4279 + div.style.cssText =
  4280 +
  4281 + // Support: Firefox<29, Android 2.3
  4282 + // Vendor-prefix box-sizing
  4283 + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
  4284 + "box-sizing:content-box;display:block;margin:0;border:0;" +
  4285 + "padding:1px;width:1px;zoom:1";
  4286 + div.appendChild( document.createElement( "div" ) ).style.width = "5px";
  4287 + shrinkWrapBlocksVal = div.offsetWidth !== 3;
  4288 + }
  4289 +
  4290 + body.removeChild( container );
  4291 +
  4292 + return shrinkWrapBlocksVal;
  4293 + };
  4294 +
  4295 +} )();
  4296 +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
  4297 +
  4298 +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
  4299 +
  4300 +
  4301 +var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
  4302 +
  4303 +var isHidden = function( elem, el ) {
  4304 +
  4305 + // isHidden might be called from jQuery#filter function;
  4306 + // in that case, element will be second argument
  4307 + elem = el || elem;
  4308 + return jQuery.css( elem, "display" ) === "none" ||
  4309 + !jQuery.contains( elem.ownerDocument, elem );
  4310 + };
  4311 +
  4312 +
  4313 +
  4314 +function adjustCSS( elem, prop, valueParts, tween ) {
  4315 + var adjusted,
  4316 + scale = 1,
  4317 + maxIterations = 20,
  4318 + currentValue = tween ?
  4319 + function() { return tween.cur(); } :
  4320 + function() { return jQuery.css( elem, prop, "" ); },
  4321 + initial = currentValue(),
  4322 + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  4323 +
  4324 + // Starting value computation is required for potential unit mismatches
  4325 + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
  4326 + rcssNum.exec( jQuery.css( elem, prop ) );
  4327 +
  4328 + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
  4329 +
  4330 + // Trust units reported by jQuery.css
  4331 + unit = unit || initialInUnit[ 3 ];
  4332 +
  4333 + // Make sure we update the tween properties later on
  4334 + valueParts = valueParts || [];
  4335 +
  4336 + // Iteratively approximate from a nonzero starting point
  4337 + initialInUnit = +initial || 1;
  4338 +
  4339 + do {
  4340 +
  4341 + // If previous iteration zeroed out, double until we get *something*.
  4342 + // Use string for doubling so we don't accidentally see scale as unchanged below
  4343 + scale = scale || ".5";
  4344 +
  4345 + // Adjust and apply
  4346 + initialInUnit = initialInUnit / scale;
  4347 + jQuery.style( elem, prop, initialInUnit + unit );
  4348 +
  4349 + // Update scale, tolerating zero or NaN from tween.cur()
  4350 + // Break the loop if scale is unchanged or perfect, or if we've just had enough.
  4351 + } while (
  4352 + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
  4353 + );
  4354 + }
  4355 +
  4356 + if ( valueParts ) {
  4357 + initialInUnit = +initialInUnit || +initial || 0;
  4358 +
  4359 + // Apply relative offset (+=/-=) if specified
  4360 + adjusted = valueParts[ 1 ] ?
  4361 + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
  4362 + +valueParts[ 2 ];
  4363 + if ( tween ) {
  4364 + tween.unit = unit;
  4365 + tween.start = initialInUnit;
  4366 + tween.end = adjusted;
  4367 + }
  4368 + }
  4369 + return adjusted;
  4370 +}
  4371 +
  4372 +
  4373 +// Multifunctional method to get and set values of a collection
  4374 +// The value/s can optionally be executed if it's a function
  4375 +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  4376 + var i = 0,
  4377 + length = elems.length,
  4378 + bulk = key == null;
  4379 +
  4380 + // Sets many values
  4381 + if ( jQuery.type( key ) === "object" ) {
  4382 + chainable = true;
  4383 + for ( i in key ) {
  4384 + access( elems, fn, i, key[ i ], true, emptyGet, raw );
  4385 + }
  4386 +
  4387 + // Sets one value
  4388 + } else if ( value !== undefined ) {
  4389 + chainable = true;
  4390 +
  4391 + if ( !jQuery.isFunction( value ) ) {
  4392 + raw = true;
  4393 + }
  4394 +
  4395 + if ( bulk ) {
  4396 +
  4397 + // Bulk operations run against the entire set
  4398 + if ( raw ) {
  4399 + fn.call( elems, value );
  4400 + fn = null;
  4401 +
  4402 + // ...except when executing function values
  4403 + } else {
  4404 + bulk = fn;
  4405 + fn = function( elem, key, value ) {
  4406 + return bulk.call( jQuery( elem ), value );
  4407 + };
  4408 + }
  4409 + }
  4410 +
  4411 + if ( fn ) {
  4412 + for ( ; i < length; i++ ) {
  4413 + fn(
  4414 + elems[ i ],
  4415 + key,
  4416 + raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
  4417 + );
  4418 + }
  4419 + }
  4420 + }
  4421 +
  4422 + return chainable ?
  4423 + elems :
  4424 +
  4425 + // Gets
  4426 + bulk ?
  4427 + fn.call( elems ) :
  4428 + length ? fn( elems[ 0 ], key ) : emptyGet;
  4429 +};
  4430 +var rcheckableType = ( /^(?:checkbox|radio)$/i );
  4431 +
  4432 +var rtagName = ( /<([\w:-]+)/ );
  4433 +
  4434 +var rscriptType = ( /^$|\/(?:java|ecma)script/i );
  4435 +
  4436 +var rleadingWhitespace = ( /^\s+/ );
  4437 +
  4438 +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
  4439 + "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
  4440 + "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
  4441 +
  4442 +
  4443 +
  4444 +function createSafeFragment( document ) {
  4445 + var list = nodeNames.split( "|" ),
  4446 + safeFrag = document.createDocumentFragment();
  4447 +
  4448 + if ( safeFrag.createElement ) {
  4449 + while ( list.length ) {
  4450 + safeFrag.createElement(
  4451 + list.pop()
  4452 + );
  4453 + }
  4454 + }
  4455 + return safeFrag;
  4456 +}
  4457 +
  4458 +
  4459 +( function() {
  4460 + var div = document.createElement( "div" ),
  4461 + fragment = document.createDocumentFragment(),
  4462 + input = document.createElement( "input" );
  4463 +
  4464 + // Setup
  4465 + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
  4466 +
  4467 + // IE strips leading whitespace when .innerHTML is used
  4468 + support.leadingWhitespace = div.firstChild.nodeType === 3;
  4469 +
  4470 + // Make sure that tbody elements aren't automatically inserted
  4471 + // IE will insert them into empty tables
  4472 + support.tbody = !div.getElementsByTagName( "tbody" ).length;
  4473 +
  4474 + // Make sure that link elements get serialized correctly by innerHTML
  4475 + // This requires a wrapper element in IE
  4476 + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
  4477 +
  4478 + // Makes sure cloning an html5 element does not cause problems
  4479 + // Where outerHTML is undefined, this still works
  4480 + support.html5Clone =
  4481 + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
  4482 +
  4483 + // Check if a disconnected checkbox will retain its checked
  4484 + // value of true after appended to the DOM (IE6/7)
  4485 + input.type = "checkbox";
  4486 + input.checked = true;
  4487 + fragment.appendChild( input );
  4488 + support.appendChecked = input.checked;
  4489 +
  4490 + // Make sure textarea (and checkbox) defaultValue is properly cloned
  4491 + // Support: IE6-IE11+
  4492 + div.innerHTML = "<textarea>x</textarea>";
  4493 + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
  4494 +
  4495 + // #11217 - WebKit loses check when the name is after the checked attribute
  4496 + fragment.appendChild( div );
  4497 +
  4498 + // Support: Windows Web Apps (WWA)
  4499 + // `name` and `type` must use .setAttribute for WWA (#14901)
  4500 + input = document.createElement( "input" );
  4501 + input.setAttribute( "type", "radio" );
  4502 + input.setAttribute( "checked", "checked" );
  4503 + input.setAttribute( "name", "t" );
  4504 +
  4505 + div.appendChild( input );
  4506 +
  4507 + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
  4508 + // old WebKit doesn't clone checked state correctly in fragments
  4509 + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
  4510 +
  4511 + // Support: IE<9
  4512 + // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
  4513 + support.noCloneEvent = !!div.addEventListener;
  4514 +
  4515 + // Support: IE<9
  4516 + // Since attributes and properties are the same in IE,
  4517 + // cleanData must set properties to undefined rather than use removeAttribute
  4518 + div[ jQuery.expando ] = 1;
  4519 + support.attributes = !div.getAttribute( jQuery.expando );
  4520 +} )();
  4521 +
  4522 +
  4523 +// We have to close these tags to support XHTML (#13200)
  4524 +var wrapMap = {
  4525 + option: [ 1, "<select multiple='multiple'>", "</select>" ],
  4526 + legend: [ 1, "<fieldset>", "</fieldset>" ],
  4527 + area: [ 1, "<map>", "</map>" ],
  4528 +
  4529 + // Support: IE8
  4530 + param: [ 1, "<object>", "</object>" ],
  4531 + thead: [ 1, "<table>", "</table>" ],
  4532 + tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  4533 + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
  4534 + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  4535 +
  4536 + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
  4537 + // unless wrapped in a div with non-breaking characters in front of it.
  4538 + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
  4539 +};
  4540 +
  4541 +// Support: IE8-IE9
  4542 +wrapMap.optgroup = wrapMap.option;
  4543 +
  4544 +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  4545 +wrapMap.th = wrapMap.td;
  4546 +
  4547 +
  4548 +function getAll( context, tag ) {
  4549 + var elems, elem,
  4550 + i = 0,
  4551 + found = typeof context.getElementsByTagName !== "undefined" ?
  4552 + context.getElementsByTagName( tag || "*" ) :
  4553 + typeof context.querySelectorAll !== "undefined" ?
  4554 + context.querySelectorAll( tag || "*" ) :
  4555 + undefined;
  4556 +
  4557 + if ( !found ) {
  4558 + for ( found = [], elems = context.childNodes || context;
  4559 + ( elem = elems[ i ] ) != null;
  4560 + i++
  4561 + ) {
  4562 + if ( !tag || jQuery.nodeName( elem, tag ) ) {
  4563 + found.push( elem );
  4564 + } else {
  4565 + jQuery.merge( found, getAll( elem, tag ) );
  4566 + }
  4567 + }
  4568 + }
  4569 +
  4570 + return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  4571 + jQuery.merge( [ context ], found ) :
  4572 + found;
  4573 +}
  4574 +
  4575 +
  4576 +// Mark scripts as having already been evaluated
  4577 +function setGlobalEval( elems, refElements ) {
  4578 + var elem,
  4579 + i = 0;
  4580 + for ( ; ( elem = elems[ i ] ) != null; i++ ) {
  4581 + jQuery._data(
  4582 + elem,
  4583 + "globalEval",
  4584 + !refElements || jQuery._data( refElements[ i ], "globalEval" )
  4585 + );
  4586 + }
  4587 +}
  4588 +
  4589 +
  4590 +var rhtml = /<|&#?\w+;/,
  4591 + rtbody = /<tbody/i;
  4592 +
  4593 +function fixDefaultChecked( elem ) {
  4594 + if ( rcheckableType.test( elem.type ) ) {
  4595 + elem.defaultChecked = elem.checked;
  4596 + }
  4597 +}
  4598 +
  4599 +function buildFragment( elems, context, scripts, selection, ignored ) {
  4600 + var j, elem, contains,
  4601 + tmp, tag, tbody, wrap,
  4602 + l = elems.length,
  4603 +
  4604 + // Ensure a safe fragment
  4605 + safe = createSafeFragment( context ),
  4606 +
  4607 + nodes = [],
  4608 + i = 0;
  4609 +
  4610 + for ( ; i < l; i++ ) {
  4611 + elem = elems[ i ];
  4612 +
  4613 + if ( elem || elem === 0 ) {
  4614 +
  4615 + // Add nodes directly
  4616 + if ( jQuery.type( elem ) === "object" ) {
  4617 + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  4618 +
  4619 + // Convert non-html into a text node
  4620 + } else if ( !rhtml.test( elem ) ) {
  4621 + nodes.push( context.createTextNode( elem ) );
  4622 +
  4623 + // Convert html into DOM nodes
  4624 + } else {
  4625 + tmp = tmp || safe.appendChild( context.createElement( "div" ) );
  4626 +
  4627 + // Deserialize a standard representation
  4628 + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
  4629 + wrap = wrapMap[ tag ] || wrapMap._default;
  4630 +
  4631 + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
  4632 +
  4633 + // Descend through wrappers to the right content
  4634 + j = wrap[ 0 ];
  4635 + while ( j-- ) {
  4636 + tmp = tmp.lastChild;
  4637 + }
  4638 +
  4639 + // Manually add leading whitespace removed by IE
  4640 + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
  4641 + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
  4642 + }
  4643 +
  4644 + // Remove IE's autoinserted <tbody> from table fragments
  4645 + if ( !support.tbody ) {
  4646 +
  4647 + // String was a <table>, *may* have spurious <tbody>
  4648 + elem = tag === "table" && !rtbody.test( elem ) ?
  4649 + tmp.firstChild :
  4650 +
  4651 + // String was a bare <thead> or <tfoot>
  4652 + wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
  4653 + tmp :
  4654 + 0;
  4655 +
  4656 + j = elem && elem.childNodes.length;
  4657 + while ( j-- ) {
  4658 + if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
  4659 + !tbody.childNodes.length ) {
  4660 +
  4661 + elem.removeChild( tbody );
  4662 + }
  4663 + }
  4664 + }
  4665 +
  4666 + jQuery.merge( nodes, tmp.childNodes );
  4667 +
  4668 + // Fix #12392 for WebKit and IE > 9
  4669 + tmp.textContent = "";
  4670 +
  4671 + // Fix #12392 for oldIE
  4672 + while ( tmp.firstChild ) {
  4673 + tmp.removeChild( tmp.firstChild );
  4674 + }
  4675 +
  4676 + // Remember the top-level container for proper cleanup
  4677 + tmp = safe.lastChild;
  4678 + }
  4679 + }
  4680 + }
  4681 +
  4682 + // Fix #11356: Clear elements from fragment
  4683 + if ( tmp ) {
  4684 + safe.removeChild( tmp );
  4685 + }
  4686 +
  4687 + // Reset defaultChecked for any radios and checkboxes
  4688 + // about to be appended to the DOM in IE 6/7 (#8060)
  4689 + if ( !support.appendChecked ) {
  4690 + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
  4691 + }
  4692 +
  4693 + i = 0;
  4694 + while ( ( elem = nodes[ i++ ] ) ) {
  4695 +
  4696 + // Skip elements already in the context collection (trac-4087)
  4697 + if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
  4698 + if ( ignored ) {
  4699 + ignored.push( elem );
  4700 + }
  4701 +
  4702 + continue;
  4703 + }
  4704 +
  4705 + contains = jQuery.contains( elem.ownerDocument, elem );
  4706 +
  4707 + // Append to fragment
  4708 + tmp = getAll( safe.appendChild( elem ), "script" );
  4709 +
  4710 + // Preserve script evaluation history
  4711 + if ( contains ) {
  4712 + setGlobalEval( tmp );
  4713 + }
  4714 +
  4715 + // Capture executables
  4716 + if ( scripts ) {
  4717 + j = 0;
  4718 + while ( ( elem = tmp[ j++ ] ) ) {
  4719 + if ( rscriptType.test( elem.type || "" ) ) {
  4720 + scripts.push( elem );
  4721 + }
  4722 + }
  4723 + }
  4724 + }
  4725 +
  4726 + tmp = null;
  4727 +
  4728 + return safe;
  4729 +}
  4730 +
  4731 +
  4732 +( function() {
  4733 + var i, eventName,
  4734 + div = document.createElement( "div" );
  4735 +
  4736 + // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
  4737 + for ( i in { submit: true, change: true, focusin: true } ) {
  4738 + eventName = "on" + i;
  4739 +
  4740 + if ( !( support[ i ] = eventName in window ) ) {
  4741 +
  4742 + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
  4743 + div.setAttribute( eventName, "t" );
  4744 + support[ i ] = div.attributes[ eventName ].expando === false;
  4745 + }
  4746 + }
  4747 +
  4748 + // Null elements to avoid leaks in IE.
  4749 + div = null;
  4750 +} )();
  4751 +
  4752 +
  4753 +var rformElems = /^(?:input|select|textarea)$/i,
  4754 + rkeyEvent = /^key/,
  4755 + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
  4756 + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  4757 + rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
  4758 +
  4759 +function returnTrue() {
  4760 + return true;
  4761 +}
  4762 +
  4763 +function returnFalse() {
  4764 + return false;
  4765 +}
  4766 +
  4767 +// Support: IE9
  4768 +// See #13393 for more info
  4769 +function safeActiveElement() {
  4770 + try {
  4771 + return document.activeElement;
  4772 + } catch ( err ) { }
  4773 +}
  4774 +
  4775 +function on( elem, types, selector, data, fn, one ) {
  4776 + var origFn, type;
  4777 +
  4778 + // Types can be a map of types/handlers
  4779 + if ( typeof types === "object" ) {
  4780 +
  4781 + // ( types-Object, selector, data )
  4782 + if ( typeof selector !== "string" ) {
  4783 +
  4784 + // ( types-Object, data )
  4785 + data = data || selector;
  4786 + selector = undefined;
  4787 + }
  4788 + for ( type in types ) {
  4789 + on( elem, type, selector, data, types[ type ], one );
  4790 + }
  4791 + return elem;
  4792 + }
  4793 +
  4794 + if ( data == null && fn == null ) {
  4795 +
  4796 + // ( types, fn )
  4797 + fn = selector;
  4798 + data = selector = undefined;
  4799 + } else if ( fn == null ) {
  4800 + if ( typeof selector === "string" ) {
  4801 +
  4802 + // ( types, selector, fn )
  4803 + fn = data;
  4804 + data = undefined;
  4805 + } else {
  4806 +
  4807 + // ( types, data, fn )
  4808 + fn = data;
  4809 + data = selector;
  4810 + selector = undefined;
  4811 + }
  4812 + }
  4813 + if ( fn === false ) {
  4814 + fn = returnFalse;
  4815 + } else if ( !fn ) {
  4816 + return elem;
  4817 + }
  4818 +
  4819 + if ( one === 1 ) {
  4820 + origFn = fn;
  4821 + fn = function( event ) {
  4822 +
  4823 + // Can use an empty set, since event contains the info
  4824 + jQuery().off( event );
  4825 + return origFn.apply( this, arguments );
  4826 + };
  4827 +
  4828 + // Use same guid so caller can remove using origFn
  4829 + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  4830 + }
  4831 + return elem.each( function() {
  4832 + jQuery.event.add( this, types, fn, data, selector );
  4833 + } );
  4834 +}
  4835 +
  4836 +/*
  4837 + * Helper functions for managing events -- not part of the public interface.
  4838 + * Props to Dean Edwards' addEvent library for many of the ideas.
  4839 + */
  4840 +jQuery.event = {
  4841 +
  4842 + global: {},
  4843 +
  4844 + add: function( elem, types, handler, data, selector ) {
  4845 + var tmp, events, t, handleObjIn,
  4846 + special, eventHandle, handleObj,
  4847 + handlers, type, namespaces, origType,
  4848 + elemData = jQuery._data( elem );
  4849 +
  4850 + // Don't attach events to noData or text/comment nodes (but allow plain objects)
  4851 + if ( !elemData ) {
  4852 + return;
  4853 + }
  4854 +
  4855 + // Caller can pass in an object of custom data in lieu of the handler
  4856 + if ( handler.handler ) {
  4857 + handleObjIn = handler;
  4858 + handler = handleObjIn.handler;
  4859 + selector = handleObjIn.selector;
  4860 + }
  4861 +
  4862 + // Make sure that the handler has a unique ID, used to find/remove it later
  4863 + if ( !handler.guid ) {
  4864 + handler.guid = jQuery.guid++;
  4865 + }
  4866 +
  4867 + // Init the element's event structure and main handler, if this is the first
  4868 + if ( !( events = elemData.events ) ) {
  4869 + events = elemData.events = {};
  4870 + }
  4871 + if ( !( eventHandle = elemData.handle ) ) {
  4872 + eventHandle = elemData.handle = function( e ) {
  4873 +
  4874 + // Discard the second event of a jQuery.event.trigger() and
  4875 + // when an event is called after a page has unloaded
  4876 + return typeof jQuery !== "undefined" &&
  4877 + ( !e || jQuery.event.triggered !== e.type ) ?
  4878 + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
  4879 + undefined;
  4880 + };
  4881 +
  4882 + // Add elem as a property of the handle fn to prevent a memory leak
  4883 + // with IE non-native events
  4884 + eventHandle.elem = elem;
  4885 + }
  4886 +
  4887 + // Handle multiple events separated by a space
  4888 + types = ( types || "" ).match( rnotwhite ) || [ "" ];
  4889 + t = types.length;
  4890 + while ( t-- ) {
  4891 + tmp = rtypenamespace.exec( types[ t ] ) || [];
  4892 + type = origType = tmp[ 1 ];
  4893 + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4894 +
  4895 + // There *must* be a type, no attaching namespace-only handlers
  4896 + if ( !type ) {
  4897 + continue;
  4898 + }
  4899 +
  4900 + // If event changes its type, use the special event handlers for the changed type
  4901 + special = jQuery.event.special[ type ] || {};
  4902 +
  4903 + // If selector defined, determine special event api type, otherwise given type
  4904 + type = ( selector ? special.delegateType : special.bindType ) || type;
  4905 +
  4906 + // Update special based on newly reset type
  4907 + special = jQuery.event.special[ type ] || {};
  4908 +
  4909 + // handleObj is passed to all event handlers
  4910 + handleObj = jQuery.extend( {
  4911 + type: type,
  4912 + origType: origType,
  4913 + data: data,
  4914 + handler: handler,
  4915 + guid: handler.guid,
  4916 + selector: selector,
  4917 + needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  4918 + namespace: namespaces.join( "." )
  4919 + }, handleObjIn );
  4920 +
  4921 + // Init the event handler queue if we're the first
  4922 + if ( !( handlers = events[ type ] ) ) {
  4923 + handlers = events[ type ] = [];
  4924 + handlers.delegateCount = 0;
  4925 +
  4926 + // Only use addEventListener/attachEvent if the special events handler returns false
  4927 + if ( !special.setup ||
  4928 + special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  4929 +
  4930 + // Bind the global event handler to the element
  4931 + if ( elem.addEventListener ) {
  4932 + elem.addEventListener( type, eventHandle, false );
  4933 +
  4934 + } else if ( elem.attachEvent ) {
  4935 + elem.attachEvent( "on" + type, eventHandle );
  4936 + }
  4937 + }
  4938 + }
  4939 +
  4940 + if ( special.add ) {
  4941 + special.add.call( elem, handleObj );
  4942 +
  4943 + if ( !handleObj.handler.guid ) {
  4944 + handleObj.handler.guid = handler.guid;
  4945 + }
  4946 + }
  4947 +
  4948 + // Add to the element's handler list, delegates in front
  4949 + if ( selector ) {
  4950 + handlers.splice( handlers.delegateCount++, 0, handleObj );
  4951 + } else {
  4952 + handlers.push( handleObj );
  4953 + }
  4954 +
  4955 + // Keep track of which events have ever been used, for event optimization
  4956 + jQuery.event.global[ type ] = true;
  4957 + }
  4958 +
  4959 + // Nullify elem to prevent memory leaks in IE
  4960 + elem = null;
  4961 + },
  4962 +
  4963 + // Detach an event or set of events from an element
  4964 + remove: function( elem, types, handler, selector, mappedTypes ) {
  4965 + var j, handleObj, tmp,
  4966 + origCount, t, events,
  4967 + special, handlers, type,
  4968 + namespaces, origType,
  4969 + elemData = jQuery.hasData( elem ) && jQuery._data( elem );
  4970 +
  4971 + if ( !elemData || !( events = elemData.events ) ) {
  4972 + return;
  4973 + }
  4974 +
  4975 + // Once for each type.namespace in types; type may be omitted
  4976 + types = ( types || "" ).match( rnotwhite ) || [ "" ];
  4977 + t = types.length;
  4978 + while ( t-- ) {
  4979 + tmp = rtypenamespace.exec( types[ t ] ) || [];
  4980 + type = origType = tmp[ 1 ];
  4981 + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4982 +
  4983 + // Unbind all events (on this namespace, if provided) for the element
  4984 + if ( !type ) {
  4985 + for ( type in events ) {
  4986 + jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  4987 + }
  4988 + continue;
  4989 + }
  4990 +
  4991 + special = jQuery.event.special[ type ] || {};
  4992 + type = ( selector ? special.delegateType : special.bindType ) || type;
  4993 + handlers = events[ type ] || [];
  4994 + tmp = tmp[ 2 ] &&
  4995 + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
  4996 +
  4997 + // Remove matching events
  4998 + origCount = j = handlers.length;
  4999 + while ( j-- ) {
  5000 + handleObj = handlers[ j ];
  5001 +
  5002 + if ( ( mappedTypes || origType === handleObj.origType ) &&
  5003 + ( !handler || handler.guid === handleObj.guid ) &&
  5004 + ( !tmp || tmp.test( handleObj.namespace ) ) &&
  5005 + ( !selector || selector === handleObj.selector ||
  5006 + selector === "**" && handleObj.selector ) ) {
  5007 + handlers.splice( j, 1 );
  5008 +
  5009 + if ( handleObj.selector ) {
  5010 + handlers.delegateCount--;
  5011 + }
  5012 + if ( special.remove ) {
  5013 + special.remove.call( elem, handleObj );
  5014 + }
  5015 + }
  5016 + }
  5017 +
  5018 + // Remove generic event handler if we removed something and no more handlers exist
  5019 + // (avoids potential for endless recursion during removal of special event handlers)
  5020 + if ( origCount && !handlers.length ) {
  5021 + if ( !special.teardown ||
  5022 + special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  5023 +
  5024 + jQuery.removeEvent( elem, type, elemData.handle );
  5025 + }
  5026 +
  5027 + delete events[ type ];
  5028 + }
  5029 + }
  5030 +
  5031 + // Remove the expando if it's no longer used
  5032 + if ( jQuery.isEmptyObject( events ) ) {
  5033 + delete elemData.handle;
  5034 +
  5035 + // removeData also checks for emptiness and clears the expando if empty
  5036 + // so use it instead of delete
  5037 + jQuery._removeData( elem, "events" );
  5038 + }
  5039 + },
  5040 +
  5041 + trigger: function( event, data, elem, onlyHandlers ) {
  5042 + var handle, ontype, cur,
  5043 + bubbleType, special, tmp, i,
  5044 + eventPath = [ elem || document ],
  5045 + type = hasOwn.call( event, "type" ) ? event.type : event,
  5046 + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
  5047 +
  5048 + cur = tmp = elem = elem || document;
  5049 +
  5050 + // Don't do events on text and comment nodes
  5051 + if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  5052 + return;
  5053 + }
  5054 +
  5055 + // focus/blur morphs to focusin/out; ensure we're not firing them right now
  5056 + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  5057 + return;
  5058 + }
  5059 +
  5060 + if ( type.indexOf( "." ) > -1 ) {
  5061 +
  5062 + // Namespaced trigger; create a regexp to match event type in handle()
  5063 + namespaces = type.split( "." );
  5064 + type = namespaces.shift();
  5065 + namespaces.sort();
  5066 + }
  5067 + ontype = type.indexOf( ":" ) < 0 && "on" + type;
  5068 +
  5069 + // Caller can pass in a jQuery.Event object, Object, or just an event type string
  5070 + event = event[ jQuery.expando ] ?
  5071 + event :
  5072 + new jQuery.Event( type, typeof event === "object" && event );
  5073 +
  5074 + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  5075 + event.isTrigger = onlyHandlers ? 2 : 3;
  5076 + event.namespace = namespaces.join( "." );
  5077 + event.rnamespace = event.namespace ?
  5078 + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
  5079 + null;
  5080 +
  5081 + // Clean up the event in case it is being reused
  5082 + event.result = undefined;
  5083 + if ( !event.target ) {
  5084 + event.target = elem;
  5085 + }
  5086 +
  5087 + // Clone any incoming data and prepend the event, creating the handler arg list
  5088 + data = data == null ?
  5089 + [ event ] :
  5090 + jQuery.makeArray( data, [ event ] );
  5091 +
  5092 + // Allow special events to draw outside the lines
  5093 + special = jQuery.event.special[ type ] || {};
  5094 + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  5095 + return;
  5096 + }
  5097 +
  5098 + // Determine event propagation path in advance, per W3C events spec (#9951)
  5099 + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  5100 + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  5101 +
  5102 + bubbleType = special.delegateType || type;
  5103 + if ( !rfocusMorph.test( bubbleType + type ) ) {
  5104 + cur = cur.parentNode;
  5105 + }
  5106 + for ( ; cur; cur = cur.parentNode ) {
  5107 + eventPath.push( cur );
  5108 + tmp = cur;
  5109 + }
  5110 +
  5111 + // Only add window if we got to document (e.g., not plain obj or detached DOM)
  5112 + if ( tmp === ( elem.ownerDocument || document ) ) {
  5113 + eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  5114 + }
  5115 + }
  5116 +
  5117 + // Fire handlers on the event path
  5118 + i = 0;
  5119 + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
  5120 +
  5121 + event.type = i > 1 ?
  5122 + bubbleType :
  5123 + special.bindType || type;
  5124 +
  5125 + // jQuery handler
  5126 + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
  5127 + jQuery._data( cur, "handle" );
  5128 +
  5129 + if ( handle ) {
  5130 + handle.apply( cur, data );
  5131 + }
  5132 +
  5133 + // Native handler
  5134 + handle = ontype && cur[ ontype ];
  5135 + if ( handle && handle.apply && acceptData( cur ) ) {
  5136 + event.result = handle.apply( cur, data );
  5137 + if ( event.result === false ) {
  5138 + event.preventDefault();
  5139 + }
  5140 + }
  5141 + }
  5142 + event.type = type;
  5143 +
  5144 + // If nobody prevented the default action, do it now
  5145 + if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  5146 +
  5147 + if (
  5148 + ( !special._default ||
  5149 + special._default.apply( eventPath.pop(), data ) === false
  5150 + ) && acceptData( elem )
  5151 + ) {
  5152 +
  5153 + // Call a native DOM method on the target with the same name name as the event.
  5154 + // Can't use an .isFunction() check here because IE6/7 fails that test.
  5155 + // Don't do default actions on window, that's where global variables be (#6170)
  5156 + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
  5157 +
  5158 + // Don't re-trigger an onFOO event when we call its FOO() method
  5159 + tmp = elem[ ontype ];
  5160 +
  5161 + if ( tmp ) {
  5162 + elem[ ontype ] = null;
  5163 + }
  5164 +
  5165 + // Prevent re-triggering of the same event, since we already bubbled it above
  5166 + jQuery.event.triggered = type;
  5167 + try {
  5168 + elem[ type ]();
  5169 + } catch ( e ) {
  5170 +
  5171 + // IE<9 dies on focus/blur to hidden element (#1486,#12518)
  5172 + // only reproducible on winXP IE8 native, not IE9 in IE8 mode
  5173 + }
  5174 + jQuery.event.triggered = undefined;
  5175 +
  5176 + if ( tmp ) {
  5177 + elem[ ontype ] = tmp;
  5178 + }
  5179 + }
  5180 + }
  5181 + }
  5182 +
  5183 + return event.result;
  5184 + },
  5185 +
  5186 + dispatch: function( event ) {
  5187 +
  5188 + // Make a writable jQuery.Event from the native event object
  5189 + event = jQuery.event.fix( event );
  5190 +
  5191 + var i, j, ret, matched, handleObj,
  5192 + handlerQueue = [],
  5193 + args = slice.call( arguments ),
  5194 + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
  5195 + special = jQuery.event.special[ event.type ] || {};
  5196 +
  5197 + // Use the fix-ed jQuery.Event rather than the (read-only) native event
  5198 + args[ 0 ] = event;
  5199 + event.delegateTarget = this;
  5200 +
  5201 + // Call the preDispatch hook for the mapped type, and let it bail if desired
  5202 + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  5203 + return;
  5204 + }
  5205 +
  5206 + // Determine handlers
  5207 + handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  5208 +
  5209 + // Run delegates first; they may want to stop propagation beneath us
  5210 + i = 0;
  5211 + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
  5212 + event.currentTarget = matched.elem;
  5213 +
  5214 + j = 0;
  5215 + while ( ( handleObj = matched.handlers[ j++ ] ) &&
  5216 + !event.isImmediatePropagationStopped() ) {
  5217 +
  5218 + // Triggered event must either 1) have no namespace, or 2) have namespace(s)
  5219 + // a subset or equal to those in the bound event (both can have no namespace).
  5220 + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
  5221 +
  5222 + event.handleObj = handleObj;
  5223 + event.data = handleObj.data;
  5224 +
  5225 + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
  5226 + handleObj.handler ).apply( matched.elem, args );
  5227 +
  5228 + if ( ret !== undefined ) {
  5229 + if ( ( event.result = ret ) === false ) {
  5230 + event.preventDefault();
  5231 + event.stopPropagation();
  5232 + }
  5233 + }
  5234 + }
  5235 + }
  5236 + }
  5237 +
  5238 + // Call the postDispatch hook for the mapped type
  5239 + if ( special.postDispatch ) {
  5240 + special.postDispatch.call( this, event );
  5241 + }
  5242 +
  5243 + return event.result;
  5244 + },
  5245 +
  5246 + handlers: function( event, handlers ) {
  5247 + var i, matches, sel, handleObj,
  5248 + handlerQueue = [],
  5249 + delegateCount = handlers.delegateCount,
  5250 + cur = event.target;
  5251 +
  5252 + // Support (at least): Chrome, IE9
  5253 + // Find delegate handlers
  5254 + // Black-hole SVG <use> instance trees (#13180)
  5255 + //
  5256 + // Support: Firefox<=42+
  5257 + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
  5258 + if ( delegateCount && cur.nodeType &&
  5259 + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
  5260 +
  5261 + /* jshint eqeqeq: false */
  5262 + for ( ; cur != this; cur = cur.parentNode || this ) {
  5263 + /* jshint eqeqeq: true */
  5264 +
  5265 + // Don't check non-elements (#13208)
  5266 + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  5267 + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
  5268 + matches = [];
  5269 + for ( i = 0; i < delegateCount; i++ ) {
  5270 + handleObj = handlers[ i ];
  5271 +
  5272 + // Don't conflict with Object.prototype properties (#13203)
  5273 + sel = handleObj.selector + " ";
  5274 +
  5275 + if ( matches[ sel ] === undefined ) {
  5276 + matches[ sel ] = handleObj.needsContext ?
  5277 + jQuery( sel, this ).index( cur ) > -1 :
  5278 + jQuery.find( sel, this, null, [ cur ] ).length;
  5279 + }
  5280 + if ( matches[ sel ] ) {
  5281 + matches.push( handleObj );
  5282 + }
  5283 + }
  5284 + if ( matches.length ) {
  5285 + handlerQueue.push( { elem: cur, handlers: matches } );
  5286 + }
  5287 + }
  5288 + }
  5289 + }
  5290 +
  5291 + // Add the remaining (directly-bound) handlers
  5292 + if ( delegateCount < handlers.length ) {
  5293 + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
  5294 + }
  5295 +
  5296 + return handlerQueue;
  5297 + },
  5298 +
  5299 + fix: function( event ) {
  5300 + if ( event[ jQuery.expando ] ) {
  5301 + return event;
  5302 + }
  5303 +
  5304 + // Create a writable copy of the event object and normalize some properties
  5305 + var i, prop, copy,
  5306 + type = event.type,
  5307 + originalEvent = event,
  5308 + fixHook = this.fixHooks[ type ];
  5309 +
  5310 + if ( !fixHook ) {
  5311 + this.fixHooks[ type ] = fixHook =
  5312 + rmouseEvent.test( type ) ? this.mouseHooks :
  5313 + rkeyEvent.test( type ) ? this.keyHooks :
  5314 + {};
  5315 + }
  5316 + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  5317 +
  5318 + event = new jQuery.Event( originalEvent );
  5319 +
  5320 + i = copy.length;
  5321 + while ( i-- ) {
  5322 + prop = copy[ i ];
  5323 + event[ prop ] = originalEvent[ prop ];
  5324 + }
  5325 +
  5326 + // Support: IE<9
  5327 + // Fix target property (#1925)
  5328 + if ( !event.target ) {
  5329 + event.target = originalEvent.srcElement || document;
  5330 + }
  5331 +
  5332 + // Support: Safari 6-8+
  5333 + // Target should not be a text node (#504, #13143)
  5334 + if ( event.target.nodeType === 3 ) {
  5335 + event.target = event.target.parentNode;
  5336 + }
  5337 +
  5338 + // Support: IE<9
  5339 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
  5340 + event.metaKey = !!event.metaKey;
  5341 +
  5342 + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
  5343 + },
  5344 +
  5345 + // Includes some event props shared by KeyEvent and MouseEvent
  5346 + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
  5347 + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
  5348 +
  5349 + fixHooks: {},
  5350 +
  5351 + keyHooks: {
  5352 + props: "char charCode key keyCode".split( " " ),
  5353 + filter: function( event, original ) {
  5354 +
  5355 + // Add which for key events
  5356 + if ( event.which == null ) {
  5357 + event.which = original.charCode != null ? original.charCode : original.keyCode;
  5358 + }
  5359 +
  5360 + return event;
  5361 + }
  5362 + },
  5363 +
  5364 + mouseHooks: {
  5365 + props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
  5366 + "pageX pageY screenX screenY toElement" ).split( " " ),
  5367 + filter: function( event, original ) {
  5368 + var body, eventDoc, doc,
  5369 + button = original.button,
  5370 + fromElement = original.fromElement;
  5371 +
  5372 + // Calculate pageX/Y if missing and clientX/Y available
  5373 + if ( event.pageX == null && original.clientX != null ) {
  5374 + eventDoc = event.target.ownerDocument || document;
  5375 + doc = eventDoc.documentElement;
  5376 + body = eventDoc.body;
  5377 +
  5378 + event.pageX = original.clientX +
  5379 + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
  5380 + ( doc && doc.clientLeft || body && body.clientLeft || 0 );
  5381 + event.pageY = original.clientY +
  5382 + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
  5383 + ( doc && doc.clientTop || body && body.clientTop || 0 );
  5384 + }
  5385 +
  5386 + // Add relatedTarget, if necessary
  5387 + if ( !event.relatedTarget && fromElement ) {
  5388 + event.relatedTarget = fromElement === event.target ?
  5389 + original.toElement :
  5390 + fromElement;
  5391 + }
  5392 +
  5393 + // Add which for click: 1 === left; 2 === middle; 3 === right
  5394 + // Note: button is not normalized, so don't use it
  5395 + if ( !event.which && button !== undefined ) {
  5396 + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
  5397 + }
  5398 +
  5399 + return event;
  5400 + }
  5401 + },
  5402 +
  5403 + special: {
  5404 + load: {
  5405 +
  5406 + // Prevent triggered image.load events from bubbling to window.load
  5407 + noBubble: true
  5408 + },
  5409 + focus: {
  5410 +
  5411 + // Fire native event if possible so blur/focus sequence is correct
  5412 + trigger: function() {
  5413 + if ( this !== safeActiveElement() && this.focus ) {
  5414 + try {
  5415 + this.focus();
  5416 + return false;
  5417 + } catch ( e ) {
  5418 +
  5419 + // Support: IE<9
  5420 + // If we error on focus to hidden element (#1486, #12518),
  5421 + // let .trigger() run the handlers
  5422 + }
  5423 + }
  5424 + },
  5425 + delegateType: "focusin"
  5426 + },
  5427 + blur: {
  5428 + trigger: function() {
  5429 + if ( this === safeActiveElement() && this.blur ) {
  5430 + this.blur();
  5431 + return false;
  5432 + }
  5433 + },
  5434 + delegateType: "focusout"
  5435 + },
  5436 + click: {
  5437 +
  5438 + // For checkbox, fire native event so checked state will be right
  5439 + trigger: function() {
  5440 + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
  5441 + this.click();
  5442 + return false;
  5443 + }
  5444 + },
  5445 +
  5446 + // For cross-browser consistency, don't fire native .click() on links
  5447 + _default: function( event ) {
  5448 + return jQuery.nodeName( event.target, "a" );
  5449 + }
  5450 + },
  5451 +
  5452 + beforeunload: {
  5453 + postDispatch: function( event ) {
  5454 +
  5455 + // Support: Firefox 20+
  5456 + // Firefox doesn't alert if the returnValue field is not set.
  5457 + if ( event.result !== undefined && event.originalEvent ) {
  5458 + event.originalEvent.returnValue = event.result;
  5459 + }
  5460 + }
  5461 + }
  5462 + },
  5463 +
  5464 + // Piggyback on a donor event to simulate a different one
  5465 + simulate: function( type, elem, event ) {
  5466 + var e = jQuery.extend(
  5467 + new jQuery.Event(),
  5468 + event,
  5469 + {
  5470 + type: type,
  5471 + isSimulated: true
  5472 +
  5473 + // Previously, `originalEvent: {}` was set here, so stopPropagation call
  5474 + // would not be triggered on donor event, since in our own
  5475 + // jQuery.event.stopPropagation function we had a check for existence of
  5476 + // originalEvent.stopPropagation method, so, consequently it would be a noop.
  5477 + //
  5478 + // Guard for simulated events was moved to jQuery.event.stopPropagation function
  5479 + // since `originalEvent` should point to the original event for the
  5480 + // constancy with other events and for more focused logic
  5481 + }
  5482 + );
  5483 +
  5484 + jQuery.event.trigger( e, null, elem );
  5485 +
  5486 + if ( e.isDefaultPrevented() ) {
  5487 + event.preventDefault();
  5488 + }
  5489 + }
  5490 +};
  5491 +
  5492 +jQuery.removeEvent = document.removeEventListener ?
  5493 + function( elem, type, handle ) {
  5494 +
  5495 + // This "if" is needed for plain objects
  5496 + if ( elem.removeEventListener ) {
  5497 + elem.removeEventListener( type, handle );
  5498 + }
  5499 + } :
  5500 + function( elem, type, handle ) {
  5501 + var name = "on" + type;
  5502 +
  5503 + if ( elem.detachEvent ) {
  5504 +
  5505 + // #8545, #7054, preventing memory leaks for custom events in IE6-8
  5506 + // detachEvent needed property on element, by name of that event,
  5507 + // to properly expose it to GC
  5508 + if ( typeof elem[ name ] === "undefined" ) {
  5509 + elem[ name ] = null;
  5510 + }
  5511 +
  5512 + elem.detachEvent( name, handle );
  5513 + }
  5514 + };
  5515 +
  5516 +jQuery.Event = function( src, props ) {
  5517 +
  5518 + // Allow instantiation without the 'new' keyword
  5519 + if ( !( this instanceof jQuery.Event ) ) {
  5520 + return new jQuery.Event( src, props );
  5521 + }
  5522 +
  5523 + // Event object
  5524 + if ( src && src.type ) {
  5525 + this.originalEvent = src;
  5526 + this.type = src.type;
  5527 +
  5528 + // Events bubbling up the document may have been marked as prevented
  5529 + // by a handler lower down the tree; reflect the correct value.
  5530 + this.isDefaultPrevented = src.defaultPrevented ||
  5531 + src.defaultPrevented === undefined &&
  5532 +
  5533 + // Support: IE < 9, Android < 4.0
  5534 + src.returnValue === false ?
  5535 + returnTrue :
  5536 + returnFalse;
  5537 +
  5538 + // Event type
  5539 + } else {
  5540 + this.type = src;
  5541 + }
  5542 +
  5543 + // Put explicitly provided properties onto the event object
  5544 + if ( props ) {
  5545 + jQuery.extend( this, props );
  5546 + }
  5547 +
  5548 + // Create a timestamp if incoming event doesn't have one
  5549 + this.timeStamp = src && src.timeStamp || jQuery.now();
  5550 +
  5551 + // Mark it as fixed
  5552 + this[ jQuery.expando ] = true;
  5553 +};
  5554 +
  5555 +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  5556 +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  5557 +jQuery.Event.prototype = {
  5558 + constructor: jQuery.Event,
  5559 + isDefaultPrevented: returnFalse,
  5560 + isPropagationStopped: returnFalse,
  5561 + isImmediatePropagationStopped: returnFalse,
  5562 +
  5563 + preventDefault: function() {
  5564 + var e = this.originalEvent;
  5565 +
  5566 + this.isDefaultPrevented = returnTrue;
  5567 + if ( !e ) {
  5568 + return;
  5569 + }
  5570 +
  5571 + // If preventDefault exists, run it on the original event
  5572 + if ( e.preventDefault ) {
  5573 + e.preventDefault();
  5574 +
  5575 + // Support: IE
  5576 + // Otherwise set the returnValue property of the original event to false
  5577 + } else {
  5578 + e.returnValue = false;
  5579 + }
  5580 + },
  5581 + stopPropagation: function() {
  5582 + var e = this.originalEvent;
  5583 +
  5584 + this.isPropagationStopped = returnTrue;
  5585 +
  5586 + if ( !e || this.isSimulated ) {
  5587 + return;
  5588 + }
  5589 +
  5590 + // If stopPropagation exists, run it on the original event
  5591 + if ( e.stopPropagation ) {
  5592 + e.stopPropagation();
  5593 + }
  5594 +
  5595 + // Support: IE
  5596 + // Set the cancelBubble property of the original event to true
  5597 + e.cancelBubble = true;
  5598 + },
  5599 + stopImmediatePropagation: function() {
  5600 + var e = this.originalEvent;
  5601 +
  5602 + this.isImmediatePropagationStopped = returnTrue;
  5603 +
  5604 + if ( e && e.stopImmediatePropagation ) {
  5605 + e.stopImmediatePropagation();
  5606 + }
  5607 +
  5608 + this.stopPropagation();
  5609 + }
  5610 +};
  5611 +
  5612 +// Create mouseenter/leave events using mouseover/out and event-time checks
  5613 +// so that event delegation works in jQuery.
  5614 +// Do the same for pointerenter/pointerleave and pointerover/pointerout
  5615 +//
  5616 +// Support: Safari 7 only
  5617 +// Safari sends mouseenter too often; see:
  5618 +// https://code.google.com/p/chromium/issues/detail?id=470258
  5619 +// for the description of the bug (it existed in older Chrome versions as well).
  5620 +jQuery.each( {
  5621 + mouseenter: "mouseover",
  5622 + mouseleave: "mouseout",
  5623 + pointerenter: "pointerover",
  5624 + pointerleave: "pointerout"
  5625 +}, function( orig, fix ) {
  5626 + jQuery.event.special[ orig ] = {
  5627 + delegateType: fix,
  5628 + bindType: fix,
  5629 +
  5630 + handle: function( event ) {
  5631 + var ret,
  5632 + target = this,
  5633 + related = event.relatedTarget,
  5634 + handleObj = event.handleObj;
  5635 +
  5636 + // For mouseenter/leave call the handler if related is outside the target.
  5637 + // NB: No relatedTarget if the mouse left/entered the browser window
  5638 + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
  5639 + event.type = handleObj.origType;
  5640 + ret = handleObj.handler.apply( this, arguments );
  5641 + event.type = fix;
  5642 + }
  5643 + return ret;
  5644 + }
  5645 + };
  5646 +} );
  5647 +
  5648 +// IE submit delegation
  5649 +if ( !support.submit ) {
  5650 +
  5651 + jQuery.event.special.submit = {
  5652 + setup: function() {
  5653 +
  5654 + // Only need this for delegated form submit events
  5655 + if ( jQuery.nodeName( this, "form" ) ) {
  5656 + return false;
  5657 + }
  5658 +
  5659 + // Lazy-add a submit handler when a descendant form may potentially be submitted
  5660 + jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
  5661 +
  5662 + // Node name check avoids a VML-related crash in IE (#9807)
  5663 + var elem = e.target,
  5664 + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
  5665 +
  5666 + // Support: IE <=8
  5667 + // We use jQuery.prop instead of elem.form
  5668 + // to allow fixing the IE8 delegated submit issue (gh-2332)
  5669 + // by 3rd party polyfills/workarounds.
  5670 + jQuery.prop( elem, "form" ) :
  5671 + undefined;
  5672 +
  5673 + if ( form && !jQuery._data( form, "submit" ) ) {
  5674 + jQuery.event.add( form, "submit._submit", function( event ) {
  5675 + event._submitBubble = true;
  5676 + } );
  5677 + jQuery._data( form, "submit", true );
  5678 + }
  5679 + } );
  5680 +
  5681 + // return undefined since we don't need an event listener
  5682 + },
  5683 +
  5684 + postDispatch: function( event ) {
  5685 +
  5686 + // If form was submitted by the user, bubble the event up the tree
  5687 + if ( event._submitBubble ) {
  5688 + delete event._submitBubble;
  5689 + if ( this.parentNode && !event.isTrigger ) {
  5690 + jQuery.event.simulate( "submit", this.parentNode, event );
  5691 + }
  5692 + }
  5693 + },
  5694 +
  5695 + teardown: function() {
  5696 +
  5697 + // Only need this for delegated form submit events
  5698 + if ( jQuery.nodeName( this, "form" ) ) {
  5699 + return false;
  5700 + }
  5701 +
  5702 + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
  5703 + jQuery.event.remove( this, "._submit" );
  5704 + }
  5705 + };
  5706 +}
  5707 +
  5708 +// IE change delegation and checkbox/radio fix
  5709 +if ( !support.change ) {
  5710 +
  5711 + jQuery.event.special.change = {
  5712 +
  5713 + setup: function() {
  5714 +
  5715 + if ( rformElems.test( this.nodeName ) ) {
  5716 +
  5717 + // IE doesn't fire change on a check/radio until blur; trigger it on click
  5718 + // after a propertychange. Eat the blur-change in special.change.handle.
  5719 + // This still fires onchange a second time for check/radio after blur.
  5720 + if ( this.type === "checkbox" || this.type === "radio" ) {
  5721 + jQuery.event.add( this, "propertychange._change", function( event ) {
  5722 + if ( event.originalEvent.propertyName === "checked" ) {
  5723 + this._justChanged = true;
  5724 + }
  5725 + } );
  5726 + jQuery.event.add( this, "click._change", function( event ) {
  5727 + if ( this._justChanged && !event.isTrigger ) {
  5728 + this._justChanged = false;
  5729 + }
  5730 +
  5731 + // Allow triggered, simulated change events (#11500)
  5732 + jQuery.event.simulate( "change", this, event );
  5733 + } );
  5734 + }
  5735 + return false;
  5736 + }
  5737 +
  5738 + // Delegated event; lazy-add a change handler on descendant inputs
  5739 + jQuery.event.add( this, "beforeactivate._change", function( e ) {
  5740 + var elem = e.target;
  5741 +
  5742 + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
  5743 + jQuery.event.add( elem, "change._change", function( event ) {
  5744 + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
  5745 + jQuery.event.simulate( "change", this.parentNode, event );
  5746 + }
  5747 + } );
  5748 + jQuery._data( elem, "change", true );
  5749 + }
  5750 + } );
  5751 + },
  5752 +
  5753 + handle: function( event ) {
  5754 + var elem = event.target;
  5755 +
  5756 + // Swallow native change events from checkbox/radio, we already triggered them above
  5757 + if ( this !== elem || event.isSimulated || event.isTrigger ||
  5758 + ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
  5759 +
  5760 + return event.handleObj.handler.apply( this, arguments );
  5761 + }
  5762 + },
  5763 +
  5764 + teardown: function() {
  5765 + jQuery.event.remove( this, "._change" );
  5766 +
  5767 + return !rformElems.test( this.nodeName );
  5768 + }
  5769 + };
  5770 +}
  5771 +
  5772 +// Support: Firefox
  5773 +// Firefox doesn't have focus(in | out) events
  5774 +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
  5775 +//
  5776 +// Support: Chrome, Safari
  5777 +// focus(in | out) events fire after focus & blur events,
  5778 +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
  5779 +// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
  5780 +if ( !support.focusin ) {
  5781 + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  5782 +
  5783 + // Attach a single capturing handler on the document while someone wants focusin/focusout
  5784 + var handler = function( event ) {
  5785 + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
  5786 + };
  5787 +
  5788 + jQuery.event.special[ fix ] = {
  5789 + setup: function() {
  5790 + var doc = this.ownerDocument || this,
  5791 + attaches = jQuery._data( doc, fix );
  5792 +
  5793 + if ( !attaches ) {
  5794 + doc.addEventListener( orig, handler, true );
  5795 + }
  5796 + jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
  5797 + },
  5798 + teardown: function() {
  5799 + var doc = this.ownerDocument || this,
  5800 + attaches = jQuery._data( doc, fix ) - 1;
  5801 +
  5802 + if ( !attaches ) {
  5803 + doc.removeEventListener( orig, handler, true );
  5804 + jQuery._removeData( doc, fix );
  5805 + } else {
  5806 + jQuery._data( doc, fix, attaches );
  5807 + }
  5808 + }
  5809 + };
  5810 + } );
  5811 +}
  5812 +
  5813 +jQuery.fn.extend( {
  5814 +
  5815 + on: function( types, selector, data, fn ) {
  5816 + return on( this, types, selector, data, fn );
  5817 + },
  5818 + one: function( types, selector, data, fn ) {
  5819 + return on( this, types, selector, data, fn, 1 );
  5820 + },
  5821 + off: function( types, selector, fn ) {
  5822 + var handleObj, type;
  5823 + if ( types && types.preventDefault && types.handleObj ) {
  5824 +
  5825 + // ( event ) dispatched jQuery.Event
  5826 + handleObj = types.handleObj;
  5827 + jQuery( types.delegateTarget ).off(
  5828 + handleObj.namespace ?
  5829 + handleObj.origType + "." + handleObj.namespace :
  5830 + handleObj.origType,
  5831 + handleObj.selector,
  5832 + handleObj.handler
  5833 + );
  5834 + return this;
  5835 + }
  5836 + if ( typeof types === "object" ) {
  5837 +
  5838 + // ( types-object [, selector] )
  5839 + for ( type in types ) {
  5840 + this.off( type, selector, types[ type ] );
  5841 + }
  5842 + return this;
  5843 + }
  5844 + if ( selector === false || typeof selector === "function" ) {
  5845 +
  5846 + // ( types [, fn] )
  5847 + fn = selector;
  5848 + selector = undefined;
  5849 + }
  5850 + if ( fn === false ) {
  5851 + fn = returnFalse;
  5852 + }
  5853 + return this.each( function() {
  5854 + jQuery.event.remove( this, types, fn, selector );
  5855 + } );
  5856 + },
  5857 +
  5858 + trigger: function( type, data ) {
  5859 + return this.each( function() {
  5860 + jQuery.event.trigger( type, data, this );
  5861 + } );
  5862 + },
  5863 + triggerHandler: function( type, data ) {
  5864 + var elem = this[ 0 ];
  5865 + if ( elem ) {
  5866 + return jQuery.event.trigger( type, data, elem, true );
  5867 + }
  5868 + }
  5869 +} );
  5870 +
  5871 +
  5872 +var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
  5873 + rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
  5874 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
  5875 +
  5876 + // Support: IE 10-11, Edge 10240+
  5877 + // In IE/Edge using regex groups here causes severe slowdowns.
  5878 + // See https://connect.microsoft.com/IE/feedback/details/1736512/
  5879 + rnoInnerhtml = /<script|<style|<link/i,
  5880 +
  5881 + // checked="checked" or checked
  5882 + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  5883 + rscriptTypeMasked = /^true\/(.*)/,
  5884 + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
  5885 + safeFragment = createSafeFragment( document ),
  5886 + fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
  5887 +
  5888 +// Support: IE<8
  5889 +// Manipulating tables requires a tbody
  5890 +function manipulationTarget( elem, content ) {
  5891 + return jQuery.nodeName( elem, "table" ) &&
  5892 + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
  5893 +
  5894 + elem.getElementsByTagName( "tbody" )[ 0 ] ||
  5895 + elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
  5896 + elem;
  5897 +}
  5898 +
  5899 +// Replace/restore the type attribute of script elements for safe DOM manipulation
  5900 +function disableScript( elem ) {
  5901 + elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
  5902 + return elem;
  5903 +}
  5904 +function restoreScript( elem ) {
  5905 + var match = rscriptTypeMasked.exec( elem.type );
  5906 + if ( match ) {
  5907 + elem.type = match[ 1 ];
  5908 + } else {
  5909 + elem.removeAttribute( "type" );
  5910 + }
  5911 + return elem;
  5912 +}
  5913 +
  5914 +function cloneCopyEvent( src, dest ) {
  5915 + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
  5916 + return;
  5917 + }
  5918 +
  5919 + var type, i, l,
  5920 + oldData = jQuery._data( src ),
  5921 + curData = jQuery._data( dest, oldData ),
  5922 + events = oldData.events;
  5923 +
  5924 + if ( events ) {
  5925 + delete curData.handle;
  5926 + curData.events = {};
  5927 +
  5928 + for ( type in events ) {
  5929 + for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  5930 + jQuery.event.add( dest, type, events[ type ][ i ] );
  5931 + }
  5932 + }
  5933 + }
  5934 +
  5935 + // make the cloned public data object a copy from the original
  5936 + if ( curData.data ) {
  5937 + curData.data = jQuery.extend( {}, curData.data );
  5938 + }
  5939 +}
  5940 +
  5941 +function fixCloneNodeIssues( src, dest ) {
  5942 + var nodeName, e, data;
  5943 +
  5944 + // We do not need to do anything for non-Elements
  5945 + if ( dest.nodeType !== 1 ) {
  5946 + return;
  5947 + }
  5948 +
  5949 + nodeName = dest.nodeName.toLowerCase();
  5950 +
  5951 + // IE6-8 copies events bound via attachEvent when using cloneNode.
  5952 + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
  5953 + data = jQuery._data( dest );
  5954 +
  5955 + for ( e in data.events ) {
  5956 + jQuery.removeEvent( dest, e, data.handle );
  5957 + }
  5958 +
  5959 + // Event data gets referenced instead of copied if the expando gets copied too
  5960 + dest.removeAttribute( jQuery.expando );
  5961 + }
  5962 +
  5963 + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
  5964 + if ( nodeName === "script" && dest.text !== src.text ) {
  5965 + disableScript( dest ).text = src.text;
  5966 + restoreScript( dest );
  5967 +
  5968 + // IE6-10 improperly clones children of object elements using classid.
  5969 + // IE10 throws NoModificationAllowedError if parent is null, #12132.
  5970 + } else if ( nodeName === "object" ) {
  5971 + if ( dest.parentNode ) {
  5972 + dest.outerHTML = src.outerHTML;
  5973 + }
  5974 +
  5975 + // This path appears unavoidable for IE9. When cloning an object
  5976 + // element in IE9, the outerHTML strategy above is not sufficient.
  5977 + // If the src has innerHTML and the destination does not,
  5978 + // copy the src.innerHTML into the dest.innerHTML. #10324
  5979 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
  5980 + dest.innerHTML = src.innerHTML;
  5981 + }
  5982 +
  5983 + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
  5984 +
  5985 + // IE6-8 fails to persist the checked state of a cloned checkbox
  5986 + // or radio button. Worse, IE6-7 fail to give the cloned element
  5987 + // a checked appearance if the defaultChecked value isn't also set
  5988 +
  5989 + dest.defaultChecked = dest.checked = src.checked;
  5990 +
  5991 + // IE6-7 get confused and end up setting the value of a cloned
  5992 + // checkbox/radio button to an empty string instead of "on"
  5993 + if ( dest.value !== src.value ) {
  5994 + dest.value = src.value;
  5995 + }
  5996 +
  5997 + // IE6-8 fails to return the selected option to the default selected
  5998 + // state when cloning options
  5999 + } else if ( nodeName === "option" ) {
  6000 + dest.defaultSelected = dest.selected = src.defaultSelected;
  6001 +
  6002 + // IE6-8 fails to set the defaultValue to the correct value when
  6003 + // cloning other types of input fields
  6004 + } else if ( nodeName === "input" || nodeName === "textarea" ) {
  6005 + dest.defaultValue = src.defaultValue;
  6006 + }
  6007 +}
  6008 +
  6009 +function domManip( collection, args, callback, ignored ) {
  6010 +
  6011 + // Flatten any nested arrays
  6012 + args = concat.apply( [], args );
  6013 +
  6014 + var first, node, hasScripts,
  6015 + scripts, doc, fragment,
  6016 + i = 0,
  6017 + l = collection.length,
  6018 + iNoClone = l - 1,
  6019 + value = args[ 0 ],
  6020 + isFunction = jQuery.isFunction( value );
  6021 +
  6022 + // We can't cloneNode fragments that contain checked, in WebKit
  6023 + if ( isFunction ||
  6024 + ( l > 1 && typeof value === "string" &&
  6025 + !support.checkClone && rchecked.test( value ) ) ) {
  6026 + return collection.each( function( index ) {
  6027 + var self = collection.eq( index );
  6028 + if ( isFunction ) {
  6029 + args[ 0 ] = value.call( this, index, self.html() );
  6030 + }
  6031 + domManip( self, args, callback, ignored );
  6032 + } );
  6033 + }
  6034 +
  6035 + if ( l ) {
  6036 + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
  6037 + first = fragment.firstChild;
  6038 +
  6039 + if ( fragment.childNodes.length === 1 ) {
  6040 + fragment = first;
  6041 + }
  6042 +
  6043 + // Require either new content or an interest in ignored elements to invoke the callback
  6044 + if ( first || ignored ) {
  6045 + scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  6046 + hasScripts = scripts.length;
  6047 +
  6048 + // Use the original fragment for the last item
  6049 + // instead of the first because it can end up
  6050 + // being emptied incorrectly in certain situations (#8070).
  6051 + for ( ; i < l; i++ ) {
  6052 + node = fragment;
  6053 +
  6054 + if ( i !== iNoClone ) {
  6055 + node = jQuery.clone( node, true, true );
  6056 +
  6057 + // Keep references to cloned scripts for later restoration
  6058 + if ( hasScripts ) {
  6059 +
  6060 + // Support: Android<4.1, PhantomJS<2
  6061 + // push.apply(_, arraylike) throws on ancient WebKit
  6062 + jQuery.merge( scripts, getAll( node, "script" ) );
  6063 + }
  6064 + }
  6065 +
  6066 + callback.call( collection[ i ], node, i );
  6067 + }
  6068 +
  6069 + if ( hasScripts ) {
  6070 + doc = scripts[ scripts.length - 1 ].ownerDocument;
  6071 +
  6072 + // Reenable scripts
  6073 + jQuery.map( scripts, restoreScript );
  6074 +
  6075 + // Evaluate executable scripts on first document insertion
  6076 + for ( i = 0; i < hasScripts; i++ ) {
  6077 + node = scripts[ i ];
  6078 + if ( rscriptType.test( node.type || "" ) &&
  6079 + !jQuery._data( node, "globalEval" ) &&
  6080 + jQuery.contains( doc, node ) ) {
  6081 +
  6082 + if ( node.src ) {
  6083 +
  6084 + // Optional AJAX dependency, but won't run scripts if not present
  6085 + if ( jQuery._evalUrl ) {
  6086 + jQuery._evalUrl( node.src );
  6087 + }
  6088 + } else {
  6089 + jQuery.globalEval(
  6090 + ( node.text || node.textContent || node.innerHTML || "" )
  6091 + .replace( rcleanScript, "" )
  6092 + );
  6093 + }
  6094 + }
  6095 + }
  6096 + }
  6097 +
  6098 + // Fix #11809: Avoid leaking memory
  6099 + fragment = first = null;
  6100 + }
  6101 + }
  6102 +
  6103 + return collection;
  6104 +}
  6105 +
  6106 +function remove( elem, selector, keepData ) {
  6107 + var node,
  6108 + elems = selector ? jQuery.filter( selector, elem ) : elem,
  6109 + i = 0;
  6110 +
  6111 + for ( ; ( node = elems[ i ] ) != null; i++ ) {
  6112 +
  6113 + if ( !keepData && node.nodeType === 1 ) {
  6114 + jQuery.cleanData( getAll( node ) );
  6115 + }
  6116 +
  6117 + if ( node.parentNode ) {
  6118 + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
  6119 + setGlobalEval( getAll( node, "script" ) );
  6120 + }
  6121 + node.parentNode.removeChild( node );
  6122 + }
  6123 + }
  6124 +
  6125 + return elem;
  6126 +}
  6127 +
  6128 +jQuery.extend( {
  6129 + htmlPrefilter: function( html ) {
  6130 + return html.replace( rxhtmlTag, "<$1></$2>" );
  6131 + },
  6132 +
  6133 + clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  6134 + var destElements, node, clone, i, srcElements,
  6135 + inPage = jQuery.contains( elem.ownerDocument, elem );
  6136 +
  6137 + if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
  6138 + !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
  6139 +
  6140 + clone = elem.cloneNode( true );
  6141 +
  6142 + // IE<=8 does not properly clone detached, unknown element nodes
  6143 + } else {
  6144 + fragmentDiv.innerHTML = elem.outerHTML;
  6145 + fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
  6146 + }
  6147 +
  6148 + if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
  6149 + ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
  6150 +
  6151 + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
  6152 + destElements = getAll( clone );
  6153 + srcElements = getAll( elem );
  6154 +
  6155 + // Fix all IE cloning issues
  6156 + for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
  6157 +
  6158 + // Ensure that the destination node is not null; Fixes #9587
  6159 + if ( destElements[ i ] ) {
  6160 + fixCloneNodeIssues( node, destElements[ i ] );
  6161 + }
  6162 + }
  6163 + }
  6164 +
  6165 + // Copy the events from the original to the clone
  6166 + if ( dataAndEvents ) {
  6167 + if ( deepDataAndEvents ) {
  6168 + srcElements = srcElements || getAll( elem );
  6169 + destElements = destElements || getAll( clone );
  6170 +
  6171 + for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
  6172 + cloneCopyEvent( node, destElements[ i ] );
  6173 + }
  6174 + } else {
  6175 + cloneCopyEvent( elem, clone );
  6176 + }
  6177 + }
  6178 +
  6179 + // Preserve script evaluation history
  6180 + destElements = getAll( clone, "script" );
  6181 + if ( destElements.length > 0 ) {
  6182 + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  6183 + }
  6184 +
  6185 + destElements = srcElements = node = null;
  6186 +
  6187 + // Return the cloned set
  6188 + return clone;
  6189 + },
  6190 +
  6191 + cleanData: function( elems, /* internal */ forceAcceptData ) {
  6192 + var elem, type, id, data,
  6193 + i = 0,
  6194 + internalKey = jQuery.expando,
  6195 + cache = jQuery.cache,
  6196 + attributes = support.attributes,
  6197 + special = jQuery.event.special;
  6198 +
  6199 + for ( ; ( elem = elems[ i ] ) != null; i++ ) {
  6200 + if ( forceAcceptData || acceptData( elem ) ) {
  6201 +
  6202 + id = elem[ internalKey ];
  6203 + data = id && cache[ id ];
  6204 +
  6205 + if ( data ) {
  6206 + if ( data.events ) {
  6207 + for ( type in data.events ) {
  6208 + if ( special[ type ] ) {
  6209 + jQuery.event.remove( elem, type );
  6210 +
  6211 + // This is a shortcut to avoid jQuery.event.remove's overhead
  6212 + } else {
  6213 + jQuery.removeEvent( elem, type, data.handle );
  6214 + }
  6215 + }
  6216 + }
  6217 +
  6218 + // Remove cache only if it was not already removed by jQuery.event.remove
  6219 + if ( cache[ id ] ) {
  6220 +
  6221 + delete cache[ id ];
  6222 +
  6223 + // Support: IE<9
  6224 + // IE does not allow us to delete expando properties from nodes
  6225 + // IE creates expando attributes along with the property
  6226 + // IE does not have a removeAttribute function on Document nodes
  6227 + if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
  6228 + elem.removeAttribute( internalKey );
  6229 +
  6230 + // Webkit & Blink performance suffers when deleting properties
  6231 + // from DOM nodes, so set to undefined instead
  6232 + // https://code.google.com/p/chromium/issues/detail?id=378607
  6233 + } else {
  6234 + elem[ internalKey ] = undefined;
  6235 + }
  6236 +
  6237 + deletedIds.push( id );
  6238 + }
  6239 + }
  6240 + }
  6241 + }
  6242 + }
  6243 +} );
  6244 +
  6245 +jQuery.fn.extend( {
  6246 +
  6247 + // Keep domManip exposed until 3.0 (gh-2225)
  6248 + domManip: domManip,
  6249 +
  6250 + detach: function( selector ) {
  6251 + return remove( this, selector, true );
  6252 + },
  6253 +
  6254 + remove: function( selector ) {
  6255 + return remove( this, selector );
  6256 + },
  6257 +
  6258 + text: function( value ) {
  6259 + return access( this, function( value ) {
  6260 + return value === undefined ?
  6261 + jQuery.text( this ) :
  6262 + this.empty().append(
  6263 + ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
  6264 + );
  6265 + }, null, value, arguments.length );
  6266 + },
  6267 +
  6268 + append: function() {
  6269 + return domManip( this, arguments, function( elem ) {
  6270 + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  6271 + var target = manipulationTarget( this, elem );
  6272 + target.appendChild( elem );
  6273 + }
  6274 + } );
  6275 + },
  6276 +
  6277 + prepend: function() {
  6278 + return domManip( this, arguments, function( elem ) {
  6279 + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  6280 + var target = manipulationTarget( this, elem );
  6281 + target.insertBefore( elem, target.firstChild );
  6282 + }
  6283 + } );
  6284 + },
  6285 +
  6286 + before: function() {
  6287 + return domManip( this, arguments, function( elem ) {
  6288 + if ( this.parentNode ) {
  6289 + this.parentNode.insertBefore( elem, this );
  6290 + }
  6291 + } );
  6292 + },
  6293 +
  6294 + after: function() {
  6295 + return domManip( this, arguments, function( elem ) {
  6296 + if ( this.parentNode ) {
  6297 + this.parentNode.insertBefore( elem, this.nextSibling );
  6298 + }
  6299 + } );
  6300 + },
  6301 +
  6302 + empty: function() {
  6303 + var elem,
  6304 + i = 0;
  6305 +
  6306 + for ( ; ( elem = this[ i ] ) != null; i++ ) {
  6307 +
  6308 + // Remove element nodes and prevent memory leaks
  6309 + if ( elem.nodeType === 1 ) {
  6310 + jQuery.cleanData( getAll( elem, false ) );
  6311 + }
  6312 +
  6313 + // Remove any remaining nodes
  6314 + while ( elem.firstChild ) {
  6315 + elem.removeChild( elem.firstChild );
  6316 + }
  6317 +
  6318 + // If this is a select, ensure that it displays empty (#12336)
  6319 + // Support: IE<9
  6320 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
  6321 + elem.options.length = 0;
  6322 + }
  6323 + }
  6324 +
  6325 + return this;
  6326 + },
  6327 +
  6328 + clone: function( dataAndEvents, deepDataAndEvents ) {
  6329 + dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  6330 + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  6331 +
  6332 + return this.map( function() {
  6333 + return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  6334 + } );
  6335 + },
  6336 +
  6337 + html: function( value ) {
  6338 + return access( this, function( value ) {
  6339 + var elem = this[ 0 ] || {},
  6340 + i = 0,
  6341 + l = this.length;
  6342 +
  6343 + if ( value === undefined ) {
  6344 + return elem.nodeType === 1 ?
  6345 + elem.innerHTML.replace( rinlinejQuery, "" ) :
  6346 + undefined;
  6347 + }
  6348 +
  6349 + // See if we can take a shortcut and just use innerHTML
  6350 + if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  6351 + ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
  6352 + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
  6353 + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  6354 +
  6355 + value = jQuery.htmlPrefilter( value );
  6356 +
  6357 + try {
  6358 + for ( ; i < l; i++ ) {
  6359 +
  6360 + // Remove element nodes and prevent memory leaks
  6361 + elem = this[ i ] || {};
  6362 + if ( elem.nodeType === 1 ) {
  6363 + jQuery.cleanData( getAll( elem, false ) );
  6364 + elem.innerHTML = value;
  6365 + }
  6366 + }
  6367 +
  6368 + elem = 0;
  6369 +
  6370 + // If using innerHTML throws an exception, use the fallback method
  6371 + } catch ( e ) {}
  6372 + }
  6373 +
  6374 + if ( elem ) {
  6375 + this.empty().append( value );
  6376 + }
  6377 + }, null, value, arguments.length );
  6378 + },
  6379 +
  6380 + replaceWith: function() {
  6381 + var ignored = [];
  6382 +
  6383 + // Make the changes, replacing each non-ignored context element with the new content
  6384 + return domManip( this, arguments, function( elem ) {
  6385 + var parent = this.parentNode;
  6386 +
  6387 + if ( jQuery.inArray( this, ignored ) < 0 ) {
  6388 + jQuery.cleanData( getAll( this ) );
  6389 + if ( parent ) {
  6390 + parent.replaceChild( elem, this );
  6391 + }
  6392 + }
  6393 +
  6394 + // Force callback invocation
  6395 + }, ignored );
  6396 + }
  6397 +} );
  6398 +
  6399 +jQuery.each( {
  6400 + appendTo: "append",
  6401 + prependTo: "prepend",
  6402 + insertBefore: "before",
  6403 + insertAfter: "after",
  6404 + replaceAll: "replaceWith"
  6405 +}, function( name, original ) {
  6406 + jQuery.fn[ name ] = function( selector ) {
  6407 + var elems,
  6408 + i = 0,
  6409 + ret = [],
  6410 + insert = jQuery( selector ),
  6411 + last = insert.length - 1;
  6412 +
  6413 + for ( ; i <= last; i++ ) {
  6414 + elems = i === last ? this : this.clone( true );
  6415 + jQuery( insert[ i ] )[ original ]( elems );
  6416 +
  6417 + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
  6418 + push.apply( ret, elems.get() );
  6419 + }
  6420 +
  6421 + return this.pushStack( ret );
  6422 + };
  6423 +} );
  6424 +
  6425 +
  6426 +var iframe,
  6427 + elemdisplay = {
  6428 +
  6429 + // Support: Firefox
  6430 + // We have to pre-define these values for FF (#10227)
  6431 + HTML: "block",
  6432 + BODY: "block"
  6433 + };
  6434 +
  6435 +/**
  6436 + * Retrieve the actual display of a element
  6437 + * @param {String} name nodeName of the element
  6438 + * @param {Object} doc Document object
  6439 + */
  6440 +
  6441 +// Called only from within defaultDisplay
  6442 +function actualDisplay( name, doc ) {
  6443 + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
  6444 +
  6445 + display = jQuery.css( elem[ 0 ], "display" );
  6446 +
  6447 + // We don't have any data stored on the element,
  6448 + // so use "detach" method as fast way to get rid of the element
  6449 + elem.detach();
  6450 +
  6451 + return display;
  6452 +}
  6453 +
  6454 +/**
  6455 + * Try to determine the default display value of an element
  6456 + * @param {String} nodeName
  6457 + */
  6458 +function defaultDisplay( nodeName ) {
  6459 + var doc = document,
  6460 + display = elemdisplay[ nodeName ];
  6461 +
  6462 + if ( !display ) {
  6463 + display = actualDisplay( nodeName, doc );
  6464 +
  6465 + // If the simple way fails, read from inside an iframe
  6466 + if ( display === "none" || !display ) {
  6467 +
  6468 + // Use the already-created iframe if possible
  6469 + iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
  6470 + .appendTo( doc.documentElement );
  6471 +
  6472 + // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
  6473 + doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
  6474 +
  6475 + // Support: IE
  6476 + doc.write();
  6477 + doc.close();
  6478 +
  6479 + display = actualDisplay( nodeName, doc );
  6480 + iframe.detach();
  6481 + }
  6482 +
  6483 + // Store the correct default display
  6484 + elemdisplay[ nodeName ] = display;
  6485 + }
  6486 +
  6487 + return display;
  6488 +}
  6489 +var rmargin = ( /^margin/ );
  6490 +
  6491 +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
  6492 +
  6493 +var swap = function( elem, options, callback, args ) {
  6494 + var ret, name,
  6495 + old = {};
  6496 +
  6497 + // Remember the old values, and insert the new ones
  6498 + for ( name in options ) {
  6499 + old[ name ] = elem.style[ name ];
  6500 + elem.style[ name ] = options[ name ];
  6501 + }
  6502 +
  6503 + ret = callback.apply( elem, args || [] );
  6504 +
  6505 + // Revert the old values
  6506 + for ( name in options ) {
  6507 + elem.style[ name ] = old[ name ];
  6508 + }
  6509 +
  6510 + return ret;
  6511 +};
  6512 +
  6513 +
  6514 +var documentElement = document.documentElement;
  6515 +
  6516 +
  6517 +
  6518 +( function() {
  6519 + var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
  6520 + reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
  6521 + container = document.createElement( "div" ),
  6522 + div = document.createElement( "div" );
  6523 +
  6524 + // Finish early in limited (non-browser) environments
  6525 + if ( !div.style ) {
  6526 + return;
  6527 + }
  6528 +
  6529 + div.style.cssText = "float:left;opacity:.5";
  6530 +
  6531 + // Support: IE<9
  6532 + // Make sure that element opacity exists (as opposed to filter)
  6533 + support.opacity = div.style.opacity === "0.5";
  6534 +
  6535 + // Verify style float existence
  6536 + // (IE uses styleFloat instead of cssFloat)
  6537 + support.cssFloat = !!div.style.cssFloat;
  6538 +
  6539 + div.style.backgroundClip = "content-box";
  6540 + div.cloneNode( true ).style.backgroundClip = "";
  6541 + support.clearCloneStyle = div.style.backgroundClip === "content-box";
  6542 +
  6543 + container = document.createElement( "div" );
  6544 + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
  6545 + "padding:0;margin-top:1px;position:absolute";
  6546 + div.innerHTML = "";
  6547 + container.appendChild( div );
  6548 +
  6549 + // Support: Firefox<29, Android 2.3
  6550 + // Vendor-prefix box-sizing
  6551 + support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
  6552 + div.style.WebkitBoxSizing === "";
  6553 +
  6554 + jQuery.extend( support, {
  6555 + reliableHiddenOffsets: function() {
  6556 + if ( pixelPositionVal == null ) {
  6557 + computeStyleTests();
  6558 + }
  6559 + return reliableHiddenOffsetsVal;
  6560 + },
  6561 +
  6562 + boxSizingReliable: function() {
  6563 +
  6564 + // We're checking for pixelPositionVal here instead of boxSizingReliableVal
  6565 + // since that compresses better and they're computed together anyway.
  6566 + if ( pixelPositionVal == null ) {
  6567 + computeStyleTests();
  6568 + }
  6569 + return boxSizingReliableVal;
  6570 + },
  6571 +
  6572 + pixelMarginRight: function() {
  6573 +
  6574 + // Support: Android 4.0-4.3
  6575 + if ( pixelPositionVal == null ) {
  6576 + computeStyleTests();
  6577 + }
  6578 + return pixelMarginRightVal;
  6579 + },
  6580 +
  6581 + pixelPosition: function() {
  6582 + if ( pixelPositionVal == null ) {
  6583 + computeStyleTests();
  6584 + }
  6585 + return pixelPositionVal;
  6586 + },
  6587 +
  6588 + reliableMarginRight: function() {
  6589 +
  6590 + // Support: Android 2.3
  6591 + if ( pixelPositionVal == null ) {
  6592 + computeStyleTests();
  6593 + }
  6594 + return reliableMarginRightVal;
  6595 + },
  6596 +
  6597 + reliableMarginLeft: function() {
  6598 +
  6599 + // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
  6600 + if ( pixelPositionVal == null ) {
  6601 + computeStyleTests();
  6602 + }
  6603 + return reliableMarginLeftVal;
  6604 + }
  6605 + } );
  6606 +
  6607 + function computeStyleTests() {
  6608 + var contents, divStyle,
  6609 + documentElement = document.documentElement;
  6610 +
  6611 + // Setup
  6612 + documentElement.appendChild( container );
  6613 +
  6614 + div.style.cssText =
  6615 +
  6616 + // Support: Android 2.3
  6617 + // Vendor-prefix box-sizing
  6618 + "-webkit-box-sizing:border-box;box-sizing:border-box;" +
  6619 + "position:relative;display:block;" +
  6620 + "margin:auto;border:1px;padding:1px;" +
  6621 + "top:1%;width:50%";
  6622 +
  6623 + // Support: IE<9
  6624 + // Assume reasonable values in the absence of getComputedStyle
  6625 + pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
  6626 + pixelMarginRightVal = reliableMarginRightVal = true;
  6627 +
  6628 + // Check for getComputedStyle so that this code is not run in IE<9.
  6629 + if ( window.getComputedStyle ) {
  6630 + divStyle = window.getComputedStyle( div );
  6631 + pixelPositionVal = ( divStyle || {} ).top !== "1%";
  6632 + reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
  6633 + boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
  6634 +
  6635 + // Support: Android 4.0 - 4.3 only
  6636 + // Some styles come back with percentage values, even though they shouldn't
  6637 + div.style.marginRight = "50%";
  6638 + pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
  6639 +
  6640 + // Support: Android 2.3 only
  6641 + // Div with explicit width and no margin-right incorrectly
  6642 + // gets computed margin-right based on width of container (#3333)
  6643 + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  6644 + contents = div.appendChild( document.createElement( "div" ) );
  6645 +
  6646 + // Reset CSS: box-sizing; display; margin; border; padding
  6647 + contents.style.cssText = div.style.cssText =
  6648 +
  6649 + // Support: Android 2.3
  6650 + // Vendor-prefix box-sizing
  6651 + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
  6652 + "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
  6653 + contents.style.marginRight = contents.style.width = "0";
  6654 + div.style.width = "1px";
  6655 +
  6656 + reliableMarginRightVal =
  6657 + !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
  6658 +
  6659 + div.removeChild( contents );
  6660 + }
  6661 +
  6662 + // Support: IE6-8
  6663 + // First check that getClientRects works as expected
  6664 + // Check if table cells still have offsetWidth/Height when they are set
  6665 + // to display:none and there are still other visible table cells in a
  6666 + // table row; if so, offsetWidth/Height are not reliable for use when
  6667 + // determining if an element has been hidden directly using
  6668 + // display:none (it is still safe to use offsets if a parent element is
  6669 + // hidden; don safety goggles and see bug #4512 for more information).
  6670 + div.style.display = "none";
  6671 + reliableHiddenOffsetsVal = div.getClientRects().length === 0;
  6672 + if ( reliableHiddenOffsetsVal ) {
  6673 + div.style.display = "";
  6674 + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
  6675 + contents = div.getElementsByTagName( "td" );
  6676 + contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
  6677 + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
  6678 + if ( reliableHiddenOffsetsVal ) {
  6679 + contents[ 0 ].style.display = "";
  6680 + contents[ 1 ].style.display = "none";
  6681 + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
  6682 + }
  6683 + }
  6684 +
  6685 + // Teardown
  6686 + documentElement.removeChild( container );
  6687 + }
  6688 +
  6689 +} )();
  6690 +
  6691 +
  6692 +var getStyles, curCSS,
  6693 + rposition = /^(top|right|bottom|left)$/;
  6694 +
  6695 +if ( window.getComputedStyle ) {
  6696 + getStyles = function( elem ) {
  6697 +
  6698 + // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
  6699 + // IE throws on elements created in popups
  6700 + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
  6701 + var view = elem.ownerDocument.defaultView;
  6702 +
  6703 + if ( !view || !view.opener ) {
  6704 + view = window;
  6705 + }
  6706 +
  6707 + return view.getComputedStyle( elem );
  6708 + };
  6709 +
  6710 + curCSS = function( elem, name, computed ) {
  6711 + var width, minWidth, maxWidth, ret,
  6712 + style = elem.style;
  6713 +
  6714 + computed = computed || getStyles( elem );
  6715 +
  6716 + // getPropertyValue is only needed for .css('filter') in IE9, see #12537
  6717 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
  6718 +
  6719 + // Support: Opera 12.1x only
  6720 + // Fall back to style even without computed
  6721 + // computed is undefined for elems on document fragments
  6722 + if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
  6723 + ret = jQuery.style( elem, name );
  6724 + }
  6725 +
  6726 + if ( computed ) {
  6727 +
  6728 + // A tribute to the "awesome hack by Dean Edwards"
  6729 + // Chrome < 17 and Safari 5.0 uses "computed value"
  6730 + // instead of "used value" for margin-right
  6731 + // Safari 5.1.7 (at least) returns percentage for a larger set of values,
  6732 + // but width seems to be reliably pixels
  6733 + // this is against the CSSOM draft spec:
  6734 + // http://dev.w3.org/csswg/cssom/#resolved-values
  6735 + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  6736 +
  6737 + // Remember the original values
  6738 + width = style.width;
  6739 + minWidth = style.minWidth;
  6740 + maxWidth = style.maxWidth;
  6741 +
  6742 + // Put in the new values to get a computed value out
  6743 + style.minWidth = style.maxWidth = style.width = ret;
  6744 + ret = computed.width;
  6745 +
  6746 + // Revert the changed values
  6747 + style.width = width;
  6748 + style.minWidth = minWidth;
  6749 + style.maxWidth = maxWidth;
  6750 + }
  6751 + }
  6752 +
  6753 + // Support: IE
  6754 + // IE returns zIndex value as an integer.
  6755 + return ret === undefined ?
  6756 + ret :
  6757 + ret + "";
  6758 + };
  6759 +} else if ( documentElement.currentStyle ) {
  6760 + getStyles = function( elem ) {
  6761 + return elem.currentStyle;
  6762 + };
  6763 +
  6764 + curCSS = function( elem, name, computed ) {
  6765 + var left, rs, rsLeft, ret,
  6766 + style = elem.style;
  6767 +
  6768 + computed = computed || getStyles( elem );
  6769 + ret = computed ? computed[ name ] : undefined;
  6770 +
  6771 + // Avoid setting ret to empty string here
  6772 + // so we don't default to auto
  6773 + if ( ret == null && style && style[ name ] ) {
  6774 + ret = style[ name ];
  6775 + }
  6776 +
  6777 + // From the awesome hack by Dean Edwards
  6778 + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  6779 +
  6780 + // If we're not dealing with a regular pixel number
  6781 + // but a number that has a weird ending, we need to convert it to pixels
  6782 + // but not position css attributes, as those are
  6783 + // proportional to the parent element instead
  6784 + // and we can't measure the parent instead because it
  6785 + // might trigger a "stacking dolls" problem
  6786 + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
  6787 +
  6788 + // Remember the original values
  6789 + left = style.left;
  6790 + rs = elem.runtimeStyle;
  6791 + rsLeft = rs && rs.left;
  6792 +
  6793 + // Put in the new values to get a computed value out
  6794 + if ( rsLeft ) {
  6795 + rs.left = elem.currentStyle.left;
  6796 + }
  6797 + style.left = name === "fontSize" ? "1em" : ret;
  6798 + ret = style.pixelLeft + "px";
  6799 +
  6800 + // Revert the changed values
  6801 + style.left = left;
  6802 + if ( rsLeft ) {
  6803 + rs.left = rsLeft;
  6804 + }
  6805 + }
  6806 +
  6807 + // Support: IE
  6808 + // IE returns zIndex value as an integer.
  6809 + return ret === undefined ?
  6810 + ret :
  6811 + ret + "" || "auto";
  6812 + };
  6813 +}
  6814 +
  6815 +
  6816 +
  6817 +
  6818 +function addGetHookIf( conditionFn, hookFn ) {
  6819 +
  6820 + // Define the hook, we'll check on the first run if it's really needed.
  6821 + return {
  6822 + get: function() {
  6823 + if ( conditionFn() ) {
  6824 +
  6825 + // Hook not needed (or it's not possible to use it due
  6826 + // to missing dependency), remove it.
  6827 + delete this.get;
  6828 + return;
  6829 + }
  6830 +
  6831 + // Hook needed; redefine it so that the support test is not executed again.
  6832 + return ( this.get = hookFn ).apply( this, arguments );
  6833 + }
  6834 + };
  6835 +}
  6836 +
  6837 +
  6838 +var
  6839 +
  6840 + ralpha = /alpha\([^)]*\)/i,
  6841 + ropacity = /opacity\s*=\s*([^)]*)/i,
  6842 +
  6843 + // swappable if display is none or starts with table except
  6844 + // "table", "table-cell", or "table-caption"
  6845 + // see here for display values:
  6846 + // https://developer.mozilla.org/en-US/docs/CSS/display
  6847 + rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  6848 + rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
  6849 +
  6850 + cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  6851 + cssNormalTransform = {
  6852 + letterSpacing: "0",
  6853 + fontWeight: "400"
  6854 + },
  6855 +
  6856 + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
  6857 + emptyStyle = document.createElement( "div" ).style;
  6858 +
  6859 +
  6860 +// return a css property mapped to a potentially vendor prefixed property
  6861 +function vendorPropName( name ) {
  6862 +
  6863 + // shortcut for names that are not vendor prefixed
  6864 + if ( name in emptyStyle ) {
  6865 + return name;
  6866 + }
  6867 +
  6868 + // check for vendor prefixed names
  6869 + var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
  6870 + i = cssPrefixes.length;
  6871 +
  6872 + while ( i-- ) {
  6873 + name = cssPrefixes[ i ] + capName;
  6874 + if ( name in emptyStyle ) {
  6875 + return name;
  6876 + }
  6877 + }
  6878 +}
  6879 +
  6880 +function showHide( elements, show ) {
  6881 + var display, elem, hidden,
  6882 + values = [],
  6883 + index = 0,
  6884 + length = elements.length;
  6885 +
  6886 + for ( ; index < length; index++ ) {
  6887 + elem = elements[ index ];
  6888 + if ( !elem.style ) {
  6889 + continue;
  6890 + }
  6891 +
  6892 + values[ index ] = jQuery._data( elem, "olddisplay" );
  6893 + display = elem.style.display;
  6894 + if ( show ) {
  6895 +
  6896 + // Reset the inline display of this element to learn if it is
  6897 + // being hidden by cascaded rules or not
  6898 + if ( !values[ index ] && display === "none" ) {
  6899 + elem.style.display = "";
  6900 + }
  6901 +
  6902 + // Set elements which have been overridden with display: none
  6903 + // in a stylesheet to whatever the default browser style is
  6904 + // for such an element
  6905 + if ( elem.style.display === "" && isHidden( elem ) ) {
  6906 + values[ index ] =
  6907 + jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
  6908 + }
  6909 + } else {
  6910 + hidden = isHidden( elem );
  6911 +
  6912 + if ( display && display !== "none" || !hidden ) {
  6913 + jQuery._data(
  6914 + elem,
  6915 + "olddisplay",
  6916 + hidden ? display : jQuery.css( elem, "display" )
  6917 + );
  6918 + }
  6919 + }
  6920 + }
  6921 +
  6922 + // Set the display of most of the elements in a second loop
  6923 + // to avoid the constant reflow
  6924 + for ( index = 0; index < length; index++ ) {
  6925 + elem = elements[ index ];
  6926 + if ( !elem.style ) {
  6927 + continue;
  6928 + }
  6929 + if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  6930 + elem.style.display = show ? values[ index ] || "" : "none";
  6931 + }
  6932 + }
  6933 +
  6934 + return elements;
  6935 +}
  6936 +
  6937 +function setPositiveNumber( elem, value, subtract ) {
  6938 + var matches = rnumsplit.exec( value );
  6939 + return matches ?
  6940 +
  6941 + // Guard against undefined "subtract", e.g., when used as in cssHooks
  6942 + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
  6943 + value;
  6944 +}
  6945 +
  6946 +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  6947 + var i = extra === ( isBorderBox ? "border" : "content" ) ?
  6948 +
  6949 + // If we already have the right measurement, avoid augmentation
  6950 + 4 :
  6951 +
  6952 + // Otherwise initialize for horizontal or vertical properties
  6953 + name === "width" ? 1 : 0,
  6954 +
  6955 + val = 0;
  6956 +
  6957 + for ( ; i < 4; i += 2 ) {
  6958 +
  6959 + // both box models exclude margin, so add it if we want it
  6960 + if ( extra === "margin" ) {
  6961 + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  6962 + }
  6963 +
  6964 + if ( isBorderBox ) {
  6965 +
  6966 + // border-box includes padding, so remove it if we want content
  6967 + if ( extra === "content" ) {
  6968 + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  6969 + }
  6970 +
  6971 + // at this point, extra isn't border nor margin, so remove border
  6972 + if ( extra !== "margin" ) {
  6973 + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  6974 + }
  6975 + } else {
  6976 +
  6977 + // at this point, extra isn't content, so add padding
  6978 + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  6979 +
  6980 + // at this point, extra isn't content nor padding, so add border
  6981 + if ( extra !== "padding" ) {
  6982 + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  6983 + }
  6984 + }
  6985 + }
  6986 +
  6987 + return val;
  6988 +}
  6989 +
  6990 +function getWidthOrHeight( elem, name, extra ) {
  6991 +
  6992 + // Start with offset property, which is equivalent to the border-box value
  6993 + var valueIsBorderBox = true,
  6994 + val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  6995 + styles = getStyles( elem ),
  6996 + isBorderBox = support.boxSizing &&
  6997 + jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  6998 +
  6999 + // Support: IE11 only
  7000 + // In IE 11 fullscreen elements inside of an iframe have
  7001 + // 100x too small dimensions (gh-1764).
  7002 + if ( document.msFullscreenElement && window.top !== window ) {
  7003 +
  7004 + // Support: IE11 only
  7005 + // Running getBoundingClientRect on a disconnected node
  7006 + // in IE throws an error.
  7007 + if ( elem.getClientRects().length ) {
  7008 + val = Math.round( elem.getBoundingClientRect()[ name ] * 100 );
  7009 + }
  7010 + }
  7011 +
  7012 + // some non-html elements return undefined for offsetWidth, so check for null/undefined
  7013 + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  7014 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  7015 + if ( val <= 0 || val == null ) {
  7016 +
  7017 + // Fall back to computed then uncomputed css if necessary
  7018 + val = curCSS( elem, name, styles );
  7019 + if ( val < 0 || val == null ) {
  7020 + val = elem.style[ name ];
  7021 + }
  7022 +
  7023 + // Computed unit is not pixels. Stop here and return.
  7024 + if ( rnumnonpx.test( val ) ) {
  7025 + return val;
  7026 + }
  7027 +
  7028 + // we need the check for style in case a browser which returns unreliable values
  7029 + // for getComputedStyle silently falls back to the reliable elem.style
  7030 + valueIsBorderBox = isBorderBox &&
  7031 + ( support.boxSizingReliable() || val === elem.style[ name ] );
  7032 +
  7033 + // Normalize "", auto, and prepare for extra
  7034 + val = parseFloat( val ) || 0;
  7035 + }
  7036 +
  7037 + // use the active box-sizing model to add/subtract irrelevant styles
  7038 + return ( val +
  7039 + augmentWidthOrHeight(
  7040 + elem,
  7041 + name,
  7042 + extra || ( isBorderBox ? "border" : "content" ),
  7043 + valueIsBorderBox,
  7044 + styles
  7045 + )
  7046 + ) + "px";
  7047 +}
  7048 +
  7049 +jQuery.extend( {
  7050 +
  7051 + // Add in style property hooks for overriding the default
  7052 + // behavior of getting and setting a style property
  7053 + cssHooks: {
  7054 + opacity: {
  7055 + get: function( elem, computed ) {
  7056 + if ( computed ) {
  7057 +
  7058 + // We should always get a number back from opacity
  7059 + var ret = curCSS( elem, "opacity" );
  7060 + return ret === "" ? "1" : ret;
  7061 + }
  7062 + }
  7063 + }
  7064 + },
  7065 +
  7066 + // Don't automatically add "px" to these possibly-unitless properties
  7067 + cssNumber: {
  7068 + "animationIterationCount": true,
  7069 + "columnCount": true,
  7070 + "fillOpacity": true,
  7071 + "flexGrow": true,
  7072 + "flexShrink": true,
  7073 + "fontWeight": true,
  7074 + "lineHeight": true,
  7075 + "opacity": true,
  7076 + "order": true,
  7077 + "orphans": true,
  7078 + "widows": true,
  7079 + "zIndex": true,
  7080 + "zoom": true
  7081 + },
  7082 +
  7083 + // Add in properties whose names you wish to fix before
  7084 + // setting or getting the value
  7085 + cssProps: {
  7086 +
  7087 + // normalize float css property
  7088 + "float": support.cssFloat ? "cssFloat" : "styleFloat"
  7089 + },
  7090 +
  7091 + // Get and set the style property on a DOM Node
  7092 + style: function( elem, name, value, extra ) {
  7093 +
  7094 + // Don't set styles on text and comment nodes
  7095 + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  7096 + return;
  7097 + }
  7098 +
  7099 + // Make sure that we're working with the right name
  7100 + var ret, type, hooks,
  7101 + origName = jQuery.camelCase( name ),
  7102 + style = elem.style;
  7103 +
  7104 + name = jQuery.cssProps[ origName ] ||
  7105 + ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  7106 +
  7107 + // gets hook for the prefixed version
  7108 + // followed by the unprefixed version
  7109 + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  7110 +
  7111 + // Check if we're setting a value
  7112 + if ( value !== undefined ) {
  7113 + type = typeof value;
  7114 +
  7115 + // Convert "+=" or "-=" to relative numbers (#7345)
  7116 + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
  7117 + value = adjustCSS( elem, name, ret );
  7118 +
  7119 + // Fixes bug #9237
  7120 + type = "number";
  7121 + }
  7122 +
  7123 + // Make sure that null and NaN values aren't set. See: #7116
  7124 + if ( value == null || value !== value ) {
  7125 + return;
  7126 + }
  7127 +
  7128 + // If a number was passed in, add the unit (except for certain CSS properties)
  7129 + if ( type === "number" ) {
  7130 + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
  7131 + }
  7132 +
  7133 + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
  7134 + // but it would mean to define eight
  7135 + // (for every problematic property) identical functions
  7136 + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  7137 + style[ name ] = "inherit";
  7138 + }
  7139 +
  7140 + // If a hook was provided, use that value, otherwise just set the specified value
  7141 + if ( !hooks || !( "set" in hooks ) ||
  7142 + ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
  7143 +
  7144 + // Support: IE
  7145 + // Swallow errors from 'invalid' CSS values (#5509)
  7146 + try {
  7147 + style[ name ] = value;
  7148 + } catch ( e ) {}
  7149 + }
  7150 +
  7151 + } else {
  7152 +
  7153 + // If a hook was provided get the non-computed value from there
  7154 + if ( hooks && "get" in hooks &&
  7155 + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
  7156 +
  7157 + return ret;
  7158 + }
  7159 +
  7160 + // Otherwise just get the value from the style object
  7161 + return style[ name ];
  7162 + }
  7163 + },
  7164 +
  7165 + css: function( elem, name, extra, styles ) {
  7166 + var num, val, hooks,
  7167 + origName = jQuery.camelCase( name );
  7168 +
  7169 + // Make sure that we're working with the right name
  7170 + name = jQuery.cssProps[ origName ] ||
  7171 + ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  7172 +
  7173 + // gets hook for the prefixed version
  7174 + // followed by the unprefixed version
  7175 + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  7176 +
  7177 + // If a hook was provided get the computed value from there
  7178 + if ( hooks && "get" in hooks ) {
  7179 + val = hooks.get( elem, true, extra );
  7180 + }
  7181 +
  7182 + // Otherwise, if a way to get the computed value exists, use that
  7183 + if ( val === undefined ) {
  7184 + val = curCSS( elem, name, styles );
  7185 + }
  7186 +
  7187 + //convert "normal" to computed value
  7188 + if ( val === "normal" && name in cssNormalTransform ) {
  7189 + val = cssNormalTransform[ name ];
  7190 + }
  7191 +
  7192 + // Return, converting to number if forced or a qualifier was provided and val looks numeric
  7193 + if ( extra === "" || extra ) {
  7194 + num = parseFloat( val );
  7195 + return extra === true || isFinite( num ) ? num || 0 : val;
  7196 + }
  7197 + return val;
  7198 + }
  7199 +} );
  7200 +
  7201 +jQuery.each( [ "height", "width" ], function( i, name ) {
  7202 + jQuery.cssHooks[ name ] = {
  7203 + get: function( elem, computed, extra ) {
  7204 + if ( computed ) {
  7205 +
  7206 + // certain elements can have dimension info if we invisibly show them
  7207 + // however, it must have a current display style that would benefit from this
  7208 + return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
  7209 + elem.offsetWidth === 0 ?
  7210 + swap( elem, cssShow, function() {
  7211 + return getWidthOrHeight( elem, name, extra );
  7212 + } ) :
  7213 + getWidthOrHeight( elem, name, extra );
  7214 + }
  7215 + },
  7216 +
  7217 + set: function( elem, value, extra ) {
  7218 + var styles = extra && getStyles( elem );
  7219 + return setPositiveNumber( elem, value, extra ?
  7220 + augmentWidthOrHeight(
  7221 + elem,
  7222 + name,
  7223 + extra,
  7224 + support.boxSizing &&
  7225 + jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  7226 + styles
  7227 + ) : 0
  7228 + );
  7229 + }
  7230 + };
  7231 +} );
  7232 +
  7233 +if ( !support.opacity ) {
  7234 + jQuery.cssHooks.opacity = {
  7235 + get: function( elem, computed ) {
  7236 +
  7237 + // IE uses filters for opacity
  7238 + return ropacity.test( ( computed && elem.currentStyle ?
  7239 + elem.currentStyle.filter :
  7240 + elem.style.filter ) || "" ) ?
  7241 + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
  7242 + computed ? "1" : "";
  7243 + },
  7244 +
  7245 + set: function( elem, value ) {
  7246 + var style = elem.style,
  7247 + currentStyle = elem.currentStyle,
  7248 + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
  7249 + filter = currentStyle && currentStyle.filter || style.filter || "";
  7250 +
  7251 + // IE has trouble with opacity if it does not have layout
  7252 + // Force it by setting the zoom level
  7253 + style.zoom = 1;
  7254 +
  7255 + // if setting opacity to 1, and no other filters exist -
  7256 + // attempt to remove filter attribute #6652
  7257 + // if value === "", then remove inline opacity #12685
  7258 + if ( ( value >= 1 || value === "" ) &&
  7259 + jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
  7260 + style.removeAttribute ) {
  7261 +
  7262 + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
  7263 + // if "filter:" is present at all, clearType is disabled, we want to avoid this
  7264 + // style.removeAttribute is IE Only, but so apparently is this code path...
  7265 + style.removeAttribute( "filter" );
  7266 +
  7267 + // if there is no filter style applied in a css rule
  7268 + // or unset inline opacity, we are done
  7269 + if ( value === "" || currentStyle && !currentStyle.filter ) {
  7270 + return;
  7271 + }
  7272 + }
  7273 +
  7274 + // otherwise, set new filter values
  7275 + style.filter = ralpha.test( filter ) ?
  7276 + filter.replace( ralpha, opacity ) :
  7277 + filter + " " + opacity;
  7278 + }
  7279 + };
  7280 +}
  7281 +
  7282 +jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
  7283 + function( elem, computed ) {
  7284 + if ( computed ) {
  7285 + return swap( elem, { "display": "inline-block" },
  7286 + curCSS, [ elem, "marginRight" ] );
  7287 + }
  7288 + }
  7289 +);
  7290 +
  7291 +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
  7292 + function( elem, computed ) {
  7293 + if ( computed ) {
  7294 + return (
  7295 + parseFloat( curCSS( elem, "marginLeft" ) ) ||
  7296 +
  7297 + // Support: IE<=11+
  7298 + // Running getBoundingClientRect on a disconnected node in IE throws an error
  7299 + // Support: IE8 only
  7300 + // getClientRects() errors on disconnected elems
  7301 + ( jQuery.contains( elem.ownerDocument, elem ) ?
  7302 + elem.getBoundingClientRect().left -
  7303 + swap( elem, { marginLeft: 0 }, function() {
  7304 + return elem.getBoundingClientRect().left;
  7305 + } ) :
  7306 + 0
  7307 + )
  7308 + ) + "px";
  7309 + }
  7310 + }
  7311 +);
  7312 +
  7313 +// These hooks are used by animate to expand properties
  7314 +jQuery.each( {
  7315 + margin: "",
  7316 + padding: "",
  7317 + border: "Width"
  7318 +}, function( prefix, suffix ) {
  7319 + jQuery.cssHooks[ prefix + suffix ] = {
  7320 + expand: function( value ) {
  7321 + var i = 0,
  7322 + expanded = {},
  7323 +
  7324 + // assumes a single number if not a string
  7325 + parts = typeof value === "string" ? value.split( " " ) : [ value ];
  7326 +
  7327 + for ( ; i < 4; i++ ) {
  7328 + expanded[ prefix + cssExpand[ i ] + suffix ] =
  7329 + parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  7330 + }
  7331 +
  7332 + return expanded;
  7333 + }
  7334 + };
  7335 +
  7336 + if ( !rmargin.test( prefix ) ) {
  7337 + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  7338 + }
  7339 +} );
  7340 +
  7341 +jQuery.fn.extend( {
  7342 + css: function( name, value ) {
  7343 + return access( this, function( elem, name, value ) {
  7344 + var styles, len,
  7345 + map = {},
  7346 + i = 0;
  7347 +
  7348 + if ( jQuery.isArray( name ) ) {
  7349 + styles = getStyles( elem );
  7350 + len = name.length;
  7351 +
  7352 + for ( ; i < len; i++ ) {
  7353 + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  7354 + }
  7355 +
  7356 + return map;
  7357 + }
  7358 +
  7359 + return value !== undefined ?
  7360 + jQuery.style( elem, name, value ) :
  7361 + jQuery.css( elem, name );
  7362 + }, name, value, arguments.length > 1 );
  7363 + },
  7364 + show: function() {
  7365 + return showHide( this, true );
  7366 + },
  7367 + hide: function() {
  7368 + return showHide( this );
  7369 + },
  7370 + toggle: function( state ) {
  7371 + if ( typeof state === "boolean" ) {
  7372 + return state ? this.show() : this.hide();
  7373 + }
  7374 +
  7375 + return this.each( function() {
  7376 + if ( isHidden( this ) ) {
  7377 + jQuery( this ).show();
  7378 + } else {
  7379 + jQuery( this ).hide();
  7380 + }
  7381 + } );
  7382 + }
  7383 +} );
  7384 +
  7385 +
  7386 +function Tween( elem, options, prop, end, easing ) {
  7387 + return new Tween.prototype.init( elem, options, prop, end, easing );
  7388 +}
  7389 +jQuery.Tween = Tween;
  7390 +
  7391 +Tween.prototype = {
  7392 + constructor: Tween,
  7393 + init: function( elem, options, prop, end, easing, unit ) {
  7394 + this.elem = elem;
  7395 + this.prop = prop;
  7396 + this.easing = easing || jQuery.easing._default;
  7397 + this.options = options;
  7398 + this.start = this.now = this.cur();
  7399 + this.end = end;
  7400 + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  7401 + },
  7402 + cur: function() {
  7403 + var hooks = Tween.propHooks[ this.prop ];
  7404 +
  7405 + return hooks && hooks.get ?
  7406 + hooks.get( this ) :
  7407 + Tween.propHooks._default.get( this );
  7408 + },
  7409 + run: function( percent ) {
  7410 + var eased,
  7411 + hooks = Tween.propHooks[ this.prop ];
  7412 +
  7413 + if ( this.options.duration ) {
  7414 + this.pos = eased = jQuery.easing[ this.easing ](
  7415 + percent, this.options.duration * percent, 0, 1, this.options.duration
  7416 + );
  7417 + } else {
  7418 + this.pos = eased = percent;
  7419 + }
  7420 + this.now = ( this.end - this.start ) * eased + this.start;
  7421 +
  7422 + if ( this.options.step ) {
  7423 + this.options.step.call( this.elem, this.now, this );
  7424 + }
  7425 +
  7426 + if ( hooks && hooks.set ) {
  7427 + hooks.set( this );
  7428 + } else {
  7429 + Tween.propHooks._default.set( this );
  7430 + }
  7431 + return this;
  7432 + }
  7433 +};
  7434 +
  7435 +Tween.prototype.init.prototype = Tween.prototype;
  7436 +
  7437 +Tween.propHooks = {
  7438 + _default: {
  7439 + get: function( tween ) {
  7440 + var result;
  7441 +
  7442 + // Use a property on the element directly when it is not a DOM element,
  7443 + // or when there is no matching style property that exists.
  7444 + if ( tween.elem.nodeType !== 1 ||
  7445 + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
  7446 + return tween.elem[ tween.prop ];
  7447 + }
  7448 +
  7449 + // passing an empty string as a 3rd parameter to .css will automatically
  7450 + // attempt a parseFloat and fallback to a string if the parse fails
  7451 + // so, simple values such as "10px" are parsed to Float.
  7452 + // complex values such as "rotate(1rad)" are returned as is.
  7453 + result = jQuery.css( tween.elem, tween.prop, "" );
  7454 +
  7455 + // Empty strings, null, undefined and "auto" are converted to 0.
  7456 + return !result || result === "auto" ? 0 : result;
  7457 + },
  7458 + set: function( tween ) {
  7459 +
  7460 + // use step hook for back compat - use cssHook if its there - use .style if its
  7461 + // available and use plain properties where available
  7462 + if ( jQuery.fx.step[ tween.prop ] ) {
  7463 + jQuery.fx.step[ tween.prop ]( tween );
  7464 + } else if ( tween.elem.nodeType === 1 &&
  7465 + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
  7466 + jQuery.cssHooks[ tween.prop ] ) ) {
  7467 + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  7468 + } else {
  7469 + tween.elem[ tween.prop ] = tween.now;
  7470 + }
  7471 + }
  7472 + }
  7473 +};
  7474 +
  7475 +// Support: IE <=9
  7476 +// Panic based approach to setting things on disconnected nodes
  7477 +
  7478 +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  7479 + set: function( tween ) {
  7480 + if ( tween.elem.nodeType && tween.elem.parentNode ) {
  7481 + tween.elem[ tween.prop ] = tween.now;
  7482 + }
  7483 + }
  7484 +};
  7485 +
  7486 +jQuery.easing = {
  7487 + linear: function( p ) {
  7488 + return p;
  7489 + },
  7490 + swing: function( p ) {
  7491 + return 0.5 - Math.cos( p * Math.PI ) / 2;
  7492 + },
  7493 + _default: "swing"
  7494 +};
  7495 +
  7496 +jQuery.fx = Tween.prototype.init;
  7497 +
  7498 +// Back Compat <1.8 extension point
  7499 +jQuery.fx.step = {};
  7500 +
  7501 +
  7502 +
  7503 +
  7504 +var
  7505 + fxNow, timerId,
  7506 + rfxtypes = /^(?:toggle|show|hide)$/,
  7507 + rrun = /queueHooks$/;
  7508 +
  7509 +// Animations created synchronously will run synchronously
  7510 +function createFxNow() {
  7511 + window.setTimeout( function() {
  7512 + fxNow = undefined;
  7513 + } );
  7514 + return ( fxNow = jQuery.now() );
  7515 +}
  7516 +
  7517 +// Generate parameters to create a standard animation
  7518 +function genFx( type, includeWidth ) {
  7519 + var which,
  7520 + attrs = { height: type },
  7521 + i = 0;
  7522 +
  7523 + // if we include width, step value is 1 to do all cssExpand values,
  7524 + // if we don't include width, step value is 2 to skip over Left and Right
  7525 + includeWidth = includeWidth ? 1 : 0;
  7526 + for ( ; i < 4 ; i += 2 - includeWidth ) {
  7527 + which = cssExpand[ i ];
  7528 + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  7529 + }
  7530 +
  7531 + if ( includeWidth ) {
  7532 + attrs.opacity = attrs.width = type;
  7533 + }
  7534 +
  7535 + return attrs;
  7536 +}
  7537 +
  7538 +function createTween( value, prop, animation ) {
  7539 + var tween,
  7540 + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
  7541 + index = 0,
  7542 + length = collection.length;
  7543 + for ( ; index < length; index++ ) {
  7544 + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
  7545 +
  7546 + // we're done with this property
  7547 + return tween;
  7548 + }
  7549 + }
  7550 +}
  7551 +
  7552 +function defaultPrefilter( elem, props, opts ) {
  7553 + /* jshint validthis: true */
  7554 + var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
  7555 + anim = this,
  7556 + orig = {},
  7557 + style = elem.style,
  7558 + hidden = elem.nodeType && isHidden( elem ),
  7559 + dataShow = jQuery._data( elem, "fxshow" );
  7560 +
  7561 + // handle queue: false promises
  7562 + if ( !opts.queue ) {
  7563 + hooks = jQuery._queueHooks( elem, "fx" );
  7564 + if ( hooks.unqueued == null ) {
  7565 + hooks.unqueued = 0;
  7566 + oldfire = hooks.empty.fire;
  7567 + hooks.empty.fire = function() {
  7568 + if ( !hooks.unqueued ) {
  7569 + oldfire();
  7570 + }
  7571 + };
  7572 + }
  7573 + hooks.unqueued++;
  7574 +
  7575 + anim.always( function() {
  7576 +
  7577 + // doing this makes sure that the complete handler will be called
  7578 + // before this completes
  7579 + anim.always( function() {
  7580 + hooks.unqueued--;
  7581 + if ( !jQuery.queue( elem, "fx" ).length ) {
  7582 + hooks.empty.fire();
  7583 + }
  7584 + } );
  7585 + } );
  7586 + }
  7587 +
  7588 + // height/width overflow pass
  7589 + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
  7590 +
  7591 + // Make sure that nothing sneaks out
  7592 + // Record all 3 overflow attributes because IE does not
  7593 + // change the overflow attribute when overflowX and
  7594 + // overflowY are set to the same value
  7595 + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  7596 +
  7597 + // Set display property to inline-block for height/width
  7598 + // animations on inline elements that are having width/height animated
  7599 + display = jQuery.css( elem, "display" );
  7600 +
  7601 + // Test default display if display is currently "none"
  7602 + checkDisplay = display === "none" ?
  7603 + jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
  7604 +
  7605 + if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
  7606 +
  7607 + // inline-level elements accept inline-block;
  7608 + // block-level elements need to be inline with layout
  7609 + if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
  7610 + style.display = "inline-block";
  7611 + } else {
  7612 + style.zoom = 1;
  7613 + }
  7614 + }
  7615 + }
  7616 +
  7617 + if ( opts.overflow ) {
  7618 + style.overflow = "hidden";
  7619 + if ( !support.shrinkWrapBlocks() ) {
  7620 + anim.always( function() {
  7621 + style.overflow = opts.overflow[ 0 ];
  7622 + style.overflowX = opts.overflow[ 1 ];
  7623 + style.overflowY = opts.overflow[ 2 ];
  7624 + } );
  7625 + }
  7626 + }
  7627 +
  7628 + // show/hide pass
  7629 + for ( prop in props ) {
  7630 + value = props[ prop ];
  7631 + if ( rfxtypes.exec( value ) ) {
  7632 + delete props[ prop ];
  7633 + toggle = toggle || value === "toggle";
  7634 + if ( value === ( hidden ? "hide" : "show" ) ) {
  7635 +
  7636 + // If there is dataShow left over from a stopped hide or show
  7637 + // and we are going to proceed with show, we should pretend to be hidden
  7638 + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  7639 + hidden = true;
  7640 + } else {
  7641 + continue;
  7642 + }
  7643 + }
  7644 + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  7645 +
  7646 + // Any non-fx value stops us from restoring the original display value
  7647 + } else {
  7648 + display = undefined;
  7649 + }
  7650 + }
  7651 +
  7652 + if ( !jQuery.isEmptyObject( orig ) ) {
  7653 + if ( dataShow ) {
  7654 + if ( "hidden" in dataShow ) {
  7655 + hidden = dataShow.hidden;
  7656 + }
  7657 + } else {
  7658 + dataShow = jQuery._data( elem, "fxshow", {} );
  7659 + }
  7660 +
  7661 + // store state if its toggle - enables .stop().toggle() to "reverse"
  7662 + if ( toggle ) {
  7663 + dataShow.hidden = !hidden;
  7664 + }
  7665 + if ( hidden ) {
  7666 + jQuery( elem ).show();
  7667 + } else {
  7668 + anim.done( function() {
  7669 + jQuery( elem ).hide();
  7670 + } );
  7671 + }
  7672 + anim.done( function() {
  7673 + var prop;
  7674 + jQuery._removeData( elem, "fxshow" );
  7675 + for ( prop in orig ) {
  7676 + jQuery.style( elem, prop, orig[ prop ] );
  7677 + }
  7678 + } );
  7679 + for ( prop in orig ) {
  7680 + tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  7681 +
  7682 + if ( !( prop in dataShow ) ) {
  7683 + dataShow[ prop ] = tween.start;
  7684 + if ( hidden ) {
  7685 + tween.end = tween.start;
  7686 + tween.start = prop === "width" || prop === "height" ? 1 : 0;
  7687 + }
  7688 + }
  7689 + }
  7690 +
  7691 + // If this is a noop like .hide().hide(), restore an overwritten display value
  7692 + } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
  7693 + style.display = display;
  7694 + }
  7695 +}
  7696 +
  7697 +function propFilter( props, specialEasing ) {
  7698 + var index, name, easing, value, hooks;
  7699 +
  7700 + // camelCase, specialEasing and expand cssHook pass
  7701 + for ( index in props ) {
  7702 + name = jQuery.camelCase( index );
  7703 + easing = specialEasing[ name ];
  7704 + value = props[ index ];
  7705 + if ( jQuery.isArray( value ) ) {
  7706 + easing = value[ 1 ];
  7707 + value = props[ index ] = value[ 0 ];
  7708 + }
  7709 +
  7710 + if ( index !== name ) {
  7711 + props[ name ] = value;
  7712 + delete props[ index ];
  7713 + }
  7714 +
  7715 + hooks = jQuery.cssHooks[ name ];
  7716 + if ( hooks && "expand" in hooks ) {
  7717 + value = hooks.expand( value );
  7718 + delete props[ name ];
  7719 +
  7720 + // not quite $.extend, this wont overwrite keys already present.
  7721 + // also - reusing 'index' from above because we have the correct "name"
  7722 + for ( index in value ) {
  7723 + if ( !( index in props ) ) {
  7724 + props[ index ] = value[ index ];
  7725 + specialEasing[ index ] = easing;
  7726 + }
  7727 + }
  7728 + } else {
  7729 + specialEasing[ name ] = easing;
  7730 + }
  7731 + }
  7732 +}
  7733 +
  7734 +function Animation( elem, properties, options ) {
  7735 + var result,
  7736 + stopped,
  7737 + index = 0,
  7738 + length = Animation.prefilters.length,
  7739 + deferred = jQuery.Deferred().always( function() {
  7740 +
  7741 + // don't match elem in the :animated selector
  7742 + delete tick.elem;
  7743 + } ),
  7744 + tick = function() {
  7745 + if ( stopped ) {
  7746 + return false;
  7747 + }
  7748 + var currentTime = fxNow || createFxNow(),
  7749 + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  7750 +
  7751 + // Support: Android 2.3
  7752 + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
  7753 + temp = remaining / animation.duration || 0,
  7754 + percent = 1 - temp,
  7755 + index = 0,
  7756 + length = animation.tweens.length;
  7757 +
  7758 + for ( ; index < length ; index++ ) {
  7759 + animation.tweens[ index ].run( percent );
  7760 + }
  7761 +
  7762 + deferred.notifyWith( elem, [ animation, percent, remaining ] );
  7763 +
  7764 + if ( percent < 1 && length ) {
  7765 + return remaining;
  7766 + } else {
  7767 + deferred.resolveWith( elem, [ animation ] );
  7768 + return false;
  7769 + }
  7770 + },
  7771 + animation = deferred.promise( {
  7772 + elem: elem,
  7773 + props: jQuery.extend( {}, properties ),
  7774 + opts: jQuery.extend( true, {
  7775 + specialEasing: {},
  7776 + easing: jQuery.easing._default
  7777 + }, options ),
  7778 + originalProperties: properties,
  7779 + originalOptions: options,
  7780 + startTime: fxNow || createFxNow(),
  7781 + duration: options.duration,
  7782 + tweens: [],
  7783 + createTween: function( prop, end ) {
  7784 + var tween = jQuery.Tween( elem, animation.opts, prop, end,
  7785 + animation.opts.specialEasing[ prop ] || animation.opts.easing );
  7786 + animation.tweens.push( tween );
  7787 + return tween;
  7788 + },
  7789 + stop: function( gotoEnd ) {
  7790 + var index = 0,
  7791 +
  7792 + // if we are going to the end, we want to run all the tweens
  7793 + // otherwise we skip this part
  7794 + length = gotoEnd ? animation.tweens.length : 0;
  7795 + if ( stopped ) {
  7796 + return this;
  7797 + }
  7798 + stopped = true;
  7799 + for ( ; index < length ; index++ ) {
  7800 + animation.tweens[ index ].run( 1 );
  7801 + }
  7802 +
  7803 + // resolve when we played the last frame
  7804 + // otherwise, reject
  7805 + if ( gotoEnd ) {
  7806 + deferred.notifyWith( elem, [ animation, 1, 0 ] );
  7807 + deferred.resolveWith( elem, [ animation, gotoEnd ] );
  7808 + } else {
  7809 + deferred.rejectWith( elem, [ animation, gotoEnd ] );
  7810 + }
  7811 + return this;
  7812 + }
  7813 + } ),
  7814 + props = animation.props;
  7815 +
  7816 + propFilter( props, animation.opts.specialEasing );
  7817 +
  7818 + for ( ; index < length ; index++ ) {
  7819 + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
  7820 + if ( result ) {
  7821 + if ( jQuery.isFunction( result.stop ) ) {
  7822 + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
  7823 + jQuery.proxy( result.stop, result );
  7824 + }
  7825 + return result;
  7826 + }
  7827 + }
  7828 +
  7829 + jQuery.map( props, createTween, animation );
  7830 +
  7831 + if ( jQuery.isFunction( animation.opts.start ) ) {
  7832 + animation.opts.start.call( elem, animation );
  7833 + }
  7834 +
  7835 + jQuery.fx.timer(
  7836 + jQuery.extend( tick, {
  7837 + elem: elem,
  7838 + anim: animation,
  7839 + queue: animation.opts.queue
  7840 + } )
  7841 + );
  7842 +
  7843 + // attach callbacks from options
  7844 + return animation.progress( animation.opts.progress )
  7845 + .done( animation.opts.done, animation.opts.complete )
  7846 + .fail( animation.opts.fail )
  7847 + .always( animation.opts.always );
  7848 +}
  7849 +
  7850 +jQuery.Animation = jQuery.extend( Animation, {
  7851 +
  7852 + tweeners: {
  7853 + "*": [ function( prop, value ) {
  7854 + var tween = this.createTween( prop, value );
  7855 + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
  7856 + return tween;
  7857 + } ]
  7858 + },
  7859 +
  7860 + tweener: function( props, callback ) {
  7861 + if ( jQuery.isFunction( props ) ) {
  7862 + callback = props;
  7863 + props = [ "*" ];
  7864 + } else {
  7865 + props = props.match( rnotwhite );
  7866 + }
  7867 +
  7868 + var prop,
  7869 + index = 0,
  7870 + length = props.length;
  7871 +
  7872 + for ( ; index < length ; index++ ) {
  7873 + prop = props[ index ];
  7874 + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
  7875 + Animation.tweeners[ prop ].unshift( callback );
  7876 + }
  7877 + },
  7878 +
  7879 + prefilters: [ defaultPrefilter ],
  7880 +
  7881 + prefilter: function( callback, prepend ) {
  7882 + if ( prepend ) {
  7883 + Animation.prefilters.unshift( callback );
  7884 + } else {
  7885 + Animation.prefilters.push( callback );
  7886 + }
  7887 + }
  7888 +} );
  7889 +
  7890 +jQuery.speed = function( speed, easing, fn ) {
  7891 + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  7892 + complete: fn || !fn && easing ||
  7893 + jQuery.isFunction( speed ) && speed,
  7894 + duration: speed,
  7895 + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  7896 + };
  7897 +
  7898 + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
  7899 + opt.duration in jQuery.fx.speeds ?
  7900 + jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
  7901 +
  7902 + // normalize opt.queue - true/undefined/null -> "fx"
  7903 + if ( opt.queue == null || opt.queue === true ) {
  7904 + opt.queue = "fx";
  7905 + }
  7906 +
  7907 + // Queueing
  7908 + opt.old = opt.complete;
  7909 +
  7910 + opt.complete = function() {
  7911 + if ( jQuery.isFunction( opt.old ) ) {
  7912 + opt.old.call( this );
  7913 + }
  7914 +
  7915 + if ( opt.queue ) {
  7916 + jQuery.dequeue( this, opt.queue );
  7917 + }
  7918 + };
  7919 +
  7920 + return opt;
  7921 +};
  7922 +
  7923 +jQuery.fn.extend( {
  7924 + fadeTo: function( speed, to, easing, callback ) {
  7925 +
  7926 + // show any hidden elements after setting opacity to 0
  7927 + return this.filter( isHidden ).css( "opacity", 0 ).show()
  7928 +
  7929 + // animate to the value specified
  7930 + .end().animate( { opacity: to }, speed, easing, callback );
  7931 + },
  7932 + animate: function( prop, speed, easing, callback ) {
  7933 + var empty = jQuery.isEmptyObject( prop ),
  7934 + optall = jQuery.speed( speed, easing, callback ),
  7935 + doAnimation = function() {
  7936 +
  7937 + // Operate on a copy of prop so per-property easing won't be lost
  7938 + var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  7939 +
  7940 + // Empty animations, or finishing resolves immediately
  7941 + if ( empty || jQuery._data( this, "finish" ) ) {
  7942 + anim.stop( true );
  7943 + }
  7944 + };
  7945 + doAnimation.finish = doAnimation;
  7946 +
  7947 + return empty || optall.queue === false ?
  7948 + this.each( doAnimation ) :
  7949 + this.queue( optall.queue, doAnimation );
  7950 + },
  7951 + stop: function( type, clearQueue, gotoEnd ) {
  7952 + var stopQueue = function( hooks ) {
  7953 + var stop = hooks.stop;
  7954 + delete hooks.stop;
  7955 + stop( gotoEnd );
  7956 + };
  7957 +
  7958 + if ( typeof type !== "string" ) {
  7959 + gotoEnd = clearQueue;
  7960 + clearQueue = type;
  7961 + type = undefined;
  7962 + }
  7963 + if ( clearQueue && type !== false ) {
  7964 + this.queue( type || "fx", [] );
  7965 + }
  7966 +
  7967 + return this.each( function() {
  7968 + var dequeue = true,
  7969 + index = type != null && type + "queueHooks",
  7970 + timers = jQuery.timers,
  7971 + data = jQuery._data( this );
  7972 +
  7973 + if ( index ) {
  7974 + if ( data[ index ] && data[ index ].stop ) {
  7975 + stopQueue( data[ index ] );
  7976 + }
  7977 + } else {
  7978 + for ( index in data ) {
  7979 + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  7980 + stopQueue( data[ index ] );
  7981 + }
  7982 + }
  7983 + }
  7984 +
  7985 + for ( index = timers.length; index--; ) {
  7986 + if ( timers[ index ].elem === this &&
  7987 + ( type == null || timers[ index ].queue === type ) ) {
  7988 +
  7989 + timers[ index ].anim.stop( gotoEnd );
  7990 + dequeue = false;
  7991 + timers.splice( index, 1 );
  7992 + }
  7993 + }
  7994 +
  7995 + // start the next in the queue if the last step wasn't forced
  7996 + // timers currently will call their complete callbacks, which will dequeue
  7997 + // but only if they were gotoEnd
  7998 + if ( dequeue || !gotoEnd ) {
  7999 + jQuery.dequeue( this, type );
  8000 + }
  8001 + } );
  8002 + },
  8003 + finish: function( type ) {
  8004 + if ( type !== false ) {
  8005 + type = type || "fx";
  8006 + }
  8007 + return this.each( function() {
  8008 + var index,
  8009 + data = jQuery._data( this ),
  8010 + queue = data[ type + "queue" ],
  8011 + hooks = data[ type + "queueHooks" ],
  8012 + timers = jQuery.timers,
  8013 + length = queue ? queue.length : 0;
  8014 +
  8015 + // enable finishing flag on private data
  8016 + data.finish = true;
  8017 +
  8018 + // empty the queue first
  8019 + jQuery.queue( this, type, [] );
  8020 +
  8021 + if ( hooks && hooks.stop ) {
  8022 + hooks.stop.call( this, true );
  8023 + }
  8024 +
  8025 + // look for any active animations, and finish them
  8026 + for ( index = timers.length; index--; ) {
  8027 + if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  8028 + timers[ index ].anim.stop( true );
  8029 + timers.splice( index, 1 );
  8030 + }
  8031 + }
  8032 +
  8033 + // look for any animations in the old queue and finish them
  8034 + for ( index = 0; index < length; index++ ) {
  8035 + if ( queue[ index ] && queue[ index ].finish ) {
  8036 + queue[ index ].finish.call( this );
  8037 + }
  8038 + }
  8039 +
  8040 + // turn off finishing flag
  8041 + delete data.finish;
  8042 + } );
  8043 + }
  8044 +} );
  8045 +
  8046 +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
  8047 + var cssFn = jQuery.fn[ name ];
  8048 + jQuery.fn[ name ] = function( speed, easing, callback ) {
  8049 + return speed == null || typeof speed === "boolean" ?
  8050 + cssFn.apply( this, arguments ) :
  8051 + this.animate( genFx( name, true ), speed, easing, callback );
  8052 + };
  8053 +} );
  8054 +
  8055 +// Generate shortcuts for custom animations
  8056 +jQuery.each( {
  8057 + slideDown: genFx( "show" ),
  8058 + slideUp: genFx( "hide" ),
  8059 + slideToggle: genFx( "toggle" ),
  8060 + fadeIn: { opacity: "show" },
  8061 + fadeOut: { opacity: "hide" },
  8062 + fadeToggle: { opacity: "toggle" }
  8063 +}, function( name, props ) {
  8064 + jQuery.fn[ name ] = function( speed, easing, callback ) {
  8065 + return this.animate( props, speed, easing, callback );
  8066 + };
  8067 +} );
  8068 +
  8069 +jQuery.timers = [];
  8070 +jQuery.fx.tick = function() {
  8071 + var timer,
  8072 + timers = jQuery.timers,
  8073 + i = 0;
  8074 +
  8075 + fxNow = jQuery.now();
  8076 +
  8077 + for ( ; i < timers.length; i++ ) {
  8078 + timer = timers[ i ];
  8079 +
  8080 + // Checks the timer has not already been removed
  8081 + if ( !timer() && timers[ i ] === timer ) {
  8082 + timers.splice( i--, 1 );
  8083 + }
  8084 + }
  8085 +
  8086 + if ( !timers.length ) {
  8087 + jQuery.fx.stop();
  8088 + }
  8089 + fxNow = undefined;
  8090 +};
  8091 +
  8092 +jQuery.fx.timer = function( timer ) {
  8093 + jQuery.timers.push( timer );
  8094 + if ( timer() ) {
  8095 + jQuery.fx.start();
  8096 + } else {
  8097 + jQuery.timers.pop();
  8098 + }
  8099 +};
  8100 +
  8101 +jQuery.fx.interval = 13;
  8102 +
  8103 +jQuery.fx.start = function() {
  8104 + if ( !timerId ) {
  8105 + timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
  8106 + }
  8107 +};
  8108 +
  8109 +jQuery.fx.stop = function() {
  8110 + window.clearInterval( timerId );
  8111 + timerId = null;
  8112 +};
  8113 +
  8114 +jQuery.fx.speeds = {
  8115 + slow: 600,
  8116 + fast: 200,
  8117 +
  8118 + // Default speed
  8119 + _default: 400
  8120 +};
  8121 +
  8122 +
  8123 +// Based off of the plugin by Clint Helfers, with permission.
  8124 +// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
  8125 +jQuery.fn.delay = function( time, type ) {
  8126 + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  8127 + type = type || "fx";
  8128 +
  8129 + return this.queue( type, function( next, hooks ) {
  8130 + var timeout = window.setTimeout( next, time );
  8131 + hooks.stop = function() {
  8132 + window.clearTimeout( timeout );
  8133 + };
  8134 + } );
  8135 +};
  8136 +
  8137 +
  8138 +( function() {
  8139 + var a,
  8140 + input = document.createElement( "input" ),
  8141 + div = document.createElement( "div" ),
  8142 + select = document.createElement( "select" ),
  8143 + opt = select.appendChild( document.createElement( "option" ) );
  8144 +
  8145 + // Setup
  8146 + div = document.createElement( "div" );
  8147 + div.setAttribute( "className", "t" );
  8148 + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
  8149 + a = div.getElementsByTagName( "a" )[ 0 ];
  8150 +
  8151 + // Support: Windows Web Apps (WWA)
  8152 + // `type` must use .setAttribute for WWA (#14901)
  8153 + input.setAttribute( "type", "checkbox" );
  8154 + div.appendChild( input );
  8155 +
  8156 + a = div.getElementsByTagName( "a" )[ 0 ];
  8157 +
  8158 + // First batch of tests.
  8159 + a.style.cssText = "top:1px";
  8160 +
  8161 + // Test setAttribute on camelCase class.
  8162 + // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
  8163 + support.getSetAttribute = div.className !== "t";
  8164 +
  8165 + // Get the style information from getAttribute
  8166 + // (IE uses .cssText instead)
  8167 + support.style = /top/.test( a.getAttribute( "style" ) );
  8168 +
  8169 + // Make sure that URLs aren't manipulated
  8170 + // (IE normalizes it by default)
  8171 + support.hrefNormalized = a.getAttribute( "href" ) === "/a";
  8172 +
  8173 + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
  8174 + support.checkOn = !!input.value;
  8175 +
  8176 + // Make sure that a selected-by-default option has a working selected property.
  8177 + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
  8178 + support.optSelected = opt.selected;
  8179 +
  8180 + // Tests for enctype support on a form (#6743)
  8181 + support.enctype = !!document.createElement( "form" ).enctype;
  8182 +
  8183 + // Make sure that the options inside disabled selects aren't marked as disabled
  8184 + // (WebKit marks them as disabled)
  8185 + select.disabled = true;
  8186 + support.optDisabled = !opt.disabled;
  8187 +
  8188 + // Support: IE8 only
  8189 + // Check if we can trust getAttribute("value")
  8190 + input = document.createElement( "input" );
  8191 + input.setAttribute( "value", "" );
  8192 + support.input = input.getAttribute( "value" ) === "";
  8193 +
  8194 + // Check if an input maintains its value after becoming a radio
  8195 + input.value = "t";
  8196 + input.setAttribute( "type", "radio" );
  8197 + support.radioValue = input.value === "t";
  8198 +} )();
  8199 +
  8200 +
  8201 +var rreturn = /\r/g;
  8202 +
  8203 +jQuery.fn.extend( {
  8204 + val: function( value ) {
  8205 + var hooks, ret, isFunction,
  8206 + elem = this[ 0 ];
  8207 +
  8208 + if ( !arguments.length ) {
  8209 + if ( elem ) {
  8210 + hooks = jQuery.valHooks[ elem.type ] ||
  8211 + jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  8212 +
  8213 + if (
  8214 + hooks &&
  8215 + "get" in hooks &&
  8216 + ( ret = hooks.get( elem, "value" ) ) !== undefined
  8217 + ) {
  8218 + return ret;
  8219 + }
  8220 +
  8221 + ret = elem.value;
  8222 +
  8223 + return typeof ret === "string" ?
  8224 +
  8225 + // handle most common string cases
  8226 + ret.replace( rreturn, "" ) :
  8227 +
  8228 + // handle cases where value is null/undef or number
  8229 + ret == null ? "" : ret;
  8230 + }
  8231 +
  8232 + return;
  8233 + }
  8234 +
  8235 + isFunction = jQuery.isFunction( value );
  8236 +
  8237 + return this.each( function( i ) {
  8238 + var val;
  8239 +
  8240 + if ( this.nodeType !== 1 ) {
  8241 + return;
  8242 + }
  8243 +
  8244 + if ( isFunction ) {
  8245 + val = value.call( this, i, jQuery( this ).val() );
  8246 + } else {
  8247 + val = value;
  8248 + }
  8249 +
  8250 + // Treat null/undefined as ""; convert numbers to string
  8251 + if ( val == null ) {
  8252 + val = "";
  8253 + } else if ( typeof val === "number" ) {
  8254 + val += "";
  8255 + } else if ( jQuery.isArray( val ) ) {
  8256 + val = jQuery.map( val, function( value ) {
  8257 + return value == null ? "" : value + "";
  8258 + } );
  8259 + }
  8260 +
  8261 + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  8262 +
  8263 + // If set returns undefined, fall back to normal setting
  8264 + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
  8265 + this.value = val;
  8266 + }
  8267 + } );
  8268 + }
  8269 +} );
  8270 +
  8271 +jQuery.extend( {
  8272 + valHooks: {
  8273 + option: {
  8274 + get: function( elem ) {
  8275 + var val = jQuery.find.attr( elem, "value" );
  8276 + return val != null ?
  8277 + val :
  8278 +
  8279 + // Support: IE10-11+
  8280 + // option.text throws exceptions (#14686, #14858)
  8281 + jQuery.trim( jQuery.text( elem ) );
  8282 + }
  8283 + },
  8284 + select: {
  8285 + get: function( elem ) {
  8286 + var value, option,
  8287 + options = elem.options,
  8288 + index = elem.selectedIndex,
  8289 + one = elem.type === "select-one" || index < 0,
  8290 + values = one ? null : [],
  8291 + max = one ? index + 1 : options.length,
  8292 + i = index < 0 ?
  8293 + max :
  8294 + one ? index : 0;
  8295 +
  8296 + // Loop through all the selected options
  8297 + for ( ; i < max; i++ ) {
  8298 + option = options[ i ];
  8299 +
  8300 + // oldIE doesn't update selected after form reset (#2551)
  8301 + if ( ( option.selected || i === index ) &&
  8302 +
  8303 + // Don't return options that are disabled or in a disabled optgroup
  8304 + ( support.optDisabled ?
  8305 + !option.disabled :
  8306 + option.getAttribute( "disabled" ) === null ) &&
  8307 + ( !option.parentNode.disabled ||
  8308 + !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
  8309 +
  8310 + // Get the specific value for the option
  8311 + value = jQuery( option ).val();
  8312 +
  8313 + // We don't need an array for one selects
  8314 + if ( one ) {
  8315 + return value;
  8316 + }
  8317 +
  8318 + // Multi-Selects return an array
  8319 + values.push( value );
  8320 + }
  8321 + }
  8322 +
  8323 + return values;
  8324 + },
  8325 +
  8326 + set: function( elem, value ) {
  8327 + var optionSet, option,
  8328 + options = elem.options,
  8329 + values = jQuery.makeArray( value ),
  8330 + i = options.length;
  8331 +
  8332 + while ( i-- ) {
  8333 + option = options[ i ];
  8334 +
  8335 + if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
  8336 +
  8337 + // Support: IE6
  8338 + // When new option element is added to select box we need to
  8339 + // force reflow of newly added node in order to workaround delay
  8340 + // of initialization properties
  8341 + try {
  8342 + option.selected = optionSet = true;
  8343 +
  8344 + } catch ( _ ) {
  8345 +
  8346 + // Will be executed only in IE6
  8347 + option.scrollHeight;
  8348 + }
  8349 +
  8350 + } else {
  8351 + option.selected = false;
  8352 + }
  8353 + }
  8354 +
  8355 + // Force browsers to behave consistently when non-matching value is set
  8356 + if ( !optionSet ) {
  8357 + elem.selectedIndex = -1;
  8358 + }
  8359 +
  8360 + return options;
  8361 + }
  8362 + }
  8363 + }
  8364 +} );
  8365 +
  8366 +// Radios and checkboxes getter/setter
  8367 +jQuery.each( [ "radio", "checkbox" ], function() {
  8368 + jQuery.valHooks[ this ] = {
  8369 + set: function( elem, value ) {
  8370 + if ( jQuery.isArray( value ) ) {
  8371 + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
  8372 + }
  8373 + }
  8374 + };
  8375 + if ( !support.checkOn ) {
  8376 + jQuery.valHooks[ this ].get = function( elem ) {
  8377 + return elem.getAttribute( "value" ) === null ? "on" : elem.value;
  8378 + };
  8379 + }
  8380 +} );
  8381 +
  8382 +
  8383 +
  8384 +
  8385 +var nodeHook, boolHook,
  8386 + attrHandle = jQuery.expr.attrHandle,
  8387 + ruseDefault = /^(?:checked|selected)$/i,
  8388 + getSetAttribute = support.getSetAttribute,
  8389 + getSetInput = support.input;
  8390 +
  8391 +jQuery.fn.extend( {
  8392 + attr: function( name, value ) {
  8393 + return access( this, jQuery.attr, name, value, arguments.length > 1 );
  8394 + },
  8395 +
  8396 + removeAttr: function( name ) {
  8397 + return this.each( function() {
  8398 + jQuery.removeAttr( this, name );
  8399 + } );
  8400 + }
  8401 +} );
  8402 +
  8403 +jQuery.extend( {
  8404 + attr: function( elem, name, value ) {
  8405 + var ret, hooks,
  8406 + nType = elem.nodeType;
  8407 +
  8408 + // Don't get/set attributes on text, comment and attribute nodes
  8409 + if ( nType === 3 || nType === 8 || nType === 2 ) {
  8410 + return;
  8411 + }
  8412 +
  8413 + // Fallback to prop when attributes are not supported
  8414 + if ( typeof elem.getAttribute === "undefined" ) {
  8415 + return jQuery.prop( elem, name, value );
  8416 + }
  8417 +
  8418 + // All attributes are lowercase
  8419 + // Grab necessary hook if one is defined
  8420 + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  8421 + name = name.toLowerCase();
  8422 + hooks = jQuery.attrHooks[ name ] ||
  8423 + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
  8424 + }
  8425 +
  8426 + if ( value !== undefined ) {
  8427 + if ( value === null ) {
  8428 + jQuery.removeAttr( elem, name );
  8429 + return;
  8430 + }
  8431 +
  8432 + if ( hooks && "set" in hooks &&
  8433 + ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  8434 + return ret;
  8435 + }
  8436 +
  8437 + elem.setAttribute( name, value + "" );
  8438 + return value;
  8439 + }
  8440 +
  8441 + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  8442 + return ret;
  8443 + }
  8444 +
  8445 + ret = jQuery.find.attr( elem, name );
  8446 +
  8447 + // Non-existent attributes return null, we normalize to undefined
  8448 + return ret == null ? undefined : ret;
  8449 + },
  8450 +
  8451 + attrHooks: {
  8452 + type: {
  8453 + set: function( elem, value ) {
  8454 + if ( !support.radioValue && value === "radio" &&
  8455 + jQuery.nodeName( elem, "input" ) ) {
  8456 +
  8457 + // Setting the type on a radio button after the value resets the value in IE8-9
  8458 + // Reset value to default in case type is set after value during creation
  8459 + var val = elem.value;
  8460 + elem.setAttribute( "type", value );
  8461 + if ( val ) {
  8462 + elem.value = val;
  8463 + }
  8464 + return value;
  8465 + }
  8466 + }
  8467 + }
  8468 + },
  8469 +
  8470 + removeAttr: function( elem, value ) {
  8471 + var name, propName,
  8472 + i = 0,
  8473 + attrNames = value && value.match( rnotwhite );
  8474 +
  8475 + if ( attrNames && elem.nodeType === 1 ) {
  8476 + while ( ( name = attrNames[ i++ ] ) ) {
  8477 + propName = jQuery.propFix[ name ] || name;
  8478 +
  8479 + // Boolean attributes get special treatment (#10870)
  8480 + if ( jQuery.expr.match.bool.test( name ) ) {
  8481 +
  8482 + // Set corresponding property to false
  8483 + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
  8484 + elem[ propName ] = false;
  8485 +
  8486 + // Support: IE<9
  8487 + // Also clear defaultChecked/defaultSelected (if appropriate)
  8488 + } else {
  8489 + elem[ jQuery.camelCase( "default-" + name ) ] =
  8490 + elem[ propName ] = false;
  8491 + }
  8492 +
  8493 + // See #9699 for explanation of this approach (setting first, then removal)
  8494 + } else {
  8495 + jQuery.attr( elem, name, "" );
  8496 + }
  8497 +
  8498 + elem.removeAttribute( getSetAttribute ? name : propName );
  8499 + }
  8500 + }
  8501 + }
  8502 +} );
  8503 +
  8504 +// Hooks for boolean attributes
  8505 +boolHook = {
  8506 + set: function( elem, value, name ) {
  8507 + if ( value === false ) {
  8508 +
  8509 + // Remove boolean attributes when set to false
  8510 + jQuery.removeAttr( elem, name );
  8511 + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
  8512 +
  8513 + // IE<8 needs the *property* name
  8514 + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
  8515 +
  8516 + } else {
  8517 +
  8518 + // Support: IE<9
  8519 + // Use defaultChecked and defaultSelected for oldIE
  8520 + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
  8521 + }
  8522 + return name;
  8523 + }
  8524 +};
  8525 +
  8526 +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  8527 + var getter = attrHandle[ name ] || jQuery.find.attr;
  8528 +
  8529 + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
  8530 + attrHandle[ name ] = function( elem, name, isXML ) {
  8531 + var ret, handle;
  8532 + if ( !isXML ) {
  8533 +
  8534 + // Avoid an infinite loop by temporarily removing this function from the getter
  8535 + handle = attrHandle[ name ];
  8536 + attrHandle[ name ] = ret;
  8537 + ret = getter( elem, name, isXML ) != null ?
  8538 + name.toLowerCase() :
  8539 + null;
  8540 + attrHandle[ name ] = handle;
  8541 + }
  8542 + return ret;
  8543 + };
  8544 + } else {
  8545 + attrHandle[ name ] = function( elem, name, isXML ) {
  8546 + if ( !isXML ) {
  8547 + return elem[ jQuery.camelCase( "default-" + name ) ] ?
  8548 + name.toLowerCase() :
  8549 + null;
  8550 + }
  8551 + };
  8552 + }
  8553 +} );
  8554 +
  8555 +// fix oldIE attroperties
  8556 +if ( !getSetInput || !getSetAttribute ) {
  8557 + jQuery.attrHooks.value = {
  8558 + set: function( elem, value, name ) {
  8559 + if ( jQuery.nodeName( elem, "input" ) ) {
  8560 +
  8561 + // Does not return so that setAttribute is also used
  8562 + elem.defaultValue = value;
  8563 + } else {
  8564 +
  8565 + // Use nodeHook if defined (#1954); otherwise setAttribute is fine
  8566 + return nodeHook && nodeHook.set( elem, value, name );
  8567 + }
  8568 + }
  8569 + };
  8570 +}
  8571 +
  8572 +// IE6/7 do not support getting/setting some attributes with get/setAttribute
  8573 +if ( !getSetAttribute ) {
  8574 +
  8575 + // Use this for any attribute in IE6/7
  8576 + // This fixes almost every IE6/7 issue
  8577 + nodeHook = {
  8578 + set: function( elem, value, name ) {
  8579 +
  8580 + // Set the existing or create a new attribute node
  8581 + var ret = elem.getAttributeNode( name );
  8582 + if ( !ret ) {
  8583 + elem.setAttributeNode(
  8584 + ( ret = elem.ownerDocument.createAttribute( name ) )
  8585 + );
  8586 + }
  8587 +
  8588 + ret.value = value += "";
  8589 +
  8590 + // Break association with cloned elements by also using setAttribute (#9646)
  8591 + if ( name === "value" || value === elem.getAttribute( name ) ) {
  8592 + return value;
  8593 + }
  8594 + }
  8595 + };
  8596 +
  8597 + // Some attributes are constructed with empty-string values when not defined
  8598 + attrHandle.id = attrHandle.name = attrHandle.coords =
  8599 + function( elem, name, isXML ) {
  8600 + var ret;
  8601 + if ( !isXML ) {
  8602 + return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
  8603 + ret.value :
  8604 + null;
  8605 + }
  8606 + };
  8607 +
  8608 + // Fixing value retrieval on a button requires this module
  8609 + jQuery.valHooks.button = {
  8610 + get: function( elem, name ) {
  8611 + var ret = elem.getAttributeNode( name );
  8612 + if ( ret && ret.specified ) {
  8613 + return ret.value;
  8614 + }
  8615 + },
  8616 + set: nodeHook.set
  8617 + };
  8618 +
  8619 + // Set contenteditable to false on removals(#10429)
  8620 + // Setting to empty string throws an error as an invalid value
  8621 + jQuery.attrHooks.contenteditable = {
  8622 + set: function( elem, value, name ) {
  8623 + nodeHook.set( elem, value === "" ? false : value, name );
  8624 + }
  8625 + };
  8626 +
  8627 + // Set width and height to auto instead of 0 on empty string( Bug #8150 )
  8628 + // This is for removals
  8629 + jQuery.each( [ "width", "height" ], function( i, name ) {
  8630 + jQuery.attrHooks[ name ] = {
  8631 + set: function( elem, value ) {
  8632 + if ( value === "" ) {
  8633 + elem.setAttribute( name, "auto" );
  8634 + return value;
  8635 + }
  8636 + }
  8637 + };
  8638 + } );
  8639 +}
  8640 +
  8641 +if ( !support.style ) {
  8642 + jQuery.attrHooks.style = {
  8643 + get: function( elem ) {
  8644 +
  8645 + // Return undefined in the case of empty string
  8646 + // Note: IE uppercases css property names, but if we were to .toLowerCase()
  8647 + // .cssText, that would destroy case sensitivity in URL's, like in "background"
  8648 + return elem.style.cssText || undefined;
  8649 + },
  8650 + set: function( elem, value ) {
  8651 + return ( elem.style.cssText = value + "" );
  8652 + }
  8653 + };
  8654 +}
  8655 +
  8656 +
  8657 +
  8658 +
  8659 +var rfocusable = /^(?:input|select|textarea|button|object)$/i,
  8660 + rclickable = /^(?:a|area)$/i;
  8661 +
  8662 +jQuery.fn.extend( {
  8663 + prop: function( name, value ) {
  8664 + return access( this, jQuery.prop, name, value, arguments.length > 1 );
  8665 + },
  8666 +
  8667 + removeProp: function( name ) {
  8668 + name = jQuery.propFix[ name ] || name;
  8669 + return this.each( function() {
  8670 +
  8671 + // try/catch handles cases where IE balks (such as removing a property on window)
  8672 + try {
  8673 + this[ name ] = undefined;
  8674 + delete this[ name ];
  8675 + } catch ( e ) {}
  8676 + } );
  8677 + }
  8678 +} );
  8679 +
  8680 +jQuery.extend( {
  8681 + prop: function( elem, name, value ) {
  8682 + var ret, hooks,
  8683 + nType = elem.nodeType;
  8684 +
  8685 + // Don't get/set properties on text, comment and attribute nodes
  8686 + if ( nType === 3 || nType === 8 || nType === 2 ) {
  8687 + return;
  8688 + }
  8689 +
  8690 + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  8691 +
  8692 + // Fix name and attach hooks
  8693 + name = jQuery.propFix[ name ] || name;
  8694 + hooks = jQuery.propHooks[ name ];
  8695 + }
  8696 +
  8697 + if ( value !== undefined ) {
  8698 + if ( hooks && "set" in hooks &&
  8699 + ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  8700 + return ret;
  8701 + }
  8702 +
  8703 + return ( elem[ name ] = value );
  8704 + }
  8705 +
  8706 + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  8707 + return ret;
  8708 + }
  8709 +
  8710 + return elem[ name ];
  8711 + },
  8712 +
  8713 + propHooks: {
  8714 + tabIndex: {
  8715 + get: function( elem ) {
  8716 +
  8717 + // elem.tabIndex doesn't always return the
  8718 + // correct value when it hasn't been explicitly set
  8719 + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  8720 + // Use proper attribute retrieval(#12072)
  8721 + var tabindex = jQuery.find.attr( elem, "tabindex" );
  8722 +
  8723 + return tabindex ?
  8724 + parseInt( tabindex, 10 ) :
  8725 + rfocusable.test( elem.nodeName ) ||
  8726 + rclickable.test( elem.nodeName ) && elem.href ?
  8727 + 0 :
  8728 + -1;
  8729 + }
  8730 + }
  8731 + },
  8732 +
  8733 + propFix: {
  8734 + "for": "htmlFor",
  8735 + "class": "className"
  8736 + }
  8737 +} );
  8738 +
  8739 +// Some attributes require a special call on IE
  8740 +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  8741 +if ( !support.hrefNormalized ) {
  8742 +
  8743 + // href/src property should get the full normalized URL (#10299/#12915)
  8744 + jQuery.each( [ "href", "src" ], function( i, name ) {
  8745 + jQuery.propHooks[ name ] = {
  8746 + get: function( elem ) {
  8747 + return elem.getAttribute( name, 4 );
  8748 + }
  8749 + };
  8750 + } );
  8751 +}
  8752 +
  8753 +// Support: Safari, IE9+
  8754 +// mis-reports the default selected property of an option
  8755 +// Accessing the parent's selectedIndex property fixes it
  8756 +if ( !support.optSelected ) {
  8757 + jQuery.propHooks.selected = {
  8758 + get: function( elem ) {
  8759 + var parent = elem.parentNode;
  8760 +
  8761 + if ( parent ) {
  8762 + parent.selectedIndex;
  8763 +
  8764 + // Make sure that it also works with optgroups, see #5701
  8765 + if ( parent.parentNode ) {
  8766 + parent.parentNode.selectedIndex;
  8767 + }
  8768 + }
  8769 + return null;
  8770 + }
  8771 + };
  8772 +}
  8773 +
  8774 +jQuery.each( [
  8775 + "tabIndex",
  8776 + "readOnly",
  8777 + "maxLength",
  8778 + "cellSpacing",
  8779 + "cellPadding",
  8780 + "rowSpan",
  8781 + "colSpan",
  8782 + "useMap",
  8783 + "frameBorder",
  8784 + "contentEditable"
  8785 +], function() {
  8786 + jQuery.propFix[ this.toLowerCase() ] = this;
  8787 +} );
  8788 +
  8789 +// IE6/7 call enctype encoding
  8790 +if ( !support.enctype ) {
  8791 + jQuery.propFix.enctype = "encoding";
  8792 +}
  8793 +
  8794 +
  8795 +
  8796 +
  8797 +var rclass = /[\t\r\n\f]/g;
  8798 +
  8799 +function getClass( elem ) {
  8800 + return jQuery.attr( elem, "class" ) || "";
  8801 +}
  8802 +
  8803 +jQuery.fn.extend( {
  8804 + addClass: function( value ) {
  8805 + var classes, elem, cur, curValue, clazz, j, finalValue,
  8806 + i = 0;
  8807 +
  8808 + if ( jQuery.isFunction( value ) ) {
  8809 + return this.each( function( j ) {
  8810 + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
  8811 + } );
  8812 + }
  8813 +
  8814 + if ( typeof value === "string" && value ) {
  8815 + classes = value.match( rnotwhite ) || [];
  8816 +
  8817 + while ( ( elem = this[ i++ ] ) ) {
  8818 + curValue = getClass( elem );
  8819 + cur = elem.nodeType === 1 &&
  8820 + ( " " + curValue + " " ).replace( rclass, " " );
  8821 +
  8822 + if ( cur ) {
  8823 + j = 0;
  8824 + while ( ( clazz = classes[ j++ ] ) ) {
  8825 + if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  8826 + cur += clazz + " ";
  8827 + }
  8828 + }
  8829 +
  8830 + // only assign if different to avoid unneeded rendering.
  8831 + finalValue = jQuery.trim( cur );
  8832 + if ( curValue !== finalValue ) {
  8833 + jQuery.attr( elem, "class", finalValue );
  8834 + }
  8835 + }
  8836 + }
  8837 + }
  8838 +
  8839 + return this;
  8840 + },
  8841 +
  8842 + removeClass: function( value ) {
  8843 + var classes, elem, cur, curValue, clazz, j, finalValue,
  8844 + i = 0;
  8845 +
  8846 + if ( jQuery.isFunction( value ) ) {
  8847 + return this.each( function( j ) {
  8848 + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
  8849 + } );
  8850 + }
  8851 +
  8852 + if ( !arguments.length ) {
  8853 + return this.attr( "class", "" );
  8854 + }
  8855 +
  8856 + if ( typeof value === "string" && value ) {
  8857 + classes = value.match( rnotwhite ) || [];
  8858 +
  8859 + while ( ( elem = this[ i++ ] ) ) {
  8860 + curValue = getClass( elem );
  8861 +
  8862 + // This expression is here for better compressibility (see addClass)
  8863 + cur = elem.nodeType === 1 &&
  8864 + ( " " + curValue + " " ).replace( rclass, " " );
  8865 +
  8866 + if ( cur ) {
  8867 + j = 0;
  8868 + while ( ( clazz = classes[ j++ ] ) ) {
  8869 +
  8870 + // Remove *all* instances
  8871 + while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
  8872 + cur = cur.replace( " " + clazz + " ", " " );
  8873 + }
  8874 + }
  8875 +
  8876 + // Only assign if different to avoid unneeded rendering.
  8877 + finalValue = jQuery.trim( cur );
  8878 + if ( curValue !== finalValue ) {
  8879 + jQuery.attr( elem, "class", finalValue );
  8880 + }
  8881 + }
  8882 + }
  8883 + }
  8884 +
  8885 + return this;
  8886 + },
  8887 +
  8888 + toggleClass: function( value, stateVal ) {
  8889 + var type = typeof value;
  8890 +
  8891 + if ( typeof stateVal === "boolean" && type === "string" ) {
  8892 + return stateVal ? this.addClass( value ) : this.removeClass( value );
  8893 + }
  8894 +
  8895 + if ( jQuery.isFunction( value ) ) {
  8896 + return this.each( function( i ) {
  8897 + jQuery( this ).toggleClass(
  8898 + value.call( this, i, getClass( this ), stateVal ),
  8899 + stateVal
  8900 + );
  8901 + } );
  8902 + }
  8903 +
  8904 + return this.each( function() {
  8905 + var className, i, self, classNames;
  8906 +
  8907 + if ( type === "string" ) {
  8908 +
  8909 + // Toggle individual class names
  8910 + i = 0;
  8911 + self = jQuery( this );
  8912 + classNames = value.match( rnotwhite ) || [];
  8913 +
  8914 + while ( ( className = classNames[ i++ ] ) ) {
  8915 +
  8916 + // Check each className given, space separated list
  8917 + if ( self.hasClass( className ) ) {
  8918 + self.removeClass( className );
  8919 + } else {
  8920 + self.addClass( className );
  8921 + }
  8922 + }
  8923 +
  8924 + // Toggle whole class name
  8925 + } else if ( value === undefined || type === "boolean" ) {
  8926 + className = getClass( this );
  8927 + if ( className ) {
  8928 +
  8929 + // store className if set
  8930 + jQuery._data( this, "__className__", className );
  8931 + }
  8932 +
  8933 + // If the element has a class name or if we're passed "false",
  8934 + // then remove the whole classname (if there was one, the above saved it).
  8935 + // Otherwise bring back whatever was previously saved (if anything),
  8936 + // falling back to the empty string if nothing was stored.
  8937 + jQuery.attr( this, "class",
  8938 + className || value === false ?
  8939 + "" :
  8940 + jQuery._data( this, "__className__" ) || ""
  8941 + );
  8942 + }
  8943 + } );
  8944 + },
  8945 +
  8946 + hasClass: function( selector ) {
  8947 + var className, elem,
  8948 + i = 0;
  8949 +
  8950 + className = " " + selector + " ";
  8951 + while ( ( elem = this[ i++ ] ) ) {
  8952 + if ( elem.nodeType === 1 &&
  8953 + ( " " + getClass( elem ) + " " ).replace( rclass, " " )
  8954 + .indexOf( className ) > -1
  8955 + ) {
  8956 + return true;
  8957 + }
  8958 + }
  8959 +
  8960 + return false;
  8961 + }
  8962 +} );
  8963 +
  8964 +
  8965 +
  8966 +
  8967 +// Return jQuery for attributes-only inclusion
  8968 +
  8969 +
  8970 +jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
  8971 + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  8972 + "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
  8973 + function( i, name ) {
  8974 +
  8975 + // Handle event binding
  8976 + jQuery.fn[ name ] = function( data, fn ) {
  8977 + return arguments.length > 0 ?
  8978 + this.on( name, null, data, fn ) :
  8979 + this.trigger( name );
  8980 + };
  8981 +} );
  8982 +
  8983 +jQuery.fn.extend( {
  8984 + hover: function( fnOver, fnOut ) {
  8985 + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  8986 + }
  8987 +} );
  8988 +
  8989 +
  8990 +var location = window.location;
  8991 +
  8992 +var nonce = jQuery.now();
  8993 +
  8994 +var rquery = ( /\?/ );
  8995 +
  8996 +
  8997 +
  8998 +var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
  8999 +
  9000 +jQuery.parseJSON = function( data ) {
  9001 +
  9002 + // Attempt to parse using the native JSON parser first
  9003 + if ( window.JSON && window.JSON.parse ) {
  9004 +
  9005 + // Support: Android 2.3
  9006 + // Workaround failure to string-cast null input
  9007 + return window.JSON.parse( data + "" );
  9008 + }
  9009 +
  9010 + var requireNonComma,
  9011 + depth = null,
  9012 + str = jQuery.trim( data + "" );
  9013 +
  9014 + // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
  9015 + // after removing valid tokens
  9016 + return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
  9017 +
  9018 + // Force termination if we see a misplaced comma
  9019 + if ( requireNonComma && comma ) {
  9020 + depth = 0;
  9021 + }
  9022 +
  9023 + // Perform no more replacements after returning to outermost depth
  9024 + if ( depth === 0 ) {
  9025 + return token;
  9026 + }
  9027 +
  9028 + // Commas must not follow "[", "{", or ","
  9029 + requireNonComma = open || comma;
  9030 +
  9031 + // Determine new depth
  9032 + // array/object open ("[" or "{"): depth += true - false (increment)
  9033 + // array/object close ("]" or "}"): depth += false - true (decrement)
  9034 + // other cases ("," or primitive): depth += true - true (numeric cast)
  9035 + depth += !close - !open;
  9036 +
  9037 + // Remove this token
  9038 + return "";
  9039 + } ) ) ?
  9040 + ( Function( "return " + str ) )() :
  9041 + jQuery.error( "Invalid JSON: " + data );
  9042 +};
  9043 +
  9044 +
  9045 +// Cross-browser xml parsing
  9046 +jQuery.parseXML = function( data ) {
  9047 + var xml, tmp;
  9048 + if ( !data || typeof data !== "string" ) {
  9049 + return null;
  9050 + }
  9051 + try {
  9052 + if ( window.DOMParser ) { // Standard
  9053 + tmp = new window.DOMParser();
  9054 + xml = tmp.parseFromString( data, "text/xml" );
  9055 + } else { // IE
  9056 + xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
  9057 + xml.async = "false";
  9058 + xml.loadXML( data );
  9059 + }
  9060 + } catch ( e ) {
  9061 + xml = undefined;
  9062 + }
  9063 + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
  9064 + jQuery.error( "Invalid XML: " + data );
  9065 + }
  9066 + return xml;
  9067 +};
  9068 +
  9069 +
  9070 +var
  9071 + rhash = /#.*$/,
  9072 + rts = /([?&])_=[^&]*/,
  9073 +
  9074 + // IE leaves an \r character at EOL
  9075 + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
  9076 +
  9077 + // #7653, #8125, #8152: local protocol detection
  9078 + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  9079 + rnoContent = /^(?:GET|HEAD)$/,
  9080 + rprotocol = /^\/\//,
  9081 + rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
  9082 +
  9083 + /* Prefilters
  9084 + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  9085 + * 2) These are called:
  9086 + * - BEFORE asking for a transport
  9087 + * - AFTER param serialization (s.data is a string if s.processData is true)
  9088 + * 3) key is the dataType
  9089 + * 4) the catchall symbol "*" can be used
  9090 + * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  9091 + */
  9092 + prefilters = {},
  9093 +
  9094 + /* Transports bindings
  9095 + * 1) key is the dataType
  9096 + * 2) the catchall symbol "*" can be used
  9097 + * 3) selection will start with transport dataType and THEN go to "*" if needed
  9098 + */
  9099 + transports = {},
  9100 +
  9101 + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  9102 + allTypes = "*/".concat( "*" ),
  9103 +
  9104 + // Document location
  9105 + ajaxLocation = location.href,
  9106 +
  9107 + // Segment location into parts
  9108 + ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
  9109 +
  9110 +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  9111 +function addToPrefiltersOrTransports( structure ) {
  9112 +
  9113 + // dataTypeExpression is optional and defaults to "*"
  9114 + return function( dataTypeExpression, func ) {
  9115 +
  9116 + if ( typeof dataTypeExpression !== "string" ) {
  9117 + func = dataTypeExpression;
  9118 + dataTypeExpression = "*";
  9119 + }
  9120 +
  9121 + var dataType,
  9122 + i = 0,
  9123 + dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
  9124 +
  9125 + if ( jQuery.isFunction( func ) ) {
  9126 +
  9127 + // For each dataType in the dataTypeExpression
  9128 + while ( ( dataType = dataTypes[ i++ ] ) ) {
  9129 +
  9130 + // Prepend if requested
  9131 + if ( dataType.charAt( 0 ) === "+" ) {
  9132 + dataType = dataType.slice( 1 ) || "*";
  9133 + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
  9134 +
  9135 + // Otherwise append
  9136 + } else {
  9137 + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
  9138 + }
  9139 + }
  9140 + }
  9141 + };
  9142 +}
  9143 +
  9144 +// Base inspection function for prefilters and transports
  9145 +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  9146 +
  9147 + var inspected = {},
  9148 + seekingTransport = ( structure === transports );
  9149 +
  9150 + function inspect( dataType ) {
  9151 + var selected;
  9152 + inspected[ dataType ] = true;
  9153 + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  9154 + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  9155 + if ( typeof dataTypeOrTransport === "string" &&
  9156 + !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  9157 +
  9158 + options.dataTypes.unshift( dataTypeOrTransport );
  9159 + inspect( dataTypeOrTransport );
  9160 + return false;
  9161 + } else if ( seekingTransport ) {
  9162 + return !( selected = dataTypeOrTransport );
  9163 + }
  9164 + } );
  9165 + return selected;
  9166 + }
  9167 +
  9168 + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  9169 +}
  9170 +
  9171 +// A special extend for ajax options
  9172 +// that takes "flat" options (not to be deep extended)
  9173 +// Fixes #9887
  9174 +function ajaxExtend( target, src ) {
  9175 + var deep, key,
  9176 + flatOptions = jQuery.ajaxSettings.flatOptions || {};
  9177 +
  9178 + for ( key in src ) {
  9179 + if ( src[ key ] !== undefined ) {
  9180 + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
  9181 + }
  9182 + }
  9183 + if ( deep ) {
  9184 + jQuery.extend( true, target, deep );
  9185 + }
  9186 +
  9187 + return target;
  9188 +}
  9189 +
  9190 +/* Handles responses to an ajax request:
  9191 + * - finds the right dataType (mediates between content-type and expected dataType)
  9192 + * - returns the corresponding response
  9193 + */
  9194 +function ajaxHandleResponses( s, jqXHR, responses ) {
  9195 + var firstDataType, ct, finalDataType, type,
  9196 + contents = s.contents,
  9197 + dataTypes = s.dataTypes;
  9198 +
  9199 + // Remove auto dataType and get content-type in the process
  9200 + while ( dataTypes[ 0 ] === "*" ) {
  9201 + dataTypes.shift();
  9202 + if ( ct === undefined ) {
  9203 + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
  9204 + }
  9205 + }
  9206 +
  9207 + // Check if we're dealing with a known content-type
  9208 + if ( ct ) {
  9209 + for ( type in contents ) {
  9210 + if ( contents[ type ] && contents[ type ].test( ct ) ) {
  9211 + dataTypes.unshift( type );
  9212 + break;
  9213 + }
  9214 + }
  9215 + }
  9216 +
  9217 + // Check to see if we have a response for the expected dataType
  9218 + if ( dataTypes[ 0 ] in responses ) {
  9219 + finalDataType = dataTypes[ 0 ];
  9220 + } else {
  9221 +
  9222 + // Try convertible dataTypes
  9223 + for ( type in responses ) {
  9224 + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
  9225 + finalDataType = type;
  9226 + break;
  9227 + }
  9228 + if ( !firstDataType ) {
  9229 + firstDataType = type;
  9230 + }
  9231 + }
  9232 +
  9233 + // Or just use first one
  9234 + finalDataType = finalDataType || firstDataType;
  9235 + }
  9236 +
  9237 + // If we found a dataType
  9238 + // We add the dataType to the list if needed
  9239 + // and return the corresponding response
  9240 + if ( finalDataType ) {
  9241 + if ( finalDataType !== dataTypes[ 0 ] ) {
  9242 + dataTypes.unshift( finalDataType );
  9243 + }
  9244 + return responses[ finalDataType ];
  9245 + }
  9246 +}
  9247 +
  9248 +/* Chain conversions given the request and the original response
  9249 + * Also sets the responseXXX fields on the jqXHR instance
  9250 + */
  9251 +function ajaxConvert( s, response, jqXHR, isSuccess ) {
  9252 + var conv2, current, conv, tmp, prev,
  9253 + converters = {},
  9254 +
  9255 + // Work with a copy of dataTypes in case we need to modify it for conversion
  9256 + dataTypes = s.dataTypes.slice();
  9257 +
  9258 + // Create converters map with lowercased keys
  9259 + if ( dataTypes[ 1 ] ) {
  9260 + for ( conv in s.converters ) {
  9261 + converters[ conv.toLowerCase() ] = s.converters[ conv ];
  9262 + }
  9263 + }
  9264 +
  9265 + current = dataTypes.shift();
  9266 +
  9267 + // Convert to each sequential dataType
  9268 + while ( current ) {
  9269 +
  9270 + if ( s.responseFields[ current ] ) {
  9271 + jqXHR[ s.responseFields[ current ] ] = response;
  9272 + }
  9273 +
  9274 + // Apply the dataFilter if provided
  9275 + if ( !prev && isSuccess && s.dataFilter ) {
  9276 + response = s.dataFilter( response, s.dataType );
  9277 + }
  9278 +
  9279 + prev = current;
  9280 + current = dataTypes.shift();
  9281 +
  9282 + if ( current ) {
  9283 +
  9284 + // There's only work to do if current dataType is non-auto
  9285 + if ( current === "*" ) {
  9286 +
  9287 + current = prev;
  9288 +
  9289 + // Convert response if prev dataType is non-auto and differs from current
  9290 + } else if ( prev !== "*" && prev !== current ) {
  9291 +
  9292 + // Seek a direct converter
  9293 + conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  9294 +
  9295 + // If none found, seek a pair
  9296 + if ( !conv ) {
  9297 + for ( conv2 in converters ) {
  9298 +
  9299 + // If conv2 outputs current
  9300 + tmp = conv2.split( " " );
  9301 + if ( tmp[ 1 ] === current ) {
  9302 +
  9303 + // If prev can be converted to accepted input
  9304 + conv = converters[ prev + " " + tmp[ 0 ] ] ||
  9305 + converters[ "* " + tmp[ 0 ] ];
  9306 + if ( conv ) {
  9307 +
  9308 + // Condense equivalence converters
  9309 + if ( conv === true ) {
  9310 + conv = converters[ conv2 ];
  9311 +
  9312 + // Otherwise, insert the intermediate dataType
  9313 + } else if ( converters[ conv2 ] !== true ) {
  9314 + current = tmp[ 0 ];
  9315 + dataTypes.unshift( tmp[ 1 ] );
  9316 + }
  9317 + break;
  9318 + }
  9319 + }
  9320 + }
  9321 + }
  9322 +
  9323 + // Apply converter (if not an equivalence)
  9324 + if ( conv !== true ) {
  9325 +
  9326 + // Unless errors are allowed to bubble, catch and return them
  9327 + if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
  9328 + response = conv( response );
  9329 + } else {
  9330 + try {
  9331 + response = conv( response );
  9332 + } catch ( e ) {
  9333 + return {
  9334 + state: "parsererror",
  9335 + error: conv ? e : "No conversion from " + prev + " to " + current
  9336 + };
  9337 + }
  9338 + }
  9339 + }
  9340 + }
  9341 + }
  9342 + }
  9343 +
  9344 + return { state: "success", data: response };
  9345 +}
  9346 +
  9347 +jQuery.extend( {
  9348 +
  9349 + // Counter for holding the number of active queries
  9350 + active: 0,
  9351 +
  9352 + // Last-Modified header cache for next request
  9353 + lastModified: {},
  9354 + etag: {},
  9355 +
  9356 + ajaxSettings: {
  9357 + url: ajaxLocation,
  9358 + type: "GET",
  9359 + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
  9360 + global: true,
  9361 + processData: true,
  9362 + async: true,
  9363 + contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  9364 + /*
  9365 + timeout: 0,
  9366 + data: null,
  9367 + dataType: null,
  9368 + username: null,
  9369 + password: null,
  9370 + cache: null,
  9371 + throws: false,
  9372 + traditional: false,
  9373 + headers: {},
  9374 + */
  9375 +
  9376 + accepts: {
  9377 + "*": allTypes,
  9378 + text: "text/plain",
  9379 + html: "text/html",
  9380 + xml: "application/xml, text/xml",
  9381 + json: "application/json, text/javascript"
  9382 + },
  9383 +
  9384 + contents: {
  9385 + xml: /\bxml\b/,
  9386 + html: /\bhtml/,
  9387 + json: /\bjson\b/
  9388 + },
  9389 +
  9390 + responseFields: {
  9391 + xml: "responseXML",
  9392 + text: "responseText",
  9393 + json: "responseJSON"
  9394 + },
  9395 +
  9396 + // Data converters
  9397 + // Keys separate source (or catchall "*") and destination types with a single space
  9398 + converters: {
  9399 +
  9400 + // Convert anything to text
  9401 + "* text": String,
  9402 +
  9403 + // Text to html (true = no transformation)
  9404 + "text html": true,
  9405 +
  9406 + // Evaluate text as a json expression
  9407 + "text json": jQuery.parseJSON,
  9408 +
  9409 + // Parse text as xml
  9410 + "text xml": jQuery.parseXML
  9411 + },
  9412 +
  9413 + // For options that shouldn't be deep extended:
  9414 + // you can add your own custom options here if
  9415 + // and when you create one that shouldn't be
  9416 + // deep extended (see ajaxExtend)
  9417 + flatOptions: {
  9418 + url: true,
  9419 + context: true
  9420 + }
  9421 + },
  9422 +
  9423 + // Creates a full fledged settings object into target
  9424 + // with both ajaxSettings and settings fields.
  9425 + // If target is omitted, writes into ajaxSettings.
  9426 + ajaxSetup: function( target, settings ) {
  9427 + return settings ?
  9428 +
  9429 + // Building a settings object
  9430 + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  9431 +
  9432 + // Extending ajaxSettings
  9433 + ajaxExtend( jQuery.ajaxSettings, target );
  9434 + },
  9435 +
  9436 + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  9437 + ajaxTransport: addToPrefiltersOrTransports( transports ),
  9438 +
  9439 + // Main method
  9440 + ajax: function( url, options ) {
  9441 +
  9442 + // If url is an object, simulate pre-1.5 signature
  9443 + if ( typeof url === "object" ) {
  9444 + options = url;
  9445 + url = undefined;
  9446 + }
  9447 +
  9448 + // Force options to be an object
  9449 + options = options || {};
  9450 +
  9451 + var
  9452 +
  9453 + // Cross-domain detection vars
  9454 + parts,
  9455 +
  9456 + // Loop variable
  9457 + i,
  9458 +
  9459 + // URL without anti-cache param
  9460 + cacheURL,
  9461 +
  9462 + // Response headers as string
  9463 + responseHeadersString,
  9464 +
  9465 + // timeout handle
  9466 + timeoutTimer,
  9467 +
  9468 + // To know if global events are to be dispatched
  9469 + fireGlobals,
  9470 +
  9471 + transport,
  9472 +
  9473 + // Response headers
  9474 + responseHeaders,
  9475 +
  9476 + // Create the final options object
  9477 + s = jQuery.ajaxSetup( {}, options ),
  9478 +
  9479 + // Callbacks context
  9480 + callbackContext = s.context || s,
  9481 +
  9482 + // Context for global events is callbackContext if it is a DOM node or jQuery collection
  9483 + globalEventContext = s.context &&
  9484 + ( callbackContext.nodeType || callbackContext.jquery ) ?
  9485 + jQuery( callbackContext ) :
  9486 + jQuery.event,
  9487 +
  9488 + // Deferreds
  9489 + deferred = jQuery.Deferred(),
  9490 + completeDeferred = jQuery.Callbacks( "once memory" ),
  9491 +
  9492 + // Status-dependent callbacks
  9493 + statusCode = s.statusCode || {},
  9494 +
  9495 + // Headers (they are sent all at once)
  9496 + requestHeaders = {},
  9497 + requestHeadersNames = {},
  9498 +
  9499 + // The jqXHR state
  9500 + state = 0,
  9501 +
  9502 + // Default abort message
  9503 + strAbort = "canceled",
  9504 +
  9505 + // Fake xhr
  9506 + jqXHR = {
  9507 + readyState: 0,
  9508 +
  9509 + // Builds headers hashtable if needed
  9510 + getResponseHeader: function( key ) {
  9511 + var match;
  9512 + if ( state === 2 ) {
  9513 + if ( !responseHeaders ) {
  9514 + responseHeaders = {};
  9515 + while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
  9516 + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
  9517 + }
  9518 + }
  9519 + match = responseHeaders[ key.toLowerCase() ];
  9520 + }
  9521 + return match == null ? null : match;
  9522 + },
  9523 +
  9524 + // Raw string
  9525 + getAllResponseHeaders: function() {
  9526 + return state === 2 ? responseHeadersString : null;
  9527 + },
  9528 +
  9529 + // Caches the header
  9530 + setRequestHeader: function( name, value ) {
  9531 + var lname = name.toLowerCase();
  9532 + if ( !state ) {
  9533 + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
  9534 + requestHeaders[ name ] = value;
  9535 + }
  9536 + return this;
  9537 + },
  9538 +
  9539 + // Overrides response content-type header
  9540 + overrideMimeType: function( type ) {
  9541 + if ( !state ) {
  9542 + s.mimeType = type;
  9543 + }
  9544 + return this;
  9545 + },
  9546 +
  9547 + // Status-dependent callbacks
  9548 + statusCode: function( map ) {
  9549 + var code;
  9550 + if ( map ) {
  9551 + if ( state < 2 ) {
  9552 + for ( code in map ) {
  9553 +
  9554 + // Lazy-add the new callback in a way that preserves old ones
  9555 + statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  9556 + }
  9557 + } else {
  9558 +
  9559 + // Execute the appropriate callbacks
  9560 + jqXHR.always( map[ jqXHR.status ] );
  9561 + }
  9562 + }
  9563 + return this;
  9564 + },
  9565 +
  9566 + // Cancel the request
  9567 + abort: function( statusText ) {
  9568 + var finalText = statusText || strAbort;
  9569 + if ( transport ) {
  9570 + transport.abort( finalText );
  9571 + }
  9572 + done( 0, finalText );
  9573 + return this;
  9574 + }
  9575 + };
  9576 +
  9577 + // Attach deferreds
  9578 + deferred.promise( jqXHR ).complete = completeDeferred.add;
  9579 + jqXHR.success = jqXHR.done;
  9580 + jqXHR.error = jqXHR.fail;
  9581 +
  9582 + // Remove hash character (#7531: and string promotion)
  9583 + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
  9584 + // Handle falsy url in the settings object (#10093: consistency with old signature)
  9585 + // We also use the url parameter if available
  9586 + s.url = ( ( url || s.url || ajaxLocation ) + "" )
  9587 + .replace( rhash, "" )
  9588 + .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
  9589 +
  9590 + // Alias method option to type as per ticket #12004
  9591 + s.type = options.method || options.type || s.method || s.type;
  9592 +
  9593 + // Extract dataTypes list
  9594 + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
  9595 +
  9596 + // A cross-domain request is in order when we have a protocol:host:port mismatch
  9597 + if ( s.crossDomain == null ) {
  9598 + parts = rurl.exec( s.url.toLowerCase() );
  9599 + s.crossDomain = !!( parts &&
  9600 + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
  9601 + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
  9602 + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
  9603 + );
  9604 + }
  9605 +
  9606 + // Convert data if not already a string
  9607 + if ( s.data && s.processData && typeof s.data !== "string" ) {
  9608 + s.data = jQuery.param( s.data, s.traditional );
  9609 + }
  9610 +
  9611 + // Apply prefilters
  9612 + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  9613 +
  9614 + // If request was aborted inside a prefilter, stop there
  9615 + if ( state === 2 ) {
  9616 + return jqXHR;
  9617 + }
  9618 +
  9619 + // We can fire global events as of now if asked to
  9620 + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
  9621 + fireGlobals = jQuery.event && s.global;
  9622 +
  9623 + // Watch for a new set of requests
  9624 + if ( fireGlobals && jQuery.active++ === 0 ) {
  9625 + jQuery.event.trigger( "ajaxStart" );
  9626 + }
  9627 +
  9628 + // Uppercase the type
  9629 + s.type = s.type.toUpperCase();
  9630 +
  9631 + // Determine if request has content
  9632 + s.hasContent = !rnoContent.test( s.type );
  9633 +
  9634 + // Save the URL in case we're toying with the If-Modified-Since
  9635 + // and/or If-None-Match header later on
  9636 + cacheURL = s.url;
  9637 +
  9638 + // More options handling for requests with no content
  9639 + if ( !s.hasContent ) {
  9640 +
  9641 + // If data is available, append data to url
  9642 + if ( s.data ) {
  9643 + cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
  9644 +
  9645 + // #9682: remove data so that it's not used in an eventual retry
  9646 + delete s.data;
  9647 + }
  9648 +
  9649 + // Add anti-cache in url if needed
  9650 + if ( s.cache === false ) {
  9651 + s.url = rts.test( cacheURL ) ?
  9652 +
  9653 + // If there is already a '_' parameter, set its value
  9654 + cacheURL.replace( rts, "$1_=" + nonce++ ) :
  9655 +
  9656 + // Otherwise add one to the end
  9657 + cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
  9658 + }
  9659 + }
  9660 +
  9661 + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  9662 + if ( s.ifModified ) {
  9663 + if ( jQuery.lastModified[ cacheURL ] ) {
  9664 + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  9665 + }
  9666 + if ( jQuery.etag[ cacheURL ] ) {
  9667 + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  9668 + }
  9669 + }
  9670 +
  9671 + // Set the correct header, if data is being sent
  9672 + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  9673 + jqXHR.setRequestHeader( "Content-Type", s.contentType );
  9674 + }
  9675 +
  9676 + // Set the Accepts header for the server, depending on the dataType
  9677 + jqXHR.setRequestHeader(
  9678 + "Accept",
  9679 + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
  9680 + s.accepts[ s.dataTypes[ 0 ] ] +
  9681 + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  9682 + s.accepts[ "*" ]
  9683 + );
  9684 +
  9685 + // Check for headers option
  9686 + for ( i in s.headers ) {
  9687 + jqXHR.setRequestHeader( i, s.headers[ i ] );
  9688 + }
  9689 +
  9690 + // Allow custom headers/mimetypes and early abort
  9691 + if ( s.beforeSend &&
  9692 + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
  9693 +
  9694 + // Abort if not done already and return
  9695 + return jqXHR.abort();
  9696 + }
  9697 +
  9698 + // aborting is no longer a cancellation
  9699 + strAbort = "abort";
  9700 +
  9701 + // Install callbacks on deferreds
  9702 + for ( i in { success: 1, error: 1, complete: 1 } ) {
  9703 + jqXHR[ i ]( s[ i ] );
  9704 + }
  9705 +
  9706 + // Get transport
  9707 + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  9708 +
  9709 + // If no transport, we auto-abort
  9710 + if ( !transport ) {
  9711 + done( -1, "No Transport" );
  9712 + } else {
  9713 + jqXHR.readyState = 1;
  9714 +
  9715 + // Send global event
  9716 + if ( fireGlobals ) {
  9717 + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  9718 + }
  9719 +
  9720 + // If request was aborted inside ajaxSend, stop there
  9721 + if ( state === 2 ) {
  9722 + return jqXHR;
  9723 + }
  9724 +
  9725 + // Timeout
  9726 + if ( s.async && s.timeout > 0 ) {
  9727 + timeoutTimer = window.setTimeout( function() {
  9728 + jqXHR.abort( "timeout" );
  9729 + }, s.timeout );
  9730 + }
  9731 +
  9732 + try {
  9733 + state = 1;
  9734 + transport.send( requestHeaders, done );
  9735 + } catch ( e ) {
  9736 +
  9737 + // Propagate exception as error if not done
  9738 + if ( state < 2 ) {
  9739 + done( -1, e );
  9740 +
  9741 + // Simply rethrow otherwise
  9742 + } else {
  9743 + throw e;
  9744 + }
  9745 + }
  9746 + }
  9747 +
  9748 + // Callback for when everything is done
  9749 + function done( status, nativeStatusText, responses, headers ) {
  9750 + var isSuccess, success, error, response, modified,
  9751 + statusText = nativeStatusText;
  9752 +
  9753 + // Called once
  9754 + if ( state === 2 ) {
  9755 + return;
  9756 + }
  9757 +
  9758 + // State is "done" now
  9759 + state = 2;
  9760 +
  9761 + // Clear timeout if it exists
  9762 + if ( timeoutTimer ) {
  9763 + window.clearTimeout( timeoutTimer );
  9764 + }
  9765 +
  9766 + // Dereference transport for early garbage collection
  9767 + // (no matter how long the jqXHR object will be used)
  9768 + transport = undefined;
  9769 +
  9770 + // Cache response headers
  9771 + responseHeadersString = headers || "";
  9772 +
  9773 + // Set readyState
  9774 + jqXHR.readyState = status > 0 ? 4 : 0;
  9775 +
  9776 + // Determine if successful
  9777 + isSuccess = status >= 200 && status < 300 || status === 304;
  9778 +
  9779 + // Get response data
  9780 + if ( responses ) {
  9781 + response = ajaxHandleResponses( s, jqXHR, responses );
  9782 + }
  9783 +
  9784 + // Convert no matter what (that way responseXXX fields are always set)
  9785 + response = ajaxConvert( s, response, jqXHR, isSuccess );
  9786 +
  9787 + // If successful, handle type chaining
  9788 + if ( isSuccess ) {
  9789 +
  9790 + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  9791 + if ( s.ifModified ) {
  9792 + modified = jqXHR.getResponseHeader( "Last-Modified" );
  9793 + if ( modified ) {
  9794 + jQuery.lastModified[ cacheURL ] = modified;
  9795 + }
  9796 + modified = jqXHR.getResponseHeader( "etag" );
  9797 + if ( modified ) {
  9798 + jQuery.etag[ cacheURL ] = modified;
  9799 + }
  9800 + }
  9801 +
  9802 + // if no content
  9803 + if ( status === 204 || s.type === "HEAD" ) {
  9804 + statusText = "nocontent";
  9805 +
  9806 + // if not modified
  9807 + } else if ( status === 304 ) {
  9808 + statusText = "notmodified";
  9809 +
  9810 + // If we have data, let's convert it
  9811 + } else {
  9812 + statusText = response.state;
  9813 + success = response.data;
  9814 + error = response.error;
  9815 + isSuccess = !error;
  9816 + }
  9817 + } else {
  9818 +
  9819 + // We extract error from statusText
  9820 + // then normalize statusText and status for non-aborts
  9821 + error = statusText;
  9822 + if ( status || !statusText ) {
  9823 + statusText = "error";
  9824 + if ( status < 0 ) {
  9825 + status = 0;
  9826 + }
  9827 + }
  9828 + }
  9829 +
  9830 + // Set data for the fake xhr object
  9831 + jqXHR.status = status;
  9832 + jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  9833 +
  9834 + // Success/Error
  9835 + if ( isSuccess ) {
  9836 + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  9837 + } else {
  9838 + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  9839 + }
  9840 +
  9841 + // Status-dependent callbacks
  9842 + jqXHR.statusCode( statusCode );
  9843 + statusCode = undefined;
  9844 +
  9845 + if ( fireGlobals ) {
  9846 + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  9847 + [ jqXHR, s, isSuccess ? success : error ] );
  9848 + }
  9849 +
  9850 + // Complete
  9851 + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  9852 +
  9853 + if ( fireGlobals ) {
  9854 + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  9855 +
  9856 + // Handle the global AJAX counter
  9857 + if ( !( --jQuery.active ) ) {
  9858 + jQuery.event.trigger( "ajaxStop" );
  9859 + }
  9860 + }
  9861 + }
  9862 +
  9863 + return jqXHR;
  9864 + },
  9865 +
  9866 + getJSON: function( url, data, callback ) {
  9867 + return jQuery.get( url, data, callback, "json" );
  9868 + },
  9869 +
  9870 + getScript: function( url, callback ) {
  9871 + return jQuery.get( url, undefined, callback, "script" );
  9872 + }
  9873 +} );
  9874 +
  9875 +jQuery.each( [ "get", "post" ], function( i, method ) {
  9876 + jQuery[ method ] = function( url, data, callback, type ) {
  9877 +
  9878 + // shift arguments if data argument was omitted
  9879 + if ( jQuery.isFunction( data ) ) {
  9880 + type = type || callback;
  9881 + callback = data;
  9882 + data = undefined;
  9883 + }
  9884 +
  9885 + // The url can be an options object (which then must have .url)
  9886 + return jQuery.ajax( jQuery.extend( {
  9887 + url: url,
  9888 + type: method,
  9889 + dataType: type,
  9890 + data: data,
  9891 + success: callback
  9892 + }, jQuery.isPlainObject( url ) && url ) );
  9893 + };
  9894 +} );
  9895 +
  9896 +
  9897 +jQuery._evalUrl = function( url ) {
  9898 + return jQuery.ajax( {
  9899 + url: url,
  9900 +
  9901 + // Make this explicit, since user can override this through ajaxSetup (#11264)
  9902 + type: "GET",
  9903 + dataType: "script",
  9904 + cache: true,
  9905 + async: false,
  9906 + global: false,
  9907 + "throws": true
  9908 + } );
  9909 +};
  9910 +
  9911 +
  9912 +jQuery.fn.extend( {
  9913 + wrapAll: function( html ) {
  9914 + if ( jQuery.isFunction( html ) ) {
  9915 + return this.each( function( i ) {
  9916 + jQuery( this ).wrapAll( html.call( this, i ) );
  9917 + } );
  9918 + }
  9919 +
  9920 + if ( this[ 0 ] ) {
  9921 +
  9922 + // The elements to wrap the target around
  9923 + var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  9924 +
  9925 + if ( this[ 0 ].parentNode ) {
  9926 + wrap.insertBefore( this[ 0 ] );
  9927 + }
  9928 +
  9929 + wrap.map( function() {
  9930 + var elem = this;
  9931 +
  9932 + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
  9933 + elem = elem.firstChild;
  9934 + }
  9935 +
  9936 + return elem;
  9937 + } ).append( this );
  9938 + }
  9939 +
  9940 + return this;
  9941 + },
  9942 +
  9943 + wrapInner: function( html ) {
  9944 + if ( jQuery.isFunction( html ) ) {
  9945 + return this.each( function( i ) {
  9946 + jQuery( this ).wrapInner( html.call( this, i ) );
  9947 + } );
  9948 + }
  9949 +
  9950 + return this.each( function() {
  9951 + var self = jQuery( this ),
  9952 + contents = self.contents();
  9953 +
  9954 + if ( contents.length ) {
  9955 + contents.wrapAll( html );
  9956 +
  9957 + } else {
  9958 + self.append( html );
  9959 + }
  9960 + } );
  9961 + },
  9962 +
  9963 + wrap: function( html ) {
  9964 + var isFunction = jQuery.isFunction( html );
  9965 +
  9966 + return this.each( function( i ) {
  9967 + jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
  9968 + } );
  9969 + },
  9970 +
  9971 + unwrap: function() {
  9972 + return this.parent().each( function() {
  9973 + if ( !jQuery.nodeName( this, "body" ) ) {
  9974 + jQuery( this ).replaceWith( this.childNodes );
  9975 + }
  9976 + } ).end();
  9977 + }
  9978 +} );
  9979 +
  9980 +
  9981 +function getDisplay( elem ) {
  9982 + return elem.style && elem.style.display || jQuery.css( elem, "display" );
  9983 +}
  9984 +
  9985 +function filterHidden( elem ) {
  9986 + while ( elem && elem.nodeType === 1 ) {
  9987 + if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
  9988 + return true;
  9989 + }
  9990 + elem = elem.parentNode;
  9991 + }
  9992 + return false;
  9993 +}
  9994 +
  9995 +jQuery.expr.filters.hidden = function( elem ) {
  9996 +
  9997 + // Support: Opera <= 12.12
  9998 + // Opera reports offsetWidths and offsetHeights less than zero on some elements
  9999 + return support.reliableHiddenOffsets() ?
  10000 + ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
  10001 + !elem.getClientRects().length ) :
  10002 + filterHidden( elem );
  10003 +};
  10004 +
  10005 +jQuery.expr.filters.visible = function( elem ) {
  10006 + return !jQuery.expr.filters.hidden( elem );
  10007 +};
  10008 +
  10009 +
  10010 +
  10011 +
  10012 +var r20 = /%20/g,
  10013 + rbracket = /\[\]$/,
  10014 + rCRLF = /\r?\n/g,
  10015 + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  10016 + rsubmittable = /^(?:input|select|textarea|keygen)/i;
  10017 +
  10018 +function buildParams( prefix, obj, traditional, add ) {
  10019 + var name;
  10020 +
  10021 + if ( jQuery.isArray( obj ) ) {
  10022 +
  10023 + // Serialize array item.
  10024 + jQuery.each( obj, function( i, v ) {
  10025 + if ( traditional || rbracket.test( prefix ) ) {
  10026 +
  10027 + // Treat each array item as a scalar.
  10028 + add( prefix, v );
  10029 +
  10030 + } else {
  10031 +
  10032 + // Item is non-scalar (array or object), encode its numeric index.
  10033 + buildParams(
  10034 + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
  10035 + v,
  10036 + traditional,
  10037 + add
  10038 + );
  10039 + }
  10040 + } );
  10041 +
  10042 + } else if ( !traditional && jQuery.type( obj ) === "object" ) {
  10043 +
  10044 + // Serialize object item.
  10045 + for ( name in obj ) {
  10046 + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  10047 + }
  10048 +
  10049 + } else {
  10050 +
  10051 + // Serialize scalar item.
  10052 + add( prefix, obj );
  10053 + }
  10054 +}
  10055 +
  10056 +// Serialize an array of form elements or a set of
  10057 +// key/values into a query string
  10058 +jQuery.param = function( a, traditional ) {
  10059 + var prefix,
  10060 + s = [],
  10061 + add = function( key, value ) {
  10062 +
  10063 + // If value is a function, invoke it and return its value
  10064 + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
  10065 + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
  10066 + };
  10067 +
  10068 + // Set traditional to true for jQuery <= 1.3.2 behavior.
  10069 + if ( traditional === undefined ) {
  10070 + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  10071 + }
  10072 +
  10073 + // If an array was passed in, assume that it is an array of form elements.
  10074 + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  10075 +
  10076 + // Serialize the form elements
  10077 + jQuery.each( a, function() {
  10078 + add( this.name, this.value );
  10079 + } );
  10080 +
  10081 + } else {
  10082 +
  10083 + // If traditional, encode the "old" way (the way 1.3.2 or older
  10084 + // did it), otherwise encode params recursively.
  10085 + for ( prefix in a ) {
  10086 + buildParams( prefix, a[ prefix ], traditional, add );
  10087 + }
  10088 + }
  10089 +
  10090 + // Return the resulting serialization
  10091 + return s.join( "&" ).replace( r20, "+" );
  10092 +};
  10093 +
  10094 +jQuery.fn.extend( {
  10095 + serialize: function() {
  10096 + return jQuery.param( this.serializeArray() );
  10097 + },
  10098 + serializeArray: function() {
  10099 + return this.map( function() {
  10100 +
  10101 + // Can add propHook for "elements" to filter or add form elements
  10102 + var elements = jQuery.prop( this, "elements" );
  10103 + return elements ? jQuery.makeArray( elements ) : this;
  10104 + } )
  10105 + .filter( function() {
  10106 + var type = this.type;
  10107 +
  10108 + // Use .is(":disabled") so that fieldset[disabled] works
  10109 + return this.name && !jQuery( this ).is( ":disabled" ) &&
  10110 + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  10111 + ( this.checked || !rcheckableType.test( type ) );
  10112 + } )
  10113 + .map( function( i, elem ) {
  10114 + var val = jQuery( this ).val();
  10115 +
  10116 + return val == null ?
  10117 + null :
  10118 + jQuery.isArray( val ) ?
  10119 + jQuery.map( val, function( val ) {
  10120 + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  10121 + } ) :
  10122 + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  10123 + } ).get();
  10124 + }
  10125 +} );
  10126 +
  10127 +
  10128 +// Create the request object
  10129 +// (This is still attached to ajaxSettings for backward compatibility)
  10130 +jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
  10131 +
  10132 + // Support: IE6-IE8
  10133 + function() {
  10134 +
  10135 + // XHR cannot access local files, always use ActiveX for that case
  10136 + if ( this.isLocal ) {
  10137 + return createActiveXHR();
  10138 + }
  10139 +
  10140 + // Support: IE 9-11
  10141 + // IE seems to error on cross-domain PATCH requests when ActiveX XHR
  10142 + // is used. In IE 9+ always use the native XHR.
  10143 + // Note: this condition won't catch Edge as it doesn't define
  10144 + // document.documentMode but it also doesn't support ActiveX so it won't
  10145 + // reach this code.
  10146 + if ( document.documentMode > 8 ) {
  10147 + return createStandardXHR();
  10148 + }
  10149 +
  10150 + // Support: IE<9
  10151 + // oldIE XHR does not support non-RFC2616 methods (#13240)
  10152 + // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
  10153 + // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
  10154 + // Although this check for six methods instead of eight
  10155 + // since IE also does not support "trace" and "connect"
  10156 + return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
  10157 + createStandardXHR() || createActiveXHR();
  10158 + } :
  10159 +
  10160 + // For all other browsers, use the standard XMLHttpRequest object
  10161 + createStandardXHR;
  10162 +
  10163 +var xhrId = 0,
  10164 + xhrCallbacks = {},
  10165 + xhrSupported = jQuery.ajaxSettings.xhr();
  10166 +
  10167 +// Support: IE<10
  10168 +// Open requests must be manually aborted on unload (#5280)
  10169 +// See https://support.microsoft.com/kb/2856746 for more info
  10170 +if ( window.attachEvent ) {
  10171 + window.attachEvent( "onunload", function() {
  10172 + for ( var key in xhrCallbacks ) {
  10173 + xhrCallbacks[ key ]( undefined, true );
  10174 + }
  10175 + } );
  10176 +}
  10177 +
  10178 +// Determine support properties
  10179 +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  10180 +xhrSupported = support.ajax = !!xhrSupported;
  10181 +
  10182 +// Create transport if the browser can provide an xhr
  10183 +if ( xhrSupported ) {
  10184 +
  10185 + jQuery.ajaxTransport( function( options ) {
  10186 +
  10187 + // Cross domain only allowed if supported through XMLHttpRequest
  10188 + if ( !options.crossDomain || support.cors ) {
  10189 +
  10190 + var callback;
  10191 +
  10192 + return {
  10193 + send: function( headers, complete ) {
  10194 + var i,
  10195 + xhr = options.xhr(),
  10196 + id = ++xhrId;
  10197 +
  10198 + // Open the socket
  10199 + xhr.open(
  10200 + options.type,
  10201 + options.url,
  10202 + options.async,
  10203 + options.username,
  10204 + options.password
  10205 + );
  10206 +
  10207 + // Apply custom fields if provided
  10208 + if ( options.xhrFields ) {
  10209 + for ( i in options.xhrFields ) {
  10210 + xhr[ i ] = options.xhrFields[ i ];
  10211 + }
  10212 + }
  10213 +
  10214 + // Override mime type if needed
  10215 + if ( options.mimeType && xhr.overrideMimeType ) {
  10216 + xhr.overrideMimeType( options.mimeType );
  10217 + }
  10218 +
  10219 + // X-Requested-With header
  10220 + // For cross-domain requests, seeing as conditions for a preflight are
  10221 + // akin to a jigsaw puzzle, we simply never set it to be sure.
  10222 + // (it can always be set on a per-request basis or even using ajaxSetup)
  10223 + // For same-domain requests, won't change header if already provided.
  10224 + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
  10225 + headers[ "X-Requested-With" ] = "XMLHttpRequest";
  10226 + }
  10227 +
  10228 + // Set headers
  10229 + for ( i in headers ) {
  10230 +
  10231 + // Support: IE<9
  10232 + // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
  10233 + // request header to a null-value.
  10234 + //
  10235 + // To keep consistent with other XHR implementations, cast the value
  10236 + // to string and ignore `undefined`.
  10237 + if ( headers[ i ] !== undefined ) {
  10238 + xhr.setRequestHeader( i, headers[ i ] + "" );
  10239 + }
  10240 + }
  10241 +
  10242 + // Do send the request
  10243 + // This may raise an exception which is actually
  10244 + // handled in jQuery.ajax (so no try/catch here)
  10245 + xhr.send( ( options.hasContent && options.data ) || null );
  10246 +
  10247 + // Listener
  10248 + callback = function( _, isAbort ) {
  10249 + var status, statusText, responses;
  10250 +
  10251 + // Was never called and is aborted or complete
  10252 + if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
  10253 +
  10254 + // Clean up
  10255 + delete xhrCallbacks[ id ];
  10256 + callback = undefined;
  10257 + xhr.onreadystatechange = jQuery.noop;
  10258 +
  10259 + // Abort manually if needed
  10260 + if ( isAbort ) {
  10261 + if ( xhr.readyState !== 4 ) {
  10262 + xhr.abort();
  10263 + }
  10264 + } else {
  10265 + responses = {};
  10266 + status = xhr.status;
  10267 +
  10268 + // Support: IE<10
  10269 + // Accessing binary-data responseText throws an exception
  10270 + // (#11426)
  10271 + if ( typeof xhr.responseText === "string" ) {
  10272 + responses.text = xhr.responseText;
  10273 + }
  10274 +
  10275 + // Firefox throws an exception when accessing
  10276 + // statusText for faulty cross-domain requests
  10277 + try {
  10278 + statusText = xhr.statusText;
  10279 + } catch ( e ) {
  10280 +
  10281 + // We normalize with Webkit giving an empty statusText
  10282 + statusText = "";
  10283 + }
  10284 +
  10285 + // Filter status for non standard behaviors
  10286 +
  10287 + // If the request is local and we have data: assume a success
  10288 + // (success with no data won't get notified, that's the best we
  10289 + // can do given current implementations)
  10290 + if ( !status && options.isLocal && !options.crossDomain ) {
  10291 + status = responses.text ? 200 : 404;
  10292 +
  10293 + // IE - #1450: sometimes returns 1223 when it should be 204
  10294 + } else if ( status === 1223 ) {
  10295 + status = 204;
  10296 + }
  10297 + }
  10298 + }
  10299 +
  10300 + // Call complete if needed
  10301 + if ( responses ) {
  10302 + complete( status, statusText, responses, xhr.getAllResponseHeaders() );
  10303 + }
  10304 + };
  10305 +
  10306 + // Do send the request
  10307 + // `xhr.send` may raise an exception, but it will be
  10308 + // handled in jQuery.ajax (so no try/catch here)
  10309 + if ( !options.async ) {
  10310 +
  10311 + // If we're in sync mode we fire the callback
  10312 + callback();
  10313 + } else if ( xhr.readyState === 4 ) {
  10314 +
  10315 + // (IE6 & IE7) if it's in cache and has been
  10316 + // retrieved directly we need to fire the callback
  10317 + window.setTimeout( callback );
  10318 + } else {
  10319 +
  10320 + // Register the callback, but delay it in case `xhr.send` throws
  10321 + // Add to the list of active xhr callbacks
  10322 + xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
  10323 + }
  10324 + },
  10325 +
  10326 + abort: function() {
  10327 + if ( callback ) {
  10328 + callback( undefined, true );
  10329 + }
  10330 + }
  10331 + };
  10332 + }
  10333 + } );
  10334 +}
  10335 +
  10336 +// Functions to create xhrs
  10337 +function createStandardXHR() {
  10338 + try {
  10339 + return new window.XMLHttpRequest();
  10340 + } catch ( e ) {}
  10341 +}
  10342 +
  10343 +function createActiveXHR() {
  10344 + try {
  10345 + return new window.ActiveXObject( "Microsoft.XMLHTTP" );
  10346 + } catch ( e ) {}
  10347 +}
  10348 +
  10349 +
  10350 +
  10351 +
  10352 +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
  10353 +jQuery.ajaxPrefilter( function( s ) {
  10354 + if ( s.crossDomain ) {
  10355 + s.contents.script = false;
  10356 + }
  10357 +} );
  10358 +
  10359 +// Install script dataType
  10360 +jQuery.ajaxSetup( {
  10361 + accepts: {
  10362 + script: "text/javascript, application/javascript, " +
  10363 + "application/ecmascript, application/x-ecmascript"
  10364 + },
  10365 + contents: {
  10366 + script: /\b(?:java|ecma)script\b/
  10367 + },
  10368 + converters: {
  10369 + "text script": function( text ) {
  10370 + jQuery.globalEval( text );
  10371 + return text;
  10372 + }
  10373 + }
  10374 +} );
  10375 +
  10376 +// Handle cache's special case and global
  10377 +jQuery.ajaxPrefilter( "script", function( s ) {
  10378 + if ( s.cache === undefined ) {
  10379 + s.cache = false;
  10380 + }
  10381 + if ( s.crossDomain ) {
  10382 + s.type = "GET";
  10383 + s.global = false;
  10384 + }
  10385 +} );
  10386 +
  10387 +// Bind script tag hack transport
  10388 +jQuery.ajaxTransport( "script", function( s ) {
  10389 +
  10390 + // This transport only deals with cross domain requests
  10391 + if ( s.crossDomain ) {
  10392 +
  10393 + var script,
  10394 + head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
  10395 +
  10396 + return {
  10397 +
  10398 + send: function( _, callback ) {
  10399 +
  10400 + script = document.createElement( "script" );
  10401 +
  10402 + script.async = true;
  10403 +
  10404 + if ( s.scriptCharset ) {
  10405 + script.charset = s.scriptCharset;
  10406 + }
  10407 +
  10408 + script.src = s.url;
  10409 +
  10410 + // Attach handlers for all browsers
  10411 + script.onload = script.onreadystatechange = function( _, isAbort ) {
  10412 +
  10413 + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
  10414 +
  10415 + // Handle memory leak in IE
  10416 + script.onload = script.onreadystatechange = null;
  10417 +
  10418 + // Remove the script
  10419 + if ( script.parentNode ) {
  10420 + script.parentNode.removeChild( script );
  10421 + }
  10422 +
  10423 + // Dereference the script
  10424 + script = null;
  10425 +
  10426 + // Callback if not abort
  10427 + if ( !isAbort ) {
  10428 + callback( 200, "success" );
  10429 + }
  10430 + }
  10431 + };
  10432 +
  10433 + // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
  10434 + // Use native DOM manipulation to avoid our domManip AJAX trickery
  10435 + head.insertBefore( script, head.firstChild );
  10436 + },
  10437 +
  10438 + abort: function() {
  10439 + if ( script ) {
  10440 + script.onload( undefined, true );
  10441 + }
  10442 + }
  10443 + };
  10444 + }
  10445 +} );
  10446 +
  10447 +
  10448 +
  10449 +
  10450 +var oldCallbacks = [],
  10451 + rjsonp = /(=)\?(?=&|$)|\?\?/;
  10452 +
  10453 +// Default jsonp settings
  10454 +jQuery.ajaxSetup( {
  10455 + jsonp: "callback",
  10456 + jsonpCallback: function() {
  10457 + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
  10458 + this[ callback ] = true;
  10459 + return callback;
  10460 + }
  10461 +} );
  10462 +
  10463 +// Detect, normalize options and install callbacks for jsonp requests
  10464 +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  10465 +
  10466 + var callbackName, overwritten, responseContainer,
  10467 + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  10468 + "url" :
  10469 + typeof s.data === "string" &&
  10470 + ( s.contentType || "" )
  10471 + .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
  10472 + rjsonp.test( s.data ) && "data"
  10473 + );
  10474 +
  10475 + // Handle iff the expected data type is "jsonp" or we have a parameter to set
  10476 + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  10477 +
  10478 + // Get callback name, remembering preexisting value associated with it
  10479 + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  10480 + s.jsonpCallback() :
  10481 + s.jsonpCallback;
  10482 +
  10483 + // Insert callback into url or form data
  10484 + if ( jsonProp ) {
  10485 + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  10486 + } else if ( s.jsonp !== false ) {
  10487 + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  10488 + }
  10489 +
  10490 + // Use data converter to retrieve json after script execution
  10491 + s.converters[ "script json" ] = function() {
  10492 + if ( !responseContainer ) {
  10493 + jQuery.error( callbackName + " was not called" );
  10494 + }
  10495 + return responseContainer[ 0 ];
  10496 + };
  10497 +
  10498 + // force json dataType
  10499 + s.dataTypes[ 0 ] = "json";
  10500 +
  10501 + // Install callback
  10502 + overwritten = window[ callbackName ];
  10503 + window[ callbackName ] = function() {
  10504 + responseContainer = arguments;
  10505 + };
  10506 +
  10507 + // Clean-up function (fires after converters)
  10508 + jqXHR.always( function() {
  10509 +
  10510 + // If previous value didn't exist - remove it
  10511 + if ( overwritten === undefined ) {
  10512 + jQuery( window ).removeProp( callbackName );
  10513 +
  10514 + // Otherwise restore preexisting value
  10515 + } else {
  10516 + window[ callbackName ] = overwritten;
  10517 + }
  10518 +
  10519 + // Save back as free
  10520 + if ( s[ callbackName ] ) {
  10521 +
  10522 + // make sure that re-using the options doesn't screw things around
  10523 + s.jsonpCallback = originalSettings.jsonpCallback;
  10524 +
  10525 + // save the callback name for future use
  10526 + oldCallbacks.push( callbackName );
  10527 + }
  10528 +
  10529 + // Call if it was a function and we have a response
  10530 + if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  10531 + overwritten( responseContainer[ 0 ] );
  10532 + }
  10533 +
  10534 + responseContainer = overwritten = undefined;
  10535 + } );
  10536 +
  10537 + // Delegate to script
  10538 + return "script";
  10539 + }
  10540 +} );
  10541 +
  10542 +
  10543 +
  10544 +
  10545 +// Support: Safari 8+
  10546 +// In Safari 8 documents created via document.implementation.createHTMLDocument
  10547 +// collapse sibling forms: the second one becomes a child of the first one.
  10548 +// Because of that, this security measure has to be disabled in Safari 8.
  10549 +// https://bugs.webkit.org/show_bug.cgi?id=137337
  10550 +support.createHTMLDocument = ( function() {
  10551 + if ( !document.implementation.createHTMLDocument ) {
  10552 + return false;
  10553 + }
  10554 + var doc = document.implementation.createHTMLDocument( "" );
  10555 + doc.body.innerHTML = "<form></form><form></form>";
  10556 + return doc.body.childNodes.length === 2;
  10557 +} )();
  10558 +
  10559 +
  10560 +// data: string of html
  10561 +// context (optional): If specified, the fragment will be created in this context,
  10562 +// defaults to document
  10563 +// keepScripts (optional): If true, will include scripts passed in the html string
  10564 +jQuery.parseHTML = function( data, context, keepScripts ) {
  10565 + if ( !data || typeof data !== "string" ) {
  10566 + return null;
  10567 + }
  10568 + if ( typeof context === "boolean" ) {
  10569 + keepScripts = context;
  10570 + context = false;
  10571 + }
  10572 +
  10573 + // document.implementation stops scripts or inline event handlers from
  10574 + // being executed immediately
  10575 + context = context || ( support.createHTMLDocument ?
  10576 + document.implementation.createHTMLDocument( "" ) :
  10577 + document );
  10578 +
  10579 + var parsed = rsingleTag.exec( data ),
  10580 + scripts = !keepScripts && [];
  10581 +
  10582 + // Single tag
  10583 + if ( parsed ) {
  10584 + return [ context.createElement( parsed[ 1 ] ) ];
  10585 + }
  10586 +
  10587 + parsed = buildFragment( [ data ], context, scripts );
  10588 +
  10589 + if ( scripts && scripts.length ) {
  10590 + jQuery( scripts ).remove();
  10591 + }
  10592 +
  10593 + return jQuery.merge( [], parsed.childNodes );
  10594 +};
  10595 +
  10596 +
  10597 +// Keep a copy of the old load method
  10598 +var _load = jQuery.fn.load;
  10599 +
  10600 +/**
  10601 + * Load a url into a page
  10602 + */
  10603 +jQuery.fn.load = function( url, params, callback ) {
  10604 + if ( typeof url !== "string" && _load ) {
  10605 + return _load.apply( this, arguments );
  10606 + }
  10607 +
  10608 + var selector, type, response,
  10609 + self = this,
  10610 + off = url.indexOf( " " );
  10611 +
  10612 + if ( off > -1 ) {
  10613 + selector = jQuery.trim( url.slice( off, url.length ) );
  10614 + url = url.slice( 0, off );
  10615 + }
  10616 +
  10617 + // If it's a function
  10618 + if ( jQuery.isFunction( params ) ) {
  10619 +
  10620 + // We assume that it's the callback
  10621 + callback = params;
  10622 + params = undefined;
  10623 +
  10624 + // Otherwise, build a param string
  10625 + } else if ( params && typeof params === "object" ) {
  10626 + type = "POST";
  10627 + }
  10628 +
  10629 + // If we have elements to modify, make the request
  10630 + if ( self.length > 0 ) {
  10631 + jQuery.ajax( {
  10632 + url: url,
  10633 +
  10634 + // If "type" variable is undefined, then "GET" method will be used.
  10635 + // Make value of this field explicit since
  10636 + // user can override it through ajaxSetup method
  10637 + type: type || "GET",
  10638 + dataType: "html",
  10639 + data: params
  10640 + } ).done( function( responseText ) {
  10641 +
  10642 + // Save response for use in complete callback
  10643 + response = arguments;
  10644 +
  10645 + self.html( selector ?
  10646 +
  10647 + // If a selector was specified, locate the right elements in a dummy div
  10648 + // Exclude scripts to avoid IE 'Permission Denied' errors
  10649 + jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
  10650 +
  10651 + // Otherwise use the full result
  10652 + responseText );
  10653 +
  10654 + // If the request succeeds, this function gets "data", "status", "jqXHR"
  10655 + // but they are ignored because response was set above.
  10656 + // If it fails, this function gets "jqXHR", "status", "error"
  10657 + } ).always( callback && function( jqXHR, status ) {
  10658 + self.each( function() {
  10659 + callback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] );
  10660 + } );
  10661 + } );
  10662 + }
  10663 +
  10664 + return this;
  10665 +};
  10666 +
  10667 +
  10668 +
  10669 +
  10670 +// Attach a bunch of functions for handling common AJAX events
  10671 +jQuery.each( [
  10672 + "ajaxStart",
  10673 + "ajaxStop",
  10674 + "ajaxComplete",
  10675 + "ajaxError",
  10676 + "ajaxSuccess",
  10677 + "ajaxSend"
  10678 +], function( i, type ) {
  10679 + jQuery.fn[ type ] = function( fn ) {
  10680 + return this.on( type, fn );
  10681 + };
  10682 +} );
  10683 +
  10684 +
  10685 +
  10686 +
  10687 +jQuery.expr.filters.animated = function( elem ) {
  10688 + return jQuery.grep( jQuery.timers, function( fn ) {
  10689 + return elem === fn.elem;
  10690 + } ).length;
  10691 +};
  10692 +
  10693 +
  10694 +
  10695 +
  10696 +
  10697 +/**
  10698 + * Gets a window from an element
  10699 + */
  10700 +function getWindow( elem ) {
  10701 + return jQuery.isWindow( elem ) ?
  10702 + elem :
  10703 + elem.nodeType === 9 ?
  10704 + elem.defaultView || elem.parentWindow :
  10705 + false;
  10706 +}
  10707 +
  10708 +jQuery.offset = {
  10709 + setOffset: function( elem, options, i ) {
  10710 + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  10711 + position = jQuery.css( elem, "position" ),
  10712 + curElem = jQuery( elem ),
  10713 + props = {};
  10714 +
  10715 + // set position first, in-case top/left are set even on static elem
  10716 + if ( position === "static" ) {
  10717 + elem.style.position = "relative";
  10718 + }
  10719 +
  10720 + curOffset = curElem.offset();
  10721 + curCSSTop = jQuery.css( elem, "top" );
  10722 + curCSSLeft = jQuery.css( elem, "left" );
  10723 + calculatePosition = ( position === "absolute" || position === "fixed" ) &&
  10724 + jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
  10725 +
  10726 + // need to be able to calculate position if either top or left
  10727 + // is auto and position is either absolute or fixed
  10728 + if ( calculatePosition ) {
  10729 + curPosition = curElem.position();
  10730 + curTop = curPosition.top;
  10731 + curLeft = curPosition.left;
  10732 + } else {
  10733 + curTop = parseFloat( curCSSTop ) || 0;
  10734 + curLeft = parseFloat( curCSSLeft ) || 0;
  10735 + }
  10736 +
  10737 + if ( jQuery.isFunction( options ) ) {
  10738 +
  10739 + // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
  10740 + options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
  10741 + }
  10742 +
  10743 + if ( options.top != null ) {
  10744 + props.top = ( options.top - curOffset.top ) + curTop;
  10745 + }
  10746 + if ( options.left != null ) {
  10747 + props.left = ( options.left - curOffset.left ) + curLeft;
  10748 + }
  10749 +
  10750 + if ( "using" in options ) {
  10751 + options.using.call( elem, props );
  10752 + } else {
  10753 + curElem.css( props );
  10754 + }
  10755 + }
  10756 +};
  10757 +
  10758 +jQuery.fn.extend( {
  10759 + offset: function( options ) {
  10760 + if ( arguments.length ) {
  10761 + return options === undefined ?
  10762 + this :
  10763 + this.each( function( i ) {
  10764 + jQuery.offset.setOffset( this, options, i );
  10765 + } );
  10766 + }
  10767 +
  10768 + var docElem, win,
  10769 + box = { top: 0, left: 0 },
  10770 + elem = this[ 0 ],
  10771 + doc = elem && elem.ownerDocument;
  10772 +
  10773 + if ( !doc ) {
  10774 + return;
  10775 + }
  10776 +
  10777 + docElem = doc.documentElement;
  10778 +
  10779 + // Make sure it's not a disconnected DOM node
  10780 + if ( !jQuery.contains( docElem, elem ) ) {
  10781 + return box;
  10782 + }
  10783 +
  10784 + // If we don't have gBCR, just use 0,0 rather than error
  10785 + // BlackBerry 5, iOS 3 (original iPhone)
  10786 + if ( typeof elem.getBoundingClientRect !== "undefined" ) {
  10787 + box = elem.getBoundingClientRect();
  10788 + }
  10789 + win = getWindow( doc );
  10790 + return {
  10791 + top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
  10792 + left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
  10793 + };
  10794 + },
  10795 +
  10796 + position: function() {
  10797 + if ( !this[ 0 ] ) {
  10798 + return;
  10799 + }
  10800 +
  10801 + var offsetParent, offset,
  10802 + parentOffset = { top: 0, left: 0 },
  10803 + elem = this[ 0 ];
  10804 +
  10805 + // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
  10806 + // because it is its only offset parent
  10807 + if ( jQuery.css( elem, "position" ) === "fixed" ) {
  10808 +
  10809 + // we assume that getBoundingClientRect is available when computed position is fixed
  10810 + offset = elem.getBoundingClientRect();
  10811 + } else {
  10812 +
  10813 + // Get *real* offsetParent
  10814 + offsetParent = this.offsetParent();
  10815 +
  10816 + // Get correct offsets
  10817 + offset = this.offset();
  10818 + if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
  10819 + parentOffset = offsetParent.offset();
  10820 + }
  10821 +
  10822 + // Add offsetParent borders
  10823 + parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
  10824 + parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
  10825 + }
  10826 +
  10827 + // Subtract parent offsets and element margins
  10828 + // note: when an element has margin: auto the offsetLeft and marginLeft
  10829 + // are the same in Safari causing offset.left to incorrectly be 0
  10830 + return {
  10831 + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  10832 + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  10833 + };
  10834 + },
  10835 +
  10836 + offsetParent: function() {
  10837 + return this.map( function() {
  10838 + var offsetParent = this.offsetParent;
  10839 +
  10840 + while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
  10841 + jQuery.css( offsetParent, "position" ) === "static" ) ) {
  10842 + offsetParent = offsetParent.offsetParent;
  10843 + }
  10844 + return offsetParent || documentElement;
  10845 + } );
  10846 + }
  10847 +} );
  10848 +
  10849 +// Create scrollLeft and scrollTop methods
  10850 +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  10851 + var top = /Y/.test( prop );
  10852 +
  10853 + jQuery.fn[ method ] = function( val ) {
  10854 + return access( this, function( elem, method, val ) {
  10855 + var win = getWindow( elem );
  10856 +
  10857 + if ( val === undefined ) {
  10858 + return win ? ( prop in win ) ? win[ prop ] :
  10859 + win.document.documentElement[ method ] :
  10860 + elem[ method ];
  10861 + }
  10862 +
  10863 + if ( win ) {
  10864 + win.scrollTo(
  10865 + !top ? val : jQuery( win ).scrollLeft(),
  10866 + top ? val : jQuery( win ).scrollTop()
  10867 + );
  10868 +
  10869 + } else {
  10870 + elem[ method ] = val;
  10871 + }
  10872 + }, method, val, arguments.length, null );
  10873 + };
  10874 +} );
  10875 +
  10876 +// Support: Safari<7-8+, Chrome<37-44+
  10877 +// Add the top/left cssHooks using jQuery.fn.position
  10878 +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  10879 +// getComputedStyle returns percent when specified for top/left/bottom/right
  10880 +// rather than make the css module depend on the offset module, we just check for it here
  10881 +jQuery.each( [ "top", "left" ], function( i, prop ) {
  10882 + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
  10883 + function( elem, computed ) {
  10884 + if ( computed ) {
  10885 + computed = curCSS( elem, prop );
  10886 +
  10887 + // if curCSS returns percentage, fallback to offset
  10888 + return rnumnonpx.test( computed ) ?
  10889 + jQuery( elem ).position()[ prop ] + "px" :
  10890 + computed;
  10891 + }
  10892 + }
  10893 + );
  10894 +} );
  10895 +
  10896 +
  10897 +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  10898 +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  10899 + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
  10900 + function( defaultExtra, funcName ) {
  10901 +
  10902 + // margin is only for outerHeight, outerWidth
  10903 + jQuery.fn[ funcName ] = function( margin, value ) {
  10904 + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  10905 + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  10906 +
  10907 + return access( this, function( elem, type, value ) {
  10908 + var doc;
  10909 +
  10910 + if ( jQuery.isWindow( elem ) ) {
  10911 +
  10912 + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
  10913 + // isn't a whole lot we can do. See pull request at this URL for discussion:
  10914 + // https://github.com/jquery/jquery/pull/764
  10915 + return elem.document.documentElement[ "client" + name ];
  10916 + }
  10917 +
  10918 + // Get document width or height
  10919 + if ( elem.nodeType === 9 ) {
  10920 + doc = elem.documentElement;
  10921 +
  10922 + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  10923 + // whichever is greatest
  10924 + // unfortunately, this causes bug #3838 in IE6/8 only,
  10925 + // but there is currently no good, small way to fix it.
  10926 + return Math.max(
  10927 + elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  10928 + elem.body[ "offset" + name ], doc[ "offset" + name ],
  10929 + doc[ "client" + name ]
  10930 + );
  10931 + }
  10932 +
  10933 + return value === undefined ?
  10934 +
  10935 + // Get width or height on the element, requesting but not forcing parseFloat
  10936 + jQuery.css( elem, type, extra ) :
  10937 +
  10938 + // Set width or height on the element
  10939 + jQuery.style( elem, type, value, extra );
  10940 + }, type, chainable ? margin : undefined, chainable, null );
  10941 + };
  10942 + } );
  10943 +} );
  10944 +
  10945 +
  10946 +jQuery.fn.extend( {
  10947 +
  10948 + bind: function( types, data, fn ) {
  10949 + return this.on( types, null, data, fn );
  10950 + },
  10951 + unbind: function( types, fn ) {
  10952 + return this.off( types, null, fn );
  10953 + },
  10954 +
  10955 + delegate: function( selector, types, data, fn ) {
  10956 + return this.on( types, selector, data, fn );
  10957 + },
  10958 + undelegate: function( selector, types, fn ) {
  10959 +
  10960 + // ( namespace ) or ( selector, types [, fn] )
  10961 + return arguments.length === 1 ?
  10962 + this.off( selector, "**" ) :
  10963 + this.off( types, selector || "**", fn );
  10964 + }
  10965 +} );
  10966 +
  10967 +// The number of elements contained in the matched element set
  10968 +jQuery.fn.size = function() {
  10969 + return this.length;
  10970 +};
  10971 +
  10972 +jQuery.fn.andSelf = jQuery.fn.addBack;
  10973 +
  10974 +
  10975 +
  10976 +
  10977 +// Register as a named AMD module, since jQuery can be concatenated with other
  10978 +// files that may use define, but not via a proper concatenation script that
  10979 +// understands anonymous AMD modules. A named AMD is safest and most robust
  10980 +// way to register. Lowercase jquery is used because AMD module names are
  10981 +// derived from file names, and jQuery is normally delivered in a lowercase
  10982 +// file name. Do this after creating the global so that if an AMD module wants
  10983 +// to call noConflict to hide this version of jQuery, it will work.
  10984 +
  10985 +// Note that for maximum portability, libraries that are not jQuery should
  10986 +// declare themselves as anonymous modules, and avoid setting a global if an
  10987 +// AMD loader is present. jQuery is a special case. For more information, see
  10988 +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
  10989 +
  10990 +if ( typeof define === "function" && define.amd ) {
  10991 + define( "jquery", [], function() {
  10992 + return jQuery;
  10993 + } );
  10994 +}
  10995 +
  10996 +
  10997 +
  10998 +var
  10999 +
  11000 + // Map over jQuery in case of overwrite
  11001 + _jQuery = window.jQuery,
  11002 +
  11003 + // Map over the $ in case of overwrite
  11004 + _$ = window.$;
  11005 +
  11006 +jQuery.noConflict = function( deep ) {
  11007 + if ( window.$ === jQuery ) {
  11008 + window.$ = _$;
  11009 + }
  11010 +
  11011 + if ( deep && window.jQuery === jQuery ) {
  11012 + window.jQuery = _jQuery;
  11013 + }
  11014 +
  11015 + return jQuery;
  11016 +};
  11017 +
  11018 +// Expose jQuery and $ identifiers, even in
  11019 +// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  11020 +// and CommonJS for browser emulators (#13566)
  11021 +if ( !noGlobal ) {
  11022 + window.jQuery = window.$ = jQuery;
  11023 +}
  11024 +
  11025 +return jQuery;
  11026 +}));
... ...
lib/md5.js 0 → 100644
  1 +++ a/lib/md5.js
  1 +/*
  2 + * JavaScript MD5
  3 + * https://github.com/blueimp/JavaScript-MD5
  4 + *
  5 + * Copyright 2011, Sebastian Tschan
  6 + * https://blueimp.net
  7 + *
  8 + * Licensed under the MIT license:
  9 + * http://www.opensource.org/licenses/MIT
  10 + *
  11 + * Based on
  12 + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
  13 + * Digest Algorithm, as defined in RFC 1321.
  14 + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
  15 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  16 + * Distributed under the BSD License
  17 + * See http://pajhome.org.uk/crypt/md5 for more info.
  18 + */
  19 +
  20 +/*global unescape, define, module */
  21 +
  22 +;(function ($) {
  23 + 'use strict'
  24 +
  25 + /*
  26 + * Add integers, wrapping at 2^32. This uses 16-bit operations internally
  27 + * to work around bugs in some JS interpreters.
  28 + */
  29 + function safe_add (x, y) {
  30 + var lsw = (x & 0xFFFF) + (y & 0xFFFF)
  31 + var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
  32 + return (msw << 16) | (lsw & 0xFFFF)
  33 + }
  34 +
  35 + /*
  36 + * Bitwise rotate a 32-bit number to the left.
  37 + */
  38 + function bit_rol (num, cnt) {
  39 + return (num << cnt) | (num >>> (32 - cnt))
  40 + }
  41 +
  42 + /*
  43 + * These functions implement the four basic operations the algorithm uses.
  44 + */
  45 + function md5_cmn (q, a, b, x, s, t) {
  46 + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
  47 + }
  48 + function md5_ff (a, b, c, d, x, s, t) {
  49 + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)
  50 + }
  51 + function md5_gg (a, b, c, d, x, s, t) {
  52 + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)
  53 + }
  54 + function md5_hh (a, b, c, d, x, s, t) {
  55 + return md5_cmn(b ^ c ^ d, a, b, x, s, t)
  56 + }
  57 + function md5_ii (a, b, c, d, x, s, t) {
  58 + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t)
  59 + }
  60 +
  61 + /*
  62 + * Calculate the MD5 of an array of little-endian words, and a bit length.
  63 + */
  64 + function binl_md5 (x, len) {
  65 + /* append padding */
  66 + x[len >> 5] |= 0x80 << (len % 32)
  67 + x[(((len + 64) >>> 9) << 4) + 14] = len
  68 +
  69 + var i
  70 + var olda
  71 + var oldb
  72 + var oldc
  73 + var oldd
  74 + var a = 1732584193
  75 + var b = -271733879
  76 + var c = -1732584194
  77 + var d = 271733878
  78 +
  79 + for (i = 0; i < x.length; i += 16) {
  80 + olda = a
  81 + oldb = b
  82 + oldc = c
  83 + oldd = d
  84 +
  85 + a = md5_ff(a, b, c, d, x[i], 7, -680876936)
  86 + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586)
  87 + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819)
  88 + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330)
  89 + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897)
  90 + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426)
  91 + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341)
  92 + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983)
  93 + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416)
  94 + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417)
  95 + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063)
  96 + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162)
  97 + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682)
  98 + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101)
  99 + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290)
  100 + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329)
  101 +
  102 + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510)
  103 + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632)
  104 + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713)
  105 + b = md5_gg(b, c, d, a, x[i], 20, -373897302)
  106 + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691)
  107 + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083)
  108 + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335)
  109 + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848)
  110 + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438)
  111 + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690)
  112 + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961)
  113 + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501)
  114 + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467)
  115 + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784)
  116 + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473)
  117 + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734)
  118 +
  119 + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558)
  120 + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463)
  121 + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562)
  122 + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556)
  123 + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060)
  124 + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353)
  125 + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632)
  126 + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640)
  127 + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174)
  128 + d = md5_hh(d, a, b, c, x[i], 11, -358537222)
  129 + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979)
  130 + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189)
  131 + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487)
  132 + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835)
  133 + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520)
  134 + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651)
  135 +
  136 + a = md5_ii(a, b, c, d, x[i], 6, -198630844)
  137 + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415)
  138 + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905)
  139 + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055)
  140 + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571)
  141 + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606)
  142 + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523)
  143 + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799)
  144 + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359)
  145 + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744)
  146 + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380)
  147 + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649)
  148 + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070)
  149 + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379)
  150 + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259)
  151 + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551)
  152 +
  153 + a = safe_add(a, olda)
  154 + b = safe_add(b, oldb)
  155 + c = safe_add(c, oldc)
  156 + d = safe_add(d, oldd)
  157 + }
  158 + return [a, b, c, d]
  159 + }
  160 +
  161 + /*
  162 + * Convert an array of little-endian words to a string
  163 + */
  164 + function binl2rstr (input) {
  165 + var i
  166 + var output = ''
  167 + for (i = 0; i < input.length * 32; i += 8) {
  168 + output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF)
  169 + }
  170 + return output
  171 + }
  172 +
  173 + /*
  174 + * Convert a raw string to an array of little-endian words
  175 + * Characters >255 have their high-byte silently ignored.
  176 + */
  177 + function rstr2binl (input) {
  178 + var i
  179 + var output = []
  180 + output[(input.length >> 2) - 1] = undefined
  181 + for (i = 0; i < output.length; i += 1) {
  182 + output[i] = 0
  183 + }
  184 + for (i = 0; i < input.length * 8; i += 8) {
  185 + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32)
  186 + }
  187 + return output
  188 + }
  189 +
  190 + /*
  191 + * Calculate the MD5 of a raw string
  192 + */
  193 + function rstr_md5 (s) {
  194 + return binl2rstr(binl_md5(rstr2binl(s), s.length * 8))
  195 + }
  196 +
  197 + /*
  198 + * Calculate the HMAC-MD5, of a key and some data (raw strings)
  199 + */
  200 + function rstr_hmac_md5 (key, data) {
  201 + var i
  202 + var bkey = rstr2binl(key)
  203 + var ipad = []
  204 + var opad = []
  205 + var hash
  206 + ipad[15] = opad[15] = undefined
  207 + if (bkey.length > 16) {
  208 + bkey = binl_md5(bkey, key.length * 8)
  209 + }
  210 + for (i = 0; i < 16; i += 1) {
  211 + ipad[i] = bkey[i] ^ 0x36363636
  212 + opad[i] = bkey[i] ^ 0x5C5C5C5C
  213 + }
  214 + hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8)
  215 + return binl2rstr(binl_md5(opad.concat(hash), 512 + 128))
  216 + }
  217 +
  218 + /*
  219 + * Convert a raw string to a hex string
  220 + */
  221 + function rstr2hex (input) {
  222 + var hex_tab = '0123456789abcdef'
  223 + var output = ''
  224 + var x
  225 + var i
  226 + for (i = 0; i < input.length; i += 1) {
  227 + x = input.charCodeAt(i)
  228 + output += hex_tab.charAt((x >>> 4) & 0x0F) +
  229 + hex_tab.charAt(x & 0x0F)
  230 + }
  231 + return output
  232 + }
  233 +
  234 + /*
  235 + * Encode a string as utf-8
  236 + */
  237 + function str2rstr_utf8 (input) {
  238 + return unescape(encodeURIComponent(input))
  239 + }
  240 +
  241 + /*
  242 + * Take string arguments and return either raw or hex encoded strings
  243 + */
  244 + function raw_md5 (s) {
  245 + return rstr_md5(str2rstr_utf8(s))
  246 + }
  247 + function hex_md5 (s) {
  248 + return rstr2hex(raw_md5(s))
  249 + }
  250 + function raw_hmac_md5 (k, d) {
  251 + return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))
  252 + }
  253 + function hex_hmac_md5 (k, d) {
  254 + return rstr2hex(raw_hmac_md5(k, d))
  255 + }
  256 +
  257 + function md5 (string, key, raw) {
  258 + if (!key) {
  259 + if (!raw) {
  260 + return hex_md5(string)
  261 + }
  262 + return raw_md5(string)
  263 + }
  264 + if (!raw) {
  265 + return hex_hmac_md5(key, string)
  266 + }
  267 + return raw_hmac_md5(key, string)
  268 + }
  269 +
  270 + if (typeof define === 'function' && define.amd) {
  271 + define(function () {
  272 + return md5
  273 + })
  274 + } else if (typeof module === 'object' && module.exports) {
  275 + module.exports = md5
  276 + } else {
  277 + $.md5 = md5
  278 + }
  279 +}(this))
0 280 \ No newline at end of file
... ...
lib/util.js 0 → 100644
  1 +++ a/lib/util.js
  1 +var util = window.util || {
  2 +
  3 + serialize: function(obj){
  4 + if(!obj){
  5 + return '';
  6 + }
  7 + if(obj instanceof Array){
  8 + return '';
  9 + }
  10 + var str = '';
  11 + for(var i in obj){
  12 + str += i + '=' + obj[i] + '&';
  13 + }
  14 + return str.slice(0, -1);
  15 + }
  16 +
  17 +};
0 18 \ No newline at end of file
... ...
manifest.json 0 → 100644
  1 +++ a/manifest.json
  1 +{
  2 + "manifest_version": 2,
  3 + "name": "VideoRecorder",
  4 + "version": "0.0.1",
  5 + "description": "Record video in pages for download",
  6 + "permissions": [
  7 + "tabs",
  8 + "downloads",
  9 + "webNavigation",
  10 + "http://*/*",
  11 + "https://*/*"
  12 + ],
  13 + "background": {
  14 + "scripts": [
  15 + "lib/jquery-1.12.1.js",
  16 + "lib/md5.js",
  17 + "lib/ffmpeg.min.js",
  18 + "background/background.js"
  19 + ]
  20 + },
  21 + "content_scripts": [
  22 + {
  23 + "matches": ["http://*/*", "https://*/*"],
  24 + "js": ["content/content.js"],
  25 + "run_at": "document_idle",
  26 + "all_frames": true
  27 + }
  28 + ],
  29 + "browser_action": {
  30 + "default_icon": "icon.png",
  31 + "default_title": "VideoRecorder",
  32 + "default_popup": "popup/popup.html"
  33 + }
  34 +}
0 35 \ No newline at end of file
... ...
package.json 0 → 100644
  1 +++ a/package.json
  1 +{
  2 + "name": "video-recorder",
  3 + "version": "1.0.0",
  4 + "description": "## 使用方法:",
  5 + "main": "index.js",
  6 + "directories": {
  7 + "lib": "lib"
  8 + },
  9 + "scripts": {
  10 + "test": "echo \"Error: no test specified\" && exit 1"
  11 + },
  12 + "keywords": [],
  13 + "author": "",
  14 + "license": "ISC"
  15 +}
... ...
popup/popup.css 0 → 100644
  1 +++ a/popup/popup.css
  1 +*{
  2 + margin: 0;
  3 + padding: 0;
  4 +}
  5 +body{
  6 + width: 240px;
  7 + height: 200px;
  8 + position: relative;
  9 +}
  10 +input,
  11 +button,
  12 +.msg,
  13 +.tit{
  14 + display: block;
  15 + width: 80%;
  16 + box-sizing: border-box;
  17 + margin: 20px auto;
  18 + padding: 5px 2px;
  19 + border-radius: 4px;
  20 + line-height: 16px;
  21 +}
  22 +input,
  23 +button{
  24 + outline: medium;
  25 + border: 1px solid #ddd;
  26 + background: #efefef;
  27 +}
  28 +button{
  29 + background: #55b131;
  30 + color: #fff;
  31 + cursor: pointer;
  32 + border-color: #469129;
  33 +}
  34 +.hide{
  35 + display: none;
  36 +}
  37 +.msg{
  38 + transition: opacity .2s linear;
  39 +}
  40 +.tit{
  41 + font-size: 14px;
  42 + color: #469129;
  43 +}
  44 +.bg{
  45 + position: absolute;
  46 + top: -10%;
  47 + left: -10%;
  48 + width: 120%;
  49 + height: 120%;
  50 + background-image: url('./icon.png');
  51 + background-size: cover;
  52 + background-position: center center;
  53 + opacity: 0.1;
  54 + z-index: -1;
  55 + -webkit-blur: filter(3px);
  56 +}
  57 +.login-box input,
  58 +.login-box button{
  59 + margin: 10px auto;
  60 +}
  61 +
... ...
popup/popup.html 0 → 100644
  1 +++ a/popup/popup.html
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <title>zoo-vocab</title>
  6 + <link rel="stylesheet" type="text/css" href="./popup.css">
  7 +</head>
  8 +<body>
  9 +
  10 + <div class="tit">111将生词添加到我的有道单词本</div>
  11 + <div class="login-box hide">
  12 + <div class="username"><input type="text" id="username" placeholder="请输入用户名" autofocus="true"></div>
  13 + <div class="password"><input type="password" id="password" placeholder="请输入密码"></div>
  14 + <div class="login-btn"><button id="login">登录</button></div>
  15 + </div>
  16 +
  17 + <div class="add-box hide">
  18 + <div class="vocab"><input id="vocab" type="text" placeholder="请输入想添加的单词" autofocus="true"></div>
  19 + <div class="save-btn"><button id="save">添加</button></div>
  20 + </div>
  21 +
  22 + <div class="msg" id="msg"></div>
  23 +
  24 + <div class="bg"></div>
  25 +
  26 +<script src="../lib/jquery-1.12.1.js"></script>
  27 +<script src="../lib/util.js"></script>
  28 +<script src="../lib/md5.js"></script>
  29 +<script src="./popup.js"></script>
  30 +</body>
  31 +</html>
0 32 \ No newline at end of file
... ...
popup/popup.js 0 → 100644
  1 +++ a/popup/popup.js
  1 +// 点击扩展图标后弹出的窗口
  2 +
  3 +var $msg = $('#msg').html('');
  4 +var $login = $('#login');
  5 +var $vocab = $('#vocab');
  6 +var $save = $('#save');
  7 +
  8 +//登录
  9 +function login(){
  10 + var username = $.trim($('#username').val());
  11 + var password = $.trim($('#password').val());
  12 + if(!username || !password){
  13 + return showMsg('用户名或密码不能为空~~~')
  14 + }
  15 + // 设置credentials: 'include'后会共享youdao.com下的cookie
  16 + fetch('https://logindict.youdao.com/login/acc/login', {
  17 + credentials: 'include',
  18 + method: 'post',
  19 + headers: {
  20 + 'Content-Type': 'application/x-www-form-urlencoded',
  21 + 'X-Requested-With': 'XMLHttpRequest'
  22 + },
  23 + body: util.serialize({
  24 + app: 'web',
  25 + tp: 'urstoken',
  26 + ru: 'http://dict.youdao.com',
  27 + product: 'DICT',
  28 + cf:3,
  29 + fr:1,
  30 + type: 1,
  31 + um: true,
  32 + username: username,
  33 + password: md5(password),
  34 + savelogin: 1
  35 + })
  36 + })
  37 + .then(function(res){
  38 + res.text().then(function(text){
  39 + if(text.indexOf('登出') > 0){
  40 + showAdd();
  41 + showMsg('登录成功!');
  42 + }
  43 + else{
  44 + showLogin();
  45 + showMsg('登录失败~~~');
  46 + }
  47 + });
  48 + });
  49 +};
  50 +
  51 +$login.on('click', login);
  52 +$('#username, #password').on('keydown', function(ev){
  53 + if(ev.keyCode === 13){
  54 + login();
  55 + }
  56 +});
  57 +
  58 +//显示登录
  59 +function showLogin(){
  60 + $('.login-box').removeClass('hide');
  61 + $('.add-box').addClass('hide');
  62 +};
  63 +
  64 +//显示添加单词
  65 +function showAdd(){
  66 + $('.login-box').addClass('hide');
  67 + $('.add-box').removeClass('hide');
  68 +};
  69 +
  70 +var timer = null;
  71 +function showMsg(msg){
  72 + $msg.html(msg).css('opacity', 1);
  73 + clearTimeout(timer);
  74 + timer = setTimeout(function(){
  75 + $msg.css('opacity', 0);
  76 + }, 1000);
  77 +};
  78 +
  79 +//添加单词
  80 +function addVocab(){
  81 + var vocab = $.trim($vocab.val());
  82 + if(!vocab){
  83 + return showMsg('请输入要添加的单词');
  84 + }
  85 + fetch('http://dict.youdao.com/wordbook/ajax?'+util.serialize({
  86 + action: 'addword',
  87 + date: new Date(),
  88 + len: 'eng',
  89 + q: vocab
  90 + }), {
  91 + credentials: 'include',
  92 + method: 'get'
  93 + })
  94 + .then(function(res){
  95 + res.json().then(function(ret){
  96 + if(ret.message === 'nouser'){
  97 + showMsg('请先登录~~~');
  98 + }
  99 + else if(ret.message === 'adddone'){
  100 + showMsg('添加成功!');
  101 + }
  102 + });
  103 + })
  104 + .catch(function(err){
  105 + showMsg(err);
  106 + });
  107 +};
  108 +
  109 +$save.on('click', addVocab);
  110 +$vocab.on('keydown', function(ev){
  111 + if(ev.keyCode === 13){
  112 + addVocab();
  113 + }
  114 +});
  115 +
  116 +
  117 +new Promise(function(resolve, reject){
  118 + //检测登录,通过访问生词本列表页,未登录用户会被重定向到登录
  119 + fetch('http://dict.youdao.com/wordbook/wordlist', {
  120 + credentials: 'include',
  121 + method: 'get'
  122 + })
  123 + .then(function(res){
  124 + res.text().then(function(text){
  125 + var isLogin = false;
  126 + //页面有登出二字,表示已登录,是不是很搞笑?哈哈
  127 + if(text.indexOf('登出') > 0){
  128 + isLogin = true;
  129 + }
  130 + else{
  131 + isLogin = false;
  132 + }
  133 + resolve(isLogin);
  134 + });
  135 + })
  136 +})
  137 +.then(function(isLogin){
  138 + if(isLogin){
  139 + showAdd();
  140 + }
  141 + //否则显示登录窗
  142 + else{
  143 + showLogin();
  144 + }
  145 +});
  146 +
... ...