PageSourceSearch

https://silencio.fi/assets/js/app.js?v=1647509972

js silencio.fi collected 2026-10-09 03:13:56 UTC 469,462 bytes, 13,841 lines download raw bytes

vendor: 3,606 bytes, lines 1-88
1/******/ (function(modules) { // webpackBootstrap
2/******/ 	// The module cache
3/******/ 	var installedModules = {};
4/******/
5/******/ 	// The require function
6/******/ 	function __webpack_require__(moduleId) {
7/******/
8/******/ 		// Check if module is in cache
9/******/ 		if(installedModules[moduleId]) {
10/******/ 			return installedModules[moduleId].exports;
11/******/ 		}
12/******/ 		// Create a new module (and put it into the cache)
13/******/ 		var module = installedModules[moduleId] = {
14/******/ 			i: moduleId,
15/******/ 			l: false,
16/******/ 			exports: {}
17/******/ 		};
18/******/
19/******/ 		// Execute the module function
20/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21/******/
22/******/ 		// Flag the module as loaded
23/******/ 		module.l = true;
24/******/
25/******/ 		// Return the exports of the module
26/******/ 		return module.exports;
27/******/ 	}
28/******/
29/******/
30/******/ 	// expose the modules object (__webpack_modules__)
31/******/ 	__webpack_require__.m = modules;
32/******/
33/******/ 	// expose the module cache
34/******/ 	__webpack_require__.c = installedModules;
35/******/
36/******/ 	// define getter function for harmony exports
37/******/ 	__webpack_require__.d = function(exports, name, getter) {
38/******/ 		if(!__webpack_require__.o(exports, name)) {
39/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
40/******/ 		}
41/******/ 	};
42/******/
43/******/ 	// define __esModule on exports
44/******/ 	__webpack_require__.r = function(exports) {
45/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
46/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
47/******/ 		}
48/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
49/******/ 	};
50/******/
51/******/ 	// create a fake namespace object
52/******/ 	// mode & 1: value is a module id, require it
53/******/ 	// mode & 2: merge all properties of value into the ns
54/******/ 	// mode & 4: return value when already ns object
55/******/ 	// mode & 8|1: behave like require
56/******/ 	__webpack_require__.t = function(value, mode) {
57/******/ 		if(mode & 1) value = __webpack_require__(value);
58/******/ 		if(mode & 8) return value;
59/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
60/******/ 		var ns = Object.create(null);
61/******/ 		__webpack_require__.r(ns);
62/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
63/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
64/******/ 		return ns;
65/******/ 	};
66/******/
67/******/ 	// getDefaultExport function for compatibility with non-harmony modules
68/******/ 	__webpack_require__.n = function(module) {
69/******/ 		var getter = module && module.__esModule ?
70/******/ 			function getDefault() { return module['default']; } :
71/******/ 			function getModuleExports() { return module; };
72/******/ 		__webpack_require__.d(getter, 'a', getter);
73/******/ 		return getter;
74/******/ 	};
75/******/
76/******/ 	// Object.prototype.hasOwnProperty.call
77/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
78/******/
79/******/ 	// __webpack_public_path__
80/******/ 	__webpack_require__.p = "";
81/******/
82/******/
83/******/ 	// Load entry module and return exports
84/******/ 	return __webpack_require__(__webpack_require__.s = "./js/app.js");
85/******/ })
86/************************************************************************/
87/******/ ({
88
89/***/ "./js/app.js":
90/*!*******************!*\
91  !*** ./js/app.js ***!
92  \*******************/
93/*! no exports provided */
94/***/ (function(module, __webpack_exports__, __webpack_require__) {
95
96"use strict";
97__webpack_require__.r(__webpack_exports__);
98/* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var _sub_silencio_anim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sub/silencio_anim */ "./js/sub/silencio_anim.js");
99"use scrict";
100
101global.$ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
102var MobileDetect = __webpack_require__(/*! mobile-detect */ "./node_modules/mobile-detect/mobile-detect.js");
103global.md = new MobileDetect(window.navigator.userAgent);
104var mainWidth;
105
106
107
108$(function(){
109
110  // window.anim = new silencio_anim();
111
112  vh();
113
114  let animX = (window.innerWidth * .5) - (window.innerWidth * .7);
115  let animY = (window.innerHeight * .5) - (window.innerWidth * .6);
116  $('.anim').css({
117    'transform' : 'translate3d('+animX+'px, '+animY+'px, 0)'
118  });
119
120  setTimeout(function(){
121    $('body').addClass('in');
122  },100);
123
124  $(window).on('load pageshow', function(){
125    setTimeout(function(){
126      $(window).trigger('scroll');
127      $('body').addClass('in');
128    },500);
129  });
130
131  $(window).on('beforeunload', function(){
132    setTimeout(function(){
133      $('body').removeClass('in');
134    },500);
135  });
136
137  binds();
138});
139
140
141function binds(){
142  $('.burger').click(function(e){
143    e.preventDefault();
144    $('html').toggleClass('nav-open');
145  });
146
147  if($('html').hasClass('home')) {
148    $('.nav--top a').unbind('click').click(function(e){
149      e.preventDefault();
150      var id = $(this).attr('href');
151      if(id!='##') {
152        $('html').animate({'scrollTop' : $(id).position().top }, 500);
153      } else {
154        $('html').animate({'scrollTop' : 0 }, 500);
155      }
156      $('html').removeClass('nav-open');
157    });
158  }
159
160  $(window).unbind('mousemove').mousemove(function(e){
161    let prcx = e.offsetX / window.innerWidth;
162    let prcy = e.offsetY / window.innerHeight;
163    console.log(prcx, prcy);
164  });
165
166  $(window).unbind('mousemove').mousemove(function(e){
167    let wx = $('.anim').outerWidth() / 2;
168    let wy = $('.anim').outerHeight() / 2;
169    let prcx = e.clientX / window.innerWidth;
170    let prcy = e.clientY / window.innerHeight;
171    let x = (window.innerWidth * prcx) - wx;
172    let y = (window.innerHeight * prcy) - wy;
173    let rotx = (.5-prcx) * -100;
174    let roty = (.5-prcy) * 100;
175    $('.anim').css({
176      'transform' : 'translate3d('+x+'px, '+y+'px, 0) rotateY('+rotx+'deg) rotateX('+roty+'deg)',
177    });
178  });
179  // $('.home-grid a, .close a').unbind('click').click(function(e){
180  //   if(!e.ctrlKey&&!e.altKey&&!e.shiftKey) {
181  //     e.preventDefault();
182  //     var href = $(this).attr('href');
183  //     $('body').removeClass('in');
184  //     setTimeout(function(){
185  //       window.location.href = href;
186  //     }, 300);
187  //   }
188  // });
189
190  var spinSpeed = 50;
191  $('.image--mouseovers').unbind('mouseenter mouseleave').mouseenter(function(){
192    $(this).children().each(function(idx){
193      var t = $(this);
194      setTimeout(function(){
195        $(t).siblings().css('opacity',0);
196        $(t).css('opacity',1);
197      }, spinSpeed*idx);
198    });
199  }).mouseleave(function(){
200    var len = $(this).children().length;
201    $(this).children().each(function(idx){
202      var t = $(this);
203      setTimeout(function(){
204        $(t).siblings().css('opacity',0);
205        $(t).css('opacity',1);
206        if(idx==0) {
207          setTimeout(function(){
208            $(t).css('opacity',0);
209          }, spinSpeed);
210        }
211      }, spinSpeed*(len-idx));
212    });
213  });
214}
215
216function vh(){
217  window.vh = window.innerHeight * 0.01;
218  document.documentElement.style.setProperty('--vh', `${window.vh}px`);
219}
220
221function resize(){
222  let newMainWidth = $('main').outerWidth();
223  if(newMainWidth!==mainWidth || !md.mobile()){
224    vh();
225  }
226  mainWidth = newMainWidth;
227}
228
229$(window).resize(function(){
230  resize();
231});
232
233/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
234
235/***/ }),
236
vendor: 38,800 bytes, lines 237-256
237/***/ "./js/sub/dat.gui.min.js":
238/*!*******************************!*\
239  !*** ./js/sub/dat.gui.min.js ***!
240  \*******************************/
241/*! no static exports found */
242/***/ (function(module, exports, __webpack_require__) {
243
244/**
245 * dat-gui JavaScript Controller Library
246 * http://code.google.com/p/dat-gui
247 *
248 * Copyright 2011 Data Arts Team, Google Creative Lab
249 *
250 * Licensed under the Apache License, Version 2.0 (the "License");
251 * you may not use this file except in compliance with the License.
252 * You may obtain a copy of the License at
253 *
254 * http://www.apache.org/licenses/LICENSE-2.0
255 */
256!function(e,t){ true?t(exports):undefined}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top,  #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML="&nbsp;",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t<e.__preset_select.length;t++)e.__preset_select[t].innerHTML=e.__preset_select[t].value;e.preset=this.value}),t.appendChild(s),t.appendChild(n),t.appendChild(o),t.appendChild(i),t.appendChild(r),ae){var a=document.getElementById("dg-local-explain"),l=document.getElementById("dg-local-storage");document.getElementById("dg-save-locally").style.display="block","true"===localStorage.getItem(m(e,"isLocal"))&&l.setAttribute("checked","checked"),b(e,a),X.bind(l,"change",function(){e.useLocalStorage=!e.useLocalStorage,b(e,a)})}var d=document.getElementById("dg-new-constructor");X.bind(d,"keydown",function(e){!e.metaKey||67!==e.which&&67!==e.keyCode||le.hide()}),X.bind(n,"click",function(){d.innerHTML=JSON.stringify(e.getSaveObject(),void 0,2),le.show(),d.focus(),d.select()}),X.bind(o,"click",function(){e.save()}),X.bind(i,"click",function(){var t=prompt("Enter a new preset name.");t&&e.saveAs(t)}),X.bind(r,"click",function(){e.revert()})}function y(e){function t(t){return t.preventDefault(),e.width+=i-t.clientX,e.onResize(),i=t.clientX,!1}function n(){X.removeClass(e.__closeButton,he.CLASS_DRAG),X.unbind(window,"mousemove",t),X.unbind(window,"mouseup",n)}function o(o){return o.preventDefault(),i=o.clientX,X.addClass(e.__closeButton,he.CLASS_DRAG),X.bind(window,"mousemove",t),X.bind(window,"mouseup",n),!1}var i=void 0;e.__resize_handle=document.createElement("div"),S.extend(e.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"}),X.bind(e.__resize_handle,"mousedown",o),X.bind(e.__closeButton,"mousedown",o),e.domElement.insertBefore(e.__resize_handle,e.domElement.firstElementChild)}function w(e,t){e.domElement.style.width=t+"px",e.__save_row&&e.autoPlace&&(e.__save_row.style.width=t+"px"),e.__closeButton&&(e.__closeButton.style.width=t+"px")}function x(e,t){var n={};return S.each(e.__rememberedObjects,function(o,i){var r={},s=e.__rememberedObjectIndecesToControllers[i];S.each(s,function(e,n){r[n]=t?e.initialValue:e.getValue()}),n[i]=r}),n}function E(e){for(var t=0;t<e.__preset_select.length;t++)e.__preset_select[t].value===e.preset&&(e.__preset_select.selectedIndex=t)}function C(e){0!==e.length&&oe.call(window,function(){C(e)}),S.each(e,function(e){e.updateDisplay()})}var A=Array.prototype.forEach,k=Array.prototype.slice,S={BREAK:{},extend:function(e){return this.each(k.call(arguments,1),function(t){(this.isObject(t)?Object.keys(t):[]).forEach(function(n){this.isUndefined(t[n])||(e[n]=t[n])}.bind(this))},this),e},defaults:function(e){return this.each(k.call(arguments,1),function(t){(this.isObject(t)?Object.keys(t):[]).forEach(function(n){this.isUndefined(e[n])&&(e[n]=t[n])}.bind(this))},this),e},compose:function(){var e=k.call(arguments);return function(){for(var t=k.call(arguments),n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o<i;o++)if(o in e&&t.call(n,e[o],o)===this.BREAK)return}else for(var r in e)if(t.call(n,e[r],r)===this.BREAK)return},defer:function(e){setTimeout(e,0)},debounce:function(e,t,n){var o=void 0;return function(){var i=this,r=arguments,s=n||!o;clearTimeout(o),o=setTimeout(function(){o=null,n||e.apply(i,r)},t),s&&e.apply(i,r)}},toArray:function(e){return e.toArray?e.toArray():k.call(e)},isUndefined:function(e){return void 0===e},isNull:function(e){return null===e},isNaN:function(e){function t(t){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}(function(e){return isNaN(e)}),isArray:Array.isArray||function(e){return e.constructor===Array},isObject:function(e){return e===Object(e)},isNumber:function(e){return e===e+0},isString:function(e){return e===e+""},isBoolean:function(e){return!1===e||!0===e},isFunction:function(e){return"[object Function]"===Object.prototype.toString.call(e)}},O=[{litmus:S.isString,conversions:{THREE_CHAR_HEX:{read:function(e){var t=e.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null!==t&&{space:"HEX",hex:parseInt("0x"+t[1].toString()+t[1].toString()+t[2].toString()+t[2].toString()+t[3].toString()+t[3].toString(),0)}},write:t},SIX_CHAR_HEX:{read:function(e){var t=e.match(/^#([A-F0-9]{6})$/i);return null!==t&&{space:"HEX",hex:parseInt("0x"+t[1].toString(),0)}},write:t},CSS_RGB:{read:function(e){var t=e.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);return null!==t&&{space:"RGB",r:parseFloat(t[1]),g:parseFloat(t[2]),b:parseFloat(t[3])}},write:t},CSS_RGBA:{read:function(e){var t=e.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);return null!==t&&{space:"RGB",r:parseFloat(t[1]),g:parseFloat(t[2]),b:parseFloat(t[3]),a:parseFloat(t[4])}},write:t}}},{litmus:S.isNumber,conversions:{HEX:{read:function(e){return{space:"HEX",hex:e,conversionName:"HEX"}},write:function(e){return e.hex}}}},{litmus:S.isArray,conversions:{RGB_ARRAY:{read:function(e){return 3===e.length&&{space:"RGB",r:e[0],g:e[1],b:e[2]}},write:function(e){return[e.r,e.g,e.b]}},RGBA_ARRAY:{read:function(e){return 4===e.length&&{space:"RGB",r:e[0],g:e[1],b:e[2],a:e[3]}},write:function(e){return[e.r,e.g,e.b,e.a]}}}},{litmus:S.isObject,conversions:{RGBA_OBJ:{read:function(e){return!!(S.isNumber(e.r)&&S.isNumber(e.g)&&S.isNumber(e.b)&&S.isNumber(e.a))&&{space:"RGB",r:e.r,g:e.g,b:e.b,a:e.a}},write:function(e){return{r:e.r,g:e.g,b:e.b,a:e.a}}},RGB_OBJ:{read:function(e){return!!(S.isNumber(e.r)&&S.isNumber(e.g)&&S.isNumber(e.b))&&{space:"RGB",r:e.r,g:e.g,b:e.b}},write:function(e){return{r:e.r,g:e.g,b:e.b}}},HSVA_OBJ:{read:function(e){return!!(S.isNumber(e.h)&&S.isNumber(e.s)&&S.isNumber(e.v)&&S.isNumber(e.a))&&{space:"HSV",h:e.h,s:e.s,v:e.v,a:e.a}},write:function(e){return{h:e.h,s:e.s,v:e.v,a:e.a}}},HSV_OBJ:{read:function(e){return!!(S.isNumber(e.h)&&S.isNumber(e.s)&&S.isNumber(e.v))&&{space:"HSV",h:e.h,s:e.s,v:e.v}},write:function(e){return{h:e.h,s:e.s,v:e.v}}}}}],T=void 0,L=void 0,R=function(){L=!1;var e=arguments.length>1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<<B)}},H="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},F=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},P=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),j=function e(t,n,o){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var r=Object.getPrototypeOf(t);return null===r?void 0:e(r,n,o)}if("value"in i)return i.value;var s=i.get;if(void 0!==s)return s.call(o)},D=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},V=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},I=function(){function e(){if(F(this,e),this.__state=R.apply(this,arguments),!1===this.__state)throw new Error("Failed to interpret color arguments");this.__state.a=this.__state.a||1}return P(e,[{key:"toString",value:function(){return t(this)}},{key:"toHexString",value:function(){return t(this,!0)}},{key:"toOriginal",value:function(){return this.__state.conversion.write(this)}}]),e}();I.recalculateRGB=function(e,t,n){if("HEX"===e.__state.space)e.__state[t]=N.component_from_hex(e.__state.hex,n);else{if("HSV"!==e.__state.space)throw new Error("Corrupted color state");S.extend(e.__state,N.hsv_to_rgb(e.__state.h,e.__state.s,e.__state.v))}},I.recalculateHSV=function(e){var t=N.rgb_to_hsv(e.r,e.g,e.b);S.extend(e.__state,{s:t.s,v:t.v}),S.isNaN(t.h)?S.isUndefined(e.__state.h)&&(e.__state.h=0):e.__state.h=t.h},I.COMPONENTS=["r","g","b","h","s","v","hex","a"],n(I.prototype,"r",2),n(I.prototype,"g",1),n(I.prototype,"b",0),o(I.prototype,"h"),o(I.prototype,"s"),o(I.prototype,"v"),Object.defineProperty(I.prototype,"a",{get:function(){return this.__state.a},set:function(e){this.__state.a=e}}),Object.defineProperty(I.prototype,"hex",{get:function(){return"HEX"!==!this.__state.space&&(this.__state.hex=N.rgb_to_hex(this.r,this.g,this.b)),this.__state.hex},set:function(e){this.__state.space="HEX",this.__state.hex=e}});var z=function(){function e(t,n){F(this,e),this.initialValue=t[n],this.domElement=document.createElement("div"),this.object=t,this.property=n,this.__onChange=void 0,this.__onFinishChange=void 0}return P(e,[{key:"onChange",value:function(e){return this.__onChange=e,this}},{key:"onFinishChange",value:function(e){return this.__onFinishChange=e,this}},{key:"setValue",value:function(e){return this.object[this.property]=e,this.__onChange&&this.__onChange.call(this,e),this.updateDisplay(),this}},{key:"getValue",value:function(){return this.object[this.property]}},{key:"updateDisplay",value:function(){return this}},{key:"isModified",value:function(){return this.initialValue!==this.getValue()}}]),e}(),M={HTMLEvents:["change"],MouseEvents:["click","mousemove","mousedown","mouseup","mouseover"],KeyboardEvents:["keydown"]},G={};S.each(M,function(e,t){S.each(e,function(e){G[e]=t})});var U=/(\d+(\.\d+)?)px/,X={makeSelectable:function(e,t){void 0!==e&&void 0!==e.style&&(e.onselectstart=t?function(){return!1}:function(){},e.style.MozUserSelect=t?"auto":"none",e.style.KhtmlUserSelect=t?"auto":"none",e.unselectable=t?"on":"off")},makeFullscreen:function(e,t,n){var o=n,i=t;S.isUndefined(i)&&(i=!0),S.isUndefined(o)&&(o=!0),e.style.position="absolute",i&&(e.style.left=0,e.style.right=0),o&&(e.style.top=0,e.style.bottom=0)},fakeEvent:function(e,t,n,o){var i=n||{},r=G[t];if(!r)throw new Error("Event type "+t+" not supported.");var s=document.createEvent(r);switch(r){case"MouseEvents":var a=i.x||i.clientX||0,l=i.y||i.clientY||0;s.initMouseEvent(t,i.bubbles||!1,i.cancelable||!0,window,i.clickCount||1,0,0,a,l,!1,!1,!1,!1,0,null);break;case"KeyboardEvents":var d=s.initKeyboardEvent||s.initKeyEvent;S.defaults(i,{cancelable:!0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,keyCode:void 0,charCode:void 0}),d(t,i.bubbles||!1,i.cancelable,window,i.ctrlKey,i.altKey,i.shiftKey,i.metaKey,i.keyCode,i.charCode);break;default:s.initEvent(t,i.bubbles||!1,i.cancelable||!0)}S.defaults(s,o),e.dispatchEvent(s)},bind:function(e,t,n,o){var i=o||!1;return e.addEventListener?e.addEventListener(t,n,i):e.attachEvent&&e.attachEvent("on"+t,n),X},unbind:function(e,t,n,o){var i=o||!1;return e.removeEventListener?e.removeEventListener(t,n,i):e.detachEvent&&e.detachEvent("on"+t,n),X},addClass:function(e,t){if(void 0===e.className)e.className=t;else if(e.className!==t){var n=e.className.split(/ +/);-1===n.indexOf(t)&&(n.push(t),e.className=n.join(" ").replace(/^\s+/,"").replace(/\s+$/,""))}return X},removeClass:function(e,t){if(t)if(e.className===t)e.removeAttribute("class");else{var n=e.className.split(/ +/),o=n.indexOf(t);-1!==o&&(n.splice(o,1),e.className=n.join(" "))}else e.className=void 0;return X},hasClass:function(e,t){return new RegExp("(?:^|\\s+)"+t+"(?:\\s+|$)").test(e.className)||!1},getWidth:function(e){var t=getComputedStyle(e);return i(t["border-left-width"])+i(t["border-right-width"])+i(t["padding-left"])+i(t["padding-right"])+i(t.width)},getHeight:function(e){var t=getComputedStyle(e);return i(t["border-top-width"])+i(t["border-bottom-width"])+i(t["padding-top"])+i(t["padding-bottom"])+i(t.height)},getOffset:function(e){var t=e,n={left:0,top:0};if(t.offsetParent)do{n.left+=t.offsetLeft,n.top+=t.offsetTop,t=t.offsetParent}while(t);return n},isActive:function(e){return e===document.activeElement&&(e.type||e.href)}},K=function(e){function t(e,n){F(this,t);var o=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),i=o;return o.__prev=o.getValue(),o.__checkbox=document.createElement("input"),o.__checkbox.setAttribute("type","checkbox"),X.bind(o.__checkbox,"change",function(){i.setValue(!i.__prev)},!1),o.domElement.appendChild(o.__checkbox),o.updateDisplay(),o}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,e);return this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),this.__prev=this.getValue(),n}},{key:"updateDisplay",value:function(){return!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0,this.__prev=!0):(this.__checkbox.checked=!1,this.__prev=!1),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Y=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=o,s=i;if(i.__select=document.createElement("select"),S.isArray(r)){var a={};S.each(r,function(e){a[e]=e}),r=a}return S.each(r,function(e,t){var n=document.createElement("option");n.innerHTML=t,n.setAttribute("value",e),s.__select.appendChild(n)}),i.updateDisplay(),X.bind(i.__select,"change",function(){var e=this.options[this.selectedIndex].value;s.setValue(e)}),i.domElement.appendChild(i.__select),i}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,e);return this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),n}},{key:"updateDisplay",value:function(){return X.isActive(this.__select)?this:(this.__select.value=this.getValue(),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this))}}]),t}(),J=function(e){function t(e,n){function o(){r.setValue(r.__input.value)}F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__input=document.createElement("input"),i.__input.setAttribute("type","text"),X.bind(i.__input,"keyup",o),X.bind(i.__input,"change",o),X.bind(i.__input,"blur",function(){r.__onFinishChange&&r.__onFinishChange.call(r,r.getValue())}),X.bind(i.__input,"keydown",function(e){13===e.keyCode&&this.blur()}),i.updateDisplay(),i.domElement.appendChild(i.__input),i}return D(t,z),P(t,[{key:"updateDisplay",value:function(){return X.isActive(this.__input)||(this.__input.value=this.getValue()),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),W=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),s=o||{};return i.__min=s.min,i.__max=s.max,i.__step=s.step,S.isUndefined(i.__step)?0===i.initialValue?i.__impliedStep=1:i.__impliedStep=Math.pow(10,Math.floor(Math.log(Math.abs(i.initialValue))/Math.LN10))/10:i.__impliedStep=i.__step,i.__precision=r(i.__impliedStep),i}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=e;return void 0!==this.__min&&n<this.__min?n=this.__min:void 0!==this.__max&&n>this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return D(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return D(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return D(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return D(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;
256font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(o.closed=!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.get
vendor: 5,470 bytes, lines 256-260
256SaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20<n?(X.addClass(e.domElement,he.CLASS_TOO_TALL),e.__ul.style.height=window.innerHeight-t-20+"px"):(X.removeClass(e.domElement,he.CLASS_TOO_TALL),e.__ul.style.height="auto")}e.__resize_handle&&S.defer(function(){e.__resize_handle.style.height=e.__ul.offsetHeight+"px"}),e.__closeButton&&(e.__closeButton.style.width=e.width+"px")},onResizeDebounced:S.debounce(function(){this.onResize()},50),remember:function(){if(S.isUndefined(le)&&((le=new ie).domElement.innerHTML='<div id="dg-save" class="dg dialogue">\n\n  Here\'s the new load parameter for your <code>GUI</code>\'s constructor:\n\n  <textarea id="dg-new-constructor"></textarea>\n\n  <div id="dg-save-locally">\n\n    <input id="dg-local-storage" type="checkbox"/> Automatically save\n    values to <code>localStorage</code> on exit.\n\n    <div id="dg-local-explain">The values saved to <code>localStorage</code> will\n      override those passed to <code>dat.GUI</code>\'s constructor. This makes it\n      easier to work incrementally, but <code>localStorage</code> is fragile,\n      and your friends may not see the same values you do.\n\n    </div>\n\n  </div>\n\n</div>'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})});
257
258
259/***/ }),
260
261/***/ "./js/sub/silencio_anim.js":
262/*!*********************************!*\
263  !*** ./js/sub/silencio_anim.js ***!
264  \*********************************/
265/*! no exports provided */
266/***/ (function(module, __webpack_exports__, __webpack_require__) {
267
268"use strict";
269__webpack_require__.r(__webpack_exports__);
270/* harmony import */ var _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dat.gui.min.js */ "./js/sub/dat.gui.min.js");
271/* harmony import */ var _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0__);
272
273
274'use strict';
275
276
277// Simulation code
278
279var canvas = document.getElementsByTagName('canvas')[0];
280resizeCanvas();
281
282var config = {
283
284    SIM_RESOLUTION: 512,
285    DYE_RESOLUTION: 512,
286    CAPTURE_RESOLUTION: 512,
287    DENSITY_DISSIPATION: 3.5,
288    VELOCITY_DISSIPATION: 2.5,
289    PRESSURE: 0.68,
290    PRESSURE_ITERATIONS: 10,
291    CURL: 0.5,
292    SPLAT_RADIUS: 2.8,
293    SPLAT_FORCE: 5000,
294    SHADING: false,
295    COLORFUL: false,
296    COLOR_UPDATE_SPEED: 20,
297    PAUSED: false,
298    // BACK_COLOR: { r: 0, g: 0, b: 0 },
299    BACK_COLOR: { r: 242, g: 242, b: 242 },
300    TRANSPARENT: false,
301    BLOOM: false,
302    BLOOM_ITERATIONS: 8,
303    BLOOM_RESOLUTION: 256,
304    BLOOM_INTENSITY: 0.8,
305    BLOOM_THRESHOLD: 0.6,
306    BLOOM_SOFT_KNEE: 0.7,
307    SUNRAYS: true,
308    SUNRAYS_RESOLUTION: 196,
309    SUNRAYS_WEIGHT: 0.7,
310    // SIM_RESOLUTION: 128,
311    // DYE_RESOLUTION: 1024,
312    // CAPTURE_RESOLUTION: 512,
313    // DENSITY_DISSIPATION: 3.4,
314    // VELOCITY_DISSIPATION: 4,
315    // PRESSURE: 0.8,
316    // PRESSURE_ITERATIONS: 20,
317    // CURL: 30,
318    // SPLAT_RADIUS: 1,
319    // SPLAT_FORCE: 6000,
320    // SHADING: false,
321    // COLORFUL: false,
322    // COLOR_UPDATE_SPEED: 1,
323    // PAUSED: false,
324    // BACK_COLOR: { r: 242, g: 242, b: 242 },
325    // TRANSPARENT: false,
326    // BLOOM: false,
327    // BLOOM_ITERATIONS: 8,
328    // BLOOM_RESOLUTION: 256,
329    // BLOOM_INTENSITY: 0.8,
330    // BLOOM_THRESHOLD: 0.6,
331    // BLOOM_SOFT_KNEE: 0.7,
332    // SUNRAYS: false,
333    // SUNRAYS_RESOLUTION: 196,
334    // SUNRAYS_WEIGHT: 1.0,
335}
336
337const THECOLOR = {
338  r: 255,
339  g: 89,
340  b: 91
341};
342
343  // r: .9,
344  // g: .349,
345  // b: .3568
346
347function pointerPrototype () {
348    this.id = -1;
349    this.texcoordX = 0.5; //scaleByPixelRatio(canvas.clientWidth);
350    this.texcoordY = 0.5; //scaleByPixelRatio(canvas.clientWidth);
351    this.prevTexcoordX = 0.5; //scaleByPixelRatio(canvas.clientWidth);
352    this.prevTexcoordY = 0.5; //scaleByPixelRatio(canvas.clientHeight);
353    this.deltaX = 0;
354    this.deltaY = 0;
355    this.down = true;
356    this.moved = true;
357    // this.color = [30, 0, 0];
358    this.color = THECOLOR;
359}
360
361var pointers = [];
362var splatStack = [];
363
364// setTimeout(function(){
365  pointers.push(new pointerPrototype());
366  console.log(pointers[0]);
367
368  window.pointer = pointers[0];
369// }, 200);
370
371window.posX = scaleByPixelRatio(canvas.clientWidth / 2);
372window.posY = scaleByPixelRatio(canvas.clientHeight / 2);
373updatePointerMoveData(pointers[0], window.posX, window.posY);
374console.log(window.posX, window.posY);
375
376var ref = getWebGLContext(canvas);
377var gl = ref.gl;
378var ext = ref.ext;
379
380// if (isMobile()) {
381//     config.DYE_RESOLUTION = 512;
382// }
383// if (!ext.supportLinearFiltering) {
384//     config.DYE_RESOLUTION = 512;
385//     config.SHADING = false;
386//     config.BLOOM = false;
387//     config.SUNRAYS = false;
388// }
389
390// startGUI();
391
392function getWebGLContext (canvas) {
393    var params = { alpha: true, depth: false, stencil: false, antialias: false, preserveDrawingBuffer: false };
394
395    var gl = canvas.getContext('webgl2', params);
396    var isWebGL2 = !!gl;
397    if (!isWebGL2)
398        { gl = canvas.getContext('webgl', params) || canvas.getContext('experimental-webgl', params); }
399
400    var halfFloat;
401    var supportLinearFiltering;
402    if (isWebGL2) {
403        gl.getExtension('EXT_color_buffer_float');
404        supportLinearFiltering = gl.getExtension('OES_texture_float_linear');
405    } else {
406        halfFloat = gl.getExtension('OES_texture_half_float');
407        supportLinearFiltering = gl.getExtension('OES_texture_half_float_linear');
408    }
409
410    gl.clearColor(0.0, 0.0, 0.0, 1.0);
411
412    var halfFloatTexType = isWebGL2 ? gl.HALF_FLOAT : halfFloat.HALF_FLOAT_OES;
413    var formatRGBA;
414    var formatRG;
415    var formatR;
416
417    if (isWebGL2)
418    {
419        formatRGBA = getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, halfFloatTexType);
420        formatRG = getSupportedFormat(gl, gl.RG16F, gl.RG, halfFloatTexType);
421        formatR = getSupportedFormat(gl, gl.R16F, gl.RED, halfFloatTexType);
422    }
423    else
424    {
425        formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
426        formatRG = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
427        formatR = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
428    }
429
430    // ga('send', 'event', isWebGL2 ? 'webgl2' : 'webgl', formatRGBA == null ? 'not supported' : 'supported');
431
432    return {
433        gl: gl,
434        ext: {
435            formatRGBA: formatRGBA,
436            formatRG: formatRG,
437            formatR: formatR,
438            halfFloatTexType: halfFloatTexType,
439            supportLinearFiltering: supportLinearFiltering
440        }
441    };
442}
443
444function getSupportedFormat (gl, internalFormat, format, type)
445{
446    if (!supportRenderTextureFormat(gl, internalFormat, format, type))
447    {
448        switch (internalFormat)
449        {
450            case gl.R16F:
451                return getSupportedFormat(gl, gl.RG16F, gl.RG, type);
452            case gl.RG16F:
453                return getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, type);
454            default:
455                return null;
456        }
457    }
458
459    return {
460        internalFormat: internalFormat,
461        format: format
462    }
463}
464
465function supportRenderTextureFormat (gl, internalFormat, format, type) {
466    var texture = gl.createTexture();
467    gl.bindTexture(gl.TEXTURE_2D, texture);
468    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
469    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
470    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
471    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
472    gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 4, 4, 0, format, type, null);
473
474    var fbo = gl.createFramebuffer();
475    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
476    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
477
478    var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
479    return status == gl.FRAMEBUFFER_COMPLETE;
480}
481
482function startGUI () {
483    var gui = new _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0___default.a.GUI({ width: 300 });
484    gui.add(config, 'DYE_RESOLUTION', { 'high': 1024, 'medium': 512, 'low': 256, 'very low': 128 }).name('quality').onFinishChange(initFramebuffers);
485    gui.add(config, 'SIM_RESOLUTION', { '32': 32, '64': 64, '128': 128, '256': 256 }).name('sim resolution').onFinishChange(initFramebuffers);
486    gui.add(config, 'DENSITY_DISSIPATION', 0, 4.0).name('density diffusion');
487    gui.add(config, 'VELOCITY_DISSIPATION', 0, 6.0).name('velocity diffusion');
488    gui.add(config, 'PRESSURE', 0.0, 1.0).name('pressure');
489    gui.add(config, 'CURL', 0, 50).name('vorticity').step(1);
490    gui.add(config, 'SPLAT_RADIUS', 0.01, 4.0).name('splat radius');
491    gui.add(config, 'SPLAT_FORCE', 50, 10000).name('splat force');
492    gui.add(config, 'SHADING').name('shading').onFinishChange(updateKeywords);
493    gui.add(config, 'COLORFUL').name('colorful');
494    gui.add(config, 'PAUSED').name('paused').listen();
495
496    gui.add({ fun: function () {
497        splatStack.push(parseInt(Math.random() * 20) + 5);
498    } }, 'fun').name('Random splats');
499
500    var bloomFolder = gui.addFolder('Bloom');
501    bloomFolder.add(config, 'BLOOM').name('enabled').onFinishChange(updateKeywords);
502    bloomFolder.add(config, 'BLOOM_INTENSITY', 0.1, 2.0).name('intensity');
503    bloomFolder.add(config, 'BLOOM_THRESHOLD', 0.0, 1.0).name('threshold');
504
505    var sunraysFolder = gui.addFolder('Sunrays');
506    sunraysFolder.add(config, 'SUNRAYS').name('enabled').onFinishChange(updateKeywords);
507    sunraysFolder.add(config, 'SUNRAYS_WEIGHT', 0.3, 1.0).name('weight');
508
509    var captureFolder = gui.addFolder('Capture');
510    captureFolder.addColor(config, 'BACK_COLOR').name('background color');
511    captureFolder.add(config, 'TRANSPARENT').name('transparent');
512    captureFolder.add({ fun: captureScreenshot }, 'fun').name('take screenshot');
513
514    gui.close();
515}
516
517function isMobile () {
518    return /Mobi|Android/i.test(navigator.userAgent);
519}
520
521function captureScreenshot () {
522    var res = getResolution(config.CAPTURE_RESOLUTION);
523    var target = createFBO(res.width, res.height, ext.formatRGBA.internalFormat, ext.formatRGBA.format, ext.halfFloatTexType, gl.NEAREST);
524    render(target);
525
526    var texture = framebufferToTexture(target);
527    texture = normalizeTexture(texture, target.width, target.height);
528
529    var captureCanvas = textureToCanvas(texture, target.width, target.height);
530    var datauri = captureCanvas.toDataURL();
531    downloadURI('fluid.png', datauri);
532    URL.revokeObjectURL(datauri);
533}
534
535function framebufferToTexture (target) {
536    gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo);
537    var length = target.width * target.height * 4;
538    var texture = new Float32Array(length);
539    gl.readPixels(0, 0, target.width, target.height, gl.RGBA, gl.FLOAT, texture);
540    return texture;
541}
542
543function normalizeTexture (texture, width, height) {
544    var result = new Uint8Array(texture.length);
545    var id = 0;
546    for (var i = height - 1; i >= 0; i--) {
547        for (var j = 0; j < width; j++) {
548            var nid = i * width * 4 + j * 4;
549            result[nid + 0] = clamp01(texture[id + 0]) * 255;
550            result[nid + 1] = clamp01(texture[id + 1]) * 255;
551            result[nid + 2] = clamp01(texture[id + 2]) * 255;
552            result[nid + 3] = clamp01(texture[id + 3]) * 255;
553            id += 4;
554        }
555    }
556    return result;
557}
558
559function clamp01 (input) {
560    return Math.min(Math.max(input, 0), 1);
561}
562
563function textureToCanvas (texture, width, height) {
564    var captureCanvas = document.createElement('canvas');
565    var ctx = captureCanvas.getContext('2d');
566    captureCanvas.width = width;
567    captureCanvas.height = height;
568
569    var imageData = ctx.createImageData(width, height);
570    imageData.data.set(texture);
571    ctx.putImageData(imageData, 0, 0);
572
573    return captureCanvas;
574}
575
576function downloadURI (filename, uri) {
577    var link = document.createElement('a');
578    link.download = filename;
579    link.href = uri;
580    document.body.appendChild(link);
581    link.click();
582    document.body.removeChild(link);
583}
584
585var Material = function Material (vertexShader, fragmentShaderSource) {
586    this.vertexShader = vertexShader;
587    this.fragmentShaderSource = fragmentShaderSource;
588    this.programs = [];
589    this.activeProgram = null;
590    this.uniforms = [];
591};
592
593Material.prototype.setKeywords = function setKeywords (keywords) {
594    var hash = 0;
595    for (var i = 0; i < keywords.length; i++)
596        { hash += hashCode(keywords[i]); }
597
598    var program = this.programs[hash];
599    if (program == null)
600    {
601        var fragmentShader = compileShader(gl.FRAGMENT_SHADER, this.fragmentShaderSource, keywords);
602        program = createProgram(this.vertexShader, fragmentShader);
603        this.programs[hash] = program;
604    }
605
606    if (program == this.activeProgram) { return; }
607
608    this.uniforms = getUniforms(program);
609    this.activeProgram = program;
610};
611
612Material.prototype.bind = function bind () {
613    gl.useProgram(this.activeProgram);
614};
615
616var Program = function Program (vertexShader, fragmentShader) {
617    this.uniforms = {};
618    this.program = createProgram(vertexShader, fragmentShader);
619    this.uniforms = getUniforms(this.program);
620};
621
622Program.prototype.bind = function bind () {
623    gl.useProgram(this.program);
624};
625
626function createProgram (vertexShader, fragmentShader) {
627    var program = gl.createProgram();
628    gl.attachShader(program, vertexShader);
629    gl.attachShader(program, fragmentShader);
630    gl.linkProgram(program);
631
632    if (!gl.getProgramParameter(program, gl.LINK_STATUS))
633        { throw gl.getProgramInfoLog(program); }
634
635    return program;
636}
637
638function getUniforms (program) {
639    var uniforms = [];
640    var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
641    for (var i = 0; i < uniformCount; i++) {
642        var uniformName = gl.getActiveUniform(program, i).name;
643        uniforms[uniformName] = gl.getUniformLocation(program, uniformName);
644    }
645    return uniforms;
646}
647
648function compileShader (type, source, keywords) {
649    source = addKeywords(source, keywords);
650
651    var shader = gl.createShader(type);
652    gl.shaderSource(shader, source);
653    gl.compileShader(shader);
654
655    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
656        { throw gl.getShaderInfoLog(shader); }
657
658    return shader;
659};
660
661function addKeywords (source, keywords) {
662    if (keywords == null) { return source; }
663    var keywordsString = '';
664    keywords.forEach(function (keyword) {
665        keywordsString += '#define ' + keyword + '\n';
666    });
667    return keywordsString + source;
668}
669
670var baseVertexShader = compileShader(gl.VERTEX_SHADER, `
671    precision highp float;
672
673    attribute vec2 aPosition;
674    varying vec2 vUv;
675    varying vec2 vL;
676    varying vec2 vR;
677    varying vec2 vT;
678    varying vec2 vB;
679    uniform vec2 texelSize;
680
681    void main () {
682        vUv = aPosition * 0.5 + 0.5;
683        vL = vUv - vec2(texelSize.x, 0.0);
684        vR = vUv + vec2(texelSize.x, 0.0);
685        vT = vUv + vec2(0.0, texelSize.y);
686        vB = vUv - vec2(0.0, texelSize.y);
687        gl_Position = vec4(aPosition, 0.0, 1.0);
688    }
689`);
690
691var blurVertexShader = compileShader(gl.VERTEX_SHADER, `
692    precision highp float;
693
694    attribute vec2 aPosition;
695    varying vec2 vUv;
696    varying vec2 vL;
697    varying vec2 vR;
698    uniform vec2 texelSize;
699
700    void main () {
701        vUv = aPosition * 0.5 + 0.5;
702        float offset = 1.33333333;
703        vL = vUv - texelSize * offset;
704        vR = vUv + texelSize * offset;
705        gl_Position = vec4(aPosition, 0.0, 1.0);
706    }
707`);
708
709var blurShader = compileShader(gl.FRAGMENT_SHADER, `
710    precision mediump float;
711    precision mediump sampler2D;
712
713    varying vec2 vUv;
714    varying vec2 vL;
715    varying vec2 vR;
716    uniform sampler2D uTexture;
717
718    void main () {
719        vec4 sum = texture2D(uTexture, vUv) * 0.29411764;
720        sum += texture2D(uTexture, vL) * 0.50294117;
721        sum += texture2D(uTexture, vR) * 0.50294117;
722        gl_FragColor = sum;
723    }
724`);
725
726var copyShader = compileShader(gl.FRAGMENT_SHADER, `
727    precision mediump float;
728    precision mediump sampler2D;
729
730    varying highp vec2 vUv;
731    uniform sampler2D uTexture;
732
733    void main () {
734        gl_FragColor = texture2D(uTexture, vUv);
735    }
736`);
737
738var clearShader = compileShader(gl.FRAGMENT_SHADER, `
739    precision mediump float;
740    precision mediump sampler2D;
741
742    varying highp vec2 vUv;
743    uniform sampler2D uTexture;
744    uniform float value;
745
746    void main () {
747        gl_FragColor = value * texture2D(uTexture, vUv);
748    }
749`);
750
751var colorShader = compileShader(gl.FRAGMENT_SHADER, `
752    precision mediump float;
753
754    uniform vec4 color;
755
756    void main () {
757        gl_FragColor = color;
758    }
759`);
760
761var checkerboardShader = compileShader(gl.FRAGMENT_SHADER, `
762    precision highp float;
763    precision highp sampler2D;
764
765    varying vec2 vUv;
766    uniform sampler2D uTexture;
767    uniform float aspectRatio;
768
769    #define SCALE 25.0
770
771    void main () {
772        vec2 uv = floor(vUv * SCALE * vec2(aspectRatio, 1.0));
773        float v = mod(uv.x + uv.y, 2.0);
774        v = v * 0.1 + 0.8;
775        gl_FragColor = vec4(vec3(v), 1.0);
776    }
777`);
778
779var displayShaderSource = `
780    precision highp float;
781    precision highp sampler2D;
782
783    varying vec2 vUv;
784    varying vec2 vL;
785    varying vec2 vR;
786    varying vec2 vT;
787    varying vec2 vB;
788    uniform sampler2D uTexture;
789    uniform sampler2D uBloom;
790    uniform sampler2D uSunrays;
791    uniform sampler2D uDithering;
792    uniform vec2 ditherScale;
793    uniform vec2 texelSize;
794
795    vec3 linearToGamma (vec3 color) {
796        color = max(color, vec3(0));
797        return max(1.055 * pow(color, vec3(0.416666667)) - 0.055, vec3(0));
798    }
799
800    void main () {
801        vec3 c = texture2D(uTexture, vUv).rgb;
802
803    #ifdef SHADING
804        vec3 lc = texture2D(uTexture, vL).rgb;
805        vec3 rc = texture2D(uTexture, vR).rgb;
806        vec3 tc = texture2D(uTexture, vT).rgb;
807        vec3 bc = texture2D(uTexture, vB).rgb;
808
809        float dx = length(rc) - length(lc);
810        float dy = length(tc) - length(bc);
811
812        vec3 n = normalize(vec3(dx, dy, length(texelSize)));
813        vec3 l = vec3(0.0, 0.0, 1.0);
814
815        float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
816        c *= diffuse;
817    #endif
818
819    #ifdef BLOOM
820        vec3 bloom = texture2D(uBloom, vUv).rgb;
821    #endif
822
823    #ifdef SUNRAYS
824        float sunrays = texture2D(uSunrays, vUv).r;
825        c *= sunrays;
826    #ifdef BLOOM
827        bloom *= sunrays;
828    #endif
829    #endif
830
831    #ifdef BLOOM
832        float noise = texture2D(uDithering, vUv * ditherScale).r;
833        noise = noise * 2.0 - 1.0;
834        bloom += noise / 255.0;
835        bloom = linearToGamma(bloom);
836        c += bloom;
837    #endif
838
839        float a = max(c.r, max(c.g, c.b));
840        gl_FragColor = vec4(c, a);
841    }
842`;
843
844var bloomPrefilterShader = compileShader(gl.FRAGMENT_SHADER, `
845    precision mediump float;
846    precision mediump sampler2D;
847
848    varying vec2 vUv;
849    uniform sampler2D uTexture;
850    uniform vec3 curve;
851    uniform float threshold;
852
853    void main () {
854        vec3 c = texture2D(uTexture, vUv).rgb;
855        float br = max(c.r, max(c.g, c.b));
856        float rq = clamp(br - curve.x, 0.0, curve.y);
857        rq = curve.z * rq * rq;
858        c *= max(rq, br - threshold) / max(br, 0.0001);
859        gl_FragColor = vec4(c, 0.0);
860    }
861`);
862
863var bloomBlurShader = compileShader(gl.FRAGMENT_SHADER, `
864    precision mediump float;
865    precision mediump sampler2D;
866
867    varying vec2 vL;
868    varying vec2 vR;
869    varying vec2 vT;
870    varying vec2 vB;
871    uniform sampler2D uTexture;
872
873    void main () {
874        vec4 sum = vec4(0.0);
875        sum += texture2D(uTexture, vL);
876        sum += texture2D(uTexture, vR);
877        sum += texture2D(uTexture, vT);
878        sum += texture2D(uTexture, vB);
879        sum *= 0.25;
880        gl_FragColor = sum;
881    }
882`);
883
884var bloomFinalShader = compileShader(gl.FRAGMENT_SHADER, `
885    precision mediump float;
886    precision mediump sampler2D;
887
888    varying vec2 vL;
889    varying vec2 vR;
890    varying vec2 vT;
891    varying vec2 vB;
892    uniform sampler2D uTexture;
893    uniform float intensity;
894
895    void main () {
896        vec4 sum = vec4(0.0);
897        sum += texture2D(uTexture, vL);
898        sum += texture2D(uTexture, vR);
899        sum += texture2D(uTexture, vT);
900        sum += texture2D(uTexture, vB);
901        sum *= 0.25;
902        gl_FragColor = sum * intensity;
903    }
904`);
905
906var sunraysMaskShader = compileShader(gl.FRAGMENT_SHADER, `
907    precision highp float;
908    precision highp sampler2D;
909
910    varying vec2 vUv;
911    uniform sampler2D uTexture;
912
913    void main () {
914        vec4 c = texture2D(uTexture, vUv);
915        float br = max(c.r, max(c.g, c.b));
916        c.a = 1.0 - min(max(br * 20.0, 0.0), 0.8);
917        gl_FragColor = c;
918    }
919`);
920
921var sunraysShader = compileShader(gl.FRAGMENT_SHADER, `
922    precision highp float;
923    precision highp sampler2D;
924
925    varying vec2 vUv;
926    uniform sampler2D uTexture;
927    uniform float weight;
928
929    #define ITERATIONS 16
930
931    void main () {
932        float Density = 0.3;
933        float Decay = 0.95;
934        float Exposure = 0.7;
935
936        vec2 coord = vUv;
937        vec2 dir = vUv - 0.5;
938
939        dir *= 1.0 / float(ITERATIONS) * Density;
940        float illuminationDecay = 1.0;
941
942        float color = texture2D(uTexture, vUv).a;
943
944        for (int i = 0; i < ITERATIONS; i++)
945        {
946            coord -= dir;
947            float col = texture2D(uTexture, coord).a;
948            color += col * illuminationDecay * weight;
949            illuminationDecay *= Decay;
950        }
951
952        gl_FragColor = vec4(color * Exposure, 0.0, 0.0, 1.0);
953    }
954`);
955
956var splatShader = compileShader(gl.FRAGMENT_SHADER, `
957    precision highp float;
958    precision highp sampler2D;
959
960    varying vec2 vUv;
961    uniform sampler2D uTarget;
962    uniform float aspectRatio;
963    uniform vec3 color;
964    uniform vec2 point;
965    uniform float radius;
966
967    void main () {
968        vec2 p = vUv - point.xy;
969        p.x *= aspectRatio;
970        vec3 splat = exp(-dot(p, p) / radius) * min(color, vec3(.07, .015, .015));
971        vec3 base = texture2D(uTarget, vUv).xyz;
972        gl_FragColor = vec4(base + splat, 1.0);
973    }
974`);
975
976// MAXIMUM RED VALUES
977// 1,
978// .349,
979// .3568
980
981var advectionShader = compileShader(gl.FRAGMENT_SHADER, `
982    precision highp float;
983    precision highp sampler2D;
984
985    varying vec2 vUv;
986    uniform sampler2D uVelocity;
987    uniform sampler2D uSource;
988    uniform vec2 texelSize;
989    uniform vec2 dyeTexelSize;
990    uniform float dt;
991    uniform float dissipation;
992
993    vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
994        vec2 st = uv / tsize - 0.5;
995
996        vec2 iuv = floor(st);
997        vec2 fuv = fract(st);
998
999        vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
1000        vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
1001        vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
1002        vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
1003
1004        return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
1005    }
1006
1007    void main () {
1008    #ifdef MANUAL_FILTERING
1009        vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
1010        vec4 result = bilerp(uSource, coord, dyeTexelSize);
1011    #else
1012        vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
1013        vec4 result = texture2D(uSource, coord);
1014    #endif
1015        float decay = 1.0 + dissipation * dt;
1016        gl_FragColor = result / decay;
1017    }`,
1018    ext.supportLinearFiltering ? null : ['MANUAL_FILTERING']
1019);
1020
1021var divergenceShader = compileShader(gl.FRAGMENT_SHADER, `
1022    precision mediump float;
1023    precision mediump sampler2D;
1024
1025    varying highp vec2 vUv;
1026    varying highp vec2 vL;
1027    varying highp vec2 vR;
1028    varying highp vec2 vT;
1029    varying highp vec2 vB;
1030    uniform sampler2D uVelocity;
1031
1032    void main () {
1033        float L = texture2D(uVelocity, vL).x;
1034        float R = texture2D(uVelocity, vR).x;
1035        float T = texture2D(uVelocity, vT).y;
1036        float B = texture2D(uVelocity, vB).y;
1037
1038        vec2 C = texture2D(uVelocity, vUv).xy;
1039        if (vL.x < 0.0) { L = -C.x; }
1040        if (vR.x > 1.0) { R = -C.x; }
1041        if (vT.y > 1.0) { T = -C.y; }
1042        if (vB.y < 0.0) { B = -C.y; }
1043
1044        float div = 0.5 * (R - L + T - B);
1045        gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
1046    }
1047`);
1048
1049var curlShader = compileShader(gl.FRAGMENT_SHADER, `
1050    precision mediump float;
1051    precision mediump sampler2D;
1052
1053    varying highp vec2 vUv;
1054    varying highp vec2 vL;
1055    varying highp vec2 vR;
1056    varying highp vec2 vT;
1057    varying highp vec2 vB;
1058    uniform sampler2D uVelocity;
1059
1060    void main () {
1061        float L = texture2D(uVelocity, vL).y;
1062        float R = texture2D(uVelocity, vR).y;
1063        float T = texture2D(uVelocity, vT).x;
1064        float B = texture2D(uVelocity, vB).x;
1065        float vorticity = R - L - T + B;
1066        gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
1067    }
1068`);
1069
1070var vorticityShader = compileShader(gl.FRAGMENT_SHADER, `
1071    precision highp float;
1072    precision highp sampler2D;
1073
1074    varying vec2 vUv;
1075    varying vec2 vL;
1076    varying vec2 vR;
1077    varying vec2 vT;
1078    varying vec2 vB;
1079    uniform sampler2D uVelocity;
1080    uniform sampler2D uCurl;
1081    uniform float curl;
1082    uniform float dt;
1083
1084    void main () {
1085        float L = texture2D(uCurl, vL).x;
1086        float R = texture2D(uCurl, vR).x;
1087        float T = texture2D(uCurl, vT).x;
1088        float B = texture2D(uCurl, vB).x;
1089        float C = texture2D(uCurl, vUv).x;
1090
1091        vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
1092        force /= length(force) + 0.0001;
1093        force *= curl * C;
1094        force.y *= -1.0;
1095
1096        vec2 vel = texture2D(uVelocity, vUv).xy;
1097        gl_FragColor = vec4(vel + force * dt, 0.0, 1.0);
1098    }
1099`);
1100
1101var pressureShader = compileShader(gl.FRAGMENT_SHADER, `
1102    precision mediump float;
1103    precision mediump sampler2D;
1104
1105    varying highp vec2 vUv;
1106    varying highp vec2 vL;
1107    varying highp vec2 vR;
1108    varying highp vec2 vT;
1109    varying highp vec2 vB;
1110    uniform sampler2D uPressure;
1111    uniform sampler2D uDivergence;
1112
1113    void main () {
1114        float L = texture2D(uPressure, vL).x;
1115        float R = texture2D(uPressure, vR).x;
1116        float T = texture2D(uPressure, vT).x;
1117        float B = texture2D(uPressure, vB).x;
1118        float C = texture2D(uPressure, vUv).x;
1119        float divergence = texture2D(uDivergence, vUv).x;
1120        float pressure = (L + R + B + T - divergence) * 0.25;
1121        gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
1122    }
1123`);
1124
1125var gradientSubtractShader = compileShader(gl.FRAGMENT_SHADER, `
1126    precision mediump float;
1127    precision mediump sampler2D;
1128
1129    varying highp vec2 vUv;
1130    varying highp vec2 vL;
1131    varying highp vec2 vR;
1132    varying highp vec2 vT;
1133    varying highp vec2 vB;
1134    uniform sampler2D uPressure;
1135    uniform sampler2D uVelocity;
1136
1137    void main () {
1138        float L = texture2D(uPressure, vL).x;
1139        float R = texture2D(uPressure, vR).x;
1140        float T = texture2D(uPressure, vT).x;
1141        float B = texture2D(uPressure, vB).x;
1142        vec2 velocity = texture2D(uVelocity, vUv).xy;
1143        velocity.xy -= vec2(R - L, T - B);
1144        gl_FragColor = vec4(velocity, 0.0, 1.0);
1145    }
1146`);
1147
1148var blit = (function () {
1149    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
1150    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), gl.STATIC_DRAW);
1151    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
1152    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW);
1153    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
1154    gl.enableVertexAttribArray(0);
1155
1156    return function (destination) {
1157        gl.bindFramebuffer(gl.FRAMEBUFFER, destination);
1158        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
1159    }
1160})();
1161
1162var dye;
1163var velocity;
1164var divergence;
1165var curl;
1166var pressure;
1167var bloom;
1168var bloomFramebuffers = [];
1169var sunrays;
1170var sunraysTemp;
1171
1172var ditheringTexture = createTextureAsync('LDR_LLL1_0.png');
1173
1174var blurProgram            = new Program(blurVertexShader, blurShader);
1175var copyProgram            = new Program(baseVertexShader, copyShader);
1176var clearProgram           = new Program(baseVertexShader, clearShader);
1177var colorProgram           = new Program(baseVertexShader, colorShader);
1178var checkerboardProgram    = new Program(baseVertexShader, checkerboardShader);
1179var bloomPrefilterProgram  = new Program(baseVertexShader, bloomPrefilterShader);
1180var bloomBlurProgram       = new Program(baseVertexShader, bloomBlurShader);
1181var bloomFinalProgram      = new Program(baseVertexShader, bloomFinalShader);
1182var sunraysMaskProgram     = new Program(baseVertexShader, sunraysMaskShader);
1183var sunraysProgram         = new Program(baseVertexShader, sunraysShader);
1184var splatProgram           = new Program(baseVertexShader, splatShader);
1185var advectionProgram       = new Program(baseVertexShader, advectionShader);
1186var divergenceProgram      = new Program(baseVertexShader, divergenceShader);
1187var curlProgram            = new Program(baseVertexShader, curlShader);
1188var vorticityProgram       = new Program(baseVertexShader, vorticitySh
1188ader);
1189var pressureProgram        = new Program(baseVertexShader, pressureShader);
1190var gradienSubtractProgram = new Program(baseVertexShader, gradientSubtractShader);
1191
1192var displayMaterial = new Material(baseVertexShader, displayShaderSource);
1193
1194function initFramebuffers () {
1195    var simRes = getResolution(config.SIM_RESOLUTION);
1196    var dyeRes = getResolution(config.DYE_RESOLUTION);
1197
1198    var texType = ext.halfFloatTexType;
1199    var rgba    = ext.formatRGBA;
1200    var rg      = ext.formatRG;
1201    var r       = ext.formatR;
1202    var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;
1203
1204    if (dye == null)
1205        { dye = createDoubleFBO(dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering); }
1206    else
1207        { dye = resizeDoubleFBO(dye, dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering); }
1208
1209    if (velocity == null)
1210        { velocity = createDoubleFBO(simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering); }
1211    else
1212        { velocity = resizeDoubleFBO(velocity, simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering); }
1213
1214    divergence = createFBO      (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);
1215    curl       = createFBO      (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);
1216    pressure   = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);
1217
1218    initBloomFramebuffers();
1219    initSunraysFramebuffers();
1220}
1221
1222function initBloomFramebuffers () {
1223    var res = getResolution(config.BLOOM_RESOLUTION);
1224
1225    var texType = ext.halfFloatTexType;
1226    var rgba = ext.formatRGBA;
1227    var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;
1228
1229    bloom = createFBO(res.width, res.height, rgba.internalFormat, rgba.format, texType, filtering);
1230
1231    bloomFramebuffers.length = 0;
1232    for (var i = 0; i < config.BLOOM_ITERATIONS; i++)
1233    {
1234        var width = res.width >> (i + 1);
1235        var height = res.height >> (i + 1);
1236
1237        if (width < 2 || height < 2) { break; }
1238
1239        var fbo = createFBO(width, height, rgba.internalFormat, rgba.format, texType, filtering);
1240        bloomFramebuffers.push(fbo);
1241    }
1242}
1243
1244function initSunraysFramebuffers () {
1245    var res = getResolution(config.SUNRAYS_RESOLUTION);
1246
1247    var texType = ext.halfFloatTexType;
1248    var r = ext.formatR;
1249    var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;
1250
1251    sunrays     = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering);
1252    sunraysTemp = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering);
1253}
1254
1255function createFBO (w, h, internalFormat, format, type, param) {
1256    gl.activeTexture(gl.TEXTURE0);
1257    var texture = gl.createTexture();
1258    gl.bindTexture(gl.TEXTURE_2D, texture);
1259    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param);
1260    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param);
1261    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1262    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1263    gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, null);
1264
1265    var fbo = gl.createFramebuffer();
1266    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
1267    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
1268    gl.viewport(0, 0, w, h);
1269    gl.clear(gl.COLOR_BUFFER_BIT);
1270
1271    var texelSizeX = 1.0 / w;
1272    var texelSizeY = 1.0 / h;
1273
1274    return {
1275        texture: texture,
1276        fbo: fbo,
1277        width: w,
1278        height: h,
1279        texelSizeX: texelSizeX,
1280        texelSizeY: texelSizeY,
1281        attach: function attach (id) {
1282            gl.activeTexture(gl.TEXTURE0 + id);
1283            gl.bindTexture(gl.TEXTURE_2D, texture);
1284            return id;
1285        }
1286    };
1287}
1288
1289function createDoubleFBO (w, h, internalFormat, format, type, param) {
1290    var fbo1 = createFBO(w, h, internalFormat, format, type, param);
1291    var fbo2 = createFBO(w, h, internalFormat, format, type, param);
1292
1293    return {
1294        width: w,
1295        height: h,
1296        texelSizeX: fbo1.texelSizeX,
1297        texelSizeY: fbo1.texelSizeY,
1298        get read () {
1299            return fbo1;
1300        },
1301        set read (value) {
1302            fbo1 = value;
1303        },
1304        get write () {
1305            return fbo2;
1306        },
1307        set write (value) {
1308            fbo2 = value;
1309        },
1310        swap: function swap () {
1311            var temp = fbo1;
1312            fbo1 = fbo2;
1313            fbo2 = temp;
1314        }
1315    }
1316}
1317
1318function resizeFBO (target, w, h, internalFormat, format, type, param) {
1319    var newFBO = createFBO(w, h, internalFormat, format, type, param);
1320    copyProgram.bind();
1321    gl.uniform1i(copyProgram.uniforms.uTexture, target.attach(0));
1322    blit(newFBO.fbo);
1323    return newFBO;
1324}
1325
1326function resizeDoubleFBO (target, w, h, internalFormat, format, type, param) {
1327    if (target.width == w && target.height == h)
1328        { return target; }
1329    target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param);
1330    target.write = createFBO(w, h, internalFormat, format, type, param);
1331    target.width = w;
1332    target.height = h;
1333    target.texelSizeX = 1.0 / w;
1334    target.texelSizeY = 1.0 / h;
1335    return target;
1336}
1337
1338function createTextureAsync (url) {
1339    var texture = gl.createTexture();
1340    gl.bindTexture(gl.TEXTURE_2D, texture);
1341    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
1342    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
1343    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
1344    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
1345    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255]));
1346
1347    var obj = {
1348        texture: texture,
1349        width: 1,
1350        height: 1,
1351        attach: function attach (id) {
1352            gl.activeTexture(gl.TEXTURE0 + id);
1353            gl.bindTexture(gl.TEXTURE_2D, texture);
1354            return id;
1355        }
1356    };
1357
1358    var image = new Image();
1359    image.onload = function () {
1360        obj.width = image.width;
1361        obj.height = image.height;
1362        gl.bindTexture(gl.TEXTURE_2D, texture);
1363        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
1364    };
1365    image.src = url;
1366
1367    return obj;
1368}
1369
1370function updateKeywords () {
1371    var displayKeywords = [];
1372    if (config.SHADING) { displayKeywords.push("SHADING"); }
1373    if (config.BLOOM) { displayKeywords.push("BLOOM"); }
1374    if (config.SUNRAYS) { displayKeywords.push("SUNRAYS"); }
1375    displayMaterial.setKeywords(displayKeywords);
1376}
1377
1378updateKeywords();
1379initFramebuffers();
1380multipleSplats(parseInt(Math.random() * 20) + 5);
1381
1382var lastUpdateTime = Date.now();
1383var colorUpdateTimer = 0.0;
1384update();
1385
1386function update () {
1387    var dt = calcDeltaTime();
1388
1389    if (resizeCanvas())
1390        { initFramebuffers(); }
1391    updateColors(dt);
1392    applyInputs();
1393
1394
1395    if (!config.PAUSED)
1396        { step(dt); }
1397    render(null);
1398    requestAnimationFrame(update);
1399}
1400
1401function calcDeltaTime () {
1402    var now = Date.now();
1403    var dt = (now - lastUpdateTime) / 1000;
1404    dt = Math.min(dt, 0.016666);
1405    lastUpdateTime = now;
1406    return dt;
1407}
1408
1409function resizeCanvas () {
1410    var width = scaleByPixelRatio(canvas.clientWidth);
1411    var height = scaleByPixelRatio(canvas.clientHeight);
1412    if (canvas.width != width || canvas.height != height) {
1413        canvas.width = width;
1414        canvas.height = height;
1415        return true;
1416    }
1417    return false;
1418}
1419
1420function updateColors (dt) {
1421    if (!config.COLORFUL) { return; }
1422
1423    colorUpdateTimer += dt * config.COLOR_UPDATE_SPEED;
1424    if (colorUpdateTimer >= 1) {
1425        colorUpdateTimer = wrap(colorUpdateTimer, 0, 1);
1426        pointers.forEach(function (p) {
1427            p.color = generateColor();
1428        });
1429    }
1430}
1431
1432function applyInputs () {
1433    if (splatStack.length > 0)
1434        { multipleSplats(splatStack.pop()); }
1435
1436    pointers.forEach(function (p) {
1437        // if (p.moved) {
1438            // p.moved = false;
1439          splatPointer(p);
1440        // }
1441    });
1442}
1443
1444function step (dt) {
1445    gl.disable(gl.BLEND);
1446    gl.viewport(0, 0, velocity.width, velocity.height);
1447
1448    // curlProgram.bind();
1449    // gl.uniform2f(curlProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1450    // gl.uniform1i(curlProgram.uniforms.uVelocity, velocity.read.attach(0));
1451    // blit(curl.fbo);
1452    //
1453    // vorticityProgram.bind();
1454    // gl.uniform2f(vorticityProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1455    // gl.uniform1i(vorticityProgram.uniforms.uVelocity, velocity.read.attach(0));
1456    // gl.uniform1i(vorticityProgram.uniforms.uCurl, curl.attach(1));
1457    // gl.uniform1f(vorticityProgram.uniforms.curl, config.CURL);
1458    // gl.uniform1f(vorticityProgram.uniforms.dt, dt);
1459    // blit(velocity.write.fbo);
1460    // velocity.swap();
1461
1462    divergenceProgram.bind();
1463    gl.uniform2f(divergenceProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1464    gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.read.attach(0));
1465    blit(divergence.fbo);
1466
1467    clearProgram.bind();
1468    gl.uniform1i(clearProgram.uniforms.uTexture, pressure.read.attach(0));
1469    gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE);
1470    blit(pressure.write.fbo);
1471    pressure.swap();
1472
1473    pressureProgram.bind();
1474    gl.uniform2f(pressureProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1475    gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence.attach(0));
1476    for (var i = 0; i < config.PRESSURE_ITERATIONS; i++) {
1477        gl.uniform1i(pressureProgram.uniforms.uPressure, pressure.read.attach(1));
1478        blit(pressure.write.fbo);
1479        pressure.swap();
1480    }
1481
1482    gradienSubtractProgram.bind();
1483    gl.uniform2f(gradienSubtractProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1484    gl.uniform1i(gradienSubtractProgram.uniforms.uPressure, pressure.read.attach(0));
1485    gl.uniform1i(gradienSubtractProgram.uniforms.uVelocity, velocity.read.attach(1));
1486    blit(velocity.write.fbo);
1487    velocity.swap();
1488
1489    advectionProgram.bind();
1490    gl.uniform2f(advectionProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY);
1491    if (!ext.supportLinearFiltering)
1492        { gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, velocity.texelSizeX, velocity.texelSizeY); }
1493    var velocityId = velocity.read.attach(0);
1494    gl.uniform1i(advectionProgram.uniforms.uVelocity, velocityId);
1495    gl.uniform1i(advectionProgram.uniforms.uSource, velocityId);
1496    gl.uniform1f(advectionProgram.uniforms.dt, dt);
1497    gl.uniform1f(advectionProgram.uniforms.dissipation, config.VELOCITY_DISSIPATION);
1498    blit(velocity.write.fbo);
1499    velocity.swap();
1500
1501    gl.viewport(0, 0, dye.width, dye.height);
1502
1503    if (!ext.supportLinearFiltering)
1504        { gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, dye.texelSizeX, dye.texelSizeY); }
1505    gl.uniform1i(advectionProgram.uniforms.uVelocity, velocity.read.attach(0));
1506    gl.uniform1i(advectionProgram.uniforms.uSource, dye.read.attach(1));
1507    gl.uniform1f(advectionProgram.uniforms.dissipation, config.DENSITY_DISSIPATION);
1508    blit(dye.write.fbo);
1509    dye.swap();
1510}
1511
1512function render (target) {
1513    if (config.BLOOM)
1514        { applyBloom(dye.read, bloom); }
1515    if (config.SUNRAYS) {
1516        applySunrays(dye.read, dye.write, sunrays);
1517        blur(sunrays, sunraysTemp, 1);
1518    }
1519
1520    if (target == null || !config.TRANSPARENT) {
1521        gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
1522        gl.enable(gl.BLEND);
1523    }
1524    else {
1525        gl.disable(gl.BLEND);
1526    }
1527
1528    var width = target == null ? gl.drawingBufferWidth : target.width;
1529    var height = target == null ? gl.drawingBufferHeight : target.height;
1530    gl.viewport(0, 0, width, height);
1531
1532    var fbo = target == null ? null : target.fbo;
1533    if (!config.TRANSPARENT)
1534        { drawColor(fbo, normalizeColor(config.BACK_COLOR)); }
1535    if (target == null && config.TRANSPARENT)
1536        { drawCheckerboard(fbo); }
1537    drawDisplay(fbo, width, height);
1538}
1539
1540function drawColor (fbo, color) {
1541    colorProgram.bind();
1542    gl.uniform4f(colorProgram.uniforms.color, color.r, color.g, color.b, 1);
1543    blit(fbo);
1544}
1545
1546function drawCheckerboard (fbo) {
1547    checkerboardProgram.bind();
1548    gl.uniform1f(checkerboardProgram.uniforms.aspectRatio, canvas.width / canvas.height);
1549    blit(fbo);
1550}
1551
1552function drawDisplay (fbo, width, height) {
1553    displayMaterial.bind();
1554    if (config.SHADING)
1555        { gl.uniform2f(displayMaterial.uniforms.texelSize, 1.0 / width, 1.0 / height); }
1556    gl.uniform1i(displayMaterial.uniforms.uTexture, dye.read.attach(0));
1557    if (config.BLOOM) {
1558        gl.uniform1i(displayMaterial.uniforms.uBloom, bloom.attach(1));
1559        gl.uniform1i(displayMaterial.uniforms.uDithering, ditheringTexture.attach(2));
1560        var scale = getTextureScale(ditheringTexture, width, height);
1561        gl.uniform2f(displayMaterial.uniforms.ditherScale, scale.x, scale.y);
1562    }
1563    if (config.SUNRAYS)
1564        { gl.uniform1i(displayMaterial.uniforms.uSunrays, sunrays.attach(3)); }
1565    blit(fbo);
1566}
1567
1568function applyBloom (source, destination) {
1569    if (bloomFramebuffers.length < 2)
1570        { return; }
1571
1572    var last = destination;
1573
1574    gl.disable(gl.BLEND);
1575    bloomPrefilterProgram.bind();
1576    var knee = config.BLOOM_THRESHOLD * config.BLOOM_SOFT_KNEE + 0.0001;
1577    var curve0 = config.BLOOM_THRESHOLD - knee;
1578    var curve1 = knee * 2;
1579    var curve2 = 0.25 / knee;
1580    gl.uniform3f(bloomPrefilterProgram.uniforms.curve, curve0, curve1, curve2);
1581    gl.uniform1f(bloomPrefilterProgram.uniforms.threshold, config.BLOOM_THRESHOLD);
1582    gl.uniform1i(bloomPrefilterProgram.uniforms.uTexture, source.attach(0));
1583    gl.viewport(0, 0, last.width, last.height);
1584    blit(last.fbo);
1585
1586    bloomBlurProgram.bind();
1587    for (var i = 0; i < bloomFramebuffers.length; i++) {
1588        var dest = bloomFramebuffers[i];
1589        gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY);
1590        gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0));
1591        gl.viewport(0, 0, dest.width, dest.height);
1592        blit(dest.fbo);
1593        last = dest;
1594    }
1595
1596    gl.blendFunc(gl.ONE, gl.ONE);
1597    gl.enable(gl.BLEND);
1598
1599    for (var i$1 = bloomFramebuffers.length - 2; i$1 >= 0; i$1--) {
1600        var baseTex = bloomFramebuffers[i$1];
1601        gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY);
1602        gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0));
1603        gl.viewport(0, 0, baseTex.width, baseTex.height);
1604        blit(baseTex.fbo);
1605        last = baseTex;
1606    }
1607
1608    gl.disable(gl.BLEND);
1609    bloomFinalProgram.bind();
1610    gl.uniform2f(bloomFinalProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY);
1611    gl.uniform1i(bloomFinalProgram.uniforms.uTexture, last.attach(0));
1612    gl.uniform1f(bloomFinalProgram.uniforms.intensity, config.BLOOM_INTENSITY);
1613    gl.viewport(0, 0, destination.width, destination.height);
1614    blit(destination.fbo);
1615}
1616
1617function applySunrays (source, mask, destination) {
1618    gl.disable(gl.BLEND);
1619    sunraysMaskProgram.bind();
1620    gl.uniform1i(sunraysMaskProgram.uniforms.uTexture, source.attach(0));
1621    gl.viewport(0, 0, mask.width, mask.height);
1622    blit(mask.fbo);
1623
1624    sunraysProgram.bind();
1625    gl.uniform1f(sunraysProgram.uniforms.weight, config.SUNRAYS_WEIGHT);
1626    gl.uniform1i(sunraysProgram.uniforms.uTexture, mask.attach(0));
1627    gl.viewport(0, 0, destination.width, destination.height);
1628    blit(destination.fbo);
1629}
1630
1631function blur (target, temp, iterations) {
1632    blurProgram.bind();
1633    for (var i = 0; i < iterations; i++) {
1634        gl.uniform2f(blurProgram.uniforms.texelSize, target.texelSizeX, 0.0);
1635        gl.uniform1i(blurProgram.uniforms.uTexture, target.attach(0));
1636        blit(temp.fbo);
1637
1638        gl.uniform2f(blurProgram.uniforms.texelSize, 0.0, target.texelSizeY);
1639        gl.uniform1i(blurProgram.uniforms.uTexture, temp.attach(0));
1640        blit(target.fbo);
1641    }
1642}
1643
1644function splatPointer (pointer) {
1645    var dx = pointer.deltaX * config.SPLAT_FORCE;
1646    var dy = pointer.deltaY * config.SPLAT_FORCE;
1647    splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color);
1648}
1649
1650function multipleSplats (amount) {
1651    for (var i = 0; i < amount; i++) {
1652        var color = generateColor();
1653        // color.r *= 10.0;
1654        // color.g *= 10.0;
1655        // color.b *= 10.0;
1656        var x = Math.random();
1657        var y = Math.random();
1658        var dx = 1000 * (Math.random() - 0.5);
1659        var dy = 1000 * (Math.random() - 0.5);
1660        splat(x, y, dx, dy, color);
1661    }
1662}
1663
1664function splat (x, y, dx, dy, color) {
1665    gl.viewport(0, 0, velocity.width, velocity.height);
1666    splatProgram.bind();
1667    gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0));
1668    gl.uniform1f(splatProgram.uniforms.aspectRatio, canvas.width / canvas.height);
1669    gl.uniform2f(splatProgram.uniforms.point, x, y);
1670    gl.uniform3f(splatProgram.uniforms.color, dx, dy, 0.0);
1671    gl.uniform1f(splatProgram.uniforms.radius, correctRadius(config.SPLAT_RADIUS / 100.0));
1672    blit(velocity.write.fbo);
1673    velocity.swap();
1674
1675    gl.viewport(0, 0, dye.width, dye.height);
1676    gl.uniform1i(splatProgram.uniforms.uTarget, dye.read.attach(0));
1677    gl.uniform3f(splatProgram.uniforms.color, color.r, color.g, color.b);
1678    blit(dye.write.fbo);
1679    dye.swap();
1680}
1681
1682function correctRadius (radius) {
1683    var aspectRatio = canvas.width / canvas.height;
1684    if (aspectRatio > 1)
1685        { radius *= aspectRatio; }
1686    return radius;
1687}
1688
1689document.addEventListener('mousedown', function (e) {
1690  // console.log(pointer);
1691  //   var posX = scaleByPixelRatio(e.offsetX);
1692  //   var posY = scaleByPixelRatio(e.offsetY);
1693  //   var pointer = pointers.find(function (p) { return p.id == -1; });
1694  //   if (pointer == null)
1695  //       { pointer = new pointerPrototype(); }
1696  //   updatePointerDownData(pointer, -1, posX, posY);
1697});
1698
1699
1700document.addEventListener('mousemove', function (e) {
1701  var pointer = pointers.find(function (p) { return p.id == -1; });
1702  if (pointer == null) {
1703    pointer = new pointerPrototype();
1704  } else {
1705    window.posX = scaleByPixelRatio(e.clientX);
1706    window.posY = scaleByPixelRatio(e.clientY);
1707    // console.log(window.posX, window.posY);
1708    updatePointerMoveData(pointer, window.posX, window.posY);
1709  }
1710});
1711
1712window.addEventListener('mouseup', function () {
1713    updatePointerUpData(pointers[0]);
1714});
1715
1716document.addEventListener('touchstart', function (e) {
1717    e.preventDefault();
1718    var touches = e.targetTouches;
1719    while (touches.length >= pointers.length)
1720        { pointers.push(new pointerPrototype()); }
1721    for (var i = 0; i < touches.length; i++) {
1722        var posX = scaleByPixelRatio(touches[i].clientX);
1723        var posY = scaleByPixelRatio(touches[i].clientY);
1724        updatePointerDownData(pointers[i + 1], touches[i].identifier, posX, posY);
1725    }
1726});
1727
1728document.addEventListener('touchmove', function (e) {
1729    e.preventDefault();
1730    var touches = e.targetTouches;
1731    for (var i = 0; i < touches.length; i++) {
1732        var pointer = pointers[i + 1];
1733        if (!pointer.down) { continue; }
1734        var posX = scaleByPixelRatio(touches[i].clientX);
1735        var posY = scaleByPixelRatio(touches[i].clientY);
1736        updatePointerMoveData(pointer, posX, posY);
1737    }
1738}, false);
1739
1740document.addEventListener('touchend', function (e) {
1741    var touches = e.changedTouches;
1742    var loop = function ( i ) {
1743        var pointer = pointers.find(function (p) { return p.id == touches[i].identifier; });
1744        if (pointer == null) { return; }
1745        updatePointerUpData(pointer);
1746    };
1747
1748    for (var i = 0; i < touches.length; i++)
1749    loop( i );
1750});
1751
1752// window.addEventListener('keydown', function (e) {
1753//     if (e.code === 'KeyP')
1754//         { config.PAUSED = !config.PAUSED; }
1755//     if (e.key === ' ')
1756//         { splatStack.push(parseInt(Math.random() * 20) + 5); }
1757// });
1758
1759function updatePointerDownData (pointer, id, posX, posY) {
1760    pointer.id = id;
1761    pointer.down = true;
1762    pointer.moved = false;
1763    pointer.texcoordX = posX / canvas.width;
1764    pointer.texcoordY = 1.0 - posY / canvas.height;
1765    pointer.prevTexcoordX = pointer.texcoordX;
1766    pointer.prevTexcoordY = pointer.texcoordY;
1767    pointer.deltaX = 0;
1768    pointer.deltaY = 0;
1769    // pointer.color = generateColor();
1770}
1771
1772function updatePointerMoveData (pointer, posX, posY) {
1773    pointer.prevTexcoordX = pointer.texcoordX;
1774    pointer.prevTexcoordY = pointer.texcoordY;
1775    pointer.texcoordX = posX / canvas.width;
1776    pointer.texcoordY = 1.0 - posY / canvas.height;
1777    pointer.deltaX = correctDeltaX(pointer.texcoordX - pointer.prevTexcoordX);
1778    pointer.deltaY = correctDeltaY(pointer.texcoordY - pointer.prevTexcoordY);
1779    pointer.moved = true; //Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0;
1780}
1781
1782function updatePointerUpData (pointer) {
1783    pointer.down = false;
1784}
1785
1786function correctDeltaX (delta) {
1787    var aspectRatio = canvas.width / canvas.height;
1788    if (aspectRatio < 1) { delta *= aspectRatio; }
1789    return delta;
1790}
1791
1792function correctDeltaY (delta) {
1793    var aspectRatio = canvas.width / canvas.height;
1794    if (aspectRatio > 1) { delta /= aspectRatio; }
1795    return delta;
1796}
1797
1798function generateColor () {
1799    // var c = HSVtoRGB(Math.random(), 1.0, 1.0);
1800    // c.r *= 0.15;
1801    // c.g *= 0.15;
1802    // c.b *= 0.15;
1803    var c = THECOLOR;
1804
1805    return c;
1806}
1807
1808function HSVtoRGB (h, s, v) {
1809    var r, g, b, i, f, p, q, t;
1810    i = Math.floor(h * 6);
1811    f = h * 6 - i;
1812    p = v * (1 - s);
1813    q = v * (1 - f * s);
1814    t = v * (1 - (1 - f) * s);
1815
1816    switch (i % 6) {
1817        case 0: r = v, g = t, b = p; break;
1818        case 1: r = q, g = v, b = p; break;
1819        case 2: r = p, g = v, b = t; break;
1820        case 3: r = p, g = q, b = v; break;
1821        case 4: r = t, g = p, b = v; break;
1822        case 5: r = v, g = p, b = q; break;
1823    }
1824
1825    return {
1826        r: r,
1827        g: g,
1828        b: b
1829    };
1830}
1831
1832function normalizeColor (input) {
1833    var output = {
1834        r: input.r / 255,
1835        g: input.g / 255,
1836        b: input.b / 255
1837    };
1838    return output;
1839}
1840
1841function wrap (value, min, max) {
1842    var range = max - min;
1843    if (range == 0) { return min; }
1844    return (value - min) % range + min;
1845}
1846
1847function getResolution (resolution) {
1848    var aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight;
1849    if (aspectRatio < 1)
1850        { aspectRatio = 1.0 / aspectRatio; }
1851
1852    var min = Math.round(resolution);
1853    var max = Math.round(resolution * aspectRatio);
1854
1855    if (gl.drawingBufferWidth > gl.drawingBufferHeight)
1856        { return { width: max, height: min }; }
1857    else
1858        { return { width: min, height: max }; }
1859}
1860
1861function getTextureScale (texture, width, height) {
1862    return {
1863        x: width / texture.width,
1864        y: height / texture.height
1865    };
1866}
1867
1868function scaleByPixelRatio (input) {
1869    var pixelRatio = window.devicePixelRatio || 1;
1870    return Math.floor(input * pixelRatio);
1871}
1872
1873function hashCode (s) {
1874    if (s.length == 0) { return 0; }
1875    var hash = 0;
1876    for (var i = 0; i < s.length; i++) {
1877        hash = (hash << 5) - hash + s.charCodeAt(i);
1878        hash |= 0; // Convert to 32bit integer
1879    }
1880    return hash;
1881};
1882
1883
1884/***/ }),
1885
vendor: 289,075 bytes, lines 1886-12778
1886/***/ "./node_modules/jquery/dist/jquery.js":
1887/*!********************************************!*\
1888  !*** ./node_modules/jquery/dist/jquery.js ***!
1889  \********************************************/
1890/*! no static exports found */
1891/***/ (function(module, exports, __webpack_require__) {
1892
1893var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
1894 * jQuery JavaScript Library v3.6.0
1895 * https://jquery.com/
1896 *
1897 * Includes Sizzle.js
1898 * https://sizzlejs.com/
1899 *
1900 * Copyright OpenJS Foundation and other contributors
1901 * Released under the MIT license
1902 * https://jquery.org/license
1903 *
1904 * Date: 2021-03-02T17:08Z
1905 */
1906( function( global, factory ) {
1907
1908	"use strict";
1909
1910	if (  true && typeof module.exports === "object" ) {
1911
1912		// For CommonJS and CommonJS-like environments where a proper `window`
1913		// is present, execute the factory and get jQuery.
1914		// For environments that do not have a `window` with a `document`
1915		// (such as Node.js), expose a factory as module.exports.
1916		// This accentuates the need for the creation of a real `window`.
1917		// e.g. var jQuery = require("jquery")(window);
1918		// See ticket #14549 for more info.
1919		module.exports = global.document ?
1920			factory( global, true ) :
1921			function( w ) {
1922				if ( !w.document ) {
1923					throw new Error( "jQuery requires a window with a document" );
1924				}
1925				return factory( w );
1926			};
1927	} else {
1928		factory( global );
1929	}
1930
1931// Pass this if window is not defined yet
1932} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
1933
1934// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
1935// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
1936// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
1937// enough that all such attempts are guarded in a try block.
1938"use strict";
1939
1940var arr = [];
1941
1942var getProto = Object.getPrototypeOf;
1943
1944var slice = arr.slice;
1945
1946var flat = arr.flat ? function( array ) {
1947	return arr.flat.call( array );
1948} : function( array ) {
1949	return arr.concat.apply( [], array );
1950};
1951
1952
1953var push = arr.push;
1954
1955var indexOf = arr.indexOf;
1956
1957var class2type = {};
1958
1959var toString = class2type.toString;
1960
1961var hasOwn = class2type.hasOwnProperty;
1962
1963var fnToString = hasOwn.toString;
1964
1965var ObjectFunctionString = fnToString.call( Object );
1966
1967var support = {};
1968
1969var isFunction = function isFunction( obj ) {
1970
1971		// Support: Chrome <=57, Firefox <=52
1972		// In some browsers, typeof returns "function" for HTML <object> elements
1973		// (i.e., `typeof document.createElement( "object" ) === "function"`).
1974		// We don't want to classify *any* DOM node as a function.
1975		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
1976		// Plus for old WebKit, typeof returns "function" for HTML collections
1977		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
1978		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
1979			typeof obj.item !== "function";
1980	};
1981
1982
1983var isWindow = function isWindow( obj ) {
1984		return obj != null && obj === obj.window;
1985	};
1986
1987
1988var document = window.document;
1989
1990
1991
1992	var preservedScriptAttributes = {
1993		type: true,
1994		src: true,
1995		nonce: true,
1996		noModule: true
1997	};
1998
1999	function DOMEval( code, node, doc ) {
2000		doc = doc || document;
2001
2002		var i, val,
2003			script = doc.createElement( "script" );
2004
2005		script.text = code;
2006		if ( node ) {
2007			for ( i in preservedScriptAttributes ) {
2008
2009				// Support: Firefox 64+, Edge 18+
2010				// Some browsers don't support the "nonce" property on scripts.
2011				// On the other hand, just using `getAttribute` is not enough as
2012				// the `nonce` attribute is reset to an empty string whenever it
2013				// becomes browsing-context connected.
2014				// See https://github.com/whatwg/html/issues/2369
2015				// See https://html.spec.whatwg.org/#nonce-attributes
2016				// The `node.getAttribute` check was added for the sake of
2017				// `jQuery.globalEval` so that it can fake a nonce-containing node
2018				// via an object.
2019				val = node[ i ] || node.getAttribute && node.getAttribute( i );
2020				if ( val ) {
2021					script.setAttribute( i, val );
2022				}
2023			}
2024		}
2025		doc.head.appendChild( script ).parentNode.removeChild( script );
2026	}
2027
2028
2029function toType( obj ) {
2030	if ( obj == null ) {
2031		return obj + "";
2032	}
2033
2034	// Support: Android <=2.3 only (functionish RegExp)
2035	return typeof obj === "object" || typeof obj === "function" ?
2036		class2type[ toString.call( obj ) ] || "object" :
2037		typeof obj;
2038}
2039/* global Symbol */
2040// Defining this global in .eslintrc.json would create a danger of using the global
2041// unguarded in another place, it seems safer to define global only for this module
2042
2043
2044
2045var
2046	version = "3.6.0",
2047
2048	// Define a local copy of jQuery
2049	jQuery = function( selector, context ) {
2050
2051		// The jQuery object is actually just the init constructor 'enhanced'
2052		// Need init if jQuery is called (just allow error to be thrown if not included)
2053		return new jQuery.fn.init( selector, context );
2054	};
2055
2056jQuery.fn = jQuery.prototype = {
2057
2058	// The current version of jQuery being used
2059	jquery: version,
2060
2061	constructor: jQuery,
2062
2063	// The default length of a jQuery object is 0
2064	length: 0,
2065
2066	toArray: function() {
2067		return slice.call( this );
2068	},
2069
2070	// Get the Nth element in the matched element set OR
2071	// Get the whole matched element set as a clean array
2072	get: function( num ) {
2073
2074		// Return all the elements in a clean array
2075		if ( num == null ) {
2076			return slice.call( this );
2077		}
2078
2079		// Return just the one element from the set
2080		return num < 0 ? this[ num + this.length ] : this[ num ];
2081	},
2082
2083	// Take an array of elements and push it onto the stack
2084	// (returning the new matched element set)
2085	pushStack: function( elems ) {
2086
2087		// Build a new jQuery matched element set
2088		var ret = jQuery.merge( this.constructor(), elems );
2089
2090		// Add the old object onto the stack (as a reference)
2091		ret.prevObject = this;
2092
2093		// Return the newly-formed element set
2094		return ret;
2095	},
2096
2097	// Execute a callback for every element in the matched set.
2098	each: function( callback ) {
2099		return jQuery.each( this, callback );
2100	},
2101
2102	map: function( callback ) {
2103		return this.pushStack( jQuery.map( this, function( elem, i ) {
2104			return callback.call( elem, i, elem );
2105		} ) );
2106	},
2107
2108	slice: function() {
2109		return this.pushStack( slice.apply( this, arguments ) );
2110	},
2111
2112	first: function() {
2113		return this.eq( 0 );
2114	},
2115
2116	last: function() {
2117		return this.eq( -1 );
2118	},
2119
2120	even: function() {
2121		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
2122			return ( i + 1 ) % 2;
2123		} ) );
2124	},
2125
2126	odd: function() {
2127		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
2128			return i % 2;
2129		} ) );
2130	},
2131
2132	eq: function( i ) {
2133		var len = this.length,
2134			j = +i + ( i < 0 ? len : 0 );
2135		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
2136	},
2137
2138	end: function() {
2139		return this.prevObject || this.constructor();
2140	},
2141
2142	// For internal use only.
2143	// Behaves like an Array's method, not like a jQuery method.
2144	push: push,
2145	sort: arr.sort,
2146	splice: arr.splice
2147};
2148
2149jQuery.extend = jQuery.fn.extend = function() {
2150	var options, name, src, copy, copyIsArray, clone,
2151		target = arguments[ 0 ] || {},
2152		i = 1,
2153		length = arguments.length,
2154		deep = false;
2155
2156	// Handle a deep copy situation
2157	if ( typeof target === "boolean" ) {
2158		deep = target;
2159
2160		// Skip the boolean and the target
2161		target = arguments[ i ] || {};
2162		i++;
2163	}
2164
2165	// Handle case when target is a string or something (possible in deep copy)
2166	if ( typeof target !== "object" && !isFunction( target ) ) {
2167		target = {};
2168	}
2169
2170	// Extend jQuery itself if only one argument is passed
2171	if ( i === length ) {
2172		target = this;
2173		i--;
2174	}
2175
2176	for ( ; i < length; i++ ) {
2177
2178		// Only deal with non-null/undefined values
2179		if ( ( options = arguments[ i ] ) != null ) {
2180
2181			// Extend the base object
2182			for ( name in options ) {
2183				copy = options[ name ];
2184
2185				// Prevent Object.prototype pollution
2186				// Prevent never-ending loop
2187				if ( name === "__proto__" || target === copy ) {
2188					continue;
2189				}
2190
2191				// Recurse if we're merging plain objects or arrays
2192				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
2193					( copyIsArray = Array.isArray( copy ) ) ) ) {
2194					src = target[ name ];
2195
2196					// Ensure proper type for the source value
2197					if ( copyIsArray && !Array.isArray( src ) ) {
2198						clone = [];
2199					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
2200						clone = {};
2201					} else {
2202						clone = src;
2203					}
2204					copyIsArray = false;
2205
2206					// Never move original objects, clone them
2207					target[ name ] = jQuery.extend( deep, clone, copy );
2208
2209				// Don't bring in undefined values
2210				} else if ( copy !== undefined ) {
2211					target[ name ] = copy;
2212				}
2213			}
2214		}
2215	}
2216
2217	// Return the modified object
2218	return target;
2219};
2220
2221jQuery.extend( {
2222
2223	// Unique for each copy of jQuery on the page
2224	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
2225
2226	// Assume jQuery is ready without the ready module
2227	isReady: true,
2228
2229	error: function( msg ) {
2230		throw new Error( msg );
2231	},
2232
2233	noop: function() {},
2234
2235	isPlainObject: function( obj ) {
2236		var proto, Ctor;
2237
2238		// Detect obvious negatives
2239		// Use toString instead of jQuery.type to catch host objects
2240		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
2241			return false;
2242		}
2243
2244		proto = getProto( obj );
2245
2246		// Objects with no prototype (e.g., `Object.create( null )`) are plain
2247		if ( !proto ) {
2248			return true;
2249		}
2250
2251		// Objects with prototype are plain iff they were constructed by a global Object function
2252		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
2253		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
2254	},
2255
2256	isEmptyObject: function( obj ) {
2257		var name;
2258
2259		for ( name in obj ) {
2260			return false;
2261		}
2262		return true;
2263	},
2264
2265	// Evaluates a script in a provided context; falls back to the global one
2266	// if not specified.
2267	globalEval: function( code, options, doc ) {
2268		DOMEval( code, { nonce: options && options.nonce }, doc );
2269	},
2270
2271	each: function( obj, callback ) {
2272		var length, i = 0;
2273
2274		if ( isArrayLike( obj ) ) {
2275			length = obj.length;
2276			for ( ; i < length; i++ ) {
2277				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
2278					break;
2279				}
2280			}
2281		} else {
2282			for ( i in obj ) {
2283				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
2284					break;
2285				}
2286			}
2287		}
2288
2289		return obj;
2290	},
2291
2292	// results is for internal usage only
2293	makeArray: function( arr, results ) {
2294		var ret = results || [];
2295
2296		if ( arr != null ) {
2297			if ( isArrayLike( Object( arr ) ) ) {
2298				jQuery.merge( ret,
2299					typeof arr === "string" ?
2300						[ arr ] : arr
2301				);
2302			} else {
2303				push.call( ret, arr );
2304			}
2305		}
2306
2307		return ret;
2308	},
2309
2310	inArray: function( elem, arr, i ) {
2311		return arr == null ? -1 : indexOf.call( arr, elem, i );
2312	},
2313
2314	// Support: Android <=4.0 only, PhantomJS 1 only
2315	// push.apply(_, arraylike) throws on ancient WebKit
2316	merge: function( first, second ) {
2317		var len = +second.length,
2318			j = 0,
2319			i = first.length;
2320
2321		for ( ; j < len; j++ ) {
2322			first[ i++ ] = second[ j ];
2323		}
2324
2325		first.length = i;
2326
2327		return first;
2328	},
2329
2330	grep: function( elems, callback, invert ) {
2331		var callbackInverse,
2332			matches = [],
2333			i = 0,
2334			length = elems.length,
2335			callbackExpect = !invert;
2336
2337		// Go through the array, only saving the items
2338		// that pass the validator function
2339		for ( ; i < length; i++ ) {
2340			callbackInverse = !callback( elems[ i ], i );
2341			if ( callbackInverse !== callbackExpect ) {
2342				matches.push( elems[ i ] );
2343			}
2344		}
2345
2346		return matches;
2347	},
2348
2349	// arg is for internal usage only
2350	map: function( elems, callback, arg ) {
2351		var length, value,
2352			i = 0,
2353			ret = [];
2354
2355		// Go through the array, translating each of the items to their new values
2356		if ( isArrayLike( elems ) ) {
2357			length = elems.length;
2358			for ( ; i < length; i++ ) {
2359				value = callback( elems[ i ], i, arg );
2360
2361				if ( value != null ) {
2362					ret.push( value );
2363				}
2364			}
2365
2366		// Go through every key on the object,
2367		} else {
2368			for ( i in elems ) {
2369				value = callback( elems[ i ], i, arg );
2370
2371				if ( value != null ) {
2372					ret.push( value );
2373				}
2374			}
2375		}
2376
2377		// Flatten any nested arrays
2378		return flat( ret );
2379	},
2380
2381	// A global GUID counter for objects
2382	guid: 1,
2383
2384	// jQuery.support is not used in Core but other projects attach their
2385	// properties to it so it needs to exist.
2386	support: support
2387} );
2388
2389if ( typeof Symbol === "function" ) {
2390	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
2391}
2392
2393// Populate the class2type map
2394jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
2395	function( _i, name ) {
2396		class2type[ "[object " + name + "]" ] = name.toLowerCase();
2397	} );
2398
2399function isArrayLike( obj ) {
2400
2401	// Support: real iOS 8.2 only (not reproducible in simulator)
2402	// `in` check used to prevent JIT error (gh-2145)
2403	// hasOwn isn't used here due to false negatives
2404	// regarding Nodelist length in IE
2405	var length = !!obj && "length" in obj && obj.length,
2406		type = toType( obj );
2407
2408	if ( isFunction( obj ) || isWindow( obj ) ) {
2409		return false;
2410	}
2411
2412	return type === "array" || length === 0 ||
2413		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
2414}
2415var Sizzle =
2416/*!
2417 * Sizzle CSS Selector Engine v2.3.6
2418 * https://sizzlejs.com/
2419 *
2420 * Copyright JS Foundation and other contributors
2421 * Released under the MIT license
2422 * https://js.foundation/
2423 *
2424 * Date: 2021-02-16
2425 */
2426( function( window ) {
2427var i,
2428	support,
2429	Expr,
2430	getText,
2431	isXML,
2432	tokenize,
2433	compile,
2434	select,
2435	outermostContext,
2436	sortInput,
2437	hasDuplicate,
2438
2439	// Local document vars
2440	setDocument,
2441	document,
2442	docElem,
2443	documentIsHTML,
2444	rbuggyQSA,
2445	rbuggyMatches,
2446	matches,
2447	contains,
2448
2449	// Instance-specific data
2450	expando = "sizzle" + 1 * new Date(),
2451	preferredDoc = window.document,
2452	dirruns = 0,
2453	done = 0,
2454	classCache = createCache(),
2455	tokenCache = createCache(),
2456	compilerCache = createCache(),
2457	nonnativeSelectorCache = createCache(),
2458	sortOrder = function( a, b ) {
2459		if ( a === b ) {
2460			hasDuplicate = true;
2461		}
2462		return 0;
2463	},
2464
2465	// Instance methods
2466	hasOwn = ( {} ).hasOwnProperty,
2467	arr = [],
2468	pop = arr.pop,
2469	pushNative = arr.push,
2470	push = arr.push,
2471	slice = arr.slice,
2472
2473	// Use a stripped-down indexOf as it's faster than native
2474	// https://jsperf.com/thor-indexof-vs-for/5
2475	indexOf = function( list, elem ) {
2476		var i = 0,
2477			len = list.length;
2478		for ( ; i < len; i++ ) {
2479			if ( list[ i ] === elem ) {
2480				return i;
2481			}
2482		}
2483		return -1;
2484	},
2485
2486	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
2487		"ismap|loop|multiple|open|readonly|required|scoped",
2488
2489	// Regular expressions
2490
2491	// http://www.w3.org/TR/css3-selectors/#whitespace
2492	whitespace = "[\\x20\\t\\r\\n\\f]",
2493
2494	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
2495	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
2496		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
2497
2498	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
2499	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
2500
2501		// Operator (capture 2)
2502		"*([*^$|!~]?=)" + whitespace +
2503
2504		// "Attribute values must be CSS identifiers [capture 5]
2505		// or strings [capture 3 or capture 4]"
2506		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
2507		whitespace + "*\\]",
2508
2509	pseudos = ":(" + identifier + ")(?:\\((" +
2510
2511		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
2512		// 1. quoted (capture 3; capture 4 or capture 5)
2513		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
2514
2515		// 2. simple (capture 6)
2516		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
2517
2518		// 3. anything else (capture 2)
2519		".*" +
2520		")\\)|)",
2521
2522	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
2523	rwhitespace = new RegExp( whitespace + "+", "g" ),
2524	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
2525		whitespace + "+$", "g" ),
2526
2527	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
2528	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
2529		"*" ),
2530	rdescend = new RegExp( whitespace + "|>" ),
2531
2532	rpseudo = new RegExp( pseudos ),
2533	ridentifier = new RegExp( "^" + identifier + "$" ),
2534
2535	matchExpr = {
2536		"ID": new RegExp( "^#(" + identifier + ")" ),
2537		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
2538		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
2539		"ATTR": new RegExp( "^" + attributes ),
2540		"PSEUDO": new RegExp( "^" + pseudos ),
2541		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
2542			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
2543			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
2544		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
2545
2546		// For use in libraries implementing .is()
2547		// We use this for POS matching in `select`
2548		"needsContext": new RegExp( "^" + whitespace +
2549			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
2550			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
2551	},
2552
2553	rhtml = /HTML$/i,
2554	rinputs = /^(?:input|select|textarea|button)$/i,
2555	rheader = /^h\d$/i,
2556
2557	rnative = /^[^{]+\{\s*\[native \w/,
2558
2559	// Easily-parseable/retrievable ID or TAG or CLASS selectors
2560	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
2561
2562	rsibling = /[+~]/,
2563
2564	// CSS escapes
2565	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
2566	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
2567	funescape = function( escape, nonHex ) {
2568		var high = "0x" + escape.slice( 1 ) - 0x10000;
2569
2570		return nonHex ?
2571
2572			// Strip the backslash prefix from a non-hex escape sequence
2573			nonHex :
2574
2575			// Replace a hexadecimal escape sequence with the encoded Unicode code point
2576			// Support: IE <=11+
2577			// For values outside the Basic Multilingual Plane (BMP), manually construct a
2578			// surrogate pair
2579			high < 0 ?
2580				String.fromCharCode( high + 0x10000 ) :
2581				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
2582	},
2583
2584	// CSS string/identifier serialization
2585	// https://drafts.csswg.org/cssom/#common-serializing-idioms
2586	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
2587	fcssescape = function( ch, asCodePoint ) {
2588		if ( asCodePoint ) {
2589
2590			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
2591			if ( ch === "\0" ) {
2592				return "\uFFFD";
2593			}
2594
2595			// Control characters and (dependent upon position) numbers get escaped as code points
2596			return ch.slice( 0, -1 ) + "\\" +
2597				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
2598		}
2599
2600		// Other potentially-special ASCII characters get backslash-escaped
2601		return "\\" + ch;
2602	},
2603
2604	// Used for iframes
2605	// See setDocument()
2606	// Removing the function wrapper causes a "Permission Denied"
2607	// error in IE
2608	unloadHandler = function() {
2609		setDocument();
2610	},
2611
2612	inDisabledFieldset = addCombinator(
2613		function( elem ) {
2614			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
2615		},
2616		{ dir: "parentNode", next: "legend" }
2617	);
2618
2619// Optimize for push.apply( _, NodeList )
2620try {
2621	push.apply(
2622		( arr = slice.call( preferredDoc.childNodes ) ),
2623		preferredDoc.childNodes
2624	);
2625
2626	// Support: Android<4.0
2627	// Detect silently failing push.apply
2628	// eslint-disable-next-line no-unused-expressions
2629	arr[ preferredDoc.childNodes.length ].nodeType;
2630} catch ( e ) {
2631	push = { apply: arr.length ?
2632
2633		// Leverage slice if possible
2634		function( target, els ) {
2635			pushNative.apply( target, slice.call( els ) );
2636		} :
2637
2638		// Support: IE<9
2639		// Otherwise append directly
2640		function( target, els ) {
2641			var j = target.length,
2642				i = 0;
2643
2644			// Can't trust NodeList.length
2645			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
2646			target.length = j - 1;
2647		}
2648	};
2649}
2650
2651function Sizzle( selector, context, results, seed ) {
2652	var m, i, elem, nid, match, groups, newSelector,
2653		newContext = context && context.ownerDocument,
2654
2655		// nodeType defaults to 9, since context defaults to document
2656		nodeType = context ? context.nodeType : 9;
2657
2658	results = results || [];
2659
2660	// Return early from calls with invalid selector or context
2661	if ( typeof selector !== "string" || !selector ||
2662		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
2663
2664		return results;
2665	}
2666
2667	// Try to shortcut find operations (as opposed to filters) in HTML documents
2668	if ( !seed ) {
2669		setDocument( context );
2670		context = context || document;
2671
2672		if ( documentIsHTML ) {
2673
2674			// If the selector is sufficiently simple, try using a "get*By*" DOM method
2675			// (excepting DocumentFragment context, where the methods don't exist)
2676			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
2677
2678				// ID selector
2679				if ( ( m = match[ 1 ] ) ) {
2680
2681					// Document context
2682					if ( nodeType === 9 ) {
2683						if ( ( elem = context.getElementById( m ) ) ) {
2684
2685							// Support: IE, Opera, Webkit
2686							// TODO: identify versions
2687							// getElementById can match elements by name instead of ID
2688							if ( elem.id === m ) {
2689								results.push( elem );
2690								return results;
2691							}
2692						} else {
2693							return results;
2694						}
2695
2696					// Element context
2697					} else {
2698
2699						// Support: IE, Opera, Webkit
2700						// TODO: identify versions
2701						// getElementById can match elements by name instead of ID
2702						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
2703							contains( context, elem ) &&
2704							elem.id === m ) {
2705
2706							results.push( elem );
2707							return results;
2708						}
2709					}
2710
2711				// Type selector
2712				} else if ( match[ 2 ] ) {
2713					push.apply( results, context.getElementsByTagName( selector ) );
2714					return results;
2715
2716				// Class selector
2717				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
2718					context.getElementsByClassName ) {
2719
2720					push.apply( results, context.getElementsByClassName( m ) );
2721					return results;
2722				}
2723			}
2724
2725			// Take advantage of querySelectorAll
2726			if ( support.qsa &&
2727				!nonnativeSelectorCache[ selector + " " ] &&
2728				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
2729
2730				// Support: IE 8 only
2731				// Exclude object elements
2732				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
2733
2734				newSelector = selector;
2735				newContext = context;
2736
2737				// qSA considers elements outside a scoping root when evaluating child or
2738				// descendant combinators, which is not what we want.
2739				// In such cases, we work around the behavior by prefixing every selector in the
2740				// list with an ID selector referencing the scope context.
2741				// The technique has to be used as well when a leading combinator is used
2742				// as such selectors are not recognized by querySelectorAll.
2743				// Thanks to Andrew Dupont for this technique.
2744				if ( nodeType === 1 &&
2745					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
2746
2747					// Expand context for sibling selectors
2748					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
2749						context;
2750
2751					// We can use :scope instead of the ID hack if the browser
2752					// supports it & if we're not changing the context.
2753					if ( newContext !== context || !support.scope ) {
2754
2755						// Capture the context ID, setting it first if necessary
2756						if ( ( nid = context.getAttribute( "id" ) ) ) {
2757							nid = nid.replace( rcssescape, fcssescape );
2758						} else {
2759							context.setAttribute( "id", ( nid = expando ) );
2760						}
2761					}
2762
2763					// Prefix every selector in the list
2764					groups = tokenize( selector );
2765					i = groups.length;
2766					while ( i-- ) {
2767						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
2768							toSelector( groups[ i ] );
2769					}
2770					newSelector = groups.join( "," );
2771				}
2772
2773				try {
2774					push.apply( results,
2775						newContext.querySelectorAll( newSelector )
2776					);
2777					return results;
2778				} catch ( qsaError ) {
2779					nonnativeSelectorCache( selector, true );
2780				} finally {
2781					if ( nid === expando ) {
2782						context.removeAttribute( "id" );
2783					}
2784				}
2785			}
2786		}
2787	}
2788
2789	// All others
2790	return select( selector.replace( rtrim, "$1" ), context, results, seed );
2791}
2792
2793/**
2794 * Create key-value caches of limited size
2795 * @returns {function(string, object)} Returns the Object data after storing it on itself with
2796 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
2797 *	deleting the oldest entry
2798 */
2799function createCache() {
2800	var keys = [];
2801
2802	function cache( key, value ) {
2803
2804		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
2805		if ( keys.push( key + " " ) > Expr.cacheLength ) {
2806
2807			// Only keep the most recent entries
2808			delete cache[ keys.shift() ];
2809		}
2810		return ( cache[ key + " " ] = value );
2811	}
2812	return cache;
2813}
2814
2815/**
2816 * Mark a function for special use by Sizzle
2817 * @param {Function} fn The function to mark
2818 */
2819function markFunction( fn ) {
2820	fn[ expando ] = true;
2821	return fn;
2822}
2823
2824/**
2825 * Support testing using an element
2826 * @param {Function} fn Passed the created element and returns a boolean result
2827 */
2828function assert( fn ) {
2829	var el = document.createElement( "fieldset" );
2830
2831	try {
2832		return !!fn( el );
2833	} catch ( e ) {
2834		return false;
2835	} finally {
2836
2837		// Remove from its parent by default
2838		if ( el.parentNode ) {
2839			el.parentNode.removeChild( el );
2840		}
2841
2842		// release memory in IE
2843		el = null;
2844	}
2845}
2846
2847/**
2848 * Adds the same handler for all of the specified attrs
2849 * @param {String} attrs Pipe-separated list of attributes
2850 * @param {Function} handler The method that will be applied
2851 */
2852function addHandle( attrs, handler ) {
2853	var arr = attrs.split( "|" ),
2854		i = arr.length;
2855
2856	while ( i-- ) {
2857		Expr.attrHandle[ arr[ i ] ] = handler;
2858	}
2859}
2860
2861/**
2862 * Checks document order of two siblings
2863 * @param {Element} a
2864 * @param {Element} b
2865 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
2866 */
2867function siblingCheck( a, b ) {
2868	var cur = b && a,
2869		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
2870			a.sourceIndex - b.sourceIndex;
2871
2872	// Use IE sourceIndex if available on both nodes
2873	if ( diff ) {
2874		return diff;
2875	}
2876
2877	// Check if b follows a
2878	if ( cur ) {
2879		while ( ( cur = cur.nextSibling ) ) {
2880			if ( cur === b ) {
2881				return -1;
2882			}
2883		}
2884	}
2885
2886	return a ? 1 : -1;
2887}
2888
2889/**
2890 * Returns a function to use in pseudos for input types
2891 * @param {String} type
2892 */
2893function createInputPseudo( type ) {
2894	return function( elem ) {
2895		var name = elem.nodeName.toLowerCase();
2896		return name === "input" && elem.type === type;
2897	};
2898}
2899
2900/**
2901 * Returns a function to use in pseudos for buttons
2902 * @param {String} type
2903 */
2904function createButtonPseudo( type ) {
2905	return function( elem ) {
2906		var name = elem.nodeName.toLowerCase();
2907		return ( name === "input" || name === "button" ) && elem.type === type;
2908	};
2909}
2910
2911/**
2912 * Returns a function to use in pseudos for :enabled/:disabled
2913 * @param {Boolean} disabled true for :disabled; false for :enabled
2914 */
2915function createDisabledPseudo( disabled ) {
2916
2917	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
2918	return function( elem ) {
2919
2920		// Only certain elements can match :enabled or :disabled
2921		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
2922		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
2923		if ( "form" in elem ) {
2924
2925			// Check for inherited disabledness on relevant non-disabled elements:
2926			// * listed form-associated elements in a disabled fieldset
2927			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
2928			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
2929			// * option elements in a disabled optgroup
2930			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
2931			// All such elements have a "form" property.
2932			if ( elem.parentNode && elem.disabled === false ) {
2933
2934				// Option elements defer to a parent optgroup if present
2935				if ( "label" in elem ) {
2936					if ( "label" in elem.parentNode ) {
2937						return elem.parentNode.disabled === disabled;
2938					} else {
2939						return elem.disabled === disabled;
2940					}
2941				}
2942
2943				// Support: IE 6 - 11
2944				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
2945				return elem.isDisabled === disabled ||
2946
2947					// Where there is no isDisabled, check manually
2948					/* jshint -W018 */
2949					elem.isDisabled !== !disabled &&
2950					inDisabledFieldset( elem ) === disabled;
2951			}
2952
2953			return elem.disabled === disabled;
2954
2955		// Try to winnow out elements that can't be disabled before trusting the disabled property.
2956		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
2957		// even exist on them, let alone have a boolean value.
2958		} else if ( "label" in elem ) {
2959			return elem.disabled === disabled;
2960		}
2961
2962		// Remaining elements are neither :enabled nor :disabled
2963		return false;
2964	};
2965}
2966
2967/**
2968 * Returns a function to use in pseudos for positionals
2969 * @param {Function} fn
2970 */
2971function createPositionalPseudo( fn ) {
2972	return markFunction( function( argument ) {
2973		argument = +argument;
2974		return markFunction( function( seed, matches ) {
2975			var j,
2976				matchIndexes = fn( [], seed.length, argument ),
2977				i = matchIndexes.length;
2978
2979			// Match elements found at the specified indexes
2980			while ( i-- ) {
2981				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
2982					seed[ j ] = !( matches[ j ] = seed[ j ] );
2983				}
2984			}
2985		} );
2986	} );
2987}
2988
2989/**
2990 * Checks a node for validity as a Sizzle context
2991 * @param {Element|Object=} context
2992 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
2993 */
2994function testContext( context ) {
2995	return context && typeof context.getElementsByTagName !== "undefined" && context;
2996}
2997
2998// Expose support vars for convenience
2999support = Sizzle.support = {};
3000
3001/**
3002 * Detects XML nodes
3003 * @param {Element|Object} elem An element or a document
3004 * @returns {Boolean} True iff elem is a non-HTML XML node
3005 */
3006isXML = Sizzle.isXML = function( elem ) {
3007	var namespace = elem && elem.namespaceURI,
3008		docElem = elem && ( elem.ownerDocument || elem ).documentElement;
3009
3010	// Support: IE <=8
3011	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
3012	// https://bugs.jquery.com/ticket/4833
3013	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
3014};
3015
3016/**
3017 * Sets document-related variables once based on the current document
3018 * @param {Element|Object} [doc] An element or document object to use to set the document
3019 * @returns {Object} Returns the current document
3020 */
3021setDocument = Sizzle.setDocument = function( node ) {
3022	var hasCompare, subWindow,
3023		doc = node ? node.ownerDocument || node : preferredDoc;
3024
3025	// Return early if doc is invalid or already selected
3026	// Support: IE 11+, Edge 17 - 18+
3027	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3028	// two documents; shallow comparisons work.
3029	// eslint-disable-next-line eqeqeq
3030	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
3031		return document;
3032	}
3033
3034	// Update global variables
3035	document = doc;
3036	docElem = document.documentElement;
3037	documentIsHTML = !isXML( document );
3038
3039	// Support: IE 9 - 11+, Edge 12 - 18+
3040	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
3041	// Support: IE 11+, Edge 17 - 18+
3042	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3043	// two documents; shallow comparisons work.
3044	// eslint-disable-next-line eqeqeq
3045	if ( preferredDoc != document &&
3046		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
3047
3048		// Support: IE 11, Edge
3049		if ( subWindow.addEventListener ) {
3050			subWindow.addEventListener( "unload", unloadHandler, false );
3051
3052		// Support: IE 9 - 10 only
3053		} else if ( subWindow.attachEvent ) {
3054			subWindow.attachEvent( "onunload", unloadHandler );
3055		}
3056	}
3057
3058	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
3059	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
3060	// IE/Edge & older browsers don't support the :scope pseudo-class.
3061	// Support: Safari 6.0 only
3062	// Safari 6.0 supports :scope but it's an alias of :root there.
3063	support.scope = assert( function( el ) {
3064		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
3065		return typeof el.querySelectorAll !== "undefined" &&
3066			!el.querySelectorAll( ":scope fieldset div" ).length;
3067	} );
3068
3069	/* Attributes
3070	---------------------------------------------------------------------- */
3071
3072	// Support: IE<8
3073	// Verify that getAttribute really returns attributes and not properties
3074	// (excepting IE8 booleans)
3075	support.attributes = assert( function( el ) {
3076		el.className = "i";
3077		return !el.getAttribute( "className" );
3078	} );
3079
3080	/* getElement(s)By*
3081	---------------------------------------------------------------------- */
3082
3083	// Check if getElementsByTagName("*") returns only elements
3084	support.getElementsByTagName = assert( function( el ) {
3085		el.appendChild( document.createComment( "" ) );
3086		return !el.getElementsByTagName( "*" ).length;
3087	} );
3088
3089	// Support: IE<9
3090	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
3091
3092	// Support: IE<10
3093	// Check if getElementById returns elements by name
3094	// The broken getElementById methods don't pick up programmatically-set names,
3095	// so use a roundabout getElementsByName test
3096	support.getById = assert( function( el ) {
3097		docElem.appendChild( el ).id = expando;
3098		return !document.getElementsByName || !document.getElementsByName( expando ).length;
3099	} );
3100
3101	// ID filter and find
3102	if ( support.getById ) {
3103		Expr.filter[ "ID" ] = function( id ) {
3104			var attrId = id.replace( runescape, funescape );
3105			return function( elem ) {
3106				return elem.getAttribute( "id" ) === attrId;
3107			};
3108		};
3109		Expr.find[ "ID" ] = function( id, context ) {
3110			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
3111				var elem = context.getElementById( id );
3112				return elem ? [ elem ] : [];
3113			}
3114		};
3115	} else {
3116		Expr.filter[ "ID" ] =  function( id ) {
3117			var attrId = id.replace( runescape, funescape );
3118			return function( elem ) {
3119				var node = typeof elem.getAttributeNode !== "undefined" &&
3120					elem.getAttributeNode( "id" );
3121				return node && node.value === attrId;
3122			};
3123		};
3124
3125		// Support: IE 6 - 7 only
3126		// getElementById is not reliable as a find shortcut
3127		Expr.find[ "ID" ] = function( id, context ) {
3128			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
3129				var node, i, elems,
3130					elem = context.getElementById( id );
3131
3132				if ( elem ) {
3133
3134					// Verify the id attribute
3135					node = elem.getAttributeNode( "id" );
3136					if ( node && node.value === id ) {
3137						return [ elem ];
3138					}
3139
3140					// Fall back on getElementsByName
3141					elems = context.getElementsByName( id );
3142					i = 0;
3143					while ( ( elem = elems[ i++ ] ) ) {
3144						node = elem.getAttributeNode( "id" );
3145						if ( node && node.value === id ) {
3146							return [ elem ];
3147						}
3148					}
3149				}
3150
3151				return [];
3152			}
3153		};
3154	}
3155
3156	// Tag
3157	Expr.find[ "TAG" ] = support.getElementsByTagName ?
3158		function( tag, context ) {
3159			if ( typeof context.getElementsByTagName !== "undefined" ) {
3160				return context.getElementsByTagName( tag );
3161
3162			// DocumentFragment nodes don't have gEBTN
3163			} else if ( support.qsa ) {
3164				return context.querySelectorAll( tag );
3165			}
3166		} :
3167
3168		function( tag, context ) {
3169			var elem,
3170				tmp = [],
3171				i = 0,
3172
3173				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
3174				results = context.getElementsByTagName( tag );
3175
3176			// Filter out possible comments
3177			if ( tag === "*" ) {
3178				while ( ( elem = results[ i++ ] ) ) {
3179					if ( elem.nodeType === 1 ) {
3180						tmp.push( elem );
3181					}
3182				}
3183
3184				return tmp;
3185			}
3186			return results;
3187		};
3188
3189	// Class
3190	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
3191		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
3192			return context.getElementsByClassName( className );
3193		}
3194	};
3195
3196	/* QSA/matchesSelector
3197	---------------------------------------------------------------------- */
3198
3199	// QSA and matchesSelector support
3200
3201	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
3202	rbuggyMatches = [];
3203
3204	// qSa(:focus) reports false when true (Chrome 21)
3205	// We allow this because of a bug in IE8/9 that throws an error
3206	// whenever `document.activeElement` is accessed on an iframe
3207	// So, we allow :focus to pass through QSA all the time to avoid the IE error
3208	// See https://bugs.jquery.com/ticket/13378
3209	rbuggyQSA = [];
3210
3211	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
3212
3213		// Build QSA regex
3214		// Regex strategy adopted from Diego Perini
3215		assert( function( el ) {
3216
3217			var input;
3218
3219			// Select is set to empty string on purpose
3220			// This is to test IE's treatment of not explicitly
3221			// setting a boolean content attribute,
3222			// since its presence should be enough
3223			// https://bugs.jquery.com/ticket/12359
3224			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
3225				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
3226				"<option selected=''></option></select>";
3227
3228			// Support: IE8, Opera 11-12.16
3229			// Nothing should be selected when empty strings follow ^= or $= or *=
3230			// The test attribute must be unknown in Opera but "safe" for WinRT
3231			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
3232			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
3233				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
3234			}
3235
3236			// Support: IE8
3237			// Boolean attributes and "value" are not treated correctly
3238			if ( !el.querySelectorAll( "[selected]" ).length ) {
3239				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
3240			}
3241
3242			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
3243			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
3244				rbuggyQSA.push( "~=" );
3245			}
3246
3247			// Support: IE 11+, Edge 15 - 18+
3248			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
3249			// Adding a temporary attribute to the document before the selection works
3250			// around the issue.
3251			// Interestingly, IE 10 & older don't seem to have the issue.
3252			input = document.createElement( "input" );
3253			input.setAttribute( "name", "" );
3254			el.appendChild( input );
3255			if ( !el.querySelectorAll( "[name='']" ).length ) {
3256				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
3257					whitespace + "*(?:''|\"\")" );
3258			}
3259
3260			// Webkit/Opera - :checked should return selected option elements
3261			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
3262			// IE8 throws error here and will not see later tests
3263			if ( !el.querySelectorAll( ":checked" ).length ) {
3264				rbuggyQSA.push( ":checked" );
3265			}
3266
3267			// Support: Safari 8+, iOS 8+
3268			// https://bugs.webkit.org/show_bug.cgi?id=136851
3269			// In-page `selector#id sibling-combinator selector` fails
3270			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
3271				rbuggyQSA.push( ".#.+[+~]" );
3272			}
3273
3274			// Support: Firefox <=3.6 - 5 only
3275			// Old Firefox doesn't throw on a badly-escaped identifier.
3276			el.querySelectorAll( "\\\f" );
3277			rbuggyQSA.push( "[\\r\\n\\f]" );
3278		} );
3279
3280		assert( function( el ) {
3281			el.innerHTML = "<a href='' disabled='disabled'></a>" +
3282				"<select disabled='disabled'><option/></select>";
3283
3284			// Support: Windows 8 Native Apps
3285			// The type and name attributes are restricted during .innerHTML assignment
3286			var input = document.createElement( "input" );
3287			input.setAttribute( "type", "hidden" );
3288			el.appendChild( input ).setAttribute( "name", "D" );
3289
3290			// Support: IE8
3291			// Enforce case-sensitivity of name attribute
3292			if ( el.querySelectorAll( "[name=d]" ).length ) {
3293				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
3294			}
3295
3296			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
3297			// IE8 throws error here and will not see later tests
3298			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
3299				rbuggyQSA.push( ":enabled", ":disabled" );
3300			}
3301
3302			// Support: IE9-11+
3303			// IE's :disabled selector does not pick up the children of disabled fieldsets
3304			docElem.appendChild( el ).disabled = true;
3305			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
3306				rbuggyQSA.push( ":enabled", ":disabled" );
3307			}
3308
3309			// Support: Opera 10 - 11 only
3310			// Opera 10-11 does not throw on post-comma invalid pseudos
3311			el.querySelectorAll( "*,:x" );
3312			rbuggyQSA.push( ",.*:" );
3313		} );
3314	}
3315
3316	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
3317		docElem.webkitMatchesSelector ||
3318		docElem.mozMatchesSelector ||
3319		docElem.oMatchesSelector ||
3320		docElem.msMatchesSelector ) ) ) ) {
3321
3322		assert( function( el ) {
3323
3324			// Check to see if it's possible to do matchesSelector
3325			// on a disconnected node (IE 9)
3326			support.disconnectedMatch = matches.call( el, "*" );
3327
3328			// This should fail with an exception
3329			// Gecko does not error, returns false instead
3330			matches.call( el, "[s!='']:x" );
3331			rbuggyMatches.push( "!=", pseudos );
3332		} );
3333	}
3334
3335	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
3336	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
3337
3338	/* Contains
3339	---------------------------------------------------------------------- */
3340	hasCompare = rnative.test( docElem.compareDocumentPosition );
3341
3342	// Element contains another
3343	// Purposefully self-exclusive
3344	// As in, an element does not contain itself
3345	contains = hasCompare || rnative.test( docElem.contains ) ?
3346		function( a, b ) {
3347			var adown = a.nodeType === 9 ? a.documentElement : a,
3348				bup = b && b.parentNode;
3349			return a === bup || !!( bup && bup.nodeType === 1 && (
3350				adown.contains ?
3351					adown.contains( bup ) :
3352					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
3353			) );
3354		} :
3355		function( a, b ) {
3356			if ( b ) {
3357				while ( ( b = b.parentNode ) ) {
3358					if ( b === a ) {
3359						return true;
3360					}
3361				}
3362			}
3363			return false;
3364		};
3365
3366	/* Sorting
3367	---------------------------------------------------------------------- */
3368
3369	// Document order sorting
3370	sortOrder = hasCompare ?
3371	function( a, b ) {
3372
3373		// Flag for duplicate removal
3374		if ( a === b ) {
3375			hasDuplicate = true;
3376			return 0;
3377		}
3378
3379		// Sort on method existence if only one input has compareDocumentPosition
3380		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
3381		if ( compare ) {
3382			return compare;
3383		}
3384
3385		// Calculate position if both inputs belong to the same document
3386		// Support: IE 11+, Edge 17 - 18+
3387		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3388		// two documents; shallow comparisons work.
3389		// eslint-disable-next-line eqeqeq
3390		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
3391			a.compareDocumentPosition( b ) :
3392
3393			// Otherwise we know they are disconnected
3394			1;
3395
3396		// Disconnected nodes
3397		if ( compare & 1 ||
3398			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
3399
3400			// Choose the first element that is related to our preferred document
3401			// Support: IE 11+, Edge 17 - 18+
3402			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3403			// two documents; shallow comparisons work.
3404			// eslint-disable-next-line eqeqeq
3405			if ( a == document || a.ownerDocument == preferredDoc &&
3406				contains( preferredDoc, a ) ) {
3407				return -1;
3408			}
3409
3410			// Support: IE 11+, Edge 17 - 18+
3411			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3412			// two documents; shallow comparisons work.
3413			// eslint-disable-next-line eqeqeq
3414			if ( b == document || b.ownerDocument == preferredDoc &&
3415				contains( preferredDoc, b ) ) {
3416				return 1;
3417			}
3418
3419			// Maintain original order
3420			return sortInput ?
3421				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
3422				0;
3423		}
3424
3425		return compare & 4 ? -1 : 1;
3426	} :
3427	function( a, b ) {
3428
3429		// Exit early if the nodes are identical
3430		if ( a === b ) {
3431			hasDuplicate = true;
3432			return 0;
3433		}
3434
3435		var cur,
3436			i = 0,
3437			aup = a.parentNode,
3438			bup = b.parentNode,
3439			ap = [ a ],
3440			bp = [ b ];
3441
3442		// Parentless nodes are either documents or disconnected
3443		if ( !aup || !bup ) {
3444
3445			// Support: IE 11+, Edge 17 - 18+
3446			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3447			// two documents; shallow comparisons work.
3448			/* eslint-disable eqeqeq */
3449			return a == document ? -1 :
3450				b == document ? 1 :
3451				/* eslint-enable eqeqeq */
3452				aup ? -1 :
3453				bup ? 1 :
3454				sortInput ?
3455				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
3456				0;
3457
3458		// If the nodes are siblings, we can do a quick check
3459		} else if ( aup === bup ) {
3460			return siblingCheck( a, b );
3461		}
3462
3463		// Otherwise we need full lists of their ancestors for comparison
3464		cur = a;
3465		while ( ( cur = cur.parentNode ) ) {
3466			ap.unshift( cur );
3467		}
3468		cur = b;
3469		while ( ( cur = cur.parentNode ) ) {
3470			bp.unshift( cur );
3471		}
3472
3473		// Walk down the tree looking for a discrepancy
3474		while ( ap[ i ] === bp[ i ] ) {
3475			i++;
3476		}
3477
3478		return i ?
3479
3480			// Do a sibling check if the nodes have a common ancestor
3481			siblingCheck( ap[ i ], bp[ i ] ) :
3482
3483			// Otherwise nodes in our document sort first
3484			// Support: IE 11+, Edge 17 - 18+
3485			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3486			// two documents; shallow comparisons work.
3487			/* eslint-disable eqeqeq */
3488			ap[ i ] == preferredDoc ? -1 :
3489			bp[ i ] == preferredDoc ? 1 :
3490			/* eslint-enable eqeqeq */
3491			0;
3492	};
3493
3494	return document;
3495};
3496
3497Sizzle.matches = function( expr, elements ) {
3498	return Sizzle( expr, null, null, elements );
3499};
3500
3501Sizzle.matchesSelector = function( elem, expr ) {
3502	setDocument( elem );
3503
3504	if ( support.matchesSelector && documentIsHTML &&
3505		!nonnativeSelectorCache[ expr + " " ] &&
3506		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
3507		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
3508
3509		try {
3510			var ret = matches.call( elem, expr );
3511
3512			// IE 9's matchesSelector returns false on disconnected nodes
3513			if ( ret || support.disconnectedMatch ||
3514
3515				// As well, disconnected nodes are said to be in a document
3516				// fragment in IE 9
3517				elem.document && elem.document.nodeType !== 11 ) {
3518				return ret;
3519			}
3520		} catch ( e ) {
3521			nonnativeSelectorCache( expr, true );
3522		}
3523	}
3524
3525	return Sizzle( expr, document, null, [ elem ] ).length > 0;
3526};
3527
3528Sizzle.contains = function( context, elem ) {
3529
3530	// Set document vars if needed
3531	// Support: IE 11+, Edge 17 - 18+
3532	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3533	// two documents; shallow comparisons work.
3534	// eslint-disable-next-line eqeqeq
3535	if ( ( context.ownerDocument || context ) != document ) {
3536		setDocument( context );
3537	}
3538	return contains( context, elem );
3539};
3540
3541Sizzle.attr = function( elem, name ) {
3542
3543	// Set document vars if needed
3544	// Support: IE 11+, Edge 17 - 18+
3545	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3546	// two documents; shallow comparisons work.
3547	// eslint-disable-next-line eqeqeq
3548	if ( ( elem.ownerDocument || elem ) != document ) {
3549		setDocument( elem );
3550	}
3551
3552	var fn = Expr.attrHandle[ name.toLowerCase() ],
3553
3554		// Don't get fooled by Object.prototype properties (jQuery #13807)
3555		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
3556			fn( elem, name, !documentIsHTML ) :
3557			undefined;
3558
3559	return val !== undefined ?
3560		val :
3561		support.attributes || !documentIsHTML ?
3562			elem.getAttribute( name ) :
3563			( val = elem.getAttributeNode( name ) ) && val.specified ?
3564				val.value :
3565				null;
3566};
3567
3568Sizzle.escape = function( sel ) {
3569	return ( sel + "" ).replace( rcssescape, fcssescape );
3570};
3571
3572Sizzle.error = function( msg ) {
3573	throw new Error( "Syntax error, unrecognized expression: " + msg );
3574};
3575
3576/**
3577 * Document sorting and removing duplicates
3578 * @param {ArrayLike} results
3579 */
3580Sizzle.uniqueSort = function( results ) {
3581	var elem,
3582		duplicates = [],
3583		j = 0,
3584		i = 0;
3585
3586	// Unless we *know* we can detect duplicates, assume their presence
3587	hasDuplicate = !support.detectDuplicates;
3588	sortInput = !support.sortStable && results.slice( 0 );
3589	results.sort( sortOrder );
3590
3591	if ( hasDuplicate ) {
3592		while ( ( elem = results[ i++ ] ) ) {
3593			if ( elem === results[ i ] ) {
3594				j = duplicates.push( i );
3595			}
3596		}
3597		while ( j-- ) {
3598			results.splice( duplicates[ j ], 1 );
3599		}
3600	}
3601
3602	// Clear input after sorting to release objects
3603	// See https://github.com/jquery/sizzle/pull/225
3604	sortInput = null;
3605
3606	return results;
3607};
3608
3609/**
3610 * Utility function for retrieving the text value of an array of DOM nodes
3611 * @param {Array|Element} elem
3612 */
3613getText = Sizzle.getText = function( elem ) {
3614	var node,
3615		ret = "",
3616		i = 0,
3617		nodeType = elem.nodeType;
3618
3619	if ( !nodeType ) {
3620
3621		// If no nodeType, this is expected to be an array
3622		while ( ( node = elem[ i++ ] ) ) {
3623
3624			// Do not traverse comment nodes
3625			ret += getText( node );
3626		}
3627	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3628
3629		// Use textContent for elements
3630		// innerText usage removed for consistency of new lines (jQuery #11153)
3631		if ( typeof elem.textContent === "string" ) {
3632			return elem.textContent;
3633		} else {
3634
3635			// Traverse its children
3636			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
3637				ret += getText( elem );
3638			}
3639		}
3640	} else if ( nodeType === 3 || nodeType === 4 ) {
3641		return elem.nodeValue;
3642	}
3643
3644	// Do not include comment or processing instruction nodes
3645
3646	return ret;
3647};
3648
3649Expr = Sizzle.selectors = {
3650
3651	// Can be adjusted by the user
3652	cacheLength: 50,
3653
3654	createPseudo: markFunction,
3655
3656	match: matchExpr,
3657
3658	attrHandle: {},
3659
3660	find: {},
3661
3662	relative: {
3663		">": { dir: "parentNode", first: true },
3664		" ": { dir: "parentNode" },
3665		"+": { dir: "previousSibling", first: true },
3666		"~": { dir: "previousSibling" }
3667	},
3668
3669	preFilter: {
3670		"ATTR": function( match ) {
3671			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
3672
3673			// Move the given value to match[3] whether quoted or unquoted
3674			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
3675				match[ 5 ] || "" ).replace( runescape, funescape );
3676
3677			if ( match[ 2 ] === "~=" ) {
3678				match[ 3 ] = " " + match[ 3 ] + " ";
3679			}
3680
3681			return match.slice( 0, 4 );
3682		},
3683
3684		"CHILD": function( match ) {
3685
3686			/* matches from matchExpr["CHILD"]
3687				1 type (only|nth|...)
3688				2 what (child|of-type)
3689				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
3690				4 xn-component of xn+y argument ([+-]?\d*n|)
3691				5 sign of xn-component
3692				6 x of xn-component
3693				7 sign of y-component
3694				8 y of y-component
3695			*/
3696			match[ 1 ] = match[ 1 ].toLowerCase();
3697
3698			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
3699
3700				// nth-* requires argument
3701				if ( !match[ 3 ] ) {
3702					Sizzle.error( match[ 0 ] );
3703				}
3704
3705				// numeric x and y parameters for Expr.filter.CHILD
3706				// remember that false/true cast respectively to 0/1
3707				match[ 4 ] = +( match[ 4 ] ?
3708					match[ 5 ] + ( match[ 6 ] || 1 ) :
3709					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
3710				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
3711
3712				// other types prohibit arguments
3713			} else if ( match[ 3 ] ) {
3714				Sizzle.error( match[ 0 ] );
3715			}
3716
3717			return match;
3718		},
3719
3720		"PSEUDO": function( match ) {
3721			var excess,
3722				unquoted = !match[ 6 ] && match[ 2 ];
3723
3724			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
3725				return null;
3726			}
3727
3728			// Accept quoted arguments as-is
3729			if ( match[ 3 ] ) {
3730				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
3731
3732			// Strip excess characters from unquoted arguments
3733			} else if ( unquoted && rpseudo.test( unquoted ) &&
3734
3735				// Get excess from tokenize (recursively)
3736				( excess = tokenize( unquoted, true ) ) &&
3737
3738				// advance to the next closing parenthesis
3739				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
3740
3741				// excess is a negative index
3742				match[ 0 ] = match[ 0 ].slice( 0, excess );
3743				match[ 2 ] = unquoted.slice( 0, excess );
3744			}
3745
3746			// Return only captures needed by the pseudo filter method (type and argument)
3747			return match.slice( 0, 3 );
3748		}
3749	},
3750
3751	filter: {
3752
3753		"TAG": function( nodeNameSelector ) {
3754			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
3755			return nodeNameSelector === "*" ?
3756				function() {
3757					return true;
3758				} :
3759				function( elem ) {
3760					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
3761				};
3762		},
3763
3764		"CLASS": function( className ) {
3765			var pattern = classCache[ className + " " ];
3766
3767			return pattern ||
3768				( pattern = new RegExp( "(^|" + whitespace +
3769					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
3770						className, function( elem ) {
3771							return pattern.test(
3772								typeof elem.className === "string" && elem.className ||
3773								typeof elem.getAttribute !== "undefined" &&
3774									elem.getAttribute( "class" ) ||
3775								""
3776							);
3777				} );
3778		},
3779
3780		"ATTR": function( name, operator, check ) {
3781			return function( elem ) {
3782				var result = Sizzle.attr( elem, name );
3783
3784				if ( result == null ) {
3785					return operator === "!=";
3786				}
3787				if ( !operator ) {
3788					return true;
3789				}
3790
3791				result += "";
3792
3793				/* eslint-disable max-len */
3794
3795				return operator === "=" ? result === check :
3796					operator === "!=" ? result !== check :
3797					operator === "^=" ? check && result.indexOf( check ) === 0 :
3798					operator === "*=" ? check && result.indexOf( check ) > -1 :
3799					operator === "$=" ? check && result.slice( -check.length ) === check :
3800					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
3801					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
3802					false;
3803				/* eslint-enable max-len */
3804
3805			};
3806		},
3807
3808		"CHILD": function( type, what, _argument, first, last ) {
3809			var simple = type.slice( 0, 3 ) !== "nth",
3810				forward = type.slice( -4 ) !== "last",
3811				ofType = what === "of-type";
3812
3813			return first === 1 && last === 0 ?
3814
3815				// Shortcut for :nth-*(n)
3816				function( elem ) {
3817					return !!elem.parentNode;
3818				} :
3819
3820				function( elem, _context, xml ) {
3821					var cache, uniqueCache, outerCache, node, nodeIndex, start,
3822						dir = simple !== forward ? "nextSibling" : "previousSibling",
3823						parent = elem.parentNode,
3824						name = ofType && elem.nodeName.toLowerCase(),
3825						useCache = !xml && !ofType,
3826						diff = false;
3827
3828					if ( parent ) {
3829
3830						// :(first|last|only)-(child|of-type)
3831						if ( simple ) {
3832							while ( dir ) {
3833								node = elem;
3834								while ( ( node = node[ dir ] ) ) {
3835									if ( ofType ?
3836										node.nodeName.toLowerCase() === name :
3837										node.nodeType === 1 ) {
3838
3839										return false;
3840									}
3841								}
3842
3843								// Reverse direction for :only-* (if we haven't yet done so)
3844								start = dir = type === "only" && !start && "nextSibling";
3845							}
3846							return true;
3847						}
3848
3849						start = [ forward ? parent.firstChild : parent.lastChild ];
3850
3851						// non-xml :nth-child(...) stores cache data on `parent`
3852						if ( forward && useCache ) {
3853
3854							// Seek `elem` from a previously-cached index
3855
3856							// ...in a gzip-friendly way
3857							node = parent;
3858							outerCache = node[ expando ] || ( node[ expando ] = {} );
3859
3860							// Support: IE <9 only
3861							// Defend against cloned attroperties (jQuery gh-1709)
3862							uniqueCache = outerCache[ node.uniqueID ] ||
3863								( outerCache[ node.uniqueID ] = {} );
3864
3865							cache = uniqueCache[ type ] || [];
3866							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
3867							diff = nodeIndex && cache[ 2 ];
3868							node = nodeIndex && parent.childNodes[ nodeIndex ];
3869
3870							while ( ( node = ++nodeIndex && node && node[ dir ] ||
3871
3872								// Fallback to seeking `elem` from the start
3873								( diff = nodeIndex = 0 ) || start.pop() ) ) {
3874
3875								// When found, cache indexes on `parent` and break
3876								if ( node.nodeType === 1 && ++diff && node === elem ) {
3877									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
3878									break;
3879								}
3880							}
3881
3882						} else {
3883
3884							// Use previously-cached element index if available
3885							if ( useCache ) {
3886
3887								// ...in a gzip-friendly way
3888								node = elem;
3889								outerCache = node[ expando ] || ( node[ expando ] = {} );
3890
3891								// Support: IE <9 only
3892								// Defend against cloned attroperties (jQuery gh-1709)
3893								uniqueCache = outerCache[ node.uniqueID ] ||
3894									( outerCache[ node.uniqueID ] = {} );
3895
3896								cache = uniqueCache[ type ] || [];
3897								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
3898								diff = nodeIndex;
3899							}
3900
3901							// xml :nth-child(...)
3902							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
3903							if ( diff === false ) {
3904
3905								// Use the same loop as above to seek `elem` from the start
3906								while ( ( node = ++nodeIndex && node && node[ dir ] ||
3907									( diff = nodeIndex = 0 ) || start.pop() ) ) {
3908
3909									if ( ( ofType ?
3910										node.nodeName.toLowerCase() === name :
3911										node.nodeType === 1 ) &&
3912										++diff ) {
3913
3914										// Cache the index of each encountered element
3915										if ( useCache ) {
3916											outerCache = node[ expando ] ||
3917												( node[ expando ] = {} );
3918
3919											// Support: IE <9 only
3920											// Defend against cloned attroperties (jQuery gh-1709)
3921											uniqueCache = outerCache[ node.uniqueID ] ||
3922												( outerCache[ node.uniqueID ] = {} );
3923
3924											uniqueCache[ type ] = [ dirruns, diff ];
3925										}
3926
3927										if ( node === elem ) {
3928											break;
3929										}
3930									}
3931								}
3932							}
3933						}
3934
3935						// Incorporate the offset, then check against cycle size
3936						diff -= last;
3937						return diff === first || ( diff % first === 0 && diff / first >= 0 );
3938					}
3939				};
3940		},
3941
3942		"PSEUDO": function( pseudo, argument ) {
3943
3944			// pseudo-class names are case-insensitive
3945			// http://www.w3.org/TR/selectors/#pseudo-classes
3946			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
3947			// Remember that setFilters inherits from pseudos
3948			var args,
3949				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
3950					Sizzle.error( "unsupported pseudo: " + pseudo );
3951
3952			// The user may use createPseudo to indicate that
3953			// arguments are needed to create the filter function
3954			// just as Sizzle does
3955			if ( fn[ expando ] ) {
3956				return fn( argument );
3957			}
3958
3959			// But maintain support for old signatures
3960			if ( fn.length > 1 ) {
3961				args = [ pseudo, pseudo, "", argument ];
3962				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
3963					markFunction( function( seed, matches ) {
3964						var idx,
3965							matched = fn( seed, argument ),
3966							i = matched.length;
3967						while ( i-- ) {
3968							idx = indexOf( seed, matched[ i ] );
3969							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
3970						}
3971					} ) :
3972					function( elem ) {
3973						return fn( elem, 0, args );
3974					};
3975			}
3976
3977			return fn;
3978		}
3979	},
3980
3981	pseudos: {
3982
3983		// Potentially complex pseudos
3984		"not": markFunction( function( selector ) {
3985
3986			// Trim the selector passed to compile
3987			// to avoid treating leading and trailing
3988			// spaces as combinators
3989			var input = [],
3990				results = [],
3991				matcher = compile( selector.replace( rtrim, "$1" ) );
3992
3993			return matcher[ expando ] ?
3994				markFunction( function( seed, matches, _context, xml ) {
3995					var elem,
3996						unmatched = matcher( seed, null, xml, [] ),
3997						i = seed.length;
3998
3999					// Match elements unmatched by `matcher`
4000					while ( i-- ) {
4001						if ( ( elem = unmatched[ i ] ) ) {
4002							seed[ i ] = !( matches[ i ] = elem );
4003						}
4004					}
4005				} ) :
4006				function( elem, _context, xml ) {
4007					input[ 0 ] = elem;
4008					matcher( input, null, xml, results );
4009
4010					// Don't keep the element (issue #299)
4011					input[ 0 ] = null;
4012					return !results.pop();
4013				};
4014		} ),
4015
4016		"has": markFunction( function( selector ) {
4017			return function( elem ) {
4018				return Sizzle( selector, elem ).length > 0;
4019			};
4020		} ),
4021
4022		"contains": markFunction( function( text ) {
4023			text = text.replace( runescape, funescape );
4024			return function( elem ) {
4025				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
4026			};
4027		} ),
4028
4029		// "Whether an element is represented by a :lang() selector
4030		// is based solely on the element's language value
4031		// being equal to the identifier C,
4032		// or beginning with the identifier C immediately followed by "-".
4033		// The matching of C against the element's language value is performed case-insensitively.
4034		// The identifier C does not have to be a valid language name."
4035		// http://www.w3.org/TR/selectors/#lang-pseudo
4036		"lang": markFunction( function( lang ) {
4037
4038			// lang value must be a valid identifier
4039			if ( !ridentifier.test( lang || "" ) ) {
4040				Sizzle.error( "unsupported lang: " + lang );
4041			}
4042			lang = lang.replace( runescape, funescape ).toLowerCase();
4043			return function( elem ) {
4044				var elemLang;
4045				do {
4046					if ( ( elemLang = documentIsHTML ?
4047						elem.lang :
4048						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
4049
4050						elemLang = elemLang.toLowerCase();
4051						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
4052					}
4053				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
4054				return false;
4055			};
4056		} ),
4057
4058		// Miscellaneous
4059		"target": function( elem ) {
4060			var hash = window.location && window.location.hash;
4061			return hash && hash.slice( 1 ) === elem.id;
4062		},
4063
4064		"root": function( elem ) {
4065			return elem === docElem;
4066		},
4067
4068		"focus": function( elem ) {
4069			return elem === document.activeElement &&
4070				( !document.hasFocus || document.hasFocus() ) &&
4071				!!( elem.type || elem.href || ~elem.tabIndex );
4072		},
4073
4074		// Boolean properties
4075		"enabled": createDisabledPseudo( false ),
4076		"disabled": createDisabledPseudo( true ),
4077
4078		"checked": function( elem ) {
4079
4080			// In CSS3, :checked should return both checked and selected elements
4081			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4082			var nodeName = elem.nodeName.toLowerCase();
4083			return ( nodeName === "input" && !!elem.checked ) ||
4084				( nodeName === "option" && !!elem.selected );
4085		},
4086
4087		"selected": function( elem ) {
4088
4089			// Accessing this property makes selected-by-default
4090			// options in Safari work properly
4091			if ( elem.parentNode ) {
4092				// eslint-disable-next-line no-unused-expressions
4093				elem.parentNode.selectedIndex;
4094			}
4095
4096			return elem.selected === true;
4097		},
4098
4099		// Contents
4100		"empty": function( elem ) {
4101
4102			// http://www.w3.org/TR/selectors/#empty-pseudo
4103			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
4104			//   but not by others (comment: 8; processing instruction: 7; etc.)
4105			// nodeType < 6 works because attributes (2) do not appear as children
4106			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4107				if ( elem.nodeType < 6 ) {
4108					return false;
4109				}
4110			}
4111			return true;
4112		},
4113
4114		"parent": function( elem ) {
4115			return !Expr.pseudos[ "empty" ]( elem );
4116		},
4117
4118		// Element/input types
4119		"header": function( elem ) {
4120			return rheader.test( elem.nodeName );
4121		},
4122
4123		"input": function( elem ) {
4124			return rinputs.test( elem.nodeName );
4125		},
4126
4127		"button": function( elem ) {
4128			var name = elem.nodeName.toLowerCase();
4129			return name === "input" && elem.type === "button" || name === "button";
4130		},
4131
4132		"text": function( elem ) {
4133			var attr;
4134			return elem.nodeName.toLowerCase() === "input" &&
4135				elem.type === "text" &&
4136
4137				// Support: IE<8
4138				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
4139				( ( attr = elem.getAttribute( "type" ) ) == null ||
4140					attr.toLowerCase() === "text" );
4141		},
4142
4143		// Position-in-collection
4144		"first": createPositionalPseudo( function() {
4145			return [ 0 ];
4146		} ),
4147
4148		"last": createPositionalPseudo( function( _matchIndexes, length ) {
4149			return [ length - 1 ];
4150		} ),
4151
4152		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
4153			return [ argument < 0 ? argument + length : argument ];
4154		} ),
4155
4156		"even": createPositionalPseudo( function( matchIndexes, length ) {
4157			var i = 0;
4158			for ( ; i < length; i += 2 ) {
4159				matchIndexes.push( i );
4160			}
4161			return matchIndexes;
4162		} ),
4163
4164		"odd": createPositionalPseudo( function( matchIndexes, length ) {
4165			var i = 1;
4166			for ( ; i < length; i += 2 ) {
4167				matchIndexes.push( i );
4168			}
4169			return matchIndexes;
4170		} ),
4171
4172		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
4173			var i = argument < 0 ?
4174				argument + length :
4175				argument > length ?
4176					length :
4177					argument;
4178			for ( ; --i >= 0; ) {
4179				matchIndexes.push( i );
4180			}
4181			return matchIndexes;
4182		} ),
4183
4184		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
4185			var i = argument < 0 ? argument + length : argument;
4186			for ( ; ++i < length; ) {
4187				matchIndexes.push( i );
4188			}
4189			return matchIndexes;
4190		} )
4191	}
4192};
4193
4194Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
4195
4196// Add button/input type pseudos
4197for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
4198	Expr.pseudos[ i ] = createInputPseudo( i );
4199}
4200for ( i in { submit: true, reset: true } ) {
4201	Expr.pseudos[ i ] = createButtonPseudo( i );
4202}
4203
4204// Easy API for creating new setFilters
4205function setFilters() {}
4206setFilters.prototype = Expr.filters = Expr.pseudos;
4207Expr.setFilters = new setFilters();
4208
4209tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
4210	var matched, match, tokens, type,
4211		soFar, groups, preFilters,
4212		cached = tokenCache[ selector + " " ];
4213
4214	if ( cached ) {
4215		return parseOnly ? 0 : cached.slice( 0 );
4216	}
4217
4218	soFar = selector;
4219	groups = [];
4220	preFilters = Expr.preFilter;
4221
4222	while ( soFar ) {
4223
4224		// Comma and first run
4225		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
4226			if ( match ) {
4227
4228				// Don't consume trailing commas as valid
4229				soFar = soFar.slice( match[ 0 ].length ) || soFar;
4230			}
4231			groups.push( ( tokens = [] ) );
4232		}
4233
4234		matched = false;
4235
4236		// Combinators
4237		if ( ( match = rcombinators.exec( soFar ) ) ) {
4238			matched = match.shift();
4239			tokens.push( {
4240				value: matched,
4241
4242				// Cast descendant combinators to space
4243				type: match[ 0 ].replace( rtrim, " " )
4244			} );
4245			soFar = soFar.slice( matched.length );
4246		}
4247
4248		// Filters
4249		for ( type in Expr.filter ) {
4250			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
4251				( match = preFilters[ type ]( match ) ) ) ) {
4252				matched = match.shift();
4253				tokens.push( {
4254					value: matched,
4255					type: type,
4256					matches: match
4257				} );
4258				soFar = soFar.slice( matched.length );
4259			}
4260		}
4261
4262		if ( !matched ) {
4263			break;
4264		}
4265	}
4266
4267	// Return the length of the invalid excess
4268	// if we're just parsing
4269	// Otherwise, throw an error or return tokens
4270	return parseOnly ?
4271		soFar.length :
4272		soFar ?
4273			Sizzle.error( selector ) :
4274
4275			// Cache the tokens
4276			tokenCache( selector, groups ).slice( 0 );
4277};
4278
4279function toSelector( tokens ) {
4280	var i = 0,
4281		len = tokens.length,
4282		selector = "";
4283	for ( ; i < len; i++ ) {
4284		selector += tokens[ i ].value;
4285	}
4286	return selector;
4287}
4288
4289function addCombinator( matcher, combinator, base ) {
4290	var dir = combinator.dir,
4291		skip = combinator.next,
4292		key = skip || dir,
4293		checkNonElements = base && key === "parentNode",
4294		doneName = done++;
4295
4296	return combinator.first ?
4297
4298		// Check against closest ancestor/preceding element
4299		function( elem, context, xml ) {
4300			while ( ( elem = elem[ dir ] ) ) {
4301				if ( elem.nodeType === 1 || checkNonElements ) {
4302					return matcher( elem, context, xml );
4303				}
4304			}
4305			return false;
4306		} :
4307
4308		// Check against all ancestor/preceding elements
4309		function( elem, context, xml ) {
4310			var oldCache, uniqueCache, outerCache,
4311				newCache = [ dirruns, doneName ];
4312
4313			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
4314			if ( xml ) {
4315				while ( ( elem = elem[ dir ] ) ) {
4316					if ( elem.nodeType === 1 || checkNonElements ) {
4317						if ( matcher( elem, context, xml ) ) {
4318							return true;
4319						}
4320					}
4321				}
4322			} else {
4323				while ( ( elem = elem[ dir ] ) ) {
4324					if ( elem.nodeType === 1 || checkNonElements ) {
4325						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
4326
4327						// Support: IE <9 only
4328						// Defend against cloned attroperties (jQuery gh-1709)
4329						uniqueCache = outerCache[ elem.uniqueID ] ||
4330							( outerCache[ elem.uniqueID ] = {} );
4331
4332						if ( skip && skip === elem.nodeName.toLowerCase() ) {
4333							elem = elem[ dir ] || elem;
4334						} else if ( ( oldCache = uniqueCache[ key ] ) &&
4335							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
4336
4337							// Assign to newCache so results back-propagate to previous elements
4338							return ( newCache[ 2 ] = oldCache[ 2 ] );
4339						} else {
4340
4341							// Reuse newcache so results back-propagate to previous elements
4342							uniqueCache[ key ] = newCache;
4343
4344							// A match means we're done; a fail means we have to keep checking
4345							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
4346								return true;
4347							}
4348						}
4349					}
4350				}
4351			}
4352			return false;
4353		};
4354}
4355
4356function elementMatcher( matchers ) {
4357	return matchers.length > 1 ?
4358		function( elem, context, xml ) {
4359			var i = matchers.length;
4360			while ( i-- ) {
4361				if ( !matchers[ i ]( elem, context, xml ) ) {
4362					return false;
4363				}
4364			}
4365			return true;
4366		} :
4367		matchers[ 0 ];
4368}
4369
4370function multipleContexts( selector, contexts, results ) {
4371	var i = 0,
4372		len = contexts.length;
4373	for ( ; i < len; i++ ) {
4374		Sizzle( selector, contexts[ i ], results );
4375	}
4376	return results;
4377}
4378
4379function condense( unmatched, map, filter, context, xml ) {
4380	var elem,
4381		newUnmatched = [],
4382		i = 0,
4383		len = unmatched.length,
4384		mapped = map != null;
4385
4386	for ( ; i < len; i++ ) {
4387		if ( ( elem = unmatched[ i ] ) ) {
4388			if ( !filter || filter( elem, context, xml ) ) {
4389				newUnmatched.push( elem );
4390				if ( mapped ) {
4391					map.push( i );
4392				}
4393			}
4394		}
4395	}
4396
4397	return newUnmatched;
4398}
4399
4400function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4401	if ( postFilter && !postFilter[ expando ] ) {
4402		postFilter = setMatcher( postFilter );
4403	}
4404	if ( postFinder && !postFinder[ expando ] ) {
4405		postFinder = setMatcher( postFinder, postSelector );
4406	}
4407	return markFunction( function( seed, results, context, xml ) {
4408		var temp, i, elem,
4409			preMap = [],
4410			postMap = [],
4411			preexisting = results.length,
4412
4413			// Get initial elements from seed or context
4414			elems = seed || multipleContexts(
4415				selector || "*",
4416				context.nodeType ? [ context ] : context,
4417				[]
4418			),
4419
4420			// Prefilter to get matcher input, preserving a map for seed-results synchronization
4421			matcherIn = preFilter && ( seed || !selector ) ?
4422				condense( elems, preMap, preFilter, context, xml ) :
4423				elems,
4424
4425			matcherOut = matcher ?
4426
4427				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
4428				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4429
4430					// ...intermediate processing is necessary
4431					[] :
4432
4433					// ...otherwise use results directly
4434					results :
4435				matcherIn;
4436
4437		// Find primary matches
4438		if ( matcher ) {
4439			matcher( matcherIn, matcherOut, context, xml );
4440		}
4441
4442		// Apply postFilter
4443		if ( postFilter ) {
4444			temp = condense( matcherOut, postMap );
4445			postFilter( temp, [], context, xml );
4446
4447			// Un-match failing elements by moving them back to matcherIn
4448			i = temp.length;
4449			while ( i-- ) {
4450				if ( ( elem = temp[ i ] ) ) {
4451					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
4452				}
4453			}
4454		}
4455
4456		if ( seed ) {
4457			if ( postFinder || preFilter ) {
4458				if ( postFinder ) {
4459
4460					// Get the final matcherOut by condensing this intermediate into postFinder contexts
4461					temp = [];
4462					i = matcherOut.length;
4463					while ( i-- ) {
4464						if ( ( elem = matcherOut[ i ] ) ) {
4465
4466							// Restore matcherIn since elem is not yet a final match
4467							temp.push( ( matcherIn[ i ] = elem ) );
4468						}
4469					}
4470					postFinder( null, ( matcherOut = [] ), temp, xml );
4471				}
4472
4473				// Move matched elements from seed to results to keep them synchronized
4474				i = matcherOut.length;
4475				while ( i-- ) {
4476					if ( ( elem = matcherOut[ i ] ) &&
4477						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
4478
4479						seed[ temp ] = !( results[ temp ] = elem );
4480					}
4481				}
4482			}
4483
4484		// Add elements to results, through postFinder if defined
4485		} else {
4486			matcherOut = condense(
4487				matcherOut === results ?
4488					matcherOut.splice( preexisting, matcherOut.length ) :
4489					matcherOut
4490			);
4491			if ( postFinder ) {
4492				postFinder( null, results, matcherOut, xml );
4493			} else {
4494				push.apply( results, matcherOut );
4495			}
4496		}
4497	} );
4498}
4499
4500function matcherFromTokens( tokens ) {
4501	var checkContext, matcher, j,
4502		len = tokens.length,
4503		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
4504		implicitRelative = leadingRelative || Expr.relative[ " " ],
4505		i = leadingRelative ? 1 : 0,
4506
4507		// The foundational matcher ensures that elements are reachable from top-level context(s)
4508		matchContext = addCombinator( function( elem ) {
4509			return elem === checkContext;
4510		}, implicitRelative, true ),
4511		matchAnyContext = addCombinator( function( elem ) {
4512			return indexOf( checkContext, elem ) > -1;
4513		}, implicitRelative, true ),
4514		matchers = [ function( elem, context, xml ) {
4515			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
4516				( checkContext = context ).nodeType ?
4517					matchContext( elem, context, xml ) :
4518					matchAnyContext( elem, context, xml ) );
4519
4520			// Avoid hanging onto element (issue #299)
4521			checkContext = null;
4522			return ret;
4523		} ];
4524
4525	for ( ; i < len; i++ ) {
4526		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
4527			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4528		} else {
4529			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
4530
4531			// Return special upon seeing a positional matcher
4532			if ( matcher[ expando ] ) {
4533
4534				// Find the next relative operator (if any) for proper handling
4535				j = ++i;
4536				for ( ; j < len; j++ ) {
4537					if ( Expr.relative[ tokens[ j ].type ] ) {
4538						break;
4539					}
4540				}
4541				return setMatcher(
4542					i > 1 && elementMatcher( matchers ),
4543					i > 1 && toSelector(
4544
4545					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
4546					tokens
4547						.slice( 0, i - 1 )
4548						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
4549					).replace( rtrim, "$1" ),
4550					matcher,
4551					i < j && matcherFromTokens( tokens.slice( i, j ) ),
4552					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
4553					j < len && toSelector( tokens )
4554				);
4555			}
4556			matchers.push( matcher );
4557		}
4558	}
4559
4560	return elementMatcher( matchers );
4561}
4562
4563function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4564	var bySet = setMatchers.length > 0,
4565		byElement = elementMatchers.length > 0,
4566		superMatcher = function( seed, context, xml, results, outermost ) {
4567			var elem, j, matcher,
4568				matchedCount = 0,
4569				i = "0",
4570				unmatched = seed && [],
4571				setMatched = [],
4572				contextBackup = outermostContext,
4573
4574				// We must always have either seed elements or outermost context
4575				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
4576
4577				// Use integer dirruns iff this is the outermost matcher
4578				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
4579				len = elems.length;
4580
4581			if ( outermost ) {
4582
4583				// Support: IE 11+, Edge 17 - 18+
4584				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
4585				// two documents; shallow comparisons work.
4586				// eslint-disable-next-line eqeqeq
4587				outermostContext = context == document || context || outermost;
4588			}
4589
4590			// Add elements passing elementMatchers directly to results
4591			// Support: IE<9, Safari
4592			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
4593			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
4594				if ( byElement && elem ) {
4595					j = 0;
4596
4597					// Support: IE 11+, Edge 17 - 18+
4598					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
4599					// two documents; shallow comparisons work.
4600					// eslint-disable-next-line eqeqeq
4601					if ( !context && elem.ownerDocument != document ) {
4602						setDocument( elem );
4603						xml = !documentIsHTML;
4604					}
4605					while ( ( matcher = elementMatchers[ j++ ] ) ) {
4606						if ( matcher( elem, context || document, xml ) ) {
4607							results.push( elem );
4608							break;
4609						}
4610					}
4611					if ( outermost ) {
4612						dirruns = dirrunsUnique;
4613					}
4614				}
4615
4616				// Track unmatched elements for set filters
4617				if ( bySet ) {
4618
4619					// They will have gone through all possible matchers
4620					if ( ( elem = !matcher && elem ) ) {
4621						matchedCount--;
4622					}
4623
4624					// Lengthen the array for every element, matched or not
4625					if ( seed ) {
4626						unmatched.push( elem );
4627					}
4628				}
4629			}
4630
4631			// `i` is now the count of elements visited above, and adding it to `matchedCount`
4632			// makes the latter nonnegative.
4633			matchedCount += i;
4634
4635			// Apply set filters to unmatched elements
4636			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
4637			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
4638			// no element matchers and no seed.
4639			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
4640			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
4641			// numerically zero.
4642			if ( bySet && i !== matchedCount ) {
4643				j = 0;
4644				while ( ( matcher = setMatchers[ j++ ] ) ) {
4645					matcher( unmatched, setMatched, context, xml );
4646				}
4647
4648				if ( seed ) {
4649
4650					// Reintegrate element matches to eliminate the need for sorting
4651					if ( matchedCount > 0 ) {
4652						while ( i-- ) {
4653							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
4654								setMatched[ i ] = pop.call( results );
4655							}
4656						}
4657					}
4658
4659					// Discard index placeholder values to get only actual matches
4660					setMatched = condense( setMatched );
4661				}
4662
4663				// Add matches to results
4664				push.apply( results, setMatched );
4665
4666				// Seedless set matches succeeding multiple successful matchers stipulate sorting
4667				if ( outermost && !seed && setMatched.length > 0 &&
4668					( matchedCount + setMatchers.length ) > 1 ) {
4669
4670					Sizzle.uniqueSort( results );
4671				}
4672			}
4673
4674			// Override manipulation of globals by nested matchers
4675			if ( outermost ) {
4676				dirruns = dirrunsUnique;
4677				outermostContext = contextBackup;
4678			}
4679
4680			return unmatched;
4681		};
4682
4683	return bySet ?
4684		markFunction( superMatcher ) :
4685		superMatcher;
4686}
4687
4688compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
4689	var i,
4690		setMatchers = [],
4691		elementMatchers = [],
4692		cached = compilerCache[ selector + " " ];
4693
4694	if ( !cached ) {
4695
4696		// Generate a function of recursive functions that can be used to check each element
4697		if ( !match ) {
4698			match = tokenize( selector );
4699		}
4700		i = match.length;
4701		while ( i-- ) {
4702			cached = matcherFromTokens( match[ i ] );
4703			if ( cached[ expando ] ) {
4704				setMatchers.push( cached );
4705			} else {
4706				elementMatchers.push( cached );
4707			}
4708		}
4709
4710		// Cache the compiled function
4711		cached = compilerCache(
4712			selector,
4713			matcherFromGroupMatchers( elementMatchers, setMatchers )
4714		);
4715
4716		// Save selector and tokenization
4717		cached.selector = selector;
4718	}
4719	return cached;
4720};
4721
4722/**
4723 * A low-level selection function that works with Sizzle's compiled
4724 *  selector functions
4725 * @param {String|Function} selector A selector or a pre-compiled
4726 *  selector function built with Sizzle.compile
4727 * @param {Element} context
4728 * @param {Array} [results]
4729 * @param {Array} [seed] A set of elements to match against
4730 */
4731select = Sizzle.select = function( selector, context, results, seed ) {
4732	var i, tokens, token, type, find,
4733		compiled = typeof selector === "function" && selector,
4734		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
4735
4736	results = results || [];
4737
4738	// Try to minimize operations if there is only one selector in the list and no seed
4739	// (the latter of which guarantees us context)
4740	if ( match.length === 1 ) {
4741
4742		// Reduce context if the leading compound selector is an ID
4743		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
4744		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
4745			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
4746
4747			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
4748				.replace( runescape, funescape ), context ) || [] )[ 0 ];
4749			if ( !context ) {
4750				return results;
4751
4752			// Precompiled matchers will still verify ancestry, so step up a level
4753			} else if ( compiled ) {
4754				context = context.parentNode;
4755			}
4756
4757			selector = selector.slice( tokens.shift().value.length );
4758		}
4759
4760		// Fetch a seed set for right-to-left matching
4761		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
4762		while ( i-- ) {
4763			token = tokens[ i ];
4764
4765			// Abort if we hit a combinator
4766			if ( Expr.relative[ ( type = token.type ) ] ) {
4767				break;
4768			}
4769			if ( ( find = Expr.find[ type ] ) ) {
4770
4771				// Search, expanding context for leading sibling combinators
4772				if ( ( seed = find(
4773					token.matches[ 0 ].replace( runescape, funescape ),
4774					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
4775						context
4776				) ) ) {
4777
4778					// If seed is empty or no tokens remain, we can return early
4779					tokens.splice( i, 1 );
4780					selector = seed.length && toSelector( tokens );
4781					if ( !selector ) {
4782						push.apply( results, seed );
4783						return results;
4784					}
4785
4786					break;
4787				}
4788			}
4789		}
4790	}
4791
4792	// Compile and execute a filtering function if one is not provided
4793	// Provide `match` to avoid retokenization if we modified the selector above
4794	( compiled || compile( selector, match ) )(
4795		seed,
4796		context,
4797		!documentIsHTML,
4798		results,
4799		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
4800	);
4801	return results;
4802};
4803
4804// One-time assignments
4805
4806// Sort stability
4807support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
4808
4809// Support: Chrome 14-35+
4810// Always assume duplicates if they aren't passed to the comparison function
4811support.detectDuplicates = !!hasDuplicate;
4812
4813// Initialize against the default document
4814setDocument();
4815
4816// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
4817// Detached nodes confoundingly follow *each other*
4818support.sortDetached = assert( function( el ) {
4819
4820	// Should return 1, but returns 4 (following)
4821	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
4822} );
4823
4824// Support: IE<8
4825// Prevent attribute/property "interpolation"
4826// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
4827if ( !assert( function( el ) {
4828	el.innerHTML = "<a href='#'></a>";
4829	return el.firstChild.getAttribute( "href" ) === "#";
4830} ) ) {
4831	addHandle( "type|href|height|width", function( elem, name, isXML ) {
4832		if ( !isXML ) {
4833			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
4834		}
4835	} );
4836}
4837
4838// Support: IE<9
4839// Use defaultValue in place of getAttribute("value")
4840if ( !support.attributes || !assert( function( el ) {
4841	el.innerHTML = "<input/>";
4842	el.firstChild.setAttribute( "value", "" );
4843	return el.firstChild.getAttribute( "value" ) === "";
4844} ) ) {
4845	addHandle( "value", function( elem, _name, isXML ) {
4846		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
4847			return elem.defaultValue;
4848		}
4849	} );
4850}
4851
4852// Support: IE<9
4853// Use getAttributeNode to fetch booleans when getAttribute lies
4854if ( !assert( function( el ) {
4855	return el.getAttribute( "disabled" ) == null;
4856} ) ) {
4857	addHandle( booleans, function( elem, name, isXML ) {
4858		var val;
4859		if ( !isXML ) {
4860			return elem[ name ] === true ? name.toLowerCase() :
4861				( val = elem.getAttributeNode( name ) ) && val.specified ?
4862					val.value :
4863					null;
4864		}
4865	} );
4866}
4867
4868return Sizzle;
4869
4870} )( window );
4871
4872
4873
4874jQuery.find = Sizzle;
4875jQuery.expr = Sizzle.selectors;
4876
4877// Deprecated
4878jQuery.expr[ ":" ] = jQuery.expr.pseudos;
4879jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
4880jQuery.text = Sizzle.getText;
4881jQuery.isXMLDoc = Sizzle.isXML;
4882jQuery.contains = Sizzle.contains;
4883jQuery.escapeSelector = Sizzle.escape;
4884
4885
4886
4887
4888var dir = function( elem, dir, until ) {
4889	var matched = [],
4890		truncate = until !== undefined;
4891
4892	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
4893		if ( elem.nodeType === 1 ) {
4894			if ( truncate && jQuery( elem ).is( until ) ) {
4895				break;
4896			}
4897			matched.push( elem );
4898		}
4899	}
4900	return matched;
4901};
4902
4903
4904var siblings = function( n, elem ) {
4905	var matched = [];
4906
4907	for ( ; n; n = n.nextSibling ) {
4908		if ( n.nodeType === 1 && n !== elem ) {
4909			matched.push( n );
4910		}
4911	}
4912
4913	return matched;
4914};
4915
4916
4917var rneedsContext = jQuery.expr.match.needsContext;
4918
4919
4920
4921function nodeName( elem, name ) {
4922
4923	return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
4924
4925}
4926var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
4927
4928
4929
4930// Implement the identical functionality for filter and not
4931function winnow( elements, qualifier, not ) {
4932	if ( isFunction( qualifier ) ) {
4933		return jQuery.grep( elements, function( elem, i ) {
4934			return !!qualifier.call( elem, i, elem ) !== not;
4935		} );
4936	}
4937
4938	// Single element
4939	if ( qualifier.nodeType ) {
4940		return jQuery.grep( elements, function( elem ) {
4941			return ( elem === qualifier ) !== not;
4942		} );
4943	}
4944
4945	// Arraylike of elements (jQuery, arguments, Array)
4946	if ( typeof qualifier !== "string" ) {
4947		return jQuery.grep( elements, function( elem ) {
4948			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
4949		} );
4950	}
4951
4952	// Filtered directly for both simple and complex selectors
4953	return jQuery.filter( qualifier, elements, not );
4954}
4955
4956jQuery.filter = function( expr, elems, not ) {
4957	var elem = elems[ 0 ];
4958
4959	if ( not ) {
4960		expr = ":not(" + expr + ")";
4961	}
4962
4963	if ( elems.length === 1 && elem.nodeType === 1 ) {
4964		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
4965	}
4966
4967	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
4968		return elem.nodeType === 1;
4969	} ) );
4970};
4971
4972jQuery.fn.extend( {
4973	find: function( selector ) {
4974		var i, ret,
4975			len = this.length,
4976			self = this;
4977
4978		if ( typeof selector !== "string" ) {
4979			return this.pushStack( jQuery( selector ).filter( function() {
4980				for ( i = 0; i < len; i++ ) {
4981					if ( jQuery.contains( self[ i ], this ) ) {
4982						return true;
4983					}
4984				}
4985			} ) );
4986		}
4987
4988		ret = this.pushStack( [] );
4989
4990		for ( i = 0; i < len; i++ ) {
4991			jQuery.find( selector, self[ i ], ret );
4992		}
4993
4994		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
4995	},
4996	filter: function( selector ) {
4997		return this.pushStack( winnow( this, selector || [], false ) );
4998	},
4999	not: function( selector ) {
5000		return this.pushStack( winnow( this, selector || [], true ) );
5001	},
5002	is: function( selector ) {
5003		return !!winnow(
5004			this,
5005
5006			// If this is a positional/relative selector, check membership in the returned set
5007			// so $("p:first").is("p:last") won't return true for a doc with two "p".
5008			typeof selector === "string" && rneedsContext.test( selector ) ?
5009				jQuery( selector ) :
5010				selector || [],
5011			false
5012		).length;
5013	}
5014} );
5015
5016
5017// Initialize a jQuery object
5018
5019
5020// A central reference to the root jQuery(document)
5021var rootjQuery,
5022
5023	// A simple way to check for HTML strings
5024	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
5025	// Strict HTML recognition (#11290: must start with <)
5026	// Shortcut simple #id case for speed
5027	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
5028
5029	init = jQuery.fn.init = function( selector, context, root ) {
5030		var match, elem;
5031
5032		// HANDLE: $(""), $(null), $(undefined), $(false)
5033		if ( !selector ) {
5034			return this;
5035		}
5036
5037		// Method init() accepts an alternate rootjQuery
5038		// so migrate can support jQuery.sub (gh-2101)
5039		root = root || rootjQuery;
5040
5041		// Handle HTML strings
5042		if ( typeof selector === "string" ) {
5043			if ( selector[ 0 ] === "<" &&
5044				selector[ selector.length - 1 ] === ">" &&
5045				selector.length >= 3 ) {
5046
5047				// Assume that strings that start and end with <> are HTML and skip the regex check
5048				match = [ null, selector, null ];
5049
5050			} else {
5051				match = rquickExpr.exec( selector );
5052			}
5053
5054			// Match html or make sure no context is specified for #id
5055			if ( match && ( match[ 1 ] || !context ) ) {
5056
5057				// HANDLE: $(html) -> $(array)
5058				if ( match[ 1 ] ) {
5059					context = context instanceof jQuery ? context[ 0 ] : context;
5060
5061					// Option to run scripts is true for back-compat
5062					// Intentionally let the error be thrown if parseHTML is not present
5063					jQuery.merge( this, jQuery.parseHTML(
5064						match[ 1 ],
5065						context && context.nodeType ? context.ownerDocument || context : document,
5066						true
5067					) );
5068
5069					// HANDLE: $(html, props)
5070					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
5071						for ( match in context ) {
5072
5073							// Properties of context are called as methods if possible
5074							if ( isFunction( this[ match ] ) ) {
5075								this[ match ]( context[ match ] );
5076
5077							// ...and otherwise set as attributes
5078							} else {
5079								this.attr( match, context[ match ] );
5080							}
5081						}
5082					}
5083
5084					return this;
5085
5086				// HANDLE: $(#id)
5087				} else {
5088					elem = document.getElementById( match[ 2 ] );
5089
5090					if ( elem ) {
5091
5092						// Inject the element directly into the jQuery object
5093						this[ 0 ] = elem;
5094						this.length = 1;
5095					}
5096					return this;
5097				}
5098
5099			// HANDLE: $(expr, $(...))
5100			} else if ( !context || context.jquery ) {
5101				return ( context || root ).find( selector );
5102
5103			// HANDLE: $(expr, context)
5104			// (which is just equivalent to: $(context).find(expr)
5105			} else {
5106				return this.constructor( context ).find( selector );
5107			}
5108
5109		// HANDLE: $(DOMElement)
5110		} else if ( selector.nodeType ) {
5111			this[ 0 ] = selector;
5112			this.length = 1;
5113			return this;
5114
5115		// HANDLE: $(function)
5116		// Shortcut for document ready
5117		} else if ( isFunction( selector ) ) {
5118			return root.ready !== undefined ?
5119				root.ready( selector ) :
5120
5121				// Execute immediately if ready is not present
5122				selector( jQuery );
5123		}
5124
5125		return jQuery.makeArray( selector, this );
5126	};
5127
5128// Give the init function the jQuery prototype for later instantiation
5129init.prototype = jQuery.fn;
5130
5131// Initialize central reference
5132rootjQuery = jQuery( document );
5133
5134
5135var rparentsprev = /^(?:parents|prev(?:Until|All))/,
5136
5137	// Methods guaranteed to produce a unique set when starting from a unique set
5138	guaranteedUnique = {
5139		children: true,
5140		contents: true,
5141		next: true,
5142		prev: true
5143	};
5144
5145jQuery.fn.extend( {
5146	has: function( target ) {
5147		var targets = jQuery( target, this ),
5148			l = targets.length;
5149
5150		return this.filter( function() {
5151			var i = 0;
5152			for ( ; i < l; i++ ) {
5153				if ( jQuery.contains( this, targets[ i ] ) ) {
5154					return true;
5155				}
5156			}
5157		} );
5158	},
5159
5160	closest: function( selectors, context ) {
5161		var cur,
5162			i = 0,
5163			l = this.length,
5164			matched = [],
5165			targets = typeof selectors !== "string" && jQuery( selectors );
5166
5167		// Positional selectors never match, since there's no _selection_ context
5168		if ( !rneedsContext.test( selectors ) ) {
5169			for ( ; i < l; i++ ) {
5170				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
5171
5172					// Always skip document fragments
5173					if ( cur.nodeType < 11 && ( targets ?
5174						targets.index( cur ) > -1 :
5175
5176						// Don't pass non-elements to Sizzle
5177						cur.nodeType === 1 &&
5178							jQuery.find.matchesSelector( cur, selectors ) ) ) {
5179
5180						matched.push( cur );
5181						break;
5182					}
5183				}
5184			}
5185		}
5186
5187		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
5188	},
5189
5190	// Determine the position of an element within the set
5191	index: function( elem ) {
5192
5193		// No argument, return index in parent
5194		if ( !elem ) {
5195			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
5196		}
5197
5198		// Index in selector
5199		if ( typeof elem === "string" ) {
5200			return indexOf.call( jQuery( elem ), this[ 0 ] );
5201		}
5202
5203		// Locate the position of the desired element
5204		return indexOf.call( this,
5205
5206			// If it receives a jQuery object, the first element is used
5207			elem.jquery ? elem[ 0 ] : elem
5208		);
5209	},
5210
5211	add: function( selector, context ) {
5212		return this.pushStack(
5213			jQuery.uniqueSort(
5214				jQuery.merge( this.get(), jQuery( selector, context ) )
5215			)
5216		);
5217	},
5218
5219	addBack: function( selector ) {
5220		return this.add( selector == null ?
5221			this.prevObject : this.prevObject.filter( selector )
5222		);
5223	}
5224} );
5225
5226function sibling( cur, dir ) {
5227	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
5228	return cur;
5229}
5230
5231jQuery.each( {
5232	parent: function( elem ) {
5233		var parent = elem.parentNode;
5234		return parent && parent.nodeType !== 11 ? parent : null;
5235	},
5236	parents: function( elem ) {
5237		return dir( elem, "parentNode" );
5238	},
5239	parentsUntil: function( elem, _i, until ) {
5240		return dir( elem, "parentNode", until );
5241	},
5242	next: function( elem ) {
5243		return sibling( elem, "nextSibling" );
5244	},
5245	prev: function( elem ) {
5246		return sibling( elem, "previousSibling" );
5247	},
5248	nextAll: function( elem ) {
5249		return dir( elem, "nextSibling" );
5250	},
5251	prevAll: function( elem ) {
5252		return dir( elem, "previousSibling" );
5253	},
5254	nextUntil: function( elem, _i, until ) {
5255		return dir( elem, "nextSibling", until );
5256	},
5257	prevUntil: function( elem, _i, until ) {
5258		return dir( elem, "previousSibling", until );
5259	},
5260	siblings: function( elem ) {
5261		return siblings( ( elem.parentNode || {} ).firstChild, elem );
5262	},
5263	children: function( elem ) {
5264		return siblings( elem.firstChild );
5265	},
5266	contents: function( elem ) {
5267		if ( elem.contentDocument != null &&
5268
5269			// Support: IE 11+
5270			// <object> elements with no `data` attribute has an object
5271			// `contentDocument` with a `null` prototype.
5272			getProto( elem.contentDocument ) ) {
5273
5274			return elem.contentDocument;
5275		}
5276
5277		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
5278		// Treat the template element as a regular one in browsers that
5279		// don't support it.
5280		if ( nodeName( elem, "template" ) ) {
5281			elem = elem.content || elem;
5282		}
5283
5284		return jQuery.merge( [], elem.childNodes );
5285	}
5286}, function( name, fn ) {
5287	jQuery.fn[ name ] = function( until, selector ) {
5288		var matched = jQuery.map( this, fn, until );
5289
5290		if ( name.slice( -5 ) !== "Until" ) {
5291			selector = until;
5292		}
5293
5294		if ( selector && typeof selector === "string" ) {
5295			matched = jQuery.filter( selector, matched );
5296		}
5297
5298		if ( this.length > 1 ) {
5299
5300			// Remove duplicates
5301			if ( !guaranteedUnique[ name ] ) {
5302				jQuery.uniqueSort( matched );
5303			}
5304
5305			// Reverse order for parents* and prev-derivatives
5306			if ( rparentsprev.test( name ) ) {
5307				matched.reverse();
5308			}
5309		}
5310
5311		return this.pushStack( matched );
5312	};
5313} );
5314var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
5315
5316
5317
5318// Convert String-formatted options into Object-formatted ones
5319function createOptions( options ) {
5320	var object = {};
5321	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
5322		object[ flag ] = true;
5323	} );
5324	return object;
5325}
5326
5327/*
5328 * Create a callback list using the following parameters:
5329 *
5330 *	options: an optional list of space-separated options that will change how
5331 *			the callback list behaves or a more traditional option object
5332 *
5333 * By default a callback list will act like an event callback list and can be
5334 * "fired" multiple times.
5335 *
5336 * Possible options:
5337 *
5338 *	once:			will ensure the callback list can only be fired once (like a Deferred)
5339 *
5340 *	memory:			will keep track of previous values and will call any callback added
5341 *					after the list has been fired right away with the latest "memorized"
5342 *					values (like a Deferred)
5343 *
5344 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
5345 *
5346 *	stopOnFalse:	interrupt callings when a callback returns false
5347 *
5348 */
5349jQuery.Callbacks = function( options ) {
5350
5351	// Convert options from String-formatted to Object-formatted if needed
5352	// (we check in cache first)
5353	options = typeof options === "string" ?
5354		createOptions( options ) :
5355		jQuery.extend( {}, options );
5356
5357	var // Flag to know if list is currently firing
5358		firing,
5359
5360		// Last fire value for non-forgettable lists
5361		memory,
5362
5363		// Flag to know if list was already fired
5364		fired,
5365
5366		// Flag to prevent firing
5367		locked,
5368
5369		// Actual callback list
5370		list = [],
5371
5372		// Queue of execution data for repeatable lists
5373		queue = [],
5374
5375		// Index of currently firing callback (modified by add/remove as needed)
5376		firingIndex = -1,
5377
5378		// Fire callbacks
5379		fire = function() {
5380
5381			// Enforce single-firing
5382			locked = locked || options.once;
5383
5384			// Execute callbacks for all pending executions,
5385			// respecting firingIndex overrides and runtime changes
5386			fired = firing = true;
5387			for ( ; queue.length; firingIndex = -1 ) {
5388				memory = queue.shift();
5389				while ( ++firingIndex < list.length ) {
5390
5391					// Run callback and check for early termination
5392					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
5393						options.stopOnFalse ) {
5394
5395						// Jump to end and forget the data so .add doesn't re-fire
5396						firingIndex = list.length;
5397						memory = false;
5398					}
5399				}
5400			}
5401
5402			// Forget the data if we're done with it
5403			if ( !options.memory ) {
5404				memory = false;
5405			}
5406
5407			firing = false;
5408
5409			// Clean up if we're done firing for good
5410			if ( locked ) {
5411
5412				// Keep an empty list if we have data for future add calls
5413				if ( memory ) {
5414					list = [];
5415
5416				// Otherwise, this object is spent
5417				} else {
5418					list = "";
5419				}
5420			}
5421		},
5422
5423		// Actual Callbacks object
5424		self = {
5425
5426			// Add a callback or a collection of callbacks to the list
5427			add: function() {
5428				if ( list ) {
5429
5430					// If we have memory from a past run, we should fire after adding
5431					if ( memory && !firing ) {
5432						firingIndex = list.length - 1;
5433						queue.push( memory );
5434					}
5435
5436					( function add( args ) {
5437						jQuery.each( args, function( _, arg ) {
5438							if ( isFunction( arg ) ) {
5439								if ( !options.unique || !self.has( arg ) ) {
5440									list.push( arg );
5441								}
5442							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
5443
5444								// Inspect recursively
5445								add( arg );
5446							}
5447						} );
5448					} )( arguments );
5449
5450					if ( memory && !firing ) {
5451						fire();
5452					}
5453				}
5454				return this;
5455			},
5456
5457			// Remove a callback from the list
5458			remove: function() {
5459				jQuery.each( arguments, function( _, arg ) {
5460					var index;
5461					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
5462						list.splice( index, 1 );
5463
5464						// Handle firing indexes
5465						if ( index <= firingIndex ) {
5466							firingIndex--;
5467						}
5468					}
5469				} );
5470				return this;
5471			},
5472
5473			// Check if a given callback is in the list.
5474			// If no argument is given, return whether or not list has callbacks attached.
5475			has: function( fn ) {
5476				return fn ?
5477					jQuery.inArray( fn, list ) > -1 :
5478					list.length > 0;
5479			},
5480
5481			// Remove all callbacks from the list
5482			empty: function() {
5483				if ( list ) {
5484					list = [];
5485				}
5486				return this;
5487			},
5488
5489			// Disable .fire and .add
5490			// Abort any current/pending executions
5491			// Clear all callbacks and values
5492			disable: function() {
5493				locked = queue = [];
5494				list = memory = "";
5495				return this;
5496			},
5497			disabled: function() {
5498				return !list;
5499			},
5500
5501			// Disable .fire
5502			// Also disable .add unless we have memory (since it would have no effect)
5503			// Abort any pending executions
5504			lock: function() {
5505				locked = queue = [];
5506				if ( !memory && !firing ) {
5507					list = memory = "";
5508				}
5509				return this;
5510			},
5511			locked: function() {
5512				return !!locked;
5513			},
5514
5515			// Call all callbacks with the given context and arguments
5516			fireWith: function( context, args ) {
5517				if ( !locked ) {
5518					args = args || [];
5519					args = [ context, args.slice ? args.slice() : args ];
5520					queue.push( args );
5521					if ( !firing ) {
5522						fire();
5523					}
5524				}
5525				return this;
5526			},
5527
5528			// Call all the callbacks with the given arguments
5529			fire: function() {
5530				self.fireWith( this, arguments );
5531				return this;
5532			},
5533
5534			// To know if the callbacks have already been called at least once
5535			fired: function() {
5536				return !!fired;
5537			}
5538		};
5539
5540	return self;
5541};
5542
5543
5544function Identity( v ) {
5545	return v;
5546}
5547function Thrower( ex ) {
5548	throw ex;
5549}
5550
5551function adoptValue( value, resolve, reject, noValue ) {
5552	var method;
5553
5554	try {
5555
5556		// Check for promise aspect first to privilege synchronous behavior
5557		if ( value && isFunction( ( method = value.promise ) ) ) {
5558			method.call( value ).done( resolve ).fail( reject );
5559
5560		// Other thenables
5561		} else if ( value && isFunction( ( method = value.then ) ) ) {
5562			method.call( value, resolve, reject );
5563
5564		// Other non-thenables
5565		} else {
5566
5567			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
5568			// * false: [ value ].slice( 0 ) => resolve( value )
5569			// * true: [ value ].slice( 1 ) => resolve()
5570			resolve.apply( undefined, [ value ].slice( noValue ) );
5571		}
5572
5573	// For Promises/A+, convert exceptions into rejections
5574	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
5575	// Deferred#then to conditionally suppress rejection.
5576	} catch ( value ) {
5577
5578		// Support: Android 4.0 only
5579		// Strict mode functions invoked without .call/.apply get global-object context
5580		reject.apply( undefined, [ value ] );
5581	}
5582}
5583
5584jQuery.extend( {
5585
5586	Deferred: function( func ) {
5587		var tuples = [
5588
5589				// action, add listener, callbacks,
5590				// ... .then handlers, argument index, [final state]
5591				[ "notify", "progress", jQuery.Callbacks( "memory" ),
5592					jQuery.Callbacks( "memory" ), 2 ],
5593				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
5594					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
5595				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
5596					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
5597			],
5598			state = "pending",
5599			promise = {
5600				state: function() {
5601					return state;
5602				},
5603				always: function() {
5604					deferred.done( arguments ).fail( arguments );
5605					return this;
5606				},
5607				"catch": function( fn ) {
5608					return promise.then( null, fn );
5609				},
5610
5611				// Keep pipe for back-compat
5612				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
5613					var fns = arguments;
5614
5615					return jQuery.Deferred( function( newDefer ) {
5616						jQuery.each( tuples, function( _i, tuple ) {
5617
5618							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
5619							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
5620
5621							// deferred.progress(function() { bind to newDefer or newDefer.notify })
5622							// deferred.done(function() { bind to newDefer or newDefer.resolve })
5623							// deferred.fail(function() { bind to newDefer or newDefer.reject })
5624							deferred[ tuple[ 1 ] ]( function() {
5625								var returned = fn && fn.apply( this, arguments );
5626								if ( returned && isFunction( returned.promise ) ) {
5627									returned.promise()
5628										.progress( newDefer.notify )
5629										.done( newDefer.resolve )
5630										.fail( newDefer.reject );
5631								} else {
5632									newDefer[ tuple[ 0 ] + "With" ](
5633										this,
5634										fn ? [ returned ] : arguments
5635									);
5636								}
5637							} );
5638						} );
5639						fns = null;
5640					} ).promise();
5641				},
5642				then: function( onFulfilled, onRejected, onProgress ) {
5643					var maxDepth = 0;
5644					function resolve( depth, deferred, handler, special ) {
5645						return function() {
5646							var that = this,
5647								args = arguments,
5648								mightThrow = function() {
5649									var returned, then;
5650
5651									// Support: Promises/A+ section 2.3.3.3.3
5652									// https://promisesaplus.com/#point-59
5653									// Ignore double-resolution attempts
5654									if ( depth < maxDepth ) {
5655										return;
5656									}
5657
5658									returned = handler.apply( that, args );
5659
5660									// Support: Promises/A+ section 2.3.1
5661									// https://promisesaplus.com/#point-48
5662									if ( returned === deferred.promise() ) {
5663										throw new TypeError( "Thenable self-resolution" );
5664									}
5665
5666									// Support: Promises/A+ sections 2.3.3.1, 3.5
5667									// https://promisesaplus.com/#point-54
5668									// https://promisesaplus.com/#point-75
5669									// Retrieve `then` only once
5670									then = returned &&
5671
5672										// Support: Promises/A+ section 2.3.4
5673										// https://promisesaplus.com/#point-64
5674										// Only check objects and functions for thenability
5675										( typeof returned === "object" ||
5676											typeof returned === "function" ) &&
5677										returned.then;
5678
5679									// Handle a returned thenable
5680									if ( isFunction( then ) ) {
5681
5682										// Special processors (notify) just wait for resolution
5683										if ( special ) {
5684											then.call(
5685												returned,
5686												resolve( maxDepth, deferred, Identity, special ),
5687												resolve( maxDepth, deferred, Thrower, special )
5688											);
5689
5690										// Normal processors (resolve) also hook into progress
5691										} else {
5692
5693											// ...and disregard older resolution values
5694											maxDepth++;
5695
5696											then.call(
5697												returned,
5698												resolve( maxDepth, deferred, Identity, special ),
5699												resolve( maxDepth, deferred, Thrower, special ),
5700												resolve( maxDepth, deferred, Identity,
5701													deferred.notifyWith )
5702											);
5703										}
5704
5705									// Handle all other returned values
5706									} else {
5707
5708										// Only substitute handlers pass on context
5709										// and multiple values (non-spec behavior)
5710										if ( handler !== Identity ) {
5711											that = undefined;
5712											args = [ returned ];
5713										}
5714
5715										// Process the value(s)
5716										// Default process is resolve
5717										( special || deferred.resolveWith )( that, args );
5718									}
5719								},
5720
5721								// Only normal processors (resolve) catch and reject exceptions
5722								process = special ?
5723									mightThrow :
5724									function() {
5725										try {
5726											mightThrow();
5727										} catch ( e ) {
5728
5729											if ( jQuery.Deferred.exceptionHook ) {
5730												jQuery.Deferred.exceptionHook( e,
5731													process.stackTrace );
5732											}
5733
5734											// Support: Promises/A+ section 2.3.3.3.4.1
5735											// https://promisesaplus.com/#point-61
5736											// Ignore post-resolution exceptions
5737											if ( depth + 1 >= maxDepth ) {
5738
5739												// Only substitute handlers pass on context
5740												// and multiple values (non-spec behavior)
5741												if ( handler !== Thrower ) {
5742													that = undefined;
5743													args = [ e ];
5744												}
5745
5746												deferred.rejectWith( that, args );
5747											}
5748										}
5749									};
5750
5751							// Support: Promises/A+ section 2.3.3.3.1
5752							// https://promisesaplus.com/#point-57
5753							// Re-resolve promises immediately to dodge false rejection from
5754							// subsequent errors
5755							if ( depth ) {
5756								process();
5757							} else {
5758
5759								// Call an optional hook to record the stack, in case of exception
5760								// since it's otherwise lost when execution goes async
5761								if ( jQuery.Deferred.getStackHook ) {
5762									process.stackTrace = jQuery.Deferred.getStackHook();
5763								}
5764								window.setTimeout( process );
5765							}
5766						};
5767					}
5768
5769					return jQuery.Deferred( function( newDefer ) {
5770
5771						// progress_handlers.add( ... )
5772						tuples[ 0 ][ 3 ].add(
5773							resolve(
5774								0,
5775								newDefer,
5776								isFunction( onProgress ) ?
5777									onProgress :
5778									Identity,
5779								newDefer.notifyWith
5780							)
5781						);
5782
5783						// fulfilled_handlers.add( ... )
5784						tuples[ 1 ][ 3 ].add(
5785							resolve(
5786								0,
5787								newDefer,
5788								isFunction( onFulfilled ) ?
5789									onFulfilled :
5790									Identity
5791							)
5792						);
5793
5794						// rejected_handlers.add( ... )
5795						tuples[ 2 ][ 3 ].add(
5796							resolve(
5797								0,
5798								newDefer,
5799								isFunction( onRejected ) ?
5800									onRejected :
5801									Thrower
5802							)
5803						);
5804					} ).promise();
5805				},
5806
5807				// Get a promise for this deferred
5808				// If obj is provided, the promise aspect is added to the object
5809				promise: function( obj ) {
5810					return obj != null ? jQuery.extend( obj, promise ) : promise;
5811				}
5812			},
5813			deferred = {};
5814
5815		// Add list-specific methods
5816		jQuery.each( tuples, function( i, tuple ) {
5817			var list = tuple[ 2 ],
5818				stateString = tuple[ 5 ];
5819
5820			// promise.progress = list.add
5821			// promise.done = list.add
5822			// promise.fail = list.add
5823			promise[ tuple[ 1 ] ] = list.add;
5824
5825			// Handle state
5826			if ( stateString ) {
5827				list.add(
5828					function() {
5829
5830						// state = "resolved" (i.e., fulfilled)
5831						// state = "rejected"
5832						state = stateString;
5833					},
5834
5835					// rejected_callbacks.disable
5836					// fulfilled_callbacks.disable
5837					tuples[ 3 - i ][ 2 ].disable,
5838
5839					// rejected_handlers.disable
5840					// fulfilled_handlers.disable
5841					tuples[ 3 - i ][ 3 ].disable,
5842
5843					// progress_callbacks.lock
5844					tuples[ 0 ][ 2 ].lock,
5845
5846					// progress_handlers.lock
5847					tuples[ 0 ][ 3 ].lock
5848				);
5849			}
5850
5851			// progress_handlers.fire
5852			// fulfilled_handlers.fire
5853			// rejected_handlers.fire
5854			list.add( tuple[ 3 ].fire );
5855
5856			// deferred.notify = function() { deferred.notifyWith(...) }
5857			// deferred.resolve = function() { deferred.resolveWith(...) }
5858			// deferred.reject = function() { deferred.rejectWith(...) }
5859			deferred[ tuple[ 0 ] ] = function() {
5860				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
5861				return this;
5862			};
5863
5864			// deferred.notifyWith = list.fireWith
5865			// deferred.resolveWith = list.fireWith
5866			// deferred.rejectWith = list.fireWith
5867			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
5868		} );
5869
5870		// Make the deferred a promise
5871		promise.promise( deferred );
5872
5873		// Call given func if any
5874		if ( func ) {
5875			func.call( deferred, deferred );
5876		}
5877
5878		// All done!
5879		return deferred;
5880	},
5881
5882	// Deferred helper
5883	when: function( singleValue ) {
5884		var
5885
5886			// count of uncompleted subordinates
5887			remaining = arguments.length,
5888
5889			// count of unprocessed arguments
5890			i = remaining,
5891
5892			// subordinate fulfillment data
5893			resolveContexts = Array( i ),
5894			resolveValues = slice.call( arguments ),
5895
5896			// the primary Deferred
5897			primary = jQuery.Deferred(),
5898
5899			// subordinate callback factory
5900			updateFunc = function( i ) {
5901				return function( value ) {
5902					resolveContexts[ i ] = this;
5903					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
5904					if ( !( --remaining ) ) {
5905						primary.resolveWith( resolveContexts, resolveValues );
5906					}
5907				};
5908			};
5909
5910		// Single- and empty arguments are adopted like Promise.resolve
5911		if ( remaining <= 1 ) {
5912			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
5913				!remaining );
5914
5915			// Use .then() to unwrap secondary thenables (cf. gh-3000)
5916			if ( primary.state() === "pending" ||
5917				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
5918
5919				return primary.then();
5920			}
5921		}
5922
5923		// Multiple arguments are aggregated like Promise.all array elements
5924		while ( i-- ) {
5925			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
5926		}
5927
5928		return primary.promise();
5929	}
5930} );
5931
5932
5933// These usually indicate a programmer mistake during development,
5934// warn about them ASAP rather than swallowing them by default.
5935var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
5936
5937jQuery.Deferred.exceptionHook = function( error, stack ) {
5938
5939	// Support: IE 8 - 9 only
5940	// Console exists when dev tools are open, which can happen at any time
5941	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
5942		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
5943	}
5944};
5945
5946
5947
5948
5949jQuery.readyException = function( error ) {
5950	window.setTimeout( function() {
5951		throw error;
5952	} );
5953};
5954
5955
5956
5957
5958// The deferred used on DOM ready
5959var readyList = jQuery.Deferred();
5960
5961jQuery.fn.ready = function( fn ) {
5962
5963	readyList
5964		.then( fn )
5965
5966		// Wrap jQuery.readyException in a function so that the lookup
5967		// happens at the time of error handling instead of callback
5968		// registration.
5969		.catch( function( error ) {
5970			jQuery.readyException( error );
5971		} );
5972
5973	return this;
5974};
5975
5976jQuery.extend( {
5977
5978	// Is the DOM ready to be used? Set to true once it occurs.
5979	isReady: false,
5980
5981	// A counter to track how many items to wait for before
5982	// the ready event fires. See #6781
5983	readyWait: 1,
5984
5985	// Handle when the DOM is ready
5986	ready: function( wait ) {
5987
5988		// Abort if there are pending holds or we're already ready
5989		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
5990			return;
5991		}
5992
5993		// Remember that the DOM is ready
5994		jQuery.isReady = true;
5995
5996		// If a normal DOM Ready event fired, decrement, and wait if need be
5997		if ( wait !== true && --jQuery.readyWait > 0 ) {
5998			return;
5999		}
6000
6001		// If there are functions bound, to execute
6002		readyList.resolveWith( document, [ jQuery ] );
6003	}
6004} );
6005
6006jQuery.ready.then = readyList.then;
6007
6008// The ready event handler and self cleanup method
6009function completed() {
6010	document.removeEventListener( "DOMContentLoaded", completed );
6011	window.removeEventListener( "load", completed );
6012	jQuery.ready();
6013}
6014
6015// Catch cases where $(document).ready() is called
6016// after the browser event has already occurred.
6017// Support: IE <=9 - 10 only
6018// Older IE sometimes signals "interactive" too soon
6019if ( document.readyState === "complete" ||
6020	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
6021
6022	// Handle it asynchronously to allow scripts the opportunity to delay ready
6023	window.setTimeout( jQuery.ready );
6024
6025} else {
6026
6027	// Use the handy event callback
6028	document.addEventListener( "DOMContentLoaded", completed );
6029
6030	// A fallback to window.onload, that will always work
6031	window.addEventListener( "load", completed );
6032}
6033
6034
6035
6036
6037// Multifunctional method to get and set values of a collection
6038// The value/s can optionally be executed if it's a function
6039var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
6040	var i = 0,
6041		len = elems.length,
6042		bulk = key == null;
6043
6044	// Sets many values
6045	if ( toType( key ) === "object" ) {
6046		chainable = true;
6047		for ( i in key ) {
6048			access( elems, fn, i, key[ i ], true, emptyGet, raw );
6049		}
6050
6051	// Sets one value
6052	} else if ( value !== undefined ) {
6053		chainable = true;
6054
6055		if ( !isFunction( value ) ) {
6056			raw = true;
6057		}
6058
6059		if ( bulk ) {
6060
6061			// Bulk operations run against the entire set
6062			if ( raw ) {
6063				fn.call( elems, value );
6064				fn = null;
6065
6066			// ...except when executing function values
6067			} else {
6068				bulk = fn;
6069				fn = function( elem, _key, value ) {
6070					return bulk.call( jQuery( elem ), value );
6071				};
6072			}
6073		}
6074
6075		if ( fn ) {
6076			for ( ; i < len; i++ ) {
6077				fn(
6078					elems[ i ], key, raw ?
6079						value :
6080						value.call( elems[ i ], i, fn( elems[ i ], key ) )
6081				);
6082			}
6083		}
6084	}
6085
6086	if ( chainable ) {
6087		return elems;
6088	}
6089
6090	// Gets
6091	if ( bulk ) {
6092		return fn.call( elems );
6093	}
6094
6095	return len ? fn( elems[ 0 ], key ) : emptyGet;
6096};
6097
6098
6099// Matches dashed string for camelizing
6100var rmsPrefix = /^-ms-/,
6101	rdashAlpha = /-([a-z])/g;
6102
6103// Used by camelCase as callback to replace()
6104function fcamelCase( _all, letter ) {
6105	return letter.toUpperCase();
6106}
6107
6108// Convert dashed to camelCase; used by the css and data modules
6109// Support: IE <=9 - 11, Edge 12 - 15
6110// Microsoft forgot to hump their vendor prefix (#9572)
6111function camelCase( string ) {
6112	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
6113}
6114var acceptData = function( owner ) {
6115
6116	// Accepts only:
6117	//  - Node
6118	//    - Node.ELEMENT_NODE
6119	//    - Node.DOCUMENT_NODE
6120	//  - Object
6121	//    - Any
6122	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
6123};
6124
6125
6126
6127
6128function Data() {
6129	this.expando = jQuery.expando + Data.uid++;
6130}
6131
6132Data.uid = 1;
6133
6134Data.prototype = {
6135
6136	cache: function( owner ) {
6137
6138		// Check if the owner object already has a cache
6139		var value = owner[ this.expando ];
6140
6141		// If not, create one
6142		if ( !value ) {
6143			value = {};
6144
6145			// We can accept data for non-element nodes in modern browsers,
6146			// but we should not, see #8335.
6147			// Always return an empty object.
6148			if ( acceptData( owner ) ) {
6149
6150				// If it is a node unlikely to be stringify-ed or looped over
6151				// use plain assignment
6152				if ( owner.nodeType ) {
6153					owner[ this.expando ] = value;
6154
6155				// Otherwise secure it in a non-enumerable property
6156				// configurable must be true to allow the property to be
6157				// deleted when data is removed
6158				} else {
6159					Object.defineProperty( owner, this.expando, {
6160						value: value,
6161						configurable: true
6162					} );
6163				}
6164			}
6165		}
6166
6167		return value;
6168	},
6169	set: function( owner, data, value ) {
6170		var prop,
6171			cache = this.cache( owner );
6172
6173		// Handle: [ owner, key, value ] args
6174		// Always use camelCase key (gh-2257)
6175		if ( typeof data === "string" ) {
6176			cache[ camelCase( data ) ] = value;
6177
6178		// Handle: [ owner, { properties } ] args
6179		} else {
6180
6181			// Copy the properties one-by-one to the cache object
6182			for ( prop in data ) {
6183				cache[ camelCase( prop ) ] = data[ prop ];
6184			}
6185		}
6186		return cache;
6187	},
6188	get: function( owner, key ) {
6189		return key === undefined ?
6190			this.cache( owner ) :
6191
6192			// Always use camelCase key (gh-2257)
6193			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
6194	},
6195	access: function( owner, key, value ) {
6196
6197		// In cases where either:
6198		//
6199		//   1. No key was specified
6200		//   2. A string key was specified, but no value provided
6201		//
6202		// Take the "read" path and allow the get method to determine
6203		// which value to return, respectively either:
6204		//
6205		//   1. The entire cache object
6206		//   2. The data stored at the key
6207		//
6208		if ( key === undefined ||
6209				( ( key && typeof key === "string" ) && value === undefined ) ) {
6210
6211			return this.get( owner, key );
6212		}
6213
6214		// When the key is not a string, or both a key and value
6215		// are specified, set or extend (existing objects) with either:
6216		//
6217		//   1. An object of properties
6218		//   2. A key and value
6219		//
6220		this.set( owner, key, value );
6221
6222		// Since the "set" path can have two possible entry points
6223		// return the expected data based on which path was taken[*]
6224		return value !== undefined ? value : key;
6225	},
6226	remove: function( owner, key ) {
6227		var i,
6228			cache = owner[ this.expando ];
6229
6230		if ( cache === undefined ) {
6231			return;
6232		}
6233
6234		if ( key !== undefined ) {
6235
6236			// Support array or space separated string of keys
6237			if ( Array.isArray( key ) ) {
6238
6239				// If key is an array of keys...
6240				// We always set camelCase keys, so remove that.
6241				key = key.map( camelCase );
6242			} else {
6243				key = camelCase( key );
6244
6245				// If a key with the spaces exists, use it.
6246				// Otherwise, create an array by matching non-whitespace
6247				key = key in cache ?
6248					[ key ] :
6249					( key.match( rnothtmlwhite ) || [] );
6250			}
6251
6252			i = key.length;
6253
6254			while ( i-- ) {
6255				delete cache[ key[ i ] ];
6256			}
6257		}
6258
6259		// Remove the expando if there's no more data
6260		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
6261
6262			// Support: Chrome <=35 - 45
6263			// Webkit & Blink performance suffers when deleting properties
6264			// from DOM nodes, so set to undefined instead
6265			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
6266			if ( owner.nodeType ) {
6267				owner[ this.expando ] = undefined;
6268			} else {
6269				delete owner[ this.expando ];
6270			}
6271		}
6272	},
6273	hasData: function( owner ) {
6274		var cache = owner[ this.expando ];
6275		return cache !== undefined && !jQuery.isEmptyObject( cache );
6276	}
6277};
6278var dataPriv = new Data();
6279
6280var dataUser = new Data();
6281
6282
6283
6284//	Implementation Summary
6285//
6286//	1. Enforce API surface and semantic compatibility with 1.9.x branch
6287//	2. Improve the module's maintainability by reducing the storage
6288//		paths to a single mechanism.
6289//	3. Use the same single mechanism to support "private" and "user" data.
6290//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
6291//	5. Avoid exposing implementation details on user objects (eg. expando properties)
6292//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
6293
6294var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
6295	rmultiDash = /[A-Z]/g;
6296
6297function getData( data ) {
6298	if ( data === "true" ) {
6299		return true;
6300	}
6301
6302	if ( data === "false" ) {
6303		return false;
6304	}
6305
6306	if ( data === "null" ) {
6307		return null;
6308	}
6309
6310	// Only convert to a number if it doesn't change the string
6311	if ( data === +data + "" ) {
6312		return +data;
6313	}
6314
6315	if ( rbrace.test( data ) ) {
6316		return JSON.parse( data );
6317	}
6318
6319	return data;
6320}
6321
6322function dataAttr( elem, key, data ) {
6323	var name;
6324
6325	// If nothing was found internally, try to fetch any
6326	// data from the HTML5 data-* attribute
6327	if ( data === undefined && elem.nodeType === 1 ) {
6328		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
6329		data = elem.getAttribute( name );
6330
6331		if ( typeof data === "string" ) {
6332			try {
6333				data = getData( data );
6334			} catch ( e ) {}
6335
6336			// Make sure we set the data so it isn't changed later
6337			dataUser.set( elem, key, data );
6338		} else {
6339			data = undefined;
6340		}
6341	}
6342	return data;
6343}
6344
6345jQuery.extend( {
6346	hasData: function( elem ) {
6347		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
6348	},
6349
6350	data: function( elem, name, data ) {
6351		return dataUser.access( elem, name, data );
6352	},
6353
6354	removeData: function( elem, name ) {
6355		dataUser.remove( elem, name );
6356	},
6357
6358	// TODO: Now that all calls to _data and _removeData have been replaced
6359	// with direct calls to dataPriv methods, these can be deprecated.
6360	_data: function( elem, name, data ) {
6361		return dataPriv.access( elem, name, data );
6362	},
6363
6364	_removeData: function( elem, name ) {
6365		dataPriv.remove( elem, name );
6366	}
6367} );
6368
6369jQuery.fn.extend( {
6370	data: function( key, value ) {
6371		var i, name, data,
6372			elem = this[ 0 ],
6373			attrs = elem && elem.attributes;
6374
6375		// Gets all values
6376		if ( key === undefined ) {
6377			if ( this.length ) {
6378				data = dataUser.get( elem );
6379
6380				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
6381					i = attrs.length;
6382					while ( i-- ) {
6383
6384						// Support: IE 11 only
6385						// The attrs elements can be null (#14894)
6386						if ( attrs[ i ] ) {
6387							name = attrs[ i ].name;
6388							if ( name.indexOf( "data-" ) === 0 ) {
6389								name = camelCase( name.slice( 5 ) );
6390								dataAttr( elem, name, data[ name ] );
6391							}
6392						}
6393					}
6394					dataPriv.set( elem, "hasDataAttrs", true );
6395				}
6396			}
6397
6398			return data;
6399		}
6400
6401		// Sets multiple values
6402		if ( typeof key === "object" ) {
6403			return this.each( function() {
6404				dataUser.set( this, key );
6405			} );
6406		}
6407
6408		return access( this, function( value ) {
6409			var data;
6410
6411			// The calling jQuery object (element matches) is not empty
6412			// (and therefore has an element appears at this[ 0 ]) and the
6413			// `value` parameter was not undefined. An empty jQuery object
6414			// will result in `undefined` for elem = this[ 0 ] which will
6415			// throw an exception if an attempt to read a data cache is made.
6416			if ( elem && value === undefined ) {
6417
6418				// Attempt to get data from the cache
6419				// The key will always be camelCased in Data
6420				data = dataUser.get( elem, key );
6421				if ( data !== undefined ) {
6422					return data;
6423				}
6424
6425				// Attempt to "discover" the data in
6426				// HTML5 custom data-* attrs
6427				data = dataAttr( elem, key );
6428				if ( data !== undefined ) {
6429					return data;
6430				}
6431
6432				// We tried really hard, but the data doesn't exist.
6433				return;
6434			}
6435
6436			// Set the data...
6437			this.each( function() {
6438
6439				// We always store the camelCased key
6440				dataUser.set( this, key, value );
6441			} );
6442		}, null, value, arguments.length > 1, null, true );
6443	},
6444
6445	removeData: function( key ) {
6446		return this.each( function() {
6447			dataUser.remove( this, key );
6448		} );
6449	}
6450} );
6451
6452
6453jQuery.extend( {
6454	queue: function( elem, type, data ) {
6455		var queue;
6456
6457		if ( elem ) {
6458			type = ( type || "fx" ) + "queue";
6459			queue = dataPriv.get( elem, type );
6460
6461			// Speed up dequeue by getting out quickly if this is just a lookup
6462			if ( data ) {
6463				if ( !queue || Array.isArray( data ) ) {
6464					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
6465				} else {
6466					queue.push( data );
6467				}
6468			}
6469			return queue || [];
6470		}
6471	},
6472
6473	dequeue: function( elem, type ) {
6474		type = type || "fx";
6475
6476		var queue = jQuery.queue( elem, type ),
6477			startLength = queue.length,
6478			fn = queue.shift(),
6479			hooks = jQuery._queueHooks( elem, type ),
6480			next = function() {
6481				jQuery.dequeue( elem, type );
6482			};
6483
6484		// If the fx queue is dequeued, always remove the progress sentinel
6485		if ( fn === "inprogress" ) {
6486			fn = queue.shift();
6487			startLength--;
6488		}
6489
6490		if ( fn ) {
6491
6492			// Add a progress sentinel to prevent the fx queue from being
6493			// automatically dequeued
6494			if ( type === "fx" ) {
6495				queue.unshift( "inprogress" );
6496			}
6497
6498			// Clear up the last queue stop function
6499			delete hooks.stop;
6500			fn.call( elem, next, hooks );
6501		}
6502
6503		if ( !startLength && hooks ) {
6504			hooks.empty.fire();
6505		}
6506	},
6507
6508	// Not public - generate a queueHooks object, or return the current one
6509	_queueHooks: function( elem, type ) {
6510		var key = type + "queueHooks";
6511		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
6512			empty: jQuery.Callbacks( "once memory" ).add( function() {
6513				dataPriv.remove( elem, [ type + "queue", key ] );
6514			} )
6515		} );
6516	}
6517} );
6518
6519jQuery.fn.extend( {
6520	queue: function( type, data ) {
6521		var setter = 2;
6522
6523		if ( typeof type !== "string" ) {
6524			data = type;
6525			type = "fx";
6526			setter--;
6527		}
6528
6529		if ( arguments.length < setter ) {
6530			return jQuery.queue( this[ 0 ], type );
6531		}
6532
6533		return data === undefined ?
6534			this :
6535			this.each( function() {
6536				var queue = jQuery.queue( this, type, data );
6537
6538				// Ensure a hooks for this queue
6539				jQuery._queueHooks( this, type );
6540
6541				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
6542					jQuery.dequeue( this, type );
6543				}
6544			} );
6545	},
6546	dequeue: function( type ) {
6547		return this.each( function() {
6548			jQuery.dequeue( this, type );
6549		} );
6550	},
6551	clearQueue: function( type ) {
6552		return this.queue( type || "fx", [] );
6553	},
6554
6555	// Get a promise resolved when queues of a certain type
6556	// are emptied (fx is the type by default)
6557	promise: function( type, obj ) {
6558		var tmp,
6559			count = 1,
6560			defer = jQuery.Deferred(),
6561			elements = this,
6562			i = this.length,
6563			resolve = function() {
6564				if ( !( --count ) ) {
6565					defer.resolveWith( elements, [ elements ] );
6566				}
6567			};
6568
6569		if ( typeof type !== "string" ) {
6570			obj = type;
6571			type = undefined;
6572		}
6573		type = type || "fx";
6574
6575		while ( i-- ) {
6576			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
6577			if ( tmp && tmp.empty ) {
6578				count++;
6579				tmp.empty.add( resolve );
6580			}
6581		}
6582		resolve();
6583		return defer.promise( obj );
6584	}
6585} );
6586var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
6587
6588var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
6589
6590
6591var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
6592
6593var documentElement = document.documentElement;
6594
6595
6596
6597	var isAttached = function( elem ) {
6598			return jQuery.contains( elem.ownerDocument, elem );
6599		},
6600		composed = { composed: true };
6601
6602	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
6603	// Check attachment across shadow DOM boundaries when possible (gh-3504)
6604	// Support: iOS 10.0-10.2 only
6605	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
6606	// leading to errors. We need to check for `getRootNode`.
6607	if ( documentElement.getRootNode ) {
6608		isAttached = function( elem ) {
6609			return jQuery.contains( elem.ownerDocument, elem ) ||
6610				elem.getRootNode( composed ) === elem.ownerDocument;
6611		};
6612	}
6613var isHiddenWithinTree = function( elem, el ) {
6614
6615		// isHiddenWithinTree might be called from jQuery#filter function;
6616		// in that case, element will be second argument
6617		elem = el || elem;
6618
6619		// Inline style trumps all
6620		return elem.style.display === "none" ||
6621			elem.style.display === "" &&
6622
6623			// Otherwise, check computed style
6624			// Support: Firefox <=43 - 45
6625			// Disconnected elements can have computed display: none, so first confirm that elem is
6626			// in the document.
6627			isAttached( elem ) &&
6628
6629			jQuery.css( elem, "display" ) === "none";
6630	};
6631
6632
6633
6634function adjustCSS( elem, prop, valueParts, tween ) {
6635	var adjusted, scale,
6636		maxIterations = 20,
6637		currentValue = tween ?
6638			function() {
6639				return tween.cur();
6640			} :
6641			function() {
6642				return jQuery.css( elem, prop, "" );
6643			},
6644		initial = currentValue(),
6645		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6646
6647		// Starting value computation is required for potential unit mismatches
6648		initialInUnit = elem.nodeType &&
6649			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
6650			rcssNum.exec( jQuery.css( elem, prop ) );
6651
6652	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
6653
6654		// Support: Firefox <=54
6655		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
6656		initial = initial / 2;
6657
6658		// Trust units reported by jQuery.css
6659		unit = unit || initialInUnit[ 3 ];
6660
6661		// Iteratively approximate from a nonzero starting point
6662		initialInUnit = +initial || 1;
6663
6664		while ( maxIterations-- ) {
6665
6666			// Evaluate and update our best guess (doubling guesses that zero out).
6667			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
6668			jQuery.style( elem, prop, initialInUnit + unit );
6669			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
6670				maxIterations = 0;
6671			}
6672			initialInUnit = initialInUnit / scale;
6673
6674		}
6675
6676		initialInUnit = initialInUnit * 2;
6677		jQuery.style( elem, prop, initialInUnit + unit );
6678
6679		// Make sure we update the tween properties later on
6680		valueParts = valueParts || [];
6681	}
6682
6683	if ( valueParts ) {
6684		initialInUnit = +initialInUnit || +initial || 0;
6685
6686		// Apply relative offset (+=/-=) if specified
6687		adjusted = valueParts[ 1 ] ?
6688			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
6689			+valueParts[ 2 ];
6690		if ( tween ) {
6691			tween.unit = unit;
6692			tween.start = initialInUnit;
6693			tween.end = adjusted;
6694		}
6695	}
6696	return adjusted;
6697}
6698
6699
6700var defaultDisplayMap = {};
6701
6702function getDefaultDisplay( elem ) {
6703	var temp,
6704		doc = elem.ownerDocument,
6705		nodeName = elem.nodeName,
6706		display = defaultDisplayMap[ nodeName ];
6707
6708	if ( display ) {
6709		return display;
6710	}
6711
6712	temp = doc.body.appendChild( doc.createElement( nodeName ) );
6713	display = jQuery.css( temp, "display" );
6714
6715	temp.parentNode.removeChild( temp );
6716
6717	if ( display === "none" ) {
6718		display = "block";
6719	}
6720	defaultDisplayMap[ nodeName ] = display;
6721
6722	return display;
6723}
6724
6725function showHide( elements, show ) {
6726	var display, elem,
6727		values = [],
6728		index = 0,
6729		length = elements.length;
6730
6731	// Determine new display value for elements that need to change
6732	for ( ; index < length; index++ ) {
6733		elem = elements[ index ];
6734		if ( !elem.style ) {
6735			continue;
6736		}
6737
6738		display = elem.style.display;
6739		if ( show ) {
6740
6741			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
6742			// check is required in this first loop unless we have a nonempty display value (either
6743			// inline or about-to-be-restored)
6744			if ( display === "none" ) {
6745				values[ index ] = dataPriv.get( elem, "display" ) || null;
6746				if ( !values[ index ] ) {
6747					elem.style.display = "";
6748				}
6749			}
6750			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
6751				values[ index ] = getDefaultDisplay( elem );
6752			}
6753		} else {
6754			if ( display !== "none" ) {
6755				values[ index ] = "none";
6756
6757				// Remember what we're overwriting
6758				dataPriv.set( elem, "display", display );
6759			}
6760		}
6761	}
6762
6763	// Set the display of the elements in a second loop to avoid constant reflow
6764	for ( index = 0; index < length; index++ ) {
6765		if ( values[ index ] != null ) {
6766			elements[ index ].style.display = values[ index ];
6767		}
6768	}
6769
6770	return elements;
6771}
6772
6773jQuery.fn.extend( {
6774	show: function() {
6775		return showHide( this, true );
6776	},
6777	hide: function() {
6778		return showHide( this );
6779	},
6780	toggle: function( state ) {
6781		if ( typeof state === "boolean" ) {
6782			return state ? this.show() : this.hide();
6783		}
6784
6785		return this.each( function() {
6786			if ( isHiddenWithinTree( this ) ) {
6787				jQuery( this ).show();
6788			} else {
6789				jQuery( this ).hide();
6790			}
6791		} );
6792	}
6793} );
6794var rcheckableType = ( /^(?:checkbox|radio)$/i );
6795
6796var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
6797
6798var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
6799
6800
6801
6802( function() {
6803	var fragment = document.createDocumentFragment(),
6804		div = fragment.appendChild( document.createElement( "div" ) ),
6805		input = document.createElement( "input" );
6806
6807	// Support: Android 4.0 - 4.3 only
6808	// Check state lost if the name is set (#11217)
6809	// Support: Windows Web Apps (WWA)
6810	// `name` and `type` must use .setAttribute for WWA (#14901)
6811	input.setAttribute( "type", "radio" );
6812	input.setAttribute( "checked", "checked" );
6813	input.setAttribute( "name", "t" );
6814
6815	div.appendChild( input );
6816
6817	// Support: Android <=4.1 only
6818	// Older WebKit doesn't clone checked state correctly in fragments
6819	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
6820
6821	// Support: IE <=11 only
6822	// Make sure textarea (and checkbox) defaultValue is properly cloned
6823	div.innerHTML = "<textarea>x</textarea>";
6824	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
6825
6826	// Support: IE <=9 only
6827	// IE <=9 replaces <option> tags with their contents when inserted outside of
6828	// the select element.
6829	div.innerHTML = "<option></option>";
6830	support.option = !!div.lastChild;
6831} )();
6832
6833
6834// We have to close these tags to support XHTML (#13200)
6835var wrapMap = {
6836
6837	// XHTML parsers do not magically insert elements in the
6838	// same way that tag soup parsers do. So we cannot shorten
6839	// this by omitting <tbody> or other required elements.
6840	thead: [ 1, "<table>", "</table>" ],
6841	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
6842	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
6843	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
6844
6845	_default: [ 0, "", "" ]
6846};
6847
6848wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
6849wrapMap.th = wrapMap.td;
6850
6851// Support: IE <=9 only
6852if ( !support.option ) {
6853	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
6854}
6855
6856
6857function getAll( context, tag ) {
6858
6859	// Support: IE <=9 - 11 only
6860	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
6861	var ret;
6862
6863	if ( typeof context.getElementsByTagName !== "undefined" ) {
6864		ret = context.getElementsByTagName( tag || "*" );
6865
6866	} else if ( typeof context.querySelectorAll !== "undefined" ) {
6867		ret = context.querySelectorAll( tag || "*" );
6868
6869	} else {
6870		ret = [];
6871	}
6872
6873	if ( tag === undefined || tag && nodeName( context, tag ) ) {
6874		return jQuery.merge( [ context ], ret );
6875	}
6876
6877	return ret;
6878}
6879
6880
6881// Mark scripts as having already been evaluated
6882function setGlobalEval( elems, refElements ) {
6883	var i = 0,
6884		l = elems.length;
6885
6886	for ( ; i < l; i++ ) {
6887		dataPriv.set(
6888			elems[ i ],
6889			"globalEval",
6890			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
6891		);
6892	}
6893}
6894
6895
6896var rhtml = /<|&#?\w+;/;
6897
6898function buildFragment( elems, context, scripts, selection, ignored ) {
6899	var elem, tmp, tag, wrap, attached, j,
6900		fragment = context.createDocumentFragment(),
6901		nodes = [],
6902		i = 0,
6903		l = elems.length;
6904
6905	for ( ; i < l; i++ ) {
6906		elem = elems[ i ];
6907
6908		if ( elem || elem === 0 ) {
6909
6910			// Add nodes directly
6911			if ( toType( elem ) === "object" ) {
6912
6913				// Support: Android <=4.0 only, PhantomJS 1 only
6914				// push.apply(_, arraylike) throws on ancient WebKit
6915				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
6916
6917			// Convert non-html into a text node
6918			} else if ( !rhtml.test( elem ) ) {
6919				nodes.push( context.createTextNode( elem ) );
6920
6921			// Convert html into DOM nodes
6922			} else {
6923				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
6924
6925				// Deserialize a standard representation
6926				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
6927				wrap = wrapMap[ tag ] || wrapMap._default;
6928				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
6929
6930				// Descend through wrappers to the right content
6931				j = wrap[ 0 ];
6932				while ( j-- ) {
6933					tmp = tmp.lastChild;
6934				}
6935
6936				// Support: Android <=4.0 only, PhantomJS 1 only
6937				// push.apply(_, arraylike) throws on ancient WebKit
6938				jQuery.merge( nodes, tmp.childNodes );
6939
6940				// Remember the top-level container
6941				tmp = fragment.firstChild;
6942
6943				// Ensure the created nodes are orphaned (#12392)
6944				tmp.textContent = "";
6945			}
6946		}
6947	}
6948
6949	// Remove wrapper from fragment
6950	fragment.textContent = "";
6951
6952	i = 0;
6953	while ( ( elem = nodes[ i++ ] ) ) {
6954
6955		// Skip elements already in the context collection (trac-4087)
6956		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
6957			if ( ignored ) {
6958				ignored.push( elem );
6959			}
6960			continue;
6961		}
6962
6963		attached = isAttached( elem );
6964
6965		// Append to fragment
6966		tmp = getAll( fragment.appendChild( elem ), "script" );
6967
6968		// Preserve script evaluation history
6969		if ( attached ) {
6970			setGlobalEval( tmp );
6971		}
6972
6973		// Capture executables
6974		if ( scripts ) {
6975			j = 0;
6976			while ( ( elem = tmp[ j++ ] ) ) {
6977				if ( rscriptType.test( elem.type || "" ) ) {
6978					scripts.push( elem );
6979				}
6980			}
6981		}
6982	}
6983
6984	return fragment;
6985}
6986
6987
6988var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
6989
6990function returnTrue() {
6991	return true;
6992}
6993
6994function returnFalse() {
6995	return false;
6996}
6997
6998// Support: IE <=9 - 11+
6999// focus() and blur() are asynchronous, except when they are no-op.
7000// So expect focus to be synchronous when the element is already active,
7001// and blur to be synchronous when the element is not already active.
7002// (focus and blur are always synchronous in other supported browsers,
7003// this just defines when we can count on it).
7004function expectSync( elem, type ) {
7005	return ( elem === safeActiveElement() ) === ( type === "focus" );
7006}
7007
7008// Support: IE <=9 only
7009// Accessing document.activeElement can throw unexpectedly
7010// https://bugs.jquery.com/ticket/13393
7011function safeActiveElement() {
7012	try {
7013		return document.activeElement;
7014	} catch ( err ) { }
7015}
7016
7017function on( elem, types, selector, data, fn, one ) {
7018	var origFn, type;
7019
7020	// Types can be a map of types/handlers
7021	if ( typeof types === "object" ) {
7022
7023		// ( types-Object, selector, data )
7024		if ( typeof selector !== "string" ) {
7025
7026			// ( types-Object, data )
7027			data = data || selector;
7028			selector = undefined;
7029		}
7030		for ( type in types ) {
7031			on( elem, type, selector, data, types[ type ], one );
7032		}
7033		return elem;
7034	}
7035
7036	if ( data == null && fn == null ) {
7037
7038		// ( types, fn )
7039		fn = selector;
7040		data = selector = undefined;
7041	} else if ( fn == null ) {
7042		if ( typeof selector === "string" ) {
7043
7044			// ( types, selector, fn )
7045			fn = data;
7046			data = undefined;
7047		} else {
7048
7049			// ( types, data, fn )
7050			fn = data;
7051			data = selector;
7052			selector = undefined;
7053		}
7054	}
7055	if ( fn === false ) {
7056		fn = returnFalse;
7057	} else if ( !fn ) {
7058		return elem;
7059	}
7060
7061	if ( one === 1 ) {
7062		origFn = fn;
7063		fn = function( event ) {
7064
7065			// Can use an empty set, since event contains the info
7066			jQuery().off( event );
7067			return origFn.apply( this, arguments );
7068		};
7069
7070		// Use same guid so caller can remove using origFn
7071		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
7072	}
7073	return elem.each( function() {
7074		jQuery.event.add( this, types, fn, data, selector );
7075	} );
7076}
7077
7078/*
7079 * Helper functions for managing events -- not part of the public interface.
7080 * Props to Dean Edwards' addEvent library for many of the ideas.
7081 */
7082jQuery.event = {
7083
7084	global: {},
7085
7086	add: function( elem, types, handler, data, selector ) {
7087
7088		var handleObjIn, eventHandle, tmp,
7089			events, t, handleObj,
7090			special, handlers, type, namespaces, origType,
7091			elemData = dataPriv.get( elem );
7092
7093		// Only attach events to objects that accept data
7094		if ( !acceptData( elem ) ) {
7095			return;
7096		}
7097
7098		// Caller can pass in an object of custom data in lieu of the handler
7099		if ( handler.handler ) {
7100			handleObjIn = handler;
7101			handler = handleObjIn.handler;
7102			selector = handleObjIn.selector;
7103		}
7104
7105		// Ensure that invalid selectors throw exceptions at attach time
7106		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
7107		if ( selector ) {
7108			jQuery.find.matchesSelector( documentElement, selector );
7109		}
7110
7111		// Make sure that the handler has a unique ID, used to find/remove it later
7112		if ( !handler.guid ) {
7113			handler.guid = jQuery.guid++;
7114		}
7115
7116		// Init the element's event structure and main handler, if this is the first
7117		if ( !( events = elemData.events ) ) {
7118			events = elemData.events = Object.create( null );
7119		}
7120		if ( !( eventHandle = elemData.handle ) ) {
7121			eventHandle = elemData.handle = function( e ) {
7122
7123				// Discard the second event of a jQuery.event.trigger() and
7124				// when an event is called after a page has unloaded
7125				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
7126					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
7127			};
7128		}
7129
7130		// Handle multiple events separated by a space
7131		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
7132		t = types.length;
7133		while ( t-- ) {
7134			tmp = rtypenamespace.exec( types[ t ] ) || [];
7135			type = origType = tmp[ 1 ];
7136			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
7137
7138			// There *must* be a type, no attaching namespace-only handlers
7139			if ( !type ) {
7140				continue;
7141			}
7142
7143			// If event changes its type, use the special event handlers for the changed type
7144			special = jQuery.event.special[ type ] || {};
7145
7146			// If selector defined, determine special event api type, otherwise given type
7147			type = ( selector ? special.delegateType : special.bindType ) || type;
7148
7149			// Update special based on newly reset type
7150			special = jQuery.event.special[ type ] || {};
7151
7152			// handleObj is passed to all event handlers
7153			handleObj = jQuery.extend( {
7154				type: type,
7155				origType: origType,
7156				data: data,
7157				handler: handler,
7158				guid: handler.guid,
7159				selector: selector,
7160				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
7161				namespace: namespaces.join( "." )
7162			}, handleObjIn );
7163
7164			// Init the event handler queue if we're the first
7165			if ( !( handlers = events[ type ] ) ) {
7166				handlers = events[ type ] = [];
7167				handlers.delegateCount = 0;
7168
7169				// Only use addEventListener if the special events handler returns false
7170				if ( !special.setup ||
7171					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
7172
7173					if ( elem.addEventListener ) {
7174						elem.addEventListener( type, eventHandle );
7175					}
7176				}
7177			}
7178
7179			if ( special.add ) {
7180				special.add.call( elem, handleObj );
7181
7182				if ( !handleObj.handler.guid ) {
7183					handleObj.handler.guid = handler.guid;
7184				}
7185			}
7186
7187			// Add to the element's handler list, delegates in front
7188			if ( selector ) {
7189				handlers.splice( handlers.delegateCount++, 0, handleObj );
7190			} else {
7191				handlers.push( handleObj );
7192			}
7193
7194			// Keep track of which events have ever been used, for event optimization
7195			jQuery.event.global[ type ] = true;
7196		}
7197
7198	},
7199
7200	// Detach an event or set of events from an element
7201	remove: function( elem, types, handler, selector, mappedTypes ) {
7202
7203		var j, origCount, tmp,
7204			events, t, handleObj,
7205			special, handlers, type, namespaces, origType,
7206			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
7207
7208		if ( !elemData || !( events = elemData.events ) ) {
7209			return;
7210		}
7211
7212		// Once for each type.namespace in types; type may be omitted
7213		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
7214		t = types.length;
7215		while ( t-- ) {
7216			tmp = rtypenamespace.exec( types[ t ] ) || [];
7217			type = origType = tmp[ 1 ];
7218			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
7219
7220			// Unbind all events (on this namespace, if provided) for the element
7221			if ( !type ) {
7222				for ( type in events ) {
7223					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
7224				}
7225				continue;
7226			}
7227
7228			special = jQuery.event.special[ type ] || {};
7229			type = ( selector ? special.delegateType : special.bindType ) || type;
7230			handlers = events[ type ] || [];
7231			tmp = tmp[ 2 ] &&
7232				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
7233
7234			// Remove matching events
7235			origCount = j = handlers.length;
7236			while ( j-- ) {
7237				handleObj = handlers[ j ];
7238
7239				if ( ( mappedTypes || origType === handleObj.origType ) &&
7240					( !handler || handler.guid === handleObj.guid ) &&
7241					( !tmp || tmp.test( handleObj.namespace ) ) &&
7242					( !selector || selector === handleObj.selector ||
7243						selector === "**" && handleObj.selector ) ) {
7244					handlers.splice( j, 1 );
7245
7246					if ( handleObj.selector ) {
7247						handlers.delegateCount--;
7248					}
7249					if ( special.remove ) {
7250						special.remove.call( elem, handleObj );
7251					}
7252				}
7253			}
7254
7255			// Remove generic event handler if we removed something and no more handlers exist
7256			// (avoids potential for endless recursion during removal of special event handlers)
7257			if ( origCount && !handlers.length ) {
7258				if ( !special.teardown ||
7259					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
7260
7261					jQuery.removeEvent( elem, type, elemData.handle );
7262				}
7263
7264				delete events[ type ];
7265			}
7266		}
7267
7268		// Remove data and the expando if it's no longer used
7269		if ( jQuery.isEmptyObject( events ) ) {
7270			dataPriv.remove( elem, "handle events" );
7271		}
7272	},
7273
7274	dispatch: function( nativeEvent ) {
7275
7276		var i, j, ret, matched, handleObj, handlerQueue,
7277			args = new Array( arguments.length ),
7278
7279			// Make a writable jQuery.Event from the native event object
7280			event = jQuery.event.fix( nativeEvent ),
7281
7282			handlers = (
7283				dataPriv.get( this, "events" ) || Object.create( null )
7284			)[ event.type ] || [],
7285			special = jQuery.event.special[ event.type ] || {};
7286
7287		// Use the fix-ed jQuery.Event rather than the (read-only) native event
7288		args[ 0 ] = event;
7289
7290		for ( i = 1; i < arguments.length; i++ ) {
7291			args[ i ] = arguments[ i ];
7292		}
7293
7294		event.delegateTarget = this;
7295
7296		// Call the preDispatch hook for the mapped type, and let it bail if desired
7297		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
7298			return;
7299		}
7300
7301		// Determine handlers
7302		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
7303
7304		// Run delegates first; they may want to stop propagation beneath us
7305		i = 0;
7306		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
7307			event.currentTarget = matched.elem;
7308
7309			j = 0;
7310			while ( ( handleObj = matched.handlers[ j++ ] ) &&
7311				!event.isImmediatePropagationStopped() ) {
7312
7313				// If the event is namespaced, then each handler is only invoked if it is
7314				// specially universal or its namespaces are a superset of the event's.
7315				if ( !event.rnamespace || handleObj.namespace === false ||
7316					event.rnamespace.test( handleObj.namespace ) ) {
7317
7318					event.handleObj = handleObj;
7319					event.data = handleObj.data;
7320
7321					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
7322						handleObj.handler ).apply( matched.elem, args );
7323
7324					if ( ret !== undefined ) {
7325						if ( ( event.result = ret ) === false ) {
7326							event.preventDefault();
7327							event.stopPropagation();
7328						}
7329					}
7330				}
7331			}
7332		}
7333
7334		// Call the postDispatch hook for the mapped type
7335		if ( special.postDispatch ) {
7336			special.postDispatch.call( this, event );
7337		}
7338
7339		return event.result;
7340	},
7341
7342	handlers: function( event, handlers ) {
7343		var i, handleObj, sel, matchedHandlers, matchedSelectors,
7344			handlerQueue = [],
7345			delegateCount = handlers.delegateCount,
7346			cur = event.target;
7347
7348		// Find delegate handlers
7349		if ( delegateCount &&
7350
7351			// Support: IE <=9
7352			// Black-hole SVG <use> instance trees (trac-13180)
7353			cur.nodeType &&
7354
7355			// Support: Firefox <=42
7356			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
7357			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
7358			// Support: IE 11 only
7359			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
7360			!( event.type === "click" && event.button >= 1 ) ) {
7361
7362			for ( ; cur !== this; cur = cur.parentNode || this ) {
7363
7364				// Don't check non-elements (#13208)
7365				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
7366				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
7367					matchedHandlers = [];
7368					matchedSelectors = {};
7369					for ( i = 0; i < delegateCount; i++ ) {
7370						handleObj = handlers[ i ];
7371
7372						// Don't conflict with Object.prototype properties (#13203)
7373						sel = handleObj.selector + " ";
7374
7375						if ( matchedSelectors[ sel ] === undefined ) {
7376							matchedSelectors[ sel ] = handleObj.needsContext ?
7377								jQuery( sel, this ).index( cur ) > -1 :
7378								jQuery.find( sel, this, null, [ cur ] ).length;
7379						}
7380						if ( matchedSelectors[ sel ] ) {
7381							matchedHandlers.push( handleObj );
7382						}
7383					}
7384					if ( matchedHandlers.length ) {
7385						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
7386					}
7387				}
7388			}
7389		}
7390
7391		// Add the remaining (directly-bound) handlers
7392		cur = this;
7393		if ( delegateCount < handlers.length ) {
7394			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
7395		}
7396
7397		return handlerQueue;
7398	},
7399
7400	addProp: function( name, hook ) {
7401		Object.defineProperty( jQuery.Event.prototype, name, {
7402			enumerable: true,
7403			configurable: true,
7404
7405			get: isFunction( hook ) ?
7406				function() {
7407					if ( this.originalEvent ) {
7408						return hook( this.originalEvent );
7409					}
7410				} :
7411				function() {
7412					if ( this.originalEvent ) {
7413						return this.originalEvent[ name ];
7414					}
7415				},
7416
7417			set: function( value ) {
7418				Object.defineProperty( this, name, {
7419					enumerable: true,
7420					configurable: true,
7421					writable: true,
7422					value: value
7423				} );
7424			}
7425		} );
7426	},
7427
7428	fix: function( originalEvent ) {
7429		return originalEvent[ jQuery.expando ] ?
7430			originalEvent :
7431			new jQuery.Event( originalEvent );
7432	},
7433
7434	special: {
7435		load: {
7436
7437			// Prevent triggered image.load events from bubbling to window.load
7438			noBubble: true
7439		},
7440		click: {
7441
7442			// Utilize native event to ensure correct state for checkable inputs
7443			setup: function( data ) {
7444
7445				// For mutual compressibility with _default, replace `this` access with a local var.
7446				// `|| data` is dead code meant only to preserve the variable through minification.
7447				var el = this || data;
7448
7449				// Claim the first handler
7450				if ( rcheckableType.test( el.type ) &&
7451					el.click && nodeName( el, "input" ) ) {
7452
7453					// dataPriv.set( el, "click", ... )
7454					leverageNative( el, "click", returnTrue );
7455				}
7456
7457				// Return false to allow normal processing in the caller
7458				return false;
7459			},
7460			trigger: function( data ) {
7461
7462				// For mutual compressibility with _default, replace `this` access with a local var.
7463				// `|| data` is dead code meant only to preserve the variable through minification.
7464				var el = this || data;
7465
7466				// Force setup before triggering a click
7467				if ( rcheckableType.test( el.type ) &&
7468					el.click && nodeName( el, "input" ) ) {
7469
7470					leverageNative( el, "click" );
7471				}
7472
7473				// Return non-false to allow normal event-path propagation
7474				return true;
7475			},
7476
7477			// For cross-browser consistency, suppress native .click() on links
7478			// Also prevent it if we're currently inside a leveraged native-event stack
7479			_default: function( event ) {
7480				var target = event.target;
7481				return rcheckableType.test( target.type ) &&
7482					target.click && nodeName( target, "input" ) &&
7483					dataPriv.get( target, "click" ) ||
7484					nodeName( target, "a" );
7485			}
7486		},
7487
7488		beforeunload: {
7489			postDispatch: function( event ) {
7490
7491				// Support: Firefox 20+
7492				// Firefox doesn't alert if the returnValue field is not set.
7493				if ( event.result !== undefined && event.originalEvent ) {
7494					event.originalEvent.returnValue = event.result;
7495				}
7496			}
7497		}
7498	}
7499};
7500
7501// Ensure the presence of an event listener that handles manually-triggered
7502// synthetic events by interrupting progress until reinvoked in response to
7503// *native* events that it fires directly, ensuring that state changes have
7504// already occurred before other listeners are invoked.
7505function leverageNative( el, type, expectSync ) {
7506
7507	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
7508	if ( !expectSync ) {
7509		if ( dataPriv.get( el, type ) === undefined ) {
7510			jQuery.event.add( el, type, returnTrue );
7511		}
7512		return;
7513	}
7514
7515	// Register the controller as a special universal handler for all event namespaces
7516	dataPriv.set( el, type, false );
7517	jQuery.event.add( el, type, {
7518		namespace: false,
7519		handler: function( event ) {
7520			var notAsync, result,
7521				saved = dataPriv.get( this, type );
7522
7523			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
7524
7525				// Interrupt processing of the outer synthetic .trigger()ed event
7526				// Saved data should be false in such cases, but might be a leftover capture object
7527				// from an async native handler (gh-4350)
7528				if ( !saved.length ) {
7529
7530					// Store arguments for use when handling the inner native event
7531					// There will always be at least one argument (an event object), so this array
7532					// will not be confused with a leftover capture object.
7533					saved = slice.call( arguments );
7534					dataPriv.set( this, type, saved );
7535
7536					// Trigger the native event and capture its result
7537					// Support: IE <=9 - 11+
7538					// focus() and blur() are asynchronous
7539					notAsync = expectSync( this, type );
7540					this[ type ]();
7541					result = dataPriv.get( this, type );
7542					if ( saved !== result || notAsync ) {
7543						dataPriv.set( this, type, false );
7544					} else {
7545						result = {};
7546					}
7547					if ( saved !== result ) {
7548
7549						// Cancel the outer synthetic event
7550						event.stopImmediatePropagation();
7551						event.preventDefault();
7552
7553						// Support: Chrome 86+
7554						// In Chrome, if an element having a focusout handler is blurred by
7555						// clicking outside of it, it invokes the handler synchronously. If
7556						// that handler calls `.remove()` on the element, the data is cleared,
7557						// leaving `result` undefined. We need to guard against this.
7558						return result && result.value;
7559					}
7560
7561				// If this is an inner synthetic event for an event with a bubbling surrogate
7562				// (focus or blur), assume that the surrogate already propagated from triggering the
7563				// native event and prevent that from happening again here.
7564				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
7565				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
7566				// less bad than duplication.
7567				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
7568					event.stopPropagation();
7569				}
7570
7571			// If this is a native event triggered above, everything is now in order
7572			// Fire an inner synthetic event with the original arguments
7573			} else if ( saved.length ) {
7574
7575				// ...and capture the result
7576				dataPriv.set( this, type, {
7577					value: jQuery.event.trigger(
7578
7579						// Support: IE <=9 - 11+
7580						// Extend with the prototype to reset the above stopImmediatePropagation()
7581						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
7582						saved.slice( 1 ),
7583						this
7584					)
7585				} );
7586
7587				// Abort handling of the native event
7588				event.stopImmediatePropagation();
7589			}
7590		}
7591	} );
7592}
7593
7594jQuery.removeEvent = function( elem, type, handle ) {
7595
7596	// This "if" is needed for plain objects
7597	if ( elem.removeEventListener ) {
7598		elem.removeEventListener( type, handle );
7599	}
7600};
7601
7602jQuery.Event = function( src, props ) {
7603
7604	// Allow instantiation without the 'new' keyword
7605	if ( !( this instanceof jQuery.Event ) ) {
7606		return new jQuery.Event( src, props );
7607	}
7608
7609	// Event object
7610	if ( src && src.type ) {
7611		this.originalEvent = src;
7612		this.type = src.type;
7613
7614		// Events bubbling up the document may have been marked as prevented
7615		// by a handler lower down the tree; reflect the correct value.
7616		this.isDefaultPrevented = src.defaultPrevented ||
7617				src.defaultPrevented === undefined &&
7618
7619				// Support: Android <=2.3 only
7620				src.returnValue === false ?
7621			returnTrue :
7622			returnFalse;
7623
7624		// Create target properties
7625		// Support: Safari <=6 - 7 only
7626		// Target should not be a text node (#504, #13143)
7627		this.target = ( src.target && src.target.nodeType === 3 ) ?
7628			src.target.parentNode :
7629			src.target;
7630
7631		this.currentTarget = src.currentTarget;
7632		this.relatedTarget = src.relatedTarget;
7633
7634	// Event type
7635	} else {
7636		this.type = src;
7637	}
7638
7639	// Put explicitly provided properties onto the event object
7640	if ( props ) {
7641		jQuery.extend( this, props );
7642	}
7643
7644	// Create a timestamp if incoming event doesn't have one
7645	this.timeStamp = src && src.timeStamp || Date.now();
7646
7647	// Mark it as fixed
7648	this[ jQuery.expando ] = true;
7649};
7650
7651// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
7652// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
7653jQuery.Event.prototype = {
7654	constructor: jQuery.Event,
7655	isDefaultPrevented: returnFalse,
7656	isPropagationStopped: returnFalse,
7657	isImmediatePropagationStopped: returnFalse,
7658	isSimulated: false,
7659
7660	preventDefault: function() {
7661		var e = this.originalEvent;
7662
7663		this.isDefaultPrevented = returnTrue;
7664
7665		if ( e && !this.isSimulated ) {
7666			e.preventDefault();
7667		}
7668	},
7669	stopPropagation: function() {
7670		var e = this.originalEvent;
7671
7672		this.isPropagationStopped = returnTrue;
7673
7674		if ( e && !this.isSimulated ) {
7675			e.stopPropagation();
7676		}
7677	},
7678	stopImmediatePropagation: function() {
7679		var e = this.originalEvent;
7680
7681		this.isImmediatePropagationStopped = returnTrue;
7682
7683		if ( e && !this.isSimulated ) {
7684			e.stopImmediatePropagation();
7685		}
7686
7687		this.stopPropagation();
7688	}
7689};
7690
7691// Includes all common event props including KeyEvent and MouseEvent specific props
7692jQuery.each( {
7693	altKey: true,
7694	bubbles: true,
7695	cancelable: true,
7696	changedTouches: true,
7697	ctrlKey: true,
7698	detail: true,
7699	eventPhase: true,
7700	metaKey: true,
7701	pageX: true,
7702	pageY: true,
7703	shiftKey: true,
7704	view: true,
7705	"char": true,
7706	code: true,
7707	charCode: true,
7708	key: true,
7709	keyCode: true,
7710	button: true,
7711	buttons: true,
7712	clientX: true,
7713	clientY: true,
7714	offsetX: true,
7715	offsetY: true,
7716	pointerId: true,
7717	pointerType: true,
7718	screenX: true,
7719	screenY: true,
7720	targetTouches: true,
7721	toElement: true,
7722	touches: true,
7723	which: true
7724}, jQuery.event.addProp );
7725
7726jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
7727	jQuery.event.special[ type ] = {
7728
7729		// Utilize native event if possible so blur/focus sequence is correct
7730		setup: function() {
7731
7732			// Claim the first handler
7733			// dataPriv.set( this, "focus", ... )
7734			// dataPriv.set( this, "blur", ... )
7735			leverageNative( this, type, expectSync );
7736
7737			// Return false to allow normal processing in the caller
7738			return false;
7739		},
7740		trigger: function() {
7741
7742			// Force setup before trigger
7743			leverageNative( this, type );
7744
7745			// Return non-false to allow normal event-path propagation
7746			return true;
7747		},
7748
7749		// Suppress native focus or blur as it's already being fired
7750		// in leverageNative.
7751		_default: function() {
7752			return true;
7753		},
7754
7755		delegateType: delegateType
7756	};
7757} );
7758
7759// Create mouseenter/leave events using mouseover/out and event-time checks
7760// so that event delegation works in jQuery.
7761// Do the same for pointerenter/pointerleave and pointerover/pointerout
7762//
7763// Support: Safari 7 only
7764// Safari sends mouseenter too often; see:
7765// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
7766// for the description of the bug (it existed in older Chrome versions as well).
7767jQuery.each( {
7768	mouseenter: "mouseover",
7769	mouseleave: "mouseout",
7770	pointerenter: "pointerover",
7771	pointerleave: "pointerout"
7772}, function( orig, fix ) {
7773	jQuery.event.special[ orig ] = {
7774		delegateType: fix,
7775		bindType: fix,
7776
7777		handle: function( event ) {
7778			var ret,
7779				target = this,
7780				related = event.relatedTarget,
7781				handleObj = event.handleObj;
7782
7783			// For mouseenter/leave call the handler if related is outside the target.
7784			// NB: No relatedTarget if the mouse left/entered the browser window
7785			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
7786				event.type = handleObj.origType;
7787				ret = handleObj.handler.apply( this, arguments );
7788				event.type = fix;
7789			}
7790			return ret;
7791		}
7792	};
7793} );
7794
7795jQuery.fn.extend( {
7796
7797	on: function( types, selector, data, fn ) {
7798		return on( this, types, selector, data, fn );
7799	},
7800	one: function( types, selector, data, fn ) {
7801		return on( this, types, selector, data, fn, 1 );
7802	},
7803	off: function( types, selector, fn ) {
7804		var handleObj, type;
7805		if ( types && types.preventDefault && types.handleObj ) {
7806
7807			// ( event )  dispatched jQuery.Event
7808			handleObj = types.handleObj;
7809			jQuery( types.delegateTarget ).off(
7810				handleObj.namespace ?
7811					handleObj.origType + "." + handleObj.namespace :
7812					handleObj.origType,
7813				handleObj.selector,
7814				handleObj.handler
7815			);
7816			return this;
7817		}
7818		if ( typeof types === "object" ) {
7819
7820			// ( types-object [, selector] )
7821			for ( type in types ) {
7822				this.off( type, selector, types[ type ] );
7823			}
7824			return this;
7825		}
7826		if ( selector === false || typeof selector === "function" ) {
7827
7828			// ( types [, fn] )
7829			fn = selector;
7830			selector = undefined;
7831		}
7832		if ( fn === false ) {
7833			fn = returnFalse;
7834		}
7835		return this.each( function() {
7836			jQuery.event.remove( this, types, fn, selector );
7837		} );
7838	}
7839} );
7840
7841
7842var
7843
7844	// Support: IE <=10 - 11, Edge 12 - 13 only
7845	// In IE/Edge using regex groups here causes severe slowdowns.
7846	// See https://connect.microsoft.com/IE/feedback/details/1736512/
7847	rnoInnerhtml = /<script|<style|<link/i,
7848
7849	// checked="checked" or checked
7850	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
7851	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
7852
7853// Prefer a tbody over its parent table for containing new rows
7854function manipulationTarget( elem, content ) {
7855	if ( nodeName( elem, "table" ) &&
7856		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
7857
7858		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
7859	}
7860
7861	return elem;
7862}
7863
7864// Replace/restore the type attribute of script elements for safe DOM manipulation
7865function disableScript( elem ) {
7866	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
7867	return elem;
7868}
7869function restoreScript( elem ) {
7870	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
7871		elem.type = elem.type.slice( 5 );
7872	} else {
7873		elem.removeAttribute( "type" );
7874	}
7875
7876	return elem;
7877}
7878
7879function cloneCopyEvent( src, dest ) {
7880	var i, l, type, pdataOld, udataOld, udataCur, events;
7881
7882	if ( dest.nodeType !== 1 ) {
7883		return;
7884	}
7885
7886	// 1. Copy private data: events, handlers, etc.
7887	if ( dataPriv.hasData( src ) ) {
7888		pdataOld = dataPriv.get( src );
7889		events = pdataOld.events;
7890
7891		if ( events ) {
7892			dataPriv.remove( dest, "handle events" );
7893
7894			for ( type in events ) {
7895				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
7896					jQuery.event.add( dest, type, events[ type ][ i ] );
7897				}
7898			}
7899		}
7900	}
7901
7902	// 2. Copy user data
7903	if ( dataUser.hasData( src ) ) {
7904		udataOld = dataUser.access( src );
7905		udataCur = jQuery.extend( {}, udataOld );
7906
7907		dataUser.set( dest, udataCur );
7908	}
7909}
7910
7911// Fix IE bugs, see support tests
7912function fixInput( src, dest ) {
7913	var nodeName = dest.nodeName.toLowerCase();
7914
7915	// Fails to persist the checked state of a cloned checkbox or radio button.
7916	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
7917		dest.checked = src.checked;
7918
7919	// Fails to return the selected option to the default selected state when cloning options
7920	} else if ( nodeName === "input" || nodeName === "textarea" ) {
7921		dest.defaultValue = src.defaultValue;
7922	}
7923}
7924
7925function domManip( collection, args, callback, ignored ) {
7926
7927	// Flatten any nested arrays
7928	args = flat( args );
7929
7930	var fragment, first, scripts, hasScripts, node, doc,
7931		i = 0,
7932		l = collection.length,
7933		iNoClone = l - 1,
7934		value = args[ 0 ],
7935		valueIsFunction = isFunction( value );
7936
7937	// We can't cloneNode fragments that contain checked, in WebKit
7938	if ( valueIsFunction ||
7939			( l > 1 && typeof value === "string" &&
7940				!support.checkClone && rchecked.test( value ) ) ) {
7941		return collection.each( function( index ) {
7942			var self = collection.eq( index );
7943			if ( valueIsFunction ) {
7944				args[ 0 ] = value.call( this, index, self.html() );
7945			}
7946			domManip( self, args, callback, ignored );
7947		} );
7948	}
7949
7950	if ( l ) {
7951		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
7952		first = fragment.firstChild;
7953
7954		if ( fragment.childNodes.length === 1 ) {
7955			fragment = first;
7956		}
7957
7958		// Require either new content or an interest in ignored elements to invoke the callback
7959		if ( first || ignored ) {
7960			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
7961			hasScripts = scripts.length;
7962
7963			// Use the original fragment for the last item
7964			// instead of the first because it can end up
7965			// being emptied incorrectly in certain situations (#8070).
7966			for ( ; i < l; i++ ) {
7967				node = fragment;
7968
7969				if ( i !== iNoClone ) {
7970					node = jQuery.clone( node, true, true );
7971
7972					// Keep references to cloned scripts for later restoration
7973					if ( hasScripts ) {
7974
7975						// Support: Android <=4.0 only, PhantomJS 1 only
7976						// push.apply(_, arraylike) throws on ancient WebKit
7977						jQuery.merge( scripts, getAll( node, "script" ) );
7978					}
7979				}
7980
7981				callback.call( collection[ i ], node, i );
7982			}
7983
7984			if ( hasScripts ) {
7985				doc = scripts[ scripts.length - 1 ].ownerDocument;
7986
7987				// Reenable scripts
7988				jQuery.map( scripts, restoreScript );
7989
7990				// Evaluate executable scripts on first document insertion
7991				for ( i = 0; i < hasScripts; i++ ) {
7992					node = scripts[ i ];
7993					if ( rscriptType.test( node.type || "" ) &&
7994						!dataPriv.access( node, "globalEval" ) &&
7995						jQuery.contains( doc, node ) ) {
7996
7997						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
7998
7999							// Optional AJAX dependency, but won't run scripts if not present
8000							if ( jQuery._evalUrl && !node.noModule ) {
8001								jQuery._evalUrl( node.src, {
8002									nonce: node.nonce || node.getAttribute( "nonce" )
8003								}, doc );
8004							}
8005						} else {
8006							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
8007						}
8008					}
8009				}
8010			}
8011		}
8012	}
8013
8014	return collection;
8015}
8016
8017function remove( elem, selector, keepData ) {
8018	var node,
8019		nodes = selector ? jQuery.filter( selector, elem ) : elem,
8020		i = 0;
8021
8022	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
8023		if ( !keepData && node.nodeType === 1 ) {
8024			jQuery.cleanData( getAll( node ) );
8025		}
8026
8027		if ( node.parentNode ) {
8028			if ( keepData && isAttached( node ) ) {
8029				setGlobalEval( getAll( node, "script" ) );
8030			}
8031			node.parentNode.removeChild( node );
8032		}
8033	}
8034
8035	return elem;
8036}
8037
8038jQuery.extend( {
8039	htmlPrefilter: function( html ) {
8040		return html;
8041	},
8042
8043	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
8044		var i, l, srcElements, destElements,
8045			clone = elem.cloneNode( true ),
8046			inPage = isAttached( elem );
8047
8048		// Fix IE cloning issues
8049		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
8050				!jQuery.isXMLDoc( elem ) ) {
8051
8052			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
8053			destElements = getAll( clone );
8054			srcElements = getAll( elem );
8055
8056			for ( i = 0, l = srcElements.length; i < l; i++ ) {
8057				fixInput( srcElements[ i ], destElements[ i ] );
8058			}
8059		}
8060
8061		// Copy the events from the original to the clone
8062		if ( dataAndEvents ) {
8063			if ( deepDataAndEvents ) {
8064				srcElements = srcElements || getAll( elem );
8065				destElements = destElements || getAll( clone );
8066
8067				for ( i = 0, l = srcElements.length; i < l; i++ ) {
8068					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
8069				}
8070			} else {
8071				cloneCopyEvent( elem, clone );
8072			}
8073		}
8074
8075		// Preserve script evaluation history
8076		destElements = getAll( clone, "script" );
8077		if ( destElements.length > 0 ) {
8078			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
8079		}
8080
8081		// Return the cloned set
8082		return clone;
8083	},
8084
8085	cleanData: function( elems ) {
8086		var data, elem, type,
8087			special = jQuery.event.special,
8088			i = 0;
8089
8090		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
8091			if ( acceptData( elem ) ) {
8092				if ( ( data = elem[ dataPriv.expando ] ) ) {
8093					if ( data.events ) {
8094						for ( type in data.events ) {
8095							if ( special[ type ] ) {
8096								jQuery.event.remove( elem, type );
8097
8098							// This is a shortcut to avoid jQuery.event.remove's overhead
8099							} else {
8100								jQuery.removeEvent( elem, type, data.handle );
8101							}
8102						}
8103					}
8104
8105					// Support: Chrome <=35 - 45+
8106					// Assign undefined instead of using delete, see Data#remove
8107					elem[ dataPriv.expando ] = undefined;
8108				}
8109				if ( elem[ dataUser.expando ] ) {
8110
8111					// Support: Chrome <=35 - 45+
8112					// Assign undefined instead of using delete, see Data#remove
8113					elem[ dataUser.expando ] = undefined;
8114				}
8115			}
8116		}
8117	}
8118} );
8119
8120jQuery.fn.extend( {
8121	detach: function( selector ) {
8122		return remove( this, selector, true );
8123	},
8124
8125	remove: function( selector ) {
8126		return remove( this, selector );
8127	},
8128
8129	text: function( value ) {
8130		return access( this, function( value ) {
8131			return value === undefined ?
8132				jQuery.text( this ) :
8133				this.empty().each( function() {
8134					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8135						this.textContent = value;
8136					}
8137				} );
8138		}, null, value, arguments.length );
8139	},
8140
8141	append: function() {
8142		return domManip( this, arguments, function( elem ) {
8143			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8144				var target = manipulationTarget( this, elem );
8145				target.appendChild( elem );
8146			}
8147		} );
8148	},
8149
8150	prepend: function() {
8151		return domManip( this, arguments, function( elem ) {
8152			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8153				var target = manipulationTarget( this, elem );
8154				target.insertBefore( elem, target.firstChild );
8155			}
8156		} );
8157	},
8158
8159	before: function() {
8160		return domManip( this, arguments, function( elem ) {
8161			if ( this.parentNode ) {
8162				this.parentNode.insertBefore( elem, this );
8163			}
8164		} );
8165	},
8166
8167	after: function() {
8168		return domManip( this, arguments, function( elem ) {
8169			if ( this.parentNode ) {
8170				this.parentNode.insertBefore( elem, this.nextSibling );
8171			}
8172		} );
8173	},
8174
8175	empty: function() {
8176		var elem,
8177			i = 0;
8178
8179		for ( ; ( elem = this[ i ] ) != null; i++ ) {
8180			if ( elem.nodeType === 1 ) {
8181
8182				// Prevent memory leaks
8183				jQuery.cleanData( getAll( elem, false ) );
8184
8185				// Remove any remaining nodes
8186				elem.textContent = "";
8187			}
8188		}
8189
8190		return this;
8191	},
8192
8193	clone: function( dataAndEvents, deepDataAndEvents ) {
8194		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
8195		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
8196
8197		return this.map( function() {
8198			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
8199		} );
8200	},
8201
8202	html: function( value ) {
8203		return access( this, function( value ) {
8204			var elem = this[ 0 ] || {},
8205				i = 0,
8206				l = this.length;
8207
8208			if ( value === undefined && elem.nodeType === 1 ) {
8209				return elem.innerHTML;
8210			}
8211
8212			// See if we can take a shortcut and just use innerHTML
8213			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
8214				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
8215
8216				value = jQuery.htmlPrefilter( value );
8217
8218				try {
8219					for ( ; i < l; i++ ) {
8220						elem = this[ i ] || {};
8221
8222						// Remove element nodes and prevent memory leaks
8223						if ( elem.nodeType === 1 ) {
8224							jQuery.cleanData( getAll( elem, false ) );
8225							elem.innerHTML = value;
8226						}
8227					}
8228
8229					elem = 0;
8230
8231				// If using innerHTML throws an exception, use the fallback method
8232				} catch ( e ) {}
8233			}
8234
8235			if ( elem ) {
8236				this.empty().append( value );
8237			}
8238		}, null, value, arguments.length );
8239	},
8240
8241	replaceWith: function() {
8242		var ignored = [];
8243
8244		// Make the changes, replacing each non-ignored context element with the new content
8245		return domManip( this, arguments, function( elem ) {
8246			var parent = this.parentNode;
8247
8248			if ( jQuery.inArray( this, ignored ) < 0 ) {
8249				jQuery.cleanData( getAll( this ) );
8250				if ( parent ) {
8251					parent.replaceChild( elem, this );
8252				}
8253			}
8254
8255		// Force callback invocation
8256		}, ignored );
8257	}
8258} );
8259
8260jQuery.each( {
8261	appendTo: "append",
8262	prependTo: "prepend",
8263	insertBefore: "before",
8264	insertAfter: "after",
8265	replaceAll: "replaceWith"
8266}, function( name, original ) {
8267	jQuery.fn[ name ] = function( selector ) {
8268		var elems,
8269			ret = [],
8270			insert = jQuery( selector ),
8271			last = insert.length - 1,
8272			i = 0;
8273
8274		for ( ; i <= last; i++ ) {
8275			elems = i === last ? this : this.clone( true );
8276			jQuery( insert[ i ] )[ original ]( elems );
8277
8278			// Support: Android <=4.0 only, PhantomJS 1 only
8279			// .get() because push.apply(_, arraylike) throws on ancient WebKit
8280			push.apply( ret, elems.get() );
8281		}
8282
8283		return this.pushStack( ret );
8284	};
8285} );
8286var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
8287
8288var getStyles = function( elem ) {
8289
8290		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
8291		// IE throws on elements created in popups
8292		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
8293		var view = elem.ownerDocument.defaultView;
8294
8295		if ( !view || !view.opener ) {
8296			view = window;
8297		}
8298
8299		return view.getComputedStyle( elem );
8300	};
8301
8302var swap = function( elem, options, callback ) {
8303	var ret, name,
8304		old = {};
8305
8306	// Remember the old values, and insert the new ones
8307	for ( name in options ) {
8308		old[ name ] = elem.style[ name ];
8309		elem.style[ name ] = options[ name ];
8310	}
8311
8312	ret = callback.call( elem );
8313
8314	// Revert the old values
8315	for ( name in options ) {
8316		elem.style[ name ] = old[ name ];
8317	}
8318
8319	return ret;
8320};
8321
8322
8323var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
8324
8325
8326
8327( function() {
8328
8329	// Executing both pixelPosition & boxSizingReliable tests require only one layout
8330	// so they're executed at the same time to save the second computation.
8331	function computeStyleTests() {
8332
8333		// This is a singleton, we need to execute it only once
8334		if ( !div ) {
8335			return;
8336		}
8337
8338		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
8339			"margin-top:1px;padding:0;border:0";
8340		div.style.cssText =
8341			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
8342			"margin:auto;border:1px;padding:1px;" +
8343			"width:60%;top:1%";
8344		documentElement.appendChild( container ).appendChild( div );
8345
8346		var divStyle = window.getComputedStyle( div );
8347		pixelPositionVal = divStyle.top !== "1%";
8348
8349		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
8350		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
8351
8352		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
8353		// Some styles come back with percentage values, even though they shouldn't
8354		div.style.right = "60%";
8355		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
8356
8357		// Support: IE 9 - 11 only
8358		// Detect misreporting of content dimensions for box-sizing:border-box elements
8359		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
8360
8361		// Support: IE 9 only
8362		// Detect overflow:scroll screwiness (gh-3699)
8363		// Support: Chrome <=64
8364		// Don't get tricked when zoom affects offsetWidth (gh-4029)
8365		div.style.position = "absolute";
8366		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
8367
8368		documentElement.removeChild( container );
8369
8370		// Nullify the div so it wouldn't be stored in the memory and
8371		// it will also be a sign that checks already performed
8372		div = null;
8373	}
8374
8375	function roundPixelMeasures( measure ) {
8376		return Math.round( parseFloat( measure ) );
8377	}
8378
8379	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
8380		reliableTrDimensionsVal, reliableMarginLeftVal,
8381		container = document.createElement( "div" ),
8382		div = document.createElement( "div" );
8383
8384	// Finish early in limited (non-browser) environments
8385	if ( !div.style ) {
8386		return;
8387	}
8388
8389	// Support: IE <=9 - 11 only
8390	// Style of cloned element affects source element cloned (#8908)
8391	div.style.backgroundClip = "content-box";
8392	div.cloneNode( true ).style.backgroundClip = "";
8393	support.clearCloneStyle = div.style.backgroundClip === "content-box";
8394
8395	jQuery.extend( support, {
8396		boxSizingReliable: function() {
8397			computeStyleTests();
8398			return boxSizingReliableVal;
8399		},
8400		pixelBoxStyles: function() {
8401			computeStyleTests();
8402			return pixelBoxStylesVal;
8403		},
8404		pixelPosition: function() {
8405			computeStyleTests();
8406			return pixelPositionVal;
8407		},
8408		reliableMarginLeft: function() {
8409			computeStyleTests();
8410			return reliableMarginLeftVal;
8411		},
8412		scrollboxSize: function() {
8413			computeStyleTests();
8414			return scrollboxSizeVal;
8415		},
8416
8417		// Support: IE 9 - 11+, Edge 15 - 18+
8418		// IE/Edge misreport `getComputedStyle` of table rows with width/height
8419		// set in CSS while `offset*` properties report correct values.
8420		// Behavior in IE 9 is more subtle than in newer versions & it passes
8421		// some versions of this test; make sure not to make it pass there!
8422		//
8423		// Support: Firefox 70+
8424		// Only Firefox includes border widths
8425		// in computed dimensions. (gh-4529)
8426		reliableTrDimensions: function() {
8427			var table, tr, trChild, trStyle;
8428			if ( reliableTrDimensionsVal == null ) {
8429				table = document.createElement( "table" );
8430				tr = document.createElement( "tr" );
8431				trChild = document.createElement( "div" );
8432
8433				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
8434				tr.style.cssText = "border:1px solid";
8435
8436				// Support: Chrome 86+
8437				// Height set through cssText does not get applied.
8438				// Computed height then comes back as 0.
8439				tr.style.height = "1px";
8440				trChild.style.height = "9px";
8441
8442				// Support: Android 8 Chrome 86+
8443				// In our bodyBackground.html iframe,
8444				// display for all div elements is set to "inline",
8445				// which causes a problem only in Android 8 Chrome 86.
8446				// Ensuring the div is display: block
8447				// gets around this issue.
8448				trChild.style.display = "block";
8449
8450				documentElement
8451					.appendChild( table )
8452					.appendChild( tr )
8453					.appendChild( trChild );
8454
8455				trStyle = window.getComputedStyle( tr );
8456				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
8457					parseInt( trStyle.borderTopWidth, 10 ) +
8458					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
8459
8460				documentElement.removeChild( table );
8461			}
8462			return reliableTrDimensionsVal;
8463		}
8464	} );
8465} )();
8466
8467
8468function curCSS( elem, name, computed ) {
8469	var width, minWidth, maxWidth, ret,
8470
8471		// Support: Firefox 51+
8472		// Retrieving style before computed somehow
8473		// fixes an issue with getting wrong values
8474		// on detached elements
8475		style = elem.style;
8476
8477	computed = computed || getStyles( elem );
8478
8479	// getPropertyValue is needed for:
8480	//   .css('filter') (IE 9 only, #12537)
8481	//   .css('--customProperty) (#3144)
8482	if ( computed ) {
8483		ret = computed.getPropertyValue( name ) || computed[ name ];
8484
8485		if ( ret === "" && !isAttached( elem ) ) {
8486			ret = jQuery.style( elem, name );
8487		}
8488
8489		// A tribute to the "awesome hack by Dean Edwards"
8490		// Android Browser returns percentage for some values,
8491		// but width seems to be reliably pixels.
8492		// This is against the CSSOM draft spec:
8493		// https://drafts.csswg.org/cssom/#resolved-values
8494		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
8495
8496			// Remember the original values
8497			width = style.width;
8498			minWidth = style.minWidth;
8499			maxWidth = style.maxWidth;
8500
8501			// Put in the new values to get a computed value out
8502			style.minWidth = style.maxWidth = style.width = ret;
8503			ret = computed.width;
8504
8505			// Revert the changed values
8506			style.width = width;
8507			style.minWidth = minWidth;
8508			style.maxWidth = maxWidth;
8509		}
8510	}
8511
8512	return ret !== undefined ?
8513
8514		// Support: IE <=9 - 11 only
8515		// IE returns zIndex value as an integer.
8516		ret + "" :
8517		ret;
8518}
8519
8520
8521function addGetHookIf( conditionFn, hookFn ) {
8522
8523	// Define the hook, we'll check on the first run if it's really needed.
8524	return {
8525		get: function() {
8526			if ( conditionFn() ) {
8527
8528				// Hook not needed (or it's not possible to use it due
8529				// to missing dependency), remove it.
8530				delete this.get;
8531				return;
8532			}
8533
8534			// Hook needed; redefine it so that the support test is not executed again.
8535			return ( this.get = hookFn ).apply( this, arguments );
8536		}
8537	};
8538}
8539
8540
8541var cssPrefixes = [ "Webkit", "Moz", "ms" ],
8542	emptyStyle = document.createElement( "div" ).style,
8543	vendorProps = {};
8544
8545// Return a vendor-prefixed property or undefined
8546function vendorPropName( name ) {
8547
8548	// Check for vendor prefixed names
8549	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
8550		i = cssPrefixes.length;
8551
8552	while ( i-- ) {
8553		name = cssPrefixes[ i ] + capName;
8554		if ( name in emptyStyle ) {
8555			return name;
8556		}
8557	}
8558}
8559
8560// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
8561function finalPropName( name ) {
8562	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
8563
8564	if ( final ) {
8565		return final;
8566	}
8567	if ( name in emptyStyle ) {
8568		return name;
8569	}
8570	return vendorProps[ name ] = vendorPropName( name ) || name;
8571}
8572
8573
8574var
8575
8576	// Swappable if display is none or starts with table
8577	// except "table", "table-cell", or "table-caption"
8578	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
8579	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
8580	rcustomProp = /^--/,
8581	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
8582	cssNormalTransform = {
8583		letterSpacing: "0",
8584		fontWeight: "400"
8585	};
8586
8587function setPositiveNumber( _elem, value, subtract ) {
8588
8589	// Any relative (+/-) values have already been
8590	// normalized at this point
8591	var matches = rcssNum.exec( value );
8592	return matches ?
8593
8594		// Guard against undefined "subtract", e.g., when used as in cssHooks
8595		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
8596		value;
8597}
8598
8599function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
8600	var i = dimension === "width" ? 1 : 0,
8601		extra = 0,
8602		delta = 0;
8603
8604	// Adjustment may not be necessary
8605	if ( box === ( isBorderBox ? "border" : "content" ) ) {
8606		return 0;
8607	}
8608
8609	for ( ; i < 4; i += 2 ) {
8610
8611		// Both box models exclude margin
8612		if ( box === "margin" ) {
8613			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
8614		}
8615
8616		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
8617		if ( !isBorderBox ) {
8618
8619			// Add padding
8620			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
8621
8622			// For "border" or "margin", add border
8623			if ( box !== "padding" ) {
8624				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8625
8626			// But still keep track of it otherwise
8627			} else {
8628				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8629			}
8630
8631		// If we get here with a border-box (content + padding + border), we're seeking "content" or
8632		// "padding" or "margin"
8633		} else {
8634
8635			// For "content", subtract padding
8636			if ( box === "content" ) {
8637				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
8638			}
8639
8640			// For "content" or "padding", subtract border
8641			if ( box !== "margin" ) {
8642				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8643			}
8644		}
8645	}
8646
8647	// Account for positive content-box scroll gutter when requested by providing computedVal
8648	if ( !isBorderBox && computedVal >= 0 ) {
8649
8650		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
8651		// Assuming integer scroll gutter, subtract the rest and round down
8652		delta += Math.max( 0, Math.ceil(
8653			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
8654			computedVal -
8655			delta -
8656			extra -
8657			0.5
8658
8659		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
8660		// Use an explicit zero to avoid NaN (gh-3964)
8661		) ) || 0;
8662	}
8663
8664	return delta;
8665}
8666
8667function getWidthOrHeight( elem, dimension, extra ) {
8668
8669	// Start with computed style
8670	var styles = getStyles( elem ),
8671
8672		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
8673		// Fake content-box until we know it's needed to know the true value.
8674		boxSizingNeeded = !support.boxSizingReliable() || extra,
8675		isBorderBox = boxSizingNeeded &&
8676			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
8677		valueIsBorderBox = isBorderBox,
8678
8679		val = curCSS( elem, dimension, styles ),
8680		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
8681
8682	// Support: Firefox <=54
8683	// Return a confounding non-pixel value or feign ignorance, as appropriate.
8684	if ( rnumnonpx.test( val ) ) {
8685		if ( !extra ) {
8686			return val;
8687		}
8688		val = "auto";
8689	}
8690
8691
8692	// Support: IE 9 - 11 only
8693	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
8694	// In those cases, the computed value can be trusted to be border-box.
8695	if ( ( !support.boxSizingReliable() && isBorderBox ||
8696
8697		// Support: IE 10 - 11+, Edge 15 - 18+
8698		// IE/Edge misreport `getComputedStyle` of table rows with width/height
8699		// set in CSS while `offset*` properties report correct values.
8700		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
8701		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
8702
8703		// Fall back to offsetWidth/offsetHeight when value is "auto"
8704		// This happens for inline elements with no explicit setting (gh-3571)
8705		val === "auto" ||
8706
8707		// Support: Android <=4.1 - 4.3 only
8708		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
8709		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
8710
8711		// Make sure the element is visible & connected
8712		elem.getClientRects().length ) {
8713
8714		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
8715
8716		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
8717		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
8718		// retrieved value as a content box dimension.
8719		valueIsBorderBox = offsetProp in elem;
8720		if ( valueIsBorderBox ) {
8721			val = elem[ offsetProp ];
8722		}
8723	}
8724
8725	// Normalize "" and auto
8726	val = parseFloat( val ) || 0;
8727
8728	// Adjust for the element's box model
8729	return ( val +
8730		boxModelAdjustment(
8731			elem,
8732			dimension,
8733			extra || ( isBorderBox ? "border" : "content" ),
8734			valueIsBorderBox,
8735			styles,
8736
8737			// Provide the current computed size to request scroll gutter calculation (gh-3589)
8738			val
8739		)
8740	) + "px";
8741}
8742
8743jQuery.extend( {
8744
8745	// Add in style property hooks for overriding the default
8746	// behavior of getting and setting a style property
8747	cssHooks: {
8748		opacity: {
8749			get: function( elem, computed ) {
8750				if ( computed ) {
8751
8752					// We should always get a number back from opacity
8753					var ret = curCSS( elem, "opacity" );
8754					return ret === "" ? "1" : ret;
8755				}
8756			}
8757		}
8758	},
8759
8760	// Don't automatically add "px" to these possibly-unitless properties
8761	cssNumber: {
8762		"animationIterationCount": true,
8763		"columnCount": true,
8764		"fillOpacity": true,
8765		"flexGrow": true,
8766		"flexShrink": true,
8767		"fontWeight": true,
8768		"gridArea": true,
8769		"gridColumn": true,
8770		"gridColumnEnd": true,
8771		"gridColumnStart": true,
8772		"gridRow": true,
8773		"gridRowEnd": true,
8774		"gridRowStart": true,
8775		"lineHeight": true,
8776		"opacity": true,
8777		"order": true,
8778		"orphans": true,
8779		"widows": true,
8780		"zIndex": true,
8781		"zoom": true
8782	},
8783
8784	// Add in properties whose names you wish to fix before
8785	// setting or getting the value
8786	cssProps: {},
8787
8788	// Get and set the style property on a DOM Node
8789	style: function( elem, name, value, extra ) {
8790
8791		// Don't set styles on text and comment nodes
8792		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
8793			return;
8794		}
8795
8796		// Make sure that we're working with the right name
8797		var ret, type, hooks,
8798			origName = camelCase( name ),
8799			isCustomProp = rcustomProp.test( name ),
8800			style = elem.style;
8801
8802		// Make sure that we're working with the right name. We don't
8803		// want to query the value if it is a CSS custom property
8804		// since they are user-defined.
8805		if ( !isCustomProp ) {
8806			name = finalPropName( origName );
8807		}
8808
8809		// Gets hook for the prefixed version, then unprefixed version
8810		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
8811
8812		// Check if we're setting a value
8813		if ( value !== undefined ) {
8814			type = typeof value;
8815
8816			// Convert "+=" or "-=" to relative numbers (#7345)
8817			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
8818				value = adjustCSS( elem, name, ret );
8819
8820				// Fixes bug #9237
8821				type = "number";
8822			}
8823
8824			// Make sure that null and NaN values aren't set (#7116)
8825			if ( value == null || value !== value ) {
8826				return;
8827			}
8828
8829			// If a number was passed in, add the unit (except for certain CSS properties)
8830			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
8831			// "px" to a few hardcoded values.
8832			if ( type === "number" && !isCustomProp ) {
8833				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
8834			}
8835
8836			// background-* props affect original clone's values
8837			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
8838				style[ name ] = "inherit";
8839			}
8840
8841			// If a hook was provided, use that value, otherwise just set the specified value
8842			if ( !hooks || !( "set" in hooks ) ||
8843				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
8844
8845				if ( isCustomProp ) {
8846					style.setProperty( name, value );
8847				} else {
8848					style[ name ] = value;
8849				}
8850			}
8851
8852		} else {
8853
8854			// If a hook was provided get the non-computed value from there
8855			if ( hooks && "get" in hooks &&
8856				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
8857
8858				return ret;
8859			}
8860
8861			// Otherwise just get the value from the style object
8862			return style[ name ];
8863		}
8864	},
8865
8866	css: function( elem, name, extra, styles ) {
8867		var val, num, hooks,
8868			origName = camelCase( name ),
8869			isCustomProp = rcustomProp.test( name );
8870
8871		// Make sure that we're working with the right name. We don't
8872		// want to modify the value if it is a CSS custom property
8873		// since they are user-defined.
8874		if ( !isCustomProp ) {
8875			name = finalPropName( origName );
8876		}
8877
8878		// Try prefixed name followed by the unprefixed name
8879		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
8880
8881		// If a hook was provided get the computed value from there
8882		if ( hooks && "get" in hooks ) {
8883			val = hooks.get( elem, true, extra );
8884		}
8885
8886		// Otherwise, if a way to get the computed value exists, use that
8887		if ( val === undefined ) {
8888			val = curCSS( elem, name, styles );
8889		}
8890
8891		// Convert "normal" to computed value
8892		if ( val === "normal" && name in cssNormalTransform ) {
8893			val = cssNormalTransform[ name ];
8894		}
8895
8896		// Make numeric if forced or a qualifier was provided and val looks numeric
8897		if ( extra === "" || extra ) {
8898			num = parseFloat( val );
8899			return extra === true || isFinite( num ) ? num || 0 : val;
8900		}
8901
8902		return val;
8903	}
8904} );
8905
8906jQuery.each( [ "height", "width" ], function( _i, dimension ) {
8907	jQuery.cssHooks[ dimension ] = {
8908		get: function( elem, computed, extra ) {
8909			if ( computed ) {
8910
8911				// Certain elements can have dimension info if we invisibly show them
8912				// but it must have a current display style that would benefit
8913				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
8914
8915					// Support: Safari 8+
8916					// Table columns in Safari have non-zero offsetWidth & zero
8917					// getBoundingClientRect().width unless display is changed.
8918					// Support: IE <=11 only
8919					// Running getBoundingClientRect on a disconnected node
8920					// in IE throws an error.
8921					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
8922					swap( elem, cssShow, function() {
8923						return getWidthOrHeight( elem, dimension, extra );
8924					} ) :
8925					getWidthOrHeight( elem, dimension, extra );
8926			}
8927		},
8928
8929		set: function( elem, value, extra ) {
8930			var matches,
8931				styles = getStyles( elem ),
8932
8933				// Only read styles.position if the test has a chance to fail
8934				// to avoid forcing a reflow.
8935				scrollboxSizeBuggy = !support.scrollboxSize() &&
8936					styles.position === "absolute",
8937
8938				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
8939				boxSizingNeeded = scrollboxSizeBuggy || extra,
8940				isBorderBox = boxSizingNeeded &&
8941					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
8942				subtract = extra ?
8943					boxModelAdjustment(
8944						elem,
8945						dimension,
8946						extra,
8947						isBorderBox,
8948						styles
8949					) :
8950					0;
8951
8952			// Account for unreliable border-box dimensions by comparing offset* to computed and
8953			// faking a content-box to get border and padding (gh-3699)
8954			if ( isBorderBox && scrollboxSizeBuggy ) {
8955				subtract -= Math.ceil(
8956					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
8957					parseFloat( styles[ dimension ] ) -
8958					boxModelAdjustment( elem, dimension, "border", false, styles ) -
8959					0.5
8960				);
8961			}
8962
8963			// Convert to pixels if value adjustment is needed
8964			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
8965				( matches[ 3 ] || "px" ) !== "px" ) {
8966
8967				elem.style[ dimension ] = value;
8968				value = jQuery.css( elem, dimension );
8969			}
8970
8971			return setPositiveNumber( elem, value, subtract );
8972		}
8973	};
8974} );
8975
8976jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
8977	function( elem, computed ) {
8978		if ( computed ) {
8979			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
8980				elem.getBoundingClientRect().left -
8981					swap( elem, { marginLeft: 0 }, function() {
8982						return elem.getBoundingClientRect().left;
8983					} )
8984			) + "px";
8985		}
8986	}
8987);
8988
8989// These hooks are used by animate to expand properties
8990jQuery.each( {
8991	margin: "",
8992	padding: "",
8993	border: "Width"
8994}, function( prefix, suffix ) {
8995	jQuery.cssHooks[ prefix + suffix ] = {
8996		expand: function( value ) {
8997			var i = 0,
8998				expanded = {},
8999
9000				// Assumes a single number if not a string
9001				parts = typeof value === "string" ? value.split( " " ) : [ value ];
9002
9003			for ( ; i < 4; i++ ) {
9004				expanded[ prefix + cssExpand[ i ] + suffix ] =
9005					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
9006			}
9007
9008			return expanded;
9009		}
9010	};
9011
9012	if ( prefix !== "margin" ) {
9013		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
9014	}
9015} );
9016
9017jQuery.fn.extend( {
9018	css: function( name, value ) {
9019		return access( this, function( elem, name, value ) {
9020			var styles, len,
9021				map = {},
9022				i = 0;
9023
9024			if ( Array.isArray( name ) ) {
9025				styles = getStyles( elem );
9026				len = name.length;
9027
9028				for ( ; i < len; i++ ) {
9029					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
9030				}
9031
9032				return map;
9033			}
9034
9035			return value !== undefined ?
9036				jQuery.style( elem, name, value ) :
9037				jQuery.css( elem, name );
9038		}, name, value, arguments.length > 1 );
9039	}
9040} );
9041
9042
9043function Tween( elem, options, prop, end, easing ) {
9044	return new Tween.prototype.init( elem, options, prop, end, easing );
9045}
9046jQuery.Tween = Tween;
9047
9048Tween.prototype = {
9049	constructor: Tween,
9050	init: function( elem, options, prop, end, easing, unit ) {
9051		this.elem = elem;
9052		this.prop = prop;
9053		this.easing = easing || jQuery.easing._default;
9054		this.options = options;
9055		this.start = this.now = this.cur();
9056		this.end = end;
9057		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
9058	},
9059	cur: function() {
9060		var hooks = Tween.propHooks[ this.prop ];
9061
9062		return hooks && hooks.get ?
9063			hooks.get( this ) :
9064			Tween.propHooks._default.get( this );
9065	},
9066	run: function( percent ) {
9067		var eased,
9068			hooks = Tween.propHooks[ this.prop ];
9069
9070		if ( this.options.duration ) {
9071			this.pos = eased = jQuery.easing[ this.easing ](
9072				percent, this.options.duration * percent, 0, 1, this.options.duration
9073			);
9074		} else {
9075			this.pos = eased = percent;
9076		}
9077		this.now = ( this.end - this.start ) * eased + this.start;
9078
9079		if ( this.options.step ) {
9080			this.options.step.call( this.elem, this.now, this );
9081		}
9082
9083		if ( hooks && hooks.set ) {
9084			hooks.set( this );
9085		} else {
9086			Tween.propHooks._default.set( this );
9087		}
9088		return this;
9089	}
9090};
9091
9092Tween.prototype.init.prototype = Tween.prototype;
9093
9094Tween.propHooks = {
9095	_default: {
9096		get: function( tween ) {
9097			var result;
9098
9099			// Use a property on the element directly when it is not a DOM element,
9100			// or when there is no matching style property that exists.
9101			if ( tween.elem.nodeType !== 1 ||
9102				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
9103				return tween.elem[ tween.prop ];
9104			}
9105
9106			// Passing an empty string as a 3rd parameter to .css will automatically
9107			// attempt a parseFloat and fallback to a string if the parse fails.
9108			// Simple values such as "10px" are parsed to Float;
9109			// complex values such as "rotate(1rad)" are returned as-is.
9110			result = jQuery.css( tween.elem, tween.prop, "" );
9111
9112			// Empty strings, null, undefined and "auto" are converted to 0.
9113			return !result || result === "auto" ? 0 : result;
9114		},
9115		set: function( tween ) {
9116
9117			// Use step hook for back compat.
9118			// Use cssHook if its there.
9119			// Use .style if available and use plain properties where available.
9120			if ( jQuery.fx.step[ tween.prop ] ) {
9121				jQuery.fx.step[ tween.prop ]( tween );
9122			} else if ( tween.elem.nodeType === 1 && (
9123				jQuery.cssHooks[ tween.prop ] ||
9124					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
9125				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
9126			} else {
9127				tween.elem[ tween.prop ] = tween.now;
9128			}
9129		}
9130	}
9131};
9132
9133// Support: IE <=9 only
9134// Panic based approach to setting things on disconnected nodes
9135Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
9136	set: function( tween ) {
9137		if ( tween.elem.nodeType && tween.elem.parentNode ) {
9138			tween.elem[ tween.prop ] = tween.now;
9139		}
9140	}
9141};
9142
9143jQuery.easing = {
9144	linear: function( p ) {
9145		return p;
9146	},
9147	swing: function( p ) {
9148		return 0.5 - Math.cos( p * Math.PI ) / 2;
9149	},
9150	_default: "swing"
9151};
9152
9153jQuery.fx = Tween.prototype.init;
9154
9155// Back compat <1.8 extension point
9156jQuery.fx.step = {};
9157
9158
9159
9160
9161var
9162	fxNow, inProgress,
9163	rfxtypes = /^(?:toggle|show|hide)$/,
9164	rrun = /queueHooks$/;
9165
9166function schedule() {
9167	if ( inProgress ) {
9168		if ( document.hidden === false && window.requestAnimationFrame ) {
9169			window.requestAnimationFrame( schedule );
9170		} else {
9171			window.setTimeout( schedule, jQuery.fx.interval );
9172		}
9173
9174		jQuery.fx.tick();
9175	}
9176}
9177
9178// Animations created synchronously will run synchronously
9179function createFxNow() {
9180	window.setTimeout( function() {
9181		fxNow = undefined;
9182	} );
9183	return ( fxNow = Date.now() );
9184}
9185
9186// Generate parameters to create a standard animation
9187function genFx( type, includeWidth ) {
9188	var which,
9189		i = 0,
9190		attrs = { height: type };
9191
9192	// If we include width, step value is 1 to do all cssExpand values,
9193	// otherwise step value is 2 to skip over Left and Right
9194	includeWidth = includeWidth ? 1 : 0;
9195	for ( ; i < 4; i += 2 - includeWidth ) {
9196		which = cssExpand[ i ];
9197		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9198	}
9199
9200	if ( includeWidth ) {
9201		attrs.opacity = attrs.width = type;
9202	}
9203
9204	return attrs;
9205}
9206
9207function createTween( value, prop, animation ) {
9208	var tween,
9209		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
9210		index = 0,
9211		length = collection.length;
9212	for ( ; index < length; index++ ) {
9213		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
9214
9215			// We're done with this property
9216			return tween;
9217		}
9218	}
9219}
9220
9221function defaultPrefilter( elem, props, opts ) {
9222	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
9223		isBox = "width" in props || "height" in props,
9224		anim = this,
9225		orig = {},
9226		style = elem.style,
9227		hidden = elem.nodeType && isHiddenWithinTree( elem ),
9228		dataShow = dataPriv.get( elem, "fxshow" );
9229
9230	// Queue-skipping animations hijack the fx hooks
9231	if ( !opts.queue ) {
9232		hooks = jQuery._queueHooks( elem, "fx" );
9233		if ( hooks.unqueued == null ) {
9234			hooks.unqueued = 0;
9235			oldfire = hooks.empty.fire;
9236			hooks.empty.fire = function() {
9237				if ( !hooks.unqueued ) {
9238					oldfire();
9239				}
9240			};
9241		}
9242		hooks.unqueued++;
9243
9244		anim.always( function() {
9245
9246			// Ensure the complete handler is called before this completes
9247			anim.always( function() {
9248				hooks.unqueued--;
9249				if ( !jQuery.queue( elem, "fx" ).length ) {
9250					hooks.empty.fire();
9251				}
9252			} );
9253		} );
9254	}
9255
9256	// Detect show/hide animations
9257	for ( prop in props ) {
9258		value = props[ prop ];
9259		if ( rfxtypes.test( value ) ) {
9260			delete props[ prop ];
9261			toggle = toggle || value === "toggle";
9262			if ( value === ( hidden ? "hide" : "show" ) ) {
9263
9264				// Pretend to be hidden if this is a "show" and
9265				// there is still data from a stopped show/hide
9266				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
9267					hidden = true;
9268
9269				// Ignore all other no-op show/hide data
9270				} else {
9271					continue;
9272				}
9273			}
9274			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
9275		}
9276	}
9277
9278	// Bail out if this is a no-op like .hide().hide()
9279	propTween = !jQuery.isEmptyObject( props );
9280	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
9281		return;
9282	}
9283
9284	// Restrict "overflow" and "display" styles during box animations
9285	if ( isBox && elem.nodeType === 1 ) {
9286
9287		// Support: IE <=9 - 11, Edge 12 - 15
9288		// Record all 3 overflow attributes because IE does not infer the shorthand
9289		// from identically-valued overflowX and overflowY and Edge just mirrors
9290		// the overflowX value there.
9291		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
9292
9293		// Identify a display type, preferring old show/hide data over the CSS cascade
9294		restoreDisplay = dataShow && dataShow.display;
9295		if ( restoreDisplay == null ) {
9296			restoreDisplay = dataPriv.get( elem, "display" );
9297		}
9298		display = jQuery.css( elem, "display" );
9299		if ( display === "none" ) {
9300			if ( restoreDisplay ) {
9301				display = restoreDisplay;
9302			} else {
9303
9304				// Get nonempty value(s) by temporarily forcing visibility
9305				showHide( [ elem ], true );
9306				restoreDisplay = elem.style.display || restoreDisplay;
9307				display = jQuery.css( elem, "display" );
9308				showHide( [ elem ] );
9309			}
9310		}
9311
9312		// Animate inline elements as inline-block
9313		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
9314			if ( jQuery.css( elem, "float" ) === "none" ) {
9315
9316				// Restore the original display value at the end of pure show/hide animations
9317				if ( !propTween ) {
9318					anim.done( function() {
9319						style.display = restoreDisplay;
9320					} );
9321					if ( restoreDisplay == null ) {
9322						display = style.display;
9323						restoreDisplay = display === "none" ? "" : display;
9324					}
9325				}
9326				style.display = "inline-block";
9327			}
9328		}
9329	}
9330
9331	if ( opts.overflow ) {
9332		style.overflow = "hidden";
9333		anim.always( function() {
9334			style.overflow = opts.overflow[ 0 ];
9335			style.overflowX = opts.overflow[ 1 ];
9336			style.overflowY = opts.overflow[ 2 ];
9337		} );
9338	}
9339
9340	// Implement show/hide animations
9341	propTween = false;
9342	for ( prop in orig ) {
9343
9344		// General show/hide setup for this element animation
9345		if ( !propTween ) {
9346			if ( dataShow ) {
9347				if ( "hidden" in dataShow ) {
9348					hidden = dataShow.hidden;
9349				}
9350			} else {
9351				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
9352			}
9353
9354			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
9355			if ( toggle ) {
9356				dataShow.hidden = !hidden;
9357			}
9358
9359			// Show elements before animating them
9360			if ( hidden ) {
9361				showHide( [ elem ], true );
9362			}
9363
9364			/* eslint-disable no-loop-func */
9365
9366			anim.done( function() {
9367
9368				/* eslint-enable no-loop-func */
9369
9370				// The final step of a "hide" animation is actually hiding the element
9371				if ( !hidden ) {
9372					showHide( [ elem ] );
9373				}
9374				dataPriv.remove( elem, "fxshow" );
9375				for ( prop in orig ) {
9376					jQuery.style( elem, prop, orig[ prop ] );
9377				}
9378			} );
9379		}
9380
9381		// Per-property setup
9382		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
9383		if ( !( prop in dataShow ) ) {
9384			dataShow[ prop ] = propTween.start;
9385			if ( hidden ) {
9386				propTween.end = propTween.start;
9387				propTween.start = 0;
9388			}
9389		}
9390	}
9391}
9392
9393function propFilter( props, specialEasing ) {
9394	var index, name, easing, value, hooks;
9395
9396	// camelCase, specialEasing and expand cssHook pass
9397	for ( index in props ) {
9398		name = camelCase( index );
9399		easing = specialEasing[ name ];
9400		value = props[ index ];
9401		if ( Array.isArray( value ) ) {
9402			easing = value[ 1 ];
9403			value = props[ index ] = value[ 0 ];
9404		}
9405
9406		if ( index !== name ) {
9407			props[ name ] = value;
9408			delete props[ index ];
9409		}
9410
9411		hooks = jQuery.cssHooks[ name ];
9412		if ( hooks && "expand" in hooks ) {
9413			value = hooks.expand( value );
9414			delete props[ name ];
9415
9416			// Not quite $.extend, this won't overwrite existing keys.
9417			// Reusing 'index' because we have the correct "name"
9418			for ( index in value ) {
9419				if ( !( index in props ) ) {
9420					props[ index ] = value[ index ];
9421					specialEasing[ index ] = easing;
9422				}
9423			}
9424		} else {
9425			specialEasing[ name ] = easing;
9426		}
9427	}
9428}
9429
9430function Animation( elem, properties, options ) {
9431	var result,
9432		stopped,
9433		index = 0,
9434		length = Animation.prefilters.length,
9435		deferred = jQuery.Deferred().always( function() {
9436
9437			// Don't match elem in the :animated selector
9438			delete tick.elem;
9439		} ),
9440		tick = function() {
9441			if ( stopped ) {
9442				return false;
9443			}
9444			var currentTime = fxNow || createFxNow(),
9445				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
9446
9447				// Support: Android 2.3 only
9448				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
9449				temp = remaining / animation.duration || 0,
9450				percent = 1 - temp,
9451				index = 0,
9452				length = animation.tweens.length;
9453
9454			for ( ; index < length; index++ ) {
9455				animation.tweens[ index ].run( percent );
9456			}
9457
9458			deferred.notifyWith( elem, [ animation, percent, remaining ] );
9459
9460			// If there's more to do, yield
9461			if ( percent < 1 && length ) {
9462				return remaining;
9463			}
9464
9465			// If this was an empty animation, synthesize a final progress notification
9466			if ( !length ) {
9467				deferred.notifyWith( elem, [ animation, 1, 0 ] );
9468			}
9469
9470			// Resolve the animation and report its conclusion
9471			deferred.resolveWith( elem, [ animation ] );
9472			return false;
9473		},
9474		animation = deferred.promise( {
9475			elem: elem,
9476			props: jQuery.extend( {}, properties ),
9477			opts: jQuery.extend( true, {
9478				specialEasing: {},
9479				easing: jQuery.easing._default
9480			}, options ),
9481			originalProperties: properties,
9482			originalOptions: options,
9483			startTime: fxNow || createFxNow(),
9484			duration: options.duration,
9485			tweens: [],
9486			createTween: function( prop, end ) {
9487				var tween = jQuery.Tween( elem, animation.opts, prop, end,
9488					animation.opts.specialEasing[ prop ] || animation.opts.easing );
9489				animation.tweens.push( tween );
9490				return tween;
9491			},
9492			stop: function( gotoEnd ) {
9493				var index = 0,
9494
9495					// If we are going to the end, we want to run all the tweens
9496					// otherwise we skip this part
9497					length = gotoEnd ? animation.tweens.length : 0;
9498				if ( stopped ) {
9499					return this;
9500				}
9501				stopped = true;
9502				for ( ; index < length; index++ ) {
9503					animation.tweens[ index ].run( 1 );
9504				}
9505
9506				// Resolve when we played the last frame; otherwise, reject
9507				if ( gotoEnd ) {
9508					deferred.notifyWith( elem, [ animation, 1, 0 ] );
9509					deferred.resolveWith( elem, [ animation, gotoEnd ] );
9510				} else {
9511					deferred.rejectWith( elem, [ animation, gotoEnd ] );
9512				}
9513				return this;
9514			}
9515		} ),
9516		props = animation.props;
9517
9518	propFilter( props, animation.opts.specialEasing );
9519
9520	for ( ; index < length; index++ ) {
9521		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
9522		if ( result ) {
9523			if ( isFunction( result.stop ) ) {
9524				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
9525					result.stop.bind( result );
9526			}
9527			return result;
9528		}
9529	}
9530
9531	jQuery.map( props, createTween, animation );
9532
9533	if ( isFunction( animation.opts.start ) ) {
9534		animation.opts.start.call( elem, animation );
9535	}
9536
9537	// Attach callbacks from options
9538	animation
9539		.progress( animation.opts.progress )
9540		.done( animation.opts.done, animation.opts.complete )
9541		.fail( animation.opts.fail )
9542		.always( animation.opts.always );
9543
9544	jQuery.fx.timer(
9545		jQuery.extend( tick, {
9546			elem: elem,
9547			anim: animation,
9548			queue: animation.opts.queue
9549		} )
9550	);
9551
9552	return animation;
9553}
9554
9555jQuery.Animation = jQuery.extend( Animation, {
9556
9557	tweeners: {
9558		"*": [ function( prop, value ) {
9559			var tween = this.createTween( prop, value );
9560			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
9561			return tween;
9562		} ]
9563	},
9564
9565	tweener: function( props, callback ) {
9566		if ( isFunction( props ) ) {
9567			callback = props;
9568			props = [ "*" ];
9569		} else {
9570			props = props.match( rnothtmlwhite );
9571		}
9572
9573		var prop,
9574			index = 0,
9575			length = props.length;
9576
9577		for ( ; index < length; index++ ) {
9578			prop = props[ index ];
9579			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
9580			Animation.tweeners[ prop ].unshift( callback );
9581		}
9582	},
9583
9584	prefilters: [ defaultPrefilter ],
9585
9586	prefilter: function( callback, prepend ) {
9587		if ( prepend ) {
9588			Animation.prefilters.unshift( callback );
9589		} else {
9590			Animation.prefilters.push( callback );
9591		}
9592	}
9593} );
9594
9595jQuery.speed = function( speed, easing, fn ) {
9596	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9597		complete: fn || !fn && easing ||
9598			isFunction( speed ) && speed,
9599		duration: speed,
9600		easing: fn && easing || easing && !isFunction( easing ) && easing
9601	};
9602
9603	// Go to the end state if fx are off
9604	if ( jQuery.fx.off ) {
9605		opt.duration = 0;
9606
9607	} else {
9608		if ( typeof opt.duration !== "number" ) {
9609			if ( opt.duration in jQuery.fx.speeds ) {
9610				opt.duration = jQuery.fx.speeds[ opt.duration ];
9611
9612			} else {
9613				opt.duration = jQuery.fx.speeds._default;
9614			}
9615		}
9616	}
9617
9618	// Normalize opt.queue - true/undefined/null -> "fx"
9619	if ( opt.queue == null || opt.queue === true ) {
9620		opt.queue = "fx";
9621	}
9622
9623	// Queueing
9624	opt.old = opt.complete;
9625
9626	opt.complete = function() {
9627		if ( isFunction( opt.old ) ) {
9628			opt.old.call( this );
9629		}
9630
9631		if ( opt.queue ) {
9632			jQuery.dequeue( this, opt.queue );
9633		}
9634	};
9635
9636	return opt;
9637};
9638
9639jQuery.fn.extend( {
9640	fadeTo: function( speed, to, easing, callback ) {
9641
9642		// Show any hidden elements after setting opacity to 0
9643		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
9644
9645			// Animate to the value specified
9646			.end().animate( { opacity: to }, speed, easing, callback );
9647	},
9648	animate: function( prop, speed, easing, callback ) {
9649		var empty = jQuery.isEmptyObject( prop ),
9650			optall = jQuery.speed( speed, easing, callback ),
9651			doAnimation = function() {
9652
9653				// Operate on a copy of prop so per-property easing won't be lost
9654				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9655
9656				// Empty animations, or finishing resolves immediately
9657				if ( empty || dataPriv.get( this, "finish" ) ) {
9658					anim.stop( true );
9659				}
9660			};
9661
9662		doAnimation.finish = doAnimation;
9663
9664		return empty || optall.queue === false ?
9665			this.each( doAnimation ) :
9666			this.queue( optall.queue, doAnimation );
9667	},
9668	stop: function( type, clearQueue, gotoEnd ) {
9669		var stopQueue = function( hooks ) {
9670			var stop = hooks.stop;
9671			delete hooks.stop;
9672			stop( gotoEnd );
9673		};
9674
9675		if ( typeof type !== "string" ) {
9676			gotoEnd = clearQueue;
9677			clearQueue = type;
9678			type = undefined;
9679		}
9680		if ( clearQueue ) {
9681			this.queue( type || "fx", [] );
9682		}
9683
9684		return this.each( function() {
9685			var dequeue = true,
9686				index = type != null && type + "queueHooks",
9687				timers = jQuery.timers,
9688				data = dataPriv.get( this );
9689
9690			if ( index ) {
9691				if ( data[ index ] && data[ index ].stop ) {
9692					stopQueue( data[ index ] );
9693				}
9694			} else {
9695				for ( index in data ) {
9696					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9697						stopQueue( data[ index ] );
9698					}
9699				}
9700			}
9701
9702			for ( index = timers.length; index--; ) {
9703				if ( timers[ index ].elem === this &&
9704					( type == null || timers[ index ].queue === type ) ) {
9705
9706					timers[ index ].anim.stop( gotoEnd );
9707					dequeue = false;
9708					timers.splice( index, 1 );
9709				}
9710			}
9711
9712			// Start the next in the queue if the last step wasn't forced.
9713			// Timers currently will call their complete callbacks, which
9714			// will dequeue but only if they were gotoEnd.
9715			if ( dequeue || !gotoEnd ) {
9716				jQuery.dequeue( this, type );
9717			}
9718		} );
9719	},
9720	finish: function( type ) {
9721		if ( type !== false ) {
9722			type = type || "fx";
9723		}
9724		return this.each( function() {
9725			var index,
9726				data = dataPriv.get( this ),
9727				queue = data[ type + "queue" ],
9728				hooks = data[ type + "queueHooks" ],
9729				timers = jQuery.timers,
9730				length = queue ? queue.length : 0;
9731
9732			// Enable finishing flag on private data
9733			data.finish = true;
9734
9735			// Empty the queue first
9736			jQuery.queue( this, type, [] );
9737
9738			if ( hooks && hooks.stop ) {
9739				hooks.stop.call( this, true );
9740			}
9741
9742			// Look for any active animations, and finish them
9743			for ( index = timers.length; index--; ) {
9744				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
9745					timers[ index ].anim.stop( true );
9746					timers.splice( index, 1 );
9747				}
9748			}
9749
9750			// Look for any animations in the old queue and finish them
9751			for ( index = 0; index < length; index++ ) {
9752				if ( queue[ index ] && queue[ index ].finish ) {
9753					queue[ index ].finish.call( this );
9754				}
9755			}
9756
9757			// Turn off finishing flag
9758			delete data.finish;
9759		} );
9760	}
9761} );
9762
9763jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
9764	var cssFn = jQuery.fn[ name ];
9765	jQuery.fn[ name ] = function( speed, easing, callback ) {
9766		return speed == null || typeof speed === "boolean" ?
9767			cssFn.apply( this, arguments ) :
9768			this.animate( genFx( name, true ), speed, easing, callback );
9769	};
9770} );
9771
9772// Generate shortcuts for custom animations
9773jQuery.each( {
9774	slideDown: genFx( "show" ),
9775	slideUp: genFx( "hide" ),
9776	slideToggle: genFx( "toggle" ),
9777	fadeIn: { opacity: "show" },
9778	fadeOut: { opacity: "hide" },
9779	fadeToggle: { opacity: "toggle" }
9780}, function( name, props ) {
9781	jQuery.fn[ name ] = function( speed, easing, callback ) {
9782		return this.animate( props, speed, easing, callback );
9783	};
9784} );
9785
9786jQuery.timers = [];
9787jQuery.fx.tick = function() {
9788	var timer,
9789		i = 0,
9790		timers = jQuery.timers;
9791
9792	fxNow = Date.now();
9793
9794	for ( ; i < timers.length; i++ ) {
9795		timer = timers[ i ];
9796
9797		// Run the timer and safely remove it when done (allowing for external removal)
9798		if ( !timer() && timers[ i ] === timer ) {
9799			timers.splice( i--, 1 );
9800		}
9801	}
9802
9803	if ( !timers.length ) {
9804		jQuery.fx.stop();
9805	}
9806	fxNow = undefined;
9807};
9808
9809jQuery.fx.timer = function( timer ) {
9810	jQuery.timers.push( timer );
9811	jQuery.fx.start();
9812};
9813
9814jQuery.fx.interval = 13;
9815jQuery.fx.start = function() {
9816	if ( inProgress ) {
9817		return;
9818	}
9819
9820	inProgress = true;
9821	schedule();
9822};
9823
9824jQuery.fx.stop = function() {
9825	inProgress = null;
9826};
9827
9828jQuery.fx.speeds = {
9829	slow: 600,
9830	fast: 200,
9831
9832	// Default speed
9833	_default: 400
9834};
9835
9836
9837// Based off of the plugin by Clint Helfers, with permission.
9838// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
9839jQuery.fn.delay = function( time, type ) {
9840	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
9841	type = type || "fx";
9842
9843	return this.queue( type, function( next, hooks ) {
9844		var timeout = window.setTimeout( next, time );
9845		hooks.stop = function() {
9846			window.clearTimeout( timeout );
9847		};
9848	} );
9849};
9850
9851
9852( function() {
9853	var input = document.createElement( "input" ),
9854		select = document.createElement( "select" ),
9855		opt = select.appendChild( document.createElement( "option" ) );
9856
9857	input.type = "checkbox";
9858
9859	// Support: Android <=4.3 only
9860	// Default value for a checkbox should be "on"
9861	support.checkOn = input.value !== "";
9862
9863	// Support: IE <=11 only
9864	// Must access selectedIndex to make default options select
9865	support.optSelected = opt.selected;
9866
9867	// Support: IE <=11 only
9868	// An input loses its value after becoming a radio
9869	input = document.createElement( "input" );
9870	input.value = "t";
9871	input.type = "radio";
9872	support.radioValue = input.value === "t";
9873} )();
9874
9875
9876var boolHook,
9877	attrHandle = jQuery.expr.attrHandle;
9878
9879jQuery.fn.extend( {
9880	attr: function( name, value ) {
9881		return access( this, jQuery.attr, name, value, arguments.length > 1 );
9882	},
9883
9884	removeAttr: function( name ) {
9885		return this.each( function() {
9886			jQuery.removeAttr( this, name );
9887		} );
9888	}
9889} );
9890
9891jQuery.extend( {
9892	attr: function( elem, name, value ) {
9893		var ret, hooks,
9894			nType = elem.nodeType;
9895
9896		// Don't get/set attributes on text, comment and attribute nodes
9897		if ( nType === 3 || nType === 8 || nType === 2 ) {
9898			return;
9899		}
9900
9901		// Fallback to prop when attributes are not supported
9902		if ( typeof elem.getAttribute === "undefined" ) {
9903			return jQuery.prop( elem, name, value );
9904		}
9905
9906		// Attribute hooks are determined by the lowercase version
9907		// Grab necessary hook if one is defined
9908		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
9909			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
9910				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
9911		}
9912
9913		if ( value !== undefined ) {
9914			if ( value === null ) {
9915				jQuery.removeAttr( elem, name );
9916				return;
9917			}
9918
9919			if ( hooks && "set" in hooks &&
9920				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
9921				return ret;
9922			}
9923
9924			elem.setAttribute( name, value + "" );
9925			return value;
9926		}
9927
9928		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
9929			return ret;
9930		}
9931
9932		ret = jQuery.find.attr( elem, name );
9933
9934		// Non-existent attributes return null, we normalize to undefined
9935		return ret == null ? undefined : ret;
9936	},
9937
9938	attrHooks: {
9939		type: {
9940			set: function( elem, value ) {
9941				if ( !support.radioValue && value === "radio" &&
9942					nodeName( elem, "input" ) ) {
9943					var val = elem.value;
9944					elem.setAttribute( "type", value );
9945					if ( val ) {
9946						elem.value = val;
9947					}
9948					return value;
9949				}
9950			}
9951		}
9952	},
9953
9954	removeAttr: function( elem, value ) {
9955		var name,
9956			i = 0,
9957
9958			// Attribute names can contain non-HTML whitespace characters
9959			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
9960			attrNames = value && value.match( rnothtmlwhite );
9961
9962		if ( attrNames && elem.nodeType === 1 ) {
9963			while ( ( name = attrNames[ i++ ] ) ) {
9964				elem.removeAttribute( name );
9965			}
9966		}
9967	}
9968} );
9969
9970// Hooks for boolean attributes
9971boolHook = {
9972	set: function( elem, value, name ) {
9973		if ( value === false ) {
9974
9975			// Remove boolean attributes when set to false
9976			jQuery.removeAttr( elem, name );
9977		} else {
9978			elem.setAttribute( name, name );
9979		}
9980		return name;
9981	}
9982};
9983
9984jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
9985	var getter = attrHandle[ name ] || jQuery.find.attr;
9986
9987	attrHandle[ name ] = function( elem, name, isXML ) {
9988		var ret, handle,
9989			lowercaseName = name.toLowerCase();
9990
9991		if ( !isXML ) {
9992
9993			// Avoid an infinite loop by temporarily removing this function from the getter
9994			handle = attrHandle[ lowercaseName ];
9995			attrHandle[ lowercaseName ] = ret;
9996			ret = getter( elem, name, isXML ) != null ?
9997				lowercaseName :
9998				null;
9999			attrHandle[ lowercaseName ] = handle;
10000		}
10001		return ret;
10002	};
10003} );
10004
10005
10006
10007
10008var rfocusable = /^(?:input|select|textarea|button)$/i,
10009	rclickable = /^(?:a|area)$/i;
10010
10011jQuery.fn.extend( {
10012	prop: function( name, value ) {
10013		return access( this, jQuery.prop, name, value, arguments.length > 1 );
10014	},
10015
10016	removeProp: function( name ) {
10017		return this.each( function() {
10018			delete this[ jQuery.propFix[ name ] || name ];
10019		} );
10020	}
10021} );
10022
10023jQuery.extend( {
10024	prop: function( elem, name, value ) {
10025		var ret, hooks,
10026			nType = elem.nodeType;
10027
10028		// Don't get/set properties on text, comment and attribute nodes
10029		if ( nType === 3 || nType === 8 || nType === 2 ) {
10030			return;
10031		}
10032
10033		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
10034
10035			// Fix name and attach hooks
10036			name = jQuery.propFix[ name ] || name;
10037			hooks = jQuery.propHooks[ name ];
10038		}
10039
10040		if ( value !== undefined ) {
10041			if ( hooks && "set" in hooks &&
10042				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
10043				return ret;
10044			}
10045
10046			return ( elem[ name ] = value );
10047		}
10048
10049		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
10050			return ret;
10051		}
10052
10053		return elem[ name ];
10054	},
10055
10056	propHooks: {
10057		tabIndex: {
10058			get: function( elem ) {
10059
10060				// Support: IE <=9 - 11 only
10061				// elem.tabIndex doesn't always return the
10062				// correct value when it hasn't been explicitly set
10063				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
10064				// Use proper attribute retrieval(#12072)
10065				var tabindex = jQuery.find.attr( elem, "tabindex" );
10066
10067				if ( tabindex ) {
10068					return parseInt( tabindex, 10 );
10069				}
10070
10071				if (
10072					rfocusable.test( elem.nodeName ) ||
10073					rclickable.test( elem.nodeName ) &&
10074					elem.href
10075				) {
10076					return 0;
10077				}
10078
10079				return -1;
10080			}
10081		}
10082	},
10083
10084	propFix: {
10085		"for": "htmlFor",
10086		"class": "className"
10087	}
10088} );
10089
10090// Support: IE <=11 only
10091// Accessing the selectedIndex property
10092// forces the browser to respect setting selected
10093// on the option
10094// The getter ensures a default option is selected
10095// when in an optgroup
10096// eslint rule "no-unused-expressions" is disabled for this code
10097// since it considers such accessions noop
10098if ( !support.optSelected ) {
10099	jQuery.propHooks.selected = {
10100		get: function( elem ) {
10101
10102			/* eslint no-unused-expressions: "off" */
10103
10104			var parent = elem.parentNode;
10105			if ( parent && parent.parentNode ) {
10106				parent.parentNode.selectedIndex;
10107			}
10108			return null;
10109		},
10110		set: function( elem ) {
10111
10112			/* eslint no-unused-expressions: "off" */
10113
10114			var parent = elem.parentNode;
10115			if ( parent ) {
10116				parent.selectedIndex;
10117
10118				if ( parent.parentNode ) {
10119					parent.parentNode.selectedIndex;
10120				}
10121			}
10122		}
10123	};
10124}
10125
10126jQuery.each( [
10127	"tabIndex",
10128	"readOnly",
10129	"maxLength",
10130	"cellSpacing",
10131	"cellPadding",
10132	"rowSpan",
10133	"colSpan",
10134	"useMap",
10135	"frameBorder",
10136	"contentEditable"
10137], function() {
10138	jQuery.propFix[ this.toLowerCase() ] = this;
10139} );
10140
10141
10142
10143
10144	// Strip and collapse whitespace according to HTML spec
10145	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
10146	function stripAndCollapse( value ) {
10147		var tokens = value.match( rnothtmlwhite ) || [];
10148		return tokens.join( " " );
10149	}
10150
10151
10152function getClass( elem ) {
10153	return elem.getAttribute && elem.getAttribute( "class" ) || "";
10154}
10155
10156function classesToArray( value ) {
10157	if ( Array.isArray( value ) ) {
10158		return value;
10159	}
10160	if ( typeof value === "string" ) {
10161		return value.match( rnothtmlwhite ) || [];
10162	}
10163	return [];
10164}
10165
10166jQuery.fn.extend( {
10167	addClass: function( value ) {
10168		var classes, elem, cur, curValue, clazz, j, finalValue,
10169			i = 0;
10170
10171		if ( isFunction( value ) ) {
10172			return this.each( function( j ) {
10173				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
10174			} );
10175		}
10176
10177		classes = classesToArray( value );
10178
10179		if ( classes.length ) {
10180			while ( ( elem = this[ i++ ] ) ) {
10181				curValue = getClass( elem );
10182				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
10183
10184				if ( cur ) {
10185					j = 0;
10186					while ( ( clazz = classes[ j++ ] ) ) {
10187						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
10188							cur += clazz + " ";
10189						}
10190					}
10191
10192					// Only assign if different to avoid unneeded rendering.
10193					finalValue = stripAndCollapse( cur );
10194					if ( curValue !== finalValue ) {
10195						elem.setAttribute( "class", finalValue );
10196					}
10197				}
10198			}
10199		}
10200
10201		return this;
10202	},
10203
10204	removeClass: function( value ) {
10205		var classes, elem, cur, curValue, clazz, j, finalValue,
10206			i = 0;
10207
10208		if ( isFunction( value ) ) {
10209			return this.each( function( j ) {
10210				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
10211			} );
10212		}
10213
10214		if ( !arguments.length ) {
10215			return this.attr( "class", "" );
10216		}
10217
10218		classes = classesToArray( value );
10219
10220		if ( classes.length ) {
10221			while ( ( elem = this[ i++ ] ) ) {
10222				curValue = getClass( elem );
10223
10224				// This expression is here for better compressibility (see addClass)
10225				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
10226
10227				if ( cur ) {
10228					j = 0;
10229					while ( ( clazz = classes[ j++ ] ) ) {
10230
10231						// Remove *all* instances
10232						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
10233							cur = cur.replace( " " + clazz + " ", " " );
10234						}
10235					}
10236
10237					// Only assign if different to avoid unneeded rendering.
10238					finalValue = stripAndCollapse( cur );
10239					if ( curValue !== finalValue ) {
10240						elem.setAttribute( "class", finalValue );
10241					}
10242				}
10243			}
10244		}
10245
10246		return this;
10247	},
10248
10249	toggleClass: function( value, stateVal ) {
10250		var type = typeof value,
10251			isValidValue = type === "string" || Array.isArray( value );
10252
10253		if ( typeof stateVal === "boolean" && isValidValue ) {
10254			return stateVal ? this.addClass( value ) : this.removeClass( value );
10255		}
10256
10257		if ( isFunction( value ) ) {
10258			return this.each( function( i ) {
10259				jQuery( this ).toggleClass(
10260					value.call( this, i, getClass( this ), stateVal ),
10261					stateVal
10262				);
10263			} );
10264		}
10265
10266		return this.each( function() {
10267			var className, i, self, classNames;
10268
10269			if ( isValidValue ) {
10270
10271				// Toggle individual class names
10272				i = 0;
10273				self = jQuery( this );
10274				classNames = classesToArray( value );
10275
10276				while ( ( className = classNames[ i++ ] ) ) {
10277
10278					// Check each className given, space separated list
10279					if ( self.hasClass( className ) ) {
10280						self.removeClass( className );
10281					} else {
10282						self.addClass( className );
10283					}
10284				}
10285
10286			// Toggle whole class name
10287			} else if ( value === undefined || type === "boolean" ) {
10288				className = getClass( this );
10289				if ( className ) {
10290
10291					// Store className if set
10292					dataPriv.set( this, "__className__", className );
10293				}
10294
10295				// If the element has a class name or if we're passed `false`,
10296				// then remove the whole classname (if there was one, the above saved it).
10297				// Otherwise bring back whatever was previously saved (if anything),
10298				// falling back to the empty string if nothing was stored.
10299				if ( this.setAttribute ) {
10300					this.setAttribute( "class",
10301						className || value === false ?
10302							"" :
10303							dataPriv.get( this, "__className__" ) || ""
10304					);
10305				}
10306			}
10307		} );
10308	},
10309
10310	hasClass: function( selector ) {
10311		var className, elem,
10312			i = 0;
10313
10314		className = " " + selector + " ";
10315		while ( ( elem = this[ i++ ] ) ) {
10316			if ( elem.nodeType === 1 &&
10317				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
10318				return true;
10319			}
10320		}
10321
10322		return false;
10323	}
10324} );
10325
10326
10327
10328
10329var rreturn = /\r/g;
10330
10331jQuery.fn.extend( {
10332	val: function( value ) {
10333		var hooks, ret, valueIsFunction,
10334			elem = this[ 0 ];
10335
10336		if ( !arguments.length ) {
10337			if ( elem ) {
10338				hooks = jQuery.valHooks[ elem.type ] ||
10339					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
10340
10341				if ( hooks &&
10342					"get" in hooks &&
10343					( ret = hooks.get( elem, "value" ) ) !== undefined
10344				) {
10345					return ret;
10346				}
10347
10348				ret = elem.value;
10349
10350				// Handle most common string cases
10351				if ( typeof ret === "string" ) {
10352					return ret.replace( rreturn, "" );
10353				}
10354
10355				// Handle cases where value is null/undef or number
10356				return ret == null ? "" : ret;
10357			}
10358
10359			return;
10360		}
10361
10362		valueIsFunction = isFunction( value );
10363
10364		return this.each( function( i ) {
10365			var val;
10366
10367			if ( this.nodeType !== 1 ) {
10368				return;
10369			}
10370
10371			if ( valueIsFunction ) {
10372				val = value.call( this, i, jQuery( this ).val() );
10373			} else {
10374				val = value;
10375			}
10376
10377			// Treat null/undefined as ""; convert numbers to string
10378			if ( val == null ) {
10379				val = "";
10380
10381			} else if ( typeof val === "number" ) {
10382				val += "";
10383
10384			} else if ( Array.isArray( val ) ) {
10385				val = jQuery.map( val, function( value ) {
10386					return value == null ? "" : value + "";
10387				} );
10388			}
10389
10390			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
10391
10392			// If set returns undefined, fall back to normal setting
10393			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
10394				this.value = val;
10395			}
10396		} );
10397	}
10398} );
10399
10400jQuery.extend( {
10401	valHooks: {
10402		option: {
10403			get: function( elem ) {
10404
10405				var val = jQuery.find.attr( elem, "value" );
10406				return val != null ?
10407					val :
10408
10409					// Support: IE <=10 - 11 only
10410					// option.text throws exceptions (#14686, #14858)
10411					// Strip and collapse whitespace
10412					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
10413					stripAndCollapse( jQuery.text( elem ) );
10414			}
10415		},
10416		select: {
10417			get: function( elem ) {
10418				var value, option, i,
10419					options = elem.options,
10420					index = elem.selectedIndex,
10421					one = elem.type === "select-one",
10422					values = one ? null : [],
10423					max = one ? index + 1 : options.length;
10424
10425				if ( index < 0 ) {
10426					i = max;
10427
10428				} else {
10429					i = one ? index : 0;
10430				}
10431
10432				// Loop through all the selected options
10433				for ( ; i < max; i++ ) {
10434					option = options[ i ];
10435
10436					// Support: IE <=9 only
10437					// IE8-9 doesn't update selected after form reset (#2551)
10438					if ( ( option.selected || i === index ) &&
10439
10440							// Don't return options that are disabled or in a disabled optgroup
10441							!option.disabled &&
10442							( !option.parentNode.disabled ||
10443								!nodeName( option.parentNode, "optgroup" ) ) ) {
10444
10445						// Get the specific value for the option
10446						value = jQuery( option ).val();
10447
10448						// We don't need an array for one selects
10449						if ( one ) {
10450							return value;
10451						}
10452
10453						// Multi-Selects return an array
10454						values.push( value );
10455					}
10456				}
10457
10458				return values;
10459			},
10460
10461			set: function( elem, value ) {
10462				var optionSet, option,
10463					options = elem.options,
10464					values = jQuery.makeArray( value ),
10465					i = options.length;
10466
10467				while ( i-- ) {
10468					option = options[ i ];
10469
10470					/* eslint-disable no-cond-assign */
10471
10472					if ( option.selected =
10473						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
10474					) {
10475						optionSet = true;
10476					}
10477
10478					/* eslint-enable no-cond-assign */
10479				}
10480
10481				// Force browsers to behave consistently when non-matching value is set
10482				if ( !optionSet ) {
10483					elem.selectedIndex = -1;
10484				}
10485				return values;
10486			}
10487		}
10488	}
10489} );
10490
10491// Radios and checkboxes getter/setter
10492jQuery.each( [ "radio", "checkbox" ], function() {
10493	jQuery.valHooks[ this ] = {
10494		set: function( elem, value ) {
10495			if ( Array.isArray( value ) ) {
10496				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
10497			}
10498		}
10499	};
10500	if ( !support.checkOn ) {
10501		jQuery.valHooks[ this ].get = function( elem ) {
10502			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
10503		};
10504	}
10505} );
10506
10507
10508
10509
10510// Return jQuery for attributes-only inclusion
10511
10512
10513support.focusin = "onfocusin" in window;
10514
10515
10516var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
10517	stopPropagationCallback = function( e ) {
10518		e.stopPropagation();
10519	};
10520
10521jQuery.extend( jQuery.event, {
10522
10523	trigger: function( event, data, elem, onlyHandlers ) {
10524
10525		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
10526			eventPath = [ elem || document ],
10527			type = hasOwn.call( event, "type" ) ? event.type : event,
10528			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
10529
10530		cur = lastElement = tmp = elem = elem || document;
10531
10532		// Don't do events on text and comment nodes
10533		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
10534			return;
10535		}
10536
10537		// focus/blur morphs to focusin/out; ensure we're not firing them right now
10538		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
10539			return;
10540		}
10541
10542		if ( type.indexOf( "." ) > -1 ) {
10543
10544			// Namespaced trigger; create a regexp to match event type in handle()
10545			namespaces = type.split( "." );
10546			type = namespaces.shift();
10547			namespaces.sort();
10548		}
10549		ontype = type.indexOf( ":" ) < 0 && "on" + type;
10550
10551		// Caller can pass in a jQuery.Event object, Object, or just an event type string
10552		event = event[ jQuery.expando ] ?
10553			event :
10554			new jQuery.Event( type, typeof event === "object" && event );
10555
10556		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
10557		event.isTrigger = onlyHandlers ? 2 : 3;
10558		event.namespace = namespaces.join( "." );
10559		event.rnamespace = event.namespace ?
10560			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
10561			null;
10562
10563		// Clean up the event in case it is being reused
10564		event.result = undefined;
10565		if ( !event.target ) {
10566			event.target = elem;
10567		}
10568
10569		// Clone any incoming data and prepend the event, creating the handler arg list
10570		data = data == null ?
10571			[ event ] :
10572			jQuery.makeArray( data, [ event ] );
10573
10574		// Allow special events to draw outside the lines
10575		special = jQuery.event.special[ type ] || {};
10576		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
10577			return;
10578		}
10579
10580		// Determine event propagation path in advance, per W3C events spec (#9951)
10581		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
10582		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
10583
10584			bubbleType = special.delegateType || type;
10585			if ( !rfocusMorph.test( bubbleType + type ) ) {
10586				cur = cur.parentNode;
10587			}
10588			for ( ; cur; cur = cur.parentNode ) {
10589				eventPath.push( cur );
10590				tmp = cur;
10591			}
10592
10593			// Only add window if we got to document (e.g., not plain obj or detached DOM)
10594			if ( tmp === ( elem.ownerDocument || document ) ) {
10595				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
10596			}
10597		}
10598
10599		// Fire handlers on the event path
10600		i = 0;
10601		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
10602			lastElement = cur;
10603			event.type = i > 1 ?
10604				bubbleType :
10605				special.bindType || type;
10606
10607			// jQuery handler
10608			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
10609				dataPriv.get( cur, "handle" );
10610			if ( handle ) {
10611				handle.apply( cur, data );
10612			}
10613
10614			// Native handler
10615			handle = ontype && cur[ ontype ];
10616			if ( handle && handle.apply && acceptData( cur ) ) {
10617				event.result = handle.apply( cur, data );
10618				if ( event.result === false ) {
10619					event.preventDefault();
10620				}
10621			}
10622		}
10623		event.type = type;
10624
10625		// If nobody prevented the default action, do it now
10626		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
10627
10628			if ( ( !special._default ||
10629				special._default.apply( eventPath.pop(), data ) === false ) &&
10630				acceptData( elem ) ) {
10631
10632				// Call a native DOM method on the target with the same name as the event.
10633				// Don't do default actions on window, that's where global variables be (#6170)
10634				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
10635
10636					// Don't re-trigger an onFOO event when we call its FOO() method
10637					tmp = elem[ ontype ];
10638
10639					if ( tmp ) {
10640						elem[ ontype ] = null;
10641					}
10642
10643					// Prevent re-triggering of the same event, since we already bubbled it above
10644					jQuery.event.triggered = type;
10645
10646					if ( event.isPropagationStopped() ) {
10647						lastElement.addEventListener( type, stopPropagationCallback );
10648					}
10649
10650					elem[ type ]();
10651
10652					if ( event.isPropagationStopped() ) {
10653						lastElement.removeEventListener( type, stopPropagationCallback );
10654					}
10655
10656					jQuery.event.triggered = undefined;
10657
10658					if ( tmp ) {
10659						elem[ ontype ] = tmp;
10660					}
10661				}
10662			}
10663		}
10664
10665		return event.result;
10666	},
10667
10668	// Piggyback on a donor event to simulate a different one
10669	// Used only for `focus(in | out)` events
10670	simulate: function( type, elem, event ) {
10671		var e = jQuery.extend(
10672			new jQuery.Event(),
10673			event,
10674			{
10675				type: type,
10676				isSimulated: true
10677			}
10678		);
10679
10680		jQuery.event.trigger( e, null, elem );
10681	}
10682
10683} );
10684
10685jQuery.fn.extend( {
10686
10687	trigger: function( type, data ) {
10688		return this.each( function() {
10689			jQuery.event.trigger( type, data, this );
10690		} );
10691	},
10692	triggerHandler: function( type, data ) {
10693		var elem = this[ 0 ];
10694		if ( elem ) {
10695			return jQuery.event.trigger( type, data, elem, true );
10696		}
10697	}
10698} );
10699
10700
10701// Support: Firefox <=44
10702// Firefox doesn't have focus(in | out) events
10703// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
10704//
10705// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
10706// focus(in | out) events fire after focus & blur events,
10707// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
10708// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
10709if ( !support.focusin ) {
10710	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
10711
10712		// Attach a single capturing handler on the document while someone wants focusin/focusout
10713		var handler = function( event ) {
10714			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
10715		};
10716
10717		jQuery.event.special[ fix ] = {
10718			setup: function() {
10719
10720				// Handle: regular nodes (via `this.ownerDocument`), window
10721				// (via `this.document`) & document (via `this`).
10722				var doc = this.ownerDocument || this.document || this,
10723					attaches = dataPriv.access( doc, fix );
10724
10725				if ( !attaches ) {
10726					doc.addEventListener( orig, handler, true );
10727				}
10728				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
10729			},
10730			teardown: function() {
10731				var doc = this.ownerDocument || this.document || this,
10732					attaches = dataPriv.access( doc, fix ) - 1;
10733
10734				if ( !attaches ) {
10735					doc.removeEventListener( orig, handler, true );
10736					dataPriv.remove( doc, fix );
10737
10738				} else {
10739					dataPriv.access( doc, fix, attaches );
10740				}
10741			}
10742		};
10743	} );
10744}
10745var location = window.location;
10746
10747var nonce = { guid: Date.now() };
10748
10749var rquery = ( /\?/ );
10750
10751
10752
10753// Cross-browser xml parsing
10754jQuery.parseXML = function( data ) {
10755	var xml, parserErrorElem;
10756	if ( !data || typeof data !== "string" ) {
10757		return null;
10758	}
10759
10760	// Support: IE 9 - 11 only
10761	// IE throws on parseFromString with invalid input.
10762	try {
10763		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
10764	} catch ( e ) {}
10765
10766	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
10767	if ( !xml || parserErrorElem ) {
10768		jQuery.error( "Invalid XML: " + (
10769			parserErrorElem ?
10770				jQuery.map( parserErrorElem.childNodes, function( el ) {
10771					return el.textContent;
10772				} ).join( "\n" ) :
10773				data
10774		) );
10775	}
10776	return xml;
10777};
10778
10779
10780var
10781	rbracket = /\[\]$/,
10782	rCRLF = /\r?\n/g,
10783	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10784	rsubmittable = /^(?:input|select|textarea|keygen)/i;
10785
10786function buildParams( prefix, obj, traditional, add ) {
10787	var name;
10788
10789	if ( Array.isArray( obj ) ) {
10790
10791		// Serialize array item.
10792		jQuery.each( obj, function( i, v ) {
10793			if ( traditional || rbracket.test( prefix ) ) {
10794
10795				// Treat each array item as a scalar.
10796				add( prefix, v );
10797
10798			} else {
10799
10800				// Item is non-scalar (array or object), encode its numeric index.
10801				buildParams(
10802					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10803					v,
10804					traditional,
10805					add
10806				);
10807			}
10808		} );
10809
10810	} else if ( !traditional && toType( obj ) === "object" ) {
10811
10812		// Serialize object item.
10813		for ( name in obj ) {
10814			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10815		}
10816
10817	} else {
10818
10819		// Serialize scalar item.
10820		add( prefix, obj );
10821	}
10822}
10823
10824// Serialize an array of form elements or a set of
10825// key/values into a query string
10826jQuery.param = function( a, traditional ) {
10827	var prefix,
10828		s = [],
10829		add = function( key, valueOrFunction ) {
10830
10831			// If value is a function, invoke it and use its return value
10832			var value = isFunction( valueOrFunction ) ?
10833				valueOrFunction() :
10834				valueOrFunction;
10835
10836			s[ s.length ] = encodeURIComponent( key ) + "=" +
10837				encodeURIComponent( value == null ? "" : value );
10838		};
10839
10840	if ( a == null ) {
10841		return "";
10842	}
10843
10844	// If an array was passed in, assume that it is an array of form elements.
10845	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10846
10847		// Serialize the form elements
10848		jQuery.each( a, function() {
10849			add( this.name, this.value );
10850		} );
10851
10852	} else {
10853
10854		// If traditional, encode the "old" way (the way 1.3.2 or older
10855		// did it), otherwise encode params recursively.
10856		for ( prefix in a ) {
10857			buildParams( prefix, a[ prefix ], traditional, add );
10858		}
10859	}
10860
10861	// Return the resulting serialization
10862	return s.join( "&" );
10863};
10864
10865jQuery.fn.extend( {
10866	serialize: function() {
10867		return jQuery.param( this.serializeArray() );
10868	},
10869	serializeArray: function() {
10870		return this.map( function() {
10871
10872			// Can add propHook for "elements" to filter or add form elements
10873			var elements = jQuery.prop( this, "elements" );
10874			return elements ? jQuery.makeArray( elements ) : this;
10875		} ).filter( function() {
10876			var type = this.type;
10877
10878			// Use .is( ":disabled" ) so that fieldset[disabled] works
10879			return this.name && !jQuery( this ).is( ":disabled" ) &&
10880				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10881				( this.checked || !rcheckableType.test( type ) );
10882		} ).map( function( _i, elem ) {
10883			var val = jQuery( this ).val();
10884
10885			if ( val == null ) {
10886				return null;
10887			}
10888
10889			if ( Array.isArray( val ) ) {
10890				return jQuery.map( val, function( val ) {
10891					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10892				} );
10893			}
10894
10895			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10896		} ).get();
10897	}
10898} );
10899
10900
10901var
10902	r20 = /%20/g,
10903	rhash = /#.*$/,
10904	rantiCache = /([?&])_=[^&]*/,
10905	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
10906
10907	// #7653, #8125, #8152: local protocol detection
10908	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
10909	rnoContent = /^(?:GET|HEAD)$/,
10910	rprotocol = /^\/\//,
10911
10912	/* Prefilters
10913	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
10914	 * 2) These are called:
10915	 *    - BEFORE asking for a transport
10916	 *    - AFTER param serialization (s.data is a string if s.processData is true)
10917	 * 3) key is the dataType
10918	 * 4) the catchall symbol "*" can be used
10919	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
10920	 */
10921	prefilters = {},
10922
10923	/* Transports bindings
10924	 * 1) key is the dataType
10925	 * 2) the catchall symbol "*" can be used
10926	 * 3) selection will start with transport dataType and THEN go to "*" if needed
10927	 */
10928	transports = {},
10929
10930	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
10931	allTypes = "*/".concat( "*" ),
10932
10933	// Anchor tag for parsing the document origin
10934	originAnchor = document.createElement( "a" );
10935
10936originAnchor.href = location.href;
10937
10938// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
10939function addToPrefiltersOrTransports( structure ) {
10940
10941	// dataTypeExpression is optional and defaults to "*"
10942	return function( dataTypeExpression, func ) {
10943
10944		if ( typeof dataTypeExpression !== "string" ) {
10945			func = dataTypeExpression;
10946			dataTypeExpression = "*";
10947		}
10948
10949		var dataType,
10950			i = 0,
10951			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
10952
10953		if ( isFunction( func ) ) {
10954
10955			// For each dataType in the dataTypeExpression
10956			while ( ( dataType = dataTypes[ i++ ] ) ) {
10957
10958				// Prepend if requested
10959				if ( dataType[ 0 ] === "+" ) {
10960					dataType = dataType.slice( 1 ) || "*";
10961					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
10962
10963				// Otherwise append
10964				} else {
10965					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
10966				}
10967			}
10968		}
10969	};
10970}
10971
10972// Base inspection function for prefilters and transports
10973function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
10974
10975	var inspected = {},
10976		seekingTransport = ( structure === transports );
10977
10978	function inspect( dataType ) {
10979		var selected;
10980		inspected[ dataType ] = true;
10981		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
10982			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
10983			if ( typeof dataTypeOrTransport === "string" &&
10984				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
10985
10986				options.dataTypes.unshift( dataTypeOrTransport );
10987				inspect( dataTypeOrTransport );
10988				return false;
10989			} else if ( seekingTransport ) {
10990				return !( selected = dataTypeOrTransport );
10991			}
10992		} );
10993		return selected;
10994	}
10995
10996	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
10997}
10998
10999// A special extend for ajax options
11000// that takes "flat" options (not to be deep extended)
11001// Fixes #9887
11002function ajaxExtend( target, src ) {
11003	var key, deep,
11004		flatOptions = jQuery.ajaxSettings.flatOptions || {};
11005
11006	for ( key in src ) {
11007		if ( src[ key ] !== undefined ) {
11008			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
11009		}
11010	}
11011	if ( deep ) {
11012		jQuery.extend( true, target, deep );
11013	}
11014
11015	return target;
11016}
11017
11018/* Handles responses to an ajax request:
11019 * - finds the right dataType (mediates between content-type and expected dataType)
11020 * - returns the corresponding response
11021 */
11022function ajaxHandleResponses( s, jqXHR, responses ) {
11023
11024	var ct, type, finalDataType, firstDataType,
11025		contents = s.contents,
11026		dataTypes = s.dataTypes;
11027
11028	// Remove auto dataType and get content-type in the process
11029	while ( dataTypes[ 0 ] === "*" ) {
11030		dataTypes.shift();
11031		if ( ct === undefined ) {
11032			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
11033		}
11034	}
11035
11036	// Check if we're dealing with a known content-type
11037	if ( ct ) {
11038		for ( type in contents ) {
11039			if ( contents[ type ] && contents[ type ].test( ct ) ) {
11040				dataTypes.unshift( type );
11041				break;
11042			}
11043		}
11044	}
11045
11046	// Check to see if we have a response for the expected dataType
11047	if ( dataTypes[ 0 ] in responses ) {
11048		finalDataType = dataTypes[ 0 ];
11049	} else {
11050
11051		// Try convertible dataTypes
11052		for ( type in responses ) {
11053			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
11054				finalDataType = type;
11055				break;
11056			}
11057			if ( !firstDataType ) {
11058				firstDataType = type;
11059			}
11060		}
11061
11062		// Or just use first one
11063		finalDataType = finalDataType || firstDataType;
11064	}
11065
11066	// If we found a dataType
11067	// We add the dataType to the list if needed
11068	// and return the corresponding response
11069	if ( finalDataType ) {
11070		if ( finalDataType !== dataTypes[ 0 ] ) {
11071			dataTypes.unshift( finalDataType );
11072		}
11073		return responses[ finalDataType ];
11074	}
11075}
11076
11077/* Chain conversions given the request and the original response
11078 * Also sets the responseXXX fields on the jqXHR instance
11079 */
11080function ajaxConvert( s, response, jqXHR, isSuccess ) {
11081	var conv2, current, conv, tmp, prev,
11082		converters = {},
11083
11084		// Work with a copy of dataTypes in case we need to modify it for conversion
11085		dataTypes = s.dataTypes.slice();
11086
11087	// Create converters map with lowercased keys
11088	if ( dataTypes[ 1 ] ) {
11089		for ( conv in s.converters ) {
11090			converters[ conv.toLowerCase() ] = s.converters[ conv ];
11091		}
11092	}
11093
11094	current = dataTypes.shift();
11095
11096	// Convert to each sequential dataType
11097	while ( current ) {
11098
11099		if ( s.responseFields[ current ] ) {
11100			jqXHR[ s.responseFields[ current ] ] = response;
11101		}
11102
11103		// Apply the dataFilter if provided
11104		if ( !prev && isSuccess && s.dataFilter ) {
11105			response = s.dataFilter( response, s.dataType );
11106		}
11107
11108		prev = current;
11109		current = dataTypes.shift();
11110
11111		if ( current ) {
11112
11113			// There's only work to do if current dataType is non-auto
11114			if ( current === "*" ) {
11115
11116				current = prev;
11117
11118			// Convert response if prev dataType is non-auto and differs from current
11119			} else if ( prev !== "*" && prev !== current ) {
11120
11121				// Seek a direct converter
11122				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
11123
11124				// If none found, seek a pair
11125				if ( !conv ) {
11126					for ( conv2 in converters ) {
11127
11128						// If conv2 outputs current
11129						tmp = conv2.split( " " );
11130						if ( tmp[ 1 ] === current ) {
11131
11132							// If prev can be converted to accepted input
11133							conv = converters[ prev + " " + tmp[ 0 ] ] ||
11134								converters[ "* " + tmp[ 0 ] ];
11135							if ( conv ) {
11136
11137								// Condense equivalence converters
11138								if ( conv === true ) {
11139									conv = converters[ conv2 ];
11140
11141								// Otherwise, insert the intermediate dataType
11142								} else if ( converters[ conv2 ] !== true ) {
11143									current = tmp[ 0 ];
11144									dataTypes.unshift( tmp[ 1 ] );
11145								}
11146								break;
11147							}
11148						}
11149					}
11150				}
11151
11152				// Apply converter (if not an equivalence)
11153				if ( conv !== true ) {
11154
11155					// Unless errors are allowed to bubble, catch and return them
11156					if ( conv && s.throws ) {
11157						response = conv( response );
11158					} else {
11159						try {
11160							response = conv( response );
11161						} catch ( e ) {
11162							return {
11163								state: "parsererror",
11164								error: conv ? e : "No conversion from " + prev + " to " + current
11165							};
11166						}
11167					}
11168				}
11169			}
11170		}
11171	}
11172
11173	return { state: "success", data: response };
11174}
11175
11176jQuery.extend( {
11177
11178	// Counter for holding the number of active queries
11179	active: 0,
11180
11181	// Last-Modified header cache for next request
11182	lastModified: {},
11183	etag: {},
11184
11185	ajaxSettings: {
11186		url: location.href,
11187		type: "GET",
11188		isLocal: rlocalProtocol.test( location.protocol ),
11189		global: true,
11190		processData: true,
11191		async: true,
11192		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
11193
11194		/*
11195		timeout: 0,
11196		data: null,
11197		dataType: null,
11198		username: null,
11199		password: null,
11200		cache: null,
11201		throws: false,
11202		traditional: false,
11203		headers: {},
11204		*/
11205
11206		accepts: {
11207			"*": allTypes,
11208			text: "text/plain",
11209			html: "text/html",
11210			xml: "application/xml, text/xml",
11211			json: "application/json, text/javascript"
11212		},
11213
11214		contents: {
11215			xml: /\bxml\b/,
11216			html: /\bhtml/,
11217			json: /\bjson\b/
11218		},
11219
11220		responseFields: {
11221			xml: "responseXML",
11222			text: "responseText",
11223			json: "responseJSON"
11224		},
11225
11226		// Data converters
11227		// Keys separate source (or catchall "*") and destination types with a single space
11228		converters: {
11229
11230			// Convert anything to text
11231			"* text": String,
11232
11233			// Text to html (true = no transformation)
11234			"text html": true,
11235
11236			// Evaluate text as a json expression
11237			"text json": JSON.parse,
11238
11239			// Parse text as xml
11240			"text xml": jQuery.parseXML
11241		},
11242
11243		// For options that shouldn't be deep extended:
11244		// you can add your own custom options here if
11245		// and when you create one that shouldn't be
11246		// deep extended (see ajaxExtend)
11247		flatOptions: {
11248			url: true,
11249			context: true
11250		}
11251	},
11252
11253	// Creates a full fledged settings object into target
11254	// with both ajaxSettings and settings fields.
11255	// If target is omitted, writes into ajaxSettings.
11256	ajaxSetup: function( target, settings ) {
11257		return settings ?
11258
11259			// Building a settings object
11260			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
11261
11262			// Extending ajaxSettings
11263			ajaxExtend( jQuery.ajaxSettings, target );
11264	},
11265
11266	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
11267	ajaxTransport: addToPrefiltersOrTransports( transports ),
11268
11269	// Main method
11270	ajax: function( url, options ) {
11271
11272		// If url is an object, simulate pre-1.5 signature
11273		if ( typeof url === "object" ) {
11274			options = url;
11275			url = undefined;
11276		}
11277
11278		// Force options to be an object
11279		options = options || {};
11280
11281		var transport,
11282
11283			// URL without anti-cache param
11284			cacheURL,
11285
11286			// Response headers
11287			responseHeadersString,
11288			responseHeaders,
11289
11290			// timeout handle
11291			timeoutTimer,
11292
11293			// Url cleanup var
11294			urlAnchor,
11295
11296			// Request state (becomes false upon send and true upon completion)
11297			completed,
11298
11299			// To know if global events are to be dispatched
11300			fireGlobals,
11301
11302			// Loop variable
11303			i,
11304
11305			// uncached part of the url
11306			uncached,
11307
11308			// Create the final options object
11309			s = jQuery.ajaxSetup( {}, options ),
11310
11311			// Callbacks context
11312			callbackContext = s.context || s,
11313
11314			// Context for global events is callbackContext if it is a DOM node or jQuery collection
11315			globalEventContext = s.context &&
11316				( callbackContext.nodeType || callbackContext.jquery ) ?
11317				jQuery( callbackContext ) :
11318				jQuery.event,
11319
11320			// Deferreds
11321			deferred = jQuery.Deferred(),
11322			completeDeferred = jQuery.Callbacks( "once memory" ),
11323
11324			// Status-dependent callbacks
11325			statusCode = s.statusCode || {},
11326
11327			// Headers (they are sent all at once)
11328			requestHeaders = {},
11329			requestHeadersNames = {},
11330
11331			// Default abort message
11332			strAbort = "canceled",
11333
11334			// Fake xhr
11335			jqXHR = {
11336				readyState: 0,
11337
11338				// Builds headers hashtable if needed
11339				getResponseHeader: function( key ) {
11340					var match;
11341					if ( completed ) {
11342						if ( !responseHeaders ) {
11343							responseHeaders = {};
11344							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
11345								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
11346									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
11347										.concat( match[ 2 ] );
11348							}
11349						}
11350						match = responseHeaders[ key.toLowerCase() + " " ];
11351					}
11352					return match == null ? null : match.join( ", " );
11353				},
11354
11355				// Raw string
11356				getAllResponseHeaders: function() {
11357					return completed ? responseHeadersString : null;
11358				},
11359
11360				// Caches the header
11361				setRequestHeader: function( name, value ) {
11362					if ( completed == null ) {
11363						name = requestHeadersNames[ name.toLowerCase() ] =
11364							requestHeadersNames[ name.toLowerCase() ] || name;
11365						requestHeaders[ name ] = value;
11366					}
11367					return this;
11368				},
11369
11370				// Overrides response content-type header
11371				overrideMimeType: function( type ) {
11372					if ( completed == null ) {
11373						s.mimeType = type;
11374					}
11375					return this;
11376				},
11377
11378				// Status-dependent callbacks
11379				statusCode: function( map ) {
11380					var code;
11381					if ( map ) {
11382						if ( completed ) {
11383
11384							// Execute the appropriate callbacks
11385							jqXHR.always( map[ jqXHR.status ] );
11386						} else {
11387
11388							// Lazy-add the new callbacks in a way that preserves old ones
11389							for ( code in map ) {
11390								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
11391							}
11392						}
11393					}
11394					return this;
11395				},
11396
11397				// Cancel the request
11398				abort: function( statusText ) {
11399					var finalText = statusText || strAbort;
11400					if ( transport ) {
11401						transport.abort( finalText );
11402					}
11403					done( 0, finalText );
11404					return this;
11405				}
11406			};
11407
11408		// Attach deferreds
11409		deferred.promise( jqXHR );
11410
11411		// Add protocol if not provided (prefilters might expect it)
11412		// Handle falsy url in the settings object (#10093: consistency with old signature)
11413		// We also use the url parameter if available
11414		s.url = ( ( url || s.url || location.href ) + "" )
11415			.replace( rprotocol, location.protocol + "//" );
11416
11417		// Alias method option to type as per ticket #12004
11418		s.type = options.method || options.type || s.method || s.type;
11419
11420		// Extract dataTypes list
11421		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
11422
11423		// A cross-domain request is in order when the origin doesn't match the current origin.
11424		if ( s.crossDomain == null ) {
11425			urlAnchor = document.createElement( "a" );
11426
11427			// Support: IE <=8 - 11, Edge 12 - 15
11428			// IE throws exception on accessing the href property if url is malformed,
11429			// e.g. http://example.com:80x/
11430			try {
11431				urlAnchor.href = s.url;
11432
11433				// Support: IE <=8 - 11 only
11434				// Anchor's host property isn't correctly set when s.url is relative
11435				urlAnchor.href = urlAnchor.href;
11436				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
11437					urlAnchor.protocol + "//" + urlAnchor.host;
11438			} catch ( e ) {
11439
11440				// If there is an error parsing the URL, assume it is crossDomain,
11441				// it can be rejected by the transport if it is invalid
11442				s.crossDomain = true;
11443			}
11444		}
11445
11446		// Convert data if not already a string
11447		if ( s.data && s.processData && typeof s.data !== "string" ) {
11448			s.data = jQuery.param( s.data, s.traditional );
11449		}
11450
11451		// Apply prefilters
11452		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
11453
11454		// If request was aborted inside a prefilter, stop there
11455		if ( completed ) {
11456			return jqXHR;
11457		}
11458
11459		// We can fire global events as of now if asked to
11460		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
11461		fireGlobals = jQuery.event && s.global;
11462
11463		// Watch for a new set of requests
11464		if ( fireGlobals && jQuery.active++ === 0 ) {
11465			jQuery.event.trigger( "ajaxStart" );
11466		}
11467
11468		// Uppercase the type
11469		s.type = s.type.toUpperCase();
11470
11471		// Determine if request has content
11472		s.hasContent = !rnoContent.test( s.type );
11473
11474		// Save the URL in case we're toying with the If-Modified-Since
11475		// and/or If-None-Match header later on
11476		// Remove hash to simplify url manipulation
11477		cacheURL = s.url.replace( rhash, "" );
11478
11479		// More options handling for requests with no content
11480		if ( !s.hasContent ) {
11481
11482			// Remember the hash so we can put it back
11483			uncached = s.url.slice( cacheURL.length );
11484
11485			// If data is available and should be processed, append data to url
11486			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
11487				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
11488
11489				// #9682: remove data so that it's not used in an eventual retry
11490				delete s.data;
11491			}
11492
11493			// Add or update anti-cache param if needed
11494			if ( s.cache === false ) {
11495				cacheURL = cacheURL.replace( rantiCache, "$1" );
11496				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
11497					uncached;
11498			}
11499
11500			// Put hash and anti-cache on the URL that will be requested (gh-1732)
11501			s.url = cacheURL + uncached;
11502
11503		// Change '%20' to '+' if this is encoded form body content (gh-2658)
11504		} else if ( s.data && s.processData &&
11505			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
11506			s.data = s.data.replace( r20, "+" );
11507		}
11508
11509		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
11510		if ( s.ifModified ) {
11511			if ( jQuery.lastModified[ cacheURL ] ) {
11512				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
11513			}
11514			if ( jQuery.etag[ cacheURL ] ) {
11515				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
11516			}
11517		}
11518
11519		// Set the correct header, if data is being sent
11520		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
11521			jqXHR.setRequestHeader( "Content-Type", s.contentType );
11522		}
11523
11524		// Set the Accepts header for the server, depending on the dataType
11525		jqXHR.setRequestHeader(
11526			"Accept",
11527			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
11528				s.accepts[ s.dataTypes[ 0 ] ] +
11529					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
11530				s.accepts[ "*" ]
11531		);
11532
11533		// Check for headers option
11534		for ( i in s.headers ) {
11535			jqXHR.setRequestHeader( i, s.headers[ i ] );
11536		}
11537
11538		// Allow custom headers/mimetypes and early abort
11539		if ( s.beforeSend &&
11540			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
11541
11542			// Abort if not done already and return
11543			return jqXHR.abort();
11544		}
11545
11546		// Aborting is no longer a cancellation
11547		strAbort = "abort";
11548
11549		// Install callbacks on deferreds
11550		completeDeferred.add( s.complete );
11551		jqXHR.done( s.success );
11552		jqXHR.fail( s.error );
11553
11554		// Get transport
11555		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
11556
11557		// If no transport, we auto-abort
11558		if ( !transport ) {
11559			done( -1, "No Transport" );
11560		} else {
11561			jqXHR.readyState = 1;
11562
11563			// Send global event
11564			if ( fireGlobals ) {
11565				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
11566			}
11567
11568			// If request was aborted inside ajaxSend, stop there
11569			if ( completed ) {
11570				return jqXHR;
11571			}
11572
11573			// Timeout
11574			if ( s.async && s.timeout > 0 ) {
11575				timeoutTimer = window.setTimeout( function() {
11576					jqXHR.abort( "timeout" );
11577				}, s.timeout );
11578			}
11579
11580			try {
11581				completed = false;
11582				transport.send( requestHeaders, done );
11583			} catch ( e ) {
11584
11585				// Rethrow post-completion exceptions
11586				if ( completed ) {
11587					throw e;
11588				}
11589
11590				// Propagate others as results
11591				done( -1, e );
11592			}
11593		}
11594
11595		// Callback for when everything is done
11596		function done( status, nativeStatusText, responses, headers ) {
11597			var isSuccess, success, error, response, modified,
11598				statusText = nativeStatusText;
11599
11600			// Ignore repeat invocations
11601			if ( completed ) {
11602				return;
11603			}
11604
11605			completed = true;
11606
11607			// Clear timeout if it exists
11608			if ( timeoutTimer ) {
11609				window.clearTimeout( timeoutTimer );
11610			}
11611
11612			// Dereference transport for early garbage collection
11613			// (no matter how long the jqXHR object will be used)
11614			transport = undefined;
11615
11616			// Cache response headers
11617			responseHeadersString = headers || "";
11618
11619			// Set readyState
11620			jqXHR.readyState = status > 0 ? 4 : 0;
11621
11622			// Determine if successful
11623			isSuccess = status >= 200 && status < 300 || status === 304;
11624
11625			// Get response data
11626			if ( responses ) {
11627				response = ajaxHandleResponses( s, jqXHR, responses );
11628			}
11629
11630			// Use a noop converter for missing script but not if jsonp
11631			if ( !isSuccess &&
11632				jQuery.inArray( "script", s.dataTypes ) > -1 &&
11633				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
11634				s.converters[ "text script" ] = function() {};
11635			}
11636
11637			// Convert no matter what (that way responseXXX fields are always set)
11638			response = ajaxConvert( s, response, jqXHR, isSuccess );
11639
11640			// If successful, handle type chaining
11641			if ( isSuccess ) {
11642
11643				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
11644				if ( s.ifModified ) {
11645					modified = jqXHR.getResponseHeader( "Last-Modified" );
11646					if ( modified ) {
11647						jQuery.lastModified[ cacheURL ] = modified;
11648					}
11649					modified = jqXHR.getResponseHeader( "etag" );
11650					if ( modified ) {
11651						jQuery.etag[ cacheURL ] = modified;
11652					}
11653				}
11654
11655				// if no content
11656				if ( status === 204 || s.type === "HEAD" ) {
11657					statusText = "nocontent";
11658
11659				// if not modified
11660				} else if ( status === 304 ) {
11661					statusText = "notmodified";
11662
11663				// If we have data, let's convert it
11664				} else {
11665					statusText = response.state;
11666					success = response.data;
11667					error = response.error;
11668					isSuccess = !error;
11669				}
11670			} else {
11671
11672				// Extract error from statusText and normalize for non-aborts
11673				error = statusText;
11674				if ( status || !statusText ) {
11675					statusText = "error";
11676					if ( status < 0 ) {
11677						status = 0;
11678					}
11679				}
11680			}
11681
11682			// Set data for the fake xhr object
11683			jqXHR.status = status;
11684			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
11685
11686			// Success/Error
11687			if ( isSuccess ) {
11688				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
11689			} else {
11690				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
11691			}
11692
11693			// Status-dependent callbacks
11694			jqXHR.statusCode( statusCode );
11695			statusCode = undefined;
11696
11697			if ( fireGlobals ) {
11698				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
11699					[ jqXHR, s, isSuccess ? success : error ] );
11700			}
11701
11702			// Complete
11703			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
11704
11705			if ( fireGlobals ) {
11706				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
11707
11708				// Handle the global AJAX counter
11709				if ( !( --jQuery.active ) ) {
11710					jQuery.event.trigger( "ajaxStop" );
11711				}
11712			}
11713		}
11714
11715		return jqXHR;
11716	},
11717
11718	getJSON: function( url, data, callback ) {
11719		return jQuery.get( url, data, callback, "json" );
11720	},
11721
11722	getScript: function( url, callback ) {
11723		return jQuery.get( url, undefined, callback, "script" );
11724	}
11725} );
11726
11727jQuery.each( [ "get", "post" ], function( _i, method ) {
11728	jQuery[ method ] = function( url, data, callback, type ) {
11729
11730		// Shift arguments if data argument was omitted
11731		if ( isFunction( data ) ) {
11732			type = type || callback;
11733			callback = data;
11734			data = undefined;
11735		}
11736
11737		// The url can be an options object (which then must have .url)
11738		return jQuery.ajax( jQuery.extend( {
11739			url: url,
11740			type: method,
11741			dataType: type,
11742			data: data,
11743			success: callback
11744		}, jQuery.isPlainObject( url ) && url ) );
11745	};
11746} );
11747
11748jQuery.ajaxPrefilter( function( s ) {
11749	var i;
11750	for ( i in s.headers ) {
11751		if ( i.toLowerCase() === "content-type" ) {
11752			s.contentType = s.headers[ i ] || "";
11753		}
11754	}
11755} );
11756
11757
11758jQuery._evalUrl = function( url, options, doc ) {
11759	return jQuery.ajax( {
11760		url: url,
11761
11762		// Make this explicit, since user can override this through ajaxSetup (#11264)
11763		type: "GET",
11764		dataType: "script",
11765		cache: true,
11766		async: false,
11767		global: false,
11768
11769		// Only evaluate the response if it is successful (gh-4126)
11770		// dataFilter is not invoked for failure responses, so using it instead
11771		// of the default converter is kludgy but it works.
11772		converters: {
11773			"text script": function() {}
11774		},
11775		dataFilter: function( response ) {
11776			jQuery.globalEval( response, options, doc );
11777		}
11778	} );
11779};
11780
11781
11782jQuery.fn.extend( {
11783	wrapAll: function( html ) {
11784		var wrap;
11785
11786		if ( this[ 0 ] ) {
11787			if ( isFunction( html ) ) {
11788				html = html.call( this[ 0 ] );
11789			}
11790
11791			// The elements to wrap the target around
11792			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
11793
11794			if ( this[ 0 ].parentNode ) {
11795				wrap.insertBefore( this[ 0 ] );
11796			}
11797
11798			wrap.map( function() {
11799				var elem = this;
11800
11801				while ( elem.firstElementChild ) {
11802					elem = elem.firstElementChild;
11803				}
11804
11805				return elem;
11806			} ).append( this );
11807		}
11808
11809		return this;
11810	},
11811
11812	wrapInner: function( html ) {
11813		if ( isFunction( html ) ) {
11814			return this.each( function( i ) {
11815				jQuery( this ).wrapInner( html.call( this, i ) );
11816			} );
11817		}
11818
11819		return this.each( function() {
11820			var self = jQuery( this ),
11821				contents = self.contents();
11822
11823			if ( contents.length ) {
11824				contents.wrapAll( html );
11825
11826			} else {
11827				self.append( html );
11828			}
11829		} );
11830	},
11831
11832	wrap: function( html ) {
11833		var htmlIsFunction = isFunction( html );
11834
11835		return this.each( function( i ) {
11836			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
11837		} );
11838	},
11839
11840	unwrap: function( selector ) {
11841		this.parent( selector ).not( "body" ).each( function() {
11842			jQuery( this ).replaceWith( this.childNodes );
11843		} );
11844		return this;
11845	}
11846} );
11847
11848
11849jQuery.expr.pseudos.hidden = function( elem ) {
11850	return !jQuery.expr.pseudos.visible( elem );
11851};
11852jQuery.expr.pseudos.visible = function( elem ) {
11853	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
11854};
11855
11856
11857
11858
11859jQuery.ajaxSettings.xhr = function() {
11860	try {
11861		return new window.XMLHttpRequest();
11862	} catch ( e ) {}
11863};
11864
11865var xhrSuccessStatus = {
11866
11867		// File protocol always yields status code 0, assume 200
11868		0: 200,
11869
11870		// Support: IE <=9 only
11871		// #1450: sometimes IE returns 1223 when it should be 204
11872		1223: 204
11873	},
11874	xhrSupported = jQuery.ajaxSettings.xhr();
11875
11876support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
11877support.ajax = xhrSupported = !!xhrSupported;
11878
11879jQuery.ajaxTransport( function( options ) {
11880	var callback, errorCallback;
11881
11882	// Cross domain only allowed if supported through XMLHttpRequest
11883	if ( support.cors || xhrSupported && !options.crossDomain ) {
11884		return {
11885			send: function( headers, complete ) {
11886				var i,
11887					xhr = options.xhr();
11888
11889				xhr.open(
11890					options.type,
11891					options.url,
11892					options.async,
11893					options.username,
11894					options.password
11895				);
11896
11897				// Apply custom fields if provided
11898				if ( options.xhrFields ) {
11899					for ( i in options.xhrFields ) {
11900						xhr[ i ] = options.xhrFields[ i ];
11901					}
11902				}
11903
11904				// Override mime type if needed
11905				if ( options.mimeType && xhr.overrideMimeType ) {
11906					xhr.overrideMimeType( options.mimeType );
11907				}
11908
11909				// X-Requested-With header
11910				// For cross-domain requests, seeing as conditions for a preflight are
11911				// akin to a jigsaw puzzle, we simply never set it to be sure.
11912				// (it can always be set on a per-request basis or even using ajaxSetup)
11913				// For same-domain requests, won't change header if already provided.
11914				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
11915					headers[ "X-Requested-With" ] = "XMLHttpRequest";
11916				}
11917
11918				// Set headers
11919				for ( i in headers ) {
11920					xhr.setRequestHeader( i, headers[ i ] );
11921				}
11922
11923				// Callback
11924				callback = function( type ) {
11925					return function() {
11926						if ( callback ) {
11927							callback = errorCallback = xhr.onload =
11928								xhr.onerror = xhr.onabort = xhr.ontimeout =
11929									xhr.onreadystatechange = null;
11930
11931							if ( type === "abort" ) {
11932								xhr.abort();
11933							} else if ( type === "error" ) {
11934
11935								// Support: IE <=9 only
11936								// On a manual native abort, IE9 throws
11937								// errors on any property access that is not readyState
11938								if ( typeof xhr.status !== "number" ) {
11939									complete( 0, "error" );
11940								} else {
11941									complete(
11942
11943										// File: protocol always yields status 0; see #8605, #14207
11944										xhr.status,
11945										xhr.statusText
11946									);
11947								}
11948							} else {
11949								complete(
11950									xhrSuccessStatus[ xhr.status ] || xhr.status,
11951									xhr.statusText,
11952
11953									// Support: IE <=9 only
11954									// IE9 has no XHR2 but throws on binary (trac-11426)
11955									// For XHR2 non-text, let the caller handle it (gh-2498)
11956									( xhr.responseType || "text" ) !== "text"  ||
11957									typeof xhr.responseText !== "string" ?
11958										{ binary: xhr.response } :
11959										{ text: xhr.responseText },
11960									xhr.getAllResponseHeaders()
11961								);
11962							}
11963						}
11964					};
11965				};
11966
11967				// Listen to events
11968				xhr.onload = callback();
11969				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
11970
11971				// Support: IE 9 only
11972				// Use onreadystatechange to replace onabort
11973				// to handle uncaught aborts
11974				if ( xhr.onabort !== undefined ) {
11975					xhr.onabort = errorCallback;
11976				} else {
11977					xhr.onreadystatechange = function() {
11978
11979						// Check readyState before timeout as it changes
11980						if ( xhr.readyState === 4 ) {
11981
11982							// Allow onerror to be called first,
11983							// but that will not handle a native abort
11984							// Also, save errorCallback to a variable
11985							// as xhr.onerror cannot be accessed
11986							window.setTimeout( function() {
11987								if ( callback ) {
11988									errorCallback();
11989								}
11990							} );
11991						}
11992					};
11993				}
11994
11995				// Create the abort callback
11996				callback = callback( "abort" );
11997
11998				try {
11999
12000					// Do send the request (this may raise an exception)
12001					xhr.send( options.hasContent && options.data || null );
12002				} catch ( e ) {
12003
12004					// #14683: Only rethrow if this hasn't been notified as an error yet
12005					if ( callback ) {
12006						throw e;
12007					}
12008				}
12009			},
12010
12011			abort: function() {
12012				if ( callback ) {
12013					callback();
12014				}
12015			}
12016		};
12017	}
12018} );
12019
12020
12021
12022
12023// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
12024jQuery.ajaxPrefilter( function( s ) {
12025	if ( s.crossDomain ) {
12026		s.contents.script = false;
12027	}
12028} );
12029
12030// Install script dataType
12031jQuery.ajaxSetup( {
12032	accepts: {
12033		script: "text/javascript, application/javascript, " +
12034			"application/ecmascript, application/x-ecmascript"
12035	},
12036	contents: {
12037		script: /\b(?:java|ecma)script\b/
12038	},
12039	converters: {
12040		"text script": function( text ) {
12041			jQuery.globalEval( text );
12042			return text;
12043		}
12044	}
12045} );
12046
12047// Handle cache's special case and crossDomain
12048jQuery.ajaxPrefilter( "script", function( s ) {
12049	if ( s.cache === undefined ) {
12050		s.cache = false;
12051	}
12052	if ( s.crossDomain ) {
12053		s.type = "GET";
12054	}
12055} );
12056
12057// Bind script tag hack transport
12058jQuery.ajaxTransport( "script", function( s ) {
12059
12060	// This transport only deals with cross domain or forced-by-attrs requests
12061	if ( s.crossDomain || s.scriptAttrs ) {
12062		var script, callback;
12063		return {
12064			send: function( _, complete ) {
12065				script = jQuery( "<script>" )
12066					.attr( s.scriptAttrs || {} )
12067					.prop( { charset: s.scriptCharset, src: s.url } )
12068					.on( "load error", callback = function( evt ) {
12069						script.remove();
12070						callback = null;
12071						if ( evt ) {
12072							complete( evt.type === "error" ? 404 : 200, evt.type );
12073						}
12074					} );
12075
12076				// Use native DOM manipulation to avoid our domManip AJAX trickery
12077				document.head.appendChild( script[ 0 ] );
12078			},
12079			abort: function() {
12080				if ( callback ) {
12081					callback();
12082				}
12083			}
12084		};
12085	}
12086} );
12087
12088
12089
12090
12091var oldCallbacks = [],
12092	rjsonp = /(=)\?(?=&|$)|\?\?/;
12093
12094// Default jsonp settings
12095jQuery.ajaxSetup( {
12096	jsonp: "callback",
12097	jsonpCallback: function() {
12098		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
12099		this[ callback ] = true;
12100		return callback;
12101	}
12102} );
12103
12104// Detect, normalize options and install callbacks for jsonp requests
12105jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
12106
12107	var callbackName, overwritten, responseContainer,
12108		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
12109			"url" :
12110			typeof s.data === "string" &&
12111				( s.contentType || "" )
12112					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
12113				rjsonp.test( s.data ) && "data"
12114		);
12115
12116	// Handle iff the expected data type is "jsonp" or we have a parameter to set
12117	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
12118
12119		// Get callback name, remembering preexisting value associated with it
12120		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
12121			s.jsonpCallback() :
12122			s.jsonpCallback;
12123
12124		// Insert callback into url or form data
12125		if ( jsonProp ) {
12126			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
12127		} else if ( s.jsonp !== false ) {
12128			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
12129		}
12130
12131		// Use data converter to retrieve json after script execution
12132		s.converters[ "script json" ] = function() {
12133			if ( !responseContainer ) {
12134				jQuery.error( callbackName + " was not called" );
12135			}
12136			return responseContainer[ 0 ];
12137		};
12138
12139		// Force json dataType
12140		s.dataTypes[ 0 ] = "json";
12141
12142		// Install callback
12143		overwritten = window[ callbackName ];
12144		window[ callbackName ] = function() {
12145			responseContainer = arguments;
12146		};
12147
12148		// Clean-up function (fires after converters)
12149		jqXHR.always( function() {
12150
12151			// If previous value didn't exist - remove it
12152			if ( overwritten === undefined ) {
12153				jQuery( window ).removeProp( callbackName );
12154
12155			// Otherwise restore preexisting value
12156			} else {
12157				window[ callbackName ] = overwritten;
12158			}
12159
12160			// Save back as free
12161			if ( s[ callbackName ] ) {
12162
12163				// Make sure that re-using the options doesn't screw things around
12164				s.jsonpCallback = originalSettings.jsonpCallback;
12165
12166				// Save the callback name for future use
12167				oldCallbacks.push( callbackName );
12168			}
12169
12170			// Call if it was a function and we have a response
12171			if ( responseContainer && isFunction( overwritten ) ) {
12172				overwritten( responseContainer[ 0 ] );
12173			}
12174
12175			responseContainer = overwritten = undefined;
12176		} );
12177
12178		// Delegate to script
12179		return "script";
12180	}
12181} );
12182
12183
12184
12185
12186// Support: Safari 8 only
12187// In Safari 8 documents created via document.implementation.createHTMLDocument
12188// collapse sibling forms: the second one becomes a child of the first one.
12189// Because of that, this security measure has to be disabled in Safari 8.
12190// https://bugs.webkit.org/show_bug.cgi?id=137337
12191support.createHTMLDocument = ( function() {
12192	var body = document.implementation.createHTMLDocument( "" ).body;
12193	body.innerHTML = "<form></form><form></form>";
12194	return body.childNodes.length === 2;
12195} )();
12196
12197
12198// Argument "data" should be string of html
12199// context (optional): If specified, the fragment will be created in this context,
12200// defaults to document
12201// keepScripts (optional): If true, will include scripts passed in the html string
12202jQuery.parseHTML = function( data, context, keepScripts ) {
12203	if ( typeof data !== "string" ) {
12204		return [];
12205	}
12206	if ( typeof context === "boolean" ) {
12207		keepScripts = context;
12208		context = false;
12209	}
12210
12211	var base, parsed, scripts;
12212
12213	if ( !context ) {
12214
12215		// Stop scripts or inline event handlers from being executed immediately
12216		// by using document.implementation
12217		if ( support.createHTMLDocument ) {
12218			context = document.implementation.createHTMLDocument( "" );
12219
12220			// Set the base href for the created document
12221			// so any parsed elements with URLs
12222			// are based on the document's URL (gh-2965)
12223			base = context.createElement( "base" );
12224			base.href = document.location.href;
12225			context.head.appendChild( base );
12226		} else {
12227			context = document;
12228		}
12229	}
12230
12231	parsed = rsingleTag.exec( data );
12232	scripts = !keepScripts && [];
12233
12234	// Single tag
12235	if ( parsed ) {
12236		return [ context.createElement( parsed[ 1 ] ) ];
12237	}
12238
12239	parsed = buildFragment( [ data ], context, scripts );
12240
12241	if ( scripts && scripts.length ) {
12242		jQuery( scripts ).remove();
12243	}
12244
12245	return jQuery.merge( [], parsed.childNodes );
12246};
12247
12248
12249/**
12250 * Load a url into a page
12251 */
12252jQuery.fn.load = function( url, params, callback ) {
12253	var selector, type, response,
12254		self = this,
12255		off = url.indexOf( " " );
12256
12257	if ( off > -1 ) {
12258		selector = stripAndCollapse( url.slice( off ) );
12259		url = url.slice( 0, off );
12260	}
12261
12262	// If it's a function
12263	if ( isFunction( params ) ) {
12264
12265		// We assume that it's the callback
12266		callback = params;
12267		params = undefined;
12268
12269	// Otherwise, build a param string
12270	} else if ( params && typeof params === "object" ) {
12271		type = "POST";
12272	}
12273
12274	// If we have elements to modify, make the request
12275	if ( self.length > 0 ) {
12276		jQuery.ajax( {
12277			url: url,
12278
12279			// If "type" variable is undefined, then "GET" method will be used.
12280			// Make value of this field explicit since
12281			// user can override it through ajaxSetup method
12282			type: type || "GET",
12283			dataType: "html",
12284			data: params
12285		} ).done( function( responseText ) {
12286
12287			// Save response for use in complete callback
12288			response = arguments;
12289
12290			self.html( selector ?
12291
12292				// If a selector was specified, locate the right elements in a dummy div
12293				// Exclude scripts to avoid IE 'Permission Denied' errors
12294				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
12295
12296				// Otherwise use the full result
12297				responseText );
12298
12299		// If the request succeeds, this function gets "data", "status", "jqXHR"
12300		// but they are ignored because response was set above.
12301		// If it fails, this function gets "jqXHR", "status", "error"
12302		} ).always( callback && function( jqXHR, status ) {
12303			self.each( function() {
12304				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
12305			} );
12306		} );
12307	}
12308
12309	return this;
12310};
12311
12312
12313
12314
12315jQuery.expr.pseudos.animated = function( elem ) {
12316	return jQuery.grep( jQuery.timers, function( fn ) {
12317		return elem === fn.elem;
12318	} ).length;
12319};
12320
12321
12322
12323
12324jQuery.offset = {
12325	setOffset: function( elem, options, i ) {
12326		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
12327			position = jQuery.css( elem, "position" ),
12328			curElem = jQuery( elem ),
12329			props = {};
12330
12331		// Set position first, in-case top/left are set even on static elem
12332		if ( position === "static" ) {
12333			elem.style.position = "relative";
12334		}
12335
12336		curOffset = curElem.offset();
12337		curCSSTop = jQuery.css( elem, "top" );
12338		curCSSLeft = jQuery.css( elem, "left" );
12339		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
12340			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
12341
12342		// Need to be able to calculate position if either
12343		// top or left is auto and position is either absolute or fixed
12344		if ( calculatePosition ) {
12345			curPosition = curElem.position();
12346			curTop = curPosition.top;
12347			curLeft = curPosition.left;
12348
12349		} else {
12350			curTop = parseFloat( curCSSTop ) || 0;
12351			curLeft = parseFloat( curCSSLeft ) || 0;
12352		}
12353
12354		if ( isFunction( options ) ) {
12355
12356			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
12357			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
12358		}
12359
12360		if ( options.top != null ) {
12361			props.top = ( options.top - curOffset.top ) + curTop;
12362		}
12363		if ( options.left != null ) {
12364			props.left = ( options.left - curOffset.left ) + curLeft;
12365		}
12366
12367		if ( "using" in options ) {
12368			options.using.call( elem, props );
12369
12370		} else {
12371			curElem.css( props );
12372		}
12373	}
12374};
12375
12376jQuery.fn.extend( {
12377
12378	// offset() relates an element's border box to the document origin
12379	offset: function( options ) {
12380
12381		// Preserve chaining for setter
12382		if ( arguments.length ) {
12383			return options === undefined ?
12384				this :
12385				this.each( function( i ) {
12386					jQuery.offset.setOffset( this, options, i );
12387				} );
12388		}
12389
12390		var rect, win,
12391			elem = this[ 0 ];
12392
12393		if ( !elem ) {
12394			return;
12395		}
12396
12397		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
12398		// Support: IE <=11 only
12399		// Running getBoundingClientRect on a
12400		// disconnected node in IE throws an error
12401		if ( !elem.getClientRects().length ) {
12402			return { top: 0, left: 0 };
12403		}
12404
12405		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
12406		rect = elem.getBoundingClientRect();
12407		win = elem.ownerDocument.defaultView;
12408		return {
12409			top: rect.top + win.pageYOffset,
12410			left: rect.left + win.pageXOffset
12411		};
12412	},
12413
12414	// position() relates an element's margin box to its offset parent's padding box
12415	// This corresponds to the behavior of CSS absolute positioning
12416	position: function() {
12417		if ( !this[ 0 ] ) {
12418			return;
12419		}
12420
12421		var offsetParent, offset, doc,
12422			elem = this[ 0 ],
12423			parentOffset = { top: 0, left: 0 };
12424
12425		// position:fixed elements are offset from the viewport, which itself always has zero offset
12426		if ( jQuery.css( elem, "position" ) === "fixed" ) {
12427
12428			// Assume position:fixed implies availability of getBoundingClientRect
12429			offset = elem.getBoundingClientRect();
12430
12431		} else {
12432			offset = this.offset();
12433
12434			// Account for the *real* offset parent, which can be the document or its root element
12435			// when a statically positioned element is identified
12436			doc = elem.ownerDocument;
12437			offsetParent = elem.offsetParent || doc.documentElement;
12438			while ( offsetParent &&
12439				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
12440				jQuery.css( offsetParent, "position" ) === "static" ) {
12441
12442				offsetParent = offsetParent.parentNode;
12443			}
12444			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
12445
12446				// Incorporate borders into its offset, since they are outside its content origin
12447				parentOffset = jQuery( offsetParent ).offset();
12448				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
12449				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
12450			}
12451		}
12452
12453		// Subtract parent offsets and element margins
12454		return {
12455			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
12456			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
12457		};
12458	},
12459
12460	// This method will return documentElement in the following cases:
12461	// 1) For the element inside the iframe without offsetParent, this method will return
12462	//    documentElement of the parent window
12463	// 2) For the hidden or detached element
12464	// 3) For body or html element, i.e. in case of the html node - it will return itself
12465	//
12466	// but those exceptions were never presented as a real life use-cases
12467	// and might be considered as more preferable results.
12468	//
12469	// This logic, however, is not guaranteed and can change at any point in the future
12470	offsetParent: function() {
12471		return this.map( function() {
12472			var offsetParent = this.offsetParent;
12473
12474			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
12475				offsetParent = offsetParent.offsetParent;
12476			}
12477
12478			return offsetParent || documentElement;
12479		} );
12480	}
12481} );
12482
12483// Create scrollLeft and scrollTop methods
12484jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
12485	var top = "pageYOffset" === prop;
12486
12487	jQuery.fn[ method ] = function( val ) {
12488		return access( this, function( elem, method, val ) {
12489
12490			// Coalesce documents and windows
12491			var win;
12492			if ( isWindow( elem ) ) {
12493				win = elem;
12494			} else if ( elem.nodeType === 9 ) {
12495				win = elem.defaultView;
12496			}
12497
12498			if ( val === undefined ) {
12499				return win ? win[ prop ] : elem[ method ];
12500			}
12501
12502			if ( win ) {
12503				win.scrollTo(
12504					!top ? val : win.pageXOffset,
12505					top ? val : win.pageYOffset
12506				);
12507
12508			} else {
12509				elem[ method ] = val;
12510			}
12511		}, method, val, arguments.length );
12512	};
12513} );
12514
12515// Support: Safari <=7 - 9.1, Chrome <=37 - 49
12516// Add the top/left cssHooks using jQuery.fn.position
12517// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
12518// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
12519// getComputedStyle returns percent when specified for top/left/bottom/right;
12520// rather than make the css module depend on the offset module, just check for it here
12521jQuery.each( [ "top", "left" ], function( _i, prop ) {
12522	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
12523		function( elem, computed ) {
12524			if ( computed ) {
12525				computed = curCSS( elem, prop );
12526
12527				// If curCSS returns percentage, fallback to offset
12528				return rnumnonpx.test( computed ) ?
12529					jQuery( elem ).position()[ prop ] + "px" :
12530					computed;
12531			}
12532		}
12533	);
12534} );
12535
12536
12537// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
12538jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
12539	jQuery.each( {
12540		padding: "inner" + name,
12541		content: type,
12542		"": "outer" + name
12543	}, function( defaultExtra, funcName ) {
12544
12545		// Margin is only for outerHeight, outerWidth
12546		jQuery.fn[ funcName ] = function( margin, value ) {
12547			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
12548				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
12549
12550			return access( this, function( elem, type, value ) {
12551				var doc;
12552
12553				if ( isWindow( elem ) ) {
12554
12555					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
12556					return funcName.indexOf( "outer" ) === 0 ?
12557						elem[ "inner" + name ] :
12558						elem.document.documentElement[ "client" + name ];
12559				}
12560
12561				// Get document width or height
12562				if ( elem.nodeType === 9 ) {
12563					doc = elem.documentElement;
12564
12565					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
12566					// whichever is greatest
12567					return Math.max(
12568						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
12569						elem.body[ "offset" + name ], doc[ "offset" + name ],
12570						doc[ "client" + name ]
12571					);
12572				}
12573
12574				return value === undefined ?
12575
12576					// Get width or height on the element, requesting but not forcing parseFloat
12577					jQuery.css( elem, type, extra ) :
12578
12579					// Set width or height on the element
12580					jQuery.style( elem, type, value, extra );
12581			}, type, chainable ? margin : undefined, chainable );
12582		};
12583	} );
12584} );
12585
12586
12587jQuery.each( [
12588	"ajaxStart",
12589	"ajaxStop",
12590	"ajaxComplete",
12591	"ajaxError",
12592	"ajaxSuccess",
12593	"ajaxSend"
12594], function( _i, type ) {
12595	jQuery.fn[ type ] = function( fn ) {
12596		return this.on( type, fn );
12597	};
12598} );
12599
12600
12601
12602
12603jQuery.fn.extend( {
12604
12605	bind: function( types, data, fn ) {
12606		return this.on( types, null, data, fn );
12607	},
12608	unbind: function( types, fn ) {
12609		return this.off( types, null, fn );
12610	},
12611
12612	delegate: function( selector, types, data, fn ) {
12613		return this.on( types, selector, data, fn );
12614	},
12615	undelegate: function( selector, types, fn ) {
12616
12617		// ( namespace ) or ( selector, types [, fn] )
12618		return arguments.length === 1 ?
12619			this.off( selector, "**" ) :
12620			this.off( types, selector || "**", fn );
12621	},
12622
12623	hover: function( fnOver, fnOut ) {
12624		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
12625	}
12626} );
12627
12628jQuery.each(
12629	( "blur focus focusin focusout resize scroll click dblclick " +
12630	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
12631	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
12632	function( _i, name ) {
12633
12634		// Handle event binding
12635		jQuery.fn[ name ] = function( data, fn ) {
12636			return arguments.length > 0 ?
12637				this.on( name, null, data, fn ) :
12638				this.trigger( name );
12639		};
12640	}
12641);
12642
12643
12644
12645
12646// Support: Android <=4.0 only
12647// Make sure we trim BOM and NBSP
12648var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
12649
12650// Bind a function to a context, optionally partially applying any
12651// arguments.
12652// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
12653// However, it is not slated for removal any time soon
12654jQuery.proxy = function( fn, context ) {
12655	var tmp, args, proxy;
12656
12657	if ( typeof context === "string" ) {
12658		tmp = fn[ context ];
12659		context = fn;
12660		fn = tmp;
12661	}
12662
12663	// Quick check to determine if target is callable, in the spec
12664	// this throws a TypeError, but we will just return undefined.
12665	if ( !isFunction( fn ) ) {
12666		return undefined;
12667	}
12668
12669	// Simulated bind
12670	args = slice.call( arguments, 2 );
12671	proxy = function() {
12672		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
12673	};
12674
12675	// Set the guid of unique handler to the same of original handler, so it can be removed
12676	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
12677
12678	return proxy;
12679};
12680
12681jQuery.holdReady = function( hold ) {
12682	if ( hold ) {
12683		jQuery.readyWait++;
12684	} else {
12685		jQuery.ready( true );
12686	}
12687};
12688jQuery.isArray = Array.isArray;
12689jQuery.parseJSON = JSON.parse;
12690jQuery.nodeName = nodeName;
12691jQuery.isFunction = isFunction;
12692jQuery.isWindow = isWindow;
12693jQuery.camelCase = camelCase;
12694jQuery.type = toType;
12695
12696jQuery.now = Date.now;
12697
12698jQuery.isNumeric = function( obj ) {
12699
12700	// As of jQuery 3.0, isNumeric is limited to
12701	// strings and numbers (primitives or objects)
12702	// that can be coerced to finite numbers (gh-2662)
12703	var type = jQuery.type( obj );
12704	return ( type === "number" || type === "string" ) &&
12705
12706		// parseFloat NaNs numeric-cast false positives ("")
12707		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
12708		// subtraction forces infinities to NaN
12709		!isNaN( obj - parseFloat( obj ) );
12710};
12711
12712jQuery.trim = function( text ) {
12713	return text == null ?
12714		"" :
12715		( text + "" ).replace( rtrim, "" );
12716};
12717
12718
12719
12720// Register as a named AMD module, since jQuery can be concatenated with other
12721// files that may use define, but not via a proper concatenation script that
12722// understands anonymous AMD modules. A named AMD is safest and most robust
12723// way to register. Lowercase jquery is used because AMD module names are
12724// derived from file names, and jQuery is normally delivered in a lowercase
12725// file name. Do this after creating the global so that if an AMD module wants
12726// to call noConflict to hide this version of jQuery, it will work.
12727
12728// Note that for maximum portability, libraries that are not jQuery should
12729// declare themselves as anonymous modules, and avoid setting a global if an
12730// AMD loader is present. jQuery is a special case. For more information, see
12731// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
12732
12733if ( true ) {
12734	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
12735		return jQuery;
12736	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
12737				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
12738}
12739
12740
12741
12742
12743var
12744
12745	// Map over jQuery in case of overwrite
12746	_jQuery = window.jQuery,
12747
12748	// Map over the $ in case of overwrite
12749	_$ = window.$;
12750
12751jQuery.noConflict = function( deep ) {
12752	if ( window.$ === jQuery ) {
12753		window.$ = _$;
12754	}
12755
12756	if ( deep && window.jQuery === jQuery ) {
12757		window.jQuery = _jQuery;
12758	}
12759
12760	return jQuery;
12761};
12762
12763// Expose jQuery and $ identifiers, even in AMD
12764// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
12765// and CommonJS for browser emulators (#13566)
12766if ( typeof noGlobal === "undefined" ) {
12767	window.jQuery = window.$ = jQuery;
12768}
12769
12770
12771
12772
12773return jQuery;
12774} );
12775
12776
12777/***/ }),
12778
vendor: 70,301 bytes, lines 12779-13794
12779/***/ "./node_modules/mobile-detect/mobile-detect.js":
12780/*!*****************************************************!*\
12781  !*** ./node_modules/mobile-detect/mobile-detect.js ***!
12782  \*****************************************************/
12783/*! no static exports found */
12784/***/ (function(module, exports, __webpack_require__) {
12785
12786// THIS FILE IS GENERATED - DO NOT EDIT!
12787/*!mobile-detect v1.4.5 2021-03-13*/
12788/*global module:false, define:false*/
12789/*jshint latedef:false*/
12790/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
12791(function (define, undefined) {
12792define(function () {
12793    'use strict';
12794
12795    var impl = {};
12796
12797    impl.mobileDetectRules = {
12798    "phones": {
12799        "iPhone": "\\biPhone\\b|\\biPod\\b",
12800        "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+",
12801        "Pixel": "; \\bPixel\\b",
12802        "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel",
12803        "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6",
12804        "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",
12805        "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052",
12806        "Samsung": "\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F",
12807        "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710",
12808        "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332",
12809        "Asus": "Asus.*Galaxy|PadFone.*Mobile",
12810        "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G",
12811        "NokiaLumia": "Lumia [0-9]{3,4}",
12812        "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",
12813        "Palm": "PalmSource|Palm",
12814        "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",
12815        "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",
12816        "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",
12817        "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",
12818        "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",
12819        "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",
12820        "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",
12821        "Alcatel": "Alcatel",
12822        "Nintendo": "Nintendo (3DS|Switch)",
12823        "Amoi": "Amoi",
12824        "INQ": "INQ",
12825        "OnePlus": "ONEPLUS",
12826        "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"
12827    },
12828    "tablets": {
12829        "iPad": "iPad|iPad.*Mobile",
12830        "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)",
12831        "GoogleTablet": "Android.*Pixel C",
12832        "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860",
12833        "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)",
12834        "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",
12835        "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",
12836        "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b",
12837        "BlackBerryTablet": "PlayBook|RIM Tablet",
12838        "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",
12839        "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",
12840        "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",
12841        "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40",
12842        "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",
12843        "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",
12844        "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",
12845        "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",
12846        "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L",
12847        "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",
12848        "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",
12849        "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",
12850        "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",
12851        "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",
12852        "IRUTablet": "M702pro",
12853        "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",
12854        "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",
12855        "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",
12856        "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",
12857        "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",
12858        "NokiaLumiaTablet": "Lumia 2520",
12859        "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712",
12860        "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",
12861        "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",
12862        "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",
12863        "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",
12864        "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",
12865        "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",
12866        "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",
12867        "FlyTablet": "IQ310|Fly Vision",
12868        "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus",
12869        "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19",
12870        "NecTablet": "\\bN-06D|\\bN-08D",
12871        "PantechTablet": "Pantech.*P4100",
12872        "BronchoTablet": "Broncho.*(N701|N708|N802|a710)",
12873        "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",
12874        "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900",
12875        "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA",
12876        "NabiTablet": "Android.*\\bNabi",
12877        "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",
12878        "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",
12879        "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",
12880        "PlaystationTablet": "Playstation.*(Portable|Vita)",
12881        "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",
12882        "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",
12883        "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",
12884        "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",
12885        "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b",
12886        "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",
12887        "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",
12888        "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",
12889        "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",
12890        "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",
12891        "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",
12892        "GUTablet": "TX-A1301|TX-M9002|Q702|kf026",
12893        "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",
12894        "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027",
12895        "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",
12896        "DPSTablet": "DPS Dream 9|DPS Dual 7",
12897        "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",
12898        "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",
12899        "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b",
12900        "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan",
12901        "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",
12902        "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",
12903        "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",
12904        "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1",
12905        "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",
12906        "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400",
12907        "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",
12908        "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",
12909        "iMobileTablet": "i-mobile i-note",
12910        "TolinoTablet": "tolino tab [0-9.]+|tolino shine",
12911        "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b",
12912        "AMPETablet": "Android.* A78 ",
12913        "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)",
12914        "TecnoTablet": "TECNO P9|TECNO DP8D",
12915        "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",
12916        "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",
12917        "FX2Tablet": "FX2 PAD7|FX2 PAD10",
12918        "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",
12919        "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",
12920        "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1",
12921        "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",
12922        "CaptivaTablet": "CAPTIVA PAD",
12923        "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",
12924        "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",
12925        "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b",
12926        "JaytechTablet": "TPC-PA762",
12927        "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010",
12928        "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",
12929        "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",
12930        "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",
12931        "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",
12932        "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",
12933        "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",
12934        "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",
12935        "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA",
12936        "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b",
12937        "NibiruTablet": "Nibiru M1|Nibiru Jupiter One",
12938        "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",
12939        "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",
12940        "UbislateTablet": "UbiSlate[\\s]?7C",
12941        "PocketBookTablet": "Pocketbook",
12942        "KocasoTablet": "\\b(TB-1207)\\b",
12943        "HisenseTablet": "\\b(F5281|E2371)\\b",
12944        "Hudl": "Hudl HT7S3|Hudl 2",
12945        "TelstraTablet": "T-Hub2",
12946        "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"
12947    },
12948    "oss": {
12949        "AndroidOS": "Android",
12950        "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os",
12951        "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",
12952        "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",
12953        "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;",
12954        "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",
12955        "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia",
12956        "iPadOS": "CPU OS 13",
12957        "SailfishOS": "Sailfish",
12958        "MeeGoOS": "MeeGo",
12959        "MaemoOS": "Maemo",
12960        "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b",
12961        "webOS": "webOS|hpwOS",
12962        "badaOS": "\\bBada\\b",
12963        "BREWOS": "BREW"
12964    },
12965    "uas": {
12966        "Chrome": "\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?",
12967        "Dolfin": "\\bDolfin\\b",
12968        "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+",
12969        "Skyfire": "Skyfire",
12970        "Edge": "\\bEdgiOS\\b|Mobile Safari\/[.0-9]* Edge",
12971        "IE": "IEMobile|MSIEMobile",
12972        "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",
12973        "Bolt": "bolt",
12974        "TeaShark": "teashark",
12975        "Blazer": "Blazer",
12976        "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari",
12977        "WeChat": "\\bMicroMessenger\\b",
12978        "UCBrowser": "UC.*Browser|UCWEB",
12979        "baiduboxapp": "baiduboxapp",
12980        "baidubrowser": "baidubrowser",
12981        "DiigoBrowser": "DiigoBrowser",
12982        "Mercury": "\\bMercury\\b",
12983        "ObigoBrowser": "Obigo",
12984        "NetFront": "NF-Browser",
12985        "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",
12986        "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon"
12987    },
12988    "props": {
12989        "Mobile": "Mobile\/[VER]",
12990        "Build": "Build\/[VER]",
12991        "Version": "Version\/[VER]",
12992        "VendorID": "VendorID\/[VER]",
12993        "iPad": "iPad.*CPU[a-z ]+[VER]",
12994        "iPhone": "iPhone.*CPU[a-z ]+[VER]",
12995        "iPod": "iPod.*CPU[a-z ]+[VER]",
12996        "Kindle": "Kindle\/[VER]",
12997        "Chrome": [
12998            "Chrome\/[VER]",
12999            "CriOS\/[VER]",
13000            "CrMo\/[VER]"
13001        ],
13002        "Coast": [
13003            "Coast\/[VER]"
13004        ],
13005        "Dolfin": "Dolfin\/[VER]",
13006        "Firefox": [
13007            "Firefox\/[VER]",
13008            "FxiOS\/[VER]"
13009        ],
13010        "Fennec": "Fennec\/[VER]",
13011        "Edge": "Edge\/[VER]",
13012        "IE": [
13013            "IEMobile\/[VER];",
13014            "IEMobile [VER]",
13015            "MSIE [VER];",
13016            "Trident\/[0-9.]+;.*rv:[VER]"
13017        ],
13018        "NetFront": "NetFront\/[VER]",
13019        "NokiaBrowser": "NokiaBrowser\/[VER]",
13020        "Opera": [
13021            " OPR\/[VER]",
13022            "Opera Mini\/[VER]",
13023            "Version\/[VER]"
13024        ],
13025        "Opera Mini": "Opera Mini\/[VER]",
13026        "Opera Mobi": "Version\/[VER]",
13027        "UCBrowser": [
13028            "UCWEB[VER]",
13029            "UC.*Browser\/[VER]"
13030        ],
13031        "MQQBrowser": "MQQBrowser\/[VER]",
13032        "MicroMessenger": "MicroMessenger\/[VER]",
13033        "baiduboxapp": "baiduboxapp\/[VER]",
13034        "baidubrowser": "baidubrowser\/[VER]",
13035        "SamsungBrowser": "SamsungBrowser\/[VER]",
13036        "Iron": "Iron\/[VER]",
13037        "Safari": [
13038            "Version\/[VER]",
13039            "Safari\/[VER]"
13040        ],
13041        "Skyfire": "Skyfire\/[VER]",
13042        "Tizen": "Tizen\/[VER]",
13043        "Webkit": "webkit[ \/][VER]",
13044        "PaleMoon": "PaleMoon\/[VER]",
13045        "SailfishBrowser": "SailfishBrowser\/[VER]",
13046        "Gecko": "Gecko\/[VER]",
13047        "Trident": "Trident\/[VER]",
13048        "Presto": "Presto\/[VER]",
13049        "Goanna": "Goanna\/[VER]",
13050        "iOS": " \\bi?OS\\b [VER][ ;]{1}",
13051        "Android": "Android [VER]",
13052        "Sailfish": "Sailfish [VER]",
13053        "BlackBerry": [
13054            "BlackBerry[\\w]+\/[VER]",
13055            "BlackBerry.*Version\/[VER]",
13056            "Version\/[VER]"
13057        ],
13058        "BREW": "BREW [VER]",
13059        "Java": "Java\/[VER]",
13060        "Windows Phone OS": [
13061            "Windows Phone OS [VER]",
13062            "Windows Phone [VER]"
13063        ],
13064        "Windows Phone": "Windows Phone [VER]",
13065        "Windows CE": "Windows CE\/[VER]",
13066        "Windows NT": "Windows NT [VER]",
13067        "Symbian": [
13068            "SymbianOS\/[VER]",
13069            "Symbian\/[VER]"
13070        ],
13071        "webOS": [
13072            "webOS\/[VER]",
13073            "hpwOS\/[VER];"
13074        ]
13075    },
13076    "utils": {
13077        "Bot": "Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot",
13078        "MobileBot": "Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2",
13079        "DesktopMode": "WPDesktop",
13080        "TV": "SonyDTV|HbbTV",
13081        "WebKit": "(webkit)[ \/]([\\w.]+)",
13082        "Console": "\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b",
13083        "Watch": "SM-V700"
13084    }
13085};
13086
13087    // following patterns come from http://detectmobilebrowsers.com/
13088    impl.detectMobileBrowsers = {
13089        fullPattern: /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,
13090        shortPattern: /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,
13091        tabletPattern: /android|ipad|playbook|silk/i
13092    };
13093
13094    var hasOwnProp = Object.prototype.hasOwnProperty,
13095        isArray;
13096
13097    impl.FALLBACK_PHONE = 'UnknownPhone';
13098    impl.FALLBACK_TABLET = 'UnknownTablet';
13099    impl.FALLBACK_MOBILE = 'UnknownMobile';
13100
13101    isArray = ('isArray' in Array) ?
13102        Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
13103
13104    function equalIC(a, b) {
13105        return a != null && b != null && a.toLowerCase() === b.toLowerCase();
13106    }
13107
13108    function containsIC(array, value) {
13109        var valueLC, i, len = array.length;
13110        if (!len || !value) {
13111            return false;
13112        }
13113        valueLC = value.toLowerCase();
13114        for (i = 0; i < len; ++i) {
13115            if (valueLC === array[i].toLowerCase()) {
13116                return true;
13117            }
13118        }
13119        return false;
13120    }
13121
13122    function convertPropsToRegExp(object) {
13123        for (var key in object) {
13124            if (hasOwnProp.call(object, key)) {
13125                object[key] = new RegExp(object[key], 'i');
13126            }
13127        }
13128    }
13129
13130    function prepareUserAgent(userAgent) {
13131        return (userAgent || '').substr(0, 500); // mitigate vulnerable to ReDoS
13132    }
13133
13134    (function init() {
13135        var key, values, value, i, len, verPos, mobileDetectRules = impl.mobileDetectRules;
13136        for (key in mobileDetectRules.props) {
13137            if (hasOwnProp.call(mobileDetectRules.props, key)) {
13138                values = mobileDetectRules.props[key];
13139                if (!isArray(values)) {
13140                    values = [values];
13141                }
13142                len = values.length;
13143                for (i = 0; i < len; ++i) {
13144                    value = values[i];
13145                    verPos = value.indexOf('[VER]');
13146                    if (verPos >= 0) {
13147                        value = value.substring(0, verPos) + '([\\w._\\+]+)' + value.substring(verPos + 5);
13148                    }
13149                    values[i] = new RegExp(value, 'i');
13150                }
13151                mobileDetectRules.props[key] = values;
13152            }
13153        }
13154        convertPropsToRegExp(mobileDetectRules.oss);
13155        convertPropsToRegExp(mobileDetectRules.phones);
13156        convertPropsToRegExp(mobileDetectRules.tablets);
13157        convertPropsToRegExp(mobileDetectRules.uas);
13158        convertPropsToRegExp(mobileDetectRules.utils);
13159
13160        // copy some patterns to oss0 which are tested first (see issue#15)
13161        mobileDetectRules.oss0 = {
13162            WindowsPhoneOS: mobileDetectRules.oss.WindowsPhoneOS,
13163            WindowsMobileOS: mobileDetectRules.oss.WindowsMobileOS
13164        };
13165    }());
13166
13167    /**
13168     * Test userAgent string against a set of rules and find the first matched key.
13169     * @param {Object} rules (key is String, value is RegExp)
13170     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
13171     * @returns {String|null} the matched key if found, otherwise <tt>null</tt>
13172     * @private
13173     */
13174    impl.findMatch = function(rules, userAgent) {
13175        for (var key in rules) {
13176            if (hasOwnProp.call(rules, key)) {
13177                if (rules[key].test(userAgent)) {
13178                    return key;
13179                }
13180            }
13181        }
13182        return null;
13183    };
13184
13185    /**
13186     * Test userAgent string against a set of rules and return an array of matched keys.
13187     * @param {Object} rules (key is String, value is RegExp)
13188     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
13189     * @returns {Array} an array of matched keys, may be empty when there is no match, but not <tt>null</tt>
13190     * @private
13191     */
13192    impl.findMatches = function(rules, userAgent) {
13193        var result = [];
13194        for (var key in rules) {
13195            if (hasOwnProp.call(rules, key)) {
13196                if (rules[key].test(userAgent)) {
13197                    result.push(key);
13198                }
13199            }
13200        }
13201        return result;
13202    };
13203
13204    /**
13205     * Check the version of the given property in the User-Agent.
13206     *
13207     * @param {String} propertyName
13208     * @param {String} userAgent
13209     * @return {String} version or <tt>null</tt> if version not found
13210     * @private
13211     */
13212    impl.getVersionStr = function (propertyName, userAgent) {
13213        var props = impl.mobileDetectRules.props, patterns, i, len, match;
13214        if (hasOwnProp.call(props, propertyName)) {
13215            patterns = props[propertyName];
13216            len = patterns.length;
13217            for (i = 0; i < len; ++i) {
13218                match = patterns[i].exec(userAgent);
13219                if (match !== null) {
13220                    return match[1];
13221                }
13222            }
13223        }
13224        return null;
13225    };
13226
13227    /**
13228     * Check the version of the given property in the User-Agent.
13229     * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
13230     *
13231     * @param {String} propertyName
13232     * @param {String} userAgent
13233     * @return {Number} version or <tt>NaN</tt> if version not found
13234     * @private
13235     */
13236    impl.getVersion = function (propertyName, userAgent) {
13237        var version = impl.getVersionStr(propertyName, userAgent);
13238        return version ? impl.prepareVersionNo(version) : NaN;
13239    };
13240
13241    /**
13242     * Prepare the version number.
13243     *
13244     * @param {String} version
13245     * @return {Number} the version number as a floating number
13246     * @private
13247     */
13248    impl.prepareVersionNo = function (version) {
13249        var numbers;
13250
13251        numbers = version.split(/[a-z._ \/\-]/i);
13252        if (numbers.length === 1) {
13253            version = numbers[0];
13254        }
13255        if (numbers.length > 1) {
13256            version = numbers[0] + '.';
13257            numbers.shift();
13258            version += numbers.join('');
13259        }
13260        return Number(version);
13261    };
13262
13263    impl.isMobileFallback = function (userAgent) {
13264        return impl.detectMobileBrowsers.fullPattern.test(userAgent) ||
13265            impl.detectMobileBrowsers.shortPattern.test(userAgent.substr(0,4));
13266    };
13267
13268    impl.isTabletFallback = function (userAgent) {
13269        return impl.detectMobileBrowsers.tabletPattern.test(userAgent);
13270    };
13271
13272    impl.prepareDetectionCache = function (cache, userAgent, maxPhoneWidth) {
13273        if (cache.mobile !== undefined) {
13274            return;
13275        }
13276        var phone, tablet, phoneSized;
13277
13278        // first check for stronger tablet rules, then phone (see issue#5)
13279        tablet = impl.findMatch(impl.mobileDetectRules.tablets, userAgent);
13280        if (tablet) {
13281            cache.mobile = cache.tablet = tablet;
13282            cache.phone = null;
13283            return; // unambiguously identified as tablet
13284        }
13285
13286        phone = impl.findMatch(impl.mobileDetectRules.phones, userAgent);
13287        if (phone) {
13288            cache.mobile = cache.phone = phone;
13289            cache.tablet = null;
13290            return; // unambiguously identified as phone
13291        }
13292
13293        // our rules haven't found a match -> try more general fallback rules
13294        if (impl.isMobileFallback(userAgent)) {
13295            phoneSized = MobileDetect.isPhoneSized(maxPhoneWidth);
13296            if (phoneSized === undefined) {
13297                cache.mobile = impl.FALLBACK_MOBILE;
13298                cache.tablet = cache.phone = null;
13299            } else if (phoneSized) {
13300                cache.mobile = cache.phone = impl.FALLBACK_PHONE;
13301                cache.tablet = null;
13302            } else {
13303                cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
13304                cache.phone = null;
13305            }
13306        } else if (impl.isTabletFallback(userAgent)) {
13307            cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
13308            cache.phone = null;
13309        } else {
13310            // not mobile at all!
13311            cache.mobile = cache.tablet = cache.phone = null;
13312        }
13313    };
13314
13315    // t is a reference to a MobileDetect instance
13316    impl.mobileGrade = function (t) {
13317        // impl note:
13318        // To keep in sync w/ Mobile_Detect.php easily, the following code is tightly aligned to the PHP version.
13319        // When changes are made in Mobile_Detect.php, copy this method and replace:
13320        //     $this-> / t.
13321        //     self::MOBILE_GRADE_(.) / '$1'
13322        //     , self::VERSION_TYPE_FLOAT / (nothing)
13323        //     isIOS() / os('iOS')
13324        //     [reg] / (nothing)   <-- jsdelivr complaining about unescaped unicode character U+00AE
13325        var $isMobile = t.mobile() !== null;
13326
13327        if (
13328            // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
13329            t.os('iOS') && t.version('iPad')>=4.3 ||
13330            t.os('iOS') && t.version('iPhone')>=3.1 ||
13331            t.os('iOS') && t.version('iPod')>=3.1 ||
13332
13333            // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
13334            // Android 3.1 (Honeycomb)  - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
13335            // Android 4.0 (ICS)  - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
13336            // Android 4.1 (Jelly Bean)  - Tested on a Galaxy Nexus and Galaxy 7
13337            ( t.version('Android')>2.1 && t.is('Webkit') ) ||
13338
13339            // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
13340            t.version('Windows Phone OS')>=7.0 ||
13341
13342            // Blackberry 7 - Tested on BlackBerry Torch 9810
13343            // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
13344            t.is('BlackBerry') && t.version('BlackBerry')>=6.0 ||
13345            // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
13346            t.match('Playbook.*Tablet') ||
13347
13348            // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
13349            ( t.version('webOS')>=1.4 && t.match('Palm|Pre|Pixi') ) ||
13350            // Palm WebOS 3.0  - Tested on HP TouchPad
13351            t.match('hp.*TouchPad') ||
13352
13353            // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
13354            ( t.is('Firefox') && t.version('Firefox')>=12 ) ||
13355
13356            // Chrome for Android - Tested on Android 4.0, 4.1 device
13357            ( t.is('Chrome') && t.is('AndroidOS') && t.version('Android')>=4.0 ) ||
13358
13359            // Skyfire 4.1 - Tested on Android 2.3 device
13360            ( t.is('Skyfire') && t.version('Skyfire')>=4.1 && t.is('AndroidOS') && t.version('Android')>=2.3 ) ||
13361
13362            // Opera Mobile 11.5-12: Tested on Android 2.3
13363            ( t.is('Opera') && t.version('Opera Mobi')>11 && t.is('AndroidOS') ) ||
13364
13365            // Meego 1.2 - Tested on Nokia 950 and N9
13366            t.is('MeeGoOS') ||
13367
13368            // Tizen (pre-release) - Tested on early hardware
13369            t.is('Tizen') ||
13370
13371            // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
13372            // @todo: more tests here!
13373            t.is('Dolfin') && t.version('Bada')>=2.0 ||
13374
13375            // UC Browser - Tested on Android 2.3 device
13376            ( (t.is('UC Browser') || t.is('Dolfin')) && t.version('Android')>=2.3 ) ||
13377
13378            // Kindle 3 and Fire  - Tested on the built-in WebKit browser for each
13379            ( t.match('Kindle Fire') ||
13380                t.is('Kindle') && t.version('Kindle')>=3.0 ) ||
13381
13382            // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
13383            t.is('AndroidOS') && t.is('NookTablet') ||
13384
13385            // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
13386            t.version('Chrome')>=11 && !$isMobile ||
13387
13388            // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
13389            t.version('Safari')>=5.0 && !$isMobile ||
13390
13391            // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
13392            t.version('Firefox')>=4.0 && !$isMobile ||
13393
13394            // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
13395            t.version('MSIE')>=7.0 && !$isMobile ||
13396
13397            // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
13398            // @reference: http://my.opera.com/community/openweb/idopera/
13399            t.version('Opera')>=10 && !$isMobile
13400
13401            ){
13402            return 'A';
13403        }
13404
13405        if (
13406            t.os('iOS') && t.version('iPad')<4.3 ||
13407            t.os('iOS') && t.version('iPhone')<3.1 ||
13408            t.os('iOS') && t.version('iPod')<3.1 ||
13409
13410            // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
13411            t.is('Blackberry') && t.version('BlackBerry')>=5 && t.version('BlackBerry')<6 ||
13412
13413            //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
13414            ( t.version('Opera Mini')>=5.0 && t.version('Opera Mini')<=6.5 &&
13415                (t.version('Android')>=2.3 || t.is('iOS')) ) ||
13416
13417            // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
13418            t.match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
13419
13420            // @todo: report this (tested on Nokia N71)
13421            t.version('Opera Mobi')>=11 && t.is('SymbianOS')
13422            ){
13423            return 'B';
13424        }
13425
13426        if (
13427        // Blackberry 4.x - Tested on the Curve 8330
13428            t.version('BlackBerry')<5.0 ||
13429            // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
13430            t.match('MSIEMobile|Windows CE.*Mobile') || t.version('Windows Mobile')<=5.2
13431
13432            ){
13433            return 'C';
13434        }
13435
13436        //All older smartphone platforms and featurephones - Any device that doesn't support media queries
13437        //will receive the basic, C grade experience.
13438        return 'C';
13439    };
13440
13441    impl.detectOS = function (ua) {
13442        return impl.findMatch(impl.mobileDetectRules.oss0, ua) ||
13443            impl.findMatch(impl.mobileDetectRules.oss, ua);
13444    };
13445
13446    impl.getDeviceSmallerSide = function () {
13447        return window.screen.width < window.screen.height ?
13448            window.screen.width :
13449            window.screen.height;
13450    };
13451
13452    /**
13453     * Constructor for MobileDetect object.
13454     * <br>
13455     * Such an object will keep a reference to the given user-agent string and cache most of the detect queries.<br>
13456     * <div style="background-color: #d9edf7; border: 1px solid #bce8f1; color: #3a87ad; padding: 14px; border-radius: 2px; margin-top: 20px">
13457     *     <strong>Find information how to download and install:</strong>
13458     *     <a href="https://github.com/hgoebl/mobile-detect.js/">github.com/hgoebl/mobile-detect.js/</a>
13459     * </div>
13460     *
13461     * @example <pre>
13462     *     var md = new MobileDetect(window.navigator.userAgent);
13463     *     if (md.mobile()) {
13464     *         location.href = (md.mobileGrade() === 'A') ? '/mobile/' : '/lynx/';
13465     *     }
13466     * </pre>
13467     *
13468     * @param {string} userAgent typically taken from window.navigator.userAgent or http_header['User-Agent']
13469     * @param {number} [maxPhoneWidth=600] <strong>only for browsers</strong> specify a value for the maximum
13470     *        width of smallest device side (in logical "CSS" pixels) until a device detected as mobile will be handled
13471     *        as phone.
13472     *        This is only used in cases where the device cannot be classified as phone or tablet.<br>
13473     *        See <a href="http://developer.android.com/guide/practices/screens_support.html">Declaring Tablet Layouts
13474     *        for Android</a>.<br>
13475     *        If you provide a value < 0, then this "fuzzy" check is disabled.
13476     * @constructor
13477     * @global
13478     */
13479    function MobileDetect(userAgent, maxPhoneWidth) {
13480        this.ua = prepareUserAgent(userAgent);
13481        this._cache = {};
13482        //600dp is typical 7" tablet minimum width
13483        this.maxPhoneWidth = maxPhoneWidth || 600;
13484    }
13485
13486    MobileDetect.prototype = {
13487        constructor: MobileDetect,
13488
13489        /**
13490         * Returns the detected phone or tablet type or <tt>null</tt> if it is not a mobile device.
13491         * <br>
13492         * For a list of possible return values see {@link MobileDetect#phone} and {@link MobileDetect#tablet}.<br>
13493         * <br>
13494         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
13495         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
13496         * is positive, a value of <code>UnknownPhone</code>, <code>UnknownTablet</code> or
13497         * <code>UnknownMobile</code> is returned.<br>
13498         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
13499         * <br>
13500         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
13501         * and <code>UnknownMobile</code>, so you will get <code>UnknownMobile</code> here.<br>
13502         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
13503         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
13504         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
13505         * <br>
13506         * In most cases you will use the return value just as a boolean.
13507         *
13508         * @returns {String} the key for the phone family or tablet family, e.g. "Nexus".
13509         * @function MobileDetect#mobile
13510         */
13511        mobile: function () {
13512            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
13513            return this._cache.mobile;
13514        },
13515
13516        /**
13517         * Returns the detected phone type/family string or <tt>null</tt>.
13518         * <br>
13519         * The returned tablet (family or producer) is one of following keys:<br>
13520         * <br><tt>iPhone, BlackBerry, Pixel, HTC, Nexus, Dell, Motorola, Samsung, LG, Sony, Asus,
13521         * Xiaomi, NokiaLumia, Micromax, Palm, Vertu, Pantech, Fly, Wiko, iMobile,
13522         * SimValley, Wolfgang, Alcatel, Nintendo, Amoi, INQ, OnePlus, GenericPhone</tt><br>
13523         * <br>
13524         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
13525         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
13526         * is positive, a value of <code>UnknownPhone</code> or <code>UnknownMobile</code> is returned.<br>
13527         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
13528         * <br>
13529         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
13530         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
13531         * will return <code>UnknownMobile</code>.<br>
13532         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
13533         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
13534         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
13535         * <br>
13536         * In most cases you will use the return value just as a boolean.
13537         *
13538         * @returns {String} the key of the phone family or producer, e.g. "iPhone"
13539         * @function MobileDetect#phone
13540         */
13541        phone: function () {
13542            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
13543            return this._cache.phone;
13544        },
13545
13546        /**
13547         * Returns the detected tablet type/family string or <tt>null</tt>.
13548         * <br>
13549         * The returned tablet (family or producer) is one of following keys:<br>
13550         * <br><tt>iPad, NexusTablet, GoogleTablet, SamsungTablet, Kindle, SurfaceTablet,
13551         * HPTablet, AsusTablet, BlackBerryTablet, HTCtablet, MotorolaTablet, NookTablet,
13552         * AcerTablet, ToshibaTablet, LGTablet, FujitsuTablet, PrestigioTablet,
13553         * LenovoTablet, DellTablet, YarvikTablet, MedionTablet, ArnovaTablet,
13554         * IntensoTablet, IRUTablet, MegafonTablet, EbodaTablet, AllViewTablet,
13555         * ArchosTablet, AinolTablet, NokiaLumiaTablet, SonyTablet, PhilipsTablet,
13556         * CubeTablet, CobyTablet, MIDTablet, MSITablet, SMiTTablet, RockChipTablet,
13557         * FlyTablet, bqTablet, HuaweiTablet, NecTablet, PantechTablet, BronchoTablet,
13558         * VersusTablet, ZyncTablet, PositivoTablet, NabiTablet, KoboTablet, DanewTablet,
13559         * TexetTablet, PlaystationTablet, TrekstorTablet, PyleAudioTablet, AdvanTablet,
13560         * DanyTechTablet, GalapadTablet, MicromaxTablet, KarbonnTablet, AllFineTablet,
13561         * PROSCANTablet, YONESTablet, ChangJiaTablet, GUTablet, PointOfViewTablet,
13562         * OvermaxTablet, HCLTablet, DPSTablet, VistureTablet, CrestaTablet,
13563         * MediatekTablet, ConcordeTablet, GoCleverTablet, ModecomTablet, VoninoTablet,
13564         * ECSTablet, StorexTablet, VodafoneTablet, EssentielBTablet, RossMoorTablet,
13565         * iMobileTablet, TolinoTablet, AudioSonicTablet, AMPETablet, SkkTablet,
13566         * TecnoTablet, JXDTablet, iJoyTablet, FX2Tablet, XoroTablet, ViewsonicTablet,
13567         * VerizonTablet, OdysTablet, CaptivaTablet, IconbitTablet, TeclastTablet,
13568         * OndaTablet, JaytechTablet, BlaupunktTablet, DigmaTablet, EvolioTablet,
13569         * LavaTablet, AocTablet, MpmanTablet, CelkonTablet, WolderTablet, MediacomTablet,
13570         * MiTablet, NibiruTablet, NexoTablet, LeaderTablet, UbislateTablet,
13571         * PocketBookTablet, KocasoTablet, HisenseTablet, Hudl, TelstraTablet,
13572         * GenericTablet</tt><br>
13573         * <br>
13574         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
13575         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
13576         * is positive, a value of <code>UnknownTablet</code> or <code>UnknownMobile</code> is returned.<br>
13577         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
13578         * <br>
13579         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
13580         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
13581         * will return <code>UnknownMobile</code>.<br>
13582         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
13583         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
13584         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
13585         * <br>
13586         * In most cases you will use the return value just as a boolean.
13587         *
13588         * @returns {String} the key of the tablet family or producer, e.g. "SamsungTablet"
13589         * @function MobileDetect#tablet
13590         */
13591        tablet: function () {
13592            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
13593            return this._cache.tablet;
13594        },
13595
13596        /**
13597         * Returns the (first) detected user-agent string or <tt>null</tt>.
13598         * <br>
13599         * The returned user-agent is one of following keys:<br>
13600         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
13601         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
13602         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
13603         * <br>
13604         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
13605         * cases where a mobile device pretends to be more than one particular browser. You can get the
13606         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
13607         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
13608         *
13609         * @returns {String} the key for the detected user-agent or <tt>null</tt>
13610         * @function MobileDetect#userAgent
13611         */
13612        userAgent: function () {
13613            if (this._cache.userAgent === undefined) {
13614                this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua);
13615            }
13616            return this._cache.userAgent;
13617        },
13618
13619        /**
13620         * Returns all detected user-agent strings.
13621         * <br>
13622         * The array is empty or contains one or more of following keys:<br>
13623         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
13624         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
13625         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
13626         * <br>
13627         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
13628         * cases where a mobile device pretends to be more than one particular browser. You can get the
13629         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
13630         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
13631         *
13632         * @returns {Array} the array of detected user-agent keys or <tt>[]</tt>
13633         * @function MobileDetect#userAgents
13634         */
13635        userAgents: function () {
13636            if (this._cache.userAgents === undefined) {
13637                this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua);
13638            }
13639            return this._cache.userAgents;
13640        },
13641
13642        /**
13643         * Returns the detected operating system string or <tt>null</tt>.
13644         * <br>
13645         * The operating system is one of following keys:<br>
13646         * <br><tt>AndroidOS, BlackBerryOS, PalmOS, SymbianOS, WindowsMobileOS, WindowsPhoneOS,
13647         * iOS, iPadOS, SailfishOS, MeeGoOS, MaemoOS, JavaOS, webOS, badaOS, BREWOS</tt><br>
13648         *
13649         * @returns {String} the key for the detected operating system.
13650         * @function MobileDetect#os
13651         */
13652        os: function () {
13653            if (this._cache.os === undefined) {
13654                this._cache.os = impl.detectOS(this.ua);
13655            }
13656            return this._cache.os;
13657        },
13658
13659        /**
13660         * Get the version (as Number) of the given property in the User-Agent.
13661         * <br>
13662         * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
13663         *
13664         * @param {String} key a key defining a thing which has a version.<br>
13665         *        You can use one of following keys:<br>
13666         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
13667         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
13668         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
13669         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
13670         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
13671         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
13672         * NT, Symbian, webOS</tt><br>
13673         *
13674         * @returns {Number} the version as float or <tt>NaN</tt> if User-Agent doesn't contain this version.
13675         *          Be careful when comparing this value with '==' operator!
13676         * @function MobileDetect#version
13677         */
13678        version: function (key) {
13679            return impl.getVersion(key, this.ua);
13680        },
13681
13682        /**
13683         * Get the version (as String) of the given property in the User-Agent.
13684         * <br>
13685         *
13686         * @param {String} key a key defining a thing which has a version.<br>
13687         *        You can use one of following keys:<br>
13688         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
13689         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
13690         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
13691         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
13692         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
13693         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
13694         * NT, Symbian, webOS</tt><br>
13695         *
13696         * @returns {String} the "raw" version as String or <tt>null</tt> if User-Agent doesn't contain this version.
13697         *
13698         * @function MobileDetect#versionStr
13699         */
13700        versionStr: function (key) {
13701            return impl.getVersionStr(key, this.ua);
13702        },
13703
13704        /**
13705         * Global test key against userAgent, os, phone, tablet and some other properties of userAgent string.
13706         *
13707         * @param {String} key the key (case-insensitive) of a userAgent, an operating system, phone or
13708         *        tablet family.<br>
13709         *        For a complete list of possible values, see {@link MobileDetect#userAgent},
13710         *        {@link MobileDetect#os}, {@link MobileDetect#phone}, {@link MobileDetect#tablet}.<br>
13711         *        Additionally you have following keys:<br>
13712         * <br><tt>Bot, MobileBot, DesktopMode, TV, WebKit, Console, Watch</tt><br>
13713         *
13714         * @returns {boolean} <tt>true</tt> when the given key is one of the defined keys of userAgent, os, phone,
13715         *                    tablet or one of the listed additional keys, otherwise <tt>false</tt>
13716         * @function MobileDetect#is
13717         */
13718        is: function (key) {
13719            return containsIC(this.userAgents(), key) ||
13720                   equalIC(key, this.os()) ||
13721                   equalIC(key, this.phone()) ||
13722                   equalIC(key, this.tablet()) ||
13723                   containsIC(impl.findMatches(impl.mobileDetectRules.utils, this.ua), key);
13724        },
13725
13726        /**
13727         * Do a quick test against navigator::userAgent.
13728         *
13729         * @param {String|RegExp} pattern the pattern, either as String or RegExp
13730         *                        (a string will be converted to a case-insensitive RegExp).
13731         * @returns {boolean} <tt>true</tt> when the pattern matches, otherwise <tt>false</tt>
13732         * @function MobileDetect#match
13733         */
13734        match: function (pattern) {
13735            if (!(pattern instanceof RegExp)) {
13736                pattern = new RegExp(pattern, 'i');
13737            }
13738            return pattern.test(this.ua);
13739        },
13740
13741        /**
13742         * Checks whether the mobile device can be considered as phone regarding <code>screen.width</code>.
13743         * <br>
13744         * Obviously this method makes sense in browser environments only (not for Node.js)!
13745         * @param {number} [maxPhoneWidth] the maximum logical pixels (aka. CSS-pixels) to be considered as phone.<br>
13746         *        The argument is optional and if not present or falsy, the value of the constructor is taken.
13747         * @returns {boolean|undefined} <code>undefined</code> if screen size wasn't detectable, else <code>true</code>
13748         *          when screen.width is less or equal to maxPhoneWidth, otherwise <code>false</code>.<br>
13749         *          Will always return <code>undefined</code> server-side.
13750         */
13751        isPhoneSized: function (maxPhoneWidth) {
13752            return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth);
13753        },
13754
13755        /**
13756         * Returns the mobile grade ('A', 'B', 'C').
13757         *
13758         * @returns {String} one of the mobile grades ('A', 'B', 'C').
13759         * @function MobileDetect#mobileGrade
13760         */
13761        mobileGrade: function () {
13762            if (this._cache.grade === undefined) {
13763                this._cache.grade = impl.mobileGrade(this);
13764            }
13765            return this._cache.grade;
13766        }
13767    };
13768
13769    // environment-dependent
13770    if (typeof window !== 'undefined' && window.screen) {
13771        MobileDetect.isPhoneSized = function (maxPhoneWidth) {
13772            return maxPhoneWidth < 0 ? undefined : impl.getDeviceSmallerSide() <= maxPhoneWidth;
13773        };
13774    } else {
13775        MobileDetect.isPhoneSized = function () {};
13776    }
13777
13778    // should not be replaced by a completely new object - just overwrite existing methods
13779    MobileDetect._impl = impl;
13780    
13781    MobileDetect.version = '1.4.5 2021-03-13';
13782
13783    return MobileDetect;
13784}); // end of call of define()
13785})((function (undefined) {
13786    if ( true && module.exports) {
13787        return function (factory) { module.exports = factory(); };
13788    } else if (true) {
13789        return __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js");
13790    } else {}
13791})());
13792
13793/***/ }),
13794
vendor: 353 bytes, lines 13795-13808
13795/***/ "./node_modules/webpack/buildin/amd-define.js":
13796/*!***************************************!*\
13797  !*** (webpack)/buildin/amd-define.js ***!
13798  \***************************************/
13799/*! no static exports found */
13800/***/ (function(module, exports) {
13801
13802module.exports = function() {
13803	throw new Error("define cannot be used indirect");
13804};
13805
13806
13807/***/ }),
13808
vendor: 721 bytes, lines 13809-13838
13809/***/ "./node_modules/webpack/buildin/global.js":
13810/*!***********************************!*\
13811  !*** (webpack)/buildin/global.js ***!
13812  \***********************************/
13813/*! no static exports found */
13814/***/ (function(module, exports) {
13815
13816var g;
13817
13818// This works in non-strict mode
13819g = (function() {
13820	return this;
13821})();
13822
13823try {
13824	// This works if eval is allowed (see CSP)
13825	g = g || new Function("return this")();
13826} catch (e) {
13827	// This works if the window reference is available
13828	if (typeof window === "object") g = window;
13829}
13830
13831// g can still be undefined, but nothing to do about it...
13832// We return undefined, instead of nothing here, so it's
13833// easier to handle this case. if(!global) { ...}
13834
13835module.exports = g;
13836
13837
13838/***/ })
13838
13839
13840/******/ });
13841//# sourceMappingURL=app.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.