text: /*!
   * pulltorefreshjs v0.1.20
   * (c) Rafael Soto
   * Released under the MIT License.
   */
  (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = global || self, global.PullToRefresh = factory());
  }(this, function () { 'use strict';
  
    var _shared = {
      pullStartY: null,
      pullMoveY: null,
      handlers: [],
      styleEl: null,
      events: null,
      dist: 0,
      state: 'pending',
      timeout: null,
      distResisted: 0,
      supportsPassive: false,
      supportsPointerEvents: !!window.PointerEvent
    };
  
    try {
      window.addEventListener('test', null, {
        get passive() {
          // eslint-disable-line getter-return
          _shared.supportsPassive = true;
        }
  
      });
    } catch (e) {// do nothing
    }
  
    function setupDOM(handler) {
      if (!handler.ptrElement) {
        var ptr = document.createElement('div');
  
        if (handler.mainElement !== document.body) {
          handler.mainElement.parentNode.insertBefore(ptr, handler.mainElement);
        } else {
          document.body.insertBefore(ptr, document.body.firstChild);
        }
  
        ptr.classList.add(((handler.classPrefix) + "ptr"));
        ptr.innerHTML = handler.getMarkup().replace(/__PREFIX__/g, handler.classPrefix);
        handler.ptrElement = ptr;
  
        if (typeof handler.onInit === 'function') {
          handler.onInit(handler);
        } // Add the css styles to the style node, and then
        // insert it into the dom
  
  
        if (!_shared.styleEl) {
          _shared.styleEl = document.createElement('style');
  
          _shared.styleEl.setAttribute('id', 'pull-to-refresh-js-style');
  
          document.head.appendChild(_shared.styleEl);
        }
  
        _shared.styleEl.textContent = handler.getStyles().replace(/__PREFIX__/g, handler.classPrefix).replace(/\s+/g, ' ');
      }
  
      return handler;
    }
  
    function onReset(handler) {
      handler.ptrElement.classList.remove(((handler.classPrefix) + "refresh"));
      handler.ptrElement.style[handler.cssProp] = '0px';
      setTimeout(function () {
        // remove previous ptr-element from DOM
        if (handler.ptrElement && handler.ptrElement.parentNode) {
          handler.ptrElement.parentNode.removeChild(handler.ptrElement);
          handler.ptrElement = null;
        } // reset state
  
  
        _shared.state = 'pending';
      }, handler.refreshTimeout);
    }
  
    function update(handler) {
      var iconEl = handler.ptrElement.querySelector(("." + (handler.classPrefix) + "icon"));
      var textEl = handler.ptrElement.querySelector(("." + (handler.classPrefix) + "text"));
  
      if (iconEl) {
        if (_shared.state === 'refreshing') {
          iconEl.innerHTML = handler.iconRefreshing;
        } else {
          iconEl.innerHTML = handler.iconArrow;
        }
      }
  
      if (textEl) {
        if (_shared.state === 'releasing') {
          textEl.innerHTML = handler.instructionsReleaseToRefresh;
        }
  
        if (_shared.state === 'pulling' || _shared.state === 'pending') {
          textEl.innerHTML = handler.instructionsPullToRefresh;
        }
  
        if (_shared.state === 'refreshing') {
          textEl.innerHTML = handler.instructionsRefreshing;
        }
      }
    }
  
    var _ptr = {
      setupDOM: setupDOM,
      onReset: onReset,
      update: update
    };
  
    var _timeout;
  
    var screenY = function screenY(event) {
      if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {
        return event.screenY;
      }
  
      return event.touches[0].screenY;
    };
  
    var _setupEvents = (function () {
      var _el;
  
      function _onTouchStart(e) {
        // here, we must pick a handler first, and then append their html/css on the DOM
        var target = _shared.handlers.filter(function (h) { return h.contains(e.target); })[0];
  
        _shared.enable = !!target;
  
        if (target && _shared.state === 'pending') {
          _el = _ptr.setupDOM(target);
  
          if (target.shouldPullToRefresh()) {
            _shared.pullStartY = screenY(e);
          }
  
          clearTimeout(_shared.timeout);
  
          _ptr.update(target);
        }
      }
  
      function _onTouchMove(e) {
        if (!(_el && _el.ptrElement && _shared.enable)) {
          return;
        }
  
        if (!_shared.pullStartY) {
          if (_el.shouldPullToRefresh()) {
            _shared.pullStartY = screenY(e);
          }
        } else {
          _shared.pullMoveY = screenY(e);
        }
  
        if (_shared.state === 'refreshing') {
          if (e.cancelable && _el.shouldPullToRefresh() && _shared.pullStartY < _shared.pullMoveY) {
            e.preventDefault();
          }
  
          return;
        }
  
        if (_shared.state === 'pending') {
          _el.ptrElement.classList.add(((_el.classPrefix) + "pull"));
  
          _shared.state = 'pulling';
  
          _ptr.update(_el);
        }
  
        if (_shared.pullStartY && _shared.pullMoveY) {
          _shared.dist = _shared.pullMoveY - _shared.pullStartY;
        }
  
        _shared.distExtra = _shared.dist - _el.distIgnore;
  
        if (_shared.distExtra > 0) {
          if (e.cancelable) {
            e.preventDefault();
          }
  
          _el.ptrElement.style[_el.cssProp] = (_shared.distResisted) + "px";
          _shared.distResisted = _el.resistanceFunction(_shared.distExtra / _el.distThreshold) * Math.min(_el.distMax, _shared.distExtra);
  
          if (_shared.state === 'pulling' && _shared.distResisted > _el.distThreshold) {
            _el.ptrElement.classList.add(((_el.classPrefix) + "release"));
  
            _shared.state = 'releasing';
  
            _ptr.update(_el);
          }
  
          if (_shared.state === 'releasing' && _shared.distResisted < _el.distThreshold) {
            _el.ptrElement.classList.remove(((_el.classPrefix) + "release"));
  
            _shared.state = 'pulling';
  
            _ptr.update(_el);
          }
        }
      }
  
      function _onTouchEnd() {
        if (!(_el && _el.ptrElement && _shared.enable)) {
          return;
        } // wait 1/2 sec before unmounting...
  
  
        clearTimeout(_timeout);
        _timeout = setTimeout(function () {
          if (_el && _el.ptrElement && _shared.state === 'pending') {
            _ptr.onReset(_el);
          }
        }, 500);
  
        if (_shared.state === 'releasing' && _shared.distResisted > _el.distThreshold) {
          _shared.state = 'refreshing';
          _el.ptrElement.style[_el.cssProp] = (_el.distReload) + "px";
  
          _el.ptrElement.classList.add(((_el.classPrefix) + "refresh"));
  
          _shared.timeout = setTimeout(function () {
            var retval = _el.onRefresh(function () { return _ptr.onReset(_el); });
  
            if (retval && typeof retval.then === 'function') {
              retval.then(function () { return _ptr.onReset(_el); });
            }
  
            if (!retval && !_el.onRefresh.length) {
              _ptr.onReset(_el);
            }
          }, _el.refreshTimeout);
        } else {
          if (_shared.state === 'refreshing') {
            return;
          }
  
          _el.ptrElement.style[_el.cssProp] = '0px';
          _shared.state = 'pending';
        }
  
        _ptr.update(_el);
  
        _el.ptrElement.classList.remove(((_el.classPrefix) + "release"));
  
        _el.ptrElement.classList.remove(((_el.classPrefix) + "pull"));
  
        _shared.pullStartY = _shared.pullMoveY = null;
        _shared.dist = _shared.distResisted = 0;
      }
  
      function _onScroll() {
        if (_el) {
          _el.mainElement.classList.toggle(((_el.classPrefix) + "top"), _el.shouldPullToRefresh());
        }
      }
  
      var _passiveSettings = _shared.supportsPassive ? {
        passive: _shared.passive || false
      } : undefined;
  
      if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {
        window.addEventListener('pointerup', _onTouchEnd);
        window.addEventListener('pointerdown', _onTouchStart);
        window.addEventListener('pointermove', _onTouchMove, _passiveSettings);
      } else {
        window.addEventListener('touchend', _onTouchEnd);
        window.addEventListener('touchstart', _onTouchStart);
        window.addEventListener('touchmove', _onTouchMove, _passiveSettings);
      }
  
      window.addEventListener('scroll', _onScroll);
      return {
        onTouchEnd: _onTouchEnd,
        onTouchStart: _onTouchStart,
        onTouchMove: _onTouchMove,
        onScroll: _onScroll,
  
        destroy: function destroy() {
          if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {
            window.removeEventListener('pointerdown', _onTouchStart);
            window.removeEventListener('pointerup', _onTouchEnd);
            window.removeEventListener('pointermove', _onTouchMove, _passiveSettings);
          } else {
            window.removeEventListener('touchstart', _onTouchStart);
            window.removeEventListener('touchend', _onTouchEnd);
            window.removeEventListener('touchmove', _onTouchMove, _passiveSettings);
          }
  
          window.removeEventListener('scroll', _onScroll);
        }
  
      };
    });
  
    var _ptrMarkup = "\n<div class=\"__PREFIX__box\">\n  <div class=\"__PREFIX__content\">\n    <div class=\"__PREFIX__icon\"></div>\n    <div class=\"__PREFIX__text\"></div>\n  </div>\n</div>\n";
  
    var _ptrStyles = "\n.__PREFIX__ptr {\n  box-shadow: inset 0 -3px 5px rgba(0, 0, 0, 0.12);\n  pointer-events: none;\n  font-size: 0.85em;\n  font-weight: bold;\n  top: 0;\n  height: 0;\n  transition: height 0.3s, min-height 0.3s;\n  text-align: center;\n  width: 100%;\n  overflow: hidden;\n  display: flex;\n  align-items: flex-end;\n  align-content: stretch;\n}\n\n.__PREFIX__box {\n  padding: 10px;\n  flex-basis: 100%;\n}\n\n.__PREFIX__pull {\n  transition: none;\n}\n\n.__PREFIX__text {\n  margin-top: .33em;\n  color: rgba(0, 0, 0, 0.3);\n}\n\n.__PREFIX__icon {\n  color: rgba(0, 0, 0, 0.3);\n  transition: transform .3s;\n}\n\n/*\nWhen at the top of the page, disable vertical overscroll so passive touch\nlisteners can take over.\n*/\n.__PREFIX__top {\n  touch-action: pan-x pan-down pinch-zoom;\n}\n\n.__PREFIX__release .__PREFIX__icon {\n  transform: rotate(180deg);\n}\n";
  
    var _defaults = {
      distThreshold: 60,
      distMax: 80,
      distReload: 50,
      distIgnore: 0,
      mainElement: 'body',
      triggerElement: 'body',
      ptrElement: '.ptr',
      classPrefix: 'ptr--',
      cssProp: 'min-height',
      iconArrow: '&#8675;',
      iconRefreshing: '&hellip;',
      instructionsPullToRefresh: 'Pull down to refresh',
      instructionsReleaseToRefresh: 'Release to refresh',
      instructionsRefreshing: 'Refreshing',
      refreshTimeout: 500,
      getMarkup: function () { return _ptrMarkup; },
      getStyles: function () { return _ptrStyles; },
      onInit: function () {},
      onRefresh: function () { return location.reload(); },
      resistanceFunction: function (t) { return Math.min(1, t / 2.5); },
      shouldPullToRefresh: function () { return !window.scrollY; }
    };
  
    var _methods = ['mainElement', 'ptrElement', 'triggerElement'];
    var _setupHandler = (function (options) {
      var _handler = {}; // merge options with defaults
  
      Object.keys(_defaults).forEach(function (key) {
        _handler[key] = options[key] || _defaults[key];
      }); // normalize timeout value, even if it is zero
  
      _handler.refreshTimeout = typeof options.refreshTimeout === 'number' ? options.refreshTimeout : _defaults.refreshTimeout; // normalize elements
  
      _methods.forEach(function (method) {
        if (typeof _handler[method] === 'string') {
          _handler[method] = document.querySelector(_handler[method]);
        }
      }); // attach events lazily
  
  
      if (!_shared.events) {
        _shared.events = _setupEvents();
      }
  
      _handler.contains = function (target) {
        return _handler.triggerElement.contains(target);
      };
  
      _handler.destroy = function () {
        // stop pending any pending callbacks
        clearTimeout(_shared.timeout); // remove handler from shared state
  
        var offset = _shared.handlers.indexOf(_handler);
  
        _shared.handlers.splice(offset, 1);
      };
  
      return _handler;
    });
  
    var index = {
      setPassiveMode: function setPassiveMode(isPassive) {
        _shared.passive = isPassive;
      },
  
      setPointerEventsMode: function setPointerEventsMode(isEnabled) {
        _shared.pointerEventsEnabled = isEnabled;
      },
  
      destroyAll: function destroyAll() {
        if (_shared.events) {
          _shared.events.destroy();
  
          _shared.events = null;
        }
  
        _shared.handlers.forEach(function (h) {
          h.destroy();
        });
      },
  
      init: function init(options) {
        if ( options === void 0 ) options = {};
  
        var handler = _setupHandler(options);
  
        _shared.handlers.push(handler);
  
        return handler;
      },
  
      // export utils for testing
      _: {
        setupHandler: _setupHandler,
        setupEvents: _setupEvents,
        setupDOM: _ptr.setupDOM,
        onReset: _ptr.onReset,
        update: _ptr.update
      }
    };
  
    return index;
  
  }));
  
  /*!
   * jQuery JavaScript Library v3.5.1
   * https://jquery.com/
   *
   * Includes Sizzle.js
   * https://sizzlejs.com/
   *
   * Copyright JS Foundation and other contributors
   * Released under the MIT license
   * https://jquery.org/license
   *
   * Date: 2020-05-04T22:49Z
   */
  ( function( global, factory ) {
  
  	"use strict";
  
  	if ( typeof module === "object" && typeof module.exports === "object" ) {
  
  		// For CommonJS and CommonJS-like environments where a proper `window`
  		// is present, execute the factory and get jQuery.
  		// For environments that do not have a `window` with a `document`
  		// (such as Node.js), expose a factory as module.exports.
  		// This accentuates the need for the creation of a real `window`.
  		// e.g. var jQuery = require("jquery")(window);
  		// See ticket #14549 for more info.
  		module.exports = global.document ?
  			factory( global, true ) :
  			function( w ) {
  				if ( !w.document ) {
  					throw new Error( "jQuery requires a window with a document" );
  				}
  				return factory( w );
  			};
  	} else {
  		factory( global );
  	}
  
  // Pass this if window is not defined yet
  } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
  
  // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
  // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
  // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
  // enough that all such attempts are guarded in a try block.
  "use strict";
  
  var arr = [];
  
  var getProto = Object.getPrototypeOf;
  
  var slice = arr.slice;
  
  var flat = arr.flat ? function( array ) {
  	return arr.flat.call( array );
  } : function( array ) {
  	return arr.concat.apply( [], array );
  };
  
  
  var push = arr.push;
  
  var indexOf = arr.indexOf;
  
  var class2type = {};
  
  var toString = class2type.toString;
  
  var hasOwn = class2type.hasOwnProperty;
  
  var fnToString = hasOwn.toString;
  
  var ObjectFunctionString = fnToString.call( Object );
  
  var support = {};
  
  var isFunction = function isFunction( obj ) {
  
        // Support: Chrome <=57, Firefox <=52
        // In some browsers, typeof returns "function" for HTML <object> elements
        // (i.e., `typeof document.createElement( "object" ) === "function"`).
        // We don't want to classify *any* DOM node as a function.
        return typeof obj === "function" && typeof obj.nodeType !== "number";
    };
  
  
  var isWindow = function isWindow( obj ) {
  		return obj != null && obj === obj.window;
  	};
  
  
  var document = window.document;
  
  
  
  	var preservedScriptAttributes = {
  		type: true,
  		src: true,
  		nonce: true,
  		noModule: true
  	};
  
  	function DOMEval( code, node, doc ) {
  		doc = doc || document;
  
  		var i, val,
  			script = doc.createElement( "script" );
  
  		script.text = code;
  		if ( node ) {
  			for ( i in preservedScriptAttributes ) {
  
  				// Support: Firefox 64+, Edge 18+
  				// Some browsers don't support the "nonce" property on scripts.
  				// On the other hand, just using `getAttribute` is not enough as
  				// the `nonce` attribute is reset to an empty string whenever it
  				// becomes browsing-context connected.
  				// See https://github.com/whatwg/html/issues/2369
  				// See https://html.spec.whatwg.org/#nonce-attributes
  				// The `node.getAttribute` check was added for the sake of
  				// `jQuery.globalEval` so that it can fake a nonce-containing node
  				// via an object.
  				val = node[ i ] || node.getAttribute && node.getAttribute( i );
  				if ( val ) {
  					script.setAttribute( i, val );
  				}
  			}
  		}
  		doc.head.appendChild( script ).parentNode.removeChild( script );
  	}
  
  
  function toType( obj ) {
  	if ( obj == null ) {
  		return obj + "";
  	}
  
  	// Support: Android <=2.3 only (functionish RegExp)
  	return typeof obj === "object" || typeof obj === "function" ?
  		class2type[ toString.call( obj ) ] || "object" :
  		typeof obj;
  }
  /* global Symbol */
  // Defining this global in .eslintrc.json would create a danger of using the global
  // unguarded in another place, it seems safer to define global only for this module
  
  
  
  var
  	version = "3.5.1",
  
  	// Define a local copy of jQuery
  	jQuery = function( selector, context ) {
  
  		// The jQuery object is actually just the init constructor 'enhanced'
  		// Need init if jQuery is called (just allow error to be thrown if not included)
  		return new jQuery.fn.init( selector, context );
  	};
  
  jQuery.fn = jQuery.prototype = {
  
  	// The current version of jQuery being used
  	jquery: version,
  
  	constructor: jQuery,
  
  	// The default length of a jQuery object is 0
  	length: 0,
  
  	toArray: function() {
  		return slice.call( this );
  	},
  
  	// Get the Nth element in the matched element set OR
  	// Get the whole matched element set as a clean array
  	get: function( num ) {
  
  		// Return all the elements in a clean array
  		if ( num == null ) {
  			return slice.call( this );
  		}
  
  		// Return just the one element from the set
  		return num < 0 ? this[ num + this.length ] : this[ num ];
  	},
  
  	// Take an array of elements and push it onto the stack
  	// (returning the new matched element set)
  	pushStack: function( elems ) {
  
  		// Build a new jQuery matched element set
  		var ret = jQuery.merge( this.constructor(), elems );
  
  		// Add the old object onto the stack (as a reference)
  		ret.prevObject = this;
  
  		// Return the newly-formed element set
  		return ret;
  	},
  
  	// Execute a callback for every element in the matched set.
  	each: function( callback ) {
  		return jQuery.each( this, callback );
  	},
  
  	map: function( callback ) {
  		return this.pushStack( jQuery.map( this, function( elem, i ) {
  			return callback.call( elem, i, elem );
  		} ) );
  	},
  
  	slice: function() {
  		return this.pushStack( slice.apply( this, arguments ) );
  	},
  
  	first: function() {
  		return this.eq( 0 );
  	},
  
  	last: function() {
  		return this.eq( -1 );
  	},
  
  	even: function() {
  		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
  			return ( i + 1 ) % 2;
  		} ) );
  	},
  
  	odd: function() {
  		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
  			return i % 2;
  		} ) );
  	},
  
  	eq: function( i ) {
  		var len = this.length,
  			j = +i + ( i < 0 ? len : 0 );
  		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
  	},
  
  	end: function() {
  		return this.prevObject || this.constructor();
  	},
  
  	// For internal use only.
  	// Behaves like an Array's method, not like a jQuery method.
  	push: push,
  	sort: arr.sort,
  	splice: arr.splice
  };
  
  jQuery.extend = jQuery.fn.extend = function() {
  	var options, name, src, copy, copyIsArray, clone,
  		target = arguments[ 0 ] || {},
  		i = 1,
  		length = arguments.length,
  		deep = false;
  
  	// Handle a deep copy situation
  	if ( typeof target === "boolean" ) {
  		deep = target;
  
  		// Skip the boolean and the target
  		target = arguments[ i ] || {};
  		i++;
  	}
  
  	// Handle case when target is a string or something (possible in deep copy)
  	if ( typeof target !== "object" && !isFunction( target ) ) {
  		target = {};
  	}
  
  	// Extend jQuery itself if only one argument is passed
  	if ( i === length ) {
  		target = this;
  		i--;
  	}
  
  	for ( ; i < length; i++ ) {
  
  		// Only deal with non-null/undefined values
  		if ( ( options = arguments[ i ] ) != null ) {
  
  			// Extend the base object
  			for ( name in options ) {
  				copy = options[ name ];
  
  				// Prevent Object.prototype pollution
  				// Prevent never-ending loop
  				if ( name === "__proto__" || target === copy ) {
  					continue;
  				}
  
  				// Recurse if we're merging plain objects or arrays
  				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
  					( copyIsArray = Array.isArray( copy ) ) ) ) {
  					src = target[ name ];
  
  					// Ensure proper type for the source value
  					if ( copyIsArray && !Array.isArray( src ) ) {
  						clone = [];
  					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
  						clone = {};
  					} else {
  						clone = src;
  					}
  					copyIsArray = false;
  
  					// Never move original objects, clone them
  					target[ name ] = jQuery.extend( deep, clone, copy );
  
  				// Don't bring in undefined values
  				} else if ( copy !== undefined ) {
  					target[ name ] = copy;
  				}
  			}
  		}
  	}
  
  	// Return the modified object
  	return target;
  };
  
  jQuery.extend( {
  
  	// Unique for each copy of jQuery on the page
  	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
  
  	// Assume jQuery is ready without the ready module
  	isReady: true,
  
  	error: function( msg ) {
  		throw new Error( msg );
  	},
  
  	noop: function() {},
  
  	isPlainObject: function( obj ) {
  		var proto, Ctor;
  
  		// Detect obvious negatives
  		// Use toString instead of jQuery.type to catch host objects
  		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
  			return false;
  		}
  
  		proto = getProto( obj );
  
  		// Objects with no prototype (e.g., `Object.create( null )`) are plain
  		if ( !proto ) {
  			return true;
  		}
  
  		// Objects with prototype are plain iff they were constructed by a global Object function
  		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
  		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
  	},
  
  	isEmptyObject: function( obj ) {
  		var name;
  
  		for ( name in obj ) {
  			return false;
  		}
  		return true;
  	},
  
  	// Evaluates a script in a provided context; falls back to the global one
  	// if not specified.
  	globalEval: function( code, options, doc ) {
  		DOMEval( code, { nonce: options && options.nonce }, doc );
  	},
  
  	each: function( obj, callback ) {
  		var length, i = 0;
  
  		if ( isArrayLike( obj ) ) {
  			length = obj.length;
  			for ( ; i < length; i++ ) {
  				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  					break;
  				}
  			}
  		} else {
  			for ( i in obj ) {
  				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  					break;
  				}
  			}
  		}
  
  		return obj;
  	},
  
  	// results is for internal usage only
  	makeArray: function( arr, results ) {
  		var ret = results || [];
  
  		if ( arr != null ) {
  			if ( isArrayLike( Object( arr ) ) ) {
  				jQuery.merge( ret,
  					typeof arr === "string" ?
  					[ arr ] : arr
  				);
  			} else {
  				push.call( ret, arr );
  			}
  		}
  
  		return ret;
  	},
  
  	inArray: function( elem, arr, i ) {
  		return arr == null ? -1 : indexOf.call( arr, elem, i );
  	},
  
  	// Support: Android <=4.0 only, PhantomJS 1 only
  	// push.apply(_, arraylike) throws on ancient WebKit
  	merge: function( first, second ) {
  		var len = +second.length,
  			j = 0,
  			i = first.length;
  
  		for ( ; j < len; j++ ) {
  			first[ i++ ] = second[ j ];
  		}
  
  		first.length = i;
  
  		return first;
  	},
  
  	grep: function( elems, callback, invert ) {
  		var callbackInverse,
  			matches = [],
  			i = 0,
  			length = elems.length,
  			callbackExpect = !invert;
  
  		// Go through the array, only saving the items
  		// that pass the validator function
  		for ( ; i < length; i++ ) {
  			callbackInverse = !callback( elems[ i ], i );
  			if ( callbackInverse !== callbackExpect ) {
  				matches.push( elems[ i ] );
  			}
  		}
  
  		return matches;
  	},
  
  	// arg is for internal usage only
  	map: function( elems, callback, arg ) {
  		var length, value,
  			i = 0,
  			ret = [];
  
  		// Go through the array, translating each of the items to their new values
  		if ( isArrayLike( elems ) ) {
  			length = elems.length;
  			for ( ; i < length; i++ ) {
  				value = callback( elems[ i ], i, arg );
  
  				if ( value != null ) {
  					ret.push( value );
  				}
  			}
  
  		// Go through every key on the object,
  		} else {
  			for ( i in elems ) {
  				value = callback( elems[ i ], i, arg );
  
  				if ( value != null ) {
  					ret.push( value );
  				}
  			}
  		}
  
  		// Flatten any nested arrays
  		return flat( ret );
  	},
  
  	// A global GUID counter for objects
  	guid: 1,
  
  	// jQuery.support is not used in Core but other projects attach their
  	// properties to it so it needs to exist.
  	support: support
  } );
  
  if ( typeof Symbol === "function" ) {
  	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
  }
  
  // Populate the class2type map
  jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
  function( _i, name ) {
  	class2type[ "[object " + name + "]" ] = name.toLowerCase();
  } );
  
  function isArrayLike( obj ) {
  
  	// Support: real iOS 8.2 only (not reproducible in simulator)
  	// `in` check used to prevent JIT error (gh-2145)
  	// hasOwn isn't used here due to false negatives
  	// regarding Nodelist length in IE
  	var length = !!obj && "length" in obj && obj.length,
  		type = toType( obj );
  
  	if ( isFunction( obj ) || isWindow( obj ) ) {
  		return false;
  	}
  
  	return type === "array" || length === 0 ||
  		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
  }
  var Sizzle =
  /*!
   * Sizzle CSS Selector Engine v2.3.5
   * https://sizzlejs.com/
   *
   * Copyright JS Foundation and other contributors
   * Released under the MIT license
   * https://js.foundation/
   *
   * Date: 2020-03-14
   */
  ( function( window ) {
  var i,
  	support,
  	Expr,
  	getText,
  	isXML,
  	tokenize,
  	compile,
  	select,
  	outermostContext,
  	sortInput,
  	hasDuplicate,
  
  	// Local document vars
  	setDocument,
  	document,
  	docElem,
  	documentIsHTML,
  	rbuggyQSA,
  	rbuggyMatches,
  	matches,
  	contains,
  
  	// Instance-specific data
  	expando = "sizzle" + 1 * new Date(),
  	preferredDoc = window.document,
  	dirruns = 0,
  	done = 0,
  	classCache = createCache(),
  	tokenCache = createCache(),
  	compilerCache = createCache(),
  	nonnativeSelectorCache = createCache(),
  	sortOrder = function( a, b ) {
  		if ( a === b ) {
  			hasDuplicate = true;
  		}
  		return 0;
  	},
  
  	// Instance methods
  	hasOwn = ( {} ).hasOwnProperty,
  	arr = [],
  	pop = arr.pop,
  	pushNative = arr.push,
  	push = arr.push,
  	slice = arr.slice,
  
  	// Use a stripped-down indexOf as it's faster than native
  	// https://jsperf.com/thor-indexof-vs-for/5
  	indexOf = function( list, elem ) {
  		var i = 0,
  			len = list.length;
  		for ( ; i < len; i++ ) {
  			if ( list[ i ] === elem ) {
  				return i;
  			}
  		}
  		return -1;
  	},
  
  	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
  		"ismap|loop|multiple|open|readonly|required|scoped",
  
  	// Regular expressions
  
  	// http://www.w3.org/TR/css3-selectors/#whitespace
  	whitespace = "[\\x20\\t\\r\\n\\f]",
  
  	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
  	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
  		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
  
  	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
  	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
  
  		// Operator (capture 2)
  		"*([*^$|!~]?=)" + whitespace +
  
  		// "Attribute values must be CSS identifiers [capture 5]
  		// or strings [capture 3 or capture 4]"
  		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
  		whitespace + "*\\]",
  
  	pseudos = ":(" + identifier + ")(?:\\((" +
  
  		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
  		// 1. quoted (capture 3; capture 4 or capture 5)
  		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
  
  		// 2. simple (capture 6)
  		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
  
  		// 3. anything else (capture 2)
  		".*" +
  		")\\)|)",
  
  	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  	rwhitespace = new RegExp( whitespace + "+", "g" ),
  	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
  		whitespace + "+$", "g" ),
  
  	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
  		"*" ),
  	rdescend = new RegExp( whitespace + "|>" ),
  
  	rpseudo = new RegExp( pseudos ),
  	ridentifier = new RegExp( "^" + identifier + "$" ),
  
  	matchExpr = {
  		"ID": new RegExp( "^#(" + identifier + ")" ),
  		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
  		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
  		"ATTR": new RegExp( "^" + attributes ),
  		"PSEUDO": new RegExp( "^" + pseudos ),
  		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
  			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
  			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  
  		// For use in libraries implementing .is()
  		// We use this for POS matching in `select`
  		"needsContext": new RegExp( "^" + whitespace +
  			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
  			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  	},
  
  	rhtml = /HTML$/i,
  	rinputs = /^(?:input|select|textarea|button)$/i,
  	rheader = /^h\d$/i,
  
  	rnative = /^[^{]+\{\s*\[native \w/,
  
  	// Easily-parseable/retrievable ID or TAG or CLASS selectors
  	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  
  	rsibling = /[+~]/,
  
  	// CSS escapes
  	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
  	funescape = function( escape, nonHex ) {
  		var high = "0x" + escape.slice( 1 ) - 0x10000;
  
  		return nonHex ?
  
  			// Strip the backslash prefix from a non-hex escape sequence
  			nonHex :
  
  			// Replace a hexadecimal escape sequence with the encoded Unicode code point
  			// Support: IE <=11+
  			// For values outside the Basic Multilingual Plane (BMP), manually construct a
  			// surrogate pair
  			high < 0 ?
  				String.fromCharCode( high + 0x10000 ) :
  				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  	},
  
  	// CSS string/identifier serialization
  	// https://drafts.csswg.org/cssom/#common-serializing-idioms
  	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
  	fcssescape = function( ch, asCodePoint ) {
  		if ( asCodePoint ) {
  
  			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
  			if ( ch === "\0" ) {
  				return "\uFFFD";
  			}
  
  			// Control characters and (dependent upon position) numbers get escaped as code points
  			return ch.slice( 0, -1 ) + "\\" +
  				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
  		}
  
  		// Other potentially-special ASCII characters get backslash-escaped
  		return "\\" + ch;
  	},
  
  	// Used for iframes
  	// See setDocument()
  	// Removing the function wrapper causes a "Permission Denied"
  	// error in IE
  	unloadHandler = function() {
  		setDocument();
  	},
  
  	inDisabledFieldset = addCombinator(
  		function( elem ) {
  			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
  		},
  		{ dir: "parentNode", next: "legend" }
  	);
  
  // Optimize for push.apply( _, NodeList )
  try {
  	push.apply(
  		( arr = slice.call( preferredDoc.childNodes ) ),
  		preferredDoc.childNodes
  	);
  
  	// Support: Android<4.0
  	// Detect silently failing push.apply
  	// eslint-disable-next-line no-unused-expressions
  	arr[ preferredDoc.childNodes.length ].nodeType;
  } catch ( e ) {
  	push = { apply: arr.length ?
  
  		// Leverage slice if possible
  		function( target, els ) {
  			pushNative.apply( target, slice.call( els ) );
  		} :
  
  		// Support: IE<9
  		// Otherwise append directly
  		function( target, els ) {
  			var j = target.length,
  				i = 0;
  
  			// Can't trust NodeList.length
  			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
  			target.length = j - 1;
  		}
  	};
  }
  
  function Sizzle( selector, context, results, seed ) {
  	var m, i, elem, nid, match, groups, newSelector,
  		newContext = context && context.ownerDocument,
  
  		// nodeType defaults to 9, since context defaults to document
  		nodeType = context ? context.nodeType : 9;
  
  	results = results || [];
  
  	// Return early from calls with invalid selector or context
  	if ( typeof selector !== "string" || !selector ||
  		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
  
  		return results;
  	}
  
  	// Try to shortcut find operations (as opposed to filters) in HTML documents
  	if ( !seed ) {
  		setDocument( context );
  		context = context || document;
  
  		if ( documentIsHTML ) {
  
  			// If the selector is sufficiently simple, try using a "get*By*" DOM method
  			// (excepting DocumentFragment context, where the methods don't exist)
  			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
  
  				// ID selector
  				if ( ( m = match[ 1 ] ) ) {
  
  					// Document context
  					if ( nodeType === 9 ) {
  						if ( ( elem = context.getElementById( m ) ) ) {
  
  							// Support: IE, Opera, Webkit
  							// TODO: identify versions
  							// getElementById can match elements by name instead of ID
  							if ( elem.id === m ) {
  								results.push( elem );
  								return results;
  							}
  						} else {
  							return results;
  						}
  
  					// Element context
  					} else {
  
  						// Support: IE, Opera, Webkit
  						// TODO: identify versions
  						// getElementById can match elements by name instead of ID
  						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
  							contains( context, elem ) &&
  							elem.id === m ) {
  
  							results.push( elem );
  							return results;
  						}
  					}
  
  				// Type selector
  				} else if ( match[ 2 ] ) {
  					push.apply( results, context.getElementsByTagName( selector ) );
  					return results;
  
  				// Class selector
  				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
  					context.getElementsByClassName ) {
  
  					push.apply( results, context.getElementsByClassName( m ) );
  					return results;
  				}
  			}
  
  			// Take advantage of querySelectorAll
  			if ( support.qsa &&
  				!nonnativeSelectorCache[ selector + " " ] &&
  				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
  
  				// Support: IE 8 only
  				// Exclude object elements
  				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
  
  				newSelector = selector;
  				newContext = context;
  
  				// qSA considers elements outside a scoping root when evaluating child or
  				// descendant combinators, which is not what we want.
  				// In such cases, we work around the behavior by prefixing every selector in the
  				// list with an ID selector referencing the scope context.
  				// The technique has to be used as well when a leading combinator is used
  				// as such selectors are not recognized by querySelectorAll.
  				// Thanks to Andrew Dupont for this technique.
  				if ( nodeType === 1 &&
  					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
  
  					// Expand context for sibling selectors
  					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
  						context;
  
  					// We can use :scope instead of the ID hack if the browser
  					// supports it & if we're not changing the context.
  					if ( newContext !== context || !support.scope ) {
  
  						// Capture the context ID, setting it first if necessary
  						if ( ( nid = context.getAttribute( "id" ) ) ) {
  							nid = nid.replace( rcssescape, fcssescape );
  						} else {
  							context.setAttribute( "id", ( nid = expando ) );
  						}
  					}
  
  					// Prefix every selector in the list
  					groups = tokenize( selector );
  					i = groups.length;
  					while ( i-- ) {
  						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
  							toSelector( groups[ i ] );
  					}
  					newSelector = groups.join( "," );
  				}
  
  				try {
  					push.apply( results,
  						newContext.querySelectorAll( newSelector )
  					);
  					return results;
  				} catch ( qsaError ) {
  					nonnativeSelectorCache( selector, true );
  				} finally {
  					if ( nid === expando ) {
  						context.removeAttribute( "id" );
  					}
  				}
  			}
  		}
  	}
  
  	// All others
  	return select( selector.replace( rtrim, "$1" ), context, results, seed );
  }
  
  /**
   * Create key-value caches of limited size
   * @returns {function(string, object)} Returns the Object data after storing it on itself with
   *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
   *	deleting the oldest entry
   */
  function createCache() {
  	var keys = [];
  
  	function cache( key, value ) {
  
  		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  		if ( keys.push( key + " " ) > Expr.cacheLength ) {
  
  			// Only keep the most recent entries
  			delete cache[ keys.shift() ];
  		}
  		return ( cache[ key + " " ] = value );
  	}
  	return cache;
  }
  
  /**
   * Mark a function for special use by Sizzle
   * @param {Function} fn The function to mark
   */
  function markFunction( fn ) {
  	fn[ expando ] = true;
  	return fn;
  }
  
  /**
   * Support testing using an element
   * @param {Function} fn Passed the created element and returns a boolean result
   */
  function assert( fn ) {
  	var el = document.createElement( "fieldset" );
  
  	try {
  		return !!fn( el );
  	} catch ( e ) {
  		return false;
  	} finally {
  
  		// Remove from its parent by default
  		if ( el.parentNode ) {
  			el.parentNode.removeChild( el );
  		}
  
  		// release memory in IE
  		el = null;
  	}
  }
  
  /**
   * Adds the same handler for all of the specified attrs
   * @param {String} attrs Pipe-separated list of attributes
   * @param {Function} handler The method that will be applied
   */
  function addHandle( attrs, handler ) {
  	var arr = attrs.split( "|" ),
  		i = arr.length;
  
  	while ( i-- ) {
  		Expr.attrHandle[ arr[ i ] ] = handler;
  	}
  }
  
  /**
   * Checks document order of two siblings
   * @param {Element} a
   * @param {Element} b
   * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
   */
  function siblingCheck( a, b ) {
  	var cur = b && a,
  		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  			a.sourceIndex - b.sourceIndex;
  
  	// Use IE sourceIndex if available on both nodes
  	if ( diff ) {
  		return diff;
  	}
  
  	// Check if b follows a
  	if ( cur ) {
  		while ( ( cur = cur.nextSibling ) ) {
  			if ( cur === b ) {
  				return -1;
  			}
  		}
  	}
  
  	return a ? 1 : -1;
  }
  
  /**
   * Returns a function to use in pseudos for input types
   * @param {String} type
   */
  function createInputPseudo( type ) {
  	return function( elem ) {
  		var name = elem.nodeName.toLowerCase();
  		return name === "input" && elem.type === type;
  	};
  }
  
  /**
   * Returns a function to use in pseudos for buttons
   * @param {String} type
   */
  function createButtonPseudo( type ) {
  	return function( elem ) {
  		var name = elem.nodeName.toLowerCase();
  		return ( name === "input" || name === "button" ) && elem.type === type;
  	};
  }
  
  /**
   * Returns a function to use in pseudos for :enabled/:disabled
   * @param {Boolean} disabled true for :disabled; false for :enabled
   */
  function createDisabledPseudo( disabled ) {
  
  	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
  	return function( elem ) {
  
  		// Only certain elements can match :enabled or :disabled
  		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
  		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
  		if ( "form" in elem ) {
  
  			// Check for inherited disabledness on relevant non-disabled elements:
  			// * listed form-associated elements in a disabled fieldset
  			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
  			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
  			// * option elements in a disabled optgroup
  			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
  			// All such elements have a "form" property.
  			if ( elem.parentNode && elem.disabled === false ) {
  
  				// Option elements defer to a parent optgroup if present
  				if ( "label" in elem ) {
  					if ( "label" in elem.parentNode ) {
  						return elem.parentNode.disabled === disabled;
  					} else {
  						return elem.disabled === disabled;
  					}
  				}
  
  				// Support: IE 6 - 11
  				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
  				return elem.isDisabled === disabled ||
  
  					// Where there is no isDisabled, check manually
  					/* jshint -W018 */
  					elem.isDisabled !== !disabled &&
  					inDisabledFieldset( elem ) === disabled;
  			}
  
  			return elem.disabled === disabled;
  
  		// Try to winnow out elements that can't be disabled before trusting the disabled property.
  		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
  		// even exist on them, let alone have a boolean value.
  		} else if ( "label" in elem ) {
  			return elem.disabled === disabled;
  		}
  
  		// Remaining elements are neither :enabled nor :disabled
  		return false;
  	};
  }
  
  /**
   * Returns a function to use in pseudos for positionals
   * @param {Function} fn
   */
  function createPositionalPseudo( fn ) {
  	return markFunction( function( argument ) {
  		argument = +argument;
  		return markFunction( function( seed, matches ) {
  			var j,
  				matchIndexes = fn( [], seed.length, argument ),
  				i = matchIndexes.length;
  
  			// Match elements found at the specified indexes
  			while ( i-- ) {
  				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
  					seed[ j ] = !( matches[ j ] = seed[ j ] );
  				}
  			}
  		} );
  	} );
  }
  
  /**
   * Checks a node for validity as a Sizzle context
   * @param {Element|Object=} context
   * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
   */
  function testContext( context ) {
  	return context && typeof context.getElementsByTagName !== "undefined" && context;
  }
  
  // Expose support vars for convenience
  support = Sizzle.support = {};
  
  /**
   * Detects XML nodes
   * @param {Element|Object} elem An element or a document
   * @returns {Boolean} True iff elem is a non-HTML XML node
   */
  isXML = Sizzle.isXML = function( elem ) {
  	var namespace = elem.namespaceURI,
  		docElem = ( elem.ownerDocument || elem ).documentElement;
  
  	// Support: IE <=8
  	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
  	// https://bugs.jquery.com/ticket/4833
  	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
  };
  
  /**
   * Sets document-related variables once based on the current document
   * @param {Element|Object} [doc] An element or document object to use to set the document
   * @returns {Object} Returns the current document
   */
  setDocument = Sizzle.setDocument = function( node ) {
  	var hasCompare, subWindow,
  		doc = node ? node.ownerDocument || node : preferredDoc;
  
  	// Return early if doc is invalid or already selected
  	// Support: IE 11+, Edge 17 - 18+
  	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  	// two documents; shallow comparisons work.
  	// eslint-disable-next-line eqeqeq
  	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
  		return document;
  	}
  
  	// Update global variables
  	document = doc;
  	docElem = document.documentElement;
  	documentIsHTML = !isXML( document );
  
  	// Support: IE 9 - 11+, Edge 12 - 18+
  	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
  	// Support: IE 11+, Edge 17 - 18+
  	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  	// two documents; shallow comparisons work.
  	// eslint-disable-next-line eqeqeq
  	if ( preferredDoc != document &&
  		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
  
  		// Support: IE 11, Edge
  		if ( subWindow.addEventListener ) {
  			subWindow.addEventListener( "unload", unloadHandler, false );
  
  		// Support: IE 9 - 10 only
  		} else if ( subWindow.attachEvent ) {
  			subWindow.attachEvent( "onunload", unloadHandler );
  		}
  	}
  
  	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
  	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
  	// IE/Edge & older browsers don't support the :scope pseudo-class.
  	// Support: Safari 6.0 only
  	// Safari 6.0 supports :scope but it's an alias of :root there.
  	support.scope = assert( function( el ) {
  		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
  		return typeof el.querySelectorAll !== "undefined" &&
  			!el.querySelectorAll( ":scope fieldset div" ).length;
  	} );
  
  	/* Attributes
  	---------------------------------------------------------------------- */
  
  	// Support: IE<8
  	// Verify that getAttribute really returns attributes and not properties
  	// (excepting IE8 booleans)
  	support.attributes = assert( function( el ) {
  		el.className = "i";
  		return !el.getAttribute( "className" );
  	} );
  
  	/* getElement(s)By*
  	---------------------------------------------------------------------- */
  
  	// Check if getElementsByTagName("*") returns only elements
  	support.getElementsByTagName = assert( function( el ) {
  		el.appendChild( document.createComment( "" ) );
  		return !el.getElementsByTagName( "*" ).length;
  	} );
  
  	// Support: IE<9
  	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
  
  	// Support: IE<10
  	// Check if getElementById returns elements by name
  	// The broken getElementById methods don't pick up programmatically-set names,
  	// so use a roundabout getElementsByName test
  	support.getById = assert( function( el ) {
  		docElem.appendChild( el ).id = expando;
  		return !document.getElementsByName || !document.getElementsByName( expando ).length;
  	} );
  
  	// ID filter and find
  	if ( support.getById ) {
  		Expr.filter[ "ID" ] = function( id ) {
  			var attrId = id.replace( runescape, funescape );
  			return function( elem ) {
  				return elem.getAttribute( "id" ) === attrId;
  			};
  		};
  		Expr.find[ "ID" ] = function( id, context ) {
  			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  				var elem = context.getElementById( id );
  				return elem ? [ elem ] : [];
  			}
  		};
  	} else {
  		Expr.filter[ "ID" ] =  function( id ) {
  			var attrId = id.replace( runescape, funescape );
  			return function( elem ) {
  				var node = typeof elem.getAttributeNode !== "undefined" &&
  					elem.getAttributeNode( "id" );
  				return node && node.value === attrId;
  			};
  		};
  
  		// Support: IE 6 - 7 only
  		// getElementById is not reliable as a find shortcut
  		Expr.find[ "ID" ] = function( id, context ) {
  			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  				var node, i, elems,
  					elem = context.getElementById( id );
  
  				if ( elem ) {
  
  					// Verify the id attribute
  					node = elem.getAttributeNode( "id" );
  					if ( node && node.value === id ) {
  						return [ elem ];
  					}
  
  					// Fall back on getElementsByName
  					elems = context.getElementsByName( id );
  					i = 0;
  					while ( ( elem = elems[ i++ ] ) ) {
  						node = elem.getAttributeNode( "id" );
  						if ( node && node.value === id ) {
  							return [ elem ];
  						}
  					}
  				}
  
  				return [];
  			}
  		};
  	}
  
  	// Tag
  	Expr.find[ "TAG" ] = support.getElementsByTagName ?
  		function( tag, context ) {
  			if ( typeof context.getElementsByTagName !== "undefined" ) {
  				return context.getElementsByTagName( tag );
  
  			// DocumentFragment nodes don't have gEBTN
  			} else if ( support.qsa ) {
  				return context.querySelectorAll( tag );
  			}
  		} :
  
  		function( tag, context ) {
  			var elem,
  				tmp = [],
  				i = 0,
  
  				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
  				results = context.getElementsByTagName( tag );
  
  			// Filter out possible comments
  			if ( tag === "*" ) {
  				while ( ( elem = results[ i++ ] ) ) {
  					if ( elem.nodeType === 1 ) {
  						tmp.push( elem );
  					}
  				}
  
  				return tmp;
  			}
  			return results;
  		};
  
  	// Class
  	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
  		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
  			return context.getElementsByClassName( className );
  		}
  	};
  
  	/* QSA/matchesSelector
  	---------------------------------------------------------------------- */
  
  	// QSA and matchesSelector support
  
  	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  	rbuggyMatches = [];
  
  	// qSa(:focus) reports false when true (Chrome 21)
  	// We allow this because of a bug in IE8/9 that throws an error
  	// whenever `document.activeElement` is accessed on an iframe
  	// So, we allow :focus to pass through QSA all the time to avoid the IE error
  	// See https://bugs.jquery.com/ticket/13378
  	rbuggyQSA = [];
  
  	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
  
  		// Build QSA regex
  		// Regex strategy adopted from Diego Perini
  		assert( function( el ) {
  
  			var input;
  
  			// Select is set to empty string on purpose
  			// This is to test IE's treatment of not explicitly
  			// setting a boolean content attribute,
  			// since its presence should be enough
  			// https://bugs.jquery.com/ticket/12359
  			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
  				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
  				"<option selected=''></option></select>";
  
  			// Support: IE8, Opera 11-12.16
  			// Nothing should be selected when empty strings follow ^= or $= or *=
  			// The test attribute must be unknown in Opera but "safe" for WinRT
  			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
  			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
  				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  			}
  
  			// Support: IE8
  			// Boolean attributes and "value" are not treated correctly
  			if ( !el.querySelectorAll( "[selected]" ).length ) {
  				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  			}
  
  			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
  			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
  				rbuggyQSA.push( "~=" );
  			}
  
  			// Support: IE 11+, Edge 15 - 18+
  			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
  			// Adding a temporary attribute to the document before the selection works
  			// around the issue.
  			// Interestingly, IE 10 & older don't seem to have the issue.
  			input = document.createElement( "input" );
  			input.setAttribute( "name", "" );
  			el.appendChild( input );
  			if ( !el.querySelectorAll( "[name='']" ).length ) {
  				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
  					whitespace + "*(?:''|\"\")" );
  			}
  
  			// Webkit/Opera - :checked should return selected option elements
  			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  			// IE8 throws error here and will not see later tests
  			if ( !el.querySelectorAll( ":checked" ).length ) {
  				rbuggyQSA.push( ":checked" );
  			}
  
  			// Support: Safari 8+, iOS 8+
  			// https://bugs.webkit.org/show_bug.cgi?id=136851
  			// In-page `selector#id sibling-combinator selector` fails
  			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
  				rbuggyQSA.push( ".#.+[+~]" );
  			}
  
  			// Support: Firefox <=3.6 - 5 only
  			// Old Firefox doesn't throw on a badly-escaped identifier.
  			el.querySelectorAll( "\\\f" );
  			rbuggyQSA.push( "[\\r\\n\\f]" );
  		} );
  
  		assert( function( el ) {
  			el.innerHTML = "<a href='' disabled='disabled'></a>" +
  				"<select disabled='disabled'><option/></select>";
  
  			// Support: Windows 8 Native Apps
  			// The type and name attributes are restricted during .innerHTML assignment
  			var input = document.createElement( "input" );
  			input.setAttribute( "type", "hidden" );
  			el.appendChild( input ).setAttribute( "name", "D" );
  
  			// Support: IE8
  			// Enforce case-sensitivity of name attribute
  			if ( el.querySelectorAll( "[name=d]" ).length ) {
  				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
  			}
  
  			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  			// IE8 throws error here and will not see later tests
  			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
  				rbuggyQSA.push( ":enabled", ":disabled" );
  			}
  
  			// Support: IE9-11+
  			// IE's :disabled selector does not pick up the children of disabled fieldsets
  			docElem.appendChild( el ).disabled = true;
  			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
  				rbuggyQSA.push( ":enabled", ":disabled" );
  			}
  
  			// Support: Opera 10 - 11 only
  			// Opera 10-11 does not throw on post-comma invalid pseudos
  			el.querySelectorAll( "*,:x" );
  			rbuggyQSA.push( ",.*:" );
  		} );
  	}
  
  	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
  		docElem.webkitMatchesSelector ||
  		docElem.mozMatchesSelector ||
  		docElem.oMatchesSelector ||
  		docElem.msMatchesSelector ) ) ) ) {
  
  		assert( function( el ) {
  
  			// Check to see if it's possible to do matchesSelector
  			// on a disconnected node (IE 9)
  			support.disconnectedMatch = matches.call( el, "*" );
  
  			// This should fail with an exception
  			// Gecko does not error, returns false instead
  			matches.call( el, "[s!='']:x" );
  			rbuggyMatches.push( "!=", pseudos );
  		} );
  	}
  
  	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
  	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
  
  	/* Contains
  	---------------------------------------------------------------------- */
  	hasCompare = rnative.test( docElem.compareDocumentPosition );
  
  	// Element contains another
  	// Purposefully self-exclusive
  	// As in, an element does not contain itself
  	contains = hasCompare || rnative.test( docElem.contains ) ?
  		function( a, b ) {
  			var adown = a.nodeType === 9 ? a.documentElement : a,
  				bup = b && b.parentNode;
  			return a === bup || !!( bup && bup.nodeType === 1 && (
  				adown.contains ?
  					adown.contains( bup ) :
  					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  			) );
  		} :
  		function( a, b ) {
  			if ( b ) {
  				while ( ( b = b.parentNode ) ) {
  					if ( b === a ) {
  						return true;
  					}
  				}
  			}
  			return false;
  		};
  
  	/* Sorting
  	---------------------------------------------------------------------- */
  
  	// Document order sorting
  	sortOrder = hasCompare ?
  	function( a, b ) {
  
  		// Flag for duplicate removal
  		if ( a === b ) {
  			hasDuplicate = true;
  			return 0;
  		}
  
  		// Sort on method existence if only one input has compareDocumentPosition
  		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  		if ( compare ) {
  			return compare;
  		}
  
  		// Calculate position if both inputs belong to the same document
  		// Support: IE 11+, Edge 17 - 18+
  		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  		// two documents; shallow comparisons work.
  		// eslint-disable-next-line eqeqeq
  		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
  			a.compareDocumentPosition( b ) :
  
  			// Otherwise we know they are disconnected
  			1;
  
  		// Disconnected nodes
  		if ( compare & 1 ||
  			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
  
  			// Choose the first element that is related to our preferred document
  			// Support: IE 11+, Edge 17 - 18+
  			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  			// two documents; shallow comparisons work.
  			// eslint-disable-next-line eqeqeq
  			if ( a == document || a.ownerDocument == preferredDoc &&
  				contains( preferredDoc, a ) ) {
  				return -1;
  			}
  
  			// Support: IE 11+, Edge 17 - 18+
  			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  			// two documents; shallow comparisons work.
  			// eslint-disable-next-line eqeqeq
  			if ( b == document || b.ownerDocument == preferredDoc &&
  				contains( preferredDoc, b ) ) {
  				return 1;
  			}
  
  			// Maintain original order
  			return sortInput ?
  				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  				0;
  		}
  
  		return compare & 4 ? -1 : 1;
  	} :
  	function( a, b ) {
  
  		// Exit early if the nodes are identical
  		if ( a === b ) {
  			hasDuplicate = true;
  			return 0;
  		}
  
  		var cur,
  			i = 0,
  			aup = a.parentNode,
  			bup = b.parentNode,
  			ap = [ a ],
  			bp = [ b ];
  
  		// Parentless nodes are either documents or disconnected
  		if ( !aup || !bup ) {
  
  			// Support: IE 11+, Edge 17 - 18+
  			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  			// two documents; shallow comparisons work.
  			/* eslint-disable eqeqeq */
  			return a == document ? -1 :
  				b == document ? 1 :
  				/* eslint-enable eqeqeq */
  				aup ? -1 :
  				bup ? 1 :
  				sortInput ?
  				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  				0;
  
  		// If the nodes are siblings, we can do a quick check
  		} else if ( aup === bup ) {
  			return siblingCheck( a, b );
  		}
  
  		// Otherwise we need full lists of their ancestors for comparison
  		cur = a;
  		while ( ( cur = cur.parentNode ) ) {
  			ap.unshift( cur );
  		}
  		cur = b;
  		while ( ( cur = cur.parentNode ) ) {
  			bp.unshift( cur );
  		}
  
  		// Walk down the tree looking for a discrepancy
  		while ( ap[ i ] === bp[ i ] ) {
  			i++;
  		}
  
  		return i ?
  
  			// Do a sibling check if the nodes have a common ancestor
  			siblingCheck( ap[ i ], bp[ i ] ) :
  
  			// Otherwise nodes in our document sort first
  			// Support: IE 11+, Edge 17 - 18+
  			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  			// two documents; shallow comparisons work.
  			/* eslint-disable eqeqeq */
  			ap[ i ] == preferredDoc ? -1 :
  			bp[ i ] == preferredDoc ? 1 :
  			/* eslint-enable eqeqeq */
  			0;
  	};
  
  	return document;
  };
  
  Sizzle.matches = function( expr, elements ) {
  	return Sizzle( expr, null, null, elements );
  };
  
  Sizzle.matchesSelector = function( elem, expr ) {
  	setDocument( elem );
  
  	if ( support.matchesSelector && documentIsHTML &&
  		!nonnativeSelectorCache[ expr + " " ] &&
  		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
  
  		try {
  			var ret = matches.call( elem, expr );
  
  			// IE 9's matchesSelector returns false on disconnected nodes
  			if ( ret || support.disconnectedMatch ||
  
  				// As well, disconnected nodes are said to be in a document
  				// fragment in IE 9
  				elem.document && elem.document.nodeType !== 11 ) {
  				return ret;
  			}
  		} catch ( e ) {
  			nonnativeSelectorCache( expr, true );
  		}
  	}
  
  	return Sizzle( expr, document, null, [ elem ] ).length > 0;
  };
  
  Sizzle.contains = function( context, elem ) {
  
  	// Set document vars if needed
  	// Support: IE 11+, Edge 17 - 18+
  	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  	// two documents; shallow comparisons work.
  	// eslint-disable-next-line eqeqeq
  	if ( ( context.ownerDocument || context ) != document ) {
  		setDocument( context );
  	}
  	return contains( context, elem );
  };
  
  Sizzle.attr = function( elem, name ) {
  
  	// Set document vars if needed
  	// Support: IE 11+, Edge 17 - 18+
  	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  	// two documents; shallow comparisons work.
  	// eslint-disable-next-line eqeqeq
  	if ( ( elem.ownerDocument || elem ) != document ) {
  		setDocument( elem );
  	}
  
  	var fn = Expr.attrHandle[ name.toLowerCase() ],
  
  		// Don't get fooled by Object.prototype properties (jQuery #13807)
  		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  			fn( elem, name, !documentIsHTML ) :
  			undefined;
  
  	return val !== undefined ?
  		val :
  		support.attributes || !documentIsHTML ?
  			elem.getAttribute( name ) :
  			( val = elem.getAttributeNode( name ) ) && val.specified ?
  				val.value :
  				null;
  };
  
  Sizzle.escape = function( sel ) {
  	return ( sel + "" ).replace( rcssescape, fcssescape );
  };
  
  Sizzle.error = function( msg ) {
  	throw new Error( "Syntax error, unrecognized expression: " + msg );
  };
  
  /**
   * Document sorting and removing duplicates
   * @param {ArrayLike} results
   */
  Sizzle.uniqueSort = function( results ) {
  	var elem,
  		duplicates = [],
  		j = 0,
  		i = 0;
  
  	// Unless we *know* we can detect duplicates, assume their presence
  	hasDuplicate = !support.detectDuplicates;
  	sortInput = !support.sortStable && results.slice( 0 );
  	results.sort( sortOrder );
  
  	if ( hasDuplicate ) {
  		while ( ( elem = results[ i++ ] ) ) {
  			if ( elem === results[ i ] ) {
  				j = duplicates.push( i );
  			}
  		}
  		while ( j-- ) {
  			results.splice( duplicates[ j ], 1 );
  		}
  	}
  
  	// Clear input after sorting to release objects
  	// See https://github.com/jquery/sizzle/pull/225
  	sortInput = null;
  
  	return results;
  };
  
  /**
   * Utility function for retrieving the text value of an array of DOM nodes
   * @param {Array|Element} elem
   */
  getText = Sizzle.getText = function( elem ) {
  	var node,
  		ret = "",
  		i = 0,
  		nodeType = elem.nodeType;
  
  	if ( !nodeType ) {
  
  		// If no nodeType, this is expected to be an array
  		while ( ( node = elem[ i++ ] ) ) {
  
  			// Do not traverse comment nodes
  			ret += getText( node );
  		}
  	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  
  		// Use textContent for elements
  		// innerText usage removed for consistency of new lines (jQuery #11153)
  		if ( typeof elem.textContent === "string" ) {
  			return elem.textContent;
  		} else {
  
  			// Traverse its children
  			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  				ret += getText( elem );
  			}
  		}
  	} else if ( nodeType === 3 || nodeType === 4 ) {
  		return elem.nodeValue;
  	}
  
  	// Do not include comment or processing instruction nodes
  
  	return ret;
  };
  
  Expr = Sizzle.selectors = {
  
  	// Can be adjusted by the user
  	cacheLength: 50,
  
  	createPseudo: markFunction,
  
  	match: matchExpr,
  
  	attrHandle: {},
  
  	find: {},
  
  	relative: {
  		">": { dir: "parentNode", first: true },
  		" ": { dir: "parentNode" },
  		"+": { dir: "previousSibling", first: true },
  		"~": { dir: "previousSibling" }
  	},
  
  	preFilter: {
  		"ATTR": function( match ) {
  			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
  
  			// Move the given value to match[3] whether quoted or unquoted
  			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
  				match[ 5 ] || "" ).replace( runescape, funescape );
  
  			if ( match[ 2 ] === "~=" ) {
  				match[ 3 ] = " " + match[ 3 ] + " ";
  			}
  
  			return match.slice( 0, 4 );
  		},
  
  		"CHILD": function( match ) {
  
  			/* matches from matchExpr["CHILD"]
  				1 type (only|nth|...)
  				2 what (child|of-type)
  				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  				4 xn-component of xn+y argument ([+-]?\d*n|)
  				5 sign of xn-component
  				6 x of xn-component
  				7 sign of y-component
  				8 y of y-component
  			*/
  			match[ 1 ] = match[ 1 ].toLowerCase();
  
  			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
  
  				// nth-* requires argument
  				if ( !match[ 3 ] ) {
  					Sizzle.error( match[ 0 ] );
  				}
  
  				// numeric x and y parameters for Expr.filter.CHILD
  				// remember that false/true cast respectively to 0/1
  				match[ 4 ] = +( match[ 4 ] ?
  					match[ 5 ] + ( match[ 6 ] || 1 ) :
  					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
  				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
  
  				// other types prohibit arguments
  			} else if ( match[ 3 ] ) {
  				Sizzle.error( match[ 0 ] );
  			}
  
  			return match;
  		},
  
  		"PSEUDO": function( match ) {
  			var excess,
  				unquoted = !match[ 6 ] && match[ 2 ];
  
  			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
  				return null;
  			}
  
  			// Accept quoted arguments as-is
  			if ( match[ 3 ] ) {
  				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
  
  			// Strip excess characters from unquoted arguments
  			} else if ( unquoted && rpseudo.test( unquoted ) &&
  
  				// Get excess from tokenize (recursively)
  				( excess = tokenize( unquoted, true ) ) &&
  
  				// advance to the next closing parenthesis
  				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
  
  				// excess is a negative index
  				match[ 0 ] = match[ 0 ].slice( 0, excess );
  				match[ 2 ] = unquoted.slice( 0, excess );
  			}
  
  			// Return only captures needed by the pseudo filter method (type and argument)
  			return match.slice( 0, 3 );
  		}
  	},
  
  	filter: {
  
  		"TAG": function( nodeNameSelector ) {
  			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  			return nodeNameSelector === "*" ?
  				function() {
  					return true;
  				} :
  				function( elem ) {
  					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  				};
  		},
  
  		"CLASS": function( className ) {
  			var pattern = classCache[ className + " " ];
  
  			return pattern ||
  				( pattern = new RegExp( "(^|" + whitespace +
  					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
  						className, function( elem ) {
  							return pattern.test(
  								typeof elem.className === "string" && elem.className ||
  								typeof elem.getAttribute !== "undefined" &&
  									elem.getAttribute( "class" ) ||
  								""
  							);
  				} );
  		},
  
  		"ATTR": function( name, operator, check ) {
  			return function( elem ) {
  				var result = Sizzle.attr( elem, name );
  
  				if ( result == null ) {
  					return operator === "!=";
  				}
  				if ( !operator ) {
  					return true;
  				}
  
  				result += "";
  
  				/* eslint-disable max-len */
  
  				return operator === "=" ? result === check :
  					operator === "!=" ? result !== check :
  					operator === "^=" ? check && result.indexOf( check ) === 0 :
  					operator === "*=" ? check && result.indexOf( check ) > -1 :
  					operator === "$=" ? check && result.slice( -check.length ) === check :
  					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
  					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  					false;
  				/* eslint-enable max-len */
  
  			};
  		},
  
  		"CHILD": function( type, what, _argument, first, last ) {
  			var simple = type.slice( 0, 3 ) !== "nth",
  				forward = type.slice( -4 ) !== "last",
  				ofType = what === "of-type";
  
  			return first === 1 && last === 0 ?
  
  				// Shortcut for :nth-*(n)
  				function( elem ) {
  					return !!elem.parentNode;
  				} :
  
  				function( elem, _context, xml ) {
  					var cache, uniqueCache, outerCache, node, nodeIndex, start,
  						dir = simple !== forward ? "nextSibling" : "previousSibling",
  						parent = elem.parentNode,
  						name = ofType && elem.nodeName.toLowerCase(),
  						useCache = !xml && !ofType,
  						diff = false;
  
  					if ( parent ) {
  
  						// :(first|last|only)-(child|of-type)
  						if ( simple ) {
  							while ( dir ) {
  								node = elem;
  								while ( ( node = node[ dir ] ) ) {
  									if ( ofType ?
  										node.nodeName.toLowerCase() === name :
  										node.nodeType === 1 ) {
  
  										return false;
  									}
  								}
  
  								// Reverse direction for :only-* (if we haven't yet done so)
  								start = dir = type === "only" && !start && "nextSibling";
  							}
  							return true;
  						}
  
  						start = [ forward ? parent.firstChild : parent.lastChild ];
  
  						// non-xml :nth-child(...) stores cache data on `parent`
  						if ( forward && useCache ) {
  
  							// Seek `elem` from a previously-cached index
  
  							// ...in a gzip-friendly way
  							node = parent;
  							outerCache = node[ expando ] || ( node[ expando ] = {} );
  
  							// Support: IE <9 only
  							// Defend against cloned attroperties (jQuery gh-1709)
  							uniqueCache = outerCache[ node.uniqueID ] ||
  								( outerCache[ node.uniqueID ] = {} );
  
  							cache = uniqueCache[ type ] || [];
  							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  							diff = nodeIndex && cache[ 2 ];
  							node = nodeIndex && parent.childNodes[ nodeIndex ];
  
  							while ( ( node = ++nodeIndex && node && node[ dir ] ||
  
  								// Fallback to seeking `elem` from the start
  								( diff = nodeIndex = 0 ) || start.pop() ) ) {
  
  								// When found, cache indexes on `parent` and break
  								if ( node.nodeType === 1 && ++diff && node === elem ) {
  									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
  									break;
  								}
  							}
  
  						} else {
  
  							// Use previously-cached element index if available
  							if ( useCache ) {
  
  								// ...in a gzip-friendly way
  								node = elem;
  								outerCache = node[ expando ] || ( node[ expando ] = {} );
  
  								// Support: IE <9 only
  								// Defend against cloned attroperties (jQuery gh-1709)
  								uniqueCache = outerCache[ node.uniqueID ] ||
  									( outerCache[ node.uniqueID ] = {} );
  
  								cache = uniqueCache[ type ] || [];
  								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  								diff = nodeIndex;
  							}
  
  							// xml :nth-child(...)
  							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
  							if ( diff === false ) {
  
  								// Use the same loop as above to seek `elem` from the start
  								while ( ( node = ++nodeIndex && node && node[ dir ] ||
  									( diff = nodeIndex = 0 ) || start.pop() ) ) {
  
  									if ( ( ofType ?
  										node.nodeName.toLowerCase() === name :
  										node.nodeType === 1 ) &&
  										++diff ) {
  
  										// Cache the index of each encountered element
  										if ( useCache ) {
  											outerCache = node[ expando ] ||
  												( node[ expando ] = {} );
  
  											// Support: IE <9 only
  											// Defend against cloned attroperties (jQuery gh-1709)
  											uniqueCache = outerCache[ node.uniqueID ] ||
  												( outerCache[ node.uniqueID ] = {} );
  
  											uniqueCache[ type ] = [ dirruns, diff ];
  										}
  
  										if ( node === elem ) {
  											break;
  										}
  									}
  								}
  							}
  						}
  
  						// Incorporate the offset, then check against cycle size
  						diff -= last;
  						return diff === first || ( diff % first === 0 && diff / first >= 0 );
  					}
  				};
  		},
  
  		"PSEUDO": function( pseudo, argument ) {
  
  			// pseudo-class names are case-insensitive
  			// http://www.w3.org/TR/selectors/#pseudo-classes
  			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  			// Remember that setFilters inherits from pseudos
  			var args,
  				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  					Sizzle.error( "unsupported pseudo: " + pseudo );
  
  			// The user may use createPseudo to indicate that
  			// arguments are needed to create the filter function
  			// just as Sizzle does
  			if ( fn[ expando ] ) {
  				return fn( argument );
  			}
  
  			// But maintain support for old signatures
  			if ( fn.length > 1 ) {
  				args = [ pseudo, pseudo, "", argument ];
  				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  					markFunction( function( seed, matches ) {
  						var idx,
  							matched = fn( seed, argument ),
  							i = matched.length;
  						while ( i-- ) {
  							idx = indexOf( seed, matched[ i ] );
  							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
  						}
  					} ) :
  					function( elem ) {
  						return fn( elem, 0, args );
  					};
  			}
  
  			return fn;
  		}
  	},
  
  	pseudos: {
  
  		// Potentially complex pseudos
  		"not": markFunction( function( selector ) {
  
  			// Trim the selector passed to compile
  			// to avoid treating leading and trailing
  			// spaces as combinators
  			var input = [],
  				results = [],
  				matcher = compile( selector.replace( rtrim, "$1" ) );
  
  			return matcher[ expando ] ?
  				markFunction( function( seed, matches, _context, xml ) {
  					var elem,
  						unmatched = matcher( seed, null, xml, [] ),
  						i = seed.length;
  
  					// Match elements unmatched by `matcher`
  					while ( i-- ) {
  						if ( ( elem = unmatched[ i ] ) ) {
  							seed[ i ] = !( matches[ i ] = elem );
  						}
  					}
  				} ) :
  				function( elem, _context, xml ) {
  					input[ 0 ] = elem;
  					matcher( input, null, xml, results );
  
  					// Don't keep the element (issue #299)
  					input[ 0 ] = null;
  					return !results.pop();
  				};
  		} ),
  
  		"has": markFunction( function( selector ) {
  			return function( elem ) {
  				return Sizzle( selector, elem ).length > 0;
  			};
  		} ),
  
  		"contains": markFunction( function( text ) {
  			text = text.replace( runescape, funescape );
  			return function( elem ) {
  				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
  			};
  		} ),
  
  		// "Whether an element is represented by a :lang() selector
  		// is based solely on the element's language value
  		// being equal to the identifier C,
  		// or beginning with the identifier C immediately followed by "-".
  		// The matching of C against the element's language value is performed case-insensitively.
  		// The identifier C does not have to be a valid language name."
  		// http://www.w3.org/TR/selectors/#lang-pseudo
  		"lang": markFunction( function( lang ) {
  
  			// lang value must be a valid identifier
  			if ( !ridentifier.test( lang || "" ) ) {
  				Sizzle.error( "unsupported lang: " + lang );
  			}
  			lang = lang.replace( runescape, funescape ).toLowerCase();
  			return function( elem ) {
  				var elemLang;
  				do {
  					if ( ( elemLang = documentIsHTML ?
  						elem.lang :
  						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
  
  						elemLang = elemLang.toLowerCase();
  						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  					}
  				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
  				return false;
  			};
  		} ),
  
  		// Miscellaneous
  		"target": function( elem ) {
  			var hash = window.location && window.location.hash;
  			return hash && hash.slice( 1 ) === elem.id;
  		},
  
  		"root": function( elem ) {
  			return elem === docElem;
  		},
  
  		"focus": function( elem ) {
  			return elem === document.activeElement &&
  				( !document.hasFocus || document.hasFocus() ) &&
  				!!( elem.type || elem.href || ~elem.tabIndex );
  		},
  
  		// Boolean properties
  		"enabled": createDisabledPseudo( false ),
  		"disabled": createDisabledPseudo( true ),
  
  		"checked": function( elem ) {
  
  			// In CSS3, :checked should return both checked and selected elements
  			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  			var nodeName = elem.nodeName.toLowerCase();
  			return ( nodeName === "input" && !!elem.checked ) ||
  				( nodeName === "option" && !!elem.selected );
  		},
  
  		"selected": function( elem ) {
  
  			// Accessing this property makes selected-by-default
  			// options in Safari work properly
  			if ( elem.parentNode ) {
  				// eslint-disable-next-line no-unused-expressions
  				elem.parentNode.selectedIndex;
  			}
  
  			return elem.selected === true;
  		},
  
  		// Contents
  		"empty": function( elem ) {
  
  			// http://www.w3.org/TR/selectors/#empty-pseudo
  			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
  			//   but not by others (comment: 8; processing instruction: 7; etc.)
  			// nodeType < 6 works because attributes (2) do not appear as children
  			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  				if ( elem.nodeType < 6 ) {
  					return false;
  				}
  			}
  			return true;
  		},
  
  		"parent": function( elem ) {
  			return !Expr.pseudos[ "empty" ]( elem );
  		},
  
  		// Element/input types
  		"header": function( elem ) {
  			return rheader.test( elem.nodeName );
  		},
  
  		"input": function( elem ) {
  			return rinputs.test( elem.nodeName );
  		},
  
  		"button": function( elem ) {
  			var name = elem.nodeName.toLowerCase();
  			return name === "input" && elem.type === "button" || name === "button";
  		},
  
  		"text": function( elem ) {
  			var attr;
  			return elem.nodeName.toLowerCase() === "input" &&
  				elem.type === "text" &&
  
  				// Support: IE<8
  				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
  				( ( attr = elem.getAttribute( "type" ) ) == null ||
  					attr.toLowerCase() === "text" );
  		},
  
  		// Position-in-collection
  		"first": createPositionalPseudo( function() {
  			return [ 0 ];
  		} ),
  
  		"last": createPositionalPseudo( function( _matchIndexes, length ) {
  			return [ length - 1 ];
  		} ),
  
  		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
  			return [ argument < 0 ? argument + length : argument ];
  		} ),
  
  		"even": createPositionalPseudo( function( matchIndexes, length ) {
  			var i = 0;
  			for ( ; i < length; i += 2 ) {
  				matchIndexes.push( i );
  			}
  			return matchIndexes;
  		} ),
  
  		"odd": createPositionalPseudo( function( matchIndexes, length ) {
  			var i = 1;
  			for ( ; i < length; i += 2 ) {
  				matchIndexes.push( i );
  			}
  			return matchIndexes;
  		} ),
  
  		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
  			var i = argument < 0 ?
  				argument + length :
  				argument > length ?
  					length :
  					argument;
  			for ( ; --i >= 0; ) {
  				matchIndexes.push( i );
  			}
  			return matchIndexes;
  		} ),
  
  		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
  			var i = argument < 0 ? argument + length : argument;
  			for ( ; ++i < length; ) {
  				matchIndexes.push( i );
  			}
  			return matchIndexes;
  		} )
  	}
  };
  
  Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
  
  // Add button/input type pseudos
  for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  	Expr.pseudos[ i ] = createInputPseudo( i );
  }
  for ( i in { submit: true, reset: true } ) {
  	Expr.pseudos[ i ] = createButtonPseudo( i );
  }
  
  // Easy API for creating new setFilters
  function setFilters() {}
  setFilters.prototype = Expr.filters = Expr.pseudos;
  Expr.setFilters = new setFilters();
  
  tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
  	var matched, match, tokens, type,
  		soFar, groups, preFilters,
  		cached = tokenCache[ selector + " " ];
  
  	if ( cached ) {
  		return parseOnly ? 0 : cached.slice( 0 );
  	}
  
  	soFar = selector;
  	groups = [];
  	preFilters = Expr.preFilter;
  
  	while ( soFar ) {
  
  		// Comma and first run
  		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
  			if ( match ) {
  
  				// Don't consume trailing commas as valid
  				soFar = soFar.slice( match[ 0 ].length ) || soFar;
  			}
  			groups.push( ( tokens = [] ) );
  		}
  
  		matched = false;
  
  		// Combinators
  		if ( ( match = rcombinators.exec( soFar ) ) ) {
  			matched = match.shift();
  			tokens.push( {
  				value: matched,
  
  				// Cast descendant combinators to space
  				type: match[ 0 ].replace( rtrim, " " )
  			} );
  			soFar = soFar.slice( matched.length );
  		}
  
  		// Filters
  		for ( type in Expr.filter ) {
  			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
  				( match = preFilters[ type ]( match ) ) ) ) {
  				matched = match.shift();
  				tokens.push( {
  					value: matched,
  					type: type,
  					matches: match
  				} );
  				soFar = soFar.slice( matched.length );
  			}
  		}
  
  		if ( !matched ) {
  			break;
  		}
  	}
  
  	// Return the length of the invalid excess
  	// if we're just parsing
  	// Otherwise, throw an error or return tokens
  	return parseOnly ?
  		soFar.length :
  		soFar ?
  			Sizzle.error( selector ) :
  
  			// Cache the tokens
  			tokenCache( selector, groups ).slice( 0 );
  };
  
  function toSelector( tokens ) {
  	var i = 0,
  		len = tokens.length,
  		selector = "";
  	for ( ; i < len; i++ ) {
  		selector += tokens[ i ].value;
  	}
  	return selector;
  }
  
  function addCombinator( matcher, combinator, base ) {
  	var dir = combinator.dir,
  		skip = combinator.next,
  		key = skip || dir,
  		checkNonElements = base && key === "parentNode",
  		doneName = done++;
  
  	return combinator.first ?
  
  		// Check against closest ancestor/preceding element
  		function( elem, context, xml ) {
  			while ( ( elem = elem[ dir ] ) ) {
  				if ( elem.nodeType === 1 || checkNonElements ) {
  					return matcher( elem, context, xml );
  				}
  			}
  			return false;
  		} :
  
  		// Check against all ancestor/preceding elements
  		function( elem, context, xml ) {
  			var oldCache, uniqueCache, outerCache,
  				newCache = [ dirruns, doneName ];
  
  			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
  			if ( xml ) {
  				while ( ( elem = elem[ dir ] ) ) {
  					if ( elem.nodeType === 1 || checkNonElements ) {
  						if ( matcher( elem, context, xml ) ) {
  							return true;
  						}
  					}
  				}
  			} else {
  				while ( ( elem = elem[ dir ] ) ) {
  					if ( elem.nodeType === 1 || checkNonElements ) {
  						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
  
  						// Support: IE <9 only
  						// Defend against cloned attroperties (jQuery gh-1709)
  						uniqueCache = outerCache[ elem.uniqueID ] ||
  							( outerCache[ elem.uniqueID ] = {} );
  
  						if ( skip && skip === elem.nodeName.toLowerCase() ) {
  							elem = elem[ dir ] || elem;
  						} else if ( ( oldCache = uniqueCache[ key ] ) &&
  							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
  
  							// Assign to newCache so results back-propagate to previous elements
  							return ( newCache[ 2 ] = oldCache[ 2 ] );
  						} else {
  
  							// Reuse newcache so results back-propagate to previous elements
  							uniqueCache[ key ] = newCache;
  
  							// A match means we're done; a fail means we have to keep checking
  							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
  								return true;
  							}
  						}
  					}
  				}
  			}
  			return false;
  		};
  }
  
  function elementMatcher( matchers ) {
  	return matchers.length > 1 ?
  		function( elem, context, xml ) {
  			var i = matchers.length;
  			while ( i-- ) {
  				if ( !matchers[ i ]( elem, context, xml ) ) {
  					return false;
  				}
  			}
  			return true;
  		} :
  		matchers[ 0 ];
  }
  
  function multipleContexts( selector, contexts, results ) {
  	var i = 0,
  		len = contexts.length;
  	for ( ; i < len; i++ ) {
  		Sizzle( selector, contexts[ i ], results );
  	}
  	return results;
  }
  
  function condense( unmatched, map, filter, context, xml ) {
  	var elem,
  		newUnmatched = [],
  		i = 0,
  		len = unmatched.length,
  		mapped = map != null;
  
  	for ( ; i < len; i++ ) {
  		if ( ( elem = unmatched[ i ] ) ) {
  			if ( !filter || filter( elem, context, xml ) ) {
  				newUnmatched.push( elem );
  				if ( mapped ) {
  					map.push( i );
  				}
  			}
  		}
  	}
  
  	return newUnmatched;
  }
  
  function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  	if ( postFilter && !postFilter[ expando ] ) {
  		postFilter = setMatcher( postFilter );
  	}
  	if ( postFinder && !postFinder[ expando ] ) {
  		postFinder = setMatcher( postFinder, postSelector );
  	}
  	return markFunction( function( seed, results, context, xml ) {
  		var temp, i, elem,
  			preMap = [],
  			postMap = [],
  			preexisting = results.length,
  
  			// Get initial elements from seed or context
  			elems = seed || multipleContexts(
  				selector || "*",
  				context.nodeType ? [ context ] : context,
  				[]
  			),
  
  			// Prefilter to get matcher input, preserving a map for seed-results synchronization
  			matcherIn = preFilter && ( seed || !selector ) ?
  				condense( elems, preMap, preFilter, context, xml ) :
  				elems,
  
  			matcherOut = matcher ?
  
  				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  
  					// ...intermediate processing is necessary
  					[] :
  
  					// ...otherwise use results directly
  					results :
  				matcherIn;
  
  		// Find primary matches
  		if ( matcher ) {
  			matcher( matcherIn, matcherOut, context, xml );
  		}
  
  		// Apply postFilter
  		if ( postFilter ) {
  			temp = condense( matcherOut, postMap );
  			postFilter( temp, [], context, xml );
  
  			// Un-match failing elements by moving them back to matcherIn
  			i = temp.length;
  			while ( i-- ) {
  				if ( ( elem = temp[ i ] ) ) {
  					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
  				}
  			}
  		}
  
  		if ( seed ) {
  			if ( postFinder || preFilter ) {
  				if ( postFinder ) {
  
  					// Get the final matcherOut by condensing this intermediate into postFinder contexts
  					temp = [];
  					i = matcherOut.length;
  					while ( i-- ) {
  						if ( ( elem = matcherOut[ i ] ) ) {
  
  							// Restore matcherIn since elem is not yet a final match
  							temp.push( ( matcherIn[ i ] = elem ) );
  						}
  					}
  					postFinder( null, ( matcherOut = [] ), temp, xml );
  				}
  
  				// Move matched elements from seed to results to keep them synchronized
  				i = matcherOut.length;
  				while ( i-- ) {
  					if ( ( elem = matcherOut[ i ] ) &&
  						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
  
  						seed[ temp ] = !( results[ temp ] = elem );
  					}
  				}
  			}
  
  		// Add elements to results, through postFinder if defined
  		} else {
  			matcherOut = condense(
  				matcherOut === results ?
  					matcherOut.splice( preexisting, matcherOut.length ) :
  					matcherOut
  			);
  			if ( postFinder ) {
  				postFinder( null, results, matcherOut, xml );
  			} else {
  				push.apply( results, matcherOut );
  			}
  		}
  	} );
  }
  
  function matcherFromTokens( tokens ) {
  	var checkContext, matcher, j,
  		len = tokens.length,
  		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
  		implicitRelative = leadingRelative || Expr.relative[ " " ],
  		i = leadingRelative ? 1 : 0,
  
  		// The foundational matcher ensures that elements are reachable from top-level context(s)
  		matchContext = addCombinator( function( elem ) {
  			return elem === checkContext;
  		}, implicitRelative, true ),
  		matchAnyContext = addCombinator( function( elem ) {
  			return indexOf( checkContext, elem ) > -1;
  		}, implicitRelative, true ),
  		matchers = [ function( elem, context, xml ) {
  			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  				( checkContext = context ).nodeType ?
  					matchContext( elem, context, xml ) :
  					matchAnyContext( elem, context, xml ) );
  
  			// Avoid hanging onto element (issue #299)
  			checkContext = null;
  			return ret;
  		} ];
  
  	for ( ; i < len; i++ ) {
  		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
  			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
  		} else {
  			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
  
  			// Return special upon seeing a positional matcher
  			if ( matcher[ expando ] ) {
  
  				// Find the next relative operator (if any) for proper handling
  				j = ++i;
  				for ( ; j < len; j++ ) {
  					if ( Expr.relative[ tokens[ j ].type ] ) {
  						break;
  					}
  				}
  				return setMatcher(
  					i > 1 && elementMatcher( matchers ),
  					i > 1 && toSelector(
  
  					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
  					tokens
  						.slice( 0, i - 1 )
  						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
  					).replace( rtrim, "$1" ),
  					matcher,
  					i < j && matcherFromTokens( tokens.slice( i, j ) ),
  					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
  					j < len && toSelector( tokens )
  				);
  			}
  			matchers.push( matcher );
  		}
  	}
  
  	return elementMatcher( matchers );
  }
  
  function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  	var bySet = setMatchers.length > 0,
  		byElement = elementMatchers.length > 0,
  		superMatcher = function( seed, context, xml, results, outermost ) {
  			var elem, j, matcher,
  				matchedCount = 0,
  				i = "0",
  				unmatched = seed && [],
  				setMatched = [],
  				contextBackup = outermostContext,
  
  				// We must always have either seed elements or outermost context
  				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
  
  				// Use integer dirruns iff this is the outermost matcher
  				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
  				len = elems.length;
  
  			if ( outermost ) {
  
  				// Support: IE 11+, Edge 17 - 18+
  				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  				// two documents; shallow comparisons work.
  				// eslint-disable-next-line eqeqeq
  				outermostContext = context == document || context || outermost;
  			}
  
  			// Add elements passing elementMatchers directly to results
  			// Support: IE<9, Safari
  			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
  			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
  				if ( byElement && elem ) {
  					j = 0;
  
  					// Support: IE 11+, Edge 17 - 18+
  					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
  					// two documents; shallow comparisons work.
  					// eslint-disable-next-line eqeqeq
  					if ( !context && elem.ownerDocument != document ) {
  						setDocument( elem );
  						xml = !documentIsHTML;
  					}
  					while ( ( matcher = elementMatchers[ j++ ] ) ) {
  						if ( matcher( elem, context || document, xml ) ) {
  							results.push( elem );
  							break;
  						}
  					}
  					if ( outermost ) {
  						dirruns = dirrunsUnique;
  					}
  				}
  
  				// Track unmatched elements for set filters
  				if ( bySet ) {
  
  					// They will have gone through all possible matchers
  					if ( ( elem = !matcher && elem ) ) {
  						matchedCount--;
  					}
  
  					// Lengthen the array for every element, matched or not
  					if ( seed ) {
  						unmatched.push( elem );
  					}
  				}
  			}
  
  			// `i` is now the count of elements visited above, and adding it to `matchedCount`
  			// makes the latter nonnegative.
  			matchedCount += i;
  
  			// Apply set filters to unmatched elements
  			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
  			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
  			// no element matchers and no seed.
  			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
  			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
  			// numerically zero.
  			if ( bySet && i !== matchedCount ) {
  				j = 0;
  				while ( ( matcher = setMatchers[ j++ ] ) ) {
  					matcher( unmatched, setMatched, context, xml );
  				}
  
  				if ( seed ) {
  
  					// Reintegrate element matches to eliminate the need for sorting
  					if ( matchedCount > 0 ) {
  						while ( i-- ) {
  							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
  								setMatched[ i ] = pop.call( results );
  							}
  						}
  					}
  
  					// Discard index placeholder values to get only actual matches
  					setMatched = condense( setMatched );
  				}
  
  				// Add matches to results
  				push.apply( results, setMatched );
  
  				// Seedless set matches succeeding multiple successful matchers stipulate sorting
  				if ( outermost && !seed && setMatched.length > 0 &&
  					( matchedCount + setMatchers.length ) > 1 ) {
  
  					Sizzle.uniqueSort( results );
  				}
  			}
  
  			// Override manipulation of globals by nested matchers
  			if ( outermost ) {
  				dirruns = dirrunsUnique;
  				outermostContext = contextBackup;
  			}
  
  			return unmatched;
  		};
  
  	return bySet ?
  		markFunction( superMatcher ) :
  		superMatcher;
  }
  
  compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
  	var i,
  		setMatchers = [],
  		elementMatchers = [],
  		cached = compilerCache[ selector + " " ];
  
  	if ( !cached ) {
  
  		// Generate a function of recursive functions that can be used to check each element
  		if ( !match ) {
  			match = tokenize( selector );
  		}
  		i = match.length;
  		while ( i-- ) {
  			cached = matcherFromTokens( match[ i ] );
  			if ( cached[ expando ] ) {
  				setMatchers.push( cached );
  			} else {
  				elementMatchers.push( cached );
  			}
  		}
  
  		// Cache the compiled function
  		cached = compilerCache(
  			selector,
  			matcherFromGroupMatchers( elementMatchers, setMatchers )
  		);
  
  		// Save selector and tokenization
  		cached.selector = selector;
  	}
  	return cached;
  };
  
  /**
   * A low-level selection function that works with Sizzle's compiled
   *  selector functions
   * @param {String|Function} selector A selector or a pre-compiled
   *  selector function built with Sizzle.compile
   * @param {Element} context
   * @param {Array} [results]
   * @param {Array} [seed] A set of elements to match against
   */
  select = Sizzle.select = function( selector, context, results, seed ) {
  	var i, tokens, token, type, find,
  		compiled = typeof selector === "function" && selector,
  		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
  
  	results = results || [];
  
  	// Try to minimize operations if there is only one selector in the list and no seed
  	// (the latter of which guarantees us context)
  	if ( match.length === 1 ) {
  
  		// Reduce context if the leading compound selector is an ID
  		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
  		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
  			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
  
  			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
  				.replace( runescape, funescape ), context ) || [] )[ 0 ];
  			if ( !context ) {
  				return results;
  
  			// Precompiled matchers will still verify ancestry, so step up a level
  			} else if ( compiled ) {
  				context = context.parentNode;
  			}
  
  			selector = selector.slice( tokens.shift().value.length );
  		}
  
  		// Fetch a seed set for right-to-left matching
  		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
  		while ( i-- ) {
  			token = tokens[ i ];
  
  			// Abort if we hit a combinator
  			if ( Expr.relative[ ( type = token.type ) ] ) {
  				break;
  			}
  			if ( ( find = Expr.find[ type ] ) ) {
  
  				// Search, expanding context for leading sibling combinators
  				if ( ( seed = find(
  					token.matches[ 0 ].replace( runescape, funescape ),
  					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
  						context
  				) ) ) {
  
  					// If seed is empty or no tokens remain, we can return early
  					tokens.splice( i, 1 );
  					selector = seed.length && toSelector( tokens );
  					if ( !selector ) {
  						push.apply( results, seed );
  						return results;
  					}
  
  					break;
  				}
  			}
  		}
  	}
  
  	// Compile and execute a filtering function if one is not provided
  	// Provide `match` to avoid retokenization if we modified the selector above
  	( compiled || compile( selector, match ) )(
  		seed,
  		context,
  		!documentIsHTML,
  		results,
  		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
  	);
  	return results;
  };
  
  // One-time assignments
  
  // Sort stability
  support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
  
  // Support: Chrome 14-35+
  // Always assume duplicates if they aren't passed to the comparison function
  support.detectDuplicates = !!hasDuplicate;
  
  // Initialize against the default document
  setDocument();
  
  // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  // Detached nodes confoundingly follow *each other*
  support.sortDetached = assert( function( el ) {
  
  	// Should return 1, but returns 4 (following)
  	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
  } );
  
  // Support: IE<8
  // Prevent attribute/property "interpolation"
  // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  if ( !assert( function( el ) {
  	el.innerHTML = "<a href='#'></a>";
  	return el.firstChild.getAttribute( "href" ) === "#";
  } ) ) {
  	addHandle( "type|href|height|width", function( elem, name, isXML ) {
  		if ( !isXML ) {
  			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  		}
  	} );
  }
  
  // Support: IE<9
  // Use defaultValue in place of getAttribute("value")
  if ( !support.attributes || !assert( function( el ) {
  	el.innerHTML = "<input/>";
  	el.firstChild.setAttribute( "value", "" );
  	return el.firstChild.getAttribute( "value" ) === "";
  } ) ) {
  	addHandle( "value", function( elem, _name, isXML ) {
  		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  			return elem.defaultValue;
  		}
  	} );
  }
  
  // Support: IE<9
  // Use getAttributeNode to fetch booleans when getAttribute lies
  if ( !assert( function( el ) {
  	return el.getAttribute( "disabled" ) == null;
  } ) ) {
  	addHandle( booleans, function( elem, name, isXML ) {
  		var val;
  		if ( !isXML ) {
  			return elem[ name ] === true ? name.toLowerCase() :
  				( val = elem.getAttributeNode( name ) ) && val.specified ?
  					val.value :
  					null;
  		}
  	} );
  }
  
  return Sizzle;
  
  } )( window );
  
  
  
  jQuery.find = Sizzle;
  jQuery.expr = Sizzle.selectors;
  
  // Deprecated
  jQuery.expr[ ":" ] = jQuery.expr.pseudos;
  jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
  jQuery.text = Sizzle.getText;
  jQuery.isXMLDoc = Sizzle.isXML;
  jQuery.contains = Sizzle.contains;
  jQuery.escapeSelector = Sizzle.escape;
  
  
  
  
  var dir = function( elem, dir, until ) {
  	var matched = [],
  		truncate = until !== undefined;
  
  	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
  		if ( elem.nodeType === 1 ) {
  			if ( truncate && jQuery( elem ).is( until ) ) {
  				break;
  			}
  			matched.push( elem );
  		}
  	}
  	return matched;
  };
  
  
  var siblings = function( n, elem ) {
  	var matched = [];
  
  	for ( ; n; n = n.nextSibling ) {
  		if ( n.nodeType === 1 && n !== elem ) {
  			matched.push( n );
  		}
  	}
  
  	return matched;
  };
  
  
  var rneedsContext = jQuery.expr.match.needsContext;
  
  
  
  function nodeName( elem, name ) {
  
    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  
  };
  var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
  
  
  
  // Implement the identical functionality for filter and not
  function winnow( elements, qualifier, not ) {
  	if ( isFunction( qualifier ) ) {
  		return jQuery.grep( elements, function( elem, i ) {
  			return !!qualifier.call( elem, i, elem ) !== not;
  		} );
  	}
  
  	// Single element
  	if ( qualifier.nodeType ) {
  		return jQuery.grep( elements, function( elem ) {
  			return ( elem === qualifier ) !== not;
  		} );
  	}
  
  	// Arraylike of elements (jQuery, arguments, Array)
  	if ( typeof qualifier !== "string" ) {
  		return jQuery.grep( elements, function( elem ) {
  			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
  		} );
  	}
  
  	// Filtered directly for both simple and complex selectors
  	return jQuery.filter( qualifier, elements, not );
  }
  
  jQuery.filter = function( expr, elems, not ) {
  	var elem = elems[ 0 ];
  
  	if ( not ) {
  		expr = ":not(" + expr + ")";
  	}
  
  	if ( elems.length === 1 && elem.nodeType === 1 ) {
  		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
  	}
  
  	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  		return elem.nodeType === 1;
  	} ) );
  };
  
  jQuery.fn.extend( {
  	find: function( selector ) {
  		var i, ret,
  			len = this.length,
  			self = this;
  
  		if ( typeof selector !== "string" ) {
  			return this.pushStack( jQuery( selector ).filter( function() {
  				for ( i = 0; i < len; i++ ) {
  					if ( jQuery.contains( self[ i ], this ) ) {
  						return true;
  					}
  				}
  			} ) );
  		}
  
  		ret = this.pushStack( [] );
  
  		for ( i = 0; i < len; i++ ) {
  			jQuery.find( selector, self[ i ], ret );
  		}
  
  		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
  	},
  	filter: function( selector ) {
  		return this.pushStack( winnow( this, selector || [], false ) );
  	},
  	not: function( selector ) {
  		return this.pushStack( winnow( this, selector || [], true ) );
  	},
  	is: function( selector ) {
  		return !!winnow(
  			this,
  
  			// If this is a positional/relative selector, check membership in the returned set
  			// so $("p:first").is("p:last") won't return true for a doc with two "p".
  			typeof selector === "string" && rneedsContext.test( selector ) ?
  				jQuery( selector ) :
  				selector || [],
  			false
  		).length;
  	}
  } );
  
  
  // Initialize a jQuery object
  
  
  // A central reference to the root jQuery(document)
  var rootjQuery,
  
  	// A simple way to check for HTML strings
  	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  	// Strict HTML recognition (#11290: must start with <)
  	// Shortcut simple #id case for speed
  	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
  
  	init = jQuery.fn.init = function( selector, context, root ) {
  		var match, elem;
  
  		// HANDLE: $(""), $(null), $(undefined), $(false)
  		if ( !selector ) {
  			return this;
  		}
  
  		// Method init() accepts an alternate rootjQuery
  		// so migrate can support jQuery.sub (gh-2101)
  		root = root || rootjQuery;
  
  		// Handle HTML strings
  		if ( typeof selector === "string" ) {
  			if ( selector[ 0 ] === "<" &&
  				selector[ selector.length - 1 ] === ">" &&
  				selector.length >= 3 ) {
  
  				// Assume that strings that start and end with <> are HTML and skip the regex check
  				match = [ null, selector, null ];
  
  			} else {
  				match = rquickExpr.exec( selector );
  			}
  
  			// Match html or make sure no context is specified for #id
  			if ( match && ( match[ 1 ] || !context ) ) {
  
  				// HANDLE: $(html) -> $(array)
  				if ( match[ 1 ] ) {
  					context = context instanceof jQuery ? context[ 0 ] : context;
  
  					// Option to run scripts is true for back-compat
  					// Intentionally let the error be thrown if parseHTML is not present
  					jQuery.merge( this, jQuery.parseHTML(
  						match[ 1 ],
  						context && context.nodeType ? context.ownerDocument || context : document,
  						true
  					) );
  
  					// HANDLE: $(html, props)
  					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
  						for ( match in context ) {
  
  							// Properties of context are called as methods if possible
  							if ( isFunction( this[ match ] ) ) {
  								this[ match ]( context[ match ] );
  
  							// ...and otherwise set as attributes
  							} else {
  								this.attr( match, context[ match ] );
  							}
  						}
  					}
  
  					return this;
  
  				// HANDLE: $(#id)
  				} else {
  					elem = document.getElementById( match[ 2 ] );
  
  					if ( elem ) {
  
  						// Inject the element directly into the jQuery object
  						this[ 0 ] = elem;
  						this.length = 1;
  					}
  					return this;
  				}
  
  			// HANDLE: $(expr, $(...))
  			} else if ( !context || context.jquery ) {
  				return ( context || root ).find( selector );
  
  			// HANDLE: $(expr, context)
  			// (which is just equivalent to: $(context).find(expr)
  			} else {
  				return this.constructor( context ).find( selector );
  			}
  
  		// HANDLE: $(DOMElement)
  		} else if ( selector.nodeType ) {
  			this[ 0 ] = selector;
  			this.length = 1;
  			return this;
  
  		// HANDLE: $(function)
  		// Shortcut for document ready
  		} else if ( isFunction( selector ) ) {
  			return root.ready !== undefined ?
  				root.ready( selector ) :
  
  				// Execute immediately if ready is not present
  				selector( jQuery );
  		}
  
  		return jQuery.makeArray( selector, this );
  	};
  
  // Give the init function the jQuery prototype for later instantiation
  init.prototype = jQuery.fn;
  
  // Initialize central reference
  rootjQuery = jQuery( document );
  
  
  var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  
  	// Methods guaranteed to produce a unique set when starting from a unique set
  	guaranteedUnique = {
  		children: true,
  		contents: true,
  		next: true,
  		prev: true
  	};
  
  jQuery.fn.extend( {
  	has: function( target ) {
  		var targets = jQuery( target, this ),
  			l = targets.length;
  
  		return this.filter( function() {
  			var i = 0;
  			for ( ; i < l; i++ ) {
  				if ( jQuery.contains( this, targets[ i ] ) ) {
  					return true;
  				}
  			}
  		} );
  	},
  
  	closest: function( selectors, context ) {
  		var cur,
  			i = 0,
  			l = this.length,
  			matched = [],
  			targets = typeof selectors !== "string" && jQuery( selectors );
  
  		// Positional selectors never match, since there's no _selection_ context
  		if ( !rneedsContext.test( selectors ) ) {
  			for ( ; i < l; i++ ) {
  				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
  
  					// Always skip document fragments
  					if ( cur.nodeType < 11 && ( targets ?
  						targets.index( cur ) > -1 :
  
  						// Don't pass non-elements to Sizzle
  						cur.nodeType === 1 &&
  							jQuery.find.matchesSelector( cur, selectors ) ) ) {
  
  						matched.push( cur );
  						break;
  					}
  				}
  			}
  		}
  
  		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
  	},
  
  	// Determine the position of an element within the set
  	index: function( elem ) {
  
  		// No argument, return index in parent
  		if ( !elem ) {
  			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  		}
  
  		// Index in selector
  		if ( typeof elem === "string" ) {
  			return indexOf.call( jQuery( elem ), this[ 0 ] );
  		}
  
  		// Locate the position of the desired element
  		return indexOf.call( this,
  
  			// If it receives a jQuery object, the first element is used
  			elem.jquery ? elem[ 0 ] : elem
  		);
  	},
  
  	add: function( selector, context ) {
  		return this.pushStack(
  			jQuery.uniqueSort(
  				jQuery.merge( this.get(), jQuery( selector, context ) )
  			)
  		);
  	},
  
  	addBack: function( selector ) {
  		return this.add( selector == null ?
  			this.prevObject : this.prevObject.filter( selector )
  		);
  	}
  } );
  
  function sibling( cur, dir ) {
  	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
  	return cur;
  }
  
  jQuery.each( {
  	parent: function( elem ) {
  		var parent = elem.parentNode;
  		return parent && parent.nodeType !== 11 ? parent : null;
  	},
  	parents: function( elem ) {
  		return dir( elem, "parentNode" );
  	},
  	parentsUntil: function( elem, _i, until ) {
  		return dir( elem, "parentNode", until );
  	},
  	next: function( elem ) {
  		return sibling( elem, "nextSibling" );
  	},
  	prev: function( elem ) {
  		return sibling( elem, "previousSibling" );
  	},
  	nextAll: function( elem ) {
  		return dir( elem, "nextSibling" );
  	},
  	prevAll: function( elem ) {
  		return dir( elem, "previousSibling" );
  	},
  	nextUntil: function( elem, _i, until ) {
  		return dir( elem, "nextSibling", until );
  	},
  	prevUntil: function( elem, _i, until ) {
  		return dir( elem, "previousSibling", until );
  	},
  	siblings: function( elem ) {
  		return siblings( ( elem.parentNode || {} ).firstChild, elem );
  	},
  	children: function( elem ) {
  		return siblings( elem.firstChild );
  	},
  	contents: function( elem ) {
  		if ( elem.contentDocument != null &&
  
  			// Support: IE 11+
  			// <object> elements with no `data` attribute has an object
  			// `contentDocument` with a `null` prototype.
  			getProto( elem.contentDocument ) ) {
  
  			return elem.contentDocument;
  		}
  
  		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
  		// Treat the template element as a regular one in browsers that
  		// don't support it.
  		if ( nodeName( elem, "template" ) ) {
  			elem = elem.content || elem;
  		}
  
  		return jQuery.merge( [], elem.childNodes );
  	}
  }, function( name, fn ) {
  	jQuery.fn[ name ] = function( until, selector ) {
  		var matched = jQuery.map( this, fn, until );
  
  		if ( name.slice( -5 ) !== "Until" ) {
  			selector = until;
  		}
  
  		if ( selector && typeof selector === "string" ) {
  			matched = jQuery.filter( selector, matched );
  		}
  
  		if ( this.length > 1 ) {
  
  			// Remove duplicates
  			if ( !guaranteedUnique[ name ] ) {
  				jQuery.uniqueSort( matched );
  			}
  
  			// Reverse order for parents* and prev-derivatives
  			if ( rparentsprev.test( name ) ) {
  				matched.reverse();
  			}
  		}
  
  		return this.pushStack( matched );
  	};
  } );
  var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
  
  
  
  // Convert String-formatted options into Object-formatted ones
  function createOptions( options ) {
  	var object = {};
  	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
  		object[ flag ] = true;
  	} );
  	return object;
  }
  
  /*
   * Create a callback list using the following parameters:
   *
   *	options: an optional list of space-separated options that will change how
   *			the callback list behaves or a more traditional option object
   *
   * By default a callback list will act like an event callback list and can be
   * "fired" multiple times.
   *
   * Possible options:
   *
   *	once:			will ensure the callback list can only be fired once (like a Deferred)
   *
   *	memory:			will keep track of previous values and will call any callback added
   *					after the list has been fired right away with the latest "memorized"
   *					values (like a Deferred)
   *
   *	unique:			will ensure a callback can only be added once (no duplicate in the list)
   *
   *	stopOnFalse:	interrupt callings when a callback returns false
   *
   */
  jQuery.Callbacks = function( options ) {
  
  	// Convert options from String-formatted to Object-formatted if needed
  	// (we check in cache first)
  	options = typeof options === "string" ?
  		createOptions( options ) :
  		jQuery.extend( {}, options );
  
  	var // Flag to know if list is currently firing
  		firing,
  
  		// Last fire value for non-forgettable lists
  		memory,
  
  		// Flag to know if list was already fired
  		fired,
  
  		// Flag to prevent firing
  		locked,
  
  		// Actual callback list
  		list = [],
  
  		// Queue of execution data for repeatable lists
  		queue = [],
  
  		// Index of currently firing callback (modified by add/remove as needed)
  		firingIndex = -1,
  
  		// Fire callbacks
  		fire = function() {
  
  			// Enforce single-firing
  			locked = locked || options.once;
  
  			// Execute callbacks for all pending executions,
  			// respecting firingIndex overrides and runtime changes
  			fired = firing = true;
  			for ( ; queue.length; firingIndex = -1 ) {
  				memory = queue.shift();
  				while ( ++firingIndex < list.length ) {
  
  					// Run callback and check for early termination
  					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
  						options.stopOnFalse ) {
  
  						// Jump to end and forget the data so .add doesn't re-fire
  						firingIndex = list.length;
  						memory = false;
  					}
  				}
  			}
  
  			// Forget the data if we're done with it
  			if ( !options.memory ) {
  				memory = false;
  			}
  
  			firing = false;
  
  			// Clean up if we're done firing for good
  			if ( locked ) {
  
  				// Keep an empty list if we have data for future add calls
  				if ( memory ) {
  					list = [];
  
  				// Otherwise, this object is spent
  				} else {
  					list = "";
  				}
  			}
  		},
  
  		// Actual Callbacks object
  		self = {
  
  			// Add a callback or a collection of callbacks to the list
  			add: function() {
  				if ( list ) {
  
  					// If we have memory from a past run, we should fire after adding
  					if ( memory && !firing ) {
  						firingIndex = list.length - 1;
  						queue.push( memory );
  					}
  
  					( function add( args ) {
  						jQuery.each( args, function( _, arg ) {
  							if ( isFunction( arg ) ) {
  								if ( !options.unique || !self.has( arg ) ) {
  									list.push( arg );
  								}
  							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
  
  								// Inspect recursively
  								add( arg );
  							}
  						} );
  					} )( arguments );
  
  					if ( memory && !firing ) {
  						fire();
  					}
  				}
  				return this;
  			},
  
  			// Remove a callback from the list
  			remove: function() {
  				jQuery.each( arguments, function( _, arg ) {
  					var index;
  					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  						list.splice( index, 1 );
  
  						// Handle firing indexes
  						if ( index <= firingIndex ) {
  							firingIndex--;
  						}
  					}
  				} );
  				return this;
  			},
  
  			// Check if a given callback is in the list.
  			// If no argument is given, return whether or not list has callbacks attached.
  			has: function( fn ) {
  				return fn ?
  					jQuery.inArray( fn, list ) > -1 :
  					list.length > 0;
  			},
  
  			// Remove all callbacks from the list
  			empty: function() {
  				if ( list ) {
  					list = [];
  				}
  				return this;
  			},
  
  			// Disable .fire and .add
  			// Abort any current/pending executions
  			// Clear all callbacks and values
  			disable: function() {
  				locked = queue = [];
  				list = memory = "";
  				return this;
  			},
  			disabled: function() {
  				return !list;
  			},
  
  			// Disable .fire
  			// Also disable .add unless we have memory (since it would have no effect)
  			// Abort any pending executions
  			lock: function() {
  				locked = queue = [];
  				if ( !memory && !firing ) {
  					list = memory = "";
  				}
  				return this;
  			},
  			locked: function() {
  				return !!locked;
  			},
  
  			// Call all callbacks with the given context and arguments
  			fireWith: function( context, args ) {
  				if ( !locked ) {
  					args = args || [];
  					args = [ context, args.slice ? args.slice() : args ];
  					queue.push( args );
  					if ( !firing ) {
  						fire();
  					}
  				}
  				return this;
  			},
  
  			// Call all the callbacks with the given arguments
  			fire: function() {
  				self.fireWith( this, arguments );
  				return this;
  			},
  
  			// To know if the callbacks have already been called at least once
  			fired: function() {
  				return !!fired;
  			}
  		};
  
  	return self;
  };
  
  
  function Identity( v ) {
  	return v;
  }
  function Thrower( ex ) {
  	throw ex;
  }
  
  function adoptValue( value, resolve, reject, noValue ) {
  	var method;
  
  	try {
  
  		// Check for promise aspect first to privilege synchronous behavior
  		if ( value && isFunction( ( method = value.promise ) ) ) {
  			method.call( value ).done( resolve ).fail( reject );
  
  		// Other thenables
  		} else if ( value && isFunction( ( method = value.then ) ) ) {
  			method.call( value, resolve, reject );
  
  		// Other non-thenables
  		} else {
  
  			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
  			// * false: [ value ].slice( 0 ) => resolve( value )
  			// * true: [ value ].slice( 1 ) => resolve()
  			resolve.apply( undefined, [ value ].slice( noValue ) );
  		}
  
  	// For Promises/A+, convert exceptions into rejections
  	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
  	// Deferred#then to conditionally suppress rejection.
  	} catch ( value ) {
  
  		// Support: Android 4.0 only
  		// Strict mode functions invoked without .call/.apply get global-object context
  		reject.apply( undefined, [ value ] );
  	}
  }
  
  jQuery.extend( {
  
  	Deferred: function( func ) {
  		var tuples = [
  
  				// action, add listener, callbacks,
  				// ... .then handlers, argument index, [final state]
  				[ "notify", "progress", jQuery.Callbacks( "memory" ),
  					jQuery.Callbacks( "memory" ), 2 ],
  				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
  					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
  				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
  					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
  			],
  			state = "pending",
  			promise = {
  				state: function() {
  					return state;
  				},
  				always: function() {
  					deferred.done( arguments ).fail( arguments );
  					return this;
  				},
  				"catch": function( fn ) {
  					return promise.then( null, fn );
  				},
  
  				// Keep pipe for back-compat
  				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
  					var fns = arguments;
  
  					return jQuery.Deferred( function( newDefer ) {
  						jQuery.each( tuples, function( _i, tuple ) {
  
  							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
  							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
  
  							// deferred.progress(function() { bind to newDefer or newDefer.notify })
  							// deferred.done(function() { bind to newDefer or newDefer.resolve })
  							// deferred.fail(function() { bind to newDefer or newDefer.reject })
  							deferred[ tuple[ 1 ] ]( function() {
  								var returned = fn && fn.apply( this, arguments );
  								if ( returned && isFunction( returned.promise ) ) {
  									returned.promise()
  										.progress( newDefer.notify )
  										.done( newDefer.resolve )
  										.fail( newDefer.reject );
  								} else {
  									newDefer[ tuple[ 0 ] + "With" ](
  										this,
  										fn ? [ returned ] : arguments
  									);
  								}
  							} );
  						} );
  						fns = null;
  					} ).promise();
  				},
  				then: function( onFulfilled, onRejected, onProgress ) {
  					var maxDepth = 0;
  					function resolve( depth, deferred, handler, special ) {
  						return function() {
  							var that = this,
  								args = arguments,
  								mightThrow = function() {
  									var returned, then;
  
  									// Support: Promises/A+ section 2.3.3.3.3
  									// https://promisesaplus.com/#point-59
  									// Ignore double-resolution attempts
  									if ( depth < maxDepth ) {
  										return;
  									}
  
  									returned = handler.apply( that, args );
  
  									// Support: Promises/A+ section 2.3.1
  									// https://promisesaplus.com/#point-48
  									if ( returned === deferred.promise() ) {
  										throw new TypeError( "Thenable self-resolution" );
  									}
  
  									// Support: Promises/A+ sections 2.3.3.1, 3.5
  									// https://promisesaplus.com/#point-54
  									// https://promisesaplus.com/#point-75
  									// Retrieve `then` only once
  									then = returned &&
  
  										// Support: Promises/A+ section 2.3.4
  										// https://promisesaplus.com/#point-64
  										// Only check objects and functions for thenability
  										( typeof returned === "object" ||
  											typeof returned === "function" ) &&
  										returned.then;
  
  									// Handle a returned thenable
  									if ( isFunction( then ) ) {
  
  										// Special processors (notify) just wait for resolution
  										if ( special ) {
  											then.call(
  												returned,
  												resolve( maxDepth, deferred, Identity, special ),
  												resolve( maxDepth, deferred, Thrower, special )
  											);
  
  										// Normal processors (resolve) also hook into progress
  										} else {
  
  											// ...and disregard older resolution values
  											maxDepth++;
  
  											then.call(
  												returned,
  												resolve( maxDepth, deferred, Identity, special ),
  												resolve( maxDepth, deferred, Thrower, special ),
  												resolve( maxDepth, deferred, Identity,
  													deferred.notifyWith )
  											);
  										}
  
  									// Handle all other returned values
  									} else {
  
  										// Only substitute handlers pass on context
  										// and multiple values (non-spec behavior)
  										if ( handler !== Identity ) {
  											that = undefined;
  											args = [ returned ];
  										}
  
  										// Process the value(s)
  										// Default process is resolve
  										( special || deferred.resolveWith )( that, args );
  									}
  								},
  
  								// Only normal processors (resolve) catch and reject exceptions
  								process = special ?
  									mightThrow :
  									function() {
  										try {
  											mightThrow();
  										} catch ( e ) {
  
  											if ( jQuery.Deferred.exceptionHook ) {
  												jQuery.Deferred.exceptionHook( e,
  													process.stackTrace );
  											}
  
  											// Support: Promises/A+ section 2.3.3.3.4.1
  											// https://promisesaplus.com/#point-61
  											// Ignore post-resolution exceptions
  											if ( depth + 1 >= maxDepth ) {
  
  												// Only substitute handlers pass on context
  												// and multiple values (non-spec behavior)
  												if ( handler !== Thrower ) {
  													that = undefined;
  													args = [ e ];
  												}
  
  												deferred.rejectWith( that, args );
  											}
  										}
  									};
  
  							// Support: Promises/A+ section 2.3.3.3.1
  							// https://promisesaplus.com/#point-57
  							// Re-resolve promises immediately to dodge false rejection from
  							// subsequent errors
  							if ( depth ) {
  								process();
  							} else {
  
  								// Call an optional hook to record the stack, in case of exception
  								// since it's otherwise lost when execution goes async
  								if ( jQuery.Deferred.getStackHook ) {
  									process.stackTrace = jQuery.Deferred.getStackHook();
  								}
  								window.setTimeout( process );
  							}
  						};
  					}
  
  					return jQuery.Deferred( function( newDefer ) {
  
  						// progress_handlers.add( ... )
  						tuples[ 0 ][ 3 ].add(
  							resolve(
  								0,
  								newDefer,
  								isFunction( onProgress ) ?
  									onProgress :
  									Identity,
  								newDefer.notifyWith
  							)
  						);
  
  						// fulfilled_handlers.add( ... )
  						tuples[ 1 ][ 3 ].add(
  							resolve(
  								0,
  								newDefer,
  								isFunction( onFulfilled ) ?
  									onFulfilled :
  									Identity
  							)
  						);
  
  						// rejected_handlers.add( ... )
  						tuples[ 2 ][ 3 ].add(
  							resolve(
  								0,
  								newDefer,
  								isFunction( onRejected ) ?
  									onRejected :
  									Thrower
  							)
  						);
  					} ).promise();
  				},
  
  				// Get a promise for this deferred
  				// If obj is provided, the promise aspect is added to the object
  				promise: function( obj ) {
  					return obj != null ? jQuery.extend( obj, promise ) : promise;
  				}
  			},
  			deferred = {};
  
  		// Add list-specific methods
  		jQuery.each( tuples, function( i, tuple ) {
  			var list = tuple[ 2 ],
  				stateString = tuple[ 5 ];
  
  			// promise.progress = list.add
  			// promise.done = list.add
  			// promise.fail = list.add
  			promise[ tuple[ 1 ] ] = list.add;
  
  			// Handle state
  			if ( stateString ) {
  				list.add(
  					function() {
  
  						// state = "resolved" (i.e., fulfilled)
  						// state = "rejected"
  						state = stateString;
  					},
  
  					// rejected_callbacks.disable
  					// fulfilled_callbacks.disable
  					tuples[ 3 - i ][ 2 ].disable,
  
  					// rejected_handlers.disable
  					// fulfilled_handlers.disable
  					tuples[ 3 - i ][ 3 ].disable,
  
  					// progress_callbacks.lock
  					tuples[ 0 ][ 2 ].lock,
  
  					// progress_handlers.lock
  					tuples[ 0 ][ 3 ].lock
  				);
  			}
  
  			// progress_handlers.fire
  			// fulfilled_handlers.fire
  			// rejected_handlers.fire
  			list.add( tuple[ 3 ].fire );
  
  			// deferred.notify = function() { deferred.notifyWith(...) }
  			// deferred.resolve = function() { deferred.resolveWith(...) }
  			// deferred.reject = function() { deferred.rejectWith(...) }
  			deferred[ tuple[ 0 ] ] = function() {
  				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
  				return this;
  			};
  
  			// deferred.notifyWith = list.fireWith
  			// deferred.resolveWith = list.fireWith
  			// deferred.rejectWith = list.fireWith
  			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
  		} );
  
  		// Make the deferred a promise
  		promise.promise( deferred );
  
  		// Call given func if any
  		if ( func ) {
  			func.call( deferred, deferred );
  		}
  
  		// All done!
  		return deferred;
  	},
  
  	// Deferred helper
  	when: function( singleValue ) {
  		var
  
  			// count of uncompleted subordinates
  			remaining = arguments.length,
  
  			// count of unprocessed arguments
  			i = remaining,
  
  			// subordinate fulfillment data
  			resolveContexts = Array( i ),
  			resolveValues = slice.call( arguments ),
  
  			// the master Deferred
  			master = jQuery.Deferred(),
  
  			// subordinate callback factory
  			updateFunc = function( i ) {
  				return function( value ) {
  					resolveContexts[ i ] = this;
  					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
  					if ( !( --remaining ) ) {
  						master.resolveWith( resolveContexts, resolveValues );
  					}
  				};
  			};
  
  		// Single- and empty arguments are adopted like Promise.resolve
  		if ( remaining <= 1 ) {
  			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
  				!remaining );
  
  			// Use .then() to unwrap secondary thenables (cf. gh-3000)
  			if ( master.state() === "pending" ||
  				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
  
  				return master.then();
  			}
  		}
  
  		// Multiple arguments are aggregated like Promise.all array elements
  		while ( i-- ) {
  			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
  		}
  
  		return master.promise();
  	}
  } );
  
  
  // These usually indicate a programmer mistake during development,
  // warn about them ASAP rather than swallowing them by default.
  var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
  
  jQuery.Deferred.exceptionHook = function( error, stack ) {
  
  	// Support: IE 8 - 9 only
  	// Console exists when dev tools are open, which can happen at any time
  	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
  		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
  	}
  };
  
  
  
  
  jQuery.readyException = function( error ) {
  	window.setTimeout( function() {
  		throw error;
  	} );
  };
  
  
  
  
  // The deferred used on DOM ready
  var readyList = jQuery.Deferred();
  
  jQuery.fn.ready = function( fn ) {
  
  	readyList
  		.then( fn )
  
  		// Wrap jQuery.readyException in a function so that the lookup
  		// happens at the time of error handling instead of callback
  		// registration.
  		.catch( function( error ) {
  			jQuery.readyException( error );
  		} );
  
  	return this;
  };
  
  jQuery.extend( {
  
  	// Is the DOM ready to be used? Set to true once it occurs.
  	isReady: false,
  
  	// A counter to track how many items to wait for before
  	// the ready event fires. See #6781
  	readyWait: 1,
  
  	// Handle when the DOM is ready
  	ready: function( wait ) {
  
  		// Abort if there are pending holds or we're already ready
  		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  			return;
  		}
  
  		// Remember that the DOM is ready
  		jQuery.isReady = true;
  
  		// If a normal DOM Ready event fired, decrement, and wait if need be
  		if ( wait !== true && --jQuery.readyWait > 0 ) {
  			return;
  		}
  
  		// If there are functions bound, to execute
  		readyList.resolveWith( document, [ jQuery ] );
  	}
  } );
  
  jQuery.ready.then = readyList.then;
  
  // The ready event handler and self cleanup method
  function completed() {
  	document.removeEventListener( "DOMContentLoaded", completed );
  	window.removeEventListener( "load", completed );
  	jQuery.ready();
  }
  
  // Catch cases where $(document).ready() is called
  // after the browser event has already occurred.
  // Support: IE <=9 - 10 only
  // Older IE sometimes signals "interactive" too soon
  if ( document.readyState === "complete" ||
  	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
  
  	// Handle it asynchronously to allow scripts the opportunity to delay ready
  	window.setTimeout( jQuery.ready );
  
  } else {
  
  	// Use the handy event callback
  	document.addEventListener( "DOMContentLoaded", completed );
  
  	// A fallback to window.onload, that will always work
  	window.addEventListener( "load", completed );
  }
  
  
  
  
  // Multifunctional method to get and set values of a collection
  // The value/s can optionally be executed if it's a function
  var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  	var i = 0,
  		len = elems.length,
  		bulk = key == null;
  
  	// Sets many values
  	if ( toType( key ) === "object" ) {
  		chainable = true;
  		for ( i in key ) {
  			access( elems, fn, i, key[ i ], true, emptyGet, raw );
  		}
  
  	// Sets one value
  	} else if ( value !== undefined ) {
  		chainable = true;
  
  		if ( !isFunction( value ) ) {
  			raw = true;
  		}
  
  		if ( bulk ) {
  
  			// Bulk operations run against the entire set
  			if ( raw ) {
  				fn.call( elems, value );
  				fn = null;
  
  			// ...except when executing function values
  			} else {
  				bulk = fn;
  				fn = function( elem, _key, value ) {
  					return bulk.call( jQuery( elem ), value );
  				};
  			}
  		}
  
  		if ( fn ) {
  			for ( ; i < len; i++ ) {
  				fn(
  					elems[ i ], key, raw ?
  					value :
  					value.call( elems[ i ], i, fn( elems[ i ], key ) )
  				);
  			}
  		}
  	}
  
  	if ( chainable ) {
  		return elems;
  	}
  
  	// Gets
  	if ( bulk ) {
  		return fn.call( elems );
  	}
  
  	return len ? fn( elems[ 0 ], key ) : emptyGet;
  };
  
  
  // Matches dashed string for camelizing
  var rmsPrefix = /^-ms-/,
  	rdashAlpha = /-([a-z])/g;
  
  // Used by camelCase as callback to replace()
  function fcamelCase( _all, letter ) {
  	return letter.toUpperCase();
  }
  
  // Convert dashed to camelCase; used by the css and data modules
  // Support: IE <=9 - 11, Edge 12 - 15
  // Microsoft forgot to hump their vendor prefix (#9572)
  function camelCase( string ) {
  	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  }
  var acceptData = function( owner ) {
  
  	// Accepts only:
  	//  - Node
  	//    - Node.ELEMENT_NODE
  	//    - Node.DOCUMENT_NODE
  	//  - Object
  	//    - Any
  	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
  };
  
  
  
  
  function Data() {
  	this.expando = jQuery.expando + Data.uid++;
  }
  
  Data.uid = 1;
  
  Data.prototype = {
  
  	cache: function( owner ) {
  
  		// Check if the owner object already has a cache
  		var value = owner[ this.expando ];
  
  		// If not, create one
  		if ( !value ) {
  			value = {};
  
  			// We can accept data for non-element nodes in modern browsers,
  			// but we should not, see #8335.
  			// Always return an empty object.
  			if ( acceptData( owner ) ) {
  
  				// If it is a node unlikely to be stringify-ed or looped over
  				// use plain assignment
  				if ( owner.nodeType ) {
  					owner[ this.expando ] = value;
  
  				// Otherwise secure it in a non-enumerable property
  				// configurable must be true to allow the property to be
  				// deleted when data is removed
  				} else {
  					Object.defineProperty( owner, this.expando, {
  						value: value,
  						configurable: true
  					} );
  				}
  			}
  		}
  
  		return value;
  	},
  	set: function( owner, data, value ) {
  		var prop,
  			cache = this.cache( owner );
  
  		// Handle: [ owner, key, value ] args
  		// Always use camelCase key (gh-2257)
  		if ( typeof data === "string" ) {
  			cache[ camelCase( data ) ] = value;
  
  		// Handle: [ owner, { properties } ] args
  		} else {
  
  			// Copy the properties one-by-one to the cache object
  			for ( prop in data ) {
  				cache[ camelCase( prop ) ] = data[ prop ];
  			}
  		}
  		return cache;
  	},
  	get: function( owner, key ) {
  		return key === undefined ?
  			this.cache( owner ) :
  
  			// Always use camelCase key (gh-2257)
  			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
  	},
  	access: function( owner, key, value ) {
  
  		// In cases where either:
  		//
  		//   1. No key was specified
  		//   2. A string key was specified, but no value provided
  		//
  		// Take the "read" path and allow the get method to determine
  		// which value to return, respectively either:
  		//
  		//   1. The entire cache object
  		//   2. The data stored at the key
  		//
  		if ( key === undefined ||
  				( ( key && typeof key === "string" ) && value === undefined ) ) {
  
  			return this.get( owner, key );
  		}
  
  		// When the key is not a string, or both a key and value
  		// are specified, set or extend (existing objects) with either:
  		//
  		//   1. An object of properties
  		//   2. A key and value
  		//
  		this.set( owner, key, value );
  
  		// Since the "set" path can have two possible entry points
  		// return the expected data based on which path was taken[*]
  		return value !== undefined ? value : key;
  	},
  	remove: function( owner, key ) {
  		var i,
  			cache = owner[ this.expando ];
  
  		if ( cache === undefined ) {
  			return;
  		}
  
  		if ( key !== undefined ) {
  
  			// Support array or space separated string of keys
  			if ( Array.isArray( key ) ) {
  
  				// If key is an array of keys...
  				// We always set camelCase keys, so remove that.
  				key = key.map( camelCase );
  			} else {
  				key = camelCase( key );
  
  				// If a key with the spaces exists, use it.
  				// Otherwise, create an array by matching non-whitespace
  				key = key in cache ?
  					[ key ] :
  					( key.match( rnothtmlwhite ) || [] );
  			}
  
  			i = key.length;
  
  			while ( i-- ) {
  				delete cache[ key[ i ] ];
  			}
  		}
  
  		// Remove the expando if there's no more data
  		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
  
  			// Support: Chrome <=35 - 45
  			// Webkit & Blink performance suffers when deleting properties
  			// from DOM nodes, so set to undefined instead
  			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
  			if ( owner.nodeType ) {
  				owner[ this.expando ] = undefined;
  			} else {
  				delete owner[ this.expando ];
  			}
  		}
  	},
  	hasData: function( owner ) {
  		var cache = owner[ this.expando ];
  		return cache !== undefined && !jQuery.isEmptyObject( cache );
  	}
  };
  var dataPriv = new Data();
  
  var dataUser = new Data();
  
  
  
  //	Implementation Summary
  //
  //	1. Enforce API surface and semantic compatibility with 1.9.x branch
  //	2. Improve the module's maintainability by reducing the storage
  //		paths to a single mechanism.
  //	3. Use the same single mechanism to support "private" and "user" data.
  //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
  //	5. Avoid exposing implementation details on user objects (eg. expando properties)
  //	6. Provide a clear path for implementation upgrade to WeakMap in 2014
  
  var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  	rmultiDash = /[A-Z]/g;
  
  function getData( data ) {
  	if ( data === "true" ) {
  		return true;
  	}
  
  	if ( data === "false" ) {
  		return false;
  	}
  
  	if ( data === "null" ) {
  		return null;
  	}
  
  	// Only convert to a number if it doesn't change the string
  	if ( data === +data + "" ) {
  		return +data;
  	}
  
  	if ( rbrace.test( data ) ) {
  		return JSON.parse( data );
  	}
  
  	return data;
  }
  
  function dataAttr( elem, key, data ) {
  	var name;
  
  	// If nothing was found internally, try to fetch any
  	// data from the HTML5 data-* attribute
  	if ( data === undefined && elem.nodeType === 1 ) {
  		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
  		data = elem.getAttribute( name );
  
  		if ( typeof data === "string" ) {
  			try {
  				data = getData( data );
  			} catch ( e ) {}
  
  			// Make sure we set the data so it isn't changed later
  			dataUser.set( elem, key, data );
  		} else {
  			data = undefined;
  		}
  	}
  	return data;
  }
  
  jQuery.extend( {
  	hasData: function( elem ) {
  		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
  	},
  
  	data: function( elem, name, data ) {
  		return dataUser.access( elem, name, data );
  	},
  
  	removeData: function( elem, name ) {
  		dataUser.remove( elem, name );
  	},
  
  	// TODO: Now that all calls to _data and _removeData have been replaced
  	// with direct calls to dataPriv methods, these can be deprecated.
  	_data: function( elem, name, data ) {
  		return dataPriv.access( elem, name, data );
  	},
  
  	_removeData: function( elem, name ) {
  		dataPriv.remove( elem, name );
  	}
  } );
  
  jQuery.fn.extend( {
  	data: function( key, value ) {
  		var i, name, data,
  			elem = this[ 0 ],
  			attrs = elem && elem.attributes;
  
  		// Gets all values
  		if ( key === undefined ) {
  			if ( this.length ) {
  				data = dataUser.get( elem );
  
  				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
  					i = attrs.length;
  					while ( i-- ) {
  
  						// Support: IE 11 only
  						// The attrs elements can be null (#14894)
  						if ( attrs[ i ] ) {
  							name = attrs[ i ].name;
  							if ( name.indexOf( "data-" ) === 0 ) {
  								name = camelCase( name.slice( 5 ) );
  								dataAttr( elem, name, data[ name ] );
  							}
  						}
  					}
  					dataPriv.set( elem, "hasDataAttrs", true );
  				}
  			}
  
  			return data;
  		}
  
  		// Sets multiple values
  		if ( typeof key === "object" ) {
  			return this.each( function() {
  				dataUser.set( this, key );
  			} );
  		}
  
  		return access( this, function( value ) {
  			var data;
  
  			// The calling jQuery object (element matches) is not empty
  			// (and therefore has an element appears at this[ 0 ]) and the
  			// `value` parameter was not undefined. An empty jQuery object
  			// will result in `undefined` for elem = this[ 0 ] which will
  			// throw an exception if an attempt to read a data cache is made.
  			if ( elem && value === undefined ) {
  
  				// Attempt to get data from the cache
  				// The key will always be camelCased in Data
  				data = dataUser.get( elem, key );
  				if ( data !== undefined ) {
  					return data;
  				}
  
  				// Attempt to "discover" the data in
  				// HTML5 custom data-* attrs
  				data = dataAttr( elem, key );
  				if ( data !== undefined ) {
  					return data;
  				}
  
  				// We tried really hard, but the data doesn't exist.
  				return;
  			}
  
  			// Set the data...
  			this.each( function() {
  
  				// We always store the camelCased key
  				dataUser.set( this, key, value );
  			} );
  		}, null, value, arguments.length > 1, null, true );
  	},
  
  	removeData: function( key ) {
  		return this.each( function() {
  			dataUser.remove( this, key );
  		} );
  	}
  } );
  
  
  jQuery.extend( {
  	queue: function( elem, type, data ) {
  		var queue;
  
  		if ( elem ) {
  			type = ( type || "fx" ) + "queue";
  			queue = dataPriv.get( elem, type );
  
  			// Speed up dequeue by getting out quickly if this is just a lookup
  			if ( data ) {
  				if ( !queue || Array.isArray( data ) ) {
  					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
  				} else {
  					queue.push( data );
  				}
  			}
  			return queue || [];
  		}
  	},
  
  	dequeue: function( elem, type ) {
  		type = type || "fx";
  
  		var queue = jQuery.queue( elem, type ),
  			startLength = queue.length,
  			fn = queue.shift(),
  			hooks = jQuery._queueHooks( elem, type ),
  			next = function() {
  				jQuery.dequeue( elem, type );
  			};
  
  		// If the fx queue is dequeued, always remove the progress sentinel
  		if ( fn === "inprogress" ) {
  			fn = queue.shift();
  			startLength--;
  		}
  
  		if ( fn ) {
  
  			// Add a progress sentinel to prevent the fx queue from being
  			// automatically dequeued
  			if ( type === "fx" ) {
  				queue.unshift( "inprogress" );
  			}
  
  			// Clear up the last queue stop function
  			delete hooks.stop;
  			fn.call( elem, next, hooks );
  		}
  
  		if ( !startLength && hooks ) {
  			hooks.empty.fire();
  		}
  	},
  
  	// Not public - generate a queueHooks object, or return the current one
  	_queueHooks: function( elem, type ) {
  		var key = type + "queueHooks";
  		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
  			empty: jQuery.Callbacks( "once memory" ).add( function() {
  				dataPriv.remove( elem, [ type + "queue", key ] );
  			} )
  		} );
  	}
  } );
  
  jQuery.fn.extend( {
  	queue: function( type, data ) {
  		var setter = 2;
  
  		if ( typeof type !== "string" ) {
  			data = type;
  			type = "fx";
  			setter--;
  		}
  
  		if ( arguments.length < setter ) {
  			return jQuery.queue( this[ 0 ], type );
  		}
  
  		return data === undefined ?
  			this :
  			this.each( function() {
  				var queue = jQuery.queue( this, type, data );
  
  				// Ensure a hooks for this queue
  				jQuery._queueHooks( this, type );
  
  				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
  					jQuery.dequeue( this, type );
  				}
  			} );
  	},
  	dequeue: function( type ) {
  		return this.each( function() {
  			jQuery.dequeue( this, type );
  		} );
  	},
  	clearQueue: function( type ) {
  		return this.queue( type || "fx", [] );
  	},
  
  	// Get a promise resolved when queues of a certain type
  	// are emptied (fx is the type by default)
  	promise: function( type, obj ) {
  		var tmp,
  			count = 1,
  			defer = jQuery.Deferred(),
  			elements = this,
  			i = this.length,
  			resolve = function() {
  				if ( !( --count ) ) {
  					defer.resolveWith( elements, [ elements ] );
  				}
  			};
  
  		if ( typeof type !== "string" ) {
  			obj = type;
  			type = undefined;
  		}
  		type = type || "fx";
  
  		while ( i-- ) {
  			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
  			if ( tmp && tmp.empty ) {
  				count++;
  				tmp.empty.add( resolve );
  			}
  		}
  		resolve();
  		return defer.promise( obj );
  	}
  } );
  var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
  
  var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
  
  
  var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
  
  var documentElement = document.documentElement;
  
  
  
  	var isAttached = function( elem ) {
  			return jQuery.contains( elem.ownerDocument, elem );
  		},
  		composed = { composed: true };
  
  	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
  	// Check attachment across shadow DOM boundaries when possible (gh-3504)
  	// Support: iOS 10.0-10.2 only
  	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
  	// leading to errors. We need to check for `getRootNode`.
  	if ( documentElement.getRootNode ) {
  		isAttached = function( elem ) {
  			return jQuery.contains( elem.ownerDocument, elem ) ||
  				elem.getRootNode( composed ) === elem.ownerDocument;
  		};
  	}
  var isHiddenWithinTree = function( elem, el ) {
  
  		// isHiddenWithinTree might be called from jQuery#filter function;
  		// in that case, element will be second argument
  		elem = el || elem;
  
  		// Inline style trumps all
  		return elem.style.display === "none" ||
  			elem.style.display === "" &&
  
  			// Otherwise, check computed style
  			// Support: Firefox <=43 - 45
  			// Disconnected elements can have computed display: none, so first confirm that elem is
  			// in the document.
  			isAttached( elem ) &&
  
  			jQuery.css( elem, "display" ) === "none";
  	};
  
  
  
  function adjustCSS( elem, prop, valueParts, tween ) {
  	var adjusted, scale,
  		maxIterations = 20,
  		currentValue = tween ?
  			function() {
  				return tween.cur();
  			} :
  			function() {
  				return jQuery.css( elem, prop, "" );
  			},
  		initial = currentValue(),
  		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  
  		// Starting value computation is required for potential unit mismatches
  		initialInUnit = elem.nodeType &&
  			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
  			rcssNum.exec( jQuery.css( elem, prop ) );
  
  	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
  
  		// Support: Firefox <=54
  		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
  		initial = initial / 2;
  
  		// Trust units reported by jQuery.css
  		unit = unit || initialInUnit[ 3 ];
  
  		// Iteratively approximate from a nonzero starting point
  		initialInUnit = +initial || 1;
  
  		while ( maxIterations-- ) {
  
  			// Evaluate and update our best guess (doubling guesses that zero out).
  			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
  			jQuery.style( elem, prop, initialInUnit + unit );
  			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
  				maxIterations = 0;
  			}
  			initialInUnit = initialInUnit / scale;
  
  		}
  
  		initialInUnit = initialInUnit * 2;
  		jQuery.style( elem, prop, initialInUnit + unit );
  
  		// Make sure we update the tween properties later on
  		valueParts = valueParts || [];
  	}
  
  	if ( valueParts ) {
  		initialInUnit = +initialInUnit || +initial || 0;
  
  		// Apply relative offset (+=/-=) if specified
  		adjusted = valueParts[ 1 ] ?
  			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
  			+valueParts[ 2 ];
  		if ( tween ) {
  			tween.unit = unit;
  			tween.start = initialInUnit;
  			tween.end = adjusted;
  		}
  	}
  	return adjusted;
  }
  
  
  var defaultDisplayMap = {};
  
  function getDefaultDisplay( elem ) {
  	var temp,
  		doc = elem.ownerDocument,
  		nodeName = elem.nodeName,
  		display = defaultDisplayMap[ nodeName ];
  
  	if ( display ) {
  		return display;
  	}
  
  	temp = doc.body.appendChild( doc.createElement( nodeName ) );
  	display = jQuery.css( temp, "display" );
  
  	temp.parentNode.removeChild( temp );
  
  	if ( display === "none" ) {
  		display = "block";
  	}
  	defaultDisplayMap[ nodeName ] = display;
  
  	return display;
  }
  
  function showHide( elements, show ) {
  	var display, elem,
  		values = [],
  		index = 0,
  		length = elements.length;
  
  	// Determine new display value for elements that need to change
  	for ( ; index < length; index++ ) {
  		elem = elements[ index ];
  		if ( !elem.style ) {
  			continue;
  		}
  
  		display = elem.style.display;
  		if ( show ) {
  
  			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
  			// check is required in this first loop unless we have a nonempty display value (either
  			// inline or about-to-be-restored)
  			if ( display === "none" ) {
  				values[ index ] = dataPriv.get( elem, "display" ) || null;
  				if ( !values[ index ] ) {
  					elem.style.display = "";
  				}
  			}
  			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
  				values[ index ] = getDefaultDisplay( elem );
  			}
  		} else {
  			if ( display !== "none" ) {
  				values[ index ] = "none";
  
  				// Remember what we're overwriting
  				dataPriv.set( elem, "display", display );
  			}
  		}
  	}
  
  	// Set the display of the elements in a second loop to avoid constant reflow
  	for ( index = 0; index < length; index++ ) {
  		if ( values[ index ] != null ) {
  			elements[ index ].style.display = values[ index ];
  		}
  	}
  
  	return elements;
  }
  
  jQuery.fn.extend( {
  	show: function() {
  		return showHide( this, true );
  	},
  	hide: function() {
  		return showHide( this );
  	},
  	toggle: function( state ) {
  		if ( typeof state === "boolean" ) {
  			return state ? this.show() : this.hide();
  		}
  
  		return this.each( function() {
  			if ( isHiddenWithinTree( this ) ) {
  				jQuery( this ).show();
  			} else {
  				jQuery( this ).hide();
  			}
  		} );
  	}
  } );
  var rcheckableType = ( /^(?:checkbox|radio)$/i );
  
  var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
  
  var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
  
  
  
  ( function() {
  	var fragment = document.createDocumentFragment(),
  		div = fragment.appendChild( document.createElement( "div" ) ),
  		input = document.createElement( "input" );
  
  	// Support: Android 4.0 - 4.3 only
  	// Check state lost if the name is set (#11217)
  	// Support: Windows Web Apps (WWA)
  	// `name` and `type` must use .setAttribute for WWA (#14901)
  	input.setAttribute( "type", "radio" );
  	input.setAttribute( "checked", "checked" );
  	input.setAttribute( "name", "t" );
  
  	div.appendChild( input );
  
  	// Support: Android <=4.1 only
  	// Older WebKit doesn't clone checked state correctly in fragments
  	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
  
  	// Support: IE <=11 only
  	// Make sure textarea (and checkbox) defaultValue is properly cloned
  	div.innerHTML = "<textarea>x</textarea>";
  	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
  
  	// Support: IE <=9 only
  	// IE <=9 replaces <option> tags with their contents when inserted outside of
  	// the select element.
  	div.innerHTML = "<option></option>";
  	support.option = !!div.lastChild;
  } )();
  
  
  // We have to close these tags to support XHTML (#13200)
  var wrapMap = {
  
  	// XHTML parsers do not magically insert elements in the
  	// same way that tag soup parsers do. So we cannot shorten
  	// this by omitting <tbody> or other required elements.
  	thead: [ 1, "<table>", "</table>" ],
  	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
  	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  
  	_default: [ 0, "", "" ]
  };
  
  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  wrapMap.th = wrapMap.td;
  
  // Support: IE <=9 only
  if ( !support.option ) {
  	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
  }
  
  
  function getAll( context, tag ) {
  
  	// Support: IE <=9 - 11 only
  	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
  	var ret;
  
  	if ( typeof context.getElementsByTagName !== "undefined" ) {
  		ret = context.getElementsByTagName( tag || "*" );
  
  	} else if ( typeof context.querySelectorAll !== "undefined" ) {
  		ret = context.querySelectorAll( tag || "*" );
  
  	} else {
  		ret = [];
  	}
  
  	if ( tag === undefined || tag && nodeName( context, tag ) ) {
  		return jQuery.merge( [ context ], ret );
  	}
  
  	return ret;
  }
  
  
  // Mark scripts as having already been evaluated
  function setGlobalEval( elems, refElements ) {
  	var i = 0,
  		l = elems.length;
  
  	for ( ; i < l; i++ ) {
  		dataPriv.set(
  			elems[ i ],
  			"globalEval",
  			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
  		);
  	}
  }
  
  
  var rhtml = /<|&#?\w+;/;
  
  function buildFragment( elems, context, scripts, selection, ignored ) {
  	var elem, tmp, tag, wrap, attached, j,
  		fragment = context.createDocumentFragment(),
  		nodes = [],
  		i = 0,
  		l = elems.length;
  
  	for ( ; i < l; i++ ) {
  		elem = elems[ i ];
  
  		if ( elem || elem === 0 ) {
  
  			// Add nodes directly
  			if ( toType( elem ) === "object" ) {
  
  				// Support: Android <=4.0 only, PhantomJS 1 only
  				// push.apply(_, arraylike) throws on ancient WebKit
  				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  
  			// Convert non-html into a text node
  			} else if ( !rhtml.test( elem ) ) {
  				nodes.push( context.createTextNode( elem ) );
  
  			// Convert html into DOM nodes
  			} else {
  				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
  
  				// Deserialize a standard representation
  				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
  				wrap = wrapMap[ tag ] || wrapMap._default;
  				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
  
  				// Descend through wrappers to the right content
  				j = wrap[ 0 ];
  				while ( j-- ) {
  					tmp = tmp.lastChild;
  				}
  
  				// Support: Android <=4.0 only, PhantomJS 1 only
  				// push.apply(_, arraylike) throws on ancient WebKit
  				jQuery.merge( nodes, tmp.childNodes );
  
  				// Remember the top-level container
  				tmp = fragment.firstChild;
  
  				// Ensure the created nodes are orphaned (#12392)
  				tmp.textContent = "";
  			}
  		}
  	}
  
  	// Remove wrapper from fragment
  	fragment.textContent = "";
  
  	i = 0;
  	while ( ( elem = nodes[ i++ ] ) ) {
  
  		// Skip elements already in the context collection (trac-4087)
  		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
  			if ( ignored ) {
  				ignored.push( elem );
  			}
  			continue;
  		}
  
  		attached = isAttached( elem );
  
  		// Append to fragment
  		tmp = getAll( fragment.appendChild( elem ), "script" );
  
  		// Preserve script evaluation history
  		if ( attached ) {
  			setGlobalEval( tmp );
  		}
  
  		// Capture executables
  		if ( scripts ) {
  			j = 0;
  			while ( ( elem = tmp[ j++ ] ) ) {
  				if ( rscriptType.test( elem.type || "" ) ) {
  					scripts.push( elem );
  				}
  			}
  		}
  	}
  
  	return fragment;
  }
  
  
  var
  	rkeyEvent = /^key/,
  	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
  	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
  
  function returnTrue() {
  	return true;
  }
  
  function returnFalse() {
  	return false;
  }
  
  // Support: IE <=9 - 11+
  // focus() and blur() are asynchronous, except when they are no-op.
  // So expect focus to be synchronous when the element is already active,
  // and blur to be synchronous when the element is not already active.
  // (focus and blur are always synchronous in other supported browsers,
  // this just defines when we can count on it).
  function expectSync( elem, type ) {
  	return ( elem === safeActiveElement() ) === ( type === "focus" );
  }
  
  // Support: IE <=9 only
  // Accessing document.activeElement can throw unexpectedly
  // https://bugs.jquery.com/ticket/13393
  function safeActiveElement() {
  	try {
  		return document.activeElement;
  	} catch ( err ) { }
  }
  
  function on( elem, types, selector, data, fn, one ) {
  	var origFn, type;
  
  	// Types can be a map of types/handlers
  	if ( typeof types === "object" ) {
  
  		// ( types-Object, selector, data )
  		if ( typeof selector !== "string" ) {
  
  			// ( types-Object, data )
  			data = data || selector;
  			selector = undefined;
  		}
  		for ( type in types ) {
  			on( elem, type, selector, data, types[ type ], one );
  		}
  		return elem;
  	}
  
  	if ( data == null && fn == null ) {
  
  		// ( types, fn )
  		fn = selector;
  		data = selector = undefined;
  	} else if ( fn == null ) {
  		if ( typeof selector === "string" ) {
  
  			// ( types, selector, fn )
  			fn = data;
  			data = undefined;
  		} else {
  
  			// ( types, data, fn )
  			fn = data;
  			data = selector;
  			selector = undefined;
  		}
  	}
  	if ( fn === false ) {
  		fn = returnFalse;
  	} else if ( !fn ) {
  		return elem;
  	}
  
  	if ( one === 1 ) {
  		origFn = fn;
  		fn = function( event ) {
  
  			// Can use an empty set, since event contains the info
  			jQuery().off( event );
  			return origFn.apply( this, arguments );
  		};
  
  		// Use same guid so caller can remove using origFn
  		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  	}
  	return elem.each( function() {
  		jQuery.event.add( this, types, fn, data, selector );
  	} );
  }
  
  /*
   * Helper functions for managing events -- not part of the public interface.
   * Props to Dean Edwards' addEvent library for many of the ideas.
   */
  jQuery.event = {
  
  	global: {},
  
  	add: function( elem, types, handler, data, selector ) {
  
  		var handleObjIn, eventHandle, tmp,
  			events, t, handleObj,
  			special, handlers, type, namespaces, origType,
  			elemData = dataPriv.get( elem );
  
  		// Only attach events to objects that accept data
  		if ( !acceptData( elem ) ) {
  			return;
  		}
  
  		// Caller can pass in an object of custom data in lieu of the handler
  		if ( handler.handler ) {
  			handleObjIn = handler;
  			handler = handleObjIn.handler;
  			selector = handleObjIn.selector;
  		}
  
  		// Ensure that invalid selectors throw exceptions at attach time
  		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
  		if ( selector ) {
  			jQuery.find.matchesSelector( documentElement, selector );
  		}
  
  		// Make sure that the handler has a unique ID, used to find/remove it later
  		if ( !handler.guid ) {
  			handler.guid = jQuery.guid++;
  		}
  
  		// Init the element's event structure and main handler, if this is the first
  		if ( !( events = elemData.events ) ) {
  			events = elemData.events = Object.create( null );
  		}
  		if ( !( eventHandle = elemData.handle ) ) {
  			eventHandle = elemData.handle = function( e ) {
  
  				// Discard the second event of a jQuery.event.trigger() and
  				// when an event is called after a page has unloaded
  				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
  					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
  			};
  		}
  
  		// Handle multiple events separated by a space
  		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
  		t = types.length;
  		while ( t-- ) {
  			tmp = rtypenamespace.exec( types[ t ] ) || [];
  			type = origType = tmp[ 1 ];
  			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  
  			// There *must* be a type, no attaching namespace-only handlers
  			if ( !type ) {
  				continue;
  			}
  
  			// If event changes its type, use the special event handlers for the changed type
  			special = jQuery.event.special[ type ] || {};
  
  			// If selector defined, determine special event api type, otherwise given type
  			type = ( selector ? special.delegateType : special.bindType ) || type;
  
  			// Update special based on newly reset type
  			special = jQuery.event.special[ type ] || {};
  
  			// handleObj is passed to all event handlers
  			handleObj = jQuery.extend( {
  				type: type,
  				origType: origType,
  				data: data,
  				handler: handler,
  				guid: handler.guid,
  				selector: selector,
  				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  				namespace: namespaces.join( "." )
  			}, handleObjIn );
  
  			// Init the event handler queue if we're the first
  			if ( !( handlers = events[ type ] ) ) {
  				handlers = events[ type ] = [];
  				handlers.delegateCount = 0;
  
  				// Only use addEventListener if the special events handler returns false
  				if ( !special.setup ||
  					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  
  					if ( elem.addEventListener ) {
  						elem.addEventListener( type, eventHandle );
  					}
  				}
  			}
  
  			if ( special.add ) {
  				special.add.call( elem, handleObj );
  
  				if ( !handleObj.handler.guid ) {
  					handleObj.handler.guid = handler.guid;
  				}
  			}
  
  			// Add to the element's handler list, delegates in front
  			if ( selector ) {
  				handlers.splice( handlers.delegateCount++, 0, handleObj );
  			} else {
  				handlers.push( handleObj );
  			}
  
  			// Keep track of which events have ever been used, for event optimization
  			jQuery.event.global[ type ] = true;
  		}
  
  	},
  
  	// Detach an event or set of events from an element
  	remove: function( elem, types, handler, selector, mappedTypes ) {
  
  		var j, origCount, tmp,
  			events, t, handleObj,
  			special, handlers, type, namespaces, origType,
  			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
  
  		if ( !elemData || !( events = elemData.events ) ) {
  			return;
  		}
  
  		// Once for each type.namespace in types; type may be omitted
  		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
  		t = types.length;
  		while ( t-- ) {
  			tmp = rtypenamespace.exec( types[ t ] ) || [];
  			type = origType = tmp[ 1 ];
  			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  
  			// Unbind all events (on this namespace, if provided) for the element
  			if ( !type ) {
  				for ( type in events ) {
  					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  				}
  				continue;
  			}
  
  			special = jQuery.event.special[ type ] || {};
  			type = ( selector ? special.delegateType : special.bindType ) || type;
  			handlers = events[ type ] || [];
  			tmp = tmp[ 2 ] &&
  				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
  
  			// Remove matching events
  			origCount = j = handlers.length;
  			while ( j-- ) {
  				handleObj = handlers[ j ];
  
  				if ( ( mappedTypes || origType === handleObj.origType ) &&
  					( !handler || handler.guid === handleObj.guid ) &&
  					( !tmp || tmp.test( handleObj.namespace ) ) &&
  					( !selector || selector === handleObj.selector ||
  						selector === "**" && handleObj.selector ) ) {
  					handlers.splice( j, 1 );
  
  					if ( handleObj.selector ) {
  						handlers.delegateCount--;
  					}
  					if ( special.remove ) {
  						special.remove.call( elem, handleObj );
  					}
  				}
  			}
  
  			// Remove generic event handler if we removed something and no more handlers exist
  			// (avoids potential for endless recursion during removal of special event handlers)
  			if ( origCount && !handlers.length ) {
  				if ( !special.teardown ||
  					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  
  					jQuery.removeEvent( elem, type, elemData.handle );
  				}
  
  				delete events[ type ];
  			}
  		}
  
  		// Remove data and the expando if it's no longer used
  		if ( jQuery.isEmptyObject( events ) ) {
  			dataPriv.remove( elem, "handle events" );
  		}
  	},
  
  	dispatch: function( nativeEvent ) {
  
  		var i, j, ret, matched, handleObj, handlerQueue,
  			args = new Array( arguments.length ),
  
  			// Make a writable jQuery.Event from the native event object
  			event = jQuery.event.fix( nativeEvent ),
  
  			handlers = (
  					dataPriv.get( this, "events" ) || Object.create( null )
  				)[ event.type ] || [],
  			special = jQuery.event.special[ event.type ] || {};
  
  		// Use the fix-ed jQuery.Event rather than the (read-only) native event
  		args[ 0 ] = event;
  
  		for ( i = 1; i < arguments.length; i++ ) {
  			args[ i ] = arguments[ i ];
  		}
  
  		event.delegateTarget = this;
  
  		// Call the preDispatch hook for the mapped type, and let it bail if desired
  		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  			return;
  		}
  
  		// Determine handlers
  		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  
  		// Run delegates first; they may want to stop propagation beneath us
  		i = 0;
  		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
  			event.currentTarget = matched.elem;
  
  			j = 0;
  			while ( ( handleObj = matched.handlers[ j++ ] ) &&
  				!event.isImmediatePropagationStopped() ) {
  
  				// If the event is namespaced, then each handler is only invoked if it is
  				// specially universal or its namespaces are a superset of the event's.
  				if ( !event.rnamespace || handleObj.namespace === false ||
  					event.rnamespace.test( handleObj.namespace ) ) {
  
  					event.handleObj = handleObj;
  					event.data = handleObj.data;
  
  					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
  						handleObj.handler ).apply( matched.elem, args );
  
  					if ( ret !== undefined ) {
  						if ( ( event.result = ret ) === false ) {
  							event.preventDefault();
  							event.stopPropagation();
  						}
  					}
  				}
  			}
  		}
  
  		// Call the postDispatch hook for the mapped type
  		if ( special.postDispatch ) {
  			special.postDispatch.call( this, event );
  		}
  
  		return event.result;
  	},
  
  	handlers: function( event, handlers ) {
  		var i, handleObj, sel, matchedHandlers, matchedSelectors,
  			handlerQueue = [],
  			delegateCount = handlers.delegateCount,
  			cur = event.target;
  
  		// Find delegate handlers
  		if ( delegateCount &&
  
  			// Support: IE <=9
  			// Black-hole SVG <use> instance trees (trac-13180)
  			cur.nodeType &&
  
  			// Support: Firefox <=42
  			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
  			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
  			// Support: IE 11 only
  			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
  			!( event.type === "click" && event.button >= 1 ) ) {
  
  			for ( ; cur !== this; cur = cur.parentNode || this ) {
  
  				// Don't check non-elements (#13208)
  				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
  					matchedHandlers = [];
  					matchedSelectors = {};
  					for ( i = 0; i < delegateCount; i++ ) {
  						handleObj = handlers[ i ];
  
  						// Don't conflict with Object.prototype properties (#13203)
  						sel = handleObj.selector + " ";
  
  						if ( matchedSelectors[ sel ] === undefined ) {
  							matchedSelectors[ sel ] = handleObj.needsContext ?
  								jQuery( sel, this ).index( cur ) > -1 :
  								jQuery.find( sel, this, null, [ cur ] ).length;
  						}
  						if ( matchedSelectors[ sel ] ) {
  							matchedHandlers.push( handleObj );
  						}
  					}
  					if ( matchedHandlers.length ) {
  						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
  					}
  				}
  			}
  		}
  
  		// Add the remaining (directly-bound) handlers
  		cur = this;
  		if ( delegateCount < handlers.length ) {
  			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
  		}
  
  		return handlerQueue;
  	},
  
  	addProp: function( name, hook ) {
  		Object.defineProperty( jQuery.Event.prototype, name, {
  			enumerable: true,
  			configurable: true,
  
  			get: isFunction( hook ) ?
  				function() {
  					if ( this.originalEvent ) {
  							return hook( this.originalEvent );
  					}
  				} :
  				function() {
  					if ( this.originalEvent ) {
  							return this.originalEvent[ name ];
  					}
  				},
  
  			set: function( value ) {
  				Object.defineProperty( this, name, {
  					enumerable: true,
  					configurable: true,
  					writable: true,
  					value: value
  				} );
  			}
  		} );
  	},
  
  	fix: function( originalEvent ) {
  		return originalEvent[ jQuery.expando ] ?
  			originalEvent :
  			new jQuery.Event( originalEvent );
  	},
  
  	special: {
  		load: {
  
  			// Prevent triggered image.load events from bubbling to window.load
  			noBubble: true
  		},
  		click: {
  
  			// Utilize native event to ensure correct state for checkable inputs
  			setup: function( data ) {
  
  				// For mutual compressibility with _default, replace `this` access with a local var.
  				// `|| data` is dead code meant only to preserve the variable through minification.
  				var el = this || data;
  
  				// Claim the first handler
  				if ( rcheckableType.test( el.type ) &&
  					el.click && nodeName( el, "input" ) ) {
  
  					// dataPriv.set( el, "click", ... )
  					leverageNative( el, "click", returnTrue );
  				}
  
  				// Return false to allow normal processing in the caller
  				return false;
  			},
  			trigger: function( data ) {
  
  				// For mutual compressibility with _default, replace `this` access with a local var.
  				// `|| data` is dead code meant only to preserve the variable through minification.
  				var el = this || data;
  
  				// Force setup before triggering a click
  				if ( rcheckableType.test( el.type ) &&
  					el.click && nodeName( el, "input" ) ) {
  
  					leverageNative( el, "click" );
  				}
  
  				// Return non-false to allow normal event-path propagation
  				return true;
  			},
  
  			// For cross-browser consistency, suppress native .click() on links
  			// Also prevent it if we're currently inside a leveraged native-event stack
  			_default: function( event ) {
  				var target = event.target;
  				return rcheckableType.test( target.type ) &&
  					target.click && nodeName( target, "input" ) &&
  					dataPriv.get( target, "click" ) ||
  					nodeName( target, "a" );
  			}
  		},
  
  		beforeunload: {
  			postDispatch: function( event ) {
  
  				// Support: Firefox 20+
  				// Firefox doesn't alert if the returnValue field is not set.
  				if ( event.result !== undefined && event.originalEvent ) {
  					event.originalEvent.returnValue = event.result;
  				}
  			}
  		}
  	}
  };
  
  // Ensure the presence of an event listener that handles manually-triggered
  // synthetic events by interrupting progress until reinvoked in response to
  // *native* events that it fires directly, ensuring that state changes have
  // already occurred before other listeners are invoked.
  function leverageNative( el, type, expectSync ) {
  
  	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
  	if ( !expectSync ) {
  		if ( dataPriv.get( el, type ) === undefined ) {
  			jQuery.event.add( el, type, returnTrue );
  		}
  		return;
  	}
  
  	// Register the controller as a special universal handler for all event namespaces
  	dataPriv.set( el, type, false );
  	jQuery.event.add( el, type, {
  		namespace: false,
  		handler: function( event ) {
  			var notAsync, result,
  				saved = dataPriv.get( this, type );
  
  			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
  
  				// Interrupt processing of the outer synthetic .trigger()ed event
  				// Saved data should be false in such cases, but might be a leftover capture object
  				// from an async native handler (gh-4350)
  				if ( !saved.length ) {
  
  					// Store arguments for use when handling the inner native event
  					// There will always be at least one argument (an event object), so this array
  					// will not be confused with a leftover capture object.
  					saved = slice.call( arguments );
  					dataPriv.set( this, type, saved );
  
  					// Trigger the native event and capture its result
  					// Support: IE <=9 - 11+
  					// focus() and blur() are asynchronous
  					notAsync = expectSync( this, type );
  					this[ type ]();
  					result = dataPriv.get( this, type );
  					if ( saved !== result || notAsync ) {
  						dataPriv.set( this, type, false );
  					} else {
  						result = {};
  					}
  					if ( saved !== result ) {
  
  						// Cancel the outer synthetic event
  						event.stopImmediatePropagation();
  						event.preventDefault();
  						return result.value;
  					}
  
  				// If this is an inner synthetic event for an event with a bubbling surrogate
  				// (focus or blur), assume that the surrogate already propagated from triggering the
  				// native event and prevent that from happening again here.
  				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
  				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
  				// less bad than duplication.
  				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
  					event.stopPropagation();
  				}
  
  			// If this is a native event triggered above, everything is now in order
  			// Fire an inner synthetic event with the original arguments
  			} else if ( saved.length ) {
  
  				// ...and capture the result
  				dataPriv.set( this, type, {
  					value: jQuery.event.trigger(
  
  						// Support: IE <=9 - 11+
  						// Extend with the prototype to reset the above stopImmediatePropagation()
  						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
  						saved.slice( 1 ),
  						this
  					)
  				} );
  
  				// Abort handling of the native event
  				event.stopImmediatePropagation();
  			}
  		}
  	} );
  }
  
  jQuery.removeEvent = function( elem, type, handle ) {
  
  	// This "if" is needed for plain objects
  	if ( elem.removeEventListener ) {
  		elem.removeEventListener( type, handle );
  	}
  };
  
  jQuery.Event = function( src, props ) {
  
  	// Allow instantiation without the 'new' keyword
  	if ( !( this instanceof jQuery.Event ) ) {
  		return new jQuery.Event( src, props );
  	}
  
  	// Event object
  	if ( src && src.type ) {
  		this.originalEvent = src;
  		this.type = src.type;
  
  		// Events bubbling up the document may have been marked as prevented
  		// by a handler lower down the tree; reflect the correct value.
  		this.isDefaultPrevented = src.defaultPrevented ||
  				src.defaultPrevented === undefined &&
  
  				// Support: Android <=2.3 only
  				src.returnValue === false ?
  			returnTrue :
  			returnFalse;
  
  		// Create target properties
  		// Support: Safari <=6 - 7 only
  		// Target should not be a text node (#504, #13143)
  		this.target = ( src.target && src.target.nodeType === 3 ) ?
  			src.target.parentNode :
  			src.target;
  
  		this.currentTarget = src.currentTarget;
  		this.relatedTarget = src.relatedTarget;
  
  	// Event type
  	} else {
  		this.type = src;
  	}
  
  	// Put explicitly provided properties onto the event object
  	if ( props ) {
  		jQuery.extend( this, props );
  	}
  
  	// Create a timestamp if incoming event doesn't have one
  	this.timeStamp = src && src.timeStamp || Date.now();
  
  	// Mark it as fixed
  	this[ jQuery.expando ] = true;
  };
  
  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  jQuery.Event.prototype = {
  	constructor: jQuery.Event,
  	isDefaultPrevented: returnFalse,
  	isPropagationStopped: returnFalse,
  	isImmediatePropagationStopped: returnFalse,
  	isSimulated: false,
  
  	preventDefault: function() {
  		var e = this.originalEvent;
  
  		this.isDefaultPrevented = returnTrue;
  
  		if ( e && !this.isSimulated ) {
  			e.preventDefault();
  		}
  	},
  	stopPropagation: function() {
  		var e = this.originalEvent;
  
  		this.isPropagationStopped = returnTrue;
  
  		if ( e && !this.isSimulated ) {
  			e.stopPropagation();
  		}
  	},
  	stopImmediatePropagation: function() {
  		var e = this.originalEvent;
  
  		this.isImmediatePropagationStopped = returnTrue;
  
  		if ( e && !this.isSimulated ) {
  			e.stopImmediatePropagation();
  		}
  
  		this.stopPropagation();
  	}
  };
  
  // Includes all common event props including KeyEvent and MouseEvent specific props
  jQuery.each( {
  	altKey: true,
  	bubbles: true,
  	cancelable: true,
  	changedTouches: true,
  	ctrlKey: true,
  	detail: true,
  	eventPhase: true,
  	metaKey: true,
  	pageX: true,
  	pageY: true,
  	shiftKey: true,
  	view: true,
  	"char": true,
  	code: true,
  	charCode: true,
  	key: true,
  	keyCode: true,
  	button: true,
  	buttons: true,
  	clientX: true,
  	clientY: true,
  	offsetX: true,
  	offsetY: true,
  	pointerId: true,
  	pointerType: true,
  	screenX: true,
  	screenY: true,
  	targetTouches: true,
  	toElement: true,
  	touches: true,
  
  	which: function( event ) {
  		var button = event.button;
  
  		// Add which for key events
  		if ( event.which == null && rkeyEvent.test( event.type ) ) {
  			return event.charCode != null ? event.charCode : event.keyCode;
  		}
  
  		// Add which for click: 1 === left; 2 === middle; 3 === right
  		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
  			if ( button & 1 ) {
  				return 1;
  			}
  
  			if ( button & 2 ) {
  				return 3;
  			}
  
  			if ( button & 4 ) {
  				return 2;
  			}
  
  			return 0;
  		}
  
  		return event.which;
  	}
  }, jQuery.event.addProp );
  
  jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
  	jQuery.event.special[ type ] = {
  
  		// Utilize native event if possible so blur/focus sequence is correct
  		setup: function() {
  
  			// Claim the first handler
  			// dataPriv.set( this, "focus", ... )
  			// dataPriv.set( this, "blur", ... )
  			leverageNative( this, type, expectSync );
  
  			// Return false to allow normal processing in the caller
  			return false;
  		},
  		trigger: function() {
  
  			// Force setup before trigger
  			leverageNative( this, type );
  
  			// Return non-false to allow normal event-path propagation
  			return true;
  		},
  
  		delegateType: delegateType
  	};
  } );
  
  // Create mouseenter/leave events using mouseover/out and event-time checks
  // so that event delegation works in jQuery.
  // Do the same for pointerenter/pointerleave and pointerover/pointerout
  //
  // Support: Safari 7 only
  // Safari sends mouseenter too often; see:
  // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
  // for the description of the bug (it existed in older Chrome versions as well).
  jQuery.each( {
  	mouseenter: "mouseover",
  	mouseleave: "mouseout",
  	pointerenter: "pointerover",
  	pointerleave: "pointerout"
  }, function( orig, fix ) {
  	jQuery.event.special[ orig ] = {
  		delegateType: fix,
  		bindType: fix,
  
  		handle: function( event ) {
  			var ret,
  				target = this,
  				related = event.relatedTarget,
  				handleObj = event.handleObj;
  
  			// For mouseenter/leave call the handler if related is outside the target.
  			// NB: No relatedTarget if the mouse left/entered the browser window
  			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
  				event.type = handleObj.origType;
  				ret = handleObj.handler.apply( this, arguments );
  				event.type = fix;
  			}
  			return ret;
  		}
  	};
  } );
  
  jQuery.fn.extend( {
  
  	on: function( types, selector, data, fn ) {
  		return on( this, types, selector, data, fn );
  	},
  	one: function( types, selector, data, fn ) {
  		return on( this, types, selector, data, fn, 1 );
  	},
  	off: function( types, selector, fn ) {
  		var handleObj, type;
  		if ( types && types.preventDefault && types.handleObj ) {
  
  			// ( event )  dispatched jQuery.Event
  			handleObj = types.handleObj;
  			jQuery( types.delegateTarget ).off(
  				handleObj.namespace ?
  					handleObj.origType + "." + handleObj.namespace :
  					handleObj.origType,
  				handleObj.selector,
  				handleObj.handler
  			);
  			return this;
  		}
  		if ( typeof types === "object" ) {
  
  			// ( types-object [, selector] )
  			for ( type in types ) {
  				this.off( type, selector, types[ type ] );
  			}
  			return this;
  		}
  		if ( selector === false || typeof selector === "function" ) {
  
  			// ( types [, fn] )
  			fn = selector;
  			selector = undefined;
  		}
  		if ( fn === false ) {
  			fn = returnFalse;
  		}
  		return this.each( function() {
  			jQuery.event.remove( this, types, fn, selector );
  		} );
  	}
  } );
  
  
  var
  
  	// Support: IE <=10 - 11, Edge 12 - 13 only
  	// In IE/Edge using regex groups here causes severe slowdowns.
  	// See https://connect.microsoft.com/IE/feedback/details/1736512/
  	rnoInnerhtml = /<script|<style|<link/i,
  
  	// checked="checked" or checked
  	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
  
  // Prefer a tbody over its parent table for containing new rows
  function manipulationTarget( elem, content ) {
  	if ( nodeName( elem, "table" ) &&
  		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
  
  		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
  	}
  
  	return elem;
  }
  
  // Replace/restore the type attribute of script elements for safe DOM manipulation
  function disableScript( elem ) {
  	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
  	return elem;
  }
  function restoreScript( elem ) {
  	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
  		elem.type = elem.type.slice( 5 );
  	} else {
  		elem.removeAttribute( "type" );
  	}
  
  	return elem;
  }
  
  function cloneCopyEvent( src, dest ) {
  	var i, l, type, pdataOld, udataOld, udataCur, events;
  
  	if ( dest.nodeType !== 1 ) {
  		return;
  	}
  
  	// 1. Copy private data: events, handlers, etc.
  	if ( dataPriv.hasData( src ) ) {
  		pdataOld = dataPriv.get( src );
  		events = pdataOld.events;
  
  		if ( events ) {
  			dataPriv.remove( dest, "handle events" );
  
  			for ( type in events ) {
  				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  					jQuery.event.add( dest, type, events[ type ][ i ] );
  				}
  			}
  		}
  	}
  
  	// 2. Copy user data
  	if ( dataUser.hasData( src ) ) {
  		udataOld = dataUser.access( src );
  		udataCur = jQuery.extend( {}, udataOld );
  
  		dataUser.set( dest, udataCur );
  	}
  }
  
  // Fix IE bugs, see support tests
  function fixInput( src, dest ) {
  	var nodeName = dest.nodeName.toLowerCase();
  
  	// Fails to persist the checked state of a cloned checkbox or radio button.
  	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
  		dest.checked = src.checked;
  
  	// Fails to return the selected option to the default selected state when cloning options
  	} else if ( nodeName === "input" || nodeName === "textarea" ) {
  		dest.defaultValue = src.defaultValue;
  	}
  }
  
  function domManip( collection, args, callback, ignored ) {
  
  	// Flatten any nested arrays
  	args = flat( args );
  
  	var fragment, first, scripts, hasScripts, node, doc,
  		i = 0,
  		l = collection.length,
  		iNoClone = l - 1,
  		value = args[ 0 ],
  		valueIsFunction = isFunction( value );
  
  	// We can't cloneNode fragments that contain checked, in WebKit
  	if ( valueIsFunction ||
  			( l > 1 && typeof value === "string" &&
  				!support.checkClone && rchecked.test( value ) ) ) {
  		return collection.each( function( index ) {
  			var self = collection.eq( index );
  			if ( valueIsFunction ) {
  				args[ 0 ] = value.call( this, index, self.html() );
  			}
  			domManip( self, args, callback, ignored );
  		} );
  	}
  
  	if ( l ) {
  		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
  		first = fragment.firstChild;
  
  		if ( fragment.childNodes.length === 1 ) {
  			fragment = first;
  		}
  
  		// Require either new content or an interest in ignored elements to invoke the callback
  		if ( first || ignored ) {
  			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  			hasScripts = scripts.length;
  
  			// Use the original fragment for the last item
  			// instead of the first because it can end up
  			// being emptied incorrectly in certain situations (#8070).
  			for ( ; i < l; i++ ) {
  				node = fragment;
  
  				if ( i !== iNoClone ) {
  					node = jQuery.clone( node, true, true );
  
  					// Keep references to cloned scripts for later restoration
  					if ( hasScripts ) {
  
  						// Support: Android <=4.0 only, PhantomJS 1 only
  						// push.apply(_, arraylike) throws on ancient WebKit
  						jQuery.merge( scripts, getAll( node, "script" ) );
  					}
  				}
  
  				callback.call( collection[ i ], node, i );
  			}
  
  			if ( hasScripts ) {
  				doc = scripts[ scripts.length - 1 ].ownerDocument;
  
  				// Reenable scripts
  				jQuery.map( scripts, restoreScript );
  
  				// Evaluate executable scripts on first document insertion
  				for ( i = 0; i < hasScripts; i++ ) {
  					node = scripts[ i ];
  					if ( rscriptType.test( node.type || "" ) &&
  						!dataPriv.access( node, "globalEval" ) &&
  						jQuery.contains( doc, node ) ) {
  
  						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
  
  							// Optional AJAX dependency, but won't run scripts if not present
  							if ( jQuery._evalUrl && !node.noModule ) {
  								jQuery._evalUrl( node.src, {
  									nonce: node.nonce || node.getAttribute( "nonce" )
  								}, doc );
  							}
  						} else {
  							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
  						}
  					}
  				}
  			}
  		}
  	}
  
  	return collection;
  }
  
  function remove( elem, selector, keepData ) {
  	var node,
  		nodes = selector ? jQuery.filter( selector, elem ) : elem,
  		i = 0;
  
  	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
  		if ( !keepData && node.nodeType === 1 ) {
  			jQuery.cleanData( getAll( node ) );
  		}
  
  		if ( node.parentNode ) {
  			if ( keepData && isAttached( node ) ) {
  				setGlobalEval( getAll( node, "script" ) );
  			}
  			node.parentNode.removeChild( node );
  		}
  	}
  
  	return elem;
  }
  
  jQuery.extend( {
  	htmlPrefilter: function( html ) {
  		return html;
  	},
  
  	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  		var i, l, srcElements, destElements,
  			clone = elem.cloneNode( true ),
  			inPage = isAttached( elem );
  
  		// Fix IE cloning issues
  		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
  				!jQuery.isXMLDoc( elem ) ) {
  
  			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
  			destElements = getAll( clone );
  			srcElements = getAll( elem );
  
  			for ( i = 0, l = srcElements.length; i < l; i++ ) {
  				fixInput( srcElements[ i ], destElements[ i ] );
  			}
  		}
  
  		// Copy the events from the original to the clone
  		if ( dataAndEvents ) {
  			if ( deepDataAndEvents ) {
  				srcElements = srcElements || getAll( elem );
  				destElements = destElements || getAll( clone );
  
  				for ( i = 0, l = srcElements.length; i < l; i++ ) {
  					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
  				}
  			} else {
  				cloneCopyEvent( elem, clone );
  			}
  		}
  
  		// Preserve script evaluation history
  		destElements = getAll( clone, "script" );
  		if ( destElements.length > 0 ) {
  			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  		}
  
  		// Return the cloned set
  		return clone;
  	},
  
  	cleanData: function( elems ) {
  		var data, elem, type,
  			special = jQuery.event.special,
  			i = 0;
  
  		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
  			if ( acceptData( elem ) ) {
  				if ( ( data = elem[ dataPriv.expando ] ) ) {
  					if ( data.events ) {
  						for ( type in data.events ) {
  							if ( special[ type ] ) {
  								jQuery.event.remove( elem, type );
  
  							// This is a shortcut to avoid jQuery.event.remove's overhead
  							} else {
  								jQuery.removeEvent( elem, type, data.handle );
  							}
  						}
  					}
  
  					// Support: Chrome <=35 - 45+
  					// Assign undefined instead of using delete, see Data#remove
  					elem[ dataPriv.expando ] = undefined;
  				}
  				if ( elem[ dataUser.expando ] ) {
  
  					// Support: Chrome <=35 - 45+
  					// Assign undefined instead of using delete, see Data#remove
  					elem[ dataUser.expando ] = undefined;
  				}
  			}
  		}
  	}
  } );
  
  jQuery.fn.extend( {
  	detach: function( selector ) {
  		return remove( this, selector, true );
  	},
  
  	remove: function( selector ) {
  		return remove( this, selector );
  	},
  
  	text: function( value ) {
  		return access( this, function( value ) {
  			return value === undefined ?
  				jQuery.text( this ) :
  				this.empty().each( function() {
  					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  						this.textContent = value;
  					}
  				} );
  		}, null, value, arguments.length );
  	},
  
  	append: function() {
  		return domManip( this, arguments, function( elem ) {
  			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  				var target = manipulationTarget( this, elem );
  				target.appendChild( elem );
  			}
  		} );
  	},
  
  	prepend: function() {
  		return domManip( this, arguments, function( elem ) {
  			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  				var target = manipulationTarget( this, elem );
  				target.insertBefore( elem, target.firstChild );
  			}
  		} );
  	},
  
  	before: function() {
  		return domManip( this, arguments, function( elem ) {
  			if ( this.parentNode ) {
  				this.parentNode.insertBefore( elem, this );
  			}
  		} );
  	},
  
  	after: function() {
  		return domManip( this, arguments, function( elem ) {
  			if ( this.parentNode ) {
  				this.parentNode.insertBefore( elem, this.nextSibling );
  			}
  		} );
  	},
  
  	empty: function() {
  		var elem,
  			i = 0;
  
  		for ( ; ( elem = this[ i ] ) != null; i++ ) {
  			if ( elem.nodeType === 1 ) {
  
  				// Prevent memory leaks
  				jQuery.cleanData( getAll( elem, false ) );
  
  				// Remove any remaining nodes
  				elem.textContent = "";
  			}
  		}
  
  		return this;
  	},
  
  	clone: function( dataAndEvents, deepDataAndEvents ) {
  		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  
  		return this.map( function() {
  			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  		} );
  	},
  
  	html: function( value ) {
  		return access( this, function( value ) {
  			var elem = this[ 0 ] || {},
  				i = 0,
  				l = this.length;
  
  			if ( value === undefined && elem.nodeType === 1 ) {
  				return elem.innerHTML;
  			}
  
  			// See if we can take a shortcut and just use innerHTML
  			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  
  				value = jQuery.htmlPrefilter( value );
  
  				try {
  					for ( ; i < l; i++ ) {
  						elem = this[ i ] || {};
  
  						// Remove element nodes and prevent memory leaks
  						if ( elem.nodeType === 1 ) {
  							jQuery.cleanData( getAll( elem, false ) );
  							elem.innerHTML = value;
  						}
  					}
  
  					elem = 0;
  
  				// If using innerHTML throws an exception, use the fallback method
  				} catch ( e ) {}
  			}
  
  			if ( elem ) {
  				this.empty().append( value );
  			}
  		}, null, value, arguments.length );
  	},
  
  	replaceWith: function() {
  		var ignored = [];
  
  		// Make the changes, replacing each non-ignored context element with the new content
  		return domManip( this, arguments, function( elem ) {
  			var parent = this.parentNode;
  
  			if ( jQuery.inArray( this, ignored ) < 0 ) {
  				jQuery.cleanData( getAll( this ) );
  				if ( parent ) {
  					parent.replaceChild( elem, this );
  				}
  			}
  
  		// Force callback invocation
  		}, ignored );
  	}
  } );
  
  jQuery.each( {
  	appendTo: "append",
  	prependTo: "prepend",
  	insertBefore: "before",
  	insertAfter: "after",
  	replaceAll: "replaceWith"
  }, function( name, original ) {
  	jQuery.fn[ name ] = function( selector ) {
  		var elems,
  			ret = [],
  			insert = jQuery( selector ),
  			last = insert.length - 1,
  			i = 0;
  
  		for ( ; i <= last; i++ ) {
  			elems = i === last ? this : this.clone( true );
  			jQuery( insert[ i ] )[ original ]( elems );
  
  			// Support: Android <=4.0 only, PhantomJS 1 only
  			// .get() because push.apply(_, arraylike) throws on ancient WebKit
  			push.apply( ret, elems.get() );
  		}
  
  		return this.pushStack( ret );
  	};
  } );
  var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
  
  var getStyles = function( elem ) {
  
  		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
  		// IE throws on elements created in popups
  		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
  		var view = elem.ownerDocument.defaultView;
  
  		if ( !view || !view.opener ) {
  			view = window;
  		}
  
  		return view.getComputedStyle( elem );
  	};
  
  var swap = function( elem, options, callback ) {
  	var ret, name,
  		old = {};
  
  	// Remember the old values, and insert the new ones
  	for ( name in options ) {
  		old[ name ] = elem.style[ name ];
  		elem.style[ name ] = options[ name ];
  	}
  
  	ret = callback.call( elem );
  
  	// Revert the old values
  	for ( name in options ) {
  		elem.style[ name ] = old[ name ];
  	}
  
  	return ret;
  };
  
  
  var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
  
  
  
  ( function() {
  
  	// Executing both pixelPosition & boxSizingReliable tests require only one layout
  	// so they're executed at the same time to save the second computation.
  	function computeStyleTests() {
  
  		// This is a singleton, we need to execute it only once
  		if ( !div ) {
  			return;
  		}
  
  		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
  			"margin-top:1px;padding:0;border:0";
  		div.style.cssText =
  			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
  			"margin:auto;border:1px;padding:1px;" +
  			"width:60%;top:1%";
  		documentElement.appendChild( container ).appendChild( div );
  
  		var divStyle = window.getComputedStyle( div );
  		pixelPositionVal = divStyle.top !== "1%";
  
  		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
  		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
  
  		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
  		// Some styles come back with percentage values, even though they shouldn't
  		div.style.right = "60%";
  		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
  
  		// Support: IE 9 - 11 only
  		// Detect misreporting of content dimensions for box-sizing:border-box elements
  		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
  
  		// Support: IE 9 only
  		// Detect overflow:scroll screwiness (gh-3699)
  		// Support: Chrome <=64
  		// Don't get tricked when zoom affects offsetWidth (gh-4029)
  		div.style.position = "absolute";
  		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
  
  		documentElement.removeChild( container );
  
  		// Nullify the div so it wouldn't be stored in the memory and
  		// it will also be a sign that checks already performed
  		div = null;
  	}
  
  	function roundPixelMeasures( measure ) {
  		return Math.round( parseFloat( measure ) );
  	}
  
  	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
  		reliableTrDimensionsVal, reliableMarginLeftVal,
  		container = document.createElement( "div" ),
  		div = document.createElement( "div" );
  
  	// Finish early in limited (non-browser) environments
  	if ( !div.style ) {
  		return;
  	}
  
  	// Support: IE <=9 - 11 only
  	// Style of cloned element affects source element cloned (#8908)
  	div.style.backgroundClip = "content-box";
  	div.cloneNode( true ).style.backgroundClip = "";
  	support.clearCloneStyle = div.style.backgroundClip === "content-box";
  
  	jQuery.extend( support, {
  		boxSizingReliable: function() {
  			computeStyleTests();
  			return boxSizingReliableVal;
  		},
  		pixelBoxStyles: function() {
  			computeStyleTests();
  			return pixelBoxStylesVal;
  		},
  		pixelPosition: function() {
  			computeStyleTests();
  			return pixelPositionVal;
  		},
  		reliableMarginLeft: function() {
  			computeStyleTests();
  			return reliableMarginLeftVal;
  		},
  		scrollboxSize: function() {
  			computeStyleTests();
  			return scrollboxSizeVal;
  		},
  
  		// Support: IE 9 - 11+, Edge 15 - 18+
  		// IE/Edge misreport `getComputedStyle` of table rows with width/height
  		// set in CSS while `offset*` properties report correct values.
  		// Behavior in IE 9 is more subtle than in newer versions & it passes
  		// some versions of this test; make sure not to make it pass there!
  		reliableTrDimensions: function() {
  			var table, tr, trChild, trStyle;
  			if ( reliableTrDimensionsVal == null ) {
  				table = document.createElement( "table" );
  				tr = document.createElement( "tr" );
  				trChild = document.createElement( "div" );
  
  				table.style.cssText = "position:absolute;left:-11111px";
  				tr.style.height = "1px";
  				trChild.style.height = "9px";
  
  				documentElement
  					.appendChild( table )
  					.appendChild( tr )
  					.appendChild( trChild );
  
  				trStyle = window.getComputedStyle( tr );
  				reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
  
  				documentElement.removeChild( table );
  			}
  			return reliableTrDimensionsVal;
  		}
  	} );
  } )();
  
  
  function curCSS( elem, name, computed ) {
  	var width, minWidth, maxWidth, ret,
  
  		// Support: Firefox 51+
  		// Retrieving style before computed somehow
  		// fixes an issue with getting wrong values
  		// on detached elements
  		style = elem.style;
  
  	computed = computed || getStyles( elem );
  
  	// getPropertyValue is needed for:
  	//   .css('filter') (IE 9 only, #12537)
  	//   .css('--customProperty) (#3144)
  	if ( computed ) {
  		ret = computed.getPropertyValue( name ) || computed[ name ];
  
  		if ( ret === "" && !isAttached( elem ) ) {
  			ret = jQuery.style( elem, name );
  		}
  
  		// A tribute to the "awesome hack by Dean Edwards"
  		// Android Browser returns percentage for some values,
  		// but width seems to be reliably pixels.
  		// This is against the CSSOM draft spec:
  		// https://drafts.csswg.org/cssom/#resolved-values
  		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
  
  			// Remember the original values
  			width = style.width;
  			minWidth = style.minWidth;
  			maxWidth = style.maxWidth;
  
  			// Put in the new values to get a computed value out
  			style.minWidth = style.maxWidth = style.width = ret;
  			ret = computed.width;
  
  			// Revert the changed values
  			style.width = width;
  			style.minWidth = minWidth;
  			style.maxWidth = maxWidth;
  		}
  	}
  
  	return ret !== undefined ?
  
  		// Support: IE <=9 - 11 only
  		// IE returns zIndex value as an integer.
  		ret + "" :
  		ret;
  }
  
  
  function addGetHookIf( conditionFn, hookFn ) {
  
  	// Define the hook, we'll check on the first run if it's really needed.
  	return {
  		get: function() {
  			if ( conditionFn() ) {
  
  				// Hook not needed (or it's not possible to use it due
  				// to missing dependency), remove it.
  				delete this.get;
  				return;
  			}
  
  			// Hook needed; redefine it so that the support test is not executed again.
  			return ( this.get = hookFn ).apply( this, arguments );
  		}
  	};
  }
  
  
  var cssPrefixes = [ "Webkit", "Moz", "ms" ],
  	emptyStyle = document.createElement( "div" ).style,
  	vendorProps = {};
  
  // Return a vendor-prefixed property or undefined
  function vendorPropName( name ) {
  
  	// Check for vendor prefixed names
  	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
  		i = cssPrefixes.length;
  
  	while ( i-- ) {
  		name = cssPrefixes[ i ] + capName;
  		if ( name in emptyStyle ) {
  			return name;
  		}
  	}
  }
  
  // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
  function finalPropName( name ) {
  	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
  
  	if ( final ) {
  		return final;
  	}
  	if ( name in emptyStyle ) {
  		return name;
  	}
  	return vendorProps[ name ] = vendorPropName( name ) || name;
  }
  
  
  var
  
  	// Swappable if display is none or starts with table
  	// except "table", "table-cell", or "table-caption"
  	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  	rcustomProp = /^--/,
  	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  	cssNormalTransform = {
  		letterSpacing: "0",
  		fontWeight: "400"
  	};
  
  function setPositiveNumber( _elem, value, subtract ) {
  
  	// Any relative (+/-) values have already been
  	// normalized at this point
  	var matches = rcssNum.exec( value );
  	return matches ?
  
  		// Guard against undefined "subtract", e.g., when used as in cssHooks
  		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
  		value;
  }
  
  function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
  	var i = dimension === "width" ? 1 : 0,
  		extra = 0,
  		delta = 0;
  
  	// Adjustment may not be necessary
  	if ( box === ( isBorderBox ? "border" : "content" ) ) {
  		return 0;
  	}
  
  	for ( ; i < 4; i += 2 ) {
  
  		// Both box models exclude margin
  		if ( box === "margin" ) {
  			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
  		}
  
  		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
  		if ( !isBorderBox ) {
  
  			// Add padding
  			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  
  			// For "border" or "margin", add border
  			if ( box !== "padding" ) {
  				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  
  			// But still keep track of it otherwise
  			} else {
  				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  			}
  
  		// If we get here with a border-box (content + padding + border), we're seeking "content" or
  		// "padding" or "margin"
  		} else {
  
  			// For "content", subtract padding
  			if ( box === "content" ) {
  				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  			}
  
  			// For "content" or "padding", subtract border
  			if ( box !== "margin" ) {
  				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  			}
  		}
  	}
  
  	// Account for positive content-box scroll gutter when requested by providing computedVal
  	if ( !isBorderBox && computedVal >= 0 ) {
  
  		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
  		// Assuming integer scroll gutter, subtract the rest and round down
  		delta += Math.max( 0, Math.ceil(
  			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
  			computedVal -
  			delta -
  			extra -
  			0.5
  
  		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
  		// Use an explicit zero to avoid NaN (gh-3964)
  		) ) || 0;
  	}
  
  	return delta;
  }
  
  function getWidthOrHeight( elem, dimension, extra ) {
  
  	// Start with computed style
  	var styles = getStyles( elem ),
  
  		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
  		// Fake content-box until we know it's needed to know the true value.
  		boxSizingNeeded = !support.boxSizingReliable() || extra,
  		isBorderBox = boxSizingNeeded &&
  			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  		valueIsBorderBox = isBorderBox,
  
  		val = curCSS( elem, dimension, styles ),
  		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
  
  	// Support: Firefox <=54
  	// Return a confounding non-pixel value or feign ignorance, as appropriate.
  	if ( rnumnonpx.test( val ) ) {
  		if ( !extra ) {
  			return val;
  		}
  		val = "auto";
  	}
  
  
  	// Support: IE 9 - 11 only
  	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
  	// In those cases, the computed value can be trusted to be border-box.
  	if ( ( !support.boxSizingReliable() && isBorderBox ||
  
  		// Support: IE 10 - 11+, Edge 15 - 18+
  		// IE/Edge misreport `getComputedStyle` of table rows with width/height
  		// set in CSS while `offset*` properties report correct values.
  		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
  		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
  
  		// Fall back to offsetWidth/offsetHeight when value is "auto"
  		// This happens for inline elements with no explicit setting (gh-3571)
  		val === "auto" ||
  
  		// Support: Android <=4.1 - 4.3 only
  		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
  		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
  
  		// Make sure the element is visible & connected
  		elem.getClientRects().length ) {
  
  		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  
  		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
  		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
  		// retrieved value as a content box dimension.
  		valueIsBorderBox = offsetProp in elem;
  		if ( valueIsBorderBox ) {
  			val = elem[ offsetProp ];
  		}
  	}
  
  	// Normalize "" and auto
  	val = parseFloat( val ) || 0;
  
  	// Adjust for the element's box model
  	return ( val +
  		boxModelAdjustment(
  			elem,
  			dimension,
  			extra || ( isBorderBox ? "border" : "content" ),
  			valueIsBorderBox,
  			styles,
  
  			// Provide the current computed size to request scroll gutter calculation (gh-3589)
  			val
  		)
  	) + "px";
  }
  
  jQuery.extend( {
  
  	// Add in style property hooks for overriding the default
  	// behavior of getting and setting a style property
  	cssHooks: {
  		opacity: {
  			get: function( elem, computed ) {
  				if ( computed ) {
  
  					// We should always get a number back from opacity
  					var ret = curCSS( elem, "opacity" );
  					return ret === "" ? "1" : ret;
  				}
  			}
  		}
  	},
  
  	// Don't automatically add "px" to these possibly-unitless properties
  	cssNumber: {
  		"animationIterationCount": true,
  		"columnCount": true,
  		"fillOpacity": true,
  		"flexGrow": true,
  		"flexShrink": true,
  		"fontWeight": true,
  		"gridArea": true,
  		"gridColumn": true,
  		"gridColumnEnd": true,
  		"gridColumnStart": true,
  		"gridRow": true,
  		"gridRowEnd": true,
  		"gridRowStart": true,
  		"lineHeight": true,
  		"opacity": true,
  		"order": true,
  		"orphans": true,
  		"widows": true,
  		"zIndex": true,
  		"zoom": true
  	},
  
  	// Add in properties whose names you wish to fix before
  	// setting or getting the value
  	cssProps: {},
  
  	// Get and set the style property on a DOM Node
  	style: function( elem, name, value, extra ) {
  
  		// Don't set styles on text and comment nodes
  		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  			return;
  		}
  
  		// Make sure that we're working with the right name
  		var ret, type, hooks,
  			origName = camelCase( name ),
  			isCustomProp = rcustomProp.test( name ),
  			style = elem.style;
  
  		// Make sure that we're working with the right name. We don't
  		// want to query the value if it is a CSS custom property
  		// since they are user-defined.
  		if ( !isCustomProp ) {
  			name = finalPropName( origName );
  		}
  
  		// Gets hook for the prefixed version, then unprefixed version
  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  
  		// Check if we're setting a value
  		if ( value !== undefined ) {
  			type = typeof value;
  
  			// Convert "+=" or "-=" to relative numbers (#7345)
  			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
  				value = adjustCSS( elem, name, ret );
  
  				// Fixes bug #9237
  				type = "number";
  			}
  
  			// Make sure that null and NaN values aren't set (#7116)
  			if ( value == null || value !== value ) {
  				return;
  			}
  
  			// If a number was passed in, add the unit (except for certain CSS properties)
  			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
  			// "px" to a few hardcoded values.
  			if ( type === "number" && !isCustomProp ) {
  				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
  			}
  
  			// background-* props affect original clone's values
  			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  				style[ name ] = "inherit";
  			}
  
  			// If a hook was provided, use that value, otherwise just set the specified value
  			if ( !hooks || !( "set" in hooks ) ||
  				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
  
  				if ( isCustomProp ) {
  					style.setProperty( name, value );
  				} else {
  					style[ name ] = value;
  				}
  			}
  
  		} else {
  
  			// If a hook was provided get the non-computed value from there
  			if ( hooks && "get" in hooks &&
  				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
  
  				return ret;
  			}
  
  			// Otherwise just get the value from the style object
  			return style[ name ];
  		}
  	},
  
  	css: function( elem, name, extra, styles ) {
  		var val, num, hooks,
  			origName = camelCase( name ),
  			isCustomProp = rcustomProp.test( name );
  
  		// Make sure that we're working with the right name. We don't
  		// want to modify the value if it is a CSS custom property
  		// since they are user-defined.
  		if ( !isCustomProp ) {
  			name = finalPropName( origName );
  		}
  
  		// Try prefixed name followed by the unprefixed name
  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  
  		// If a hook was provided get the computed value from there
  		if ( hooks && "get" in hooks ) {
  			val = hooks.get( elem, true, extra );
  		}
  
  		// Otherwise, if a way to get the computed value exists, use that
  		if ( val === undefined ) {
  			val = curCSS( elem, name, styles );
  		}
  
  		// Convert "normal" to computed value
  		if ( val === "normal" && name in cssNormalTransform ) {
  			val = cssNormalTransform[ name ];
  		}
  
  		// Make numeric if forced or a qualifier was provided and val looks numeric
  		if ( extra === "" || extra ) {
  			num = parseFloat( val );
  			return extra === true || isFinite( num ) ? num || 0 : val;
  		}
  
  		return val;
  	}
  } );
  
  jQuery.each( [ "height", "width" ], function( _i, dimension ) {
  	jQuery.cssHooks[ dimension ] = {
  		get: function( elem, computed, extra ) {
  			if ( computed ) {
  
  				// Certain elements can have dimension info if we invisibly show them
  				// but it must have a current display style that would benefit
  				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
  
  					// Support: Safari 8+
  					// Table columns in Safari have non-zero offsetWidth & zero
  					// getBoundingClientRect().width unless display is changed.
  					// Support: IE <=11 only
  					// Running getBoundingClientRect on a disconnected node
  					// in IE throws an error.
  					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
  						swap( elem, cssShow, function() {
  							return getWidthOrHeight( elem, dimension, extra );
  						} ) :
  						getWidthOrHeight( elem, dimension, extra );
  			}
  		},
  
  		set: function( elem, value, extra ) {
  			var matches,
  				styles = getStyles( elem ),
  
  				// Only read styles.position if the test has a chance to fail
  				// to avoid forcing a reflow.
  				scrollboxSizeBuggy = !support.scrollboxSize() &&
  					styles.position === "absolute",
  
  				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
  				boxSizingNeeded = scrollboxSizeBuggy || extra,
  				isBorderBox = boxSizingNeeded &&
  					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  				subtract = extra ?
  					boxModelAdjustment(
  						elem,
  						dimension,
  						extra,
  						isBorderBox,
  						styles
  					) :
  					0;
  
  			// Account for unreliable border-box dimensions by comparing offset* to computed and
  			// faking a content-box to get border and padding (gh-3699)
  			if ( isBorderBox && scrollboxSizeBuggy ) {
  				subtract -= Math.ceil(
  					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
  					parseFloat( styles[ dimension ] ) -
  					boxModelAdjustment( elem, dimension, "border", false, styles ) -
  					0.5
  				);
  			}
  
  			// Convert to pixels if value adjustment is needed
  			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
  				( matches[ 3 ] || "px" ) !== "px" ) {
  
  				elem.style[ dimension ] = value;
  				value = jQuery.css( elem, dimension );
  			}
  
  			return setPositiveNumber( elem, value, subtract );
  		}
  	};
  } );
  
  jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
  	function( elem, computed ) {
  		if ( computed ) {
  			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
  				elem.getBoundingClientRect().left -
  					swap( elem, { marginLeft: 0 }, function() {
  						return elem.getBoundingClientRect().left;
  					} )
  				) + "px";
  		}
  	}
  );
  
  // These hooks are used by animate to expand properties
  jQuery.each( {
  	margin: "",
  	padding: "",
  	border: "Width"
  }, function( prefix, suffix ) {
  	jQuery.cssHooks[ prefix + suffix ] = {
  		expand: function( value ) {
  			var i = 0,
  				expanded = {},
  
  				// Assumes a single number if not a string
  				parts = typeof value === "string" ? value.split( " " ) : [ value ];
  
  			for ( ; i < 4; i++ ) {
  				expanded[ prefix + cssExpand[ i ] + suffix ] =
  					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  			}
  
  			return expanded;
  		}
  	};
  
  	if ( prefix !== "margin" ) {
  		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  	}
  } );
  
  jQuery.fn.extend( {
  	css: function( name, value ) {
  		return access( this, function( elem, name, value ) {
  			var styles, len,
  				map = {},
  				i = 0;
  
  			if ( Array.isArray( name ) ) {
  				styles = getStyles( elem );
  				len = name.length;
  
  				for ( ; i < len; i++ ) {
  					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  				}
  
  				return map;
  			}
  
  			return value !== undefined ?
  				jQuery.style( elem, name, value ) :
  				jQuery.css( elem, name );
  		}, name, value, arguments.length > 1 );
  	}
  } );
  
  
  function Tween( elem, options, prop, end, easing ) {
  	return new Tween.prototype.init( elem, options, prop, end, easing );
  }
  jQuery.Tween = Tween;
  
  Tween.prototype = {
  	constructor: Tween,
  	init: function( elem, options, prop, end, easing, unit ) {
  		this.elem = elem;
  		this.prop = prop;
  		this.easing = easing || jQuery.easing._default;
  		this.options = options;
  		this.start = this.now = this.cur();
  		this.end = end;
  		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  	},
  	cur: function() {
  		var hooks = Tween.propHooks[ this.prop ];
  
  		return hooks && hooks.get ?
  			hooks.get( this ) :
  			Tween.propHooks._default.get( this );
  	},
  	run: function( percent ) {
  		var eased,
  			hooks = Tween.propHooks[ this.prop ];
  
  		if ( this.options.duration ) {
  			this.pos = eased = jQuery.easing[ this.easing ](
  				percent, this.options.duration * percent, 0, 1, this.options.duration
  			);
  		} else {
  			this.pos = eased = percent;
  		}
  		this.now = ( this.end - this.start ) * eased + this.start;
  
  		if ( this.options.step ) {
  			this.options.step.call( this.elem, this.now, this );
  		}
  
  		if ( hooks && hooks.set ) {
  			hooks.set( this );
  		} else {
  			Tween.propHooks._default.set( this );
  		}
  		return this;
  	}
  };
  
  Tween.prototype.init.prototype = Tween.prototype;
  
  Tween.propHooks = {
  	_default: {
  		get: function( tween ) {
  			var result;
  
  			// Use a property on the element directly when it is not a DOM element,
  			// or when there is no matching style property that exists.
  			if ( tween.elem.nodeType !== 1 ||
  				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
  				return tween.elem[ tween.prop ];
  			}
  
  			// Passing an empty string as a 3rd parameter to .css will automatically
  			// attempt a parseFloat and fallback to a string if the parse fails.
  			// Simple values such as "10px" are parsed to Float;
  			// complex values such as "rotate(1rad)" are returned as-is.
  			result = jQuery.css( tween.elem, tween.prop, "" );
  
  			// Empty strings, null, undefined and "auto" are converted to 0.
  			return !result || result === "auto" ? 0 : result;
  		},
  		set: function( tween ) {
  
  			// Use step hook for back compat.
  			// Use cssHook if its there.
  			// Use .style if available and use plain properties where available.
  			if ( jQuery.fx.step[ tween.prop ] ) {
  				jQuery.fx.step[ tween.prop ]( tween );
  			} else if ( tween.elem.nodeType === 1 && (
  					jQuery.cssHooks[ tween.prop ] ||
  					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
  				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  			} else {
  				tween.elem[ tween.prop ] = tween.now;
  			}
  		}
  	}
  };
  
  // Support: IE <=9 only
  // Panic based approach to setting things on disconnected nodes
  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  	set: function( tween ) {
  		if ( tween.elem.nodeType && tween.elem.parentNode ) {
  			tween.elem[ tween.prop ] = tween.now;
  		}
  	}
  };
  
  jQuery.easing = {
  	linear: function( p ) {
  		return p;
  	},
  	swing: function( p ) {
  		return 0.5 - Math.cos( p * Math.PI ) / 2;
  	},
  	_default: "swing"
  };
  
  jQuery.fx = Tween.prototype.init;
  
  // Back compat <1.8 extension point
  jQuery.fx.step = {};
  
  
  
  
  var
  	fxNow, inProgress,
  	rfxtypes = /^(?:toggle|show|hide)$/,
  	rrun = /queueHooks$/;
  
  function schedule() {
  	if ( inProgress ) {
  		if ( document.hidden === false && window.requestAnimationFrame ) {
  			window.requestAnimationFrame( schedule );
  		} else {
  			window.setTimeout( schedule, jQuery.fx.interval );
  		}
  
  		jQuery.fx.tick();
  	}
  }
  
  // Animations created synchronously will run synchronously
  function createFxNow() {
  	window.setTimeout( function() {
  		fxNow = undefined;
  	} );
  	return ( fxNow = Date.now() );
  }
  
  // Generate parameters to create a standard animation
  function genFx( type, includeWidth ) {
  	var which,
  		i = 0,
  		attrs = { height: type };
  
  	// If we include width, step value is 1 to do all cssExpand values,
  	// otherwise step value is 2 to skip over Left and Right
  	includeWidth = includeWidth ? 1 : 0;
  	for ( ; i < 4; i += 2 - includeWidth ) {
  		which = cssExpand[ i ];
  		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  	}
  
  	if ( includeWidth ) {
  		attrs.opacity = attrs.width = type;
  	}
  
  	return attrs;
  }
  
  function createTween( value, prop, animation ) {
  	var tween,
  		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
  		index = 0,
  		length = collection.length;
  	for ( ; index < length; index++ ) {
  		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
  
  			// We're done with this property
  			return tween;
  		}
  	}
  }
  
  function defaultPrefilter( elem, props, opts ) {
  	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
  		isBox = "width" in props || "height" in props,
  		anim = this,
  		orig = {},
  		style = elem.style,
  		hidden = elem.nodeType && isHiddenWithinTree( elem ),
  		dataShow = dataPriv.get( elem, "fxshow" );
  
  	// Queue-skipping animations hijack the fx hooks
  	if ( !opts.queue ) {
  		hooks = jQuery._queueHooks( elem, "fx" );
  		if ( hooks.unqueued == null ) {
  			hooks.unqueued = 0;
  			oldfire = hooks.empty.fire;
  			hooks.empty.fire = function() {
  				if ( !hooks.unqueued ) {
  					oldfire();
  				}
  			};
  		}
  		hooks.unqueued++;
  
  		anim.always( function() {
  
  			// Ensure the complete handler is called before this completes
  			anim.always( function() {
  				hooks.unqueued--;
  				if ( !jQuery.queue( elem, "fx" ).length ) {
  					hooks.empty.fire();
  				}
  			} );
  		} );
  	}
  
  	// Detect show/hide animations
  	for ( prop in props ) {
  		value = props[ prop ];
  		if ( rfxtypes.test( value ) ) {
  			delete props[ prop ];
  			toggle = toggle || value === "toggle";
  			if ( value === ( hidden ? "hide" : "show" ) ) {
  
  				// Pretend to be hidden if this is a "show" and
  				// there is still data from a stopped show/hide
  				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  					hidden = true;
  
  				// Ignore all other no-op show/hide data
  				} else {
  					continue;
  				}
  			}
  			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  		}
  	}
  
  	// Bail out if this is a no-op like .hide().hide()
  	propTween = !jQuery.isEmptyObject( props );
  	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
  		return;
  	}
  
  	// Restrict "overflow" and "display" styles during box animations
  	if ( isBox && elem.nodeType === 1 ) {
  
  		// Support: IE <=9 - 11, Edge 12 - 15
  		// Record all 3 overflow attributes because IE does not infer the shorthand
  		// from identically-valued overflowX and overflowY and Edge just mirrors
  		// the overflowX value there.
  		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  
  		// Identify a display type, preferring old show/hide data over the CSS cascade
  		restoreDisplay = dataShow && dataShow.display;
  		if ( restoreDisplay == null ) {
  			restoreDisplay = dataPriv.get( elem, "display" );
  		}
  		display = jQuery.css( elem, "display" );
  		if ( display === "none" ) {
  			if ( restoreDisplay ) {
  				display = restoreDisplay;
  			} else {
  
  				// Get nonempty value(s) by temporarily forcing visibility
  				showHide( [ elem ], true );
  				restoreDisplay = elem.style.display || restoreDisplay;
  				display = jQuery.css( elem, "display" );
  				showHide( [ elem ] );
  			}
  		}
  
  		// Animate inline elements as inline-block
  		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
  			if ( jQuery.css( elem, "float" ) === "none" ) {
  
  				// Restore the original display value at the end of pure show/hide animations
  				if ( !propTween ) {
  					anim.done( function() {
  						style.display = restoreDisplay;
  					} );
  					if ( restoreDisplay == null ) {
  						display = style.display;
  						restoreDisplay = display === "none" ? "" : display;
  					}
  				}
  				style.display = "inline-block";
  			}
  		}
  	}
  
  	if ( opts.overflow ) {
  		style.overflow = "hidden";
  		anim.always( function() {
  			style.overflow = opts.overflow[ 0 ];
  			style.overflowX = opts.overflow[ 1 ];
  			style.overflowY = opts.overflow[ 2 ];
  		} );
  	}
  
  	// Implement show/hide animations
  	propTween = false;
  	for ( prop in orig ) {
  
  		// General show/hide setup for this element animation
  		if ( !propTween ) {
  			if ( dataShow ) {
  				if ( "hidden" in dataShow ) {
  					hidden = dataShow.hidden;
  				}
  			} else {
  				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
  			}
  
  			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
  			if ( toggle ) {
  				dataShow.hidden = !hidden;
  			}
  
  			// Show elements before animating them
  			if ( hidden ) {
  				showHide( [ elem ], true );
  			}
  
  			/* eslint-disable no-loop-func */
  
  			anim.done( function() {
  
  			/* eslint-enable no-loop-func */
  
  				// The final step of a "hide" animation is actually hiding the element
  				if ( !hidden ) {
  					showHide( [ elem ] );
  				}
  				dataPriv.remove( elem, "fxshow" );
  				for ( prop in orig ) {
  					jQuery.style( elem, prop, orig[ prop ] );
  				}
  			} );
  		}
  
  		// Per-property setup
  		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  		if ( !( prop in dataShow ) ) {
  			dataShow[ prop ] = propTween.start;
  			if ( hidden ) {
  				propTween.end = propTween.start;
  				propTween.start = 0;
  			}
  		}
  	}
  }
  
  function propFilter( props, specialEasing ) {
  	var index, name, easing, value, hooks;
  
  	// camelCase, specialEasing and expand cssHook pass
  	for ( index in props ) {
  		name = camelCase( index );
  		easing = specialEasing[ name ];
  		value = props[ index ];
  		if ( Array.isArray( value ) ) {
  			easing = value[ 1 ];
  			value = props[ index ] = value[ 0 ];
  		}
  
  		if ( index !== name ) {
  			props[ name ] = value;
  			delete props[ index ];
  		}
  
  		hooks = jQuery.cssHooks[ name ];
  		if ( hooks && "expand" in hooks ) {
  			value = hooks.expand( value );
  			delete props[ name ];
  
  			// Not quite $.extend, this won't overwrite existing keys.
  			// Reusing 'index' because we have the correct "name"
  			for ( index in value ) {
  				if ( !( index in props ) ) {
  					props[ index ] = value[ index ];
  					specialEasing[ index ] = easing;
  				}
  			}
  		} else {
  			specialEasing[ name ] = easing;
  		}
  	}
  }
  
  function Animation( elem, properties, options ) {
  	var result,
  		stopped,
  		index = 0,
  		length = Animation.prefilters.length,
  		deferred = jQuery.Deferred().always( function() {
  
  			// Don't match elem in the :animated selector
  			delete tick.elem;
  		} ),
  		tick = function() {
  			if ( stopped ) {
  				return false;
  			}
  			var currentTime = fxNow || createFxNow(),
  				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  
  				// Support: Android 2.3 only
  				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
  				temp = remaining / animation.duration || 0,
  				percent = 1 - temp,
  				index = 0,
  				length = animation.tweens.length;
  
  			for ( ; index < length; index++ ) {
  				animation.tweens[ index ].run( percent );
  			}
  
  			deferred.notifyWith( elem, [ animation, percent, remaining ] );
  
  			// If there's more to do, yield
  			if ( percent < 1 && length ) {
  				return remaining;
  			}
  
  			// If this was an empty animation, synthesize a final progress notification
  			if ( !length ) {
  				deferred.notifyWith( elem, [ animation, 1, 0 ] );
  			}
  
  			// Resolve the animation and report its conclusion
  			deferred.resolveWith( elem, [ animation ] );
  			return false;
  		},
  		animation = deferred.promise( {
  			elem: elem,
  			props: jQuery.extend( {}, properties ),
  			opts: jQuery.extend( true, {
  				specialEasing: {},
  				easing: jQuery.easing._default
  			}, options ),
  			originalProperties: properties,
  			originalOptions: options,
  			startTime: fxNow || createFxNow(),
  			duration: options.duration,
  			tweens: [],
  			createTween: function( prop, end ) {
  				var tween = jQuery.Tween( elem, animation.opts, prop, end,
  						animation.opts.specialEasing[ prop ] || animation.opts.easing );
  				animation.tweens.push( tween );
  				return tween;
  			},
  			stop: function( gotoEnd ) {
  				var index = 0,
  
  					// If we are going to the end, we want to run all the tweens
  					// otherwise we skip this part
  					length = gotoEnd ? animation.tweens.length : 0;
  				if ( stopped ) {
  					return this;
  				}
  				stopped = true;
  				for ( ; index < length; index++ ) {
  					animation.tweens[ index ].run( 1 );
  				}
  
  				// Resolve when we played the last frame; otherwise, reject
  				if ( gotoEnd ) {
  					deferred.notifyWith( elem, [ animation, 1, 0 ] );
  					deferred.resolveWith( elem, [ animation, gotoEnd ] );
  				} else {
  					deferred.rejectWith( elem, [ animation, gotoEnd ] );
  				}
  				return this;
  			}
  		} ),
  		props = animation.props;
  
  	propFilter( props, animation.opts.specialEasing );
  
  	for ( ; index < length; index++ ) {
  		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
  		if ( result ) {
  			if ( isFunction( result.stop ) ) {
  				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
  					result.stop.bind( result );
  			}
  			return result;
  		}
  	}
  
  	jQuery.map( props, createTween, animation );
  
  	if ( isFunction( animation.opts.start ) ) {
  		animation.opts.start.call( elem, animation );
  	}
  
  	// Attach callbacks from options
  	animation
  		.progress( animation.opts.progress )
  		.done( animation.opts.done, animation.opts.complete )
  		.fail( animation.opts.fail )
  		.always( animation.opts.always );
  
  	jQuery.fx.timer(
  		jQuery.extend( tick, {
  			elem: elem,
  			anim: animation,
  			queue: animation.opts.queue
  		} )
  	);
  
  	return animation;
  }
  
  jQuery.Animation = jQuery.extend( Animation, {
  
  	tweeners: {
  		"*": [ function( prop, value ) {
  			var tween = this.createTween( prop, value );
  			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
  			return tween;
  		} ]
  	},
  
  	tweener: function( props, callback ) {
  		if ( isFunction( props ) ) {
  			callback = props;
  			props = [ "*" ];
  		} else {
  			props = props.match( rnothtmlwhite );
  		}
  
  		var prop,
  			index = 0,
  			length = props.length;
  
  		for ( ; index < length; index++ ) {
  			prop = props[ index ];
  			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
  			Animation.tweeners[ prop ].unshift( callback );
  		}
  	},
  
  	prefilters: [ defaultPrefilter ],
  
  	prefilter: function( callback, prepend ) {
  		if ( prepend ) {
  			Animation.prefilters.unshift( callback );
  		} else {
  			Animation.prefilters.push( callback );
  		}
  	}
  } );
  
  jQuery.speed = function( speed, easing, fn ) {
  	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  		complete: fn || !fn && easing ||
  			isFunction( speed ) && speed,
  		duration: speed,
  		easing: fn && easing || easing && !isFunction( easing ) && easing
  	};
  
  	// Go to the end state if fx are off
  	if ( jQuery.fx.off ) {
  		opt.duration = 0;
  
  	} else {
  		if ( typeof opt.duration !== "number" ) {
  			if ( opt.duration in jQuery.fx.speeds ) {
  				opt.duration = jQuery.fx.speeds[ opt.duration ];
  
  			} else {
  				opt.duration = jQuery.fx.speeds._default;
  			}
  		}
  	}
  
  	// Normalize opt.queue - true/undefined/null -> "fx"
  	if ( opt.queue == null || opt.queue === true ) {
  		opt.queue = "fx";
  	}
  
  	// Queueing
  	opt.old = opt.complete;
  
  	opt.complete = function() {
  		if ( isFunction( opt.old ) ) {
  			opt.old.call( this );
  		}
  
  		if ( opt.queue ) {
  			jQuery.dequeue( this, opt.queue );
  		}
  	};
  
  	return opt;
  };
  
  jQuery.fn.extend( {
  	fadeTo: function( speed, to, easing, callback ) {
  
  		// Show any hidden elements after setting opacity to 0
  		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
  
  			// Animate to the value specified
  			.end().animate( { opacity: to }, speed, easing, callback );
  	},
  	animate: function( prop, speed, easing, callback ) {
  		var empty = jQuery.isEmptyObject( prop ),
  			optall = jQuery.speed( speed, easing, callback ),
  			doAnimation = function() {
  
  				// Operate on a copy of prop so per-property easing won't be lost
  				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  
  				// Empty animations, or finishing resolves immediately
  				if ( empty || dataPriv.get( this, "finish" ) ) {
  					anim.stop( true );
  				}
  			};
  			doAnimation.finish = doAnimation;
  
  		return empty || optall.queue === false ?
  			this.each( doAnimation ) :
  			this.queue( optall.queue, doAnimation );
  	},
  	stop: function( type, clearQueue, gotoEnd ) {
  		var stopQueue = function( hooks ) {
  			var stop = hooks.stop;
  			delete hooks.stop;
  			stop( gotoEnd );
  		};
  
  		if ( typeof type !== "string" ) {
  			gotoEnd = clearQueue;
  			clearQueue = type;
  			type = undefined;
  		}
  		if ( clearQueue ) {
  			this.queue( type || "fx", [] );
  		}
  
  		return this.each( function() {
  			var dequeue = true,
  				index = type != null && type + "queueHooks",
  				timers = jQuery.timers,
  				data = dataPriv.get( this );
  
  			if ( index ) {
  				if ( data[ index ] && data[ index ].stop ) {
  					stopQueue( data[ index ] );
  				}
  			} else {
  				for ( index in data ) {
  					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  						stopQueue( data[ index ] );
  					}
  				}
  			}
  
  			for ( index = timers.length; index--; ) {
  				if ( timers[ index ].elem === this &&
  					( type == null || timers[ index ].queue === type ) ) {
  
  					timers[ index ].anim.stop( gotoEnd );
  					dequeue = false;
  					timers.splice( index, 1 );
  				}
  			}
  
  			// Start the next in the queue if the last step wasn't forced.
  			// Timers currently will call their complete callbacks, which
  			// will dequeue but only if they were gotoEnd.
  			if ( dequeue || !gotoEnd ) {
  				jQuery.dequeue( this, type );
  			}
  		} );
  	},
  	finish: function( type ) {
  		if ( type !== false ) {
  			type = type || "fx";
  		}
  		return this.each( function() {
  			var index,
  				data = dataPriv.get( this ),
  				queue = data[ type + "queue" ],
  				hooks = data[ type + "queueHooks" ],
  				timers = jQuery.timers,
  				length = queue ? queue.length : 0;
  
  			// Enable finishing flag on private data
  			data.finish = true;
  
  			// Empty the queue first
  			jQuery.queue( this, type, [] );
  
  			if ( hooks && hooks.stop ) {
  				hooks.stop.call( this, true );
  			}
  
  			// Look for any active animations, and finish them
  			for ( index = timers.length; index--; ) {
  				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  					timers[ index ].anim.stop( true );
  					timers.splice( index, 1 );
  				}
  			}
  
  			// Look for any animations in the old queue and finish them
  			for ( index = 0; index < length; index++ ) {
  				if ( queue[ index ] && queue[ index ].finish ) {
  					queue[ index ].finish.call( this );
  				}
  			}
  
  			// Turn off finishing flag
  			delete data.finish;
  		} );
  	}
  } );
  
  jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
  	var cssFn = jQuery.fn[ name ];
  	jQuery.fn[ name ] = function( speed, easing, callback ) {
  		return speed == null || typeof speed === "boolean" ?
  			cssFn.apply( this, arguments ) :
  			this.animate( genFx( name, true ), speed, easing, callback );
  	};
  } );
  
  // Generate shortcuts for custom animations
  jQuery.each( {
  	slideDown: genFx( "show" ),
  	slideUp: genFx( "hide" ),
  	slideToggle: genFx( "toggle" ),
  	fadeIn: { opacity: "show" },
  	fadeOut: { opacity: "hide" },
  	fadeToggle: { opacity: "toggle" }
  }, function( name, props ) {
  	jQuery.fn[ name ] = function( speed, easing, callback ) {
  		return this.animate( props, speed, easing, callback );
  	};
  } );
  
  jQuery.timers = [];
  jQuery.fx.tick = function() {
  	var timer,
  		i = 0,
  		timers = jQuery.timers;
  
  	fxNow = Date.now();
  
  	for ( ; i < timers.length; i++ ) {
  		timer = timers[ i ];
  
  		// Run the timer and safely remove it when done (allowing for external removal)
  		if ( !timer() && timers[ i ] === timer ) {
  			timers.splice( i--, 1 );
  		}
  	}
  
  	if ( !timers.length ) {
  		jQuery.fx.stop();
  	}
  	fxNow = undefined;
  };
  
  jQuery.fx.timer = function( timer ) {
  	jQuery.timers.push( timer );
  	jQuery.fx.start();
  };
  
  jQuery.fx.interval = 13;
  jQuery.fx.start = function() {
  	if ( inProgress ) {
  		return;
  	}
  
  	inProgress = true;
  	schedule();
  };
  
  jQuery.fx.stop = function() {
  	inProgress = null;
  };
  
  jQuery.fx.speeds = {
  	slow: 600,
  	fast: 200,
  
  	// Default speed
  	_default: 400
  };
  
  
  // Based off of the plugin by Clint Helfers, with permission.
  // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
  jQuery.fn.delay = function( time, type ) {
  	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  	type = type || "fx";
  
  	return this.queue( type, function( next, hooks ) {
  		var timeout = window.setTimeout( next, time );
  		hooks.stop = function() {
  			window.clearTimeout( timeout );
  		};
  	} );
  };
  
  
  ( function() {
  	var input = document.createElement( "input" ),
  		select = document.createElement( "select" ),
  		opt = select.appendChild( document.createElement( "option" ) );
  
  	input.type = "checkbox";
  
  	// Support: Android <=4.3 only
  	// Default value for a checkbox should be "on"
  	support.checkOn = input.value !== "";
  
  	// Support: IE <=11 only
  	// Must access selectedIndex to make default options select
  	support.optSelected = opt.selected;
  
  	// Support: IE <=11 only
  	// An input loses its value after becoming a radio
  	input = document.createElement( "input" );
  	input.value = "t";
  	input.type = "radio";
  	support.radioValue = input.value === "t";
  } )();
  
  
  var boolHook,
  	attrHandle = jQuery.expr.attrHandle;
  
  jQuery.fn.extend( {
  	attr: function( name, value ) {
  		return access( this, jQuery.attr, name, value, arguments.length > 1 );
  	},
  
  	removeAttr: function( name ) {
  		return this.each( function() {
  			jQuery.removeAttr( this, name );
  		} );
  	}
  } );
  
  jQuery.extend( {
  	attr: function( elem, name, value ) {
  		var ret, hooks,
  			nType = elem.nodeType;
  
  		// Don't get/set attributes on text, comment and attribute nodes
  		if ( nType === 3 || nType === 8 || nType === 2 ) {
  			return;
  		}
  
  		// Fallback to prop when attributes are not supported
  		if ( typeof elem.getAttribute === "undefined" ) {
  			return jQuery.prop( elem, name, value );
  		}
  
  		// Attribute hooks are determined by the lowercase version
  		// Grab necessary hook if one is defined
  		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
  				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
  		}
  
  		if ( value !== undefined ) {
  			if ( value === null ) {
  				jQuery.removeAttr( elem, name );
  				return;
  			}
  
  			if ( hooks && "set" in hooks &&
  				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  				return ret;
  			}
  
  			elem.setAttribute( name, value + "" );
  			return value;
  		}
  
  		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  			return ret;
  		}
  
  		ret = jQuery.find.attr( elem, name );
  
  		// Non-existent attributes return null, we normalize to undefined
  		return ret == null ? undefined : ret;
  	},
  
  	attrHooks: {
  		type: {
  			set: function( elem, value ) {
  				if ( !support.radioValue && value === "radio" &&
  					nodeName( elem, "input" ) ) {
  					var val = elem.value;
  					elem.setAttribute( "type", value );
  					if ( val ) {
  						elem.value = val;
  					}
  					return value;
  				}
  			}
  		}
  	},
  
  	removeAttr: function( elem, value ) {
  		var name,
  			i = 0,
  
  			// Attribute names can contain non-HTML whitespace characters
  			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
  			attrNames = value && value.match( rnothtmlwhite );
  
  		if ( attrNames && elem.nodeType === 1 ) {
  			while ( ( name = attrNames[ i++ ] ) ) {
  				elem.removeAttribute( name );
  			}
  		}
  	}
  } );
  
  // Hooks for boolean attributes
  boolHook = {
  	set: function( elem, value, name ) {
  		if ( value === false ) {
  
  			// Remove boolean attributes when set to false
  			jQuery.removeAttr( elem, name );
  		} else {
  			elem.setAttribute( name, name );
  		}
  		return name;
  	}
  };
  
  jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
  	var getter = attrHandle[ name ] || jQuery.find.attr;
  
  	attrHandle[ name ] = function( elem, name, isXML ) {
  		var ret, handle,
  			lowercaseName = name.toLowerCase();
  
  		if ( !isXML ) {
  
  			// Avoid an infinite loop by temporarily removing this function from the getter
  			handle = attrHandle[ lowercaseName ];
  			attrHandle[ lowercaseName ] = ret;
  			ret = getter( elem, name, isXML ) != null ?
  				lowercaseName :
  				null;
  			attrHandle[ lowercaseName ] = handle;
  		}
  		return ret;
  	};
  } );
  
  
  
  
  var rfocusable = /^(?:input|select|textarea|button)$/i,
  	rclickable = /^(?:a|area)$/i;
  
  jQuery.fn.extend( {
  	prop: function( name, value ) {
  		return access( this, jQuery.prop, name, value, arguments.length > 1 );
  	},
  
  	removeProp: function( name ) {
  		return this.each( function() {
  			delete this[ jQuery.propFix[ name ] || name ];
  		} );
  	}
  } );
  
  jQuery.extend( {
  	prop: function( elem, name, value ) {
  		var ret, hooks,
  			nType = elem.nodeType;
  
  		// Don't get/set properties on text, comment and attribute nodes
  		if ( nType === 3 || nType === 8 || nType === 2 ) {
  			return;
  		}
  
  		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  
  			// Fix name and attach hooks
  			name = jQuery.propFix[ name ] || name;
  			hooks = jQuery.propHooks[ name ];
  		}
  
  		if ( value !== undefined ) {
  			if ( hooks && "set" in hooks &&
  				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  				return ret;
  			}
  
  			return ( elem[ name ] = value );
  		}
  
  		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  			return ret;
  		}
  
  		return elem[ name ];
  	},
  
  	propHooks: {
  		tabIndex: {
  			get: function( elem ) {
  
  				// Support: IE <=9 - 11 only
  				// elem.tabIndex doesn't always return the
  				// correct value when it hasn't been explicitly set
  				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  				// Use proper attribute retrieval(#12072)
  				var tabindex = jQuery.find.attr( elem, "tabindex" );
  
  				if ( tabindex ) {
  					return parseInt( tabindex, 10 );
  				}
  
  				if (
  					rfocusable.test( elem.nodeName ) ||
  					rclickable.test( elem.nodeName ) &&
  					elem.href
  				) {
  					return 0;
  				}
  
  				return -1;
  			}
  		}
  	},
  
  	propFix: {
  		"for": "htmlFor",
  		"class": "className"
  	}
  } );
  
  // Support: IE <=11 only
  // Accessing the selectedIndex property
  // forces the browser to respect setting selected
  // on the option
  // The getter ensures a default option is selected
  // when in an optgroup
  // eslint rule "no-unused-expressions" is disabled for this code
  // since it considers such accessions noop
  if ( !support.optSelected ) {
  	jQuery.propHooks.selected = {
  		get: function( elem ) {
  
  			/* eslint no-unused-expressions: "off" */
  
  			var parent = elem.parentNode;
  			if ( parent && parent.parentNode ) {
  				parent.parentNode.selectedIndex;
  			}
  			return null;
  		},
  		set: function( elem ) {
  
  			/* eslint no-unused-expressions: "off" */
  
  			var parent = elem.parentNode;
  			if ( parent ) {
  				parent.selectedIndex;
  
  				if ( parent.parentNode ) {
  					parent.parentNode.selectedIndex;
  				}
  			}
  		}
  	};
  }
  
  jQuery.each( [
  	"tabIndex",
  	"readOnly",
  	"maxLength",
  	"cellSpacing",
  	"cellPadding",
  	"rowSpan",
  	"colSpan",
  	"useMap",
  	"frameBorder",
  	"contentEditable"
  ], function() {
  	jQuery.propFix[ this.toLowerCase() ] = this;
  } );
  
  
  
  
  	// Strip and collapse whitespace according to HTML spec
  	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
  	function stripAndCollapse( value ) {
  		var tokens = value.match( rnothtmlwhite ) || [];
  		return tokens.join( " " );
  	}
  
  
  function getClass( elem ) {
  	return elem.getAttribute && elem.getAttribute( "class" ) || "";
  }
  
  function classesToArray( value ) {
  	if ( Array.isArray( value ) ) {
  		return value;
  	}
  	if ( typeof value === "string" ) {
  		return value.match( rnothtmlwhite ) || [];
  	}
  	return [];
  }
  
  jQuery.fn.extend( {
  	addClass: function( value ) {
  		var classes, elem, cur, curValue, clazz, j, finalValue,
  			i = 0;
  
  		if ( isFunction( value ) ) {
  			return this.each( function( j ) {
  				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
  			} );
  		}
  
  		classes = classesToArray( value );
  
  		if ( classes.length ) {
  			while ( ( elem = this[ i++ ] ) ) {
  				curValue = getClass( elem );
  				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
  
  				if ( cur ) {
  					j = 0;
  					while ( ( clazz = classes[ j++ ] ) ) {
  						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  							cur += clazz + " ";
  						}
  					}
  
  					// Only assign if different to avoid unneeded rendering.
  					finalValue = stripAndCollapse( cur );
  					if ( curValue !== finalValue ) {
  						elem.setAttribute( "class", finalValue );
  					}
  				}
  			}
  		}
  
  		return this;
  	},
  
  	removeClass: function( value ) {
  		var classes, elem, cur, curValue, clazz, j, finalValue,
  			i = 0;
  
  		if ( isFunction( value ) ) {
  			return this.each( function( j ) {
  				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
  			} );
  		}
  
  		if ( !arguments.length ) {
  			return this.attr( "class", "" );
  		}
  
  		classes = classesToArray( value );
  
  		if ( classes.length ) {
  			while ( ( elem = this[ i++ ] ) ) {
  				curValue = getClass( elem );
  
  				// This expression is here for better compressibility (see addClass)
  				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
  
  				if ( cur ) {
  					j = 0;
  					while ( ( clazz = classes[ j++ ] ) ) {
  
  						// Remove *all* instances
  						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
  							cur = cur.replace( " " + clazz + " ", " " );
  						}
  					}
  
  					// Only assign if different to avoid unneeded rendering.
  					finalValue = stripAndCollapse( cur );
  					if ( curValue !== finalValue ) {
  						elem.setAttribute( "class", finalValue );
  					}
  				}
  			}
  		}
  
  		return this;
  	},
  
  	toggleClass: function( value, stateVal ) {
  		var type = typeof value,
  			isValidValue = type === "string" || Array.isArray( value );
  
  		if ( typeof stateVal === "boolean" && isValidValue ) {
  			return stateVal ? this.addClass( value ) : this.removeClass( value );
  		}
  
  		if ( isFunction( value ) ) {
  			return this.each( function( i ) {
  				jQuery( this ).toggleClass(
  					value.call( this, i, getClass( this ), stateVal ),
  					stateVal
  				);
  			} );
  		}
  
  		return this.each( function() {
  			var className, i, self, classNames;
  
  			if ( isValidValue ) {
  
  				// Toggle individual class names
  				i = 0;
  				self = jQuery( this );
  				classNames = classesToArray( value );
  
  				while ( ( className = classNames[ i++ ] ) ) {
  
  					// Check each className given, space separated list
  					if ( self.hasClass( className ) ) {
  						self.removeClass( className );
  					} else {
  						self.addClass( className );
  					}
  				}
  
  			// Toggle whole class name
  			} else if ( value === undefined || type === "boolean" ) {
  				className = getClass( this );
  				if ( className ) {
  
  					// Store className if set
  					dataPriv.set( this, "__className__", className );
  				}
  
  				// If the element has a class name or if we're passed `false`,
  				// then remove the whole classname (if there was one, the above saved it).
  				// Otherwise bring back whatever was previously saved (if anything),
  				// falling back to the empty string if nothing was stored.
  				if ( this.setAttribute ) {
  					this.setAttribute( "class",
  						className || value === false ?
  						"" :
  						dataPriv.get( this, "__className__" ) || ""
  					);
  				}
  			}
  		} );
  	},
  
  	hasClass: function( selector ) {
  		var className, elem,
  			i = 0;
  
  		className = " " + selector + " ";
  		while ( ( elem = this[ i++ ] ) ) {
  			if ( elem.nodeType === 1 &&
  				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
  					return true;
  			}
  		}
  
  		return false;
  	}
  } );
  
  
  
  
  var rreturn = /\r/g;
  
  jQuery.fn.extend( {
  	val: function( value ) {
  		var hooks, ret, valueIsFunction,
  			elem = this[ 0 ];
  
  		if ( !arguments.length ) {
  			if ( elem ) {
  				hooks = jQuery.valHooks[ elem.type ] ||
  					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  
  				if ( hooks &&
  					"get" in hooks &&
  					( ret = hooks.get( elem, "value" ) ) !== undefined
  				) {
  					return ret;
  				}
  
  				ret = elem.value;
  
  				// Handle most common string cases
  				if ( typeof ret === "string" ) {
  					return ret.replace( rreturn, "" );
  				}
  
  				// Handle cases where value is null/undef or number
  				return ret == null ? "" : ret;
  			}
  
  			return;
  		}
  
  		valueIsFunction = isFunction( value );
  
  		return this.each( function( i ) {
  			var val;
  
  			if ( this.nodeType !== 1 ) {
  				return;
  			}
  
  			if ( valueIsFunction ) {
  				val = value.call( this, i, jQuery( this ).val() );
  			} else {
  				val = value;
  			}
  
  			// Treat null/undefined as ""; convert numbers to string
  			if ( val == null ) {
  				val = "";
  
  			} else if ( typeof val === "number" ) {
  				val += "";
  
  			} else if ( Array.isArray( val ) ) {
  				val = jQuery.map( val, function( value ) {
  					return value == null ? "" : value + "";
  				} );
  			}
  
  			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  
  			// If set returns undefined, fall back to normal setting
  			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
  				this.value = val;
  			}
  		} );
  	}
  } );
  
  jQuery.extend( {
  	valHooks: {
  		option: {
  			get: function( elem ) {
  
  				var val = jQuery.find.attr( elem, "value" );
  				return val != null ?
  					val :
  
  					// Support: IE <=10 - 11 only
  					// option.text throws exceptions (#14686, #14858)
  					// Strip and collapse whitespace
  					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
  					stripAndCollapse( jQuery.text( elem ) );
  			}
  		},
  		select: {
  			get: function( elem ) {
  				var value, option, i,
  					options = elem.options,
  					index = elem.selectedIndex,
  					one = elem.type === "select-one",
  					values = one ? null : [],
  					max = one ? index + 1 : options.length;
  
  				if ( index < 0 ) {
  					i = max;
  
  				} else {
  					i = one ? index : 0;
  				}
  
  				// Loop through all the selected options
  				for ( ; i < max; i++ ) {
  					option = options[ i ];
  
  					// Support: IE <=9 only
  					// IE8-9 doesn't update selected after form reset (#2551)
  					if ( ( option.selected || i === index ) &&
  
  							// Don't return options that are disabled or in a disabled optgroup
  							!option.disabled &&
  							( !option.parentNode.disabled ||
  								!nodeName( option.parentNode, "optgroup" ) ) ) {
  
  						// Get the specific value for the option
  						value = jQuery( option ).val();
  
  						// We don't need an array for one selects
  						if ( one ) {
  							return value;
  						}
  
  						// Multi-Selects return an array
  						values.push( value );
  					}
  				}
  
  				return values;
  			},
  
  			set: function( elem, value ) {
  				var optionSet, option,
  					options = elem.options,
  					values = jQuery.makeArray( value ),
  					i = options.length;
  
  				while ( i-- ) {
  					option = options[ i ];
  
  					/* eslint-disable no-cond-assign */
  
  					if ( option.selected =
  						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
  					) {
  						optionSet = true;
  					}
  
  					/* eslint-enable no-cond-assign */
  				}
  
  				// Force browsers to behave consistently when non-matching value is set
  				if ( !optionSet ) {
  					elem.selectedIndex = -1;
  				}
  				return values;
  			}
  		}
  	}
  } );
  
  // Radios and checkboxes getter/setter
  jQuery.each( [ "radio", "checkbox" ], function() {
  	jQuery.valHooks[ this ] = {
  		set: function( elem, value ) {
  			if ( Array.isArray( value ) ) {
  				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
  			}
  		}
  	};
  	if ( !support.checkOn ) {
  		jQuery.valHooks[ this ].get = function( elem ) {
  			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
  		};
  	}
  } );
  
  
  
  
  // Return jQuery for attributes-only inclusion
  
  
  support.focusin = "onfocusin" in window;
  
  
  var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  	stopPropagationCallback = function( e ) {
  		e.stopPropagation();
  	};
  
  jQuery.extend( jQuery.event, {
  
  	trigger: function( event, data, elem, onlyHandlers ) {
  
  		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
  			eventPath = [ elem || document ],
  			type = hasOwn.call( event, "type" ) ? event.type : event,
  			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
  
  		cur = lastElement = tmp = elem = elem || document;
  
  		// Don't do events on text and comment nodes
  		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  			return;
  		}
  
  		// focus/blur morphs to focusin/out; ensure we're not firing them right now
  		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  			return;
  		}
  
  		if ( type.indexOf( "." ) > -1 ) {
  
  			// Namespaced trigger; create a regexp to match event type in handle()
  			namespaces = type.split( "." );
  			type = namespaces.shift();
  			namespaces.sort();
  		}
  		ontype = type.indexOf( ":" ) < 0 && "on" + type;
  
  		// Caller can pass in a jQuery.Event object, Object, or just an event type string
  		event = event[ jQuery.expando ] ?
  			event :
  			new jQuery.Event( type, typeof event === "object" && event );
  
  		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  		event.isTrigger = onlyHandlers ? 2 : 3;
  		event.namespace = namespaces.join( "." );
  		event.rnamespace = event.namespace ?
  			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
  			null;
  
  		// Clean up the event in case it is being reused
  		event.result = undefined;
  		if ( !event.target ) {
  			event.target = elem;
  		}
  
  		// Clone any incoming data and prepend the event, creating the handler arg list
  		data = data == null ?
  			[ event ] :
  			jQuery.makeArray( data, [ event ] );
  
  		// Allow special events to draw outside the lines
  		special = jQuery.event.special[ type ] || {};
  		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  			return;
  		}
  
  		// Determine event propagation path in advance, per W3C events spec (#9951)
  		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
  
  			bubbleType = special.delegateType || type;
  			if ( !rfocusMorph.test( bubbleType + type ) ) {
  				cur = cur.parentNode;
  			}
  			for ( ; cur; cur = cur.parentNode ) {
  				eventPath.push( cur );
  				tmp = cur;
  			}
  
  			// Only add window if we got to document (e.g., not plain obj or detached DOM)
  			if ( tmp === ( elem.ownerDocument || document ) ) {
  				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  			}
  		}
  
  		// Fire handlers on the event path
  		i = 0;
  		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
  			lastElement = cur;
  			event.type = i > 1 ?
  				bubbleType :
  				special.bindType || type;
  
  			// jQuery handler
  			handle = (
  					dataPriv.get( cur, "events" ) || Object.create( null )
  				)[ event.type ] &&
  				dataPriv.get( cur, "handle" );
  			if ( handle ) {
  				handle.apply( cur, data );
  			}
  
  			// Native handler
  			handle = ontype && cur[ ontype ];
  			if ( handle && handle.apply && acceptData( cur ) ) {
  				event.result = handle.apply( cur, data );
  				if ( event.result === false ) {
  					event.preventDefault();
  				}
  			}
  		}
  		event.type = type;
  
  		// If nobody prevented the default action, do it now
  		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  
  			if ( ( !special._default ||
  				special._default.apply( eventPath.pop(), data ) === false ) &&
  				acceptData( elem ) ) {
  
  				// Call a native DOM method on the target with the same name as the event.
  				// Don't do default actions on window, that's where global variables be (#6170)
  				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
  
  					// Don't re-trigger an onFOO event when we call its FOO() method
  					tmp = elem[ ontype ];
  
  					if ( tmp ) {
  						elem[ ontype ] = null;
  					}
  
  					// Prevent re-triggering of the same event, since we already bubbled it above
  					jQuery.event.triggered = type;
  
  					if ( event.isPropagationStopped() ) {
  						lastElement.addEventListener( type, stopPropagationCallback );
  					}
  
  					elem[ type ]();
  
  					if ( event.isPropagationStopped() ) {
  						lastElement.removeEventListener( type, stopPropagationCallback );
  					}
  
  					jQuery.event.triggered = undefined;
  
  					if ( tmp ) {
  						elem[ ontype ] = tmp;
  					}
  				}
  			}
  		}
  
  		return event.result;
  	},
  
  	// Piggyback on a donor event to simulate a different one
  	// Used only for `focus(in | out)` events
  	simulate: function( type, elem, event ) {
  		var e = jQuery.extend(
  			new jQuery.Event(),
  			event,
  			{
  				type: type,
  				isSimulated: true
  			}
  		);
  
  		jQuery.event.trigger( e, null, elem );
  	}
  
  } );
  
  jQuery.fn.extend( {
  
  	trigger: function( type, data ) {
  		return this.each( function() {
  			jQuery.event.trigger( type, data, this );
  		} );
  	},
  	triggerHandler: function( type, data ) {
  		var elem = this[ 0 ];
  		if ( elem ) {
  			return jQuery.event.trigger( type, data, elem, true );
  		}
  	}
  } );
  
  
  // Support: Firefox <=44
  // Firefox doesn't have focus(in | out) events
  // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
  //
  // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
  // focus(in | out) events fire after focus & blur events,
  // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
  // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
  if ( !support.focusin ) {
  	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  
  		// Attach a single capturing handler on the document while someone wants focusin/focusout
  		var handler = function( event ) {
  			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
  		};
  
  		jQuery.event.special[ fix ] = {
  			setup: function() {
  
  				// Handle: regular nodes (via `this.ownerDocument`), window
  				// (via `this.document`) & document (via `this`).
  				var doc = this.ownerDocument || this.document || this,
  					attaches = dataPriv.access( doc, fix );
  
  				if ( !attaches ) {
  					doc.addEventListener( orig, handler, true );
  				}
  				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
  			},
  			teardown: function() {
  				var doc = this.ownerDocument || this.document || this,
  					attaches = dataPriv.access( doc, fix ) - 1;
  
  				if ( !attaches ) {
  					doc.removeEventListener( orig, handler, true );
  					dataPriv.remove( doc, fix );
  
  				} else {
  					dataPriv.access( doc, fix, attaches );
  				}
  			}
  		};
  	} );
  }
  var location = window.location;
  
  var nonce = { guid: Date.now() };
  
  var rquery = ( /\?/ );
  
  
  
  // Cross-browser xml parsing
  jQuery.parseXML = function( data ) {
  	var xml;
  	if ( !data || typeof data !== "string" ) {
  		return null;
  	}
  
  	// Support: IE 9 - 11 only
  	// IE throws on parseFromString with invalid input.
  	try {
  		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
  	} catch ( e ) {
  		xml = undefined;
  	}
  
  	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
  		jQuery.error( "Invalid XML: " + data );
  	}
  	return xml;
  };
  
  
  var
  	rbracket = /\[\]$/,
  	rCRLF = /\r?\n/g,
  	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  	rsubmittable = /^(?:input|select|textarea|keygen)/i;
  
  function buildParams( prefix, obj, traditional, add ) {
  	var name;
  
  	if ( Array.isArray( obj ) ) {
  
  		// Serialize array item.
  		jQuery.each( obj, function( i, v ) {
  			if ( traditional || rbracket.test( prefix ) ) {
  
  				// Treat each array item as a scalar.
  				add( prefix, v );
  
  			} else {
  
  				// Item is non-scalar (array or object), encode its numeric index.
  				buildParams(
  					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
  					v,
  					traditional,
  					add
  				);
  			}
  		} );
  
  	} else if ( !traditional && toType( obj ) === "object" ) {
  
  		// Serialize object item.
  		for ( name in obj ) {
  			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  		}
  
  	} else {
  
  		// Serialize scalar item.
  		add( prefix, obj );
  	}
  }
  
  // Serialize an array of form elements or a set of
  // key/values into a query string
  jQuery.param = function( a, traditional ) {
  	var prefix,
  		s = [],
  		add = function( key, valueOrFunction ) {
  
  			// If value is a function, invoke it and use its return value
  			var value = isFunction( valueOrFunction ) ?
  				valueOrFunction() :
  				valueOrFunction;
  
  			s[ s.length ] = encodeURIComponent( key ) + "=" +
  				encodeURIComponent( value == null ? "" : value );
  		};
  
  	if ( a == null ) {
  		return "";
  	}
  
  	// If an array was passed in, assume that it is an array of form elements.
  	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  
  		// Serialize the form elements
  		jQuery.each( a, function() {
  			add( this.name, this.value );
  		} );
  
  	} else {
  
  		// If traditional, encode the "old" way (the way 1.3.2 or older
  		// did it), otherwise encode params recursively.
  		for ( prefix in a ) {
  			buildParams( prefix, a[ prefix ], traditional, add );
  		}
  	}
  
  	// Return the resulting serialization
  	return s.join( "&" );
  };
  
  jQuery.fn.extend( {
  	serialize: function() {
  		return jQuery.param( this.serializeArray() );
  	},
  	serializeArray: function() {
  		return this.map( function() {
  
  			// Can add propHook for "elements" to filter or add form elements
  			var elements = jQuery.prop( this, "elements" );
  			return elements ? jQuery.makeArray( elements ) : this;
  		} )
  		.filter( function() {
  			var type = this.type;
  
  			// Use .is( ":disabled" ) so that fieldset[disabled] works
  			return this.name && !jQuery( this ).is( ":disabled" ) &&
  				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  				( this.checked || !rcheckableType.test( type ) );
  		} )
  		.map( function( _i, elem ) {
  			var val = jQuery( this ).val();
  
  			if ( val == null ) {
  				return null;
  			}
  
  			if ( Array.isArray( val ) ) {
  				return jQuery.map( val, function( val ) {
  					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  				} );
  			}
  
  			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  		} ).get();
  	}
  } );
  
  
  var
  	r20 = /%20/g,
  	rhash = /#.*$/,
  	rantiCache = /([?&])_=[^&]*/,
  	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
  
  	// #7653, #8125, #8152: local protocol detection
  	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  	rnoContent = /^(?:GET|HEAD)$/,
  	rprotocol = /^\/\//,
  
  	/* Prefilters
  	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  	 * 2) These are called:
  	 *    - BEFORE asking for a transport
  	 *    - AFTER param serialization (s.data is a string if s.processData is true)
  	 * 3) key is the dataType
  	 * 4) the catchall symbol "*" can be used
  	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  	 */
  	prefilters = {},
  
  	/* Transports bindings
  	 * 1) key is the dataType
  	 * 2) the catchall symbol "*" can be used
  	 * 3) selection will start with transport dataType and THEN go to "*" if needed
  	 */
  	transports = {},
  
  	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  	allTypes = "*/".concat( "*" ),
  
  	// Anchor tag for parsing the document origin
  	originAnchor = document.createElement( "a" );
  	originAnchor.href = location.href;
  
  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  function addToPrefiltersOrTransports( structure ) {
  
  	// dataTypeExpression is optional and defaults to "*"
  	return function( dataTypeExpression, func ) {
  
  		if ( typeof dataTypeExpression !== "string" ) {
  			func = dataTypeExpression;
  			dataTypeExpression = "*";
  		}
  
  		var dataType,
  			i = 0,
  			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
  
  		if ( isFunction( func ) ) {
  
  			// For each dataType in the dataTypeExpression
  			while ( ( dataType = dataTypes[ i++ ] ) ) {
  
  				// Prepend if requested
  				if ( dataType[ 0 ] === "+" ) {
  					dataType = dataType.slice( 1 ) || "*";
  					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
  
  				// Otherwise append
  				} else {
  					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
  				}
  			}
  		}
  	};
  }
  
  // Base inspection function for prefilters and transports
  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  
  	var inspected = {},
  		seekingTransport = ( structure === transports );
  
  	function inspect( dataType ) {
  		var selected;
  		inspected[ dataType ] = true;
  		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  			if ( typeof dataTypeOrTransport === "string" &&
  				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  
  				options.dataTypes.unshift( dataTypeOrTransport );
  				inspect( dataTypeOrTransport );
  				return false;
  			} else if ( seekingTransport ) {
  				return !( selected = dataTypeOrTransport );
  			}
  		} );
  		return selected;
  	}
  
  	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  }
  
  // A special extend for ajax options
  // that takes "flat" options (not to be deep extended)
  // Fixes #9887
  function ajaxExtend( target, src ) {
  	var key, deep,
  		flatOptions = jQuery.ajaxSettings.flatOptions || {};
  
  	for ( key in src ) {
  		if ( src[ key ] !== undefined ) {
  			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
  		}
  	}
  	if ( deep ) {
  		jQuery.extend( true, target, deep );
  	}
  
  	return target;
  }
  
  /* Handles responses to an ajax request:
   * - finds the right dataType (mediates between content-type and expected dataType)
   * - returns the corresponding response
   */
  function ajaxHandleResponses( s, jqXHR, responses ) {
  
  	var ct, type, finalDataType, firstDataType,
  		contents = s.contents,
  		dataTypes = s.dataTypes;
  
  	// Remove auto dataType and get content-type in the process
  	while ( dataTypes[ 0 ] === "*" ) {
  		dataTypes.shift();
  		if ( ct === undefined ) {
  			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
  		}
  	}
  
  	// Check if we're dealing with a known content-type
  	if ( ct ) {
  		for ( type in contents ) {
  			if ( contents[ type ] && contents[ type ].test( ct ) ) {
  				dataTypes.unshift( type );
  				break;
  			}
  		}
  	}
  
  	// Check to see if we have a response for the expected dataType
  	if ( dataTypes[ 0 ] in responses ) {
  		finalDataType = dataTypes[ 0 ];
  	} else {
  
  		// Try convertible dataTypes
  		for ( type in responses ) {
  			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
  				finalDataType = type;
  				break;
  			}
  			if ( !firstDataType ) {
  				firstDataType = type;
  			}
  		}
  
  		// Or just use first one
  		finalDataType = finalDataType || firstDataType;
  	}
  
  	// If we found a dataType
  	// We add the dataType to the list if needed
  	// and return the corresponding response
  	if ( finalDataType ) {
  		if ( finalDataType !== dataTypes[ 0 ] ) {
  			dataTypes.unshift( finalDataType );
  		}
  		return responses[ finalDataType ];
  	}
  }
  
  /* Chain conversions given the request and the original response
   * Also sets the responseXXX fields on the jqXHR instance
   */
  function ajaxConvert( s, response, jqXHR, isSuccess ) {
  	var conv2, current, conv, tmp, prev,
  		converters = {},
  
  		// Work with a copy of dataTypes in case we need to modify it for conversion
  		dataTypes = s.dataTypes.slice();
  
  	// Create converters map with lowercased keys
  	if ( dataTypes[ 1 ] ) {
  		for ( conv in s.converters ) {
  			converters[ conv.toLowerCase() ] = s.converters[ conv ];
  		}
  	}
  
  	current = dataTypes.shift();
  
  	// Convert to each sequential dataType
  	while ( current ) {
  
  		if ( s.responseFields[ current ] ) {
  			jqXHR[ s.responseFields[ current ] ] = response;
  		}
  
  		// Apply the dataFilter if provided
  		if ( !prev && isSuccess && s.dataFilter ) {
  			response = s.dataFilter( response, s.dataType );
  		}
  
  		prev = current;
  		current = dataTypes.shift();
  
  		if ( current ) {
  
  			// There's only work to do if current dataType is non-auto
  			if ( current === "*" ) {
  
  				current = prev;
  
  			// Convert response if prev dataType is non-auto and differs from current
  			} else if ( prev !== "*" && prev !== current ) {
  
  				// Seek a direct converter
  				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  
  				// If none found, seek a pair
  				if ( !conv ) {
  					for ( conv2 in converters ) {
  
  						// If conv2 outputs current
  						tmp = conv2.split( " " );
  						if ( tmp[ 1 ] === current ) {
  
  							// If prev can be converted to accepted input
  							conv = converters[ prev + " " + tmp[ 0 ] ] ||
  								converters[ "* " + tmp[ 0 ] ];
  							if ( conv ) {
  
  								// Condense equivalence converters
  								if ( conv === true ) {
  									conv = converters[ conv2 ];
  
  								// Otherwise, insert the intermediate dataType
  								} else if ( converters[ conv2 ] !== true ) {
  									current = tmp[ 0 ];
  									dataTypes.unshift( tmp[ 1 ] );
  								}
  								break;
  							}
  						}
  					}
  				}
  
  				// Apply converter (if not an equivalence)
  				if ( conv !== true ) {
  
  					// Unless errors are allowed to bubble, catch and return them
  					if ( conv && s.throws ) {
  						response = conv( response );
  					} else {
  						try {
  							response = conv( response );
  						} catch ( e ) {
  							return {
  								state: "parsererror",
  								error: conv ? e : "No conversion from " + prev + " to " + current
  							};
  						}
  					}
  				}
  			}
  		}
  	}
  
  	return { state: "success", data: response };
  }
  
  jQuery.extend( {
  
  	// Counter for holding the number of active queries
  	active: 0,
  
  	// Last-Modified header cache for next request
  	lastModified: {},
  	etag: {},
  
  	ajaxSettings: {
  		url: location.href,
  		type: "GET",
  		isLocal: rlocalProtocol.test( location.protocol ),
  		global: true,
  		processData: true,
  		async: true,
  		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  
  		/*
  		timeout: 0,
  		data: null,
  		dataType: null,
  		username: null,
  		password: null,
  		cache: null,
  		throws: false,
  		traditional: false,
  		headers: {},
  		*/
  
  		accepts: {
  			"*": allTypes,
  			text: "text/plain",
  			html: "text/html",
  			xml: "application/xml, text/xml",
  			json: "application/json, text/javascript"
  		},
  
  		contents: {
  			xml: /\bxml\b/,
  			html: /\bhtml/,
  			json: /\bjson\b/
  		},
  
  		responseFields: {
  			xml: "responseXML",
  			text: "responseText",
  			json: "responseJSON"
  		},
  
  		// Data converters
  		// Keys separate source (or catchall "*") and destination types with a single space
  		converters: {
  
  			// Convert anything to text
  			"* text": String,
  
  			// Text to html (true = no transformation)
  			"text html": true,
  
  			// Evaluate text as a json expression
  			"text json": JSON.parse,
  
  			// Parse text as xml
  			"text xml": jQuery.parseXML
  		},
  
  		// For options that shouldn't be deep extended:
  		// you can add your own custom options here if
  		// and when you create one that shouldn't be
  		// deep extended (see ajaxExtend)
  		flatOptions: {
  			url: true,
  			context: true
  		}
  	},
  
  	// Creates a full fledged settings object into target
  	// with both ajaxSettings and settings fields.
  	// If target is omitted, writes into ajaxSettings.
  	ajaxSetup: function( target, settings ) {
  		return settings ?
  
  			// Building a settings object
  			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  
  			// Extending ajaxSettings
  			ajaxExtend( jQuery.ajaxSettings, target );
  	},
  
  	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  	ajaxTransport: addToPrefiltersOrTransports( transports ),
  
  	// Main method
  	ajax: function( url, options ) {
  
  		// If url is an object, simulate pre-1.5 signature
  		if ( typeof url === "object" ) {
  			options = url;
  			url = undefined;
  		}
  
  		// Force options to be an object
  		options = options || {};
  
  		var transport,
  
  			// URL without anti-cache param
  			cacheURL,
  
  			// Response headers
  			responseHeadersString,
  			responseHeaders,
  
  			// timeout handle
  			timeoutTimer,
  
  			// Url cleanup var
  			urlAnchor,
  
  			// Request state (becomes false upon send and true upon completion)
  			completed,
  
  			// To know if global events are to be dispatched
  			fireGlobals,
  
  			// Loop variable
  			i,
  
  			// uncached part of the url
  			uncached,
  
  			// Create the final options object
  			s = jQuery.ajaxSetup( {}, options ),
  
  			// Callbacks context
  			callbackContext = s.context || s,
  
  			// Context for global events is callbackContext if it is a DOM node or jQuery collection
  			globalEventContext = s.context &&
  				( callbackContext.nodeType || callbackContext.jquery ) ?
  					jQuery( callbackContext ) :
  					jQuery.event,
  
  			// Deferreds
  			deferred = jQuery.Deferred(),
  			completeDeferred = jQuery.Callbacks( "once memory" ),
  
  			// Status-dependent callbacks
  			statusCode = s.statusCode || {},
  
  			// Headers (they are sent all at once)
  			requestHeaders = {},
  			requestHeadersNames = {},
  
  			// Default abort message
  			strAbort = "canceled",
  
  			// Fake xhr
  			jqXHR = {
  				readyState: 0,
  
  				// Builds headers hashtable if needed
  				getResponseHeader: function( key ) {
  					var match;
  					if ( completed ) {
  						if ( !responseHeaders ) {
  							responseHeaders = {};
  							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
  								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
  									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
  										.concat( match[ 2 ] );
  							}
  						}
  						match = responseHeaders[ key.toLowerCase() + " " ];
  					}
  					return match == null ? null : match.join( ", " );
  				},
  
  				// Raw string
  				getAllResponseHeaders: function() {
  					return completed ? responseHeadersString : null;
  				},
  
  				// Caches the header
  				setRequestHeader: function( name, value ) {
  					if ( completed == null ) {
  						name = requestHeadersNames[ name.toLowerCase() ] =
  							requestHeadersNames[ name.toLowerCase() ] || name;
  						requestHeaders[ name ] = value;
  					}
  					return this;
  				},
  
  				// Overrides response content-type header
  				overrideMimeType: function( type ) {
  					if ( completed == null ) {
  						s.mimeType = type;
  					}
  					return this;
  				},
  
  				// Status-dependent callbacks
  				statusCode: function( map ) {
  					var code;
  					if ( map ) {
  						if ( completed ) {
  
  							// Execute the appropriate callbacks
  							jqXHR.always( map[ jqXHR.status ] );
  						} else {
  
  							// Lazy-add the new callbacks in a way that preserves old ones
  							for ( code in map ) {
  								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  							}
  						}
  					}
  					return this;
  				},
  
  				// Cancel the request
  				abort: function( statusText ) {
  					var finalText = statusText || strAbort;
  					if ( transport ) {
  						transport.abort( finalText );
  					}
  					done( 0, finalText );
  					return this;
  				}
  			};
  
  		// Attach deferreds
  		deferred.promise( jqXHR );
  
  		// Add protocol if not provided (prefilters might expect it)
  		// Handle falsy url in the settings object (#10093: consistency with old signature)
  		// We also use the url parameter if available
  		s.url = ( ( url || s.url || location.href ) + "" )
  			.replace( rprotocol, location.protocol + "//" );
  
  		// Alias method option to type as per ticket #12004
  		s.type = options.method || options.type || s.method || s.type;
  
  		// Extract dataTypes list
  		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
  
  		// A cross-domain request is in order when the origin doesn't match the current origin.
  		if ( s.crossDomain == null ) {
  			urlAnchor = document.createElement( "a" );
  
  			// Support: IE <=8 - 11, Edge 12 - 15
  			// IE throws exception on accessing the href property if url is malformed,
  			// e.g. http://example.com:80x/
  			try {
  				urlAnchor.href = s.url;
  
  				// Support: IE <=8 - 11 only
  				// Anchor's host property isn't correctly set when s.url is relative
  				urlAnchor.href = urlAnchor.href;
  				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
  					urlAnchor.protocol + "//" + urlAnchor.host;
  			} catch ( e ) {
  
  				// If there is an error parsing the URL, assume it is crossDomain,
  				// it can be rejected by the transport if it is invalid
  				s.crossDomain = true;
  			}
  		}
  
  		// Convert data if not already a string
  		if ( s.data && s.processData && typeof s.data !== "string" ) {
  			s.data = jQuery.param( s.data, s.traditional );
  		}
  
  		// Apply prefilters
  		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  
  		// If request was aborted inside a prefilter, stop there
  		if ( completed ) {
  			return jqXHR;
  		}
  
  		// We can fire global events as of now if asked to
  		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
  		fireGlobals = jQuery.event && s.global;
  
  		// Watch for a new set of requests
  		if ( fireGlobals && jQuery.active++ === 0 ) {
  			jQuery.event.trigger( "ajaxStart" );
  		}
  
  		// Uppercase the type
  		s.type = s.type.toUpperCase();
  
  		// Determine if request has content
  		s.hasContent = !rnoContent.test( s.type );
  
  		// Save the URL in case we're toying with the If-Modified-Since
  		// and/or If-None-Match header later on
  		// Remove hash to simplify url manipulation
  		cacheURL = s.url.replace( rhash, "" );
  
  		// More options handling for requests with no content
  		if ( !s.hasContent ) {
  
  			// Remember the hash so we can put it back
  			uncached = s.url.slice( cacheURL.length );
  
  			// If data is available and should be processed, append data to url
  			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
  				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
  
  				// #9682: remove data so that it's not used in an eventual retry
  				delete s.data;
  			}
  
  			// Add or update anti-cache param if needed
  			if ( s.cache === false ) {
  				cacheURL = cacheURL.replace( rantiCache, "$1" );
  				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
  					uncached;
  			}
  
  			// Put hash and anti-cache on the URL that will be requested (gh-1732)
  			s.url = cacheURL + uncached;
  
  		// Change '%20' to '+' if this is encoded form body content (gh-2658)
  		} else if ( s.data && s.processData &&
  			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
  			s.data = s.data.replace( r20, "+" );
  		}
  
  		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  		if ( s.ifModified ) {
  			if ( jQuery.lastModified[ cacheURL ] ) {
  				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  			}
  			if ( jQuery.etag[ cacheURL ] ) {
  				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  			}
  		}
  
  		// Set the correct header, if data is being sent
  		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  			jqXHR.setRequestHeader( "Content-Type", s.contentType );
  		}
  
  		// Set the Accepts header for the server, depending on the dataType
  		jqXHR.setRequestHeader(
  			"Accept",
  			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
  				s.accepts[ s.dataTypes[ 0 ] ] +
  					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  				s.accepts[ "*" ]
  		);
  
  		// Check for headers option
  		for ( i in s.headers ) {
  			jqXHR.setRequestHeader( i, s.headers[ i ] );
  		}
  
  		// Allow custom headers/mimetypes and early abort
  		if ( s.beforeSend &&
  			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
  
  			// Abort if not done already and return
  			return jqXHR.abort();
  		}
  
  		// Aborting is no longer a cancellation
  		strAbort = "abort";
  
  		// Install callbacks on deferreds
  		completeDeferred.add( s.complete );
  		jqXHR.done( s.success );
  		jqXHR.fail( s.error );
  
  		// Get transport
  		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  
  		// If no transport, we auto-abort
  		if ( !transport ) {
  			done( -1, "No Transport" );
  		} else {
  			jqXHR.readyState = 1;
  
  			// Send global event
  			if ( fireGlobals ) {
  				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  			}
  
  			// If request was aborted inside ajaxSend, stop there
  			if ( completed ) {
  				return jqXHR;
  			}
  
  			// Timeout
  			if ( s.async && s.timeout > 0 ) {
  				timeoutTimer = window.setTimeout( function() {
  					jqXHR.abort( "timeout" );
  				}, s.timeout );
  			}
  
  			try {
  				completed = false;
  				transport.send( requestHeaders, done );
  			} catch ( e ) {
  
  				// Rethrow post-completion exceptions
  				if ( completed ) {
  					throw e;
  				}
  
  				// Propagate others as results
  				done( -1, e );
  			}
  		}
  
  		// Callback for when everything is done
  		function done( status, nativeStatusText, responses, headers ) {
  			var isSuccess, success, error, response, modified,
  				statusText = nativeStatusText;
  
  			// Ignore repeat invocations
  			if ( completed ) {
  				return;
  			}
  
  			completed = true;
  
  			// Clear timeout if it exists
  			if ( timeoutTimer ) {
  				window.clearTimeout( timeoutTimer );
  			}
  
  			// Dereference transport for early garbage collection
  			// (no matter how long the jqXHR object will be used)
  			transport = undefined;
  
  			// Cache response headers
  			responseHeadersString = headers || "";
  
  			// Set readyState
  			jqXHR.readyState = status > 0 ? 4 : 0;
  
  			// Determine if successful
  			isSuccess = status >= 200 && status < 300 || status === 304;
  
  			// Get response data
  			if ( responses ) {
  				response = ajaxHandleResponses( s, jqXHR, responses );
  			}
  
  			// Use a noop converter for missing script
  			if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
  				s.converters[ "text script" ] = function() {};
  			}
  
  			// Convert no matter what (that way responseXXX fields are always set)
  			response = ajaxConvert( s, response, jqXHR, isSuccess );
  
  			// If successful, handle type chaining
  			if ( isSuccess ) {
  
  				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  				if ( s.ifModified ) {
  					modified = jqXHR.getResponseHeader( "Last-Modified" );
  					if ( modified ) {
  						jQuery.lastModified[ cacheURL ] = modified;
  					}
  					modified = jqXHR.getResponseHeader( "etag" );
  					if ( modified ) {
  						jQuery.etag[ cacheURL ] = modified;
  					}
  				}
  
  				// if no content
  				if ( status === 204 || s.type === "HEAD" ) {
  					statusText = "nocontent";
  
  				// if not modified
  				} else if ( status === 304 ) {
  					statusText = "notmodified";
  
  				// If we have data, let's convert it
  				} else {
  					statusText = response.state;
  					success = response.data;
  					error = response.error;
  					isSuccess = !error;
  				}
  			} else {
  
  				// Extract error from statusText and normalize for non-aborts
  				error = statusText;
  				if ( status || !statusText ) {
  					statusText = "error";
  					if ( status < 0 ) {
  						status = 0;
  					}
  				}
  			}
  
  			// Set data for the fake xhr object
  			jqXHR.status = status;
  			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  
  			// Success/Error
  			if ( isSuccess ) {
  				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  			} else {
  				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  			}
  
  			// Status-dependent callbacks
  			jqXHR.statusCode( statusCode );
  			statusCode = undefined;
  
  			if ( fireGlobals ) {
  				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  					[ jqXHR, s, isSuccess ? success : error ] );
  			}
  
  			// Complete
  			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  
  			if ( fireGlobals ) {
  				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  
  				// Handle the global AJAX counter
  				if ( !( --jQuery.active ) ) {
  					jQuery.event.trigger( "ajaxStop" );
  				}
  			}
  		}
  
  		return jqXHR;
  	},
  
  	getJSON: function( url, data, callback ) {
  		return jQuery.get( url, data, callback, "json" );
  	},
  
  	getScript: function( url, callback ) {
  		return jQuery.get( url, undefined, callback, "script" );
  	}
  } );
  
  jQuery.each( [ "get", "post" ], function( _i, method ) {
  	jQuery[ method ] = function( url, data, callback, type ) {
  
  		// Shift arguments if data argument was omitted
  		if ( isFunction( data ) ) {
  			type = type || callback;
  			callback = data;
  			data = undefined;
  		}
  
  		// The url can be an options object (which then must have .url)
  		return jQuery.ajax( jQuery.extend( {
  			url: url,
  			type: method,
  			dataType: type,
  			data: data,
  			success: callback
  		}, jQuery.isPlainObject( url ) && url ) );
  	};
  } );
  
  jQuery.ajaxPrefilter( function( s ) {
  	var i;
  	for ( i in s.headers ) {
  		if ( i.toLowerCase() === "content-type" ) {
  			s.contentType = s.headers[ i ] || "";
  		}
  	}
  } );
  
  
  jQuery._evalUrl = function( url, options, doc ) {
  	return jQuery.ajax( {
  		url: url,
  
  		// Make this explicit, since user can override this through ajaxSetup (#11264)
  		type: "GET",
  		dataType: "script",
  		cache: true,
  		async: false,
  		global: false,
  
  		// Only evaluate the response if it is successful (gh-4126)
  		// dataFilter is not invoked for failure responses, so using it instead
  		// of the default converter is kludgy but it works.
  		converters: {
  			"text script": function() {}
  		},
  		dataFilter: function( response ) {
  			jQuery.globalEval( response, options, doc );
  		}
  	} );
  };
  
  
  jQuery.fn.extend( {
  	wrapAll: function( html ) {
  		var wrap;
  
  		if ( this[ 0 ] ) {
  			if ( isFunction( html ) ) {
  				html = html.call( this[ 0 ] );
  			}
  
  			// The elements to wrap the target around
  			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  
  			if ( this[ 0 ].parentNode ) {
  				wrap.insertBefore( this[ 0 ] );
  			}
  
  			wrap.map( function() {
  				var elem = this;
  
  				while ( elem.firstElementChild ) {
  					elem = elem.firstElementChild;
  				}
  
  				return elem;
  			} ).append( this );
  		}
  
  		return this;
  	},
  
  	wrapInner: function( html ) {
  		if ( isFunction( html ) ) {
  			return this.each( function( i ) {
  				jQuery( this ).wrapInner( html.call( this, i ) );
  			} );
  		}
  
  		return this.each( function() {
  			var self = jQuery( this ),
  				contents = self.contents();
  
  			if ( contents.length ) {
  				contents.wrapAll( html );
  
  			} else {
  				self.append( html );
  			}
  		} );
  	},
  
  	wrap: function( html ) {
  		var htmlIsFunction = isFunction( html );
  
  		return this.each( function( i ) {
  			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
  		} );
  	},
  
  	unwrap: function( selector ) {
  		this.parent( selector ).not( "body" ).each( function() {
  			jQuery( this ).replaceWith( this.childNodes );
  		} );
  		return this;
  	}
  } );
  
  
  jQuery.expr.pseudos.hidden = function( elem ) {
  	return !jQuery.expr.pseudos.visible( elem );
  };
  jQuery.expr.pseudos.visible = function( elem ) {
  	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
  };
  
  
  
  
  jQuery.ajaxSettings.xhr = function() {
  	try {
  		return new window.XMLHttpRequest();
  	} catch ( e ) {}
  };
  
  var xhrSuccessStatus = {
  
  		// File protocol always yields status code 0, assume 200
  		0: 200,
  
  		// Support: IE <=9 only
  		// #1450: sometimes IE returns 1223 when it should be 204
  		1223: 204
  	},
  	xhrSupported = jQuery.ajaxSettings.xhr();
  
  support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  support.ajax = xhrSupported = !!xhrSupported;
  
  jQuery.ajaxTransport( function( options ) {
  	var callback, errorCallback;
  
  	// Cross domain only allowed if supported through XMLHttpRequest
  	if ( support.cors || xhrSupported && !options.crossDomain ) {
  		return {
  			send: function( headers, complete ) {
  				var i,
  					xhr = options.xhr();
  
  				xhr.open(
  					options.type,
  					options.url,
  					options.async,
  					options.username,
  					options.password
  				);
  
  				// Apply custom fields if provided
  				if ( options.xhrFields ) {
  					for ( i in options.xhrFields ) {
  						xhr[ i ] = options.xhrFields[ i ];
  					}
  				}
  
  				// Override mime type if needed
  				if ( options.mimeType && xhr.overrideMimeType ) {
  					xhr.overrideMimeType( options.mimeType );
  				}
  
  				// X-Requested-With header
  				// For cross-domain requests, seeing as conditions for a preflight are
  				// akin to a jigsaw puzzle, we simply never set it to be sure.
  				// (it can always be set on a per-request basis or even using ajaxSetup)
  				// For same-domain requests, won't change header if already provided.
  				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
  					headers[ "X-Requested-With" ] = "XMLHttpRequest";
  				}
  
  				// Set headers
  				for ( i in headers ) {
  					xhr.setRequestHeader( i, headers[ i ] );
  				}
  
  				// Callback
  				callback = function( type ) {
  					return function() {
  						if ( callback ) {
  							callback = errorCallback = xhr.onload =
  								xhr.onerror = xhr.onabort = xhr.ontimeout =
  									xhr.onreadystatechange = null;
  
  							if ( type === "abort" ) {
  								xhr.abort();
  							} else if ( type === "error" ) {
  
  								// Support: IE <=9 only
  								// On a manual native abort, IE9 throws
  								// errors on any property access that is not readyState
  								if ( typeof xhr.status !== "number" ) {
  									complete( 0, "error" );
  								} else {
  									complete(
  
  										// File: protocol always yields status 0; see #8605, #14207
  										xhr.status,
  										xhr.statusText
  									);
  								}
  							} else {
  								complete(
  									xhrSuccessStatus[ xhr.status ] || xhr.status,
  									xhr.statusText,
  
  									// Support: IE <=9 only
  									// IE9 has no XHR2 but throws on binary (trac-11426)
  									// For XHR2 non-text, let the caller handle it (gh-2498)
  									( xhr.responseType || "text" ) !== "text"  ||
  									typeof xhr.responseText !== "string" ?
  										{ binary: xhr.response } :
  										{ text: xhr.responseText },
  									xhr.getAllResponseHeaders()
  								);
  							}
  						}
  					};
  				};
  
  				// Listen to events
  				xhr.onload = callback();
  				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
  
  				// Support: IE 9 only
  				// Use onreadystatechange to replace onabort
  				// to handle uncaught aborts
  				if ( xhr.onabort !== undefined ) {
  					xhr.onabort = errorCallback;
  				} else {
  					xhr.onreadystatechange = function() {
  
  						// Check readyState before timeout as it changes
  						if ( xhr.readyState === 4 ) {
  
  							// Allow onerror to be called first,
  							// but that will not handle a native abort
  							// Also, save errorCallback to a variable
  							// as xhr.onerror cannot be accessed
  							window.setTimeout( function() {
  								if ( callback ) {
  									errorCallback();
  								}
  							} );
  						}
  					};
  				}
  
  				// Create the abort callback
  				callback = callback( "abort" );
  
  				try {
  
  					// Do send the request (this may raise an exception)
  					xhr.send( options.hasContent && options.data || null );
  				} catch ( e ) {
  
  					// #14683: Only rethrow if this hasn't been notified as an error yet
  					if ( callback ) {
  						throw e;
  					}
  				}
  			},
  
  			abort: function() {
  				if ( callback ) {
  					callback();
  				}
  			}
  		};
  	}
  } );
  
  
  
  
  // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
  jQuery.ajaxPrefilter( function( s ) {
  	if ( s.crossDomain ) {
  		s.contents.script = false;
  	}
  } );
  
  // Install script dataType
  jQuery.ajaxSetup( {
  	accepts: {
  		script: "text/javascript, application/javascript, " +
  			"application/ecmascript, application/x-ecmascript"
  	},
  	contents: {
  		script: /\b(?:java|ecma)script\b/
  	},
  	converters: {
  		"text script": function( text ) {
  			jQuery.globalEval( text );
  			return text;
  		}
  	}
  } );
  
  // Handle cache's special case and crossDomain
  jQuery.ajaxPrefilter( "script", function( s ) {
  	if ( s.cache === undefined ) {
  		s.cache = false;
  	}
  	if ( s.crossDomain ) {
  		s.type = "GET";
  	}
  } );
  
  // Bind script tag hack transport
  jQuery.ajaxTransport( "script", function( s ) {
  
  	// This transport only deals with cross domain or forced-by-attrs requests
  	if ( s.crossDomain || s.scriptAttrs ) {
  		var script, callback;
  		return {
  			send: function( _, complete ) {
  				script = jQuery( "<script>" )
  					.attr( s.scriptAttrs || {} )
  					.prop( { charset: s.scriptCharset, src: s.url } )
  					.on( "load error", callback = function( evt ) {
  						script.remove();
  						callback = null;
  						if ( evt ) {
  							complete( evt.type === "error" ? 404 : 200, evt.type );
  						}
  					} );
  
  				// Use native DOM manipulation to avoid our domManip AJAX trickery
  				document.head.appendChild( script[ 0 ] );
  			},
  			abort: function() {
  				if ( callback ) {
  					callback();
  				}
  			}
  		};
  	}
  } );
  
  
  
  
  var oldCallbacks = [],
  	rjsonp = /(=)\?(?=&|$)|\?\?/;
  
  // Default jsonp settings
  jQuery.ajaxSetup( {
  	jsonp: "callback",
  	jsonpCallback: function() {
  		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
  		this[ callback ] = true;
  		return callback;
  	}
  } );
  
  // Detect, normalize options and install callbacks for jsonp requests
  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  
  	var callbackName, overwritten, responseContainer,
  		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  			"url" :
  			typeof s.data === "string" &&
  				( s.contentType || "" )
  					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
  				rjsonp.test( s.data ) && "data"
  		);
  
  	// Handle iff the expected data type is "jsonp" or we have a parameter to set
  	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  
  		// Get callback name, remembering preexisting value associated with it
  		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
  			s.jsonpCallback() :
  			s.jsonpCallback;
  
  		// Insert callback into url or form data
  		if ( jsonProp ) {
  			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  		} else if ( s.jsonp !== false ) {
  			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  		}
  
  		// Use data converter to retrieve json after script execution
  		s.converters[ "script json" ] = function() {
  			if ( !responseContainer ) {
  				jQuery.error( callbackName + " was not called" );
  			}
  			return responseContainer[ 0 ];
  		};
  
  		// Force json dataType
  		s.dataTypes[ 0 ] = "json";
  
  		// Install callback
  		overwritten = window[ callbackName ];
  		window[ callbackName ] = function() {
  			responseContainer = arguments;
  		};
  
  		// Clean-up function (fires after converters)
  		jqXHR.always( function() {
  
  			// If previous value didn't exist - remove it
  			if ( overwritten === undefined ) {
  				jQuery( window ).removeProp( callbackName );
  
  			// Otherwise restore preexisting value
  			} else {
  				window[ callbackName ] = overwritten;
  			}
  
  			// Save back as free
  			if ( s[ callbackName ] ) {
  
  				// Make sure that re-using the options doesn't screw things around
  				s.jsonpCallback = originalSettings.jsonpCallback;
  
  				// Save the callback name for future use
  				oldCallbacks.push( callbackName );
  			}
  
  			// Call if it was a function and we have a response
  			if ( responseContainer && isFunction( overwritten ) ) {
  				overwritten( responseContainer[ 0 ] );
  			}
  
  			responseContainer = overwritten = undefined;
  		} );
  
  		// Delegate to script
  		return "script";
  	}
  } );
  
  
  
  
  // Support: Safari 8 only
  // In Safari 8 documents created via document.implementation.createHTMLDocument
  // collapse sibling forms: the second one becomes a child of the first one.
  // Because of that, this security measure has to be disabled in Safari 8.
  // https://bugs.webkit.org/show_bug.cgi?id=137337
  support.createHTMLDocument = ( function() {
  	var body = document.implementation.createHTMLDocument( "" ).body;
  	body.innerHTML = "<form></form><form></form>";
  	return body.childNodes.length === 2;
  } )();
  
  
  // Argument "data" should be string of html
  // context (optional): If specified, the fragment will be created in this context,
  // defaults to document
  // keepScripts (optional): If true, will include scripts passed in the html string
  jQuery.parseHTML = function( data, context, keepScripts ) {
  	if ( typeof data !== "string" ) {
  		return [];
  	}
  	if ( typeof context === "boolean" ) {
  		keepScripts = context;
  		context = false;
  	}
  
  	var base, parsed, scripts;
  
  	if ( !context ) {
  
  		// Stop scripts or inline event handlers from being executed immediately
  		// by using document.implementation
  		if ( support.createHTMLDocument ) {
  			context = document.implementation.createHTMLDocument( "" );
  
  			// Set the base href for the created document
  			// so any parsed elements with URLs
  			// are based on the document's URL (gh-2965)
  			base = context.createElement( "base" );
  			base.href = document.location.href;
  			context.head.appendChild( base );
  		} else {
  			context = document;
  		}
  	}
  
  	parsed = rsingleTag.exec( data );
  	scripts = !keepScripts && [];
  
  	// Single tag
  	if ( parsed ) {
  		return [ context.createElement( parsed[ 1 ] ) ];
  	}
  
  	parsed = buildFragment( [ data ], context, scripts );
  
  	if ( scripts && scripts.length ) {
  		jQuery( scripts ).remove();
  	}
  
  	return jQuery.merge( [], parsed.childNodes );
  };
  
  
  /**
   * Load a url into a page
   */
  jQuery.fn.load = function( url, params, callback ) {
  	var selector, type, response,
  		self = this,
  		off = url.indexOf( " " );
  
  	if ( off > -1 ) {
  		selector = stripAndCollapse( url.slice( off ) );
  		url = url.slice( 0, off );
  	}
  
  	// If it's a function
  	if ( isFunction( params ) ) {
  
  		// We assume that it's the callback
  		callback = params;
  		params = undefined;
  
  	// Otherwise, build a param string
  	} else if ( params && typeof params === "object" ) {
  		type = "POST";
  	}
  
  	// If we have elements to modify, make the request
  	if ( self.length > 0 ) {
  		jQuery.ajax( {
  			url: url,
  
  			// If "type" variable is undefined, then "GET" method will be used.
  			// Make value of this field explicit since
  			// user can override it through ajaxSetup method
  			type: type || "GET",
  			dataType: "html",
  			data: params
  		} ).done( function( responseText ) {
  
  			// Save response for use in complete callback
  			response = arguments;
  
  			self.html( selector ?
  
  				// If a selector was specified, locate the right elements in a dummy div
  				// Exclude scripts to avoid IE 'Permission Denied' errors
  				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
  
  				// Otherwise use the full result
  				responseText );
  
  		// If the request succeeds, this function gets "data", "status", "jqXHR"
  		// but they are ignored because response was set above.
  		// If it fails, this function gets "jqXHR", "status", "error"
  		} ).always( callback && function( jqXHR, status ) {
  			self.each( function() {
  				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
  			} );
  		} );
  	}
  
  	return this;
  };
  
  
  
  
  jQuery.expr.pseudos.animated = function( elem ) {
  	return jQuery.grep( jQuery.timers, function( fn ) {
  		return elem === fn.elem;
  	} ).length;
  };
  
  
  
  
  jQuery.offset = {
  	setOffset: function( elem, options, i ) {
  		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  			position = jQuery.css( elem, "position" ),
  			curElem = jQuery( elem ),
  			props = {};
  
  		// Set position first, in-case top/left are set even on static elem
  		if ( position === "static" ) {
  			elem.style.position = "relative";
  		}
  
  		curOffset = curElem.offset();
  		curCSSTop = jQuery.css( elem, "top" );
  		curCSSLeft = jQuery.css( elem, "left" );
  		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
  			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
  
  		// Need to be able to calculate position if either
  		// top or left is auto and position is either absolute or fixed
  		if ( calculatePosition ) {
  			curPosition = curElem.position();
  			curTop = curPosition.top;
  			curLeft = curPosition.left;
  
  		} else {
  			curTop = parseFloat( curCSSTop ) || 0;
  			curLeft = parseFloat( curCSSLeft ) || 0;
  		}
  
  		if ( isFunction( options ) ) {
  
  			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
  			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
  		}
  
  		if ( options.top != null ) {
  			props.top = ( options.top - curOffset.top ) + curTop;
  		}
  		if ( options.left != null ) {
  			props.left = ( options.left - curOffset.left ) + curLeft;
  		}
  
  		if ( "using" in options ) {
  			options.using.call( elem, props );
  
  		} else {
  			if ( typeof props.top === "number" ) {
  				props.top += "px";
  			}
  			if ( typeof props.left === "number" ) {
  				props.left += "px";
  			}
  			curElem.css( props );
  		}
  	}
  };
  
  jQuery.fn.extend( {
  
  	// offset() relates an element's border box to the document origin
  	offset: function( options ) {
  
  		// Preserve chaining for setter
  		if ( arguments.length ) {
  			return options === undefined ?
  				this :
  				this.each( function( i ) {
  					jQuery.offset.setOffset( this, options, i );
  				} );
  		}
  
  		var rect, win,
  			elem = this[ 0 ];
  
  		if ( !elem ) {
  			return;
  		}
  
  		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
  		// Support: IE <=11 only
  		// Running getBoundingClientRect on a
  		// disconnected node in IE throws an error
  		if ( !elem.getClientRects().length ) {
  			return { top: 0, left: 0 };
  		}
  
  		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
  		rect = elem.getBoundingClientRect();
  		win = elem.ownerDocument.defaultView;
  		return {
  			top: rect.top + win.pageYOffset,
  			left: rect.left + win.pageXOffset
  		};
  	},
  
  	// position() relates an element's margin box to its offset parent's padding box
  	// This corresponds to the behavior of CSS absolute positioning
  	position: function() {
  		if ( !this[ 0 ] ) {
  			return;
  		}
  
  		var offsetParent, offset, doc,
  			elem = this[ 0 ],
  			parentOffset = { top: 0, left: 0 };
  
  		// position:fixed elements are offset from the viewport, which itself always has zero offset
  		if ( jQuery.css( elem, "position" ) === "fixed" ) {
  
  			// Assume position:fixed implies availability of getBoundingClientRect
  			offset = elem.getBoundingClientRect();
  
  		} else {
  			offset = this.offset();
  
  			// Account for the *real* offset parent, which can be the document or its root element
  			// when a statically positioned element is identified
  			doc = elem.ownerDocument;
  			offsetParent = elem.offsetParent || doc.documentElement;
  			while ( offsetParent &&
  				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
  				jQuery.css( offsetParent, "position" ) === "static" ) {
  
  				offsetParent = offsetParent.parentNode;
  			}
  			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
  
  				// Incorporate borders into its offset, since they are outside its content origin
  				parentOffset = jQuery( offsetParent ).offset();
  				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
  				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
  			}
  		}
  
  		// Subtract parent offsets and element margins
  		return {
  			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  		};
  	},
  
  	// This method will return documentElement in the following cases:
  	// 1) For the element inside the iframe without offsetParent, this method will return
  	//    documentElement of the parent window
  	// 2) For the hidden or detached element
  	// 3) For body or html element, i.e. in case of the html node - it will return itself
  	//
  	// but those exceptions were never presented as a real life use-cases
  	// and might be considered as more preferable results.
  	//
  	// This logic, however, is not guaranteed and can change at any point in the future
  	offsetParent: function() {
  		return this.map( function() {
  			var offsetParent = this.offsetParent;
  
  			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
  				offsetParent = offsetParent.offsetParent;
  			}
  
  			return offsetParent || documentElement;
  		} );
  	}
  } );
  
  // Create scrollLeft and scrollTop methods
  jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  	var top = "pageYOffset" === prop;
  
  	jQuery.fn[ method ] = function( val ) {
  		return access( this, function( elem, method, val ) {
  
  			// Coalesce documents and windows
  			var win;
  			if ( isWindow( elem ) ) {
  				win = elem;
  			} else if ( elem.nodeType === 9 ) {
  				win = elem.defaultView;
  			}
  
  			if ( val === undefined ) {
  				return win ? win[ prop ] : elem[ method ];
  			}
  
  			if ( win ) {
  				win.scrollTo(
  					!top ? val : win.pageXOffset,
  					top ? val : win.pageYOffset
  				);
  
  			} else {
  				elem[ method ] = val;
  			}
  		}, method, val, arguments.length );
  	};
  } );
  
  // Support: Safari <=7 - 9.1, Chrome <=37 - 49
  // Add the top/left cssHooks using jQuery.fn.position
  // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
  // getComputedStyle returns percent when specified for top/left/bottom/right;
  // rather than make the css module depend on the offset module, just check for it here
  jQuery.each( [ "top", "left" ], function( _i, prop ) {
  	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
  		function( elem, computed ) {
  			if ( computed ) {
  				computed = curCSS( elem, prop );
  
  				// If curCSS returns percentage, fallback to offset
  				return rnumnonpx.test( computed ) ?
  					jQuery( elem ).position()[ prop ] + "px" :
  					computed;
  			}
  		}
  	);
  } );
  
  
  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
  		function( defaultExtra, funcName ) {
  
  		// Margin is only for outerHeight, outerWidth
  		jQuery.fn[ funcName ] = function( margin, value ) {
  			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  
  			return access( this, function( elem, type, value ) {
  				var doc;
  
  				if ( isWindow( elem ) ) {
  
  					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
  					return funcName.indexOf( "outer" ) === 0 ?
  						elem[ "inner" + name ] :
  						elem.document.documentElement[ "client" + name ];
  				}
  
  				// Get document width or height
  				if ( elem.nodeType === 9 ) {
  					doc = elem.documentElement;
  
  					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  					// whichever is greatest
  					return Math.max(
  						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  						elem.body[ "offset" + name ], doc[ "offset" + name ],
  						doc[ "client" + name ]
  					);
  				}
  
  				return value === undefined ?
  
  					// Get width or height on the element, requesting but not forcing parseFloat
  					jQuery.css( elem, type, extra ) :
  
  					// Set width or height on the element
  					jQuery.style( elem, type, value, extra );
  			}, type, chainable ? margin : undefined, chainable );
  		};
  	} );
  } );
  
  
  jQuery.each( [
  	"ajaxStart",
  	"ajaxStop",
  	"ajaxComplete",
  	"ajaxError",
  	"ajaxSuccess",
  	"ajaxSend"
  ], function( _i, type ) {
  	jQuery.fn[ type ] = function( fn ) {
  		return this.on( type, fn );
  	};
  } );
  
  
  
  
  jQuery.fn.extend( {
  
  	bind: function( types, data, fn ) {
  		return this.on( types, null, data, fn );
  	},
  	unbind: function( types, fn ) {
  		return this.off( types, null, fn );
  	},
  
  	delegate: function( selector, types, data, fn ) {
  		return this.on( types, selector, data, fn );
  	},
  	undelegate: function( selector, types, fn ) {
  
  		// ( namespace ) or ( selector, types [, fn] )
  		return arguments.length === 1 ?
  			this.off( selector, "**" ) :
  			this.off( types, selector || "**", fn );
  	},
  
  	hover: function( fnOver, fnOut ) {
  		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  	}
  } );
  
  jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
  	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
  	function( _i, name ) {
  
  		// Handle event binding
  		jQuery.fn[ name ] = function( data, fn ) {
  			return arguments.length > 0 ?
  				this.on( name, null, data, fn ) :
  				this.trigger( name );
  		};
  	} );
  
  
  
  
  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
  
  // Bind a function to a context, optionally partially applying any
  // arguments.
  // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
  // However, it is not slated for removal any time soon
  jQuery.proxy = function( fn, context ) {
  	var tmp, args, proxy;
  
  	if ( typeof context === "string" ) {
  		tmp = fn[ context ];
  		context = fn;
  		fn = tmp;
  	}
  
  	// Quick check to determine if target is callable, in the spec
  	// this throws a TypeError, but we will just return undefined.
  	if ( !isFunction( fn ) ) {
  		return undefined;
  	}
  
  	// Simulated bind
  	args = slice.call( arguments, 2 );
  	proxy = function() {
  		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
  	};
  
  	// Set the guid of unique handler to the same of original handler, so it can be removed
  	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  
  	return proxy;
  };
  
  jQuery.holdReady = function( hold ) {
  	if ( hold ) {
  		jQuery.readyWait++;
  	} else {
  		jQuery.ready( true );
  	}
  };
  jQuery.isArray = Array.isArray;
  jQuery.parseJSON = JSON.parse;
  jQuery.nodeName = nodeName;
  jQuery.isFunction = isFunction;
  jQuery.isWindow = isWindow;
  jQuery.camelCase = camelCase;
  jQuery.type = toType;
  
  jQuery.now = Date.now;
  
  jQuery.isNumeric = function( obj ) {
  
  	// As of jQuery 3.0, isNumeric is limited to
  	// strings and numbers (primitives or objects)
  	// that can be coerced to finite numbers (gh-2662)
  	var type = jQuery.type( obj );
  	return ( type === "number" || type === "string" ) &&
  
  		// parseFloat NaNs numeric-cast false positives ("")
  		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  		// subtraction forces infinities to NaN
  		!isNaN( obj - parseFloat( obj ) );
  };
  
  jQuery.trim = function( text ) {
  	return text == null ?
  		"" :
  		( text + "" ).replace( rtrim, "" );
  };
  
  
  
  // Register as a named AMD module, since jQuery can be concatenated with other
  // files that may use define, but not via a proper concatenation script that
  // understands anonymous AMD modules. A named AMD is safest and most robust
  // way to register. Lowercase jquery is used because AMD module names are
  // derived from file names, and jQuery is normally delivered in a lowercase
  // file name. Do this after creating the global so that if an AMD module wants
  // to call noConflict to hide this version of jQuery, it will work.
  
  // Note that for maximum portability, libraries that are not jQuery should
  // declare themselves as anonymous modules, and avoid setting a global if an
  // AMD loader is present. jQuery is a special case. For more information, see
  // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
  
  if ( typeof define === "function" && define.amd ) {
  	define( "jquery", [], function() {
  		return jQuery;
  	} );
  }
  
  
  
  
  var
  
  	// Map over jQuery in case of overwrite
  	_jQuery = window.jQuery,
  
  	// Map over the $ in case of overwrite
  	_$ = window.$;
  
  jQuery.noConflict = function( deep ) {
  	if ( window.$ === jQuery ) {
  		window.$ = _$;
  	}
  
  	if ( deep && window.jQuery === jQuery ) {
  		window.jQuery = _jQuery;
  	}
  
  	return jQuery;
  };
  
  // Expose jQuery and $ identifiers, even in AMD
  // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  // and CommonJS for browser emulators (#13566)
  if ( typeof noGlobal === "undefined" ) {
  	window.jQuery = window.$ = jQuery;
  }
  
  
  
  
  return jQuery;
  } );
  
  /**!
   * @fileOverview Kickass library to create and place poppers near their reference elements.
   * @version 1.16.1
   * @license
   * Copyright (c) 2016 Federico Zivolo and contributors
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  	typeof define === 'function' && define.amd ? define(factory) :
  	(global.Popper = factory());
  }(this, (function () { 'use strict';
  
  var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
  
  var timeoutDuration = function () {
    var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
    for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
      if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
        return 1;
      }
    }
    return 0;
  }();
  
  function microtaskDebounce(fn) {
    var called = false;
    return function () {
      if (called) {
        return;
      }
      called = true;
      window.Promise.resolve().then(function () {
        called = false;
        fn();
      });
    };
  }
  
  function taskDebounce(fn) {
    var scheduled = false;
    return function () {
      if (!scheduled) {
        scheduled = true;
        setTimeout(function () {
          scheduled = false;
          fn();
        }, timeoutDuration);
      }
    };
  }
  
  var supportsMicroTasks = isBrowser && window.Promise;
  
  /**
  * Create a debounced version of a method, that's asynchronously deferred
  * but called in the minimum time possible.
  *
  * @method
  * @memberof Popper.Utils
  * @argument {Function} fn
  * @returns {Function}
  */
  var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
  
  /**
   * Check if the given variable is a function
   * @method
   * @memberof Popper.Utils
   * @argument {Any} functionToCheck - variable to check
   * @returns {Boolean} answer to: is a function?
   */
  function isFunction(functionToCheck) {
    var getType = {};
    return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
  }
  
  /**
   * Get CSS computed property of the given element
   * @method
   * @memberof Popper.Utils
   * @argument {Eement} element
   * @argument {String} property
   */
  function getStyleComputedProperty(element, property) {
    if (element.nodeType !== 1) {
      return [];
    }
    // NOTE: 1 DOM access here
    var window = element.ownerDocument.defaultView;
    var css = window.getComputedStyle(element, null);
    return property ? css[property] : css;
  }
  
  /**
   * Returns the parentNode or the host of the element
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @returns {Element} parent
   */
  function getParentNode(element) {
    if (element.nodeName === 'HTML') {
      return element;
    }
    return element.parentNode || element.host;
  }
  
  /**
   * Returns the scrolling parent of the given element
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @returns {Element} scroll parent
   */
  function getScrollParent(element) {
    // Return body, `getScroll` will take care to get the correct `scrollTop` from it
    if (!element) {
      return document.body;
    }
  
    switch (element.nodeName) {
      case 'HTML':
      case 'BODY':
        return element.ownerDocument.body;
      case '#document':
        return element.body;
    }
  
    // Firefox want us to check `-x` and `-y` variations as well
  
    var _getStyleComputedProp = getStyleComputedProperty(element),
        overflow = _getStyleComputedProp.overflow,
        overflowX = _getStyleComputedProp.overflowX,
        overflowY = _getStyleComputedProp.overflowY;
  
    if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
      return element;
    }
  
    return getScrollParent(getParentNode(element));
  }
  
  /**
   * Returns the reference node of the reference object, or the reference object itself.
   * @method
   * @memberof Popper.Utils
   * @param {Element|Object} reference - the reference element (the popper will be relative to this)
   * @returns {Element} parent
   */
  function getReferenceNode(reference) {
    return reference && reference.referenceNode ? reference.referenceNode : reference;
  }
  
  var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
  var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
  
  /**
   * Determines if the browser is Internet Explorer
   * @method
   * @memberof Popper.Utils
   * @param {Number} version to check
   * @returns {Boolean} isIE
   */
  function isIE(version) {
    if (version === 11) {
      return isIE11;
    }
    if (version === 10) {
      return isIE10;
    }
    return isIE11 || isIE10;
  }
  
  /**
   * Returns the offset parent of the given element
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @returns {Element} offset parent
   */
  function getOffsetParent(element) {
    if (!element) {
      return document.documentElement;
    }
  
    var noOffsetParent = isIE(10) ? document.body : null;
  
    // NOTE: 1 DOM access here
    var offsetParent = element.offsetParent || null;
    // Skip hidden elements which don't have an offsetParent
    while (offsetParent === noOffsetParent && element.nextElementSibling) {
      offsetParent = (element = element.nextElementSibling).offsetParent;
    }
  
    var nodeName = offsetParent && offsetParent.nodeName;
  
    if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
      return element ? element.ownerDocument.documentElement : document.documentElement;
    }
  
    // .offsetParent will return the closest TH, TD or TABLE in case
    // no offsetParent is present, I hate this job...
    if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
      return getOffsetParent(offsetParent);
    }
  
    return offsetParent;
  }
  
  function isOffsetContainer(element) {
    var nodeName = element.nodeName;
  
    if (nodeName === 'BODY') {
      return false;
    }
    return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
  }
  
  /**
   * Finds the root node (document, shadowDOM root) of the given element
   * @method
   * @memberof Popper.Utils
   * @argument {Element} node
   * @returns {Element} root node
   */
  function getRoot(node) {
    if (node.parentNode !== null) {
      return getRoot(node.parentNode);
    }
  
    return node;
  }
  
  /**
   * Finds the offset parent common to the two provided nodes
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element1
   * @argument {Element} element2
   * @returns {Element} common offset parent
   */
  function findCommonOffsetParent(element1, element2) {
    // This check is needed to avoid errors in case one of the elements isn't defined for any reason
    if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
      return document.documentElement;
    }
  
    // Here we make sure to give as "start" the element that comes first in the DOM
    var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
    var start = order ? element1 : element2;
    var end = order ? element2 : element1;
  
    // Get common ancestor container
    var range = document.createRange();
    range.setStart(start, 0);
    range.setEnd(end, 0);
    var commonAncestorContainer = range.commonAncestorContainer;
  
    // Both nodes are inside #document
  
    if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
      if (isOffsetContainer(commonAncestorContainer)) {
        return commonAncestorContainer;
      }
  
      return getOffsetParent(commonAncestorContainer);
    }
  
    // one of the nodes is inside shadowDOM, find which one
    var element1root = getRoot(element1);
    if (element1root.host) {
      return findCommonOffsetParent(element1root.host, element2);
    } else {
      return findCommonOffsetParent(element1, getRoot(element2).host);
    }
  }
  
  /**
   * Gets the scroll value of the given element in the given side (top and left)
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @argument {String} side `top` or `left`
   * @returns {number} amount of scrolled pixels
   */
  function getScroll(element) {
    var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
  
    var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
    var nodeName = element.nodeName;
  
    if (nodeName === 'BODY' || nodeName === 'HTML') {
      var html = element.ownerDocument.documentElement;
      var scrollingElement = element.ownerDocument.scrollingElement || html;
      return scrollingElement[upperSide];
    }
  
    return element[upperSide];
  }
  
  /*
   * Sum or subtract the element scroll values (left and top) from a given rect object
   * @method
   * @memberof Popper.Utils
   * @param {Object} rect - Rect object you want to change
   * @param {HTMLElement} element - The element from the function reads the scroll values
   * @param {Boolean} subtract - set to true if you want to subtract the scroll values
   * @return {Object} rect - The modifier rect object
   */
  function includeScroll(rect, element) {
    var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  
    var scrollTop = getScroll(element, 'top');
    var scrollLeft = getScroll(element, 'left');
    var modifier = subtract ? -1 : 1;
    rect.top += scrollTop * modifier;
    rect.bottom += scrollTop * modifier;
    rect.left += scrollLeft * modifier;
    rect.right += scrollLeft * modifier;
    return rect;
  }
  
  /*
   * Helper to detect borders of a given element
   * @method
   * @memberof Popper.Utils
   * @param {CSSStyleDeclaration} styles
   * Result of `getStyleComputedProperty` on the given element
   * @param {String} axis - `x` or `y`
   * @return {number} borders - The borders size of the given axis
   */
  
  function getBordersSize(styles, axis) {
    var sideA = axis === 'x' ? 'Left' : 'Top';
    var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
  
    return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);
  }
  
  function getSize(axis, body, html, computedStyle) {
    return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
  }
  
  function getWindowSizes(document) {
    var body = document.body;
    var html = document.documentElement;
    var computedStyle = isIE(10) && getComputedStyle(html);
  
    return {
      height: getSize('Height', body, html, computedStyle),
      width: getSize('Width', body, html, computedStyle)
    };
  }
  
  var classCallCheck = function (instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  };
  
  var createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }
  
    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();
  
  
  
  
  
  var defineProperty = function (obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }
  
    return obj;
  };
  
  var _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];
  
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }
  
    return target;
  };
  
  /**
   * Given element offsets, generate an output similar to getBoundingClientRect
   * @method
   * @memberof Popper.Utils
   * @argument {Object} offsets
   * @returns {Object} ClientRect like output
   */
  function getClientRect(offsets) {
    return _extends({}, offsets, {
      right: offsets.left + offsets.width,
      bottom: offsets.top + offsets.height
    });
  }
  
  /**
   * Get bounding client rect of given element
   * @method
   * @memberof Popper.Utils
   * @param {HTMLElement} element
   * @return {Object} client rect
   */
  function getBoundingClientRect(element) {
    var rect = {};
  
    // IE10 10 FIX: Please, don't ask, the element isn't
    // considered in DOM in some circumstances...
    // This isn't reproducible in IE10 compatibility mode of IE11
    try {
      if (isIE(10)) {
        rect = element.getBoundingClientRect();
        var scrollTop = getScroll(element, 'top');
        var scrollLeft = getScroll(element, 'left');
        rect.top += scrollTop;
        rect.left += scrollLeft;
        rect.bottom += scrollTop;
        rect.right += scrollLeft;
      } else {
        rect = element.getBoundingClientRect();
      }
    } catch (e) {}
  
    var result = {
      left: rect.left,
      top: rect.top,
      width: rect.right - rect.left,
      height: rect.bottom - rect.top
    };
  
    // subtract scrollbar size from sizes
    var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
    var width = sizes.width || element.clientWidth || result.width;
    var height = sizes.height || element.clientHeight || result.height;
  
    var horizScrollbar = element.offsetWidth - width;
    var vertScrollbar = element.offsetHeight - height;
  
    // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
    // we make this check conditional for performance reasons
    if (horizScrollbar || vertScrollbar) {
      var styles = getStyleComputedProperty(element);
      horizScrollbar -= getBordersSize(styles, 'x');
      vertScrollbar -= getBordersSize(styles, 'y');
  
      result.width -= horizScrollbar;
      result.height -= vertScrollbar;
    }
  
    return getClientRect(result);
  }
  
  function getOffsetRectRelativeToArbitraryNode(children, parent) {
    var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  
    var isIE10 = isIE(10);
    var isHTML = parent.nodeName === 'HTML';
    var childrenRect = getBoundingClientRect(children);
    var parentRect = getBoundingClientRect(parent);
    var scrollParent = getScrollParent(children);
  
    var styles = getStyleComputedProperty(parent);
    var borderTopWidth = parseFloat(styles.borderTopWidth);
    var borderLeftWidth = parseFloat(styles.borderLeftWidth);
  
    // In cases where the parent is fixed, we must ignore negative scroll in offset calc
    if (fixedPosition && isHTML) {
      parentRect.top = Math.max(parentRect.top, 0);
      parentRect.left = Math.max(parentRect.left, 0);
    }
    var offsets = getClientRect({
      top: childrenRect.top - parentRect.top - borderTopWidth,
      left: childrenRect.left - parentRect.left - borderLeftWidth,
      width: childrenRect.width,
      height: childrenRect.height
    });
    offsets.marginTop = 0;
    offsets.marginLeft = 0;
  
    // Subtract margins of documentElement in case it's being used as parent
    // we do this only on HTML because it's the only element that behaves
    // differently when margins are applied to it. The margins are included in
    // the box of the documentElement, in the other cases not.
    if (!isIE10 && isHTML) {
      var marginTop = parseFloat(styles.marginTop);
      var marginLeft = parseFloat(styles.marginLeft);
  
      offsets.top -= borderTopWidth - marginTop;
      offsets.bottom -= borderTopWidth - marginTop;
      offsets.left -= borderLeftWidth - marginLeft;
      offsets.right -= borderLeftWidth - marginLeft;
  
      // Attach marginTop and marginLeft because in some circumstances we may need them
      offsets.marginTop = marginTop;
      offsets.marginLeft = marginLeft;
    }
  
    if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
      offsets = includeScroll(offsets, parent);
    }
  
    return offsets;
  }
  
  function getViewportOffsetRectRelativeToArtbitraryNode(element) {
    var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
    var html = element.ownerDocument.documentElement;
    var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
    var width = Math.max(html.clientWidth, window.innerWidth || 0);
    var height = Math.max(html.clientHeight, window.innerHeight || 0);
  
    var scrollTop = !excludeScroll ? getScroll(html) : 0;
    var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
  
    var offset = {
      top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
      left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
      width: width,
      height: height
    };
  
    return getClientRect(offset);
  }
  
  /**
   * Check if the given element is fixed or is inside a fixed parent
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @argument {Element} customContainer
   * @returns {Boolean} answer to "isFixed?"
   */
  function isFixed(element) {
    var nodeName = element.nodeName;
    if (nodeName === 'BODY' || nodeName === 'HTML') {
      return false;
    }
    if (getStyleComputedProperty(element, 'position') === 'fixed') {
      return true;
    }
    var parentNode = getParentNode(element);
    if (!parentNode) {
      return false;
    }
    return isFixed(parentNode);
  }
  
  /**
   * Finds the first parent of an element that has a transformed property defined
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @returns {Element} first transformed parent or documentElement
   */
  
  function getFixedPositionOffsetParent(element) {
    // This check is needed to avoid errors in case one of the elements isn't defined for any reason
    if (!element || !element.parentElement || isIE()) {
      return document.documentElement;
    }
    var el = element.parentElement;
    while (el && getStyleComputedProperty(el, 'transform') === 'none') {
      el = el.parentElement;
    }
    return el || document.documentElement;
  }
  
  /**
   * Computed the boundaries limits and return them
   * @method
   * @memberof Popper.Utils
   * @param {HTMLElement} popper
   * @param {HTMLElement} reference
   * @param {number} padding
   * @param {HTMLElement} boundariesElement - Element used to define the boundaries
   * @param {Boolean} fixedPosition - Is in fixed position mode
   * @returns {Object} Coordinates of the boundaries
   */
  function getBoundaries(popper, reference, padding, boundariesElement) {
    var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
  
    // NOTE: 1 DOM access here
  
    var boundaries = { top: 0, left: 0 };
    var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
  
    // Handle viewport case
    if (boundariesElement === 'viewport') {
      boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
    } else {
      // Handle other cases based on DOM element used as boundaries
      var boundariesNode = void 0;
      if (boundariesElement === 'scrollParent') {
        boundariesNode = getScrollParent(getParentNode(reference));
        if (boundariesNode.nodeName === 'BODY') {
          boundariesNode = popper.ownerDocument.documentElement;
        }
      } else if (boundariesElement === 'window') {
        boundariesNode = popper.ownerDocument.documentElement;
      } else {
        boundariesNode = boundariesElement;
      }
  
      var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
  
      // In case of HTML, we need a different computation
      if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
        var _getWindowSizes = getWindowSizes(popper.ownerDocument),
            height = _getWindowSizes.height,
            width = _getWindowSizes.width;
  
        boundaries.top += offsets.top - offsets.marginTop;
        boundaries.bottom = height + offsets.top;
        boundaries.left += offsets.left - offsets.marginLeft;
        boundaries.right = width + offsets.left;
      } else {
        // for all the other DOM elements, this one is good
        boundaries = offsets;
      }
    }
  
    // Add paddings
    padding = padding || 0;
    var isPaddingNumber = typeof padding === 'number';
    boundaries.left += isPaddingNumber ? padding : padding.left || 0;
    boundaries.top += isPaddingNumber ? padding : padding.top || 0;
    boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
    boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
  
    return boundaries;
  }
  
  function getArea(_ref) {
    var width = _ref.width,
        height = _ref.height;
  
    return width * height;
  }
  
  /**
   * Utility used to transform the `auto` placement to the placement with more
   * available space.
   * @method
   * @memberof Popper.Utils
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
    var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
  
    if (placement.indexOf('auto') === -1) {
      return placement;
    }
  
    var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
  
    var rects = {
      top: {
        width: boundaries.width,
        height: refRect.top - boundaries.top
      },
      right: {
        width: boundaries.right - refRect.right,
        height: boundaries.height
      },
      bottom: {
        width: boundaries.width,
        height: boundaries.bottom - refRect.bottom
      },
      left: {
        width: refRect.left - boundaries.left,
        height: boundaries.height
      }
    };
  
    var sortedAreas = Object.keys(rects).map(function (key) {
      return _extends({
        key: key
      }, rects[key], {
        area: getArea(rects[key])
      });
    }).sort(function (a, b) {
      return b.area - a.area;
    });
  
    var filteredAreas = sortedAreas.filter(function (_ref2) {
      var width = _ref2.width,
          height = _ref2.height;
      return width >= popper.clientWidth && height >= popper.clientHeight;
    });
  
    var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
  
    var variation = placement.split('-')[1];
  
    return computedPlacement + (variation ? '-' + variation : '');
  }
  
  /**
   * Get offsets to the reference element
   * @method
   * @memberof Popper.Utils
   * @param {Object} state
   * @param {Element} popper - the popper element
   * @param {Element} reference - the reference element (the popper will be relative to this)
   * @param {Element} fixedPosition - is in fixed position mode
   * @returns {Object} An object containing the offsets which will be applied to the popper
   */
  function getReferenceOffsets(state, popper, reference) {
    var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
  
    var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
    return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
  }
  
  /**
   * Get the outer sizes of the given element (offset size + margins)
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element
   * @returns {Object} object containing width and height properties
   */
  function getOuterSizes(element) {
    var window = element.ownerDocument.defaultView;
    var styles = window.getComputedStyle(element);
    var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
    var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
    var result = {
      width: element.offsetWidth + y,
      height: element.offsetHeight + x
    };
    return result;
  }
  
  /**
   * Get the opposite placement of the given one
   * @method
   * @memberof Popper.Utils
   * @argument {String} placement
   * @returns {String} flipped placement
   */
  function getOppositePlacement(placement) {
    var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
    return placement.replace(/left|right|bottom|top/g, function (matched) {
      return hash[matched];
    });
  }
  
  /**
   * Get offsets to the popper
   * @method
   * @memberof Popper.Utils
   * @param {Object} position - CSS position the Popper will get applied
   * @param {HTMLElement} popper - the popper element
   * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
   * @param {String} placement - one of the valid placement options
   * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
   */
  function getPopperOffsets(popper, referenceOffsets, placement) {
    placement = placement.split('-')[0];
  
    // Get popper node sizes
    var popperRect = getOuterSizes(popper);
  
    // Add position, width and height to our offsets object
    var popperOffsets = {
      width: popperRect.width,
      height: popperRect.height
    };
  
    // depending by the popper placement we have to compute its offsets slightly differently
    var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
    var mainSide = isHoriz ? 'top' : 'left';
    var secondarySide = isHoriz ? 'left' : 'top';
    var measurement = isHoriz ? 'height' : 'width';
    var secondaryMeasurement = !isHoriz ? 'height' : 'width';
  
    popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
    if (placement === secondarySide) {
      popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
    } else {
      popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
    }
  
    return popperOffsets;
  }
  
  /**
   * Mimics the `find` method of Array
   * @method
   * @memberof Popper.Utils
   * @argument {Array} arr
   * @argument prop
   * @argument value
   * @returns index or -1
   */
  function find(arr, check) {
    // use native find if supported
    if (Array.prototype.find) {
      return arr.find(check);
    }
  
    // use `filter` to obtain the same behavior of `find`
    return arr.filter(check)[0];
  }
  
  /**
   * Return the index of the matching object
   * @method
   * @memberof Popper.Utils
   * @argument {Array} arr
   * @argument prop
   * @argument value
   * @returns index or -1
   */
  function findIndex(arr, prop, value) {
    // use native findIndex if supported
    if (Array.prototype.findIndex) {
      return arr.findIndex(function (cur) {
        return cur[prop] === value;
      });
    }
  
    // use `find` + `indexOf` if `findIndex` isn't supported
    var match = find(arr, function (obj) {
      return obj[prop] === value;
    });
    return arr.indexOf(match);
  }
  
  /**
   * Loop trough the list of modifiers and run them in order,
   * each of them will then edit the data object.
   * @method
   * @memberof Popper.Utils
   * @param {dataObject} data
   * @param {Array} modifiers
   * @param {String} ends - Optional modifier name used as stopper
   * @returns {dataObject}
   */
  function runModifiers(modifiers, data, ends) {
    var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
  
    modifiersToRun.forEach(function (modifier) {
      if (modifier['function']) {
        // eslint-disable-line dot-notation
        console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
      }
      var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
      if (modifier.enabled && isFunction(fn)) {
        // Add properties to offsets to make them a complete clientRect object
        // we do this before each modifier to make sure the previous one doesn't
        // mess with these values
        data.offsets.popper = getClientRect(data.offsets.popper);
        data.offsets.reference = getClientRect(data.offsets.reference);
  
        data = fn(data, modifier);
      }
    });
  
    return data;
  }
  
  /**
   * Updates the position of the popper, computing the new offsets and applying
   * the new style.<br />
   * Prefer `scheduleUpdate` over `update` because of performance reasons.
   * @method
   * @memberof Popper
   */
  function update() {
    // if popper is destroyed, don't perform any further update
    if (this.state.isDestroyed) {
      return;
    }
  
    var data = {
      instance: this,
      styles: {},
      arrowStyles: {},
      attributes: {},
      flipped: false,
      offsets: {}
    };
  
    // compute reference element offsets
    data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
  
    // compute auto placement, store placement inside the data object,
    // modifiers will be able to edit `placement` if needed
    // and refer to originalPlacement to know the original value
    data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
  
    // store the computed placement inside `originalPlacement`
    data.originalPlacement = data.placement;
  
    data.positionFixed = this.options.positionFixed;
  
    // compute the popper offsets
    data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
  
    data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
  
    // run the modifiers
    data = runModifiers(this.modifiers, data);
  
    // the first `update` will call `onCreate` callback
    // the other ones will call `onUpdate` callback
    if (!this.state.isCreated) {
      this.state.isCreated = true;
      this.options.onCreate(data);
    } else {
      this.options.onUpdate(data);
    }
  }
  
  /**
   * Helper used to know if the given modifier is enabled.
   * @method
   * @memberof Popper.Utils
   * @returns {Boolean}
   */
  function isModifierEnabled(modifiers, modifierName) {
    return modifiers.some(function (_ref) {
      var name = _ref.name,
          enabled = _ref.enabled;
      return enabled && name === modifierName;
    });
  }
  
  /**
   * Get the prefixed supported property name
   * @method
   * @memberof Popper.Utils
   * @argument {String} property (camelCase)
   * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
   */
  function getSupportedPropertyName(property) {
    var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
    var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
  
    for (var i = 0; i < prefixes.length; i++) {
      var prefix = prefixes[i];
      var toCheck = prefix ? '' + prefix + upperProp : property;
      if (typeof document.body.style[toCheck] !== 'undefined') {
        return toCheck;
      }
    }
    return null;
  }
  
  /**
   * Destroys the popper.
   * @method
   * @memberof Popper
   */
  function destroy() {
    this.state.isDestroyed = true;
  
    // touch DOM only if `applyStyle` modifier is enabled
    if (isModifierEnabled(this.modifiers, 'applyStyle')) {
      this.popper.removeAttribute('x-placement');
      this.popper.style.position = '';
      this.popper.style.top = '';
      this.popper.style.left = '';
      this.popper.style.right = '';
      this.popper.style.bottom = '';
      this.popper.style.willChange = '';
      this.popper.style[getSupportedPropertyName('transform')] = '';
    }
  
    this.disableEventListeners();
  
    // remove the popper if user explicitly asked for the deletion on destroy
    // do not use `remove` because IE11 doesn't support it
    if (this.options.removeOnDestroy) {
      this.popper.parentNode.removeChild(this.popper);
    }
    return this;
  }
  
  /**
   * Get the window associated with the element
   * @argument {Element} element
   * @returns {Window}
   */
  function getWindow(element) {
    var ownerDocument = element.ownerDocument;
    return ownerDocument ? ownerDocument.defaultView : window;
  }
  
  function attachToScrollParents(scrollParent, event, callback, scrollParents) {
    var isBody = scrollParent.nodeName === 'BODY';
    var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
    target.addEventListener(event, callback, { passive: true });
  
    if (!isBody) {
      attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
    }
    scrollParents.push(target);
  }
  
  /**
   * Setup needed event listeners used to update the popper position
   * @method
   * @memberof Popper.Utils
   * @private
   */
  function setupEventListeners(reference, options, state, updateBound) {
    // Resize event listener on window
    state.updateBound = updateBound;
    getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
  
    // Scroll event listener on scroll parents
    var scrollElement = getScrollParent(reference);
    attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
    state.scrollElement = scrollElement;
    state.eventsEnabled = true;
  
    return state;
  }
  
  /**
   * It will add resize/scroll events and start recalculating
   * position of the popper element when they are triggered.
   * @method
   * @memberof Popper
   */
  function enableEventListeners() {
    if (!this.state.eventsEnabled) {
      this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
    }
  }
  
  /**
   * Remove event listeners used to update the popper position
   * @method
   * @memberof Popper.Utils
   * @private
   */
  function removeEventListeners(reference, state) {
    // Remove resize event listener on window
    getWindow(reference).removeEventListener('resize', state.updateBound);
  
    // Remove scroll event listener on scroll parents
    state.scrollParents.forEach(function (target) {
      target.removeEventListener('scroll', state.updateBound);
    });
  
    // Reset state
    state.updateBound = null;
    state.scrollParents = [];
    state.scrollElement = null;
    state.eventsEnabled = false;
    return state;
  }
  
  /**
   * It will remove resize/scroll events and won't recalculate popper position
   * when they are triggered. It also won't trigger `onUpdate` callback anymore,
   * unless you call `update` method manually.
   * @method
   * @memberof Popper
   */
  function disableEventListeners() {
    if (this.state.eventsEnabled) {
      cancelAnimationFrame(this.scheduleUpdate);
      this.state = removeEventListeners(this.reference, this.state);
    }
  }
  
  /**
   * Tells if a given input is a number
   * @method
   * @memberof Popper.Utils
   * @param {*} input to check
   * @return {Boolean}
   */
  function isNumeric(n) {
    return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
  }
  
  /**
   * Set the style to the given popper
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element - Element to apply the style to
   * @argument {Object} styles
   * Object with a list of properties and values which will be applied to the element
   */
  function setStyles(element, styles) {
    Object.keys(styles).forEach(function (prop) {
      var unit = '';
      // add unit if the value is numeric and is one of the following
      if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
        unit = 'px';
      }
      element.style[prop] = styles[prop] + unit;
    });
  }
  
  /**
   * Set the attributes to the given popper
   * @method
   * @memberof Popper.Utils
   * @argument {Element} element - Element to apply the attributes to
   * @argument {Object} styles
   * Object with a list of properties and values which will be applied to the element
   */
  function setAttributes(element, attributes) {
    Object.keys(attributes).forEach(function (prop) {
      var value = attributes[prop];
      if (value !== false) {
        element.setAttribute(prop, attributes[prop]);
      } else {
        element.removeAttribute(prop);
      }
    });
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Object} data.styles - List of style properties - values to apply to popper element
   * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The same data object
   */
  function applyStyle(data) {
    // any property present in `data.styles` will be applied to the popper,
    // in this way we can make the 3rd party modifiers add custom styles to it
    // Be aware, modifiers could override the properties defined in the previous
    // lines of this modifier!
    setStyles(data.instance.popper, data.styles);
  
    // any property present in `data.attributes` will be applied to the popper,
    // they will be set as HTML attributes of the element
    setAttributes(data.instance.popper, data.attributes);
  
    // if arrowElement is defined and arrowStyles has some properties
    if (data.arrowElement && Object.keys(data.arrowStyles).length) {
      setStyles(data.arrowElement, data.arrowStyles);
    }
  
    return data;
  }
  
  /**
   * Set the x-placement attribute before everything else because it could be used
   * to add margins to the popper margins needs to be calculated to get the
   * correct popper offsets.
   * @method
   * @memberof Popper.modifiers
   * @param {HTMLElement} reference - The reference element used to position the popper
   * @param {HTMLElement} popper - The HTML element used as popper
   * @param {Object} options - Popper.js options
   */
  function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
    // compute reference element offsets
    var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
  
    // compute auto placement, store placement inside the data object,
    // modifiers will be able to edit `placement` if needed
    // and refer to originalPlacement to know the original value
    var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
  
    popper.setAttribute('x-placement', placement);
  
    // Apply `position` to popper before anything else because
    // without the position applied we can't guarantee correct computations
    setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
  
    return options;
  }
  
  /**
   * @function
   * @memberof Popper.Utils
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Boolean} shouldRound - If the offsets should be rounded at all
   * @returns {Object} The popper's position offsets rounded
   *
   * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
   * good as it can be within reason.
   * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
   *
   * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
   * as well on High DPI screens).
   *
   * Firefox prefers no rounding for positioning and does not have blurriness on
   * high DPI screens.
   *
   * Only horizontal placement and left/right values need to be considered.
   */
  function getRoundedOffsets(data, shouldRound) {
    var _data$offsets = data.offsets,
        popper = _data$offsets.popper,
        reference = _data$offsets.reference;
    var round = Math.round,
        floor = Math.floor;
  
    var noRound = function noRound(v) {
      return v;
    };
  
    var referenceWidth = round(reference.width);
    var popperWidth = round(popper.width);
  
    var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
    var isVariation = data.placement.indexOf('-') !== -1;
    var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
    var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
  
    var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
    var verticalToInteger = !shouldRound ? noRound : round;
  
    return {
      left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
      top: verticalToInteger(popper.top),
      bottom: verticalToInteger(popper.bottom),
      right: horizontalToInteger(popper.right)
    };
  }
  
  var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function computeStyle(data, options) {
    var x = options.x,
        y = options.y;
    var popper = data.offsets.popper;
  
    // Remove this legacy support in Popper.js v2
  
    var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
      return modifier.name === 'applyStyle';
    }).gpuAcceleration;
    if (legacyGpuAccelerationOption !== undefined) {
      console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
    }
    var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
  
    var offsetParent = getOffsetParent(data.instance.popper);
    var offsetParentRect = getBoundingClientRect(offsetParent);
  
    // Styles
    var styles = {
      position: popper.position
    };
  
    var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
  
    var sideA = x === 'bottom' ? 'top' : 'bottom';
    var sideB = y === 'right' ? 'left' : 'right';
  
    // if gpuAcceleration is set to `true` and transform is supported,
    //  we use `translate3d` to apply the position to the popper we
    // automatically use the supported prefixed version if needed
    var prefixedProperty = getSupportedPropertyName('transform');
  
    // now, let's make a step back and look at this code closely (wtf?)
    // If the content of the popper grows once it's been positioned, it
    // may happen that the popper gets misplaced because of the new content
    // overflowing its reference element
    // To avoid this problem, we provide two options (x and y), which allow
    // the consumer to define the offset origin.
    // If we position a popper on top of a reference element, we can set
    // `x` to `top` to make the popper grow towards its top instead of
    // its bottom.
    var left = void 0,
        top = void 0;
    if (sideA === 'bottom') {
      // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
      // and not the bottom of the html element
      if (offsetParent.nodeName === 'HTML') {
        top = -offsetParent.clientHeight + offsets.bottom;
      } else {
        top = -offsetParentRect.height + offsets.bottom;
      }
    } else {
      top = offsets.top;
    }
    if (sideB === 'right') {
      if (offsetParent.nodeName === 'HTML') {
        left = -offsetParent.clientWidth + offsets.right;
      } else {
        left = -offsetParentRect.width + offsets.right;
      }
    } else {
      left = offsets.left;
    }
    if (gpuAcceleration && prefixedProperty) {
      styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
      styles[sideA] = 0;
      styles[sideB] = 0;
      styles.willChange = 'transform';
    } else {
      // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
      var invertTop = sideA === 'bottom' ? -1 : 1;
      var invertLeft = sideB === 'right' ? -1 : 1;
      styles[sideA] = top * invertTop;
      styles[sideB] = left * invertLeft;
      styles.willChange = sideA + ', ' + sideB;
    }
  
    // Attributes
    var attributes = {
      'x-placement': data.placement
    };
  
    // Update `data` attributes, styles and arrowStyles
    data.attributes = _extends({}, attributes, data.attributes);
    data.styles = _extends({}, styles, data.styles);
    data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
  
    return data;
  }
  
  /**
   * Helper used to know if the given modifier depends from another one.<br />
   * It checks if the needed modifier is listed and enabled.
   * @method
   * @memberof Popper.Utils
   * @param {Array} modifiers - list of modifiers
   * @param {String} requestingName - name of requesting modifier
   * @param {String} requestedName - name of requested modifier
   * @returns {Boolean}
   */
  function isModifierRequired(modifiers, requestingName, requestedName) {
    var requesting = find(modifiers, function (_ref) {
      var name = _ref.name;
      return name === requestingName;
    });
  
    var isRequired = !!requesting && modifiers.some(function (modifier) {
      return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
    });
  
    if (!isRequired) {
      var _requesting = '`' + requestingName + '`';
      var requested = '`' + requestedName + '`';
      console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
    }
    return isRequired;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function arrow(data, options) {
    var _data$offsets$arrow;
  
    // arrow depends on keepTogether in order to work
    if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
      return data;
    }
  
    var arrowElement = options.element;
  
    // if arrowElement is a string, suppose it's a CSS selector
    if (typeof arrowElement === 'string') {
      arrowElement = data.instance.popper.querySelector(arrowElement);
  
      // if arrowElement is not found, don't run the modifier
      if (!arrowElement) {
        return data;
      }
    } else {
      // if the arrowElement isn't a query selector we must check that the
      // provided DOM node is child of its popper node
      if (!data.instance.popper.contains(arrowElement)) {
        console.warn('WARNING: `arrow.element` must be child of its popper element!');
        return data;
      }
    }
  
    var placement = data.placement.split('-')[0];
    var _data$offsets = data.offsets,
        popper = _data$offsets.popper,
        reference = _data$offsets.reference;
  
    var isVertical = ['left', 'right'].indexOf(placement) !== -1;
  
    var len = isVertical ? 'height' : 'width';
    var sideCapitalized = isVertical ? 'Top' : 'Left';
    var side = sideCapitalized.toLowerCase();
    var altSide = isVertical ? 'left' : 'top';
    var opSide = isVertical ? 'bottom' : 'right';
    var arrowElementSize = getOuterSizes(arrowElement)[len];
  
    //
    // extends keepTogether behavior making sure the popper and its
    // reference have enough pixels in conjunction
    //
  
    // top/left side
    if (reference[opSide] - arrowElementSize < popper[side]) {
      data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
    }
    // bottom/right side
    if (reference[side] + arrowElementSize > popper[opSide]) {
      data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
    }
    data.offsets.popper = getClientRect(data.offsets.popper);
  
    // compute center of the popper
    var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
  
    // Compute the sideValue using the updated popper offsets
    // take popper margin in account because we don't have this info available
    var css = getStyleComputedProperty(data.instance.popper);
    var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);
    var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);
    var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
  
    // prevent arrowElement from being placed not contiguously to its popper
    sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
  
    data.arrowElement = arrowElement;
    data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
  
    return data;
  }
  
  /**
   * Get the opposite placement variation of the given one
   * @method
   * @memberof Popper.Utils
   * @argument {String} placement variation
   * @returns {String} flipped placement variation
   */
  function getOppositeVariation(variation) {
    if (variation === 'end') {
      return 'start';
    } else if (variation === 'start') {
      return 'end';
    }
    return variation;
  }
  
  /**
   * List of accepted placements to use as values of the `placement` option.<br />
   * Valid placements are:
   * - `auto`
   * - `top`
   * - `right`
   * - `bottom`
   * - `left`
   *
   * Each placement can have a variation from this list:
   * - `-start`
   * - `-end`
   *
   * Variations are interpreted easily if you think of them as the left to right
   * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
   * is right.<br />
   * Vertically (`left` and `right`), `start` is top and `end` is bottom.
   *
   * Some valid examples are:
   * - `top-end` (on top of reference, right aligned)
   * - `right-start` (on right of reference, top aligned)
   * - `bottom` (on bottom, centered)
   * - `auto-end` (on the side with more space available, alignment depends by placement)
   *
   * @static
   * @type {Array}
   * @enum {String}
   * @readonly
   * @method placements
   * @memberof Popper
   */
  var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
  
  // Get rid of `auto` `auto-start` and `auto-end`
  var validPlacements = placements.slice(3);
  
  /**
   * Given an initial placement, returns all the subsequent placements
   * clockwise (or counter-clockwise).
   *
   * @method
   * @memberof Popper.Utils
   * @argument {String} placement - A valid placement (it accepts variations)
   * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
   * @returns {Array} placements including their variations
   */
  function clockwise(placement) {
    var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
    var index = validPlacements.indexOf(placement);
    var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
    return counter ? arr.reverse() : arr;
  }
  
  var BEHAVIORS = {
    FLIP: 'flip',
    CLOCKWISE: 'clockwise',
    COUNTERCLOCKWISE: 'counterclockwise'
  };
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function flip(data, options) {
    // if `inner` modifier is enabled, we can't use the `flip` modifier
    if (isModifierEnabled(data.instance.modifiers, 'inner')) {
      return data;
    }
  
    if (data.flipped && data.placement === data.originalPlacement) {
      // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
      return data;
    }
  
    var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
  
    var placement = data.placement.split('-')[0];
    var placementOpposite = getOppositePlacement(placement);
    var variation = data.placement.split('-')[1] || '';
  
    var flipOrder = [];
  
    switch (options.behavior) {
      case BEHAVIORS.FLIP:
        flipOrder = [placement, placementOpposite];
        break;
      case BEHAVIORS.CLOCKWISE:
        flipOrder = clockwise(placement);
        break;
      case BEHAVIORS.COUNTERCLOCKWISE:
        flipOrder = clockwise(placement, true);
        break;
      default:
        flipOrder = options.behavior;
    }
  
    flipOrder.forEach(function (step, index) {
      if (placement !== step || flipOrder.length === index + 1) {
        return data;
      }
  
      placement = data.placement.split('-')[0];
      placementOpposite = getOppositePlacement(placement);
  
      var popperOffsets = data.offsets.popper;
      var refOffsets = data.offsets.reference;
  
      // using floor because the reference offsets may contain decimals we are not going to consider here
      var floor = Math.floor;
      var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
  
      var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
      var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
      var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
      var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
  
      var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
  
      // flip the variation if required
      var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
  
      // flips variation if reference element overflows boundaries
      var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
  
      // flips variation if popper content overflows boundaries
      var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
  
      var flippedVariation = flippedVariationByRef || flippedVariationByContent;
  
      if (overlapsRef || overflowsBoundaries || flippedVariation) {
        // this boolean to detect any flip loop
        data.flipped = true;
  
        if (overlapsRef || overflowsBoundaries) {
          placement = flipOrder[index + 1];
        }
  
        if (flippedVariation) {
          variation = getOppositeVariation(variation);
        }
  
        data.placement = placement + (variation ? '-' + variation : '');
  
        // this object contains `position`, we want to preserve it along with
        // any additional property we may add in the future
        data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
  
        data = runModifiers(data.instance.modifiers, data, 'flip');
      }
    });
    return data;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function keepTogether(data) {
    var _data$offsets = data.offsets,
        popper = _data$offsets.popper,
        reference = _data$offsets.reference;
  
    var placement = data.placement.split('-')[0];
    var floor = Math.floor;
    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
    var side = isVertical ? 'right' : 'bottom';
    var opSide = isVertical ? 'left' : 'top';
    var measurement = isVertical ? 'width' : 'height';
  
    if (popper[side] < floor(reference[opSide])) {
      data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
    }
    if (popper[opSide] > floor(reference[side])) {
      data.offsets.popper[opSide] = floor(reference[side]);
    }
  
    return data;
  }
  
  /**
   * Converts a string containing value + unit into a px value number
   * @function
   * @memberof {modifiers~offset}
   * @private
   * @argument {String} str - Value + unit string
   * @argument {String} measurement - `height` or `width`
   * @argument {Object} popperOffsets
   * @argument {Object} referenceOffsets
   * @returns {Number|String}
   * Value in pixels, or original string if no values were extracted
   */
  function toValue(str, measurement, popperOffsets, referenceOffsets) {
    // separate value from unit
    var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
    var value = +split[1];
    var unit = split[2];
  
    // If it's not a number it's an operator, I guess
    if (!value) {
      return str;
    }
  
    if (unit.indexOf('%') === 0) {
      var element = void 0;
      switch (unit) {
        case '%p':
          element = popperOffsets;
          break;
        case '%':
        case '%r':
        default:
          element = referenceOffsets;
      }
  
      var rect = getClientRect(element);
      return rect[measurement] / 100 * value;
    } else if (unit === 'vh' || unit === 'vw') {
      // if is a vh or vw, we calculate the size based on the viewport
      var size = void 0;
      if (unit === 'vh') {
        size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
      } else {
        size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
      }
      return size / 100 * value;
    } else {
      // if is an explicit pixel unit, we get rid of the unit and keep the value
      // if is an implicit unit, it's px, and we return just the value
      return value;
    }
  }
  
  /**
   * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
   * @function
   * @memberof {modifiers~offset}
   * @private
   * @argument {String} offset
   * @argument {Object} popperOffsets
   * @argument {Object} referenceOffsets
   * @argument {String} basePlacement
   * @returns {Array} a two cells array with x and y offsets in numbers
   */
  function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
    var offsets = [0, 0];
  
    // Use height if placement is left or right and index is 0 otherwise use width
    // in this way the first offset will use an axis and the second one
    // will use the other one
    var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
  
    // Split the offset string to obtain a list of values and operands
    // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
    var fragments = offset.split(/(\+|\-)/).map(function (frag) {
      return frag.trim();
    });
  
    // Detect if the offset string contains a pair of values or a single one
    // they could be separated by comma or space
    var divider = fragments.indexOf(find(fragments, function (frag) {
      return frag.search(/,|\s/) !== -1;
    }));
  
    if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
      console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
    }
  
    // If divider is found, we divide the list of values and operands to divide
    // them by ofset X and Y.
    var splitRegex = /\s*,\s*|\s+/;
    var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
  
    // Convert the values with units to absolute pixels to allow our computations
    ops = ops.map(function (op, index) {
      // Most of the units rely on the orientation of the popper
      var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
      var mergeWithPrevious = false;
      return op
      // This aggregates any `+` or `-` sign that aren't considered operators
      // e.g.: 10 + +5 => [10, +, +5]
      .reduce(function (a, b) {
        if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
          a[a.length - 1] = b;
          mergeWithPrevious = true;
          return a;
        } else if (mergeWithPrevious) {
          a[a.length - 1] += b;
          mergeWithPrevious = false;
          return a;
        } else {
          return a.concat(b);
        }
      }, [])
      // Here we convert the string values into number values (in px)
      .map(function (str) {
        return toValue(str, measurement, popperOffsets, referenceOffsets);
      });
    });
  
    // Loop trough the offsets arrays and execute the operations
    ops.forEach(function (op, index) {
      op.forEach(function (frag, index2) {
        if (isNumeric(frag)) {
          offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
        }
      });
    });
    return offsets;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @argument {Number|String} options.offset=0
   * The offset value as described in the modifier description
   * @returns {Object} The data object, properly modified
   */
  function offset(data, _ref) {
    var offset = _ref.offset;
    var placement = data.placement,
        _data$offsets = data.offsets,
        popper = _data$offsets.popper,
        reference = _data$offsets.reference;
  
    var basePlacement = placement.split('-')[0];
  
    var offsets = void 0;
    if (isNumeric(+offset)) {
      offsets = [+offset, 0];
    } else {
      offsets = parseOffset(offset, popper, reference, basePlacement);
    }
  
    if (basePlacement === 'left') {
      popper.top += offsets[0];
      popper.left -= offsets[1];
    } else if (basePlacement === 'right') {
      popper.top += offsets[0];
      popper.left += offsets[1];
    } else if (basePlacement === 'top') {
      popper.left += offsets[0];
      popper.top -= offsets[1];
    } else if (basePlacement === 'bottom') {
      popper.left += offsets[0];
      popper.top += offsets[1];
    }
  
    data.popper = popper;
    return data;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function preventOverflow(data, options) {
    var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
  
    // If offsetParent is the reference element, we really want to
    // go one step up and use the next offsetParent as reference to
    // avoid to make this modifier completely useless and look like broken
    if (data.instance.reference === boundariesElement) {
      boundariesElement = getOffsetParent(boundariesElement);
    }
  
    // NOTE: DOM access here
    // resets the popper's position so that the document size can be calculated excluding
    // the size of the popper element itself
    var transformProp = getSupportedPropertyName('transform');
    var popperStyles = data.instance.popper.style; // assignment to help minification
    var top = popperStyles.top,
        left = popperStyles.left,
        transform = popperStyles[transformProp];
  
    popperStyles.top = '';
    popperStyles.left = '';
    popperStyles[transformProp] = '';
  
    var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
  
    // NOTE: DOM access here
    // restores the original style properties after the offsets have been computed
    popperStyles.top = top;
    popperStyles.left = left;
    popperStyles[transformProp] = transform;
  
    options.boundaries = boundaries;
  
    var order = options.priority;
    var popper = data.offsets.popper;
  
    var check = {
      primary: function primary(placement) {
        var value = popper[placement];
        if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
          value = Math.max(popper[placement], boundaries[placement]);
        }
        return defineProperty({}, placement, value);
      },
      secondary: function secondary(placement) {
        var mainSide = placement === 'right' ? 'left' : 'top';
        var value = popper[mainSide];
        if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
          value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
        }
        return defineProperty({}, mainSide, value);
      }
    };
  
    order.forEach(function (placement) {
      var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
      popper = _extends({}, popper, check[side](placement));
    });
  
    data.offsets.popper = popper;
  
    return data;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function shift(data) {
    var placement = data.placement;
    var basePlacement = placement.split('-')[0];
    var shiftvariation = placement.split('-')[1];
  
    // if shift shiftvariation is specified, run the modifier
    if (shiftvariation) {
      var _data$offsets = data.offsets,
          reference = _data$offsets.reference,
          popper = _data$offsets.popper;
  
      var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
      var side = isVertical ? 'left' : 'top';
      var measurement = isVertical ? 'width' : 'height';
  
      var shiftOffsets = {
        start: defineProperty({}, side, reference[side]),
        end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
      };
  
      data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
    }
  
    return data;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by update method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function hide(data) {
    if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
      return data;
    }
  
    var refRect = data.offsets.reference;
    var bound = find(data.instance.modifiers, function (modifier) {
      return modifier.name === 'preventOverflow';
    }).boundaries;
  
    if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
      // Avoid unnecessary DOM access if visibility hasn't changed
      if (data.hide === true) {
        return data;
      }
  
      data.hide = true;
      data.attributes['x-out-of-boundaries'] = '';
    } else {
      // Avoid unnecessary DOM access if visibility hasn't changed
      if (data.hide === false) {
        return data;
      }
  
      data.hide = false;
      data.attributes['x-out-of-boundaries'] = false;
    }
  
    return data;
  }
  
  /**
   * @function
   * @memberof Modifiers
   * @argument {Object} data - The data object generated by `update` method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {Object} The data object, properly modified
   */
  function inner(data) {
    var placement = data.placement;
    var basePlacement = placement.split('-')[0];
    var _data$offsets = data.offsets,
        popper = _data$offsets.popper,
        reference = _data$offsets.reference;
  
    var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
  
    var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
  
    popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
  
    data.placement = getOppositePlacement(placement);
    data.offsets.popper = getClientRect(popper);
  
    return data;
  }
  
  /**
   * Modifier function, each modifier can have a function of this type assigned
   * to its `fn` property.<br />
   * These functions will be called on each update, this means that you must
   * make sure they are performant enough to avoid performance bottlenecks.
   *
   * @function ModifierFn
   * @argument {dataObject} data - The data object generated by `update` method
   * @argument {Object} options - Modifiers configuration and options
   * @returns {dataObject} The data object, properly modified
   */
  
  /**
   * Modifiers are plugins used to alter the behavior of your poppers.<br />
   * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
   * needed by the library.
   *
   * Usually you don't want to override the `order`, `fn` and `onLoad` props.
   * All the other properties are configurations that could be tweaked.
   * @namespace modifiers
   */
  var modifiers = {
    /**
     * Modifier used to shift the popper on the start or end of its reference
     * element.<br />
     * It will read the variation of the `placement` property.<br />
     * It can be one either `-end` or `-start`.
     * @memberof modifiers
     * @inner
     */
    shift: {
      /** @prop {number} order=100 - Index used to define the order of execution */
      order: 100,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: shift
    },
  
    /**
     * The `offset` modifier can shift your popper on both its axis.
     *
     * It accepts the following units:
     * - `px` or unit-less, interpreted as pixels
     * - `%` or `%r`, percentage relative to the length of the reference element
     * - `%p`, percentage relative to the length of the popper element
     * - `vw`, CSS viewport width unit
     * - `vh`, CSS viewport height unit
     *
     * For length is intended the main axis relative to the placement of the popper.<br />
     * This means that if the placement is `top` or `bottom`, the length will be the
     * `width`. In case of `left` or `right`, it will be the `height`.
     *
     * You can provide a single value (as `Number` or `String`), or a pair of values
     * as `String` divided by a comma or one (or more) white spaces.<br />
     * The latter is a deprecated method because it leads to confusion and will be
     * removed in v2.<br />
     * Additionally, it accepts additions and subtractions between different units.
     * Note that multiplications and divisions aren't supported.
     *
     * Valid examples are:
     * ```
     * 10
     * '10%'
     * '10, 10'
     * '10%, 10'
     * '10 + 10%'
     * '10 - 5vh + 3%'
     * '-10px + 5vh, 5px - 6%'
     * ```
     * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
     * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
     * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
     *
     * @memberof modifiers
     * @inner
     */
    offset: {
      /** @prop {number} order=200 - Index used to define the order of execution */
      order: 200,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: offset,
      /** @prop {Number|String} offset=0
       * The offset value as described in the modifier description
       */
      offset: 0
    },
  
    /**
     * Modifier used to prevent the popper from being positioned outside the boundary.
     *
     * A scenario exists where the reference itself is not within the boundaries.<br />
     * We can say it has "escaped the boundaries" — or just "escaped".<br />
     * In this case we need to decide whether the popper should either:
     *
     * - detach from the reference and remain "trapped" in the boundaries, or
     * - if it should ignore the boundary and "escape with its reference"
     *
     * When `escapeWithReference` is set to`true` and reference is completely
     * outside its boundaries, the popper will overflow (or completely leave)
     * the boundaries in order to remain attached to the edge of the reference.
     *
     * @memberof modifiers
     * @inner
     */
    preventOverflow: {
      /** @prop {number} order=300 - Index used to define the order of execution */
      order: 300,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: preventOverflow,
      /**
       * @prop {Array} [priority=['left','right','top','bottom']]
       * Popper will try to prevent overflow following these priorities by default,
       * then, it could overflow on the left and on top of the `boundariesElement`
       */
      priority: ['left', 'right', 'top', 'bottom'],
      /**
       * @prop {number} padding=5
       * Amount of pixel used to define a minimum distance between the boundaries
       * and the popper. This makes sure the popper always has a little padding
       * between the edges of its container
       */
      padding: 5,
      /**
       * @prop {String|HTMLElement} boundariesElement='scrollParent'
       * Boundaries used by the modifier. Can be `scrollParent`, `window`,
       * `viewport` or any DOM element.
       */
      boundariesElement: 'scrollParent'
    },
  
    /**
     * Modifier used to make sure the reference and its popper stay near each other
     * without leaving any gap between the two. Especially useful when the arrow is
     * enabled and you want to ensure that it points to its reference element.
     * It cares only about the first axis. You can still have poppers with margin
     * between the popper and its reference element.
     * @memberof modifiers
     * @inner
     */
    keepTogether: {
      /** @prop {number} order=400 - Index used to define the order of execution */
      order: 400,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: keepTogether
    },
  
    /**
     * This modifier is used to move the `arrowElement` of the popper to make
     * sure it is positioned between the reference element and its popper element.
     * It will read the outer size of the `arrowElement` node to detect how many
     * pixels of conjunction are needed.
     *
     * It has no effect if no `arrowElement` is provided.
     * @memberof modifiers
     * @inner
     */
    arrow: {
      /** @prop {number} order=500 - Index used to define the order of execution */
      order: 500,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: arrow,
      /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
      element: '[x-arrow]'
    },
  
    /**
     * Modifier used to flip the popper's placement when it starts to overlap its
     * reference element.
     *
     * Requires the `preventOverflow` modifier before it in order to work.
     *
     * **NOTE:** this modifier will interrupt the current update cycle and will
     * restart it if it detects the need to flip the placement.
     * @memberof modifiers
     * @inner
     */
    flip: {
      /** @prop {number} order=600 - Index used to define the order of execution */
      order: 600,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: flip,
      /**
       * @prop {String|Array} behavior='flip'
       * The behavior used to change the popper's placement. It can be one of
       * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
       * placements (with optional variations)
       */
      behavior: 'flip',
      /**
       * @prop {number} padding=5
       * The popper will flip if it hits the edges of the `boundariesElement`
       */
      padding: 5,
      /**
       * @prop {String|HTMLElement} boundariesElement='viewport'
       * The element which will define the boundaries of the popper position.
       * The popper will never be placed outside of the defined boundaries
       * (except if `keepTogether` is enabled)
       */
      boundariesElement: 'viewport',
      /**
       * @prop {Boolean} flipVariations=false
       * The popper will switch placement variation between `-start` and `-end` when
       * the reference element overlaps its boundaries.
       *
       * The original placement should have a set variation.
       */
      flipVariations: false,
      /**
       * @prop {Boolean} flipVariationsByContent=false
       * The popper will switch placement variation between `-start` and `-end` when
       * the popper element overlaps its reference boundaries.
       *
       * The original placement should have a set variation.
       */
      flipVariationsByContent: false
    },
  
    /**
     * Modifier used to make the popper flow toward the inner of the reference element.
     * By default, when this modifier is disabled, the popper will be placed outside
     * the reference element.
     * @memberof modifiers
     * @inner
     */
    inner: {
      /** @prop {number} order=700 - Index used to define the order of execution */
      order: 700,
      /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
      enabled: false,
      /** @prop {ModifierFn} */
      fn: inner
    },
  
    /**
     * Modifier used to hide the popper when its reference element is outside of the
     * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
     * be used to hide with a CSS selector the popper when its reference is
     * out of boundaries.
     *
     * Requires the `preventOverflow` modifier before it in order to work.
     * @memberof modifiers
     * @inner
     */
    hide: {
      /** @prop {number} order=800 - Index used to define the order of execution */
      order: 800,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: hide
    },
  
    /**
     * Computes the style that will be applied to the popper element to gets
     * properly positioned.
     *
     * Note that this modifier will not touch the DOM, it just prepares the styles
     * so that `applyStyle` modifier can apply it. This separation is useful
     * in case you need to replace `applyStyle` with a custom implementation.
     *
     * This modifier has `850` as `order` value to maintain backward compatibility
     * with previous versions of Popper.js. Expect the modifiers ordering method
     * to change in future major versions of the library.
     *
     * @memberof modifiers
     * @inner
     */
    computeStyle: {
      /** @prop {number} order=850 - Index used to define the order of execution */
      order: 850,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: computeStyle,
      /**
       * @prop {Boolean} gpuAcceleration=true
       * If true, it uses the CSS 3D transformation to position the popper.
       * Otherwise, it will use the `top` and `left` properties
       */
      gpuAcceleration: true,
      /**
       * @prop {string} [x='bottom']
       * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
       * Change this if your popper should grow in a direction different from `bottom`
       */
      x: 'bottom',
      /**
       * @prop {string} [x='left']
       * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
       * Change this if your popper should grow in a direction different from `right`
       */
      y: 'right'
    },
  
    /**
     * Applies the computed styles to the popper element.
     *
     * All the DOM manipulations are limited to this modifier. This is useful in case
     * you want to integrate Popper.js inside a framework or view library and you
     * want to delegate all the DOM manipulations to it.
     *
     * Note that if you disable this modifier, you must make sure the popper element
     * has its position set to `absolute` before Popper.js can do its work!
     *
     * Just disable this modifier and define your own to achieve the desired effect.
     *
     * @memberof modifiers
     * @inner
     */
    applyStyle: {
      /** @prop {number} order=900 - Index used to define the order of execution */
      order: 900,
      /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
      enabled: true,
      /** @prop {ModifierFn} */
      fn: applyStyle,
      /** @prop {Function} */
      onLoad: applyStyleOnLoad,
      /**
       * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
       * @prop {Boolean} gpuAcceleration=true
       * If true, it uses the CSS 3D transformation to position the popper.
       * Otherwise, it will use the `top` and `left` properties
       */
      gpuAcceleration: undefined
    }
  };
  
  /**
   * The `dataObject` is an object containing all the information used by Popper.js.
   * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
   * @name dataObject
   * @property {Object} data.instance The Popper.js instance
   * @property {String} data.placement Placement applied to popper
   * @property {String} data.originalPlacement Placement originally defined on init
   * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
   * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
   * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
   * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
   * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
   * @property {Object} data.boundaries Offsets of the popper boundaries
   * @property {Object} data.offsets The measurements of popper, reference and arrow elements
   * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
   * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
   * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
   */
  
  /**
   * Default options provided to Popper.js constructor.<br />
   * These can be overridden using the `options` argument of Popper.js.<br />
   * To override an option, simply pass an object with the same
   * structure of the `options` object, as the 3rd argument. For example:
   * ```
   * new Popper(ref, pop, {
   *   modifiers: {
   *     preventOverflow: { enabled: false }
   *   }
   * })
   * ```
   * @type {Object}
   * @static
   * @memberof Popper
   */
  var Defaults = {
    /**
     * Popper's placement.
     * @prop {Popper.placements} placement='bottom'
     */
    placement: 'bottom',
  
    /**
     * Set this to true if you want popper to position it self in 'fixed' mode
     * @prop {Boolean} positionFixed=false
     */
    positionFixed: false,
  
    /**
     * Whether events (resize, scroll) are initially enabled.
     * @prop {Boolean} eventsEnabled=true
     */
    eventsEnabled: true,
  
    /**
     * Set to true if you want to automatically remove the popper when
     * you call the `destroy` method.
     * @prop {Boolean} removeOnDestroy=false
     */
    removeOnDestroy: false,
  
    /**
     * Callback called when the popper is created.<br />
     * By default, it is set to no-op.<br />
     * Access Popper.js instance with `data.instance`.
     * @prop {onCreate}
     */
    onCreate: function onCreate() {},
  
    /**
     * Callback called when the popper is updated. This callback is not called
     * on the initialization/creation of the popper, but only on subsequent
     * updates.<br />
     * By default, it is set to no-op.<br />
     * Access Popper.js instance with `data.instance`.
     * @prop {onUpdate}
     */
    onUpdate: function onUpdate() {},
  
    /**
     * List of modifiers used to modify the offsets before they are applied to the popper.
     * They provide most of the functionalities of Popper.js.
     * @prop {modifiers}
     */
    modifiers: modifiers
  };
  
  /**
   * @callback onCreate
   * @param {dataObject} data
   */
  
  /**
   * @callback onUpdate
   * @param {dataObject} data
   */
  
  // Utils
  // Methods
  var Popper = function () {
    /**
     * Creates a new Popper.js instance.
     * @class Popper
     * @param {Element|referenceObject} reference - The reference element used to position the popper
     * @param {Element} popper - The HTML / XML element used as the popper
     * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
     * @return {Object} instance - The generated Popper.js instance
     */
    function Popper(reference, popper) {
      var _this = this;
  
      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
      classCallCheck(this, Popper);
  
      this.scheduleUpdate = function () {
        return requestAnimationFrame(_this.update);
      };
  
      // make update() debounced, so that it only runs at most once-per-tick
      this.update = debounce(this.update.bind(this));
  
      // with {} we create a new object with the options inside it
      this.options = _extends({}, Popper.Defaults, options);
  
      // init state
      this.state = {
        isDestroyed: false,
        isCreated: false,
        scrollParents: []
      };
  
      // get reference and popper elements (allow jQuery wrappers)
      this.reference = reference && reference.jquery ? reference[0] : reference;
      this.popper = popper && popper.jquery ? popper[0] : popper;
  
      // Deep merge modifiers options
      this.options.modifiers = {};
      Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
        _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
      });
  
      // Refactoring modifiers' list (Object => Array)
      this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
        return _extends({
          name: name
        }, _this.options.modifiers[name]);
      })
      // sort the modifiers by order
      .sort(function (a, b) {
        return a.order - b.order;
      });
  
      // modifiers have the ability to execute arbitrary code when Popper.js get inited
      // such code is executed in the same order of its modifier
      // they could add new properties to their options configuration
      // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
      this.modifiers.forEach(function (modifierOptions) {
        if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
          modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
        }
      });
  
      // fire the first update to position the popper in the right place
      this.update();
  
      var eventsEnabled = this.options.eventsEnabled;
      if (eventsEnabled) {
        // setup event listeners, they will take care of update the position in specific situations
        this.enableEventListeners();
      }
  
      this.state.eventsEnabled = eventsEnabled;
    }
  
    // We can't use class properties because they don't get listed in the
    // class prototype and break stuff like Sinon stubs
  
  
    createClass(Popper, [{
      key: 'update',
      value: function update$$1() {
        return update.call(this);
      }
    }, {
      key: 'destroy',
      value: function destroy$$1() {
        return destroy.call(this);
      }
    }, {
      key: 'enableEventListeners',
      value: function enableEventListeners$$1() {
        return enableEventListeners.call(this);
      }
    }, {
      key: 'disableEventListeners',
      value: function disableEventListeners$$1() {
        return disableEventListeners.call(this);
      }
  
      /**
       * Schedules an update. It will run on the next UI update available.
       * @method scheduleUpdate
       * @memberof Popper
       */
  
  
      /**
       * Collection of utilities useful when writing custom modifiers.
       * Starting from version 1.7, this method is available only if you
       * include `popper-utils.js` before `popper.js`.
       *
       * **DEPRECATION**: This way to access PopperUtils is deprecated
       * and will be removed in v2! Use the PopperUtils module directly instead.
       * Due to the high instability of the methods contained in Utils, we can't
       * guarantee them to follow semver. Use them at your own risk!
       * @static
       * @private
       * @type {Object}
       * @deprecated since version 1.8
       * @member Utils
       * @memberof Popper
       */
  
    }]);
    return Popper;
  }();
  
  /**
   * The `referenceObject` is an object that provides an interface compatible with Popper.js
   * and lets you use it as replacement of a real DOM node.<br />
   * You can use this method to position a popper relatively to a set of coordinates
   * in case you don't have a DOM node to use as reference.
   *
   * ```
   * new Popper(referenceObject, popperNode);
   * ```
   *
   * NB: This feature isn't supported in Internet Explorer 10.
   * @name referenceObject
   * @property {Function} data.getBoundingClientRect
   * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
   * @property {number} data.clientWidth
   * An ES6 getter that will return the width of the virtual reference element.
   * @property {number} data.clientHeight
   * An ES6 getter that will return the height of the virtual reference element.
   */
  
  
  Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
  Popper.placements = placements;
  Popper.Defaults = Defaults;
  
  return Popper;
  
  })));
  //# sourceMappingURL=popper.js.map
  
  /*!
    * Bootstrap v4.5.0 (https://getbootstrap.com/)
    * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
    * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
    */
  (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) :
    typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) :
    (global = global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper));
  }(this, (function (exports, $, Popper) { 'use strict';
  
    $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
    Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper;
  
    function _defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }
  
    function _createClass(Constructor, protoProps, staticProps) {
      if (protoProps) _defineProperties(Constructor.prototype, protoProps);
      if (staticProps) _defineProperties(Constructor, staticProps);
      return Constructor;
    }
  
    function _defineProperty(obj, key, value) {
      if (key in obj) {
        Object.defineProperty(obj, key, {
          value: value,
          enumerable: true,
          configurable: true,
          writable: true
        });
      } else {
        obj[key] = value;
      }
  
      return obj;
    }
  
    function ownKeys(object, enumerableOnly) {
      var keys = Object.keys(object);
  
      if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) symbols = symbols.filter(function (sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });
        keys.push.apply(keys, symbols);
      }
  
      return keys;
    }
  
    function _objectSpread2(target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i] != null ? arguments[i] : {};
  
        if (i % 2) {
          ownKeys(Object(source), true).forEach(function (key) {
            _defineProperty(target, key, source[key]);
          });
        } else if (Object.getOwnPropertyDescriptors) {
          Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
        } else {
          ownKeys(Object(source)).forEach(function (key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
          });
        }
      }
  
      return target;
    }
  
    function _inheritsLoose(subClass, superClass) {
      subClass.prototype = Object.create(superClass.prototype);
      subClass.prototype.constructor = subClass;
      subClass.__proto__ = superClass;
    }
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v4.5.0): util.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * --------------------------------------------------------------------------
     */
    /**
     * ------------------------------------------------------------------------
     * Private TransitionEnd Helpers
     * ------------------------------------------------------------------------
     */
  
    var TRANSITION_END = 'transitionend';
    var MAX_UID = 1000000;
    var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
  
    function toType(obj) {
      if (obj === null || typeof obj === 'undefined') {
        return "" + obj;
      }
  
      return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
    }
  
    function getSpecialTransitionEndEvent() {
      return {
        bindType: TRANSITION_END,
        delegateType: TRANSITION_END,
        handle: function handle(event) {
          if ($(event.target).is(this)) {
            return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
          }
  
          return undefined;
        }
      };
    }
  
    function transitionEndEmulator(duration) {
      var _this = this;
  
      var called = false;
      $(this).one(Util.TRANSITION_END, function () {
        called = true;
      });
      setTimeout(function () {
        if (!called) {
          Util.triggerTransitionEnd(_this);
        }
      }, duration);
      return this;
    }
  
    function setTransitionEndSupport() {
      $.fn.emulateTransitionEnd = transitionEndEmulator;
      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
    }
    /**
     * --------------------------------------------------------------------------
     * Public Util Api
     * --------------------------------------------------------------------------
     */
  
  
    var Util = {
      TRANSITION_END: 'bsTransitionEnd',
      getUID: function getUID(prefix) {
        do {
          // eslint-disable-next-line no-bitwise
          prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
        } while (document.getElementById(prefix));
  
        return prefix;
      },
      getSelectorFromElement: function getSelectorFromElement(element) {
        var selector = element.getAttribute('data-target');
  
        if (!selector || selector === '#') {
          var hrefAttr = element.getAttribute('href');
          selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
        }
  
        try {
          return document.querySelector(selector) ? selector : null;
        } catch (err) {
          return null;
        }
      },
      getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
        if (!element) {
          return 0;
        } // Get transition-duration of the element
  
  
        var transitionDuration = $(element).css('transition-duration');
        var transitionDelay = $(element).css('transition-delay');
        var floatTransitionDuration = parseFloat(transitionDuration);
        var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
  
        if (!floatTransitionDuration && !floatTransitionDelay) {
          return 0;
        } // If multiple durations are defined, take the first
  
  
        transitionDuration = transitionDuration.split(',')[0];
        transitionDelay = transitionDelay.split(',')[0];
        return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
      },
      reflow: function reflow(element) {
        return element.offsetHeight;
      },
      triggerTransitionEnd: function triggerTransitionEnd(element) {
        $(element).trigger(TRANSITION_END);
      },
      // TODO: Remove in v5
      supportsTransitionEnd: function supportsTransitionEnd() {
        return Boolean(TRANSITION_END);
      },
      isElement: function isElement(obj) {
        return (obj[0] || obj).nodeType;
      },
      typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
        for (var property in configTypes) {
          if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
            var expectedTypes = configTypes[property];
            var value = config[property];
            var valueType = value && Util.isElement(value) ? 'element' : toType(value);
  
            if (!new RegExp(expectedTypes).test(valueType)) {
              throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
            }
          }
        }
      },
      findShadowRoot: function findShadowRoot(element) {
        if (!document.documentElement.attachShadow) {
          return null;
        } // Can find the shadow root otherwise it'll return the document
  
  
        if (typeof element.getRootNode === 'function') {
          var root = element.getRootNode();
          return root instanceof ShadowRoot ? root : null;
        }
  
        if (element instanceof ShadowRoot) {
          return element;
        } // when we don't find a shadow root
  
  
        if (!element.parentNode) {
          return null;
        }
  
        return Util.findShadowRoot(element.parentNode);
      },
      jQueryDetection: function jQueryDetection() {
        if (typeof $ === 'undefined') {
          throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
        }
  
        var version = $.fn.jquery.split(' ')[0].split('.');
        var minMajor = 1;
        var ltMajor = 2;
        var minMinor = 9;
        var minPatch = 1;
        var maxMajor = 4;
  
        if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
          throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
        }
      }
    };
    Util.jQueryDetection();
    setTransitionEndSupport();
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME = 'alert';
    var VERSION = '4.5.0';
    var DATA_KEY = 'bs.alert';
    var EVENT_KEY = "." + DATA_KEY;
    var DATA_API_KEY = '.data-api';
    var JQUERY_NO_CONFLICT = $.fn[NAME];
    var SELECTOR_DISMISS = '[data-dismiss="alert"]';
    var EVENT_CLOSE = "close" + EVENT_KEY;
    var EVENT_CLOSED = "closed" + EVENT_KEY;
    var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
    var CLASS_NAME_ALERT = 'alert';
    var CLASS_NAME_FADE = 'fade';
    var CLASS_NAME_SHOW = 'show';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Alert = /*#__PURE__*/function () {
      function Alert(element) {
        this._element = element;
      } // Getters
  
  
      var _proto = Alert.prototype;
  
      // Public
      _proto.close = function close(element) {
        var rootElement = this._element;
  
        if (element) {
          rootElement = this._getRootElement(element);
        }
  
        var customEvent = this._triggerCloseEvent(rootElement);
  
        if (customEvent.isDefaultPrevented()) {
          return;
        }
  
        this._removeElement(rootElement);
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY);
        this._element = null;
      } // Private
      ;
  
      _proto._getRootElement = function _getRootElement(element) {
        var selector = Util.getSelectorFromElement(element);
        var parent = false;
  
        if (selector) {
          parent = document.querySelector(selector);
        }
  
        if (!parent) {
          parent = $(element).closest("." + CLASS_NAME_ALERT)[0];
        }
  
        return parent;
      };
  
      _proto._triggerCloseEvent = function _triggerCloseEvent(element) {
        var closeEvent = $.Event(EVENT_CLOSE);
        $(element).trigger(closeEvent);
        return closeEvent;
      };
  
      _proto._removeElement = function _removeElement(element) {
        var _this = this;
  
        $(element).removeClass(CLASS_NAME_SHOW);
  
        if (!$(element).hasClass(CLASS_NAME_FADE)) {
          this._destroyElement(element);
  
          return;
        }
  
        var transitionDuration = Util.getTransitionDurationFromElement(element);
        $(element).one(Util.TRANSITION_END, function (event) {
          return _this._destroyElement(element, event);
        }).emulateTransitionEnd(transitionDuration);
      };
  
      _proto._destroyElement = function _destroyElement(element) {
        $(element).detach().trigger(EVENT_CLOSED).remove();
      } // Static
      ;
  
      Alert._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var $element = $(this);
          var data = $element.data(DATA_KEY);
  
          if (!data) {
            data = new Alert(this);
            $element.data(DATA_KEY, data);
          }
  
          if (config === 'close') {
            data[config](this);
          }
        });
      };
  
      Alert._handleDismiss = function _handleDismiss(alertInstance) {
        return function (event) {
          if (event) {
            event.preventDefault();
          }
  
          alertInstance.close(this);
        };
      };
  
      _createClass(Alert, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION;
        }
      }]);
  
      return Alert;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert._handleDismiss(new Alert()));
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME] = Alert._jQueryInterface;
    $.fn[NAME].Constructor = Alert;
  
    $.fn[NAME].noConflict = function () {
      $.fn[NAME] = JQUERY_NO_CONFLICT;
      return Alert._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$1 = 'button';
    var VERSION$1 = '4.5.0';
    var DATA_KEY$1 = 'bs.button';
    var EVENT_KEY$1 = "." + DATA_KEY$1;
    var DATA_API_KEY$1 = '.data-api';
    var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1];
    var CLASS_NAME_ACTIVE = 'active';
    var CLASS_NAME_BUTTON = 'btn';
    var CLASS_NAME_FOCUS = 'focus';
    var SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]';
    var SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]';
    var SELECTOR_DATA_TOGGLE = '[data-toggle="button"]';
    var SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn';
    var SELECTOR_INPUT = 'input:not([type="hidden"])';
    var SELECTOR_ACTIVE = '.active';
    var SELECTOR_BUTTON = '.btn';
    var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$1 + DATA_API_KEY$1;
    var EVENT_FOCUS_BLUR_DATA_API = "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1);
    var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$1 + DATA_API_KEY$1;
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Button = /*#__PURE__*/function () {
      function Button(element) {
        this._element = element;
      } // Getters
  
  
      var _proto = Button.prototype;
  
      // Public
      _proto.toggle = function toggle() {
        var triggerChangeEvent = true;
        var addAriaPressed = true;
        var rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0];
  
        if (rootElement) {
          var input = this._element.querySelector(SELECTOR_INPUT);
  
          if (input) {
            if (input.type === 'radio') {
              if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
                triggerChangeEvent = false;
              } else {
                var activeElement = rootElement.querySelector(SELECTOR_ACTIVE);
  
                if (activeElement) {
                  $(activeElement).removeClass(CLASS_NAME_ACTIVE);
                }
              }
            }
  
            if (triggerChangeEvent) {
              // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
              if (input.type === 'checkbox' || input.type === 'radio') {
                input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE);
              }
  
              $(input).trigger('change');
            }
  
            input.focus();
            addAriaPressed = false;
          }
        }
  
        if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
          if (addAriaPressed) {
            this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE));
          }
  
          if (triggerChangeEvent) {
            $(this._element).toggleClass(CLASS_NAME_ACTIVE);
          }
        }
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY$1);
        this._element = null;
      } // Static
      ;
  
      Button._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$1);
  
          if (!data) {
            data = new Button(this);
            $(this).data(DATA_KEY$1, data);
          }
  
          if (config === 'toggle') {
            data[config]();
          }
        });
      };
  
      _createClass(Button, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$1;
        }
      }]);
  
      return Button;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
      var button = event.target;
      var initialButton = button;
  
      if (!$(button).hasClass(CLASS_NAME_BUTTON)) {
        button = $(button).closest(SELECTOR_BUTTON)[0];
      }
  
      if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
        event.preventDefault(); // work around Firefox bug #1540995
      } else {
        var inputBtn = button.querySelector(SELECTOR_INPUT);
  
        if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
          event.preventDefault(); // work around Firefox bug #1540995
  
          return;
        }
  
        if (initialButton.tagName === 'LABEL' && inputBtn && inputBtn.type === 'checkbox') {
          event.preventDefault(); // work around event sent to label and input
        }
  
        Button._jQueryInterface.call($(button), 'toggle');
      }
    }).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
      var button = $(event.target).closest(SELECTOR_BUTTON)[0];
      $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type));
    });
    $(window).on(EVENT_LOAD_DATA_API, function () {
      // ensure correct active class is set to match the controls' actual values/states
      // find all checkboxes/readio buttons inside data-toggle groups
      var buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS));
  
      for (var i = 0, len = buttons.length; i < len; i++) {
        var button = buttons[i];
        var input = button.querySelector(SELECTOR_INPUT);
  
        if (input.checked || input.hasAttribute('checked')) {
          button.classList.add(CLASS_NAME_ACTIVE);
        } else {
          button.classList.remove(CLASS_NAME_ACTIVE);
        }
      } // find all button toggles
  
  
      buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
  
      for (var _i = 0, _len = buttons.length; _i < _len; _i++) {
        var _button = buttons[_i];
  
        if (_button.getAttribute('aria-pressed') === 'true') {
          _button.classList.add(CLASS_NAME_ACTIVE);
        } else {
          _button.classList.remove(CLASS_NAME_ACTIVE);
        }
      }
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$1] = Button._jQueryInterface;
    $.fn[NAME$1].Constructor = Button;
  
    $.fn[NAME$1].noConflict = function () {
      $.fn[NAME$1] = JQUERY_NO_CONFLICT$1;
      return Button._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$2 = 'carousel';
    var VERSION$2 = '4.5.0';
    var DATA_KEY$2 = 'bs.carousel';
    var EVENT_KEY$2 = "." + DATA_KEY$2;
    var DATA_API_KEY$2 = '.data-api';
    var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2];
    var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
  
    var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
  
    var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
  
    var SWIPE_THRESHOLD = 40;
    var Default = {
      interval: 5000,
      keyboard: true,
      slide: false,
      pause: 'hover',
      wrap: true,
      touch: true
    };
    var DefaultType = {
      interval: '(number|boolean)',
      keyboard: 'boolean',
      slide: '(boolean|string)',
      pause: '(string|boolean)',
      wrap: 'boolean',
      touch: 'boolean'
    };
    var DIRECTION_NEXT = 'next';
    var DIRECTION_PREV = 'prev';
    var DIRECTION_LEFT = 'left';
    var DIRECTION_RIGHT = 'right';
    var EVENT_SLIDE = "slide" + EVENT_KEY$2;
    var EVENT_SLID = "slid" + EVENT_KEY$2;
    var EVENT_KEYDOWN = "keydown" + EVENT_KEY$2;
    var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$2;
    var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$2;
    var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$2;
    var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$2;
    var EVENT_TOUCHEND = "touchend" + EVENT_KEY$2;
    var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$2;
    var EVENT_POINTERUP = "pointerup" + EVENT_KEY$2;
    var EVENT_DRAG_START = "dragstart" + EVENT_KEY$2;
    var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$2 + DATA_API_KEY$2;
    var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$2 + DATA_API_KEY$2;
    var CLASS_NAME_CAROUSEL = 'carousel';
    var CLASS_NAME_ACTIVE$1 = 'active';
    var CLASS_NAME_SLIDE = 'slide';
    var CLASS_NAME_RIGHT = 'carousel-item-right';
    var CLASS_NAME_LEFT = 'carousel-item-left';
    var CLASS_NAME_NEXT = 'carousel-item-next';
    var CLASS_NAME_PREV = 'carousel-item-prev';
    var CLASS_NAME_POINTER_EVENT = 'pointer-event';
    var SELECTOR_ACTIVE$1 = '.active';
    var SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
    var SELECTOR_ITEM = '.carousel-item';
    var SELECTOR_ITEM_IMG = '.carousel-item img';
    var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
    var SELECTOR_INDICATORS = '.carousel-indicators';
    var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]';
    var SELECTOR_DATA_RIDE = '[data-ride="carousel"]';
    var PointerType = {
      TOUCH: 'touch',
      PEN: 'pen'
    };
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Carousel = /*#__PURE__*/function () {
      function Carousel(element, config) {
        this._items = null;
        this._interval = null;
        this._activeElement = null;
        this._isPaused = false;
        this._isSliding = false;
        this.touchTimeout = null;
        this.touchStartX = 0;
        this.touchDeltaX = 0;
        this._config = this._getConfig(config);
        this._element = element;
        this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS);
        this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
        this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
  
        this._addEventListeners();
      } // Getters
  
  
      var _proto = Carousel.prototype;
  
      // Public
      _proto.next = function next() {
        if (!this._isSliding) {
          this._slide(DIRECTION_NEXT);
        }
      };
  
      _proto.nextWhenVisible = function nextWhenVisible() {
        // Don't call next when the page isn't visible
        // or the carousel or its parent isn't visible
        if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') {
          this.next();
        }
      };
  
      _proto.prev = function prev() {
        if (!this._isSliding) {
          this._slide(DIRECTION_PREV);
        }
      };
  
      _proto.pause = function pause(event) {
        if (!event) {
          this._isPaused = true;
        }
  
        if (this._element.querySelector(SELECTOR_NEXT_PREV)) {
          Util.triggerTransitionEnd(this._element);
          this.cycle(true);
        }
  
        clearInterval(this._interval);
        this._interval = null;
      };
  
      _proto.cycle = function cycle(event) {
        if (!event) {
          this._isPaused = false;
        }
  
        if (this._interval) {
          clearInterval(this._interval);
          this._interval = null;
        }
  
        if (this._config.interval && !this._isPaused) {
          this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
        }
      };
  
      _proto.to = function to(index) {
        var _this = this;
  
        this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
  
        var activeIndex = this._getItemIndex(this._activeElement);
  
        if (index > this._items.length - 1 || index < 0) {
          return;
        }
  
        if (this._isSliding) {
          $(this._element).one(EVENT_SLID, function () {
            return _this.to(index);
          });
          return;
        }
  
        if (activeIndex === index) {
          this.pause();
          this.cycle();
          return;
        }
  
        var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV;
  
        this._slide(direction, this._items[index]);
      };
  
      _proto.dispose = function dispose() {
        $(this._element).off(EVENT_KEY$2);
        $.removeData(this._element, DATA_KEY$2);
        this._items = null;
        this._config = null;
        this._element = null;
        this._interval = null;
        this._isPaused = null;
        this._isSliding = null;
        this._activeElement = null;
        this._indicatorsElement = null;
      } // Private
      ;
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2({}, Default), config);
        Util.typeCheckConfig(NAME$2, config, DefaultType);
        return config;
      };
  
      _proto._handleSwipe = function _handleSwipe() {
        var absDeltax = Math.abs(this.touchDeltaX);
  
        if (absDeltax <= SWIPE_THRESHOLD) {
          return;
        }
  
        var direction = absDeltax / this.touchDeltaX;
        this.touchDeltaX = 0; // swipe left
  
        if (direction > 0) {
          this.prev();
        } // swipe right
  
  
        if (direction < 0) {
          this.next();
        }
      };
  
      _proto._addEventListeners = function _addEventListeners() {
        var _this2 = this;
  
        if (this._config.keyboard) {
          $(this._element).on(EVENT_KEYDOWN, function (event) {
            return _this2._keydown(event);
          });
        }
  
        if (this._config.pause === 'hover') {
          $(this._element).on(EVENT_MOUSEENTER, function (event) {
            return _this2.pause(event);
          }).on(EVENT_MOUSELEAVE, function (event) {
            return _this2.cycle(event);
          });
        }
  
        if (this._config.touch) {
          this._addTouchEventListeners();
        }
      };
  
      _proto._addTouchEventListeners = function _addTouchEventListeners() {
        var _this3 = this;
  
        if (!this._touchSupported) {
          return;
        }
  
        var start = function start(event) {
          if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
            _this3.touchStartX = event.originalEvent.clientX;
          } else if (!_this3._pointerEvent) {
            _this3.touchStartX = event.originalEvent.touches[0].clientX;
          }
        };
  
        var move = function move(event) {
          // ensure swiping with one touch and not pinching
          if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {
            _this3.touchDeltaX = 0;
          } else {
            _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;
          }
        };
  
        var end = function end(event) {
          if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
            _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
          }
  
          _this3._handleSwipe();
  
          if (_this3._config.pause === 'hover') {
            // If it's a touch-enabled device, mouseenter/leave are fired as
            // part of the mouse compatibility events on first tap - the carousel
            // would stop cycling until user tapped out of it;
            // here, we listen for touchend, explicitly pause the carousel
            // (as if it's the second time we tap on it, mouseenter compat event
            // is NOT fired) and after a timeout (to allow for mouse compatibility
            // events to fire) we explicitly restart cycling
            _this3.pause();
  
            if (_this3.touchTimeout) {
              clearTimeout(_this3.touchTimeout);
            }
  
            _this3.touchTimeout = setTimeout(function (event) {
              return _this3.cycle(event);
            }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
          }
        };
  
        $(this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, function (e) {
          return e.preventDefault();
        });
  
        if (this._pointerEvent) {
          $(this._element).on(EVENT_POINTERDOWN, function (event) {
            return start(event);
          });
          $(this._element).on(EVENT_POINTERUP, function (event) {
            return end(event);
          });
  
          this._element.classList.add(CLASS_NAME_POINTER_EVENT);
        } else {
          $(this._element).on(EVENT_TOUCHSTART, function (event) {
            return start(event);
          });
          $(this._element).on(EVENT_TOUCHMOVE, function (event) {
            return move(event);
          });
          $(this._element).on(EVENT_TOUCHEND, function (event) {
            return end(event);
          });
        }
      };
  
      _proto._keydown = function _keydown(event) {
        if (/input|textarea/i.test(event.target.tagName)) {
          return;
        }
  
        switch (event.which) {
          case ARROW_LEFT_KEYCODE:
            event.preventDefault();
            this.prev();
            break;
  
          case ARROW_RIGHT_KEYCODE:
            event.preventDefault();
            this.next();
            break;
        }
      };
  
      _proto._getItemIndex = function _getItemIndex(element) {
        this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : [];
        return this._items.indexOf(element);
      };
  
      _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
        var isNextDirection = direction === DIRECTION_NEXT;
        var isPrevDirection = direction === DIRECTION_PREV;
  
        var activeIndex = this._getItemIndex(activeElement);
  
        var lastItemIndex = this._items.length - 1;
        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
  
        if (isGoingToWrap && !this._config.wrap) {
          return activeElement;
        }
  
        var delta = direction === DIRECTION_PREV ? -1 : 1;
        var itemIndex = (activeIndex + delta) % this._items.length;
        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
      };
  
      _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
        var targetIndex = this._getItemIndex(relatedTarget);
  
        var fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM));
  
        var slideEvent = $.Event(EVENT_SLIDE, {
          relatedTarget: relatedTarget,
          direction: eventDirectionName,
          from: fromIndex,
          to: targetIndex
        });
        $(this._element).trigger(slideEvent);
        return slideEvent;
      };
  
      _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
        if (this._indicatorsElement) {
          var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE$1));
          $(indicators).removeClass(CLASS_NAME_ACTIVE$1);
  
          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
  
          if (nextIndicator) {
            $(nextIndicator).addClass(CLASS_NAME_ACTIVE$1);
          }
        }
      };
  
      _proto._slide = function _slide(direction, element) {
        var _this4 = this;
  
        var activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
  
        var activeElementIndex = this._getItemIndex(activeElement);
  
        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
  
        var nextElementIndex = this._getItemIndex(nextElement);
  
        var isCycling = Boolean(this._interval);
        var directionalClassName;
        var orderClassName;
        var eventDirectionName;
  
        if (direction === DIRECTION_NEXT) {
          directionalClassName = CLASS_NAME_LEFT;
          orderClassName = CLASS_NAME_NEXT;
          eventDirectionName = DIRECTION_LEFT;
        } else {
          directionalClassName = CLASS_NAME_RIGHT;
          orderClassName = CLASS_NAME_PREV;
          eventDirectionName = DIRECTION_RIGHT;
        }
  
        if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE$1)) {
          this._isSliding = false;
          return;
        }
  
        var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
  
        if (slideEvent.isDefaultPrevented()) {
          return;
        }
  
        if (!activeElement || !nextElement) {
          // Some weirdness is happening, so we bail
          return;
        }
  
        this._isSliding = true;
  
        if (isCycling) {
          this.pause();
        }
  
        this._setActiveIndicatorElement(nextElement);
  
        var slidEvent = $.Event(EVENT_SLID, {
          relatedTarget: nextElement,
          direction: eventDirectionName,
          from: activeElementIndex,
          to: nextElementIndex
        });
  
        if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {
          $(nextElement).addClass(orderClassName);
          Util.reflow(nextElement);
          $(activeElement).addClass(directionalClassName);
          $(nextElement).addClass(directionalClassName);
          var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10);
  
          if (nextElementInterval) {
            this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
            this._config.interval = nextElementInterval;
          } else {
            this._config.interval = this._config.defaultInterval || this._config.interval;
          }
  
          var transitionDuration = Util.getTransitionDurationFromElement(activeElement);
          $(activeElement).one(Util.TRANSITION_END, function () {
            $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$1);
            $(activeElement).removeClass(CLASS_NAME_ACTIVE$1 + " " + orderClassName + " " + directionalClassName);
            _this4._isSliding = false;
            setTimeout(function () {
              return $(_this4._element).trigger(slidEvent);
            }, 0);
          }).emulateTransitionEnd(transitionDuration);
        } else {
          $(activeElement).removeClass(CLASS_NAME_ACTIVE$1);
          $(nextElement).addClass(CLASS_NAME_ACTIVE$1);
          this._isSliding = false;
          $(this._element).trigger(slidEvent);
        }
  
        if (isCycling) {
          this.cycle();
        }
      } // Static
      ;
  
      Carousel._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$2);
  
          var _config = _objectSpread2(_objectSpread2({}, Default), $(this).data());
  
          if (typeof config === 'object') {
            _config = _objectSpread2(_objectSpread2({}, _config), config);
          }
  
          var action = typeof config === 'string' ? config : _config.slide;
  
          if (!data) {
            data = new Carousel(this, _config);
            $(this).data(DATA_KEY$2, data);
          }
  
          if (typeof config === 'number') {
            data.to(config);
          } else if (typeof action === 'string') {
            if (typeof data[action] === 'undefined') {
              throw new TypeError("No method named \"" + action + "\"");
            }
  
            data[action]();
          } else if (_config.interval && _config.ride) {
            data.pause();
            data.cycle();
          }
        });
      };
  
      Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
        var selector = Util.getSelectorFromElement(this);
  
        if (!selector) {
          return;
        }
  
        var target = $(selector)[0];
  
        if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {
          return;
        }
  
        var config = _objectSpread2(_objectSpread2({}, $(target).data()), $(this).data());
  
        var slideIndex = this.getAttribute('data-slide-to');
  
        if (slideIndex) {
          config.interval = false;
        }
  
        Carousel._jQueryInterface.call($(target), config);
  
        if (slideIndex) {
          $(target).data(DATA_KEY$2).to(slideIndex);
        }
  
        event.preventDefault();
      };
  
      _createClass(Carousel, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$2;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default;
        }
      }]);
  
      return Carousel;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API$2, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler);
    $(window).on(EVENT_LOAD_DATA_API$1, function () {
      var carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE));
  
      for (var i = 0, len = carousels.length; i < len; i++) {
        var $carousel = $(carousels[i]);
  
        Carousel._jQueryInterface.call($carousel, $carousel.data());
      }
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$2] = Carousel._jQueryInterface;
    $.fn[NAME$2].Constructor = Carousel;
  
    $.fn[NAME$2].noConflict = function () {
      $.fn[NAME$2] = JQUERY_NO_CONFLICT$2;
      return Carousel._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$3 = 'collapse';
    var VERSION$3 = '4.5.0';
    var DATA_KEY$3 = 'bs.collapse';
    var EVENT_KEY$3 = "." + DATA_KEY$3;
    var DATA_API_KEY$3 = '.data-api';
    var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3];
    var Default$1 = {
      toggle: true,
      parent: ''
    };
    var DefaultType$1 = {
      toggle: 'boolean',
      parent: '(string|element)'
    };
    var EVENT_SHOW = "show" + EVENT_KEY$3;
    var EVENT_SHOWN = "shown" + EVENT_KEY$3;
    var EVENT_HIDE = "hide" + EVENT_KEY$3;
    var EVENT_HIDDEN = "hidden" + EVENT_KEY$3;
    var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$3 + DATA_API_KEY$3;
    var CLASS_NAME_SHOW$1 = 'show';
    var CLASS_NAME_COLLAPSE = 'collapse';
    var CLASS_NAME_COLLAPSING = 'collapsing';
    var CLASS_NAME_COLLAPSED = 'collapsed';
    var DIMENSION_WIDTH = 'width';
    var DIMENSION_HEIGHT = 'height';
    var SELECTOR_ACTIVES = '.show, .collapsing';
    var SELECTOR_DATA_TOGGLE$1 = '[data-toggle="collapse"]';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Collapse = /*#__PURE__*/function () {
      function Collapse(element, config) {
        this._isTransitioning = false;
        this._element = element;
        this._config = this._getConfig(config);
        this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
        var toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$1));
  
        for (var i = 0, len = toggleList.length; i < len; i++) {
          var elem = toggleList[i];
          var selector = Util.getSelectorFromElement(elem);
          var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
            return foundElem === element;
          });
  
          if (selector !== null && filterElement.length > 0) {
            this._selector = selector;
  
            this._triggerArray.push(elem);
          }
        }
  
        this._parent = this._config.parent ? this._getParent() : null;
  
        if (!this._config.parent) {
          this._addAriaAndCollapsedClass(this._element, this._triggerArray);
        }
  
        if (this._config.toggle) {
          this.toggle();
        }
      } // Getters
  
  
      var _proto = Collapse.prototype;
  
      // Public
      _proto.toggle = function toggle() {
        if ($(this._element).hasClass(CLASS_NAME_SHOW$1)) {
          this.hide();
        } else {
          this.show();
        }
      };
  
      _proto.show = function show() {
        var _this = this;
  
        if (this._isTransitioning || $(this._element).hasClass(CLASS_NAME_SHOW$1)) {
          return;
        }
  
        var actives;
        var activesData;
  
        if (this._parent) {
          actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)).filter(function (elem) {
            if (typeof _this._config.parent === 'string') {
              return elem.getAttribute('data-parent') === _this._config.parent;
            }
  
            return elem.classList.contains(CLASS_NAME_COLLAPSE);
          });
  
          if (actives.length === 0) {
            actives = null;
          }
        }
  
        if (actives) {
          activesData = $(actives).not(this._selector).data(DATA_KEY$3);
  
          if (activesData && activesData._isTransitioning) {
            return;
          }
        }
  
        var startEvent = $.Event(EVENT_SHOW);
        $(this._element).trigger(startEvent);
  
        if (startEvent.isDefaultPrevented()) {
          return;
        }
  
        if (actives) {
          Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide');
  
          if (!activesData) {
            $(actives).data(DATA_KEY$3, null);
          }
        }
  
        var dimension = this._getDimension();
  
        $(this._element).removeClass(CLASS_NAME_COLLAPSE).addClass(CLASS_NAME_COLLAPSING);
        this._element.style[dimension] = 0;
  
        if (this._triggerArray.length) {
          $(this._triggerArray).removeClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', true);
        }
  
        this.setTransitioning(true);
  
        var complete = function complete() {
          $(_this._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
          _this._element.style[dimension] = '';
  
          _this.setTransitioning(false);
  
          $(_this._element).trigger(EVENT_SHOWN);
        };
  
        var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
        var scrollSize = "scroll" + capitalizedDimension;
        var transitionDuration = Util.getTransitionDurationFromElement(this._element);
        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
        this._element.style[dimension] = this._element[scrollSize] + "px";
      };
  
      _proto.hide = function hide() {
        var _this2 = this;
  
        if (this._isTransitioning || !$(this._element).hasClass(CLASS_NAME_SHOW$1)) {
          return;
        }
  
        var startEvent = $.Event(EVENT_HIDE);
        $(this._element).trigger(startEvent);
  
        if (startEvent.isDefaultPrevented()) {
          return;
        }
  
        var dimension = this._getDimension();
  
        this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
        Util.reflow(this._element);
        $(this._element).addClass(CLASS_NAME_COLLAPSING).removeClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
        var triggerArrayLength = this._triggerArray.length;
  
        if (triggerArrayLength > 0) {
          for (var i = 0; i < triggerArrayLength; i++) {
            var trigger = this._triggerArray[i];
            var selector = Util.getSelectorFromElement(trigger);
  
            if (selector !== null) {
              var $elem = $([].slice.call(document.querySelectorAll(selector)));
  
              if (!$elem.hasClass(CLASS_NAME_SHOW$1)) {
                $(trigger).addClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', false);
              }
            }
          }
        }
  
        this.setTransitioning(true);
  
        var complete = function complete() {
          _this2.setTransitioning(false);
  
          $(_this2._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE).trigger(EVENT_HIDDEN);
        };
  
        this._element.style[dimension] = '';
        var transitionDuration = Util.getTransitionDurationFromElement(this._element);
        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
      };
  
      _proto.setTransitioning = function setTransitioning(isTransitioning) {
        this._isTransitioning = isTransitioning;
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY$3);
        this._config = null;
        this._parent = null;
        this._element = null;
        this._triggerArray = null;
        this._isTransitioning = null;
      } // Private
      ;
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2({}, Default$1), config);
        config.toggle = Boolean(config.toggle); // Coerce string values
  
        Util.typeCheckConfig(NAME$3, config, DefaultType$1);
        return config;
      };
  
      _proto._getDimension = function _getDimension() {
        var hasWidth = $(this._element).hasClass(DIMENSION_WIDTH);
        return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT;
      };
  
      _proto._getParent = function _getParent() {
        var _this3 = this;
  
        var parent;
  
        if (Util.isElement(this._config.parent)) {
          parent = this._config.parent; // It's a jQuery object
  
          if (typeof this._config.parent.jquery !== 'undefined') {
            parent = this._config.parent[0];
          }
        } else {
          parent = document.querySelector(this._config.parent);
        }
  
        var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
        var children = [].slice.call(parent.querySelectorAll(selector));
        $(children).each(function (i, element) {
          _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
        });
        return parent;
      };
  
      _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
        var isOpen = $(element).hasClass(CLASS_NAME_SHOW$1);
  
        if (triggerArray.length) {
          $(triggerArray).toggleClass(CLASS_NAME_COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
        }
      } // Static
      ;
  
      Collapse._getTargetFromElement = function _getTargetFromElement(element) {
        var selector = Util.getSelectorFromElement(element);
        return selector ? document.querySelector(selector) : null;
      };
  
      Collapse._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var $this = $(this);
          var data = $this.data(DATA_KEY$3);
  
          var _config = _objectSpread2(_objectSpread2(_objectSpread2({}, Default$1), $this.data()), typeof config === 'object' && config ? config : {});
  
          if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
            _config.toggle = false;
          }
  
          if (!data) {
            data = new Collapse(this, _config);
            $this.data(DATA_KEY$3, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      _createClass(Collapse, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$3;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$1;
        }
      }]);
  
      return Collapse;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$1, function (event) {
      // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
      if (event.currentTarget.tagName === 'A') {
        event.preventDefault();
      }
  
      var $trigger = $(this);
      var selector = Util.getSelectorFromElement(this);
      var selectors = [].slice.call(document.querySelectorAll(selector));
      $(selectors).each(function () {
        var $target = $(this);
        var data = $target.data(DATA_KEY$3);
        var config = data ? 'toggle' : $trigger.data();
  
        Collapse._jQueryInterface.call($target, config);
      });
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$3] = Collapse._jQueryInterface;
    $.fn[NAME$3].Constructor = Collapse;
  
    $.fn[NAME$3].noConflict = function () {
      $.fn[NAME$3] = JQUERY_NO_CONFLICT$3;
      return Collapse._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$4 = 'dropdown';
    var VERSION$4 = '4.5.0';
    var DATA_KEY$4 = 'bs.dropdown';
    var EVENT_KEY$4 = "." + DATA_KEY$4;
    var DATA_API_KEY$4 = '.data-api';
    var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4];
    var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
  
    var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
  
    var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
  
    var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
  
    var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
  
    var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
  
    var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
    var EVENT_HIDE$1 = "hide" + EVENT_KEY$4;
    var EVENT_HIDDEN$1 = "hidden" + EVENT_KEY$4;
    var EVENT_SHOW$1 = "show" + EVENT_KEY$4;
    var EVENT_SHOWN$1 = "shown" + EVENT_KEY$4;
    var EVENT_CLICK = "click" + EVENT_KEY$4;
    var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$4 + DATA_API_KEY$4;
    var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$4 + DATA_API_KEY$4;
    var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$4 + DATA_API_KEY$4;
    var CLASS_NAME_DISABLED = 'disabled';
    var CLASS_NAME_SHOW$2 = 'show';
    var CLASS_NAME_DROPUP = 'dropup';
    var CLASS_NAME_DROPRIGHT = 'dropright';
    var CLASS_NAME_DROPLEFT = 'dropleft';
    var CLASS_NAME_MENURIGHT = 'dropdown-menu-right';
    var CLASS_NAME_POSITION_STATIC = 'position-static';
    var SELECTOR_DATA_TOGGLE$2 = '[data-toggle="dropdown"]';
    var SELECTOR_FORM_CHILD = '.dropdown form';
    var SELECTOR_MENU = '.dropdown-menu';
    var SELECTOR_NAVBAR_NAV = '.navbar-nav';
    var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
    var PLACEMENT_TOP = 'top-start';
    var PLACEMENT_TOPEND = 'top-end';
    var PLACEMENT_BOTTOM = 'bottom-start';
    var PLACEMENT_BOTTOMEND = 'bottom-end';
    var PLACEMENT_RIGHT = 'right-start';
    var PLACEMENT_LEFT = 'left-start';
    var Default$2 = {
      offset: 0,
      flip: true,
      boundary: 'scrollParent',
      reference: 'toggle',
      display: 'dynamic',
      popperConfig: null
    };
    var DefaultType$2 = {
      offset: '(number|string|function)',
      flip: 'boolean',
      boundary: '(string|element)',
      reference: '(string|element)',
      display: 'string',
      popperConfig: '(null|object)'
    };
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Dropdown = /*#__PURE__*/function () {
      function Dropdown(element, config) {
        this._element = element;
        this._popper = null;
        this._config = this._getConfig(config);
        this._menu = this._getMenuElement();
        this._inNavbar = this._detectNavbar();
  
        this._addEventListeners();
      } // Getters
  
  
      var _proto = Dropdown.prototype;
  
      // Public
      _proto.toggle = function toggle() {
        if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {
          return;
        }
  
        var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW$2);
  
        Dropdown._clearMenus();
  
        if (isActive) {
          return;
        }
  
        this.show(true);
      };
  
      _proto.show = function show(usePopper) {
        if (usePopper === void 0) {
          usePopper = false;
        }
  
        if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW$2)) {
          return;
        }
  
        var relatedTarget = {
          relatedTarget: this._element
        };
        var showEvent = $.Event(EVENT_SHOW$1, relatedTarget);
  
        var parent = Dropdown._getParentFromElement(this._element);
  
        $(parent).trigger(showEvent);
  
        if (showEvent.isDefaultPrevented()) {
          return;
        } // Disable totally Popper.js for Dropdown in Navbar
  
  
        if (!this._inNavbar && usePopper) {
          /**
           * Check for Popper dependency
           * Popper - https://popper.js.org
           */
          if (typeof Popper === 'undefined') {
            throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
          }
  
          var referenceElement = this._element;
  
          if (this._config.reference === 'parent') {
            referenceElement = parent;
          } else if (Util.isElement(this._config.reference)) {
            referenceElement = this._config.reference; // Check if it's jQuery element
  
            if (typeof this._config.reference.jquery !== 'undefined') {
              referenceElement = this._config.reference[0];
            }
          } // If boundary is not `scrollParent`, then set position to `static`
          // to allow the menu to "escape" the scroll parent's boundaries
          // https://github.com/twbs/bootstrap/issues/24251
  
  
          if (this._config.boundary !== 'scrollParent') {
            $(parent).addClass(CLASS_NAME_POSITION_STATIC);
          }
  
          this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
        } // If this is a touch-enabled device we add extra
        // empty mouseover listeners to the body's immediate children;
        // only needed because of broken event delegation on iOS
        // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
  
  
        if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
          $(document.body).children().on('mouseover', null, $.noop);
        }
  
        this._element.focus();
  
        this._element.setAttribute('aria-expanded', true);
  
        $(this._menu).toggleClass(CLASS_NAME_SHOW$2);
        $(parent).toggleClass(CLASS_NAME_SHOW$2).trigger($.Event(EVENT_SHOWN$1, relatedTarget));
      };
  
      _proto.hide = function hide() {
        if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW$2)) {
          return;
        }
  
        var relatedTarget = {
          relatedTarget: this._element
        };
        var hideEvent = $.Event(EVENT_HIDE$1, relatedTarget);
  
        var parent = Dropdown._getParentFromElement(this._element);
  
        $(parent).trigger(hideEvent);
  
        if (hideEvent.isDefaultPrevented()) {
          return;
        }
  
        if (this._popper) {
          this._popper.destroy();
        }
  
        $(this._menu).toggleClass(CLASS_NAME_SHOW$2);
        $(parent).toggleClass(CLASS_NAME_SHOW$2).trigger($.Event(EVENT_HIDDEN$1, relatedTarget));
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY$4);
        $(this._element).off(EVENT_KEY$4);
        this._element = null;
        this._menu = null;
  
        if (this._popper !== null) {
          this._popper.destroy();
  
          this._popper = null;
        }
      };
  
      _proto.update = function update() {
        this._inNavbar = this._detectNavbar();
  
        if (this._popper !== null) {
          this._popper.scheduleUpdate();
        }
      } // Private
      ;
  
      _proto._addEventListeners = function _addEventListeners() {
        var _this = this;
  
        $(this._element).on(EVENT_CLICK, function (event) {
          event.preventDefault();
          event.stopPropagation();
  
          _this.toggle();
        });
      };
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config);
        Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
        return config;
      };
  
      _proto._getMenuElement = function _getMenuElement() {
        if (!this._menu) {
          var parent = Dropdown._getParentFromElement(this._element);
  
          if (parent) {
            this._menu = parent.querySelector(SELECTOR_MENU);
          }
        }
  
        return this._menu;
      };
  
      _proto._getPlacement = function _getPlacement() {
        var $parentDropdown = $(this._element.parentNode);
        var placement = PLACEMENT_BOTTOM; // Handle dropup
  
        if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
          placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP;
        } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
          placement = PLACEMENT_RIGHT;
        } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
          placement = PLACEMENT_LEFT;
        } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
          placement = PLACEMENT_BOTTOMEND;
        }
  
        return placement;
      };
  
      _proto._detectNavbar = function _detectNavbar() {
        return $(this._element).closest('.navbar').length > 0;
      };
  
      _proto._getOffset = function _getOffset() {
        var _this2 = this;
  
        var offset = {};
  
        if (typeof this._config.offset === 'function') {
          offset.fn = function (data) {
            data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {});
            return data;
          };
        } else {
          offset.offset = this._config.offset;
        }
  
        return offset;
      };
  
      _proto._getPopperConfig = function _getPopperConfig() {
        var popperConfig = {
          placement: this._getPlacement(),
          modifiers: {
            offset: this._getOffset(),
            flip: {
              enabled: this._config.flip
            },
            preventOverflow: {
              boundariesElement: this._config.boundary
            }
          }
        }; // Disable Popper.js if we have a static display
  
        if (this._config.display === 'static') {
          popperConfig.modifiers.applyStyle = {
            enabled: false
          };
        }
  
        return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig);
      } // Static
      ;
  
      Dropdown._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$4);
  
          var _config = typeof config === 'object' ? config : null;
  
          if (!data) {
            data = new Dropdown(this, _config);
            $(this).data(DATA_KEY$4, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      Dropdown._clearMenus = function _clearMenus(event) {
        if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
          return;
        }
  
        var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$2));
  
        for (var i = 0, len = toggles.length; i < len; i++) {
          var parent = Dropdown._getParentFromElement(toggles[i]);
  
          var context = $(toggles[i]).data(DATA_KEY$4);
          var relatedTarget = {
            relatedTarget: toggles[i]
          };
  
          if (event && event.type === 'click') {
            relatedTarget.clickEvent = event;
          }
  
          if (!context) {
            continue;
          }
  
          var dropdownMenu = context._menu;
  
          if (!$(parent).hasClass(CLASS_NAME_SHOW$2)) {
            continue;
          }
  
          if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
            continue;
          }
  
          var hideEvent = $.Event(EVENT_HIDE$1, relatedTarget);
          $(parent).trigger(hideEvent);
  
          if (hideEvent.isDefaultPrevented()) {
            continue;
          } // If this is a touch-enabled device we remove the extra
          // empty mouseover listeners we added for iOS support
  
  
          if ('ontouchstart' in document.documentElement) {
            $(document.body).children().off('mouseover', null, $.noop);
          }
  
          toggles[i].setAttribute('aria-expanded', 'false');
  
          if (context._popper) {
            context._popper.destroy();
          }
  
          $(dropdownMenu).removeClass(CLASS_NAME_SHOW$2);
          $(parent).removeClass(CLASS_NAME_SHOW$2).trigger($.Event(EVENT_HIDDEN$1, relatedTarget));
        }
      };
  
      Dropdown._getParentFromElement = function _getParentFromElement(element) {
        var parent;
        var selector = Util.getSelectorFromElement(element);
  
        if (selector) {
          parent = document.querySelector(selector);
        }
  
        return parent || element.parentNode;
      } // eslint-disable-next-line complexity
      ;
  
      Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
        // If not input/textarea:
        //  - And not a key in REGEXP_KEYDOWN => not a dropdown command
        // If input/textarea:
        //  - If space key => not a dropdown command
        //  - If key is other than escape
        //    - If key is not up or down => not a dropdown command
        //    - If trigger inside the menu => not a dropdown command
        if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
          return;
        }
  
        if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {
          return;
        }
  
        var parent = Dropdown._getParentFromElement(this);
  
        var isActive = $(parent).hasClass(CLASS_NAME_SHOW$2);
  
        if (!isActive && event.which === ESCAPE_KEYCODE) {
          return;
        }
  
        event.preventDefault();
        event.stopPropagation();
  
        if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
          if (event.which === ESCAPE_KEYCODE) {
            $(parent.querySelector(SELECTOR_DATA_TOGGLE$2)).trigger('focus');
          }
  
          $(this).trigger('click');
          return;
        }
  
        var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) {
          return $(item).is(':visible');
        });
  
        if (items.length === 0) {
          return;
        }
  
        var index = items.indexOf(event.target);
  
        if (event.which === ARROW_UP_KEYCODE && index > 0) {
          // Up
          index--;
        }
  
        if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
          // Down
          index++;
        }
  
        if (index < 0) {
          index = 0;
        }
  
        items[index].focus();
      };
  
      _createClass(Dropdown, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$4;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$2;
        }
      }, {
        key: "DefaultType",
        get: function get() {
          return DefaultType$2;
        }
      }]);
  
      return Dropdown;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API$4 + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$2, function (event) {
      event.preventDefault();
      event.stopPropagation();
  
      Dropdown._jQueryInterface.call($(this), 'toggle');
    }).on(EVENT_CLICK_DATA_API$4, SELECTOR_FORM_CHILD, function (e) {
      e.stopPropagation();
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$4] = Dropdown._jQueryInterface;
    $.fn[NAME$4].Constructor = Dropdown;
  
    $.fn[NAME$4].noConflict = function () {
      $.fn[NAME$4] = JQUERY_NO_CONFLICT$4;
      return Dropdown._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$5 = 'modal';
    var VERSION$5 = '4.5.0';
    var DATA_KEY$5 = 'bs.modal';
    var EVENT_KEY$5 = "." + DATA_KEY$5;
    var DATA_API_KEY$5 = '.data-api';
    var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5];
    var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key
  
    var Default$3 = {
      backdrop: true,
      keyboard: true,
      focus: true,
      show: true
    };
    var DefaultType$3 = {
      backdrop: '(boolean|string)',
      keyboard: 'boolean',
      focus: 'boolean',
      show: 'boolean'
    };
    var EVENT_HIDE$2 = "hide" + EVENT_KEY$5;
    var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5;
    var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5;
    var EVENT_SHOW$2 = "show" + EVENT_KEY$5;
    var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5;
    var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5;
    var EVENT_RESIZE = "resize" + EVENT_KEY$5;
    var EVENT_CLICK_DISMISS = "click.dismiss" + EVENT_KEY$5;
    var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5;
    var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5;
    var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5;
    var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$5 + DATA_API_KEY$5;
    var CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable';
    var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
    var CLASS_NAME_BACKDROP = 'modal-backdrop';
    var CLASS_NAME_OPEN = 'modal-open';
    var CLASS_NAME_FADE$1 = 'fade';
    var CLASS_NAME_SHOW$3 = 'show';
    var CLASS_NAME_STATIC = 'modal-static';
    var SELECTOR_DIALOG = '.modal-dialog';
    var SELECTOR_MODAL_BODY = '.modal-body';
    var SELECTOR_DATA_TOGGLE$3 = '[data-toggle="modal"]';
    var SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]';
    var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
    var SELECTOR_STICKY_CONTENT = '.sticky-top';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Modal = /*#__PURE__*/function () {
      function Modal(element, config) {
        this._config = this._getConfig(config);
        this._element = element;
        this._dialog = element.querySelector(SELECTOR_DIALOG);
        this._backdrop = null;
        this._isShown = false;
        this._isBodyOverflowing = false;
        this._ignoreBackdropClick = false;
        this._isTransitioning = false;
        this._scrollbarWidth = 0;
      } // Getters
  
  
      var _proto = Modal.prototype;
  
      // Public
      _proto.toggle = function toggle(relatedTarget) {
        return this._isShown ? this.hide() : this.show(relatedTarget);
      };
  
      _proto.show = function show(relatedTarget) {
        var _this = this;
  
        if (this._isShown || this._isTransitioning) {
          return;
        }
  
        if ($(this._element).hasClass(CLASS_NAME_FADE$1)) {
          this._isTransitioning = true;
        }
  
        var showEvent = $.Event(EVENT_SHOW$2, {
          relatedTarget: relatedTarget
        });
        $(this._element).trigger(showEvent);
  
        if (this._isShown || showEvent.isDefaultPrevented()) {
          return;
        }
  
        this._isShown = true;
  
        this._checkScrollbar();
  
        this._setScrollbar();
  
        this._adjustDialog();
  
        this._setEscapeEvent();
  
        this._setResizeEvent();
  
        $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, function (event) {
          return _this.hide(event);
        });
        $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, function () {
          $(_this._element).one(EVENT_MOUSEUP_DISMISS, function (event) {
            if ($(event.target).is(_this._element)) {
              _this._ignoreBackdropClick = true;
            }
          });
        });
  
        this._showBackdrop(function () {
          return _this._showElement(relatedTarget);
        });
      };
  
      _proto.hide = function hide(event) {
        var _this2 = this;
  
        if (event) {
          event.preventDefault();
        }
  
        if (!this._isShown || this._isTransitioning) {
          return;
        }
  
        var hideEvent = $.Event(EVENT_HIDE$2);
        $(this._element).trigger(hideEvent);
  
        if (!this._isShown || hideEvent.isDefaultPrevented()) {
          return;
        }
  
        this._isShown = false;
        var transition = $(this._element).hasClass(CLASS_NAME_FADE$1);
  
        if (transition) {
          this._isTransitioning = true;
        }
  
        this._setEscapeEvent();
  
        this._setResizeEvent();
  
        $(document).off(EVENT_FOCUSIN);
        $(this._element).removeClass(CLASS_NAME_SHOW$3);
        $(this._element).off(EVENT_CLICK_DISMISS);
        $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS);
  
        if (transition) {
          var transitionDuration = Util.getTransitionDurationFromElement(this._element);
          $(this._element).one(Util.TRANSITION_END, function (event) {
            return _this2._hideModal(event);
          }).emulateTransitionEnd(transitionDuration);
        } else {
          this._hideModal();
        }
      };
  
      _proto.dispose = function dispose() {
        [window, this._element, this._dialog].forEach(function (htmlElement) {
          return $(htmlElement).off(EVENT_KEY$5);
        });
        /**
         * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
         * Do not move `document` in `htmlElements` array
         * It will remove `EVENT_CLICK_DATA_API` event that should remain
         */
  
        $(document).off(EVENT_FOCUSIN);
        $.removeData(this._element, DATA_KEY$5);
        this._config = null;
        this._element = null;
        this._dialog = null;
        this._backdrop = null;
        this._isShown = null;
        this._isBodyOverflowing = null;
        this._ignoreBackdropClick = null;
        this._isTransitioning = null;
        this._scrollbarWidth = null;
      };
  
      _proto.handleUpdate = function handleUpdate() {
        this._adjustDialog();
      } // Private
      ;
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2({}, Default$3), config);
        Util.typeCheckConfig(NAME$5, config, DefaultType$3);
        return config;
      };
  
      _proto._triggerBackdropTransition = function _triggerBackdropTransition() {
        var _this3 = this;
  
        if (this._config.backdrop === 'static') {
          var hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED);
          $(this._element).trigger(hideEventPrevented);
  
          if (hideEventPrevented.defaultPrevented) {
            return;
          }
  
          this._element.classList.add(CLASS_NAME_STATIC);
  
          var modalTransitionDuration = Util.getTransitionDurationFromElement(this._element);
          $(this._element).one(Util.TRANSITION_END, function () {
            _this3._element.classList.remove(CLASS_NAME_STATIC);
          }).emulateTransitionEnd(modalTransitionDuration);
  
          this._element.focus();
        } else {
          this.hide();
        }
      };
  
      _proto._showElement = function _showElement(relatedTarget) {
        var _this4 = this;
  
        var transition = $(this._element).hasClass(CLASS_NAME_FADE$1);
        var modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null;
  
        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
          // Don't move modal's DOM position
          document.body.appendChild(this._element);
        }
  
        this._element.style.display = 'block';
  
        this._element.removeAttribute('aria-hidden');
  
        this._element.setAttribute('aria-modal', true);
  
        if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
          modalBody.scrollTop = 0;
        } else {
          this._element.scrollTop = 0;
        }
  
        if (transition) {
          Util.reflow(this._element);
        }
  
        $(this._element).addClass(CLASS_NAME_SHOW$3);
  
        if (this._config.focus) {
          this._enforceFocus();
        }
  
        var shownEvent = $.Event(EVENT_SHOWN$2, {
          relatedTarget: relatedTarget
        });
  
        var transitionComplete = function transitionComplete() {
          if (_this4._config.focus) {
            _this4._element.focus();
          }
  
          _this4._isTransitioning = false;
          $(_this4._element).trigger(shownEvent);
        };
  
        if (transition) {
          var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);
          $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
        } else {
          transitionComplete();
        }
      };
  
      _proto._enforceFocus = function _enforceFocus() {
        var _this5 = this;
  
        $(document).off(EVENT_FOCUSIN) // Guard against infinite focus loop
        .on(EVENT_FOCUSIN, function (event) {
          if (document !== event.target && _this5._element !== event.target && $(_this5._element).has(event.target).length === 0) {
            _this5._element.focus();
          }
        });
      };
  
      _proto._setEscapeEvent = function _setEscapeEvent() {
        var _this6 = this;
  
        if (this._isShown) {
          $(this._element).on(EVENT_KEYDOWN_DISMISS, function (event) {
            if (_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
              event.preventDefault();
  
              _this6.hide();
            } else if (!_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
              _this6._triggerBackdropTransition();
            }
          });
        } else if (!this._isShown) {
          $(this._element).off(EVENT_KEYDOWN_DISMISS);
        }
      };
  
      _proto._setResizeEvent = function _setResizeEvent() {
        var _this7 = this;
  
        if (this._isShown) {
          $(window).on(EVENT_RESIZE, function (event) {
            return _this7.handleUpdate(event);
          });
        } else {
          $(window).off(EVENT_RESIZE);
        }
      };
  
      _proto._hideModal = function _hideModal() {
        var _this8 = this;
  
        this._element.style.display = 'none';
  
        this._element.setAttribute('aria-hidden', true);
  
        this._element.removeAttribute('aria-modal');
  
        this._isTransitioning = false;
  
        this._showBackdrop(function () {
          $(document.body).removeClass(CLASS_NAME_OPEN);
  
          _this8._resetAdjustments();
  
          _this8._resetScrollbar();
  
          $(_this8._element).trigger(EVENT_HIDDEN$2);
        });
      };
  
      _proto._removeBackdrop = function _removeBackdrop() {
        if (this._backdrop) {
          $(this._backdrop).remove();
          this._backdrop = null;
        }
      };
  
      _proto._showBackdrop = function _showBackdrop(callback) {
        var _this9 = this;
  
        var animate = $(this._element).hasClass(CLASS_NAME_FADE$1) ? CLASS_NAME_FADE$1 : '';
  
        if (this._isShown && this._config.backdrop) {
          this._backdrop = document.createElement('div');
          this._backdrop.className = CLASS_NAME_BACKDROP;
  
          if (animate) {
            this._backdrop.classList.add(animate);
          }
  
          $(this._backdrop).appendTo(document.body);
          $(this._element).on(EVENT_CLICK_DISMISS, function (event) {
            if (_this9._ignoreBackdropClick) {
              _this9._ignoreBackdropClick = false;
              return;
            }
  
            if (event.target !== event.currentTarget) {
              return;
            }
  
            _this9._triggerBackdropTransition();
          });
  
          if (animate) {
            Util.reflow(this._backdrop);
          }
  
          $(this._backdrop).addClass(CLASS_NAME_SHOW$3);
  
          if (!callback) {
            return;
          }
  
          if (!animate) {
            callback();
            return;
          }
  
          var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
          $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
        } else if (!this._isShown && this._backdrop) {
          $(this._backdrop).removeClass(CLASS_NAME_SHOW$3);
  
          var callbackRemove = function callbackRemove() {
            _this9._removeBackdrop();
  
            if (callback) {
              callback();
            }
          };
  
          if ($(this._element).hasClass(CLASS_NAME_FADE$1)) {
            var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
  
            $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
          } else {
            callbackRemove();
          }
        } else if (callback) {
          callback();
        }
      } // ----------------------------------------------------------------------
      // the following methods are used to handle overflowing modals
      // todo (fat): these should probably be refactored out of modal.js
      // ----------------------------------------------------------------------
      ;
  
      _proto._adjustDialog = function _adjustDialog() {
        var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
  
        if (!this._isBodyOverflowing && isModalOverflowing) {
          this._element.style.paddingLeft = this._scrollbarWidth + "px";
        }
  
        if (this._isBodyOverflowing && !isModalOverflowing) {
          this._element.style.paddingRight = this._scrollbarWidth + "px";
        }
      };
  
      _proto._resetAdjustments = function _resetAdjustments() {
        this._element.style.paddingLeft = '';
        this._element.style.paddingRight = '';
      };
  
      _proto._checkScrollbar = function _checkScrollbar() {
        var rect = document.body.getBoundingClientRect();
        this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
        this._scrollbarWidth = this._getScrollbarWidth();
      };
  
      _proto._setScrollbar = function _setScrollbar() {
        var _this10 = this;
  
        if (this._isBodyOverflowing) {
          // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
          //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
          var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
          var stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)); // Adjust fixed content padding
  
          $(fixedContent).each(function (index, element) {
            var actualPadding = element.style.paddingRight;
            var calculatedPadding = $(element).css('padding-right');
            $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px");
          }); // Adjust sticky content margin
  
          $(stickyContent).each(function (index, element) {
            var actualMargin = element.style.marginRight;
            var calculatedMargin = $(element).css('margin-right');
            $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px");
          }); // Adjust body padding
  
          var actualPadding = document.body.style.paddingRight;
          var calculatedPadding = $(document.body).css('padding-right');
          $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
        }
  
        $(document.body).addClass(CLASS_NAME_OPEN);
      };
  
      _proto._resetScrollbar = function _resetScrollbar() {
        // Restore fixed content padding
        var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
        $(fixedContent).each(function (index, element) {
          var padding = $(element).data('padding-right');
          $(element).removeData('padding-right');
          element.style.paddingRight = padding ? padding : '';
        }); // Restore sticky content
  
        var elements = [].slice.call(document.querySelectorAll("" + SELECTOR_STICKY_CONTENT));
        $(elements).each(function (index, element) {
          var margin = $(element).data('margin-right');
  
          if (typeof margin !== 'undefined') {
            $(element).css('margin-right', margin).removeData('margin-right');
          }
        }); // Restore body padding
  
        var padding = $(document.body).data('padding-right');
        $(document.body).removeData('padding-right');
        document.body.style.paddingRight = padding ? padding : '';
      };
  
      _proto._getScrollbarWidth = function _getScrollbarWidth() {
        // thx d.walsh
        var scrollDiv = document.createElement('div');
        scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
        document.body.appendChild(scrollDiv);
        var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
        document.body.removeChild(scrollDiv);
        return scrollbarWidth;
      } // Static
      ;
  
      Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$5);
  
          var _config = _objectSpread2(_objectSpread2(_objectSpread2({}, Default$3), $(this).data()), typeof config === 'object' && config ? config : {});
  
          if (!data) {
            data = new Modal(this, _config);
            $(this).data(DATA_KEY$5, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config](relatedTarget);
          } else if (_config.show) {
            data.show(relatedTarget);
          }
        });
      };
  
      _createClass(Modal, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$5;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$3;
        }
      }]);
  
      return Modal;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE$3, function (event) {
      var _this11 = this;
  
      var target;
      var selector = Util.getSelectorFromElement(this);
  
      if (selector) {
        target = document.querySelector(selector);
      }
  
      var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread2(_objectSpread2({}, $(target).data()), $(this).data());
  
      if (this.tagName === 'A' || this.tagName === 'AREA') {
        event.preventDefault();
      }
  
      var $target = $(target).one(EVENT_SHOW$2, function (showEvent) {
        if (showEvent.isDefaultPrevented()) {
          // Only register focus restorer if modal will actually get shown
          return;
        }
  
        $target.one(EVENT_HIDDEN$2, function () {
          if ($(_this11).is(':visible')) {
            _this11.focus();
          }
        });
      });
  
      Modal._jQueryInterface.call($(target), config, this);
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$5] = Modal._jQueryInterface;
    $.fn[NAME$5].Constructor = Modal;
  
    $.fn[NAME$5].noConflict = function () {
      $.fn[NAME$5] = JQUERY_NO_CONFLICT$5;
      return Modal._jQueryInterface;
    };
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v4.5.0): tools/sanitizer.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * --------------------------------------------------------------------------
     */
    var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
    var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
    var DefaultWhitelist = {
      // Global attributes allowed on any supplied element below.
      '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
      a: ['target', 'href', 'title', 'rel'],
      area: [],
      b: [],
      br: [],
      col: [],
      code: [],
      div: [],
      em: [],
      hr: [],
      h1: [],
      h2: [],
      h3: [],
      h4: [],
      h5: [],
      h6: [],
      i: [],
      img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
      li: [],
      ol: [],
      p: [],
      pre: [],
      s: [],
      small: [],
      span: [],
      sub: [],
      sup: [],
      strong: [],
      u: [],
      ul: []
    };
    /**
     * A pattern that recognizes a commonly useful subset of URLs that are safe.
     *
     * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
     */
  
    var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi;
    /**
     * A pattern that matches safe data URLs. Only matches image, video and audio types.
     *
     * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
     */
  
    var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
  
    function allowedAttribute(attr, allowedAttributeList) {
      var attrName = attr.nodeName.toLowerCase();
  
      if (allowedAttributeList.indexOf(attrName) !== -1) {
        if (uriAttrs.indexOf(attrName) !== -1) {
          return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
        }
  
        return true;
      }
  
      var regExp = allowedAttributeList.filter(function (attrRegex) {
        return attrRegex instanceof RegExp;
      }); // Check if a regular expression validates the attribute.
  
      for (var i = 0, len = regExp.length; i < len; i++) {
        if (attrName.match(regExp[i])) {
          return true;
        }
      }
  
      return false;
    }
  
    function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
      if (unsafeHtml.length === 0) {
        return unsafeHtml;
      }
  
      if (sanitizeFn && typeof sanitizeFn === 'function') {
        return sanitizeFn(unsafeHtml);
      }
  
      var domParser = new window.DOMParser();
      var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
      var whitelistKeys = Object.keys(whiteList);
      var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
  
      var _loop = function _loop(i, len) {
        var el = elements[i];
        var elName = el.nodeName.toLowerCase();
  
        if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
          el.parentNode.removeChild(el);
          return "continue";
        }
  
        var attributeList = [].slice.call(el.attributes);
        var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
        attributeList.forEach(function (attr) {
          if (!allowedAttribute(attr, whitelistedAttributes)) {
            el.removeAttribute(attr.nodeName);
          }
        });
      };
  
      for (var i = 0, len = elements.length; i < len; i++) {
        var _ret = _loop(i);
  
        if (_ret === "continue") continue;
      }
  
      return createdDocument.body.innerHTML;
    }
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$6 = 'tooltip';
    var VERSION$6 = '4.5.0';
    var DATA_KEY$6 = 'bs.tooltip';
    var EVENT_KEY$6 = "." + DATA_KEY$6;
    var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
    var CLASS_PREFIX = 'bs-tooltip';
    var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
    var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
    var DefaultType$4 = {
      animation: 'boolean',
      template: 'string',
      title: '(string|element|function)',
      trigger: 'string',
      delay: '(number|object)',
      html: 'boolean',
      selector: '(string|boolean)',
      placement: '(string|function)',
      offset: '(number|string|function)',
      container: '(string|element|boolean)',
      fallbackPlacement: '(string|array)',
      boundary: '(string|element)',
      sanitize: 'boolean',
      sanitizeFn: '(null|function)',
      whiteList: 'object',
      popperConfig: '(null|object)'
    };
    var AttachmentMap = {
      AUTO: 'auto',
      TOP: 'top',
      RIGHT: 'right',
      BOTTOM: 'bottom',
      LEFT: 'left'
    };
    var Default$4 = {
      animation: true,
      template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
      trigger: 'hover focus',
      title: '',
      delay: 0,
      html: false,
      selector: false,
      placement: 'top',
      offset: 0,
      container: false,
      fallbackPlacement: 'flip',
      boundary: 'scrollParent',
      sanitize: true,
      sanitizeFn: null,
      whiteList: DefaultWhitelist,
      popperConfig: null
    };
    var HOVER_STATE_SHOW = 'show';
    var HOVER_STATE_OUT = 'out';
    var Event = {
      HIDE: "hide" + EVENT_KEY$6,
      HIDDEN: "hidden" + EVENT_KEY$6,
      SHOW: "show" + EVENT_KEY$6,
      SHOWN: "shown" + EVENT_KEY$6,
      INSERTED: "inserted" + EVENT_KEY$6,
      CLICK: "click" + EVENT_KEY$6,
      FOCUSIN: "focusin" + EVENT_KEY$6,
      FOCUSOUT: "focusout" + EVENT_KEY$6,
      MOUSEENTER: "mouseenter" + EVENT_KEY$6,
      MOUSELEAVE: "mouseleave" + EVENT_KEY$6
    };
    var CLASS_NAME_FADE$2 = 'fade';
    var CLASS_NAME_SHOW$4 = 'show';
    var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
    var SELECTOR_ARROW = '.arrow';
    var TRIGGER_HOVER = 'hover';
    var TRIGGER_FOCUS = 'focus';
    var TRIGGER_CLICK = 'click';
    var TRIGGER_MANUAL = 'manual';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Tooltip = /*#__PURE__*/function () {
      function Tooltip(element, config) {
        if (typeof Popper === 'undefined') {
          throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
        } // private
  
  
        this._isEnabled = true;
        this._timeout = 0;
        this._hoverState = '';
        this._activeTrigger = {};
        this._popper = null; // Protected
  
        this.element = element;
        this.config = this._getConfig(config);
        this.tip = null;
  
        this._setListeners();
      } // Getters
  
  
      var _proto = Tooltip.prototype;
  
      // Public
      _proto.enable = function enable() {
        this._isEnabled = true;
      };
  
      _proto.disable = function disable() {
        this._isEnabled = false;
      };
  
      _proto.toggleEnabled = function toggleEnabled() {
        this._isEnabled = !this._isEnabled;
      };
  
      _proto.toggle = function toggle(event) {
        if (!this._isEnabled) {
          return;
        }
  
        if (event) {
          var dataKey = this.constructor.DATA_KEY;
          var context = $(event.currentTarget).data(dataKey);
  
          if (!context) {
            context = new this.constructor(event.currentTarget, this._getDelegateConfig());
            $(event.currentTarget).data(dataKey, context);
          }
  
          context._activeTrigger.click = !context._activeTrigger.click;
  
          if (context._isWithActiveTrigger()) {
            context._enter(null, context);
          } else {
            context._leave(null, context);
          }
        } else {
          if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW$4)) {
            this._leave(null, this);
  
            return;
          }
  
          this._enter(null, this);
        }
      };
  
      _proto.dispose = function dispose() {
        clearTimeout(this._timeout);
        $.removeData(this.element, this.constructor.DATA_KEY);
        $(this.element).off(this.constructor.EVENT_KEY);
        $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
  
        if (this.tip) {
          $(this.tip).remove();
        }
  
        this._isEnabled = null;
        this._timeout = null;
        this._hoverState = null;
        this._activeTrigger = null;
  
        if (this._popper) {
          this._popper.destroy();
        }
  
        this._popper = null;
        this.element = null;
        this.config = null;
        this.tip = null;
      };
  
      _proto.show = function show() {
        var _this = this;
  
        if ($(this.element).css('display') === 'none') {
          throw new Error('Please use show on visible elements');
        }
  
        var showEvent = $.Event(this.constructor.Event.SHOW);
  
        if (this.isWithContent() && this._isEnabled) {
          $(this.element).trigger(showEvent);
          var shadowRoot = Util.findShadowRoot(this.element);
          var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
  
          if (showEvent.isDefaultPrevented() || !isInTheDom) {
            return;
          }
  
          var tip = this.getTipElement();
          var tipId = Util.getUID(this.constructor.NAME);
          tip.setAttribute('id', tipId);
          this.element.setAttribute('aria-describedby', tipId);
          this.setContent();
  
          if (this.config.animation) {
            $(tip).addClass(CLASS_NAME_FADE$2);
          }
  
          var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
  
          var attachment = this._getAttachment(placement);
  
          this.addAttachmentClass(attachment);
  
          var container = this._getContainer();
  
          $(tip).data(this.constructor.DATA_KEY, this);
  
          if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
            $(tip).appendTo(container);
          }
  
          $(this.element).trigger(this.constructor.Event.INSERTED);
          this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
          $(tip).addClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we add extra
          // empty mouseover listeners to the body's immediate children;
          // only needed because of broken event delegation on iOS
          // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
  
          if ('ontouchstart' in document.documentElement) {
            $(document.body).children().on('mouseover', null, $.noop);
          }
  
          var complete = function complete() {
            if (_this.config.animation) {
              _this._fixTransition();
            }
  
            var prevHoverState = _this._hoverState;
            _this._hoverState = null;
            $(_this.element).trigger(_this.constructor.Event.SHOWN);
  
            if (prevHoverState === HOVER_STATE_OUT) {
              _this._leave(null, _this);
            }
          };
  
          if ($(this.tip).hasClass(CLASS_NAME_FADE$2)) {
            var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
            $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
          } else {
            complete();
          }
        }
      };
  
      _proto.hide = function hide(callback) {
        var _this2 = this;
  
        var tip = this.getTipElement();
        var hideEvent = $.Event(this.constructor.Event.HIDE);
  
        var complete = function complete() {
          if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
            tip.parentNode.removeChild(tip);
          }
  
          _this2._cleanTipClass();
  
          _this2.element.removeAttribute('aria-describedby');
  
          $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
  
          if (_this2._popper !== null) {
            _this2._popper.destroy();
          }
  
          if (callback) {
            callback();
          }
        };
  
        $(this.element).trigger(hideEvent);
  
        if (hideEvent.isDefaultPrevented()) {
          return;
        }
  
        $(tip).removeClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we remove the extra
        // empty mouseover listeners we added for iOS support
  
        if ('ontouchstart' in document.documentElement) {
          $(document.body).children().off('mouseover', null, $.noop);
        }
  
        this._activeTrigger[TRIGGER_CLICK] = false;
        this._activeTrigger[TRIGGER_FOCUS] = false;
        this._activeTrigger[TRIGGER_HOVER] = false;
  
        if ($(this.tip).hasClass(CLASS_NAME_FADE$2)) {
          var transitionDuration = Util.getTransitionDurationFromElement(tip);
          $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
        } else {
          complete();
        }
  
        this._hoverState = '';
      };
  
      _proto.update = function update() {
        if (this._popper !== null) {
          this._popper.scheduleUpdate();
        }
      } // Protected
      ;
  
      _proto.isWithContent = function isWithContent() {
        return Boolean(this.getTitle());
      };
  
      _proto.addAttachmentClass = function addAttachmentClass(attachment) {
        $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
      };
  
      _proto.getTipElement = function getTipElement() {
        this.tip = this.tip || $(this.config.template)[0];
        return this.tip;
      };
  
      _proto.setContent = function setContent() {
        var tip = this.getTipElement();
        this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
        $(tip).removeClass(CLASS_NAME_FADE$2 + " " + CLASS_NAME_SHOW$4);
      };
  
      _proto.setElementContent = function setElementContent($element, content) {
        if (typeof content === 'object' && (content.nodeType || content.jquery)) {
          // Content is a DOM node or a jQuery
          if (this.config.html) {
            if (!$(content).parent().is($element)) {
              $element.empty().append(content);
            }
          } else {
            $element.text($(content).text());
          }
  
          return;
        }
  
        if (this.config.html) {
          if (this.config.sanitize) {
            content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
          }
  
          $element.html(content);
        } else {
          $element.text(content);
        }
      };
  
      _proto.getTitle = function getTitle() {
        var title = this.element.getAttribute('data-original-title');
  
        if (!title) {
          title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
        }
  
        return title;
      } // Private
      ;
  
      _proto._getPopperConfig = function _getPopperConfig(attachment) {
        var _this3 = this;
  
        var defaultBsConfig = {
          placement: attachment,
          modifiers: {
            offset: this._getOffset(),
            flip: {
              behavior: this.config.fallbackPlacement
            },
            arrow: {
              element: SELECTOR_ARROW
            },
            preventOverflow: {
              boundariesElement: this.config.boundary
            }
          },
          onCreate: function onCreate(data) {
            if (data.originalPlacement !== data.placement) {
              _this3._handlePopperPlacementChange(data);
            }
          },
          onUpdate: function onUpdate(data) {
            return _this3._handlePopperPlacementChange(data);
          }
        };
        return _objectSpread2(_objectSpread2({}, defaultBsConfig), this.config.popperConfig);
      };
  
      _proto._getOffset = function _getOffset() {
        var _this4 = this;
  
        var offset = {};
  
        if (typeof this.config.offset === 'function') {
          offset.fn = function (data) {
            data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this4.config.offset(data.offsets, _this4.element) || {});
            return data;
          };
        } else {
          offset.offset = this.config.offset;
        }
  
        return offset;
      };
  
      _proto._getContainer = function _getContainer() {
        if (this.config.container === false) {
          return document.body;
        }
  
        if (Util.isElement(this.config.container)) {
          return $(this.config.container);
        }
  
        return $(document).find(this.config.container);
      };
  
      _proto._getAttachment = function _getAttachment(placement) {
        return AttachmentMap[placement.toUpperCase()];
      };
  
      _proto._setListeners = function _setListeners() {
        var _this5 = this;
  
        var triggers = this.config.trigger.split(' ');
        triggers.forEach(function (trigger) {
          if (trigger === 'click') {
            $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
              return _this5.toggle(event);
            });
          } else if (trigger !== TRIGGER_MANUAL) {
            var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
            var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
            $(_this5.element).on(eventIn, _this5.config.selector, function (event) {
              return _this5._enter(event);
            }).on(eventOut, _this5.config.selector, function (event) {
              return _this5._leave(event);
            });
          }
        });
  
        this._hideModalHandler = function () {
          if (_this5.element) {
            _this5.hide();
          }
        };
  
        $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
  
        if (this.config.selector) {
          this.config = _objectSpread2(_objectSpread2({}, this.config), {}, {
            trigger: 'manual',
            selector: ''
          });
        } else {
          this._fixTitle();
        }
      };
  
      _proto._fixTitle = function _fixTitle() {
        var titleType = typeof this.element.getAttribute('data-original-title');
  
        if (this.element.getAttribute('title') || titleType !== 'string') {
          this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
          this.element.setAttribute('title', '');
        }
      };
  
      _proto._enter = function _enter(event, context) {
        var dataKey = this.constructor.DATA_KEY;
        context = context || $(event.currentTarget).data(dataKey);
  
        if (!context) {
          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
          $(event.currentTarget).data(dataKey, context);
        }
  
        if (event) {
          context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
        }
  
        if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW$4) || context._hoverState === HOVER_STATE_SHOW) {
          context._hoverState = HOVER_STATE_SHOW;
          return;
        }
  
        clearTimeout(context._timeout);
        context._hoverState = HOVER_STATE_SHOW;
  
        if (!context.config.delay || !context.config.delay.show) {
          context.show();
          return;
        }
  
        context._timeout = setTimeout(function () {
          if (context._hoverState === HOVER_STATE_SHOW) {
            context.show();
          }
        }, context.config.delay.show);
      };
  
      _proto._leave = function _leave(event, context) {
        var dataKey = this.constructor.DATA_KEY;
        context = context || $(event.currentTarget).data(dataKey);
  
        if (!context) {
          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
          $(event.currentTarget).data(dataKey, context);
        }
  
        if (event) {
          context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
        }
  
        if (context._isWithActiveTrigger()) {
          return;
        }
  
        clearTimeout(context._timeout);
        context._hoverState = HOVER_STATE_OUT;
  
        if (!context.config.delay || !context.config.delay.hide) {
          context.hide();
          return;
        }
  
        context._timeout = setTimeout(function () {
          if (context._hoverState === HOVER_STATE_OUT) {
            context.hide();
          }
        }, context.config.delay.hide);
      };
  
      _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
        for (var trigger in this._activeTrigger) {
          if (this._activeTrigger[trigger]) {
            return true;
          }
        }
  
        return false;
      };
  
      _proto._getConfig = function _getConfig(config) {
        var dataAttributes = $(this.element).data();
        Object.keys(dataAttributes).forEach(function (dataAttr) {
          if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
            delete dataAttributes[dataAttr];
          }
        });
        config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), dataAttributes), typeof config === 'object' && config ? config : {});
  
        if (typeof config.delay === 'number') {
          config.delay = {
            show: config.delay,
            hide: config.delay
          };
        }
  
        if (typeof config.title === 'number') {
          config.title = config.title.toString();
        }
  
        if (typeof config.content === 'number') {
          config.content = config.content.toString();
        }
  
        Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);
  
        if (config.sanitize) {
          config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
        }
  
        return config;
      };
  
      _proto._getDelegateConfig = function _getDelegateConfig() {
        var config = {};
  
        if (this.config) {
          for (var key in this.config) {
            if (this.constructor.Default[key] !== this.config[key]) {
              config[key] = this.config[key];
            }
          }
        }
  
        return config;
      };
  
      _proto._cleanTipClass = function _cleanTipClass() {
        var $tip = $(this.getTipElement());
        var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
  
        if (tabClass !== null && tabClass.length) {
          $tip.removeClass(tabClass.join(''));
        }
      };
  
      _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
        this.tip = popperData.instance.popper;
  
        this._cleanTipClass();
  
        this.addAttachmentClass(this._getAttachment(popperData.placement));
      };
  
      _proto._fixTransition = function _fixTransition() {
        var tip = this.getTipElement();
        var initConfigAnimation = this.config.animation;
  
        if (tip.getAttribute('x-placement') !== null) {
          return;
        }
  
        $(tip).removeClass(CLASS_NAME_FADE$2);
        this.config.animation = false;
        this.hide();
        this.show();
        this.config.animation = initConfigAnimation;
      } // Static
      ;
  
      Tooltip._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$6);
  
          var _config = typeof config === 'object' && config;
  
          if (!data && /dispose|hide/.test(config)) {
            return;
          }
  
          if (!data) {
            data = new Tooltip(this, _config);
            $(this).data(DATA_KEY$6, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      _createClass(Tooltip, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$6;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$4;
        }
      }, {
        key: "NAME",
        get: function get() {
          return NAME$6;
        }
      }, {
        key: "DATA_KEY",
        get: function get() {
          return DATA_KEY$6;
        }
      }, {
        key: "Event",
        get: function get() {
          return Event;
        }
      }, {
        key: "EVENT_KEY",
        get: function get() {
          return EVENT_KEY$6;
        }
      }, {
        key: "DefaultType",
        get: function get() {
          return DefaultType$4;
        }
      }]);
  
      return Tooltip;
    }();
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
  
    $.fn[NAME$6] = Tooltip._jQueryInterface;
    $.fn[NAME$6].Constructor = Tooltip;
  
    $.fn[NAME$6].noConflict = function () {
      $.fn[NAME$6] = JQUERY_NO_CONFLICT$6;
      return Tooltip._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$7 = 'popover';
    var VERSION$7 = '4.5.0';
    var DATA_KEY$7 = 'bs.popover';
    var EVENT_KEY$7 = "." + DATA_KEY$7;
    var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
    var CLASS_PREFIX$1 = 'bs-popover';
    var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
  
    var Default$5 = _objectSpread2(_objectSpread2({}, Tooltip.Default), {}, {
      placement: 'right',
      trigger: 'click',
      content: '',
      template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
    });
  
    var DefaultType$5 = _objectSpread2(_objectSpread2({}, Tooltip.DefaultType), {}, {
      content: '(string|element|function)'
    });
  
    var CLASS_NAME_FADE$3 = 'fade';
    var CLASS_NAME_SHOW$5 = 'show';
    var SELECTOR_TITLE = '.popover-header';
    var SELECTOR_CONTENT = '.popover-body';
    var Event$1 = {
      HIDE: "hide" + EVENT_KEY$7,
      HIDDEN: "hidden" + EVENT_KEY$7,
      SHOW: "show" + EVENT_KEY$7,
      SHOWN: "shown" + EVENT_KEY$7,
      INSERTED: "inserted" + EVENT_KEY$7,
      CLICK: "click" + EVENT_KEY$7,
      FOCUSIN: "focusin" + EVENT_KEY$7,
      FOCUSOUT: "focusout" + EVENT_KEY$7,
      MOUSEENTER: "mouseenter" + EVENT_KEY$7,
      MOUSELEAVE: "mouseleave" + EVENT_KEY$7
    };
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Popover = /*#__PURE__*/function (_Tooltip) {
      _inheritsLoose(Popover, _Tooltip);
  
      function Popover() {
        return _Tooltip.apply(this, arguments) || this;
      }
  
      var _proto = Popover.prototype;
  
      // Overrides
      _proto.isWithContent = function isWithContent() {
        return this.getTitle() || this._getContent();
      };
  
      _proto.addAttachmentClass = function addAttachmentClass(attachment) {
        $(this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment);
      };
  
      _proto.getTipElement = function getTipElement() {
        this.tip = this.tip || $(this.config.template)[0];
        return this.tip;
      };
  
      _proto.setContent = function setContent() {
        var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events
  
        this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle());
  
        var content = this._getContent();
  
        if (typeof content === 'function') {
          content = content.call(this.element);
        }
  
        this.setElementContent($tip.find(SELECTOR_CONTENT), content);
        $tip.removeClass(CLASS_NAME_FADE$3 + " " + CLASS_NAME_SHOW$5);
      } // Private
      ;
  
      _proto._getContent = function _getContent() {
        return this.element.getAttribute('data-content') || this.config.content;
      };
  
      _proto._cleanTipClass = function _cleanTipClass() {
        var $tip = $(this.getTipElement());
        var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);
  
        if (tabClass !== null && tabClass.length > 0) {
          $tip.removeClass(tabClass.join(''));
        }
      } // Static
      ;
  
      Popover._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$7);
  
          var _config = typeof config === 'object' ? config : null;
  
          if (!data && /dispose|hide/.test(config)) {
            return;
          }
  
          if (!data) {
            data = new Popover(this, _config);
            $(this).data(DATA_KEY$7, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      _createClass(Popover, null, [{
        key: "VERSION",
        // Getters
        get: function get() {
          return VERSION$7;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$5;
        }
      }, {
        key: "NAME",
        get: function get() {
          return NAME$7;
        }
      }, {
        key: "DATA_KEY",
        get: function get() {
          return DATA_KEY$7;
        }
      }, {
        key: "Event",
        get: function get() {
          return Event$1;
        }
      }, {
        key: "EVENT_KEY",
        get: function get() {
          return EVENT_KEY$7;
        }
      }, {
        key: "DefaultType",
        get: function get() {
          return DefaultType$5;
        }
      }]);
  
      return Popover;
    }(Tooltip);
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
  
    $.fn[NAME$7] = Popover._jQueryInterface;
    $.fn[NAME$7].Constructor = Popover;
  
    $.fn[NAME$7].noConflict = function () {
      $.fn[NAME$7] = JQUERY_NO_CONFLICT$7;
      return Popover._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$8 = 'scrollspy';
    var VERSION$8 = '4.5.0';
    var DATA_KEY$8 = 'bs.scrollspy';
    var EVENT_KEY$8 = "." + DATA_KEY$8;
    var DATA_API_KEY$6 = '.data-api';
    var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8];
    var Default$6 = {
      offset: 10,
      method: 'auto',
      target: ''
    };
    var DefaultType$6 = {
      offset: 'number',
      method: 'string',
      target: '(string|element)'
    };
    var EVENT_ACTIVATE = "activate" + EVENT_KEY$8;
    var EVENT_SCROLL = "scroll" + EVENT_KEY$8;
    var EVENT_LOAD_DATA_API$2 = "load" + EVENT_KEY$8 + DATA_API_KEY$6;
    var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
    var CLASS_NAME_ACTIVE$2 = 'active';
    var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
    var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
    var SELECTOR_NAV_LINKS = '.nav-link';
    var SELECTOR_NAV_ITEMS = '.nav-item';
    var SELECTOR_LIST_ITEMS = '.list-group-item';
    var SELECTOR_DROPDOWN = '.dropdown';
    var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
    var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
    var METHOD_OFFSET = 'offset';
    var METHOD_POSITION = 'position';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var ScrollSpy = /*#__PURE__*/function () {
      function ScrollSpy(element, config) {
        var _this = this;
  
        this._element = element;
        this._scrollElement = element.tagName === 'BODY' ? window : element;
        this._config = this._getConfig(config);
        this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
        this._offsets = [];
        this._targets = [];
        this._activeTarget = null;
        this._scrollHeight = 0;
        $(this._scrollElement).on(EVENT_SCROLL, function (event) {
          return _this._process(event);
        });
        this.refresh();
  
        this._process();
      } // Getters
  
  
      var _proto = ScrollSpy.prototype;
  
      // Public
      _proto.refresh = function refresh() {
        var _this2 = this;
  
        var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
        var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
        var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
        this._offsets = [];
        this._targets = [];
        this._scrollHeight = this._getScrollHeight();
        var targets = [].slice.call(document.querySelectorAll(this._selector));
        targets.map(function (element) {
          var target;
          var targetSelector = Util.getSelectorFromElement(element);
  
          if (targetSelector) {
            target = document.querySelector(targetSelector);
          }
  
          if (target) {
            var targetBCR = target.getBoundingClientRect();
  
            if (targetBCR.width || targetBCR.height) {
              // TODO (fat): remove sketch reliance on jQuery position/offset
              return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
            }
          }
  
          return null;
        }).filter(function (item) {
          return item;
        }).sort(function (a, b) {
          return a[0] - b[0];
        }).forEach(function (item) {
          _this2._offsets.push(item[0]);
  
          _this2._targets.push(item[1]);
        });
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY$8);
        $(this._scrollElement).off(EVENT_KEY$8);
        this._element = null;
        this._scrollElement = null;
        this._config = null;
        this._selector = null;
        this._offsets = null;
        this._targets = null;
        this._activeTarget = null;
        this._scrollHeight = null;
      } // Private
      ;
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2({}, Default$6), typeof config === 'object' && config ? config : {});
  
        if (typeof config.target !== 'string' && Util.isElement(config.target)) {
          var id = $(config.target).attr('id');
  
          if (!id) {
            id = Util.getUID(NAME$8);
            $(config.target).attr('id', id);
          }
  
          config.target = "#" + id;
        }
  
        Util.typeCheckConfig(NAME$8, config, DefaultType$6);
        return config;
      };
  
      _proto._getScrollTop = function _getScrollTop() {
        return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
      };
  
      _proto._getScrollHeight = function _getScrollHeight() {
        return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
      };
  
      _proto._getOffsetHeight = function _getOffsetHeight() {
        return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
      };
  
      _proto._process = function _process() {
        var scrollTop = this._getScrollTop() + this._config.offset;
  
        var scrollHeight = this._getScrollHeight();
  
        var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
  
        if (this._scrollHeight !== scrollHeight) {
          this.refresh();
        }
  
        if (scrollTop >= maxScroll) {
          var target = this._targets[this._targets.length - 1];
  
          if (this._activeTarget !== target) {
            this._activate(target);
          }
  
          return;
        }
  
        if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
          this._activeTarget = null;
  
          this._clear();
  
          return;
        }
  
        for (var i = this._offsets.length; i--;) {
          var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
  
          if (isActiveTarget) {
            this._activate(this._targets[i]);
          }
        }
      };
  
      _proto._activate = function _activate(target) {
        this._activeTarget = target;
  
        this._clear();
  
        var queries = this._selector.split(',').map(function (selector) {
          return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
        });
  
        var $link = $([].slice.call(document.querySelectorAll(queries.join(','))));
  
        if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
          $link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE$2);
          $link.addClass(CLASS_NAME_ACTIVE$2);
        } else {
          // Set triggered link as active
          $link.addClass(CLASS_NAME_ACTIVE$2); // Set triggered links parents as active
          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
  
          $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_LINKS + ", " + SELECTOR_LIST_ITEMS).addClass(CLASS_NAME_ACTIVE$2); // Handle special case when .nav-link is inside .nav-item
  
          $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE$2);
        }
  
        $(this._scrollElement).trigger(EVENT_ACTIVATE, {
          relatedTarget: target
        });
      };
  
      _proto._clear = function _clear() {
        [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
          return node.classList.contains(CLASS_NAME_ACTIVE$2);
        }).forEach(function (node) {
          return node.classList.remove(CLASS_NAME_ACTIVE$2);
        });
      } // Static
      ;
  
      ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY$8);
  
          var _config = typeof config === 'object' && config;
  
          if (!data) {
            data = new ScrollSpy(this, _config);
            $(this).data(DATA_KEY$8, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      _createClass(ScrollSpy, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$8;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$6;
        }
      }]);
  
      return ScrollSpy;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(window).on(EVENT_LOAD_DATA_API$2, function () {
      var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
      var scrollSpysLength = scrollSpys.length;
  
      for (var i = scrollSpysLength; i--;) {
        var $spy = $(scrollSpys[i]);
  
        ScrollSpy._jQueryInterface.call($spy, $spy.data());
      }
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$8] = ScrollSpy._jQueryInterface;
    $.fn[NAME$8].Constructor = ScrollSpy;
  
    $.fn[NAME$8].noConflict = function () {
      $.fn[NAME$8] = JQUERY_NO_CONFLICT$8;
      return ScrollSpy._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$9 = 'tab';
    var VERSION$9 = '4.5.0';
    var DATA_KEY$9 = 'bs.tab';
    var EVENT_KEY$9 = "." + DATA_KEY$9;
    var DATA_API_KEY$7 = '.data-api';
    var JQUERY_NO_CONFLICT$9 = $.fn[NAME$9];
    var EVENT_HIDE$3 = "hide" + EVENT_KEY$9;
    var EVENT_HIDDEN$3 = "hidden" + EVENT_KEY$9;
    var EVENT_SHOW$3 = "show" + EVENT_KEY$9;
    var EVENT_SHOWN$3 = "shown" + EVENT_KEY$9;
    var EVENT_CLICK_DATA_API$6 = "click" + EVENT_KEY$9 + DATA_API_KEY$7;
    var CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
    var CLASS_NAME_ACTIVE$3 = 'active';
    var CLASS_NAME_DISABLED$1 = 'disabled';
    var CLASS_NAME_FADE$4 = 'fade';
    var CLASS_NAME_SHOW$6 = 'show';
    var SELECTOR_DROPDOWN$1 = '.dropdown';
    var SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';
    var SELECTOR_ACTIVE$2 = '.active';
    var SELECTOR_ACTIVE_UL = '> li > .active';
    var SELECTOR_DATA_TOGGLE$4 = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]';
    var SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
    var SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Tab = /*#__PURE__*/function () {
      function Tab(element) {
        this._element = element;
      } // Getters
  
  
      var _proto = Tab.prototype;
  
      // Public
      _proto.show = function show() {
        var _this = this;
  
        if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(CLASS_NAME_ACTIVE$3) || $(this._element).hasClass(CLASS_NAME_DISABLED$1)) {
          return;
        }
  
        var target;
        var previous;
        var listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP$1)[0];
        var selector = Util.getSelectorFromElement(this._element);
  
        if (listElement) {
          var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE$2;
          previous = $.makeArray($(listElement).find(itemSelector));
          previous = previous[previous.length - 1];
        }
  
        var hideEvent = $.Event(EVENT_HIDE$3, {
          relatedTarget: this._element
        });
        var showEvent = $.Event(EVENT_SHOW$3, {
          relatedTarget: previous
        });
  
        if (previous) {
          $(previous).trigger(hideEvent);
        }
  
        $(this._element).trigger(showEvent);
  
        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
          return;
        }
  
        if (selector) {
          target = document.querySelector(selector);
        }
  
        this._activate(this._element, listElement);
  
        var complete = function complete() {
          var hiddenEvent = $.Event(EVENT_HIDDEN$3, {
            relatedTarget: _this._element
          });
          var shownEvent = $.Event(EVENT_SHOWN$3, {
            relatedTarget: previous
          });
          $(previous).trigger(hiddenEvent);
          $(_this._element).trigger(shownEvent);
        };
  
        if (target) {
          this._activate(target, target.parentNode, complete);
        } else {
          complete();
        }
      };
  
      _proto.dispose = function dispose() {
        $.removeData(this._element, DATA_KEY$9);
        this._element = null;
      } // Private
      ;
  
      _proto._activate = function _activate(element, container, callback) {
        var _this2 = this;
  
        var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $(container).find(SELECTOR_ACTIVE_UL) : $(container).children(SELECTOR_ACTIVE$2);
        var active = activeElements[0];
        var isTransitioning = callback && active && $(active).hasClass(CLASS_NAME_FADE$4);
  
        var complete = function complete() {
          return _this2._transitionComplete(element, active, callback);
        };
  
        if (active && isTransitioning) {
          var transitionDuration = Util.getTransitionDurationFromElement(active);
          $(active).removeClass(CLASS_NAME_SHOW$6).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
        } else {
          complete();
        }
      };
  
      _proto._transitionComplete = function _transitionComplete(element, active, callback) {
        if (active) {
          $(active).removeClass(CLASS_NAME_ACTIVE$3);
          var dropdownChild = $(active.parentNode).find(SELECTOR_DROPDOWN_ACTIVE_CHILD)[0];
  
          if (dropdownChild) {
            $(dropdownChild).removeClass(CLASS_NAME_ACTIVE$3);
          }
  
          if (active.getAttribute('role') === 'tab') {
            active.setAttribute('aria-selected', false);
          }
        }
  
        $(element).addClass(CLASS_NAME_ACTIVE$3);
  
        if (element.getAttribute('role') === 'tab') {
          element.setAttribute('aria-selected', true);
        }
  
        Util.reflow(element);
  
        if (element.classList.contains(CLASS_NAME_FADE$4)) {
          element.classList.add(CLASS_NAME_SHOW$6);
        }
  
        if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {
          var dropdownElement = $(element).closest(SELECTOR_DROPDOWN$1)[0];
  
          if (dropdownElement) {
            var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE$1));
            $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE$3);
          }
  
          element.setAttribute('aria-expanded', true);
        }
  
        if (callback) {
          callback();
        }
      } // Static
      ;
  
      Tab._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var $this = $(this);
          var data = $this.data(DATA_KEY$9);
  
          if (!data) {
            data = new Tab(this);
            $this.data(DATA_KEY$9, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config]();
          }
        });
      };
  
      _createClass(Tab, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$9;
        }
      }]);
  
      return Tab;
    }();
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    $(document).on(EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$4, function (event) {
      event.preventDefault();
  
      Tab._jQueryInterface.call($(this), 'show');
    });
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    $.fn[NAME$9] = Tab._jQueryInterface;
    $.fn[NAME$9].Constructor = Tab;
  
    $.fn[NAME$9].noConflict = function () {
      $.fn[NAME$9] = JQUERY_NO_CONFLICT$9;
      return Tab._jQueryInterface;
    };
  
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    var NAME$a = 'toast';
    var VERSION$a = '4.5.0';
    var DATA_KEY$a = 'bs.toast';
    var EVENT_KEY$a = "." + DATA_KEY$a;
    var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
    var EVENT_CLICK_DISMISS$1 = "click.dismiss" + EVENT_KEY$a;
    var EVENT_HIDE$4 = "hide" + EVENT_KEY$a;
    var EVENT_HIDDEN$4 = "hidden" + EVENT_KEY$a;
    var EVENT_SHOW$4 = "show" + EVENT_KEY$a;
    var EVENT_SHOWN$4 = "shown" + EVENT_KEY$a;
    var CLASS_NAME_FADE$5 = 'fade';
    var CLASS_NAME_HIDE = 'hide';
    var CLASS_NAME_SHOW$7 = 'show';
    var CLASS_NAME_SHOWING = 'showing';
    var DefaultType$7 = {
      animation: 'boolean',
      autohide: 'boolean',
      delay: 'number'
    };
    var Default$7 = {
      animation: true,
      autohide: true,
      delay: 500
    };
    var SELECTOR_DATA_DISMISS$1 = '[data-dismiss="toast"]';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    var Toast = /*#__PURE__*/function () {
      function Toast(element, config) {
        this._element = element;
        this._config = this._getConfig(config);
        this._timeout = null;
  
        this._setListeners();
      } // Getters
  
  
      var _proto = Toast.prototype;
  
      // Public
      _proto.show = function show() {
        var _this = this;
  
        var showEvent = $.Event(EVENT_SHOW$4);
        $(this._element).trigger(showEvent);
  
        if (showEvent.isDefaultPrevented()) {
          return;
        }
  
        if (this._config.animation) {
          this._element.classList.add(CLASS_NAME_FADE$5);
        }
  
        var complete = function complete() {
          _this._element.classList.remove(CLASS_NAME_SHOWING);
  
          _this._element.classList.add(CLASS_NAME_SHOW$7);
  
          $(_this._element).trigger(EVENT_SHOWN$4);
  
          if (_this._config.autohide) {
            _this._timeout = setTimeout(function () {
              _this.hide();
            }, _this._config.delay);
          }
        };
  
        this._element.classList.remove(CLASS_NAME_HIDE);
  
        Util.reflow(this._element);
  
        this._element.classList.add(CLASS_NAME_SHOWING);
  
        if (this._config.animation) {
          var transitionDuration = Util.getTransitionDurationFromElement(this._element);
          $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
        } else {
          complete();
        }
      };
  
      _proto.hide = function hide() {
        if (!this._element.classList.contains(CLASS_NAME_SHOW$7)) {
          return;
        }
  
        var hideEvent = $.Event(EVENT_HIDE$4);
        $(this._element).trigger(hideEvent);
  
        if (hideEvent.isDefaultPrevented()) {
          return;
        }
  
        this._close();
      };
  
      _proto.dispose = function dispose() {
        clearTimeout(this._timeout);
        this._timeout = null;
  
        if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
          this._element.classList.remove(CLASS_NAME_SHOW$7);
        }
  
        $(this._element).off(EVENT_CLICK_DISMISS$1);
        $.removeData(this._element, DATA_KEY$a);
        this._element = null;
        this._config = null;
      } // Private
      ;
  
      _proto._getConfig = function _getConfig(config) {
        config = _objectSpread2(_objectSpread2(_objectSpread2({}, Default$7), $(this._element).data()), typeof config === 'object' && config ? config : {});
        Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
        return config;
      };
  
      _proto._setListeners = function _setListeners() {
        var _this2 = this;
  
        $(this._element).on(EVENT_CLICK_DISMISS$1, SELECTOR_DATA_DISMISS$1, function () {
          return _this2.hide();
        });
      };
  
      _proto._close = function _close() {
        var _this3 = this;
  
        var complete = function complete() {
          _this3._element.classList.add(CLASS_NAME_HIDE);
  
          $(_this3._element).trigger(EVENT_HIDDEN$4);
        };
  
        this._element.classList.remove(CLASS_NAME_SHOW$7);
  
        if (this._config.animation) {
          var transitionDuration = Util.getTransitionDurationFromElement(this._element);
          $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
        } else {
          complete();
        }
      } // Static
      ;
  
      Toast._jQueryInterface = function _jQueryInterface(config) {
        return this.each(function () {
          var $element = $(this);
          var data = $element.data(DATA_KEY$a);
  
          var _config = typeof config === 'object' && config;
  
          if (!data) {
            data = new Toast(this, _config);
            $element.data(DATA_KEY$a, data);
          }
  
          if (typeof config === 'string') {
            if (typeof data[config] === 'undefined') {
              throw new TypeError("No method named \"" + config + "\"");
            }
  
            data[config](this);
          }
        });
      };
  
      _createClass(Toast, null, [{
        key: "VERSION",
        get: function get() {
          return VERSION$a;
        }
      }, {
        key: "DefaultType",
        get: function get() {
          return DefaultType$7;
        }
      }, {
        key: "Default",
        get: function get() {
          return Default$7;
        }
      }]);
  
      return Toast;
    }();
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
  
    $.fn[NAME$a] = Toast._jQueryInterface;
    $.fn[NAME$a].Constructor = Toast;
  
    $.fn[NAME$a].noConflict = function () {
      $.fn[NAME$a] = JQUERY_NO_CONFLICT$a;
      return Toast._jQueryInterface;
    };
  
    exports.Alert = Alert;
    exports.Button = Button;
    exports.Carousel = Carousel;
    exports.Collapse = Collapse;
    exports.Dropdown = Dropdown;
    exports.Modal = Modal;
    exports.Popover = Popover;
    exports.Scrollspy = ScrollSpy;
    exports.Tab = Tab;
    exports.Toast = Toast;
    exports.Tooltip = Tooltip;
    exports.Util = Util;
  
    Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=bootstrap.js.map
  
  //! moment.js
  //! version : 2.27.0
  //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
  //! license : MIT
  //! momentjs.com
  
  ;(function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define(factory) :
      global.moment = factory()
  }(this, (function () { 'use strict';
  
      var hookCallback;
  
      function hooks() {
          return hookCallback.apply(null, arguments);
      }
  
      // This is done to register the method called with moment()
      // without creating circular dependencies.
      function setHookCallback(callback) {
          hookCallback = callback;
      }
  
      function isArray(input) {
          return (
              input instanceof Array ||
              Object.prototype.toString.call(input) === '[object Array]'
          );
      }
  
      function isObject(input) {
          // IE8 will treat undefined and null as object if it wasn't for
          // input != null
          return (
              input != null &&
              Object.prototype.toString.call(input) === '[object Object]'
          );
      }
  
      function hasOwnProp(a, b) {
          return Object.prototype.hasOwnProperty.call(a, b);
      }
  
      function isObjectEmpty(obj) {
          if (Object.getOwnPropertyNames) {
              return Object.getOwnPropertyNames(obj).length === 0;
          } else {
              var k;
              for (k in obj) {
                  if (hasOwnProp(obj, k)) {
                      return false;
                  }
              }
              return true;
          }
      }
  
      function isUndefined(input) {
          return input === void 0;
      }
  
      function isNumber(input) {
          return (
              typeof input === 'number' ||
              Object.prototype.toString.call(input) === '[object Number]'
          );
      }
  
      function isDate(input) {
          return (
              input instanceof Date ||
              Object.prototype.toString.call(input) === '[object Date]'
          );
      }
  
      function map(arr, fn) {
          var res = [],
              i;
          for (i = 0; i < arr.length; ++i) {
              res.push(fn(arr[i], i));
          }
          return res;
      }
  
      function extend(a, b) {
          for (var i in b) {
              if (hasOwnProp(b, i)) {
                  a[i] = b[i];
              }
          }
  
          if (hasOwnProp(b, 'toString')) {
              a.toString = b.toString;
          }
  
          if (hasOwnProp(b, 'valueOf')) {
              a.valueOf = b.valueOf;
          }
  
          return a;
      }
  
      function createUTC(input, format, locale, strict) {
          return createLocalOrUTC(input, format, locale, strict, true).utc();
      }
  
      function defaultParsingFlags() {
          // We need to deep clone this object.
          return {
              empty: false,
              unusedTokens: [],
              unusedInput: [],
              overflow: -2,
              charsLeftOver: 0,
              nullInput: false,
              invalidEra: null,
              invalidMonth: null,
              invalidFormat: false,
              userInvalidated: false,
              iso: false,
              parsedDateParts: [],
              era: null,
              meridiem: null,
              rfc2822: false,
              weekdayMismatch: false,
          };
      }
  
      function getParsingFlags(m) {
          if (m._pf == null) {
              m._pf = defaultParsingFlags();
          }
          return m._pf;
      }
  
      var some;
      if (Array.prototype.some) {
          some = Array.prototype.some;
      } else {
          some = function (fun) {
              var t = Object(this),
                  len = t.length >>> 0,
                  i;
  
              for (i = 0; i < len; i++) {
                  if (i in t && fun.call(this, t[i], i, t)) {
                      return true;
                  }
              }
  
              return false;
          };
      }
  
      function isValid(m) {
          if (m._isValid == null) {
              var flags = getParsingFlags(m),
                  parsedParts = some.call(flags.parsedDateParts, function (i) {
                      return i != null;
                  }),
                  isNowValid =
                      !isNaN(m._d.getTime()) &&
                      flags.overflow < 0 &&
                      !flags.empty &&
                      !flags.invalidEra &&
                      !flags.invalidMonth &&
                      !flags.invalidWeekday &&
                      !flags.weekdayMismatch &&
                      !flags.nullInput &&
                      !flags.invalidFormat &&
                      !flags.userInvalidated &&
                      (!flags.meridiem || (flags.meridiem && parsedParts));
  
              if (m._strict) {
                  isNowValid =
                      isNowValid &&
                      flags.charsLeftOver === 0 &&
                      flags.unusedTokens.length === 0 &&
                      flags.bigHour === undefined;
              }
  
              if (Object.isFrozen == null || !Object.isFrozen(m)) {
                  m._isValid = isNowValid;
              } else {
                  return isNowValid;
              }
          }
          return m._isValid;
      }
  
      function createInvalid(flags) {
          var m = createUTC(NaN);
          if (flags != null) {
              extend(getParsingFlags(m), flags);
          } else {
              getParsingFlags(m).userInvalidated = true;
          }
  
          return m;
      }
  
      // Plugins that add properties should also add the key here (null value),
      // so we can properly clone ourselves.
      var momentProperties = (hooks.momentProperties = []),
          updateInProgress = false;
  
      function copyConfig(to, from) {
          var i, prop, val;
  
          if (!isUndefined(from._isAMomentObject)) {
              to._isAMomentObject = from._isAMomentObject;
          }
          if (!isUndefined(from._i)) {
              to._i = from._i;
          }
          if (!isUndefined(from._f)) {
              to._f = from._f;
          }
          if (!isUndefined(from._l)) {
              to._l = from._l;
          }
          if (!isUndefined(from._strict)) {
              to._strict = from._strict;
          }
          if (!isUndefined(from._tzm)) {
              to._tzm = from._tzm;
          }
          if (!isUndefined(from._isUTC)) {
              to._isUTC = from._isUTC;
          }
          if (!isUndefined(from._offset)) {
              to._offset = from._offset;
          }
          if (!isUndefined(from._pf)) {
              to._pf = getParsingFlags(from);
          }
          if (!isUndefined(from._locale)) {
              to._locale = from._locale;
          }
  
          if (momentProperties.length > 0) {
              for (i = 0; i < momentProperties.length; i++) {
                  prop = momentProperties[i];
                  val = from[prop];
                  if (!isUndefined(val)) {
                      to[prop] = val;
                  }
              }
          }
  
          return to;
      }
  
      // Moment prototype object
      function Moment(config) {
          copyConfig(this, config);
          this._d = new Date(config._d != null ? config._d.getTime() : NaN);
          if (!this.isValid()) {
              this._d = new Date(NaN);
          }
          // Prevent infinite loop in case updateOffset creates new moment
          // objects.
          if (updateInProgress === false) {
              updateInProgress = true;
              hooks.updateOffset(this);
              updateInProgress = false;
          }
      }
  
      function isMoment(obj) {
          return (
              obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
          );
      }
  
      function warn(msg) {
          if (
              hooks.suppressDeprecationWarnings === false &&
              typeof console !== 'undefined' &&
              console.warn
          ) {
              console.warn('Deprecation warning: ' + msg);
          }
      }
  
      function deprecate(msg, fn) {
          var firstTime = true;
  
          return extend(function () {
              if (hooks.deprecationHandler != null) {
                  hooks.deprecationHandler(null, msg);
              }
              if (firstTime) {
                  var args = [],
                      arg,
                      i,
                      key;
                  for (i = 0; i < arguments.length; i++) {
                      arg = '';
                      if (typeof arguments[i] === 'object') {
                          arg += '\n[' + i + '] ';
                          for (key in arguments[0]) {
                              if (hasOwnProp(arguments[0], key)) {
                                  arg += key + ': ' + arguments[0][key] + ', ';
                              }
                          }
                          arg = arg.slice(0, -2); // Remove trailing comma and space
                      } else {
                          arg = arguments[i];
                      }
                      args.push(arg);
                  }
                  warn(
                      msg +
                          '\nArguments: ' +
                          Array.prototype.slice.call(args).join('') +
                          '\n' +
                          new Error().stack
                  );
                  firstTime = false;
              }
              return fn.apply(this, arguments);
          }, fn);
      }
  
      var deprecations = {};
  
      function deprecateSimple(name, msg) {
          if (hooks.deprecationHandler != null) {
              hooks.deprecationHandler(name, msg);
          }
          if (!deprecations[name]) {
              warn(msg);
              deprecations[name] = true;
          }
      }
  
      hooks.suppressDeprecationWarnings = false;
      hooks.deprecationHandler = null;
  
      function isFunction(input) {
          return (
              (typeof Function !== 'undefined' && input instanceof Function) ||
              Object.prototype.toString.call(input) === '[object Function]'
          );
      }
  
      function set(config) {
          var prop, i;
          for (i in config) {
              if (hasOwnProp(config, i)) {
                  prop = config[i];
                  if (isFunction(prop)) {
                      this[i] = prop;
                  } else {
                      this['_' + i] = prop;
                  }
              }
          }
          this._config = config;
          // Lenient ordinal parsing accepts just a number in addition to
          // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
          // TODO: Remove "ordinalParse" fallback in next major release.
          this._dayOfMonthOrdinalParseLenient = new RegExp(
              (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
                  '|' +
                  /\d{1,2}/.source
          );
      }
  
      function mergeConfigs(parentConfig, childConfig) {
          var res = extend({}, parentConfig),
              prop;
          for (prop in childConfig) {
              if (hasOwnProp(childConfig, prop)) {
                  if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                      res[prop] = {};
                      extend(res[prop], parentConfig[prop]);
                      extend(res[prop], childConfig[prop]);
                  } else if (childConfig[prop] != null) {
                      res[prop] = childConfig[prop];
                  } else {
                      delete res[prop];
                  }
              }
          }
          for (prop in parentConfig) {
              if (
                  hasOwnProp(parentConfig, prop) &&
                  !hasOwnProp(childConfig, prop) &&
                  isObject(parentConfig[prop])
              ) {
                  // make sure changes to properties don't modify parent config
                  res[prop] = extend({}, res[prop]);
              }
          }
          return res;
      }
  
      function Locale(config) {
          if (config != null) {
              this.set(config);
          }
      }
  
      var keys;
  
      if (Object.keys) {
          keys = Object.keys;
      } else {
          keys = function (obj) {
              var i,
                  res = [];
              for (i in obj) {
                  if (hasOwnProp(obj, i)) {
                      res.push(i);
                  }
              }
              return res;
          };
      }
  
      var defaultCalendar = {
          sameDay: '[Today at] LT',
          nextDay: '[Tomorrow at] LT',
          nextWeek: 'dddd [at] LT',
          lastDay: '[Yesterday at] LT',
          lastWeek: '[Last] dddd [at] LT',
          sameElse: 'L',
      };
  
      function calendar(key, mom, now) {
          var output = this._calendar[key] || this._calendar['sameElse'];
          return isFunction(output) ? output.call(mom, now) : output;
      }
  
      function zeroFill(number, targetLength, forceSign) {
          var absNumber = '' + Math.abs(number),
              zerosToFill = targetLength - absNumber.length,
              sign = number >= 0;
          return (
              (sign ? (forceSign ? '+' : '') : '-') +
              Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
              absNumber
          );
      }
  
      var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
          localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
          formatFunctions = {},
          formatTokenFunctions = {};
  
      // token:    'M'
      // padded:   ['MM', 2]
      // ordinal:  'Mo'
      // callback: function () { this.month() + 1 }
      function addFormatToken(token, padded, ordinal, callback) {
          var func = callback;
          if (typeof callback === 'string') {
              func = function () {
                  return this[callback]();
              };
          }
          if (token) {
              formatTokenFunctions[token] = func;
          }
          if (padded) {
              formatTokenFunctions[padded[0]] = function () {
                  return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
              };
          }
          if (ordinal) {
              formatTokenFunctions[ordinal] = function () {
                  return this.localeData().ordinal(
                      func.apply(this, arguments),
                      token
                  );
              };
          }
      }
  
      function removeFormattingTokens(input) {
          if (input.match(/\[[\s\S]/)) {
              return input.replace(/^\[|\]$/g, '');
          }
          return input.replace(/\\/g, '');
      }
  
      function makeFormatFunction(format) {
          var array = format.match(formattingTokens),
              i,
              length;
  
          for (i = 0, length = array.length; i < length; i++) {
              if (formatTokenFunctions[array[i]]) {
                  array[i] = formatTokenFunctions[array[i]];
              } else {
                  array[i] = removeFormattingTokens(array[i]);
              }
          }
  
          return function (mom) {
              var output = '',
                  i;
              for (i = 0; i < length; i++) {
                  output += isFunction(array[i])
                      ? array[i].call(mom, format)
                      : array[i];
              }
              return output;
          };
      }
  
      // format date using native date object
      function formatMoment(m, format) {
          if (!m.isValid()) {
              return m.localeData().invalidDate();
          }
  
          format = expandFormat(format, m.localeData());
          formatFunctions[format] =
              formatFunctions[format] || makeFormatFunction(format);
  
          return formatFunctions[format](m);
      }
  
      function expandFormat(format, locale) {
          var i = 5;
  
          function replaceLongDateFormatTokens(input) {
              return locale.longDateFormat(input) || input;
          }
  
          localFormattingTokens.lastIndex = 0;
          while (i >= 0 && localFormattingTokens.test(format)) {
              format = format.replace(
                  localFormattingTokens,
                  replaceLongDateFormatTokens
              );
              localFormattingTokens.lastIndex = 0;
              i -= 1;
          }
  
          return format;
      }
  
      var defaultLongDateFormat = {
          LTS: 'h:mm:ss A',
          LT: 'h:mm A',
          L: 'MM/DD/YYYY',
          LL: 'MMMM D, YYYY',
          LLL: 'MMMM D, YYYY h:mm A',
          LLLL: 'dddd, MMMM D, YYYY h:mm A',
      };
  
      function longDateFormat(key) {
          var format = this._longDateFormat[key],
              formatUpper = this._longDateFormat[key.toUpperCase()];
  
          if (format || !formatUpper) {
              return format;
          }
  
          this._longDateFormat[key] = formatUpper
              .match(formattingTokens)
              .map(function (tok) {
                  if (
                      tok === 'MMMM' ||
                      tok === 'MM' ||
                      tok === 'DD' ||
                      tok === 'dddd'
                  ) {
                      return tok.slice(1);
                  }
                  return tok;
              })
              .join('');
  
          return this._longDateFormat[key];
      }
  
      var defaultInvalidDate = 'Invalid date';
  
      function invalidDate() {
          return this._invalidDate;
      }
  
      var defaultOrdinal = '%d',
          defaultDayOfMonthOrdinalParse = /\d{1,2}/;
  
      function ordinal(number) {
          return this._ordinal.replace('%d', number);
      }
  
      var defaultRelativeTime = {
          future: 'in %s',
          past: '%s ago',
          s: 'a few seconds',
          ss: '%d seconds',
          m: 'a minute',
          mm: '%d minutes',
          h: 'an hour',
          hh: '%d hours',
          d: 'a day',
          dd: '%d days',
          w: 'a week',
          ww: '%d weeks',
          M: 'a month',
          MM: '%d months',
          y: 'a year',
          yy: '%d years',
      };
  
      function relativeTime(number, withoutSuffix, string, isFuture) {
          var output = this._relativeTime[string];
          return isFunction(output)
              ? output(number, withoutSuffix, string, isFuture)
              : output.replace(/%d/i, number);
      }
  
      function pastFuture(diff, output) {
          var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
          return isFunction(format) ? format(output) : format.replace(/%s/i, output);
      }
  
      var aliases = {};
  
      function addUnitAlias(unit, shorthand) {
          var lowerCase = unit.toLowerCase();
          aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
      }
  
      function normalizeUnits(units) {
          return typeof units === 'string'
              ? aliases[units] || aliases[units.toLowerCase()]
              : undefined;
      }
  
      function normalizeObjectUnits(inputObject) {
          var normalizedInput = {},
              normalizedProp,
              prop;
  
          for (prop in inputObject) {
              if (hasOwnProp(inputObject, prop)) {
                  normalizedProp = normalizeUnits(prop);
                  if (normalizedProp) {
                      normalizedInput[normalizedProp] = inputObject[prop];
                  }
              }
          }
  
          return normalizedInput;
      }
  
      var priorities = {};
  
      function addUnitPriority(unit, priority) {
          priorities[unit] = priority;
      }
  
      function getPrioritizedUnits(unitsObj) {
          var units = [],
              u;
          for (u in unitsObj) {
              if (hasOwnProp(unitsObj, u)) {
                  units.push({ unit: u, priority: priorities[u] });
              }
          }
          units.sort(function (a, b) {
              return a.priority - b.priority;
          });
          return units;
      }
  
      function isLeapYear(year) {
          return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
      }
  
      function absFloor(number) {
          if (number < 0) {
              // -0 -> 0
              return Math.ceil(number) || 0;
          } else {
              return Math.floor(number);
          }
      }
  
      function toInt(argumentForCoercion) {
          var coercedNumber = +argumentForCoercion,
              value = 0;
  
          if (coercedNumber !== 0 && isFinite(coercedNumber)) {
              value = absFloor(coercedNumber);
          }
  
          return value;
      }
  
      function makeGetSet(unit, keepTime) {
          return function (value) {
              if (value != null) {
                  set$1(this, unit, value);
                  hooks.updateOffset(this, keepTime);
                  return this;
              } else {
                  return get(this, unit);
              }
          };
      }
  
      function get(mom, unit) {
          return mom.isValid()
              ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
              : NaN;
      }
  
      function set$1(mom, unit, value) {
          if (mom.isValid() && !isNaN(value)) {
              if (
                  unit === 'FullYear' &&
                  isLeapYear(mom.year()) &&
                  mom.month() === 1 &&
                  mom.date() === 29
              ) {
                  value = toInt(value);
                  mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
                      value,
                      mom.month(),
                      daysInMonth(value, mom.month())
                  );
              } else {
                  mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
              }
          }
      }
  
      // MOMENTS
  
      function stringGet(units) {
          units = normalizeUnits(units);
          if (isFunction(this[units])) {
              return this[units]();
          }
          return this;
      }
  
      function stringSet(units, value) {
          if (typeof units === 'object') {
              units = normalizeObjectUnits(units);
              var prioritized = getPrioritizedUnits(units),
                  i;
              for (i = 0; i < prioritized.length; i++) {
                  this[prioritized[i].unit](units[prioritized[i].unit]);
              }
          } else {
              units = normalizeUnits(units);
              if (isFunction(this[units])) {
                  return this[units](value);
              }
          }
          return this;
      }
  
      var match1 = /\d/, //       0 - 9
          match2 = /\d\d/, //      00 - 99
          match3 = /\d{3}/, //     000 - 999
          match4 = /\d{4}/, //    0000 - 9999
          match6 = /[+-]?\d{6}/, // -999999 - 999999
          match1to2 = /\d\d?/, //       0 - 99
          match3to4 = /\d\d\d\d?/, //     999 - 9999
          match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
          match1to3 = /\d{1,3}/, //       0 - 999
          match1to4 = /\d{1,4}/, //       0 - 9999
          match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
          matchUnsigned = /\d+/, //       0 - inf
          matchSigned = /[+-]?\d+/, //    -inf - inf
          matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
          matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
          matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
          // any word (or two) characters or numbers including two/three word month in arabic.
          // includes scottish gaelic two word and hyphenated months
          matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
          regexes;
  
      regexes = {};
  
      function addRegexToken(token, regex, strictRegex) {
          regexes[token] = isFunction(regex)
              ? regex
              : function (isStrict, localeData) {
                    return isStrict && strictRegex ? strictRegex : regex;
                };
      }
  
      function getParseRegexForToken(token, config) {
          if (!hasOwnProp(regexes, token)) {
              return new RegExp(unescapeFormat(token));
          }
  
          return regexes[token](config._strict, config._locale);
      }
  
      // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
      function unescapeFormat(s) {
          return regexEscape(
              s
                  .replace('\\', '')
                  .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (
                      matched,
                      p1,
                      p2,
                      p3,
                      p4
                  ) {
                      return p1 || p2 || p3 || p4;
                  })
          );
      }
  
      function regexEscape(s) {
          return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
      }
  
      var tokens = {};
  
      function addParseToken(token, callback) {
          var i,
              func = callback;
          if (typeof token === 'string') {
              token = [token];
          }
          if (isNumber(callback)) {
              func = function (input, array) {
                  array[callback] = toInt(input);
              };
          }
          for (i = 0; i < token.length; i++) {
              tokens[token[i]] = func;
          }
      }
  
      function addWeekParseToken(token, callback) {
          addParseToken(token, function (input, array, config, token) {
              config._w = config._w || {};
              callback(input, config._w, config, token);
          });
      }
  
      function addTimeToArrayFromToken(token, input, config) {
          if (input != null && hasOwnProp(tokens, token)) {
              tokens[token](input, config._a, config, token);
          }
      }
  
      var YEAR = 0,
          MONTH = 1,
          DATE = 2,
          HOUR = 3,
          MINUTE = 4,
          SECOND = 5,
          MILLISECOND = 6,
          WEEK = 7,
          WEEKDAY = 8;
  
      function mod(n, x) {
          return ((n % x) + x) % x;
      }
  
      var indexOf;
  
      if (Array.prototype.indexOf) {
          indexOf = Array.prototype.indexOf;
      } else {
          indexOf = function (o) {
              // I know
              var i;
              for (i = 0; i < this.length; ++i) {
                  if (this[i] === o) {
                      return i;
                  }
              }
              return -1;
          };
      }
  
      function daysInMonth(year, month) {
          if (isNaN(year) || isNaN(month)) {
              return NaN;
          }
          var modMonth = mod(month, 12);
          year += (month - modMonth) / 12;
          return modMonth === 1
              ? isLeapYear(year)
                  ? 29
                  : 28
              : 31 - ((modMonth % 7) % 2);
      }
  
      // FORMATTING
  
      addFormatToken('M', ['MM', 2], 'Mo', function () {
          return this.month() + 1;
      });
  
      addFormatToken('MMM', 0, 0, function (format) {
          return this.localeData().monthsShort(this, format);
      });
  
      addFormatToken('MMMM', 0, 0, function (format) {
          return this.localeData().months(this, format);
      });
  
      // ALIASES
  
      addUnitAlias('month', 'M');
  
      // PRIORITY
  
      addUnitPriority('month', 8);
  
      // PARSING
  
      addRegexToken('M', match1to2);
      addRegexToken('MM', match1to2, match2);
      addRegexToken('MMM', function (isStrict, locale) {
          return locale.monthsShortRegex(isStrict);
      });
      addRegexToken('MMMM', function (isStrict, locale) {
          return locale.monthsRegex(isStrict);
      });
  
      addParseToken(['M', 'MM'], function (input, array) {
          array[MONTH] = toInt(input) - 1;
      });
  
      addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
          var month = config._locale.monthsParse(input, token, config._strict);
          // if we didn't find a month name, mark the date as invalid.
          if (month != null) {
              array[MONTH] = month;
          } else {
              getParsingFlags(config).invalidMonth = input;
          }
      });
  
      // LOCALES
  
      var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
              '_'
          ),
          defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split(
              '_'
          ),
          MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
          defaultMonthsShortRegex = matchWord,
          defaultMonthsRegex = matchWord;
  
      function localeMonths(m, format) {
          if (!m) {
              return isArray(this._months)
                  ? this._months
                  : this._months['standalone'];
          }
          return isArray(this._months)
              ? this._months[m.month()]
              : this._months[
                    (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
                        ? 'format'
                        : 'standalone'
                ][m.month()];
      }
  
      function localeMonthsShort(m, format) {
          if (!m) {
              return isArray(this._monthsShort)
                  ? this._monthsShort
                  : this._monthsShort['standalone'];
          }
          return isArray(this._monthsShort)
              ? this._monthsShort[m.month()]
              : this._monthsShort[
                    MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
                ][m.month()];
      }
  
      function handleStrictParse(monthName, format, strict) {
          var i,
              ii,
              mom,
              llc = monthName.toLocaleLowerCase();
          if (!this._monthsParse) {
              // this is not used
              this._monthsParse = [];
              this._longMonthsParse = [];
              this._shortMonthsParse = [];
              for (i = 0; i < 12; ++i) {
                  mom = createUTC([2000, i]);
                  this._shortMonthsParse[i] = this.monthsShort(
                      mom,
                      ''
                  ).toLocaleLowerCase();
                  this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
              }
          }
  
          if (strict) {
              if (format === 'MMM') {
                  ii = indexOf.call(this._shortMonthsParse, llc);
                  return ii !== -1 ? ii : null;
              } else {
                  ii = indexOf.call(this._longMonthsParse, llc);
                  return ii !== -1 ? ii : null;
              }
          } else {
              if (format === 'MMM') {
                  ii = indexOf.call(this._shortMonthsParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._longMonthsParse, llc);
                  return ii !== -1 ? ii : null;
              } else {
                  ii = indexOf.call(this._longMonthsParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._shortMonthsParse, llc);
                  return ii !== -1 ? ii : null;
              }
          }
      }
  
      function localeMonthsParse(monthName, format, strict) {
          var i, mom, regex;
  
          if (this._monthsParseExact) {
              return handleStrictParse.call(this, monthName, format, strict);
          }
  
          if (!this._monthsParse) {
              this._monthsParse = [];
              this._longMonthsParse = [];
              this._shortMonthsParse = [];
          }
  
          // TODO: add sorting
          // Sorting makes sure if one month (or abbr) is a prefix of another
          // see sorting in computeMonthsParse
          for (i = 0; i < 12; i++) {
              // make the regex if we don't have it already
              mom = createUTC([2000, i]);
              if (strict && !this._longMonthsParse[i]) {
                  this._longMonthsParse[i] = new RegExp(
                      '^' + this.months(mom, '').replace('.', '') + '$',
                      'i'
                  );
                  this._shortMonthsParse[i] = new RegExp(
                      '^' + this.monthsShort(mom, '').replace('.', '') + '$',
                      'i'
                  );
              }
              if (!strict && !this._monthsParse[i]) {
                  regex =
                      '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                  this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
              }
              // test the regex
              if (
                  strict &&
                  format === 'MMMM' &&
                  this._longMonthsParse[i].test(monthName)
              ) {
                  return i;
              } else if (
                  strict &&
                  format === 'MMM' &&
                  this._shortMonthsParse[i].test(monthName)
              ) {
                  return i;
              } else if (!strict && this._monthsParse[i].test(monthName)) {
                  return i;
              }
          }
      }
  
      // MOMENTS
  
      function setMonth(mom, value) {
          var dayOfMonth;
  
          if (!mom.isValid()) {
              // No op
              return mom;
          }
  
          if (typeof value === 'string') {
              if (/^\d+$/.test(value)) {
                  value = toInt(value);
              } else {
                  value = mom.localeData().monthsParse(value);
                  // TODO: Another silent failure?
                  if (!isNumber(value)) {
                      return mom;
                  }
              }
          }
  
          dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
          mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
          return mom;
      }
  
      function getSetMonth(value) {
          if (value != null) {
              setMonth(this, value);
              hooks.updateOffset(this, true);
              return this;
          } else {
              return get(this, 'Month');
          }
      }
  
      function getDaysInMonth() {
          return daysInMonth(this.year(), this.month());
      }
  
      function monthsShortRegex(isStrict) {
          if (this._monthsParseExact) {
              if (!hasOwnProp(this, '_monthsRegex')) {
                  computeMonthsParse.call(this);
              }
              if (isStrict) {
                  return this._monthsShortStrictRegex;
              } else {
                  return this._monthsShortRegex;
              }
          } else {
              if (!hasOwnProp(this, '_monthsShortRegex')) {
                  this._monthsShortRegex = defaultMonthsShortRegex;
              }
              return this._monthsShortStrictRegex && isStrict
                  ? this._monthsShortStrictRegex
                  : this._monthsShortRegex;
          }
      }
  
      function monthsRegex(isStrict) {
          if (this._monthsParseExact) {
              if (!hasOwnProp(this, '_monthsRegex')) {
                  computeMonthsParse.call(this);
              }
              if (isStrict) {
                  return this._monthsStrictRegex;
              } else {
                  return this._monthsRegex;
              }
          } else {
              if (!hasOwnProp(this, '_monthsRegex')) {
                  this._monthsRegex = defaultMonthsRegex;
              }
              return this._monthsStrictRegex && isStrict
                  ? this._monthsStrictRegex
                  : this._monthsRegex;
          }
      }
  
      function computeMonthsParse() {
          function cmpLenRev(a, b) {
              return b.length - a.length;
          }
  
          var shortPieces = [],
              longPieces = [],
              mixedPieces = [],
              i,
              mom;
          for (i = 0; i < 12; i++) {
              // make the regex if we don't have it already
              mom = createUTC([2000, i]);
              shortPieces.push(this.monthsShort(mom, ''));
              longPieces.push(this.months(mom, ''));
              mixedPieces.push(this.months(mom, ''));
              mixedPieces.push(this.monthsShort(mom, ''));
          }
          // Sorting makes sure if one month (or abbr) is a prefix of another it
          // will match the longer piece.
          shortPieces.sort(cmpLenRev);
          longPieces.sort(cmpLenRev);
          mixedPieces.sort(cmpLenRev);
          for (i = 0; i < 12; i++) {
              shortPieces[i] = regexEscape(shortPieces[i]);
              longPieces[i] = regexEscape(longPieces[i]);
          }
          for (i = 0; i < 24; i++) {
              mixedPieces[i] = regexEscape(mixedPieces[i]);
          }
  
          this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
          this._monthsShortRegex = this._monthsRegex;
          this._monthsStrictRegex = new RegExp(
              '^(' + longPieces.join('|') + ')',
              'i'
          );
          this._monthsShortStrictRegex = new RegExp(
              '^(' + shortPieces.join('|') + ')',
              'i'
          );
      }
  
      // FORMATTING
  
      addFormatToken('Y', 0, 0, function () {
          var y = this.year();
          return y <= 9999 ? zeroFill(y, 4) : '+' + y;
      });
  
      addFormatToken(0, ['YY', 2], 0, function () {
          return this.year() % 100;
      });
  
      addFormatToken(0, ['YYYY', 4], 0, 'year');
      addFormatToken(0, ['YYYYY', 5], 0, 'year');
      addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
  
      // ALIASES
  
      addUnitAlias('year', 'y');
  
      // PRIORITIES
  
      addUnitPriority('year', 1);
  
      // PARSING
  
      addRegexToken('Y', matchSigned);
      addRegexToken('YY', match1to2, match2);
      addRegexToken('YYYY', match1to4, match4);
      addRegexToken('YYYYY', match1to6, match6);
      addRegexToken('YYYYYY', match1to6, match6);
  
      addParseToken(['YYYYY', 'YYYYYY'], YEAR);
      addParseToken('YYYY', function (input, array) {
          array[YEAR] =
              input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
      });
      addParseToken('YY', function (input, array) {
          array[YEAR] = hooks.parseTwoDigitYear(input);
      });
      addParseToken('Y', function (input, array) {
          array[YEAR] = parseInt(input, 10);
      });
  
      // HELPERS
  
      function daysInYear(year) {
          return isLeapYear(year) ? 366 : 365;
      }
  
      // HOOKS
  
      hooks.parseTwoDigitYear = function (input) {
          return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
      };
  
      // MOMENTS
  
      var getSetYear = makeGetSet('FullYear', true);
  
      function getIsLeapYear() {
          return isLeapYear(this.year());
      }
  
      function createDate(y, m, d, h, M, s, ms) {
          // can't just apply() to create a date:
          // https://stackoverflow.com/q/181348
          var date;
          // the date constructor remaps years 0-99 to 1900-1999
          if (y < 100 && y >= 0) {
              // preserve leap years using a full 400 year cycle, then reset
              date = new Date(y + 400, m, d, h, M, s, ms);
              if (isFinite(date.getFullYear())) {
                  date.setFullYear(y);
              }
          } else {
              date = new Date(y, m, d, h, M, s, ms);
          }
  
          return date;
      }
  
      function createUTCDate(y) {
          var date, args;
          // the Date.UTC function remaps years 0-99 to 1900-1999
          if (y < 100 && y >= 0) {
              args = Array.prototype.slice.call(arguments);
              // preserve leap years using a full 400 year cycle, then reset
              args[0] = y + 400;
              date = new Date(Date.UTC.apply(null, args));
              if (isFinite(date.getUTCFullYear())) {
                  date.setUTCFullYear(y);
              }
          } else {
              date = new Date(Date.UTC.apply(null, arguments));
          }
  
          return date;
      }
  
      // start-of-first-week - start-of-year
      function firstWeekOffset(year, dow, doy) {
          var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
              fwd = 7 + dow - doy,
              // first-week day local weekday -- which local weekday is fwd
              fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
  
          return -fwdlw + fwd - 1;
      }
  
      // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
      function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
          var localWeekday = (7 + weekday - dow) % 7,
              weekOffset = firstWeekOffset(year, dow, doy),
              dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
              resYear,
              resDayOfYear;
  
          if (dayOfYear <= 0) {
              resYear = year - 1;
              resDayOfYear = daysInYear(resYear) + dayOfYear;
          } else if (dayOfYear > daysInYear(year)) {
              resYear = year + 1;
              resDayOfYear = dayOfYear - daysInYear(year);
          } else {
              resYear = year;
              resDayOfYear = dayOfYear;
          }
  
          return {
              year: resYear,
              dayOfYear: resDayOfYear,
          };
      }
  
      function weekOfYear(mom, dow, doy) {
          var weekOffset = firstWeekOffset(mom.year(), dow, doy),
              week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
              resWeek,
              resYear;
  
          if (week < 1) {
              resYear = mom.year() - 1;
              resWeek = week + weeksInYear(resYear, dow, doy);
          } else if (week > weeksInYear(mom.year(), dow, doy)) {
              resWeek = week - weeksInYear(mom.year(), dow, doy);
              resYear = mom.year() + 1;
          } else {
              resYear = mom.year();
              resWeek = week;
          }
  
          return {
              week: resWeek,
              year: resYear,
          };
      }
  
      function weeksInYear(year, dow, doy) {
          var weekOffset = firstWeekOffset(year, dow, doy),
              weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
          return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
      }
  
      // FORMATTING
  
      addFormatToken('w', ['ww', 2], 'wo', 'week');
      addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
  
      // ALIASES
  
      addUnitAlias('week', 'w');
      addUnitAlias('isoWeek', 'W');
  
      // PRIORITIES
  
      addUnitPriority('week', 5);
      addUnitPriority('isoWeek', 5);
  
      // PARSING
  
      addRegexToken('w', match1to2);
      addRegexToken('ww', match1to2, match2);
      addRegexToken('W', match1to2);
      addRegexToken('WW', match1to2, match2);
  
      addWeekParseToken(['w', 'ww', 'W', 'WW'], function (
          input,
          week,
          config,
          token
      ) {
          week[token.substr(0, 1)] = toInt(input);
      });
  
      // HELPERS
  
      // LOCALES
  
      function localeWeek(mom) {
          return weekOfYear(mom, this._week.dow, this._week.doy).week;
      }
  
      var defaultLocaleWeek = {
          dow: 0, // Sunday is the first day of the week.
          doy: 6, // The week that contains Jan 6th is the first week of the year.
      };
  
      function localeFirstDayOfWeek() {
          return this._week.dow;
      }
  
      function localeFirstDayOfYear() {
          return this._week.doy;
      }
  
      // MOMENTS
  
      function getSetWeek(input) {
          var week = this.localeData().week(this);
          return input == null ? week : this.add((input - week) * 7, 'd');
      }
  
      function getSetISOWeek(input) {
          var week = weekOfYear(this, 1, 4).week;
          return input == null ? week : this.add((input - week) * 7, 'd');
      }
  
      // FORMATTING
  
      addFormatToken('d', 0, 'do', 'day');
  
      addFormatToken('dd', 0, 0, function (format) {
          return this.localeData().weekdaysMin(this, format);
      });
  
      addFormatToken('ddd', 0, 0, function (format) {
          return this.localeData().weekdaysShort(this, format);
      });
  
      addFormatToken('dddd', 0, 0, function (format) {
          return this.localeData().weekdays(this, format);
      });
  
      addFormatToken('e', 0, 0, 'weekday');
      addFormatToken('E', 0, 0, 'isoWeekday');
  
      // ALIASES
  
      addUnitAlias('day', 'd');
      addUnitAlias('weekday', 'e');
      addUnitAlias('isoWeekday', 'E');
  
      // PRIORITY
      addUnitPriority('day', 11);
      addUnitPriority('weekday', 11);
      addUnitPriority('isoWeekday', 11);
  
      // PARSING
  
      addRegexToken('d', match1to2);
      addRegexToken('e', match1to2);
      addRegexToken('E', match1to2);
      addRegexToken('dd', function (isStrict, locale) {
          return locale.weekdaysMinRegex(isStrict);
      });
      addRegexToken('ddd', function (isStrict, locale) {
          return locale.weekdaysShortRegex(isStrict);
      });
      addRegexToken('dddd', function (isStrict, locale) {
          return locale.weekdaysRegex(isStrict);
      });
  
      addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
          var weekday = config._locale.weekdaysParse(input, token, config._strict);
          // if we didn't get a weekday name, mark the date as invalid
          if (weekday != null) {
              week.d = weekday;
          } else {
              getParsingFlags(config).invalidWeekday = input;
          }
      });
  
      addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
          week[token] = toInt(input);
      });
  
      // HELPERS
  
      function parseWeekday(input, locale) {
          if (typeof input !== 'string') {
              return input;
          }
  
          if (!isNaN(input)) {
              return parseInt(input, 10);
          }
  
          input = locale.weekdaysParse(input);
          if (typeof input === 'number') {
              return input;
          }
  
          return null;
      }
  
      function parseIsoWeekday(input, locale) {
          if (typeof input === 'string') {
              return locale.weekdaysParse(input) % 7 || 7;
          }
          return isNaN(input) ? null : input;
      }
  
      // LOCALES
      function shiftWeekdays(ws, n) {
          return ws.slice(n, 7).concat(ws.slice(0, n));
      }
  
      var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
              '_'
          ),
          defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
          defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
          defaultWeekdaysRegex = matchWord,
          defaultWeekdaysShortRegex = matchWord,
          defaultWeekdaysMinRegex = matchWord;
  
      function localeWeekdays(m, format) {
          var weekdays = isArray(this._weekdays)
              ? this._weekdays
              : this._weekdays[
                    m && m !== true && this._weekdays.isFormat.test(format)
                        ? 'format'
                        : 'standalone'
                ];
          return m === true
              ? shiftWeekdays(weekdays, this._week.dow)
              : m
              ? weekdays[m.day()]
              : weekdays;
      }
  
      function localeWeekdaysShort(m) {
          return m === true
              ? shiftWeekdays(this._weekdaysShort, this._week.dow)
              : m
              ? this._weekdaysShort[m.day()]
              : this._weekdaysShort;
      }
  
      function localeWeekdaysMin(m) {
          return m === true
              ? shiftWeekdays(this._weekdaysMin, this._week.dow)
              : m
              ? this._weekdaysMin[m.day()]
              : this._weekdaysMin;
      }
  
      function handleStrictParse$1(weekdayName, format, strict) {
          var i,
              ii,
              mom,
              llc = weekdayName.toLocaleLowerCase();
          if (!this._weekdaysParse) {
              this._weekdaysParse = [];
              this._shortWeekdaysParse = [];
              this._minWeekdaysParse = [];
  
              for (i = 0; i < 7; ++i) {
                  mom = createUTC([2000, 1]).day(i);
                  this._minWeekdaysParse[i] = this.weekdaysMin(
                      mom,
                      ''
                  ).toLocaleLowerCase();
                  this._shortWeekdaysParse[i] = this.weekdaysShort(
                      mom,
                      ''
                  ).toLocaleLowerCase();
                  this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
              }
          }
  
          if (strict) {
              if (format === 'dddd') {
                  ii = indexOf.call(this._weekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              } else if (format === 'ddd') {
                  ii = indexOf.call(this._shortWeekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              } else {
                  ii = indexOf.call(this._minWeekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              }
          } else {
              if (format === 'dddd') {
                  ii = indexOf.call(this._weekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._shortWeekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._minWeekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              } else if (format === 'ddd') {
                  ii = indexOf.call(this._shortWeekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._weekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._minWeekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              } else {
                  ii = indexOf.call(this._minWeekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._weekdaysParse, llc);
                  if (ii !== -1) {
                      return ii;
                  }
                  ii = indexOf.call(this._shortWeekdaysParse, llc);
                  return ii !== -1 ? ii : null;
              }
          }
      }
  
      function localeWeekdaysParse(weekdayName, format, strict) {
          var i, mom, regex;
  
          if (this._weekdaysParseExact) {
              return handleStrictParse$1.call(this, weekdayName, format, strict);
          }
  
          if (!this._weekdaysParse) {
              this._weekdaysParse = [];
              this._minWeekdaysParse = [];
              this._shortWeekdaysParse = [];
              this._fullWeekdaysParse = [];
          }
  
          for (i = 0; i < 7; i++) {
              // make the regex if we don't have it already
  
              mom = createUTC([2000, 1]).day(i);
              if (strict && !this._fullWeekdaysParse[i]) {
                  this._fullWeekdaysParse[i] = new RegExp(
                      '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
                      'i'
                  );
                  this._shortWeekdaysParse[i] = new RegExp(
                      '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
                      'i'
                  );
                  this._minWeekdaysParse[i] = new RegExp(
                      '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
                      'i'
                  );
              }
              if (!this._weekdaysParse[i]) {
                  regex =
                      '^' +
                      this.weekdays(mom, '') +
                      '|^' +
                      this.weekdaysShort(mom, '') +
                      '|^' +
                      this.weekdaysMin(mom, '');
                  this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
              }
              // test the regex
              if (
                  strict &&
                  format === 'dddd' &&
                  this._fullWeekdaysParse[i].test(weekdayName)
              ) {
                  return i;
              } else if (
                  strict &&
                  format === 'ddd' &&
                  this._shortWeekdaysParse[i].test(weekdayName)
              ) {
                  return i;
              } else if (
                  strict &&
                  format === 'dd' &&
                  this._minWeekdaysParse[i].test(weekdayName)
              ) {
                  return i;
              } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                  return i;
              }
          }
      }
  
      // MOMENTS
  
      function getSetDayOfWeek(input) {
          if (!this.isValid()) {
              return input != null ? this : NaN;
          }
          var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
          if (input != null) {
              input = parseWeekday(input, this.localeData());
              return this.add(input - day, 'd');
          } else {
              return day;
          }
      }
  
      function getSetLocaleDayOfWeek(input) {
          if (!this.isValid()) {
              return input != null ? this : NaN;
          }
          var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
          return input == null ? weekday : this.add(input - weekday, 'd');
      }
  
      function getSetISODayOfWeek(input) {
          if (!this.isValid()) {
              return input != null ? this : NaN;
          }
  
          // behaves the same as moment#day except
          // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
          // as a setter, sunday should belong to the previous week.
  
          if (input != null) {
              var weekday = parseIsoWeekday(input, this.localeData());
              return this.day(this.day() % 7 ? weekday : weekday - 7);
          } else {
              return this.day() || 7;
          }
      }
  
      function weekdaysRegex(isStrict) {
          if (this._weekdaysParseExact) {
              if (!hasOwnProp(this, '_weekdaysRegex')) {
                  computeWeekdaysParse.call(this);
              }
              if (isStrict) {
                  return this._weekdaysStrictRegex;
              } else {
                  return this._weekdaysRegex;
              }
          } else {
              if (!hasOwnProp(this, '_weekdaysRegex')) {
                  this._weekdaysRegex = defaultWeekdaysRegex;
              }
              return this._weekdaysStrictRegex && isStrict
                  ? this._weekdaysStrictRegex
                  : this._weekdaysRegex;
          }
      }
  
      function weekdaysShortRegex(isStrict) {
          if (this._weekdaysParseExact) {
              if (!hasOwnProp(this, '_weekdaysRegex')) {
                  computeWeekdaysParse.call(this);
              }
              if (isStrict) {
                  return this._weekdaysShortStrictRegex;
              } else {
                  return this._weekdaysShortRegex;
              }
          } else {
              if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                  this._weekdaysShortRegex = defaultWeekdaysShortRegex;
              }
              return this._weekdaysShortStrictRegex && isStrict
                  ? this._weekdaysShortStrictRegex
                  : this._weekdaysShortRegex;
          }
      }
  
      function weekdaysMinRegex(isStrict) {
          if (this._weekdaysParseExact) {
              if (!hasOwnProp(this, '_weekdaysRegex')) {
                  computeWeekdaysParse.call(this);
              }
              if (isStrict) {
                  return this._weekdaysMinStrictRegex;
              } else {
                  return this._weekdaysMinRegex;
              }
          } else {
              if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                  this._weekdaysMinRegex = defaultWeekdaysMinRegex;
              }
              return this._weekdaysMinStrictRegex && isStrict
                  ? this._weekdaysMinStrictRegex
                  : this._weekdaysMinRegex;
          }
      }
  
      function computeWeekdaysParse() {
          function cmpLenRev(a, b) {
              return b.length - a.length;
          }
  
          var minPieces = [],
              shortPieces = [],
              longPieces = [],
              mixedPieces = [],
              i,
              mom,
              minp,
              shortp,
              longp;
          for (i = 0; i < 7; i++) {
              // make the regex if we don't have it already
              mom = createUTC([2000, 1]).day(i);
              minp = regexEscape(this.weekdaysMin(mom, ''));
              shortp = regexEscape(this.weekdaysShort(mom, ''));
              longp = regexEscape(this.weekdays(mom, ''));
              minPieces.push(minp);
              shortPieces.push(shortp);
              longPieces.push(longp);
              mixedPieces.push(minp);
              mixedPieces.push(shortp);
              mixedPieces.push(longp);
          }
          // Sorting makes sure if one weekday (or abbr) is a prefix of another it
          // will match the longer piece.
          minPieces.sort(cmpLenRev);
          shortPieces.sort(cmpLenRev);
          longPieces.sort(cmpLenRev);
          mixedPieces.sort(cmpLenRev);
  
          this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
          this._weekdaysShortRegex = this._weekdaysRegex;
          this._weekdaysMinRegex = this._weekdaysRegex;
  
          this._weekdaysStrictRegex = new RegExp(
              '^(' + longPieces.join('|') + ')',
              'i'
          );
          this._weekdaysShortStrictRegex = new RegExp(
              '^(' + shortPieces.join('|') + ')',
              'i'
          );
          this._weekdaysMinStrictRegex = new RegExp(
              '^(' + minPieces.join('|') + ')',
              'i'
          );
      }
  
      // FORMATTING
  
      function hFormat() {
          return this.hours() % 12 || 12;
      }
  
      function kFormat() {
          return this.hours() || 24;
      }
  
      addFormatToken('H', ['HH', 2], 0, 'hour');
      addFormatToken('h', ['hh', 2], 0, hFormat);
      addFormatToken('k', ['kk', 2], 0, kFormat);
  
      addFormatToken('hmm', 0, 0, function () {
          return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
      });
  
      addFormatToken('hmmss', 0, 0, function () {
          return (
              '' +
              hFormat.apply(this) +
              zeroFill(this.minutes(), 2) +
              zeroFill(this.seconds(), 2)
          );
      });
  
      addFormatToken('Hmm', 0, 0, function () {
          return '' + this.hours() + zeroFill(this.minutes(), 2);
      });
  
      addFormatToken('Hmmss', 0, 0, function () {
          return (
              '' +
              this.hours() +
              zeroFill(this.minutes(), 2) +
              zeroFill(this.seconds(), 2)
          );
      });
  
      function meridiem(token, lowercase) {
          addFormatToken(token, 0, 0, function () {
              return this.localeData().meridiem(
                  this.hours(),
                  this.minutes(),
                  lowercase
              );
          });
      }
  
      meridiem('a', true);
      meridiem('A', false);
  
      // ALIASES
  
      addUnitAlias('hour', 'h');
  
      // PRIORITY
      addUnitPriority('hour', 13);
  
      // PARSING
  
      function matchMeridiem(isStrict, locale) {
          return locale._meridiemParse;
      }
  
      addRegexToken('a', matchMeridiem);
      addRegexToken('A', matchMeridiem);
      addRegexToken('H', match1to2);
      addRegexToken('h', match1to2);
      addRegexToken('k', match1to2);
      addRegexToken('HH', match1to2, match2);
      addRegexToken('hh', match1to2, match2);
      addRegexToken('kk', match1to2, match2);
  
      addRegexToken('hmm', match3to4);
      addRegexToken('hmmss', match5to6);
      addRegexToken('Hmm', match3to4);
      addRegexToken('Hmmss', match5to6);
  
      addParseToken(['H', 'HH'], HOUR);
      addParseToken(['k', 'kk'], function (input, array, config) {
          var kInput = toInt(input);
          array[HOUR] = kInput === 24 ? 0 : kInput;
      });
      addParseToken(['a', 'A'], function (input, array, config) {
          config._isPm = config._locale.isPM(input);
          config._meridiem = input;
      });
      addParseToken(['h', 'hh'], function (input, array, config) {
          array[HOUR] = toInt(input);
          getParsingFlags(config).bigHour = true;
      });
      addParseToken('hmm', function (input, array, config) {
          var pos = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos));
          array[MINUTE] = toInt(input.substr(pos));
          getParsingFlags(config).bigHour = true;
      });
      addParseToken('hmmss', function (input, array, config) {
          var pos1 = input.length - 4,
              pos2 = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos1));
          array[MINUTE] = toInt(input.substr(pos1, 2));
          array[SECOND] = toInt(input.substr(pos2));
          getParsingFlags(config).bigHour = true;
      });
      addParseToken('Hmm', function (input, array, config) {
          var pos = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos));
          array[MINUTE] = toInt(input.substr(pos));
      });
      addParseToken('Hmmss', function (input, array, config) {
          var pos1 = input.length - 4,
              pos2 = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos1));
          array[MINUTE] = toInt(input.substr(pos1, 2));
          array[SECOND] = toInt(input.substr(pos2));
      });
  
      // LOCALES
  
      function localeIsPM(input) {
          // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
          // Using charAt should be more compatible.
          return (input + '').toLowerCase().charAt(0) === 'p';
      }
  
      var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
          // Setting the hour should keep the time, because the user explicitly
          // specified which hour they want. So trying to maintain the same hour (in
          // a new timezone) makes sense. Adding/subtracting hours does not follow
          // this rule.
          getSetHour = makeGetSet('Hours', true);
  
      function localeMeridiem(hours, minutes, isLower) {
          if (hours > 11) {
              return isLower ? 'pm' : 'PM';
          } else {
              return isLower ? 'am' : 'AM';
          }
      }
  
      var baseConfig = {
          calendar: defaultCalendar,
          longDateFormat: defaultLongDateFormat,
          invalidDate: defaultInvalidDate,
          ordinal: defaultOrdinal,
          dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
          relativeTime: defaultRelativeTime,
  
          months: defaultLocaleMonths,
          monthsShort: defaultLocaleMonthsShort,
  
          week: defaultLocaleWeek,
  
          weekdays: defaultLocaleWeekdays,
          weekdaysMin: defaultLocaleWeekdaysMin,
          weekdaysShort: defaultLocaleWeekdaysShort,
  
          meridiemParse: defaultLocaleMeridiemParse,
      };
  
      // internal storage for locale config files
      var locales = {},
          localeFamilies = {},
          globalLocale;
  
      function commonPrefix(arr1, arr2) {
          var i,
              minl = Math.min(arr1.length, arr2.length);
          for (i = 0; i < minl; i += 1) {
              if (arr1[i] !== arr2[i]) {
                  return i;
              }
          }
          return minl;
      }
  
      function normalizeLocale(key) {
          return key ? key.toLowerCase().replace('_', '-') : key;
      }
  
      // pick the locale from the array
      // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
      // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
      function chooseLocale(names) {
          var i = 0,
              j,
              next,
              locale,
              split;
  
          while (i < names.length) {
              split = normalizeLocale(names[i]).split('-');
              j = split.length;
              next = normalizeLocale(names[i + 1]);
              next = next ? next.split('-') : null;
              while (j > 0) {
                  locale = loadLocale(split.slice(0, j).join('-'));
                  if (locale) {
                      return locale;
                  }
                  if (
                      next &&
                      next.length >= j &&
                      commonPrefix(split, next) >= j - 1
                  ) {
                      //the next array item is better than a shallower substring of this one
                      break;
                  }
                  j--;
              }
              i++;
          }
          return globalLocale;
      }
  
      function loadLocale(name) {
          var oldLocale = null,
              aliasedRequire;
          // TODO: Find a better way to register and load all the locales in Node
          if (
              locales[name] === undefined &&
              typeof module !== 'undefined' &&
              module &&
              module.exports
          ) {
              try {
                  oldLocale = globalLocale._abbr;
                  aliasedRequire = require;
                  aliasedRequire('./locale/' + name);
                  getSetGlobalLocale(oldLocale);
              } catch (e) {
                  // mark as not found to avoid repeating expensive file require call causing high CPU
                  // when trying to find en-US, en_US, en-us for every format call
                  locales[name] = null; // null means not found
              }
          }
          return locales[name];
      }
  
      // This function will load locale and then set the global locale.  If
      // no arguments are passed in, it will simply return the current global
      // locale key.
      function getSetGlobalLocale(key, values) {
          var data;
          if (key) {
              if (isUndefined(values)) {
                  data = getLocale(key);
              } else {
                  data = defineLocale(key, values);
              }
  
              if (data) {
                  // moment.duration._locale = moment._locale = data;
                  globalLocale = data;
              } else {
                  if (typeof console !== 'undefined' && console.warn) {
                      //warn user if arguments are passed but the locale could not be set
                      console.warn(
                          'Locale ' + key + ' not found. Did you forget to load it?'
                      );
                  }
              }
          }
  
          return globalLocale._abbr;
      }
  
      function defineLocale(name, config) {
          if (config !== null) {
              var locale,
                  parentConfig = baseConfig;
              config.abbr = name;
              if (locales[name] != null) {
                  deprecateSimple(
                      'defineLocaleOverride',
                      'use moment.updateLocale(localeName, config) to change ' +
                          'an existing locale. moment.defineLocale(localeName, ' +
                          'config) should only be used for creating a new locale ' +
                          'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
                  );
                  parentConfig = locales[name]._config;
              } else if (config.parentLocale != null) {
                  if (locales[config.parentLocale] != null) {
                      parentConfig = locales[config.parentLocale]._config;
                  } else {
                      locale = loadLocale(config.parentLocale);
                      if (locale != null) {
                          parentConfig = locale._config;
                      } else {
                          if (!localeFamilies[config.parentLocale]) {
                              localeFamilies[config.parentLocale] = [];
                          }
                          localeFamilies[config.parentLocale].push({
                              name: name,
                              config: config,
                          });
                          return null;
                      }
                  }
              }
              locales[name] = new Locale(mergeConfigs(parentConfig, config));
  
              if (localeFamilies[name]) {
                  localeFamilies[name].forEach(function (x) {
                      defineLocale(x.name, x.config);
                  });
              }
  
              // backwards compat for now: also set the locale
              // make sure we set the locale AFTER all child locales have been
              // created, so we won't end up with the child locale set.
              getSetGlobalLocale(name);
  
              return locales[name];
          } else {
              // useful for testing
              delete locales[name];
              return null;
          }
      }
  
      function updateLocale(name, config) {
          if (config != null) {
              var locale,
                  tmpLocale,
                  parentConfig = baseConfig;
  
              if (locales[name] != null && locales[name].parentLocale != null) {
                  // Update existing child locale in-place to avoid memory-leaks
                  locales[name].set(mergeConfigs(locales[name]._config, config));
              } else {
                  // MERGE
                  tmpLocale = loadLocale(name);
                  if (tmpLocale != null) {
                      parentConfig = tmpLocale._config;
                  }
                  config = mergeConfigs(parentConfig, config);
                  if (tmpLocale == null) {
                      // updateLocale is called for creating a new locale
                      // Set abbr so it will have a name (getters return
                      // undefined otherwise).
                      config.abbr = name;
                  }
                  locale = new Locale(config);
                  locale.parentLocale = locales[name];
                  locales[name] = locale;
              }
  
              // backwards compat for now: also set the locale
              getSetGlobalLocale(name);
          } else {
              // pass null for config to unupdate, useful for tests
              if (locales[name] != null) {
                  if (locales[name].parentLocale != null) {
                      locales[name] = locales[name].parentLocale;
                      if (name === getSetGlobalLocale()) {
                          getSetGlobalLocale(name);
                      }
                  } else if (locales[name] != null) {
                      delete locales[name];
                  }
              }
          }
          return locales[name];
      }
  
      // returns locale data
      function getLocale(key) {
          var locale;
  
          if (key && key._locale && key._locale._abbr) {
              key = key._locale._abbr;
          }
  
          if (!key) {
              return globalLocale;
          }
  
          if (!isArray(key)) {
              //short-circuit everything else
              locale = loadLocale(key);
              if (locale) {
                  return locale;
              }
              key = [key];
          }
  
          return chooseLocale(key);
      }
  
      function listLocales() {
          return keys(locales);
      }
  
      function checkOverflow(m) {
          var overflow,
              a = m._a;
  
          if (a && getParsingFlags(m).overflow === -2) {
              overflow =
                  a[MONTH] < 0 || a[MONTH] > 11
                      ? MONTH
                      : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
                      ? DATE
                      : a[HOUR] < 0 ||
                        a[HOUR] > 24 ||
                        (a[HOUR] === 24 &&
                            (a[MINUTE] !== 0 ||
                                a[SECOND] !== 0 ||
                                a[MILLISECOND] !== 0))
                      ? HOUR
                      : a[MINUTE] < 0 || a[MINUTE] > 59
                      ? MINUTE
                      : a[SECOND] < 0 || a[SECOND] > 59
                      ? SECOND
                      : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
                      ? MILLISECOND
                      : -1;
  
              if (
                  getParsingFlags(m)._overflowDayOfYear &&
                  (overflow < YEAR || overflow > DATE)
              ) {
                  overflow = DATE;
              }
              if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                  overflow = WEEK;
              }
              if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                  overflow = WEEKDAY;
              }
  
              getParsingFlags(m).overflow = overflow;
          }
  
          return m;
      }
  
      // iso 8601 regex
      // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
      var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
          basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
          tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
          isoDates = [
              ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
              ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
              ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
              ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
              ['YYYY-DDD', /\d{4}-\d{3}/],
              ['YYYY-MM', /\d{4}-\d\d/, false],
              ['YYYYYYMMDD', /[+-]\d{10}/],
              ['YYYYMMDD', /\d{8}/],
              ['GGGG[W]WWE', /\d{4}W\d{3}/],
              ['GGGG[W]WW', /\d{4}W\d{2}/, false],
              ['YYYYDDD', /\d{7}/],
              ['YYYYMM', /\d{6}/, false],
              ['YYYY', /\d{4}/, false],
          ],
          // iso time formats and regexes
          isoTimes = [
              ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
              ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
              ['HH:mm:ss', /\d\d:\d\d:\d\d/],
              ['HH:mm', /\d\d:\d\d/],
              ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
              ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
              ['HHmmss', /\d\d\d\d\d\d/],
              ['HHmm', /\d\d\d\d/],
              ['HH', /\d\d/],
          ],
          aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
          // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
          rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
          obsOffsets = {
              UT: 0,
              GMT: 0,
              EDT: -4 * 60,
              EST: -5 * 60,
              CDT: -5 * 60,
              CST: -6 * 60,
              MDT: -6 * 60,
              MST: -7 * 60,
              PDT: -7 * 60,
              PST: -8 * 60,
          };
  
      // date from iso format
      function configFromISO(config) {
          var i,
              l,
              string = config._i,
              match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
              allowTime,
              dateFormat,
              timeFormat,
              tzFormat;
  
          if (match) {
              getParsingFlags(config).iso = true;
  
              for (i = 0, l = isoDates.length; i < l; i++) {
                  if (isoDates[i][1].exec(match[1])) {
                      dateFormat = isoDates[i][0];
                      allowTime = isoDates[i][2] !== false;
                      break;
                  }
              }
              if (dateFormat == null) {
                  config._isValid = false;
                  return;
              }
              if (match[3]) {
                  for (i = 0, l = isoTimes.length; i < l; i++) {
                      if (isoTimes[i][1].exec(match[3])) {
                          // match[2] should be 'T' or space
                          timeFormat = (match[2] || ' ') + isoTimes[i][0];
                          break;
                      }
                  }
                  if (timeFormat == null) {
                      config._isValid = false;
                      return;
                  }
              }
              if (!allowTime && timeFormat != null) {
                  config._isValid = false;
                  return;
              }
              if (match[4]) {
                  if (tzRegex.exec(match[4])) {
                      tzFormat = 'Z';
                  } else {
                      config._isValid = false;
                      return;
                  }
              }
              config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
              configFromStringAndFormat(config);
          } else {
              config._isValid = false;
          }
      }
  
      function extractFromRFC2822Strings(
          yearStr,
          monthStr,
          dayStr,
          hourStr,
          minuteStr,
          secondStr
      ) {
          var result = [
              untruncateYear(yearStr),
              defaultLocaleMonthsShort.indexOf(monthStr),
              parseInt(dayStr, 10),
              parseInt(hourStr, 10),
              parseInt(minuteStr, 10),
          ];
  
          if (secondStr) {
              result.push(parseInt(secondStr, 10));
          }
  
          return result;
      }
  
      function untruncateYear(yearStr) {
          var year = parseInt(yearStr, 10);
          if (year <= 49) {
              return 2000 + year;
          } else if (year <= 999) {
              return 1900 + year;
          }
          return year;
      }
  
      function preprocessRFC2822(s) {
          // Remove comments and folding whitespace and replace multiple-spaces with a single space
          return s
              .replace(/\([^)]*\)|[\n\t]/g, ' ')
              .replace(/(\s\s+)/g, ' ')
              .replace(/^\s\s*/, '')
              .replace(/\s\s*$/, '');
      }
  
      function checkWeekday(weekdayStr, parsedInput, config) {
          if (weekdayStr) {
              // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
              var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
                  weekdayActual = new Date(
                      parsedInput[0],
                      parsedInput[1],
                      parsedInput[2]
                  ).getDay();
              if (weekdayProvided !== weekdayActual) {
                  getParsingFlags(config).weekdayMismatch = true;
                  config._isValid = false;
                  return false;
              }
          }
          return true;
      }
  
      function calculateOffset(obsOffset, militaryOffset, numOffset) {
          if (obsOffset) {
              return obsOffsets[obsOffset];
          } else if (militaryOffset) {
              // the only allowed military tz is Z
              return 0;
          } else {
              var hm = parseInt(numOffset, 10),
                  m = hm % 100,
                  h = (hm - m) / 100;
              return h * 60 + m;
          }
      }
  
      // date and time from ref 2822 format
      function configFromRFC2822(config) {
          var match = rfc2822.exec(preprocessRFC2822(config._i)),
              parsedArray;
          if (match) {
              parsedArray = extractFromRFC2822Strings(
                  match[4],
                  match[3],
                  match[2],
                  match[5],
                  match[6],
                  match[7]
              );
              if (!checkWeekday(match[1], parsedArray, config)) {
                  return;
              }
  
              config._a = parsedArray;
              config._tzm = calculateOffset(match[8], match[9], match[10]);
  
              config._d = createUTCDate.apply(null, config._a);
              config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
  
              getParsingFlags(config).rfc2822 = true;
          } else {
              config._isValid = false;
          }
      }
  
      // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
      function configFromString(config) {
          var matched = aspNetJsonRegex.exec(config._i);
          if (matched !== null) {
              config._d = new Date(+matched[1]);
              return;
          }
  
          configFromISO(config);
          if (config._isValid === false) {
              delete config._isValid;
          } else {
              return;
          }
  
          configFromRFC2822(config);
          if (config._isValid === false) {
              delete config._isValid;
          } else {
              return;
          }
  
          if (config._strict) {
              config._isValid = false;
          } else {
              // Final attempt, use Input Fallback
              hooks.createFromInputFallback(config);
          }
      }
  
      hooks.createFromInputFallback = deprecate(
          'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
              'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
              'discouraged and will be removed in an upcoming major release. Please refer to ' +
              'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
          function (config) {
              config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
          }
      );
  
      // Pick the first defined of two or three arguments.
      function defaults(a, b, c) {
          if (a != null) {
              return a;
          }
          if (b != null) {
              return b;
          }
          return c;
      }
  
      function currentDateArray(config) {
          // hooks is actually the exported moment object
          var nowValue = new Date(hooks.now());
          if (config._useUTC) {
              return [
                  nowValue.getUTCFullYear(),
                  nowValue.getUTCMonth(),
                  nowValue.getUTCDate(),
              ];
          }
          return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
      }
  
      // convert an array to a date.
      // the array should mirror the parameters below
      // note: all values past the year are optional and will default to the lowest possible value.
      // [year, month, day , hour, minute, second, millisecond]
      function configFromArray(config) {
          var i,
              date,
              input = [],
              currentDate,
              expectedWeekday,
              yearToUse;
  
          if (config._d) {
              return;
          }
  
          currentDate = currentDateArray(config);
  
          //compute day of the year from weeks and weekdays
          if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
              dayOfYearFromWeekInfo(config);
          }
  
          //if the day of the year is set, figure out what it is
          if (config._dayOfYear != null) {
              yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
  
              if (
                  config._dayOfYear > daysInYear(yearToUse) ||
                  config._dayOfYear === 0
              ) {
                  getParsingFlags(config)._overflowDayOfYear = true;
              }
  
              date = createUTCDate(yearToUse, 0, config._dayOfYear);
              config._a[MONTH] = date.getUTCMonth();
              config._a[DATE] = date.getUTCDate();
          }
  
          // Default to current date.
          // * if no year, month, day of month are given, default to today
          // * if day of month is given, default month and year
          // * if month is given, default only year
          // * if year is given, don't default anything
          for (i = 0; i < 3 && config._a[i] == null; ++i) {
              config._a[i] = input[i] = currentDate[i];
          }
  
          // Zero out whatever was not defaulted, including time
          for (; i < 7; i++) {
              config._a[i] = input[i] =
                  config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
          }
  
          // Check for 24:00:00.000
          if (
              config._a[HOUR] === 24 &&
              config._a[MINUTE] === 0 &&
              config._a[SECOND] === 0 &&
              config._a[MILLISECOND] === 0
          ) {
              config._nextDay = true;
              config._a[HOUR] = 0;
          }
  
          config._d = (config._useUTC ? createUTCDate : createDate).apply(
              null,
              input
          );
          expectedWeekday = config._useUTC
              ? config._d.getUTCDay()
              : config._d.getDay();
  
          // Apply timezone offset from input. The actual utcOffset can be changed
          // with parseZone.
          if (config._tzm != null) {
              config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
          }
  
          if (config._nextDay) {
              config._a[HOUR] = 24;
          }
  
          // check for mismatching day of week
          if (
              config._w &&
              typeof config._w.d !== 'undefined' &&
              config._w.d !== expectedWeekday
          ) {
              getParsingFlags(config).weekdayMismatch = true;
          }
      }
  
      function dayOfYearFromWeekInfo(config) {
          var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
  
          w = config._w;
          if (w.GG != null || w.W != null || w.E != null) {
              dow = 1;
              doy = 4;
  
              // TODO: We need to take the current isoWeekYear, but that depends on
              // how we interpret now (local, utc, fixed offset). So create
              // a now version of current config (take local/utc/offset flags, and
              // create now).
              weekYear = defaults(
                  w.GG,
                  config._a[YEAR],
                  weekOfYear(createLocal(), 1, 4).year
              );
              week = defaults(w.W, 1);
              weekday = defaults(w.E, 1);
              if (weekday < 1 || weekday > 7) {
                  weekdayOverflow = true;
              }
          } else {
              dow = config._locale._week.dow;
              doy = config._locale._week.doy;
  
              curWeek = weekOfYear(createLocal(), dow, doy);
  
              weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
  
              // Default to current week.
              week = defaults(w.w, curWeek.week);
  
              if (w.d != null) {
                  // weekday -- low day numbers are considered next week
                  weekday = w.d;
                  if (weekday < 0 || weekday > 6) {
                      weekdayOverflow = true;
                  }
              } else if (w.e != null) {
                  // local weekday -- counting starts from beginning of week
                  weekday = w.e + dow;
                  if (w.e < 0 || w.e > 6) {
                      weekdayOverflow = true;
                  }
              } else {
                  // default to beginning of week
                  weekday = dow;
              }
          }
          if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
              getParsingFlags(config)._overflowWeeks = true;
          } else if (weekdayOverflow != null) {
              getParsingFlags(config)._overflowWeekday = true;
          } else {
              temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
              config._a[YEAR] = temp.year;
              config._dayOfYear = temp.dayOfYear;
          }
      }
  
      // constant that refers to the ISO standard
      hooks.ISO_8601 = function () {};
  
      // constant that refers to the RFC 2822 form
      hooks.RFC_2822 = function () {};
  
      // date from string and format string
      function configFromStringAndFormat(config) {
          // TODO: Move this to another part of the creation flow to prevent circular deps
          if (config._f === hooks.ISO_8601) {
              configFromISO(config);
              return;
          }
          if (config._f === hooks.RFC_2822) {
              configFromRFC2822(config);
              return;
          }
          config._a = [];
          getParsingFlags(config).empty = true;
  
          // This array is used to make a Date, either with `new Date` or `Date.UTC`
          var string = '' + config._i,
              i,
              parsedInput,
              tokens,
              token,
              skipped,
              stringLength = string.length,
              totalParsedInputLength = 0,
              era;
  
          tokens =
              expandFormat(config._f, config._locale).match(formattingTokens) || [];
  
          for (i = 0; i < tokens.length; i++) {
              token = tokens[i];
              parsedInput = (string.match(getParseRegexForToken(token, config)) ||
                  [])[0];
              if (parsedInput) {
                  skipped = string.substr(0, string.indexOf(parsedInput));
                  if (skipped.length > 0) {
                      getParsingFlags(config).unusedInput.push(skipped);
                  }
                  string = string.slice(
                      string.indexOf(parsedInput) + parsedInput.length
                  );
                  totalParsedInputLength += parsedInput.length;
              }
              // don't parse if it's not a known token
              if (formatTokenFunctions[token]) {
                  if (parsedInput) {
                      getParsingFlags(config).empty = false;
                  } else {
                      getParsingFlags(config).unusedTokens.push(token);
                  }
                  addTimeToArrayFromToken(token, parsedInput, config);
              } else if (config._strict && !parsedInput) {
                  getParsingFlags(config).unusedTokens.push(token);
              }
          }
  
          // add remaining unparsed input length to the string
          getParsingFlags(config).charsLeftOver =
              stringLength - totalParsedInputLength;
          if (string.length > 0) {
              getParsingFlags(config).unusedInput.push(string);
          }
  
          // clear _12h flag if hour is <= 12
          if (
              config._a[HOUR] <= 12 &&
              getParsingFlags(config).bigHour === true &&
              config._a[HOUR] > 0
          ) {
              getParsingFlags(config).bigHour = undefined;
          }
  
          getParsingFlags(config).parsedDateParts = config._a.slice(0);
          getParsingFlags(config).meridiem = config._meridiem;
          // handle meridiem
          config._a[HOUR] = meridiemFixWrap(
              config._locale,
              config._a[HOUR],
              config._meridiem
          );
  
          // handle era
          era = getParsingFlags(config).era;
          if (era !== null) {
              config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
          }
  
          configFromArray(config);
          checkOverflow(config);
      }
  
      function meridiemFixWrap(locale, hour, meridiem) {
          var isPm;
  
          if (meridiem == null) {
              // nothing to do
              return hour;
          }
          if (locale.meridiemHour != null) {
              return locale.meridiemHour(hour, meridiem);
          } else if (locale.isPM != null) {
              // Fallback
              isPm = locale.isPM(meridiem);
              if (isPm && hour < 12) {
                  hour += 12;
              }
              if (!isPm && hour === 12) {
                  hour = 0;
              }
              return hour;
          } else {
              // this is not supposed to happen
              return hour;
          }
      }
  
      // date from string and array of format strings
      function configFromStringAndArray(config) {
          var tempConfig,
              bestMoment,
              scoreToBeat,
              i,
              currentScore,
              validFormatFound,
              bestFormatIsValid = false;
  
          if (config._f.length === 0) {
              getParsingFlags(config).invalidFormat = true;
              config._d = new Date(NaN);
              return;
          }
  
          for (i = 0; i < config._f.length; i++) {
              currentScore = 0;
              validFormatFound = false;
              tempConfig = copyConfig({}, config);
              if (config._useUTC != null) {
                  tempConfig._useUTC = config._useUTC;
              }
              tempConfig._f = config._f[i];
              configFromStringAndFormat(tempConfig);
  
              if (isValid(tempConfig)) {
                  validFormatFound = true;
              }
  
              // if there is any input that was not parsed add a penalty for that format
              currentScore += getParsingFlags(tempConfig).charsLeftOver;
  
              //or tokens
              currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
  
              getParsingFlags(tempConfig).score = currentScore;
  
              if (!bestFormatIsValid) {
                  if (
                      scoreToBeat == null ||
                      currentScore < scoreToBeat ||
                      validFormatFound
                  ) {
                      scoreToBeat = currentScore;
                      bestMoment = tempConfig;
                      if (validFormatFound) {
                          bestFormatIsValid = true;
                      }
                  }
              } else {
                  if (currentScore < scoreToBeat) {
                      scoreToBeat = currentScore;
                      bestMoment = tempConfig;
                  }
              }
          }
  
          extend(config, bestMoment || tempConfig);
      }
  
      function configFromObject(config) {
          if (config._d) {
              return;
          }
  
          var i = normalizeObjectUnits(config._i),
              dayOrDate = i.day === undefined ? i.date : i.day;
          config._a = map(
              [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
              function (obj) {
                  return obj && parseInt(obj, 10);
              }
          );
  
          configFromArray(config);
      }
  
      function createFromConfig(config) {
          var res = new Moment(checkOverflow(prepareConfig(config)));
          if (res._nextDay) {
              // Adding is smart enough around DST
              res.add(1, 'd');
              res._nextDay = undefined;
          }
  
          return res;
      }
  
      function prepareConfig(config) {
          var input = config._i,
              format = config._f;
  
          config._locale = config._locale || getLocale(config._l);
  
          if (input === null || (format === undefined && input === '')) {
              return createInvalid({ nullInput: true });
          }
  
          if (typeof input === 'string') {
              config._i = input = config._locale.preparse(input);
          }
  
          if (isMoment(input)) {
              return new Moment(checkOverflow(input));
          } else if (isDate(input)) {
              config._d = input;
          } else if (isArray(format)) {
              configFromStringAndArray(config);
          } else if (format) {
              configFromStringAndFormat(config);
          } else {
              configFromInput(config);
          }
  
          if (!isValid(config)) {
              config._d = null;
          }
  
          return config;
      }
  
      function configFromInput(config) {
          var input = config._i;
          if (isUndefined(input)) {
              config._d = new Date(hooks.now());
          } else if (isDate(input)) {
              config._d = new Date(input.valueOf());
          } else if (typeof input === 'string') {
              configFromString(config);
          } else if (isArray(input)) {
              config._a = map(input.slice(0), function (obj) {
                  return parseInt(obj, 10);
              });
              configFromArray(config);
          } else if (isObject(input)) {
              configFromObject(config);
          } else if (isNumber(input)) {
              // from milliseconds
              config._d = new Date(input);
          } else {
              hooks.createFromInputFallback(config);
          }
      }
  
      function createLocalOrUTC(input, format, locale, strict, isUTC) {
          var c = {};
  
          if (format === true || format === false) {
              strict = format;
              format = undefined;
          }
  
          if (locale === true || locale === false) {
              strict = locale;
              locale = undefined;
          }
  
          if (
              (isObject(input) && isObjectEmpty(input)) ||
              (isArray(input) && input.length === 0)
          ) {
              input = undefined;
          }
          // object construction must be done this way.
          // https://github.com/moment/moment/issues/1423
          c._isAMomentObject = true;
          c._useUTC = c._isUTC = isUTC;
          c._l = locale;
          c._i = input;
          c._f = format;
          c._strict = strict;
  
          return createFromConfig(c);
      }
  
      function createLocal(input, format, locale, strict) {
          return createLocalOrUTC(input, format, locale, strict, false);
      }
  
      var prototypeMin = deprecate(
              'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
              function () {
                  var other = createLocal.apply(null, arguments);
                  if (this.isValid() && other.isValid()) {
                      return other < this ? this : other;
                  } else {
                      return createInvalid();
                  }
              }
          ),
          prototypeMax = deprecate(
              'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
              function () {
                  var other = createLocal.apply(null, arguments);
                  if (this.isValid() && other.isValid()) {
                      return other > this ? this : other;
                  } else {
                      return createInvalid();
                  }
              }
          );
  
      // Pick a moment m from moments so that m[fn](other) is true for all
      // other. This relies on the function fn to be transitive.
      //
      // moments should either be an array of moment objects or an array, whose
      // first element is an array of moment objects.
      function pickBy(fn, moments) {
          var res, i;
          if (moments.length === 1 && isArray(moments[0])) {
              moments = moments[0];
          }
          if (!moments.length) {
              return createLocal();
          }
          res = moments[0];
          for (i = 1; i < moments.length; ++i) {
              if (!moments[i].isValid() || moments[i][fn](res)) {
                  res = moments[i];
              }
          }
          return res;
      }
  
      // TODO: Use [].sort instead?
      function min() {
          var args = [].slice.call(arguments, 0);
  
          return pickBy('isBefore', args);
      }
  
      function max() {
          var args = [].slice.call(arguments, 0);
  
          return pickBy('isAfter', args);
      }
  
      var now = function () {
          return Date.now ? Date.now() : +new Date();
      };
  
      var ordering = [
          'year',
          'quarter',
          'month',
          'week',
          'day',
          'hour',
          'minute',
          'second',
          'millisecond',
      ];
  
      function isDurationValid(m) {
          var key,
              unitHasDecimal = false,
              i;
          for (key in m) {
              if (
                  hasOwnProp(m, key) &&
                  !(
                      indexOf.call(ordering, key) !== -1 &&
                      (m[key] == null || !isNaN(m[key]))
                  )
              ) {
                  return false;
              }
          }
  
          for (i = 0; i < ordering.length; ++i) {
              if (m[ordering[i]]) {
                  if (unitHasDecimal) {
                      return false; // only allow non-integers for smallest unit
                  }
                  if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                      unitHasDecimal = true;
                  }
              }
          }
  
          return true;
      }
  
      function isValid$1() {
          return this._isValid;
      }
  
      function createInvalid$1() {
          return createDuration(NaN);
      }
  
      function Duration(duration) {
          var normalizedInput = normalizeObjectUnits(duration),
              years = normalizedInput.year || 0,
              quarters = normalizedInput.quarter || 0,
              months = normalizedInput.month || 0,
              weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
              days = normalizedInput.day || 0,
              hours = normalizedInput.hour || 0,
              minutes = normalizedInput.minute || 0,
              seconds = normalizedInput.second || 0,
              milliseconds = normalizedInput.millisecond || 0;
  
          this._isValid = isDurationValid(normalizedInput);
  
          // representation for dateAddRemove
          this._milliseconds =
              +milliseconds +
              seconds * 1e3 + // 1000
              minutes * 6e4 + // 1000 * 60
              hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
          // Because of dateAddRemove treats 24 hours as different from a
          // day when working around DST, we need to store them separately
          this._days = +days + weeks * 7;
          // It is impossible to translate months into days without knowing
          // which months you are are talking about, so we have to store
          // it separately.
          this._months = +months + quarters * 3 + years * 12;
  
          this._data = {};
  
          this._locale = getLocale();
  
          this._bubble();
      }
  
      function isDuration(obj) {
          return obj instanceof Duration;
      }
  
      function absRound(number) {
          if (number < 0) {
              return Math.round(-1 * number) * -1;
          } else {
              return Math.round(number);
          }
      }
  
      // compare two arrays, return the number of differences
      function compareArrays(array1, array2, dontConvert) {
          var len = Math.min(array1.length, array2.length),
              lengthDiff = Math.abs(array1.length - array2.length),
              diffs = 0,
              i;
          for (i = 0; i < len; i++) {
              if (
                  (dontConvert && array1[i] !== array2[i]) ||
                  (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
              ) {
                  diffs++;
              }
          }
          return diffs + lengthDiff;
      }
  
      // FORMATTING
  
      function offset(token, separator) {
          addFormatToken(token, 0, 0, function () {
              var offset = this.utcOffset(),
                  sign = '+';
              if (offset < 0) {
                  offset = -offset;
                  sign = '-';
              }
              return (
                  sign +
                  zeroFill(~~(offset / 60), 2) +
                  separator +
                  zeroFill(~~offset % 60, 2)
              );
          });
      }
  
      offset('Z', ':');
      offset('ZZ', '');
  
      // PARSING
  
      addRegexToken('Z', matchShortOffset);
      addRegexToken('ZZ', matchShortOffset);
      addParseToken(['Z', 'ZZ'], function (input, array, config) {
          config._useUTC = true;
          config._tzm = offsetFromString(matchShortOffset, input);
      });
  
      // HELPERS
  
      // timezone chunker
      // '+10:00' > ['10',  '00']
      // '-1530'  > ['-15', '30']
      var chunkOffset = /([\+\-]|\d\d)/gi;
  
      function offsetFromString(matcher, string) {
          var matches = (string || '').match(matcher),
              chunk,
              parts,
              minutes;
  
          if (matches === null) {
              return null;
          }
  
          chunk = matches[matches.length - 1] || [];
          parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
          minutes = +(parts[1] * 60) + toInt(parts[2]);
  
          return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
      }
  
      // Return a moment from input, that is local/utc/zone equivalent to model.
      function cloneWithOffset(input, model) {
          var res, diff;
          if (model._isUTC) {
              res = model.clone();
              diff =
                  (isMoment(input) || isDate(input)
                      ? input.valueOf()
                      : createLocal(input).valueOf()) - res.valueOf();
              // Use low-level api, because this fn is low-level api.
              res._d.setTime(res._d.valueOf() + diff);
              hooks.updateOffset(res, false);
              return res;
          } else {
              return createLocal(input).local();
          }
      }
  
      function getDateOffset(m) {
          // On Firefox.24 Date#getTimezoneOffset returns a floating point.
          // https://github.com/moment/moment/pull/1871
          return -Math.round(m._d.getTimezoneOffset());
      }
  
      // HOOKS
  
      // This function will be called whenever a moment is mutated.
      // It is intended to keep the offset in sync with the timezone.
      hooks.updateOffset = function () {};
  
      // MOMENTS
  
      // keepLocalTime = true means only change the timezone, without
      // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
      // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
      // +0200, so we adjust the time as needed, to be valid.
      //
      // Keeping the time actually adds/subtracts (one hour)
      // from the actual represented time. That is why we call updateOffset
      // a second time. In case it wants us to change the offset again
      // _changeInProgress == true case, then we have to adjust, because
      // there is no such time in the given timezone.
      function getSetOffset(input, keepLocalTime, keepMinutes) {
          var offset = this._offset || 0,
              localAdjust;
          if (!this.isValid()) {
              return input != null ? this : NaN;
          }
          if (input != null) {
              if (typeof input === 'string') {
                  input = offsetFromString(matchShortOffset, input);
                  if (input === null) {
                      return this;
                  }
              } else if (Math.abs(input) < 16 && !keepMinutes) {
                  input = input * 60;
              }
              if (!this._isUTC && keepLocalTime) {
                  localAdjust = getDateOffset(this);
              }
              this._offset = input;
              this._isUTC = true;
              if (localAdjust != null) {
                  this.add(localAdjust, 'm');
              }
              if (offset !== input) {
                  if (!keepLocalTime || this._changeInProgress) {
                      addSubtract(
                          this,
                          createDuration(input - offset, 'm'),
                          1,
                          false
                      );
                  } else if (!this._changeInProgress) {
                      this._changeInProgress = true;
                      hooks.updateOffset(this, true);
                      this._changeInProgress = null;
                  }
              }
              return this;
          } else {
              return this._isUTC ? offset : getDateOffset(this);
          }
      }
  
      function getSetZone(input, keepLocalTime) {
          if (input != null) {
              if (typeof input !== 'string') {
                  input = -input;
              }
  
              this.utcOffset(input, keepLocalTime);
  
              return this;
          } else {
              return -this.utcOffset();
          }
      }
  
      function setOffsetToUTC(keepLocalTime) {
          return this.utcOffset(0, keepLocalTime);
      }
  
      function setOffsetToLocal(keepLocalTime) {
          if (this._isUTC) {
              this.utcOffset(0, keepLocalTime);
              this._isUTC = false;
  
              if (keepLocalTime) {
                  this.subtract(getDateOffset(this), 'm');
              }
          }
          return this;
      }
  
      function setOffsetToParsedOffset() {
          if (this._tzm != null) {
              this.utcOffset(this._tzm, false, true);
          } else if (typeof this._i === 'string') {
              var tZone = offsetFromString(matchOffset, this._i);
              if (tZone != null) {
                  this.utcOffset(tZone);
              } else {
                  this.utcOffset(0, true);
              }
          }
          return this;
      }
  
      function hasAlignedHourOffset(input) {
          if (!this.isValid()) {
              return false;
          }
          input = input ? createLocal(input).utcOffset() : 0;
  
          return (this.utcOffset() - input) % 60 === 0;
      }
  
      function isDaylightSavingTime() {
          return (
              this.utcOffset() > this.clone().month(0).utcOffset() ||
              this.utcOffset() > this.clone().month(5).utcOffset()
          );
      }
  
      function isDaylightSavingTimeShifted() {
          if (!isUndefined(this._isDSTShifted)) {
              return this._isDSTShifted;
          }
  
          var c = {},
              other;
  
          copyConfig(c, this);
          c = prepareConfig(c);
  
          if (c._a) {
              other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
              this._isDSTShifted =
                  this.isValid() && compareArrays(c._a, other.toArray()) > 0;
          } else {
              this._isDSTShifted = false;
          }
  
          return this._isDSTShifted;
      }
  
      function isLocal() {
          return this.isValid() ? !this._isUTC : false;
      }
  
      function isUtcOffset() {
          return this.isValid() ? this._isUTC : false;
      }
  
      function isUtc() {
          return this.isValid() ? this._isUTC && this._offset === 0 : false;
      }
  
      // ASP.NET json date format regex
      var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
          // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
          // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
          // and further modified to allow for strings containing both week and day
          isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
  
      function createDuration(input, key) {
          var duration = input,
              // matching against regexp is expensive, do it on demand
              match = null,
              sign,
              ret,
              diffRes;
  
          if (isDuration(input)) {
              duration = {
                  ms: input._milliseconds,
                  d: input._days,
                  M: input._months,
              };
          } else if (isNumber(input) || !isNaN(+input)) {
              duration = {};
              if (key) {
                  duration[key] = +input;
              } else {
                  duration.milliseconds = +input;
              }
          } else if ((match = aspNetRegex.exec(input))) {
              sign = match[1] === '-' ? -1 : 1;
              duration = {
                  y: 0,
                  d: toInt(match[DATE]) * sign,
                  h: toInt(match[HOUR]) * sign,
                  m: toInt(match[MINUTE]) * sign,
                  s: toInt(match[SECOND]) * sign,
                  ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
              };
          } else if ((match = isoRegex.exec(input))) {
              sign = match[1] === '-' ? -1 : 1;
              duration = {
                  y: parseIso(match[2], sign),
                  M: parseIso(match[3], sign),
                  w: parseIso(match[4], sign),
                  d: parseIso(match[5], sign),
                  h: parseIso(match[6], sign),
                  m: parseIso(match[7], sign),
                  s: parseIso(match[8], sign),
              };
          } else if (duration == null) {
              // checks for null or undefined
              duration = {};
          } else if (
              typeof duration === 'object' &&
              ('from' in duration || 'to' in duration)
          ) {
              diffRes = momentsDifference(
                  createLocal(duration.from),
                  createLocal(duration.to)
              );
  
              duration = {};
              duration.ms = diffRes.milliseconds;
              duration.M = diffRes.months;
          }
  
          ret = new Duration(duration);
  
          if (isDuration(input) && hasOwnProp(input, '_locale')) {
              ret._locale = input._locale;
          }
  
          if (isDuration(input) && hasOwnProp(input, '_isValid')) {
              ret._isValid = input._isValid;
          }
  
          return ret;
      }
  
      createDuration.fn = Duration.prototype;
      createDuration.invalid = createInvalid$1;
  
      function parseIso(inp, sign) {
          // We'd normally use ~~inp for this, but unfortunately it also
          // converts floats to ints.
          // inp may be undefined, so careful calling replace on it.
          var res = inp && parseFloat(inp.replace(',', '.'));
          // apply sign while we're at it
          return (isNaN(res) ? 0 : res) * sign;
      }
  
      function positiveMomentsDifference(base, other) {
          var res = {};
  
          res.months =
              other.month() - base.month() + (other.year() - base.year()) * 12;
          if (base.clone().add(res.months, 'M').isAfter(other)) {
              --res.months;
          }
  
          res.milliseconds = +other - +base.clone().add(res.months, 'M');
  
          return res;
      }
  
      function momentsDifference(base, other) {
          var res;
          if (!(base.isValid() && other.isValid())) {
              return { milliseconds: 0, months: 0 };
          }
  
          other = cloneWithOffset(other, base);
          if (base.isBefore(other)) {
              res = positiveMomentsDifference(base, other);
          } else {
              res = positiveMomentsDifference(other, base);
              res.milliseconds = -res.milliseconds;
              res.months = -res.months;
          }
  
          return res;
      }
  
      // TODO: remove 'name' arg after deprecation is removed
      function createAdder(direction, name) {
          return function (val, period) {
              var dur, tmp;
              //invert the arguments, but complain about it
              if (period !== null && !isNaN(+period)) {
                  deprecateSimple(
                      name,
                      'moment().' +
                          name +
                          '(period, number) is deprecated. Please use moment().' +
                          name +
                          '(number, period). ' +
                          'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
                  );
                  tmp = val;
                  val = period;
                  period = tmp;
              }
  
              dur = createDuration(val, period);
              addSubtract(this, dur, direction);
              return this;
          };
      }
  
      function addSubtract(mom, duration, isAdding, updateOffset) {
          var milliseconds = duration._milliseconds,
              days = absRound(duration._days),
              months = absRound(duration._months);
  
          if (!mom.isValid()) {
              // No op
              return;
          }
  
          updateOffset = updateOffset == null ? true : updateOffset;
  
          if (months) {
              setMonth(mom, get(mom, 'Month') + months * isAdding);
          }
          if (days) {
              set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
          }
          if (milliseconds) {
              mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
          }
          if (updateOffset) {
              hooks.updateOffset(mom, days || months);
          }
      }
  
      var add = createAdder(1, 'add'),
          subtract = createAdder(-1, 'subtract');
  
      function isString(input) {
          return typeof input === 'string' || input instanceof String;
      }
  
      // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
      function isMomentInput(input) {
          return (
              isMoment(input) ||
              isDate(input) ||
              isString(input) ||
              isNumber(input) ||
              isNumberOrStringArray(input) ||
              isMomentInputObject(input) ||
              input === null ||
              input === undefined
          );
      }
  
      function isMomentInputObject(input) {
          var objectTest = isObject(input) && !isObjectEmpty(input),
              propertyTest = false,
              properties = [
                  'years',
                  'year',
                  'y',
                  'months',
                  'month',
                  'M',
                  'days',
                  'day',
                  'd',
                  'dates',
                  'date',
                  'D',
                  'hours',
                  'hour',
                  'h',
                  'minutes',
                  'minute',
                  'm',
                  'seconds',
                  'second',
                  's',
                  'milliseconds',
                  'millisecond',
                  'ms',
              ],
              i,
              property;
  
          for (i = 0; i < properties.length; i += 1) {
              property = properties[i];
              propertyTest = propertyTest || hasOwnProp(input, property);
          }
  
          return objectTest && propertyTest;
      }
  
      function isNumberOrStringArray(input) {
          var arrayTest = isArray(input),
              dataTypeTest = false;
          if (arrayTest) {
              dataTypeTest =
                  input.filter(function (item) {
                      return !isNumber(item) && isString(input);
                  }).length === 0;
          }
          return arrayTest && dataTypeTest;
      }
  
      function isCalendarSpec(input) {
          var objectTest = isObject(input) && !isObjectEmpty(input),
              propertyTest = false,
              properties = [
                  'sameDay',
                  'nextDay',
                  'lastDay',
                  'nextWeek',
                  'lastWeek',
                  'sameElse',
              ],
              i,
              property;
  
          for (i = 0; i < properties.length; i += 1) {
              property = properties[i];
              propertyTest = propertyTest || hasOwnProp(input, property);
          }
  
          return objectTest && propertyTest;
      }
  
      function getCalendarFormat(myMoment, now) {
          var diff = myMoment.diff(now, 'days', true);
          return diff < -6
              ? 'sameElse'
              : diff < -1
              ? 'lastWeek'
              : diff < 0
              ? 'lastDay'
              : diff < 1
              ? 'sameDay'
              : diff < 2
              ? 'nextDay'
              : diff < 7
              ? 'nextWeek'
              : 'sameElse';
      }
  
      function calendar$1(time, formats) {
          // Support for single parameter, formats only overload to the calendar function
          if (arguments.length === 1) {
              if (isMomentInput(arguments[0])) {
                  time = arguments[0];
                  formats = undefined;
              } else if (isCalendarSpec(arguments[0])) {
                  formats = arguments[0];
                  time = undefined;
              }
          }
          // We want to compare the start of today, vs this.
          // Getting start-of-today depends on whether we're local/utc/offset or not.
          var now = time || createLocal(),
              sod = cloneWithOffset(now, this).startOf('day'),
              format = hooks.calendarFormat(this, sod) || 'sameElse',
              output =
                  formats &&
                  (isFunction(formats[format])
                      ? formats[format].call(this, now)
                      : formats[format]);
  
          return this.format(
              output || this.localeData().calendar(format, this, createLocal(now))
          );
      }
  
      function clone() {
          return new Moment(this);
      }
  
      function isAfter(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input);
          if (!(this.isValid() && localInput.isValid())) {
              return false;
          }
          units = normalizeUnits(units) || 'millisecond';
          if (units === 'millisecond') {
              return this.valueOf() > localInput.valueOf();
          } else {
              return localInput.valueOf() < this.clone().startOf(units).valueOf();
          }
      }
  
      function isBefore(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input);
          if (!(this.isValid() && localInput.isValid())) {
              return false;
          }
          units = normalizeUnits(units) || 'millisecond';
          if (units === 'millisecond') {
              return this.valueOf() < localInput.valueOf();
          } else {
              return this.clone().endOf(units).valueOf() < localInput.valueOf();
          }
      }
  
      function isBetween(from, to, units, inclusivity) {
          var localFrom = isMoment(from) ? from : createLocal(from),
              localTo = isMoment(to) ? to : createLocal(to);
          if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
              return false;
          }
          inclusivity = inclusivity || '()';
          return (
              (inclusivity[0] === '('
                  ? this.isAfter(localFrom, units)
                  : !this.isBefore(localFrom, units)) &&
              (inclusivity[1] === ')'
                  ? this.isBefore(localTo, units)
                  : !this.isAfter(localTo, units))
          );
      }
  
      function isSame(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input),
              inputMs;
          if (!(this.isValid() && localInput.isValid())) {
              return false;
          }
          units = normalizeUnits(units) || 'millisecond';
          if (units === 'millisecond') {
              return this.valueOf() === localInput.valueOf();
          } else {
              inputMs = localInput.valueOf();
              return (
                  this.clone().startOf(units).valueOf() <= inputMs &&
                  inputMs <= this.clone().endOf(units).valueOf()
              );
          }
      }
  
      function isSameOrAfter(input, units) {
          return this.isSame(input, units) || this.isAfter(input, units);
      }
  
      function isSameOrBefore(input, units) {
          return this.isSame(input, units) || this.isBefore(input, units);
      }
  
      function diff(input, units, asFloat) {
          var that, zoneDelta, output;
  
          if (!this.isValid()) {
              return NaN;
          }
  
          that = cloneWithOffset(input, this);
  
          if (!that.isValid()) {
              return NaN;
          }
  
          zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
  
          units = normalizeUnits(units);
  
          switch (units) {
              case 'year':
                  output = monthDiff(this, that) / 12;
                  break;
              case 'month':
                  output = monthDiff(this, that);
                  break;
              case 'quarter':
                  output = monthDiff(this, that) / 3;
                  break;
              case 'second':
                  output = (this - that) / 1e3;
                  break; // 1000
              case 'minute':
                  output = (this - that) / 6e4;
                  break; // 1000 * 60
              case 'hour':
                  output = (this - that) / 36e5;
                  break; // 1000 * 60 * 60
              case 'day':
                  output = (this - that - zoneDelta) / 864e5;
                  break; // 1000 * 60 * 60 * 24, negate dst
              case 'week':
                  output = (this - that - zoneDelta) / 6048e5;
                  break; // 1000 * 60 * 60 * 24 * 7, negate dst
              default:
                  output = this - that;
          }
  
          return asFloat ? output : absFloor(output);
      }
  
      function monthDiff(a, b) {
          if (a.date() < b.date()) {
              // end-of-month calculations work correct when the start month has more
              // days than the end month.
              return -monthDiff(b, a);
          }
          // difference in months
          var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
              // b is in (anchor - 1 month, anchor + 1 month)
              anchor = a.clone().add(wholeMonthDiff, 'months'),
              anchor2,
              adjust;
  
          if (b - anchor < 0) {
              anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
              // linear across the month
              adjust = (b - anchor) / (anchor - anchor2);
          } else {
              anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
              // linear across the month
              adjust = (b - anchor) / (anchor2 - anchor);
          }
  
          //check for negative zero, return zero if negative zero
          return -(wholeMonthDiff + adjust) || 0;
      }
  
      hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
      hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
  
      function toString() {
          return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
      }
  
      function toISOString(keepOffset) {
          if (!this.isValid()) {
              return null;
          }
          var utc = keepOffset !== true,
              m = utc ? this.clone().utc() : this;
          if (m.year() < 0 || m.year() > 9999) {
              return formatMoment(
                  m,
                  utc
                      ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
                      : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
              );
          }
          if (isFunction(Date.prototype.toISOString)) {
              // native implementation is ~50x faster, use it when we can
              if (utc) {
                  return this.toDate().toISOString();
              } else {
                  return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
                      .toISOString()
                      .replace('Z', formatMoment(m, 'Z'));
              }
          }
          return formatMoment(
              m,
              utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
          );
      }
  
      /**
       * Return a human readable representation of a moment that can
       * also be evaluated to get a new moment which is the same
       *
       * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
       */
      function inspect() {
          if (!this.isValid()) {
              return 'moment.invalid(/* ' + this._i + ' */)';
          }
          var func = 'moment',
              zone = '',
              prefix,
              year,
              datetime,
              suffix;
          if (!this.isLocal()) {
              func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
              zone = 'Z';
          }
          prefix = '[' + func + '("]';
          year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
          datetime = '-MM-DD[T]HH:mm:ss.SSS';
          suffix = zone + '[")]';
  
          return this.format(prefix + year + datetime + suffix);
      }
  
      function format(inputString) {
          if (!inputString) {
              inputString = this.isUtc()
                  ? hooks.defaultFormatUtc
                  : hooks.defaultFormat;
          }
          var output = formatMoment(this, inputString);
          return this.localeData().postformat(output);
      }
  
      function from(time, withoutSuffix) {
          if (
              this.isValid() &&
              ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
          ) {
              return createDuration({ to: this, from: time })
                  .locale(this.locale())
                  .humanize(!withoutSuffix);
          } else {
              return this.localeData().invalidDate();
          }
      }
  
      function fromNow(withoutSuffix) {
          return this.from(createLocal(), withoutSuffix);
      }
  
      function to(time, withoutSuffix) {
          if (
              this.isValid() &&
              ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
          ) {
              return createDuration({ from: this, to: time })
                  .locale(this.locale())
                  .humanize(!withoutSuffix);
          } else {
              return this.localeData().invalidDate();
          }
      }
  
      function toNow(withoutSuffix) {
          return this.to(createLocal(), withoutSuffix);
      }
  
      // If passed a locale key, it will set the locale for this
      // instance.  Otherwise, it will return the locale configuration
      // variables for this instance.
      function locale(key) {
          var newLocaleData;
  
          if (key === undefined) {
              return this._locale._abbr;
          } else {
              newLocaleData = getLocale(key);
              if (newLocaleData != null) {
                  this._locale = newLocaleData;
              }
              return this;
          }
      }
  
      var lang = deprecate(
          'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
          function (key) {
              if (key === undefined) {
                  return this.localeData();
              } else {
                  return this.locale(key);
              }
          }
      );
  
      function localeData() {
          return this._locale;
      }
  
      var MS_PER_SECOND = 1000,
          MS_PER_MINUTE = 60 * MS_PER_SECOND,
          MS_PER_HOUR = 60 * MS_PER_MINUTE,
          MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
  
      // actual modulo - handles negative numbers (for dates before 1970):
      function mod$1(dividend, divisor) {
          return ((dividend % divisor) + divisor) % divisor;
      }
  
      function localStartOfDate(y, m, d) {
          // the date constructor remaps years 0-99 to 1900-1999
          if (y < 100 && y >= 0) {
              // preserve leap years using a full 400 year cycle, then reset
              return new Date(y + 400, m, d) - MS_PER_400_YEARS;
          } else {
              return new Date(y, m, d).valueOf();
          }
      }
  
      function utcStartOfDate(y, m, d) {
          // Date.UTC remaps years 0-99 to 1900-1999
          if (y < 100 && y >= 0) {
              // preserve leap years using a full 400 year cycle, then reset
              return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
          } else {
              return Date.UTC(y, m, d);
          }
      }
  
      function startOf(units) {
          var time, startOfDate;
          units = normalizeUnits(units);
          if (units === undefined || units === 'millisecond' || !this.isValid()) {
              return this;
          }
  
          startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
  
          switch (units) {
              case 'year':
                  time = startOfDate(this.year(), 0, 1);
                  break;
              case 'quarter':
                  time = startOfDate(
                      this.year(),
                      this.month() - (this.month() % 3),
                      1
                  );
                  break;
              case 'month':
                  time = startOfDate(this.year(), this.month(), 1);
                  break;
              case 'week':
                  time = startOfDate(
                      this.year(),
                      this.month(),
                      this.date() - this.weekday()
                  );
                  break;
              case 'isoWeek':
                  time = startOfDate(
                      this.year(),
                      this.month(),
                      this.date() - (this.isoWeekday() - 1)
                  );
                  break;
              case 'day':
              case 'date':
                  time = startOfDate(this.year(), this.month(), this.date());
                  break;
              case 'hour':
                  time = this._d.valueOf();
                  time -= mod$1(
                      time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                      MS_PER_HOUR
                  );
                  break;
              case 'minute':
                  time = this._d.valueOf();
                  time -= mod$1(time, MS_PER_MINUTE);
                  break;
              case 'second':
                  time = this._d.valueOf();
                  time -= mod$1(time, MS_PER_SECOND);
                  break;
          }
  
          this._d.setTime(time);
          hooks.updateOffset(this, true);
          return this;
      }
  
      function endOf(units) {
          var time, startOfDate;
          units = normalizeUnits(units);
          if (units === undefined || units === 'millisecond' || !this.isValid()) {
              return this;
          }
  
          startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
  
          switch (units) {
              case 'year':
                  time = startOfDate(this.year() + 1, 0, 1) - 1;
                  break;
              case 'quarter':
                  time =
                      startOfDate(
                          this.year(),
                          this.month() - (this.month() % 3) + 3,
                          1
                      ) - 1;
                  break;
              case 'month':
                  time = startOfDate(this.year(), this.month() + 1, 1) - 1;
                  break;
              case 'week':
                  time =
                      startOfDate(
                          this.year(),
                          this.month(),
                          this.date() - this.weekday() + 7
                      ) - 1;
                  break;
              case 'isoWeek':
                  time =
                      startOfDate(
                          this.year(),
                          this.month(),
                          this.date() - (this.isoWeekday() - 1) + 7
                      ) - 1;
                  break;
              case 'day':
              case 'date':
                  time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
                  break;
              case 'hour':
                  time = this._d.valueOf();
                  time +=
                      MS_PER_HOUR -
                      mod$1(
                          time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                          MS_PER_HOUR
                      ) -
                      1;
                  break;
              case 'minute':
                  time = this._d.valueOf();
                  time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
                  break;
              case 'second':
                  time = this._d.valueOf();
                  time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
                  break;
          }
  
          this._d.setTime(time);
          hooks.updateOffset(this, true);
          return this;
      }
  
      function valueOf() {
          return this._d.valueOf() - (this._offset || 0) * 60000;
      }
  
      function unix() {
          return Math.floor(this.valueOf() / 1000);
      }
  
      function toDate() {
          return new Date(this.valueOf());
      }
  
      function toArray() {
          var m = this;
          return [
              m.year(),
              m.month(),
              m.date(),
              m.hour(),
              m.minute(),
              m.second(),
              m.millisecond(),
          ];
      }
  
      function toObject() {
          var m = this;
          return {
              years: m.year(),
              months: m.month(),
              date: m.date(),
              hours: m.hours(),
              minutes: m.minutes(),
              seconds: m.seconds(),
              milliseconds: m.milliseconds(),
          };
      }
  
      function toJSON() {
          // new Date(NaN).toJSON() === null
          return this.isValid() ? this.toISOString() : null;
      }
  
      function isValid$2() {
          return isValid(this);
      }
  
      function parsingFlags() {
          return extend({}, getParsingFlags(this));
      }
  
      function invalidAt() {
          return getParsingFlags(this).overflow;
      }
  
      function creationData() {
          return {
              input: this._i,
              format: this._f,
              locale: this._locale,
              isUTC: this._isUTC,
              strict: this._strict,
          };
      }
  
      addFormatToken('N', 0, 0, 'eraAbbr');
      addFormatToken('NN', 0, 0, 'eraAbbr');
      addFormatToken('NNN', 0, 0, 'eraAbbr');
      addFormatToken('NNNN', 0, 0, 'eraName');
      addFormatToken('NNNNN', 0, 0, 'eraNarrow');
  
      addFormatToken('y', ['y', 1], 'yo', 'eraYear');
      addFormatToken('y', ['yy', 2], 0, 'eraYear');
      addFormatToken('y', ['yyy', 3], 0, 'eraYear');
      addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
  
      addRegexToken('N', matchEraAbbr);
      addRegexToken('NN', matchEraAbbr);
      addRegexToken('NNN', matchEraAbbr);
      addRegexToken('NNNN', matchEraName);
      addRegexToken('NNNNN', matchEraNarrow);
  
      addParseToken(['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function (
          input,
          array,
          config,
          token
      ) {
          var era = config._locale.erasParse(input, token, config._strict);
          if (era) {
              getParsingFlags(config).era = era;
          } else {
              getParsingFlags(config).invalidEra = input;
          }
      });
  
      addRegexToken('y', matchUnsigned);
      addRegexToken('yy', matchUnsigned);
      addRegexToken('yyy', matchUnsigned);
      addRegexToken('yyyy', matchUnsigned);
      addRegexToken('yo', matchEraYearOrdinal);
  
      addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
      addParseToken(['yo'], function (input, array, config, token) {
          var match;
          if (config._locale._eraYearOrdinalRegex) {
              match = input.match(config._locale._eraYearOrdinalRegex);
          }
  
          if (config._locale.eraYearOrdinalParse) {
              array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
          } else {
              array[YEAR] = parseInt(input, 10);
          }
      });
  
      function localeEras(m, format) {
          var i,
              l,
              date,
              eras = this._eras || getLocale('en')._eras;
          for (i = 0, l = eras.length; i < l; ++i) {
              switch (typeof eras[i].since) {
                  case 'string':
                      // truncate time
                      date = hooks(eras[i].since).startOf('day');
                      eras[i].since = date.valueOf();
                      break;
              }
  
              switch (typeof eras[i].until) {
                  case 'undefined':
                      eras[i].until = +Infinity;
                      break;
                  case 'string':
                      // truncate time
                      date = hooks(eras[i].until).startOf('day').valueOf();
                      eras[i].until = date.valueOf();
                      break;
              }
          }
          return eras;
      }
  
      function localeErasParse(eraName, format, strict) {
          var i,
              l,
              eras = this.eras(),
              name,
              abbr,
              narrow;
          eraName = eraName.toUpperCase();
  
          for (i = 0, l = eras.length; i < l; ++i) {
              name = eras[i].name.toUpperCase();
              abbr = eras[i].abbr.toUpperCase();
              narrow = eras[i].narrow.toUpperCase();
  
              if (strict) {
                  switch (format) {
                      case 'N':
                      case 'NN':
                      case 'NNN':
                          if (abbr === eraName) {
                              return eras[i];
                          }
                          break;
  
                      case 'NNNN':
                          if (name === eraName) {
                              return eras[i];
                          }
                          break;
  
                      case 'NNNNN':
                          if (narrow === eraName) {
                              return eras[i];
                          }
                          break;
                  }
              } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
                  return eras[i];
              }
          }
      }
  
      function localeErasConvertYear(era, year) {
          var dir = era.since <= era.until ? +1 : -1;
          if (year === undefined) {
              return hooks(era.since).year();
          } else {
              return hooks(era.since).year() + (year - era.offset) * dir;
          }
      }
  
      function getEraName() {
          var i,
              l,
              val,
              eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
              // truncate time
              val = this.startOf('day').valueOf();
  
              if (eras[i].since <= val && val <= eras[i].until) {
                  return eras[i].name;
              }
              if (eras[i].until <= val && val <= eras[i].since) {
                  return eras[i].name;
              }
          }
  
          return '';
      }
  
      function getEraNarrow() {
          var i,
              l,
              val,
              eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
              // truncate time
              val = this.startOf('day').valueOf();
  
              if (eras[i].since <= val && val <= eras[i].until) {
                  return eras[i].narrow;
              }
              if (eras[i].until <= val && val <= eras[i].since) {
                  return eras[i].narrow;
              }
          }
  
          return '';
      }
  
      function getEraAbbr() {
          var i,
              l,
              val,
              eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
              // truncate time
              val = this.startOf('day').valueOf();
  
              if (eras[i].since <= val && val <= eras[i].until) {
                  return eras[i].abbr;
              }
              if (eras[i].until <= val && val <= eras[i].since) {
                  return eras[i].abbr;
              }
          }
  
          return '';
      }
  
      function getEraYear() {
          var i,
              l,
              dir,
              val,
              eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
              dir = eras[i].since <= eras[i].until ? +1 : -1;
  
              // truncate time
              val = this.startOf('day').valueOf();
  
              if (
                  (eras[i].since <= val && val <= eras[i].until) ||
                  (eras[i].until <= val && val <= eras[i].since)
              ) {
                  return (
                      (this.year() - hooks(eras[i].since).year()) * dir +
                      eras[i].offset
                  );
              }
          }
  
          return this.year();
      }
  
      function erasNameRegex(isStrict) {
          if (!hasOwnProp(this, '_erasNameRegex')) {
              computeErasParse.call(this);
          }
          return isStrict ? this._erasNameRegex : this._erasRegex;
      }
  
      function erasAbbrRegex(isStrict) {
          if (!hasOwnProp(this, '_erasAbbrRegex')) {
              computeErasParse.call(this);
          }
          return isStrict ? this._erasAbbrRegex : this._erasRegex;
      }
  
      function erasNarrowRegex(isStrict) {
          if (!hasOwnProp(this, '_erasNarrowRegex')) {
              computeErasParse.call(this);
          }
          return isStrict ? this._erasNarrowRegex : this._erasRegex;
      }
  
      function matchEraAbbr(isStrict, locale) {
          return locale.erasAbbrRegex(isStrict);
      }
  
      function matchEraName(isStrict, locale) {
          return locale.erasNameRegex(isStrict);
      }
  
      function matchEraNarrow(isStrict, locale) {
          return locale.erasNarrowRegex(isStrict);
      }
  
      function matchEraYearOrdinal(isStrict, locale) {
          return locale._eraYearOrdinalRegex || matchUnsigned;
      }
  
      function computeErasParse() {
          var abbrPieces = [],
              namePieces = [],
              narrowPieces = [],
              mixedPieces = [],
              i,
              l,
              eras = this.eras();
  
          for (i = 0, l = eras.length; i < l; ++i) {
              namePieces.push(regexEscape(eras[i].name));
              abbrPieces.push(regexEscape(eras[i].abbr));
              narrowPieces.push(regexEscape(eras[i].narrow));
  
              mixedPieces.push(regexEscape(eras[i].name));
              mixedPieces.push(regexEscape(eras[i].abbr));
              mixedPieces.push(regexEscape(eras[i].narrow));
          }
  
          this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
          this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
          this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
          this._erasNarrowRegex = new RegExp(
              '^(' + narrowPieces.join('|') + ')',
              'i'
          );
      }
  
      // FORMATTING
  
      addFormatToken(0, ['gg', 2], 0, function () {
          return this.weekYear() % 100;
      });
  
      addFormatToken(0, ['GG', 2], 0, function () {
          return this.isoWeekYear() % 100;
      });
  
      function addWeekYearFormatToken(token, getter) {
          addFormatToken(0, [token, token.length], 0, getter);
      }
  
      addWeekYearFormatToken('gggg', 'weekYear');
      addWeekYearFormatToken('ggggg', 'weekYear');
      addWeekYearFormatToken('GGGG', 'isoWeekYear');
      addWeekYearFormatToken('GGGGG', 'isoWeekYear');
  
      // ALIASES
  
      addUnitAlias('weekYear', 'gg');
      addUnitAlias('isoWeekYear', 'GG');
  
      // PRIORITY
  
      addUnitPriority('weekYear', 1);
      addUnitPriority('isoWeekYear', 1);
  
      // PARSING
  
      addRegexToken('G', matchSigned);
      addRegexToken('g', matchSigned);
      addRegexToken('GG', match1to2, match2);
      addRegexToken('gg', match1to2, match2);
      addRegexToken('GGGG', match1to4, match4);
      addRegexToken('gggg', match1to4, match4);
      addRegexToken('GGGGG', match1to6, match6);
      addRegexToken('ggggg', match1to6, match6);
  
      addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (
          input,
          week,
          config,
          token
      ) {
          week[token.substr(0, 2)] = toInt(input);
      });
  
      addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
          week[token] = hooks.parseTwoDigitYear(input);
      });
  
      // MOMENTS
  
      function getSetWeekYear(input) {
          return getSetWeekYearHelper.call(
              this,
              input,
              this.week(),
              this.weekday(),
              this.localeData()._week.dow,
              this.localeData()._week.doy
          );
      }
  
      function getSetISOWeekYear(input) {
          return getSetWeekYearHelper.call(
              this,
              input,
              this.isoWeek(),
              this.isoWeekday(),
              1,
              4
          );
      }
  
      function getISOWeeksInYear() {
          return weeksInYear(this.year(), 1, 4);
      }
  
      function getISOWeeksInISOWeekYear() {
          return weeksInYear(this.isoWeekYear(), 1, 4);
      }
  
      function getWeeksInYear() {
          var weekInfo = this.localeData()._week;
          return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
      }
  
      function getWeeksInWeekYear() {
          var weekInfo = this.localeData()._week;
          return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
      }
  
      function getSetWeekYearHelper(input, week, weekday, dow, doy) {
          var weeksTarget;
          if (input == null) {
              return weekOfYear(this, dow, doy).year;
          } else {
              weeksTarget = weeksInYear(input, dow, doy);
              if (week > weeksTarget) {
                  week = weeksTarget;
              }
              return setWeekAll.call(this, input, week, weekday, dow, doy);
          }
      }
  
      function setWeekAll(weekYear, week, weekday, dow, doy) {
          var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
              date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
  
          this.year(date.getUTCFullYear());
          this.month(date.getUTCMonth());
          this.date(date.getUTCDate());
          return this;
      }
  
      // FORMATTING
  
      addFormatToken('Q', 0, 'Qo', 'quarter');
  
      // ALIASES
  
      addUnitAlias('quarter', 'Q');
  
      // PRIORITY
  
      addUnitPriority('quarter', 7);
  
      // PARSING
  
      addRegexToken('Q', match1);
      addParseToken('Q', function (input, array) {
          array[MONTH] = (toInt(input) - 1) * 3;
      });
  
      // MOMENTS
  
      function getSetQuarter(input) {
          return input == null
              ? Math.ceil((this.month() + 1) / 3)
              : this.month((input - 1) * 3 + (this.month() % 3));
      }
  
      // FORMATTING
  
      addFormatToken('D', ['DD', 2], 'Do', 'date');
  
      // ALIASES
  
      addUnitAlias('date', 'D');
  
      // PRIORITY
      addUnitPriority('date', 9);
  
      // PARSING
  
      addRegexToken('D', match1to2);
      addRegexToken('DD', match1to2, match2);
      addRegexToken('Do', function (isStrict, locale) {
          // TODO: Remove "ordinalParse" fallback in next major release.
          return isStrict
              ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
              : locale._dayOfMonthOrdinalParseLenient;
      });
  
      addParseToken(['D', 'DD'], DATE);
      addParseToken('Do', function (input, array) {
          array[DATE] = toInt(input.match(match1to2)[0]);
      });
  
      // MOMENTS
  
      var getSetDayOfMonth = makeGetSet('Date', true);
  
      // FORMATTING
  
      addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
  
      // ALIASES
  
      addUnitAlias('dayOfYear', 'DDD');
  
      // PRIORITY
      addUnitPriority('dayOfYear', 4);
  
      // PARSING
  
      addRegexToken('DDD', match1to3);
      addRegexToken('DDDD', match3);
      addParseToken(['DDD', 'DDDD'], function (input, array, config) {
          config._dayOfYear = toInt(input);
      });
  
      // HELPERS
  
      // MOMENTS
  
      function getSetDayOfYear(input) {
          var dayOfYear =
              Math.round(
                  (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
              ) + 1;
          return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
      }
  
      // FORMATTING
  
      addFormatToken('m', ['mm', 2], 0, 'minute');
  
      // ALIASES
  
      addUnitAlias('minute', 'm');
  
      // PRIORITY
  
      addUnitPriority('minute', 14);
  
      // PARSING
  
      addRegexToken('m', match1to2);
      addRegexToken('mm', match1to2, match2);
      addParseToken(['m', 'mm'], MINUTE);
  
      // MOMENTS
  
      var getSetMinute = makeGetSet('Minutes', false);
  
      // FORMATTING
  
      addFormatToken('s', ['ss', 2], 0, 'second');
  
      // ALIASES
  
      addUnitAlias('second', 's');
  
      // PRIORITY
  
      addUnitPriority('second', 15);
  
      // PARSING
  
      addRegexToken('s', match1to2);
      addRegexToken('ss', match1to2, match2);
      addParseToken(['s', 'ss'], SECOND);
  
      // MOMENTS
  
      var getSetSecond = makeGetSet('Seconds', false);
  
      // FORMATTING
  
      addFormatToken('S', 0, 0, function () {
          return ~~(this.millisecond() / 100);
      });
  
      addFormatToken(0, ['SS', 2], 0, function () {
          return ~~(this.millisecond() / 10);
      });
  
      addFormatToken(0, ['SSS', 3], 0, 'millisecond');
      addFormatToken(0, ['SSSS', 4], 0, function () {
          return this.millisecond() * 10;
      });
      addFormatToken(0, ['SSSSS', 5], 0, function () {
          return this.millisecond() * 100;
      });
      addFormatToken(0, ['SSSSSS', 6], 0, function () {
          return this.millisecond() * 1000;
      });
      addFormatToken(0, ['SSSSSSS', 7], 0, function () {
          return this.millisecond() * 10000;
      });
      addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
          return this.millisecond() * 100000;
      });
      addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
          return this.millisecond() * 1000000;
      });
  
      // ALIASES
  
      addUnitAlias('millisecond', 'ms');
  
      // PRIORITY
  
      addUnitPriority('millisecond', 16);
  
      // PARSING
  
      addRegexToken('S', match1to3, match1);
      addRegexToken('SS', match1to3, match2);
      addRegexToken('SSS', match1to3, match3);
  
      var token, getSetMillisecond;
      for (token = 'SSSS'; token.length <= 9; token += 'S') {
          addRegexToken(token, matchUnsigned);
      }
  
      function parseMs(input, array) {
          array[MILLISECOND] = toInt(('0.' + input) * 1000);
      }
  
      for (token = 'S'; token.length <= 9; token += 'S') {
          addParseToken(token, parseMs);
      }
  
      getSetMillisecond = makeGetSet('Milliseconds', false);
  
      // FORMATTING
  
      addFormatToken('z', 0, 0, 'zoneAbbr');
      addFormatToken('zz', 0, 0, 'zoneName');
  
      // MOMENTS
  
      function getZoneAbbr() {
          return this._isUTC ? 'UTC' : '';
      }
  
      function getZoneName() {
          return this._isUTC ? 'Coordinated Universal Time' : '';
      }
  
      var proto = Moment.prototype;
  
      proto.add = add;
      proto.calendar = calendar$1;
      proto.clone = clone;
      proto.diff = diff;
      proto.endOf = endOf;
      proto.format = format;
      proto.from = from;
      proto.fromNow = fromNow;
      proto.to = to;
      proto.toNow = toNow;
      proto.get = stringGet;
      proto.invalidAt = invalidAt;
      proto.isAfter = isAfter;
      proto.isBefore = isBefore;
      proto.isBetween = isBetween;
      proto.isSame = isSame;
      proto.isSameOrAfter = isSameOrAfter;
      proto.isSameOrBefore = isSameOrBefore;
      proto.isValid = isValid$2;
      proto.lang = lang;
      proto.locale = locale;
      proto.localeData = localeData;
      proto.max = prototypeMax;
      proto.min = prototypeMin;
      proto.parsingFlags = parsingFlags;
      proto.set = stringSet;
      proto.startOf = startOf;
      proto.subtract = subtract;
      proto.toArray = toArray;
      proto.toObject = toObject;
      proto.toDate = toDate;
      proto.toISOString = toISOString;
      proto.inspect = inspect;
      if (typeof Symbol !== 'undefined' && Symbol.for != null) {
          proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
              return 'Moment<' + this.format() + '>';
          };
      }
      proto.toJSON = toJSON;
      proto.toString = toString;
      proto.unix = unix;
      proto.valueOf = valueOf;
      proto.creationData = creationData;
      proto.eraName = getEraName;
      proto.eraNarrow = getEraNarrow;
      proto.eraAbbr = getEraAbbr;
      proto.eraYear = getEraYear;
      proto.year = getSetYear;
      proto.isLeapYear = getIsLeapYear;
      proto.weekYear = getSetWeekYear;
      proto.isoWeekYear = getSetISOWeekYear;
      proto.quarter = proto.quarters = getSetQuarter;
      proto.month = getSetMonth;
      proto.daysInMonth = getDaysInMonth;
      proto.week = proto.weeks = getSetWeek;
      proto.isoWeek = proto.isoWeeks = getSetISOWeek;
      proto.weeksInYear = getWeeksInYear;
      proto.weeksInWeekYear = getWeeksInWeekYear;
      proto.isoWeeksInYear = getISOWeeksInYear;
      proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
      proto.date = getSetDayOfMonth;
      proto.day = proto.days = getSetDayOfWeek;
      proto.weekday = getSetLocaleDayOfWeek;
      proto.isoWeekday = getSetISODayOfWeek;
      proto.dayOfYear = getSetDayOfYear;
      proto.hour = proto.hours = getSetHour;
      proto.minute = proto.minutes = getSetMinute;
      proto.second = proto.seconds = getSetSecond;
      proto.millisecond = proto.milliseconds = getSetMillisecond;
      proto.utcOffset = getSetOffset;
      proto.utc = setOffsetToUTC;
      proto.local = setOffsetToLocal;
      proto.parseZone = setOffsetToParsedOffset;
      proto.hasAlignedHourOffset = hasAlignedHourOffset;
      proto.isDST = isDaylightSavingTime;
      proto.isLocal = isLocal;
      proto.isUtcOffset = isUtcOffset;
      proto.isUtc = isUtc;
      proto.isUTC = isUtc;
      proto.zoneAbbr = getZoneAbbr;
      proto.zoneName = getZoneName;
      proto.dates = deprecate(
          'dates accessor is deprecated. Use date instead.',
          getSetDayOfMonth
      );
      proto.months = deprecate(
          'months accessor is deprecated. Use month instead',
          getSetMonth
      );
      proto.years = deprecate(
          'years accessor is deprecated. Use year instead',
          getSetYear
      );
      proto.zone = deprecate(
          'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
          getSetZone
      );
      proto.isDSTShifted = deprecate(
          'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
          isDaylightSavingTimeShifted
      );
  
      function createUnix(input) {
          return createLocal(input * 1000);
      }
  
      function createInZone() {
          return createLocal.apply(null, arguments).parseZone();
      }
  
      function preParsePostFormat(string) {
          return string;
      }
  
      var proto$1 = Locale.prototype;
  
      proto$1.calendar = calendar;
      proto$1.longDateFormat = longDateFormat;
      proto$1.invalidDate = invalidDate;
      proto$1.ordinal = ordinal;
      proto$1.preparse = preParsePostFormat;
      proto$1.postformat = preParsePostFormat;
      proto$1.relativeTime = relativeTime;
      proto$1.pastFuture = pastFuture;
      proto$1.set = set;
      proto$1.eras = localeEras;
      proto$1.erasParse = localeErasParse;
      proto$1.erasConvertYear = localeErasConvertYear;
      proto$1.erasAbbrRegex = erasAbbrRegex;
      proto$1.erasNameRegex = erasNameRegex;
      proto$1.erasNarrowRegex = erasNarrowRegex;
  
      proto$1.months = localeMonths;
      proto$1.monthsShort = localeMonthsShort;
      proto$1.monthsParse = localeMonthsParse;
      proto$1.monthsRegex = monthsRegex;
      proto$1.monthsShortRegex = monthsShortRegex;
      proto$1.week = localeWeek;
      proto$1.firstDayOfYear = localeFirstDayOfYear;
      proto$1.firstDayOfWeek = localeFirstDayOfWeek;
  
      proto$1.weekdays = localeWeekdays;
      proto$1.weekdaysMin = localeWeekdaysMin;
      proto$1.weekdaysShort = localeWeekdaysShort;
      proto$1.weekdaysParse = localeWeekdaysParse;
  
      proto$1.weekdaysRegex = weekdaysRegex;
      proto$1.weekdaysShortRegex = weekdaysShortRegex;
      proto$1.weekdaysMinRegex = weekdaysMinRegex;
  
      proto$1.isPM = localeIsPM;
      proto$1.meridiem = localeMeridiem;
  
      function get$1(format, index, field, setter) {
          var locale = getLocale(),
              utc = createUTC().set(setter, index);
          return locale[field](utc, format);
      }
  
      function listMonthsImpl(format, index, field) {
          if (isNumber(format)) {
              index = format;
              format = undefined;
          }
  
          format = format || '';
  
          if (index != null) {
              return get$1(format, index, field, 'month');
          }
  
          var i,
              out = [];
          for (i = 0; i < 12; i++) {
              out[i] = get$1(format, i, field, 'month');
          }
          return out;
      }
  
      // ()
      // (5)
      // (fmt, 5)
      // (fmt)
      // (true)
      // (true, 5)
      // (true, fmt, 5)
      // (true, fmt)
      function listWeekdaysImpl(localeSorted, format, index, field) {
          if (typeof localeSorted === 'boolean') {
              if (isNumber(format)) {
                  index = format;
                  format = undefined;
              }
  
              format = format || '';
          } else {
              format = localeSorted;
              index = format;
              localeSorted = false;
  
              if (isNumber(format)) {
                  index = format;
                  format = undefined;
              }
  
              format = format || '';
          }
  
          var locale = getLocale(),
              shift = localeSorted ? locale._week.dow : 0,
              i,
              out = [];
  
          if (index != null) {
              return get$1(format, (index + shift) % 7, field, 'day');
          }
  
          for (i = 0; i < 7; i++) {
              out[i] = get$1(format, (i + shift) % 7, field, 'day');
          }
          return out;
      }
  
      function listMonths(format, index) {
          return listMonthsImpl(format, index, 'months');
      }
  
      function listMonthsShort(format, index) {
          return listMonthsImpl(format, index, 'monthsShort');
      }
  
      function listWeekdays(localeSorted, format, index) {
          return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
      }
  
      function listWeekdaysShort(localeSorted, format, index) {
          return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
      }
  
      function listWeekdaysMin(localeSorted, format, index) {
          return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
      }
  
      getSetGlobalLocale('en', {
          eras: [
              {
                  since: '0001-01-01',
                  until: +Infinity,
                  offset: 1,
                  name: 'Anno Domini',
                  narrow: 'AD',
                  abbr: 'AD',
              },
              {
                  since: '0000-12-31',
                  until: -Infinity,
                  offset: 1,
                  name: 'Before Christ',
                  narrow: 'BC',
                  abbr: 'BC',
              },
          ],
          dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
          ordinal: function (number) {
              var b = number % 10,
                  output =
                      toInt((number % 100) / 10) === 1
                          ? 'th'
                          : b === 1
                          ? 'st'
                          : b === 2
                          ? 'nd'
                          : b === 3
                          ? 'rd'
                          : 'th';
              return number + output;
          },
      });
  
      // Side effect imports
  
      hooks.lang = deprecate(
          'moment.lang is deprecated. Use moment.locale instead.',
          getSetGlobalLocale
      );
      hooks.langData = deprecate(
          'moment.langData is deprecated. Use moment.localeData instead.',
          getLocale
      );
  
      var mathAbs = Math.abs;
  
      function abs() {
          var data = this._data;
  
          this._milliseconds = mathAbs(this._milliseconds);
          this._days = mathAbs(this._days);
          this._months = mathAbs(this._months);
  
          data.milliseconds = mathAbs(data.milliseconds);
          data.seconds = mathAbs(data.seconds);
          data.minutes = mathAbs(data.minutes);
          data.hours = mathAbs(data.hours);
          data.months = mathAbs(data.months);
          data.years = mathAbs(data.years);
  
          return this;
      }
  
      function addSubtract$1(duration, input, value, direction) {
          var other = createDuration(input, value);
  
          duration._milliseconds += direction * other._milliseconds;
          duration._days += direction * other._days;
          duration._months += direction * other._months;
  
          return duration._bubble();
      }
  
      // supports only 2.0-style add(1, 's') or add(duration)
      function add$1(input, value) {
          return addSubtract$1(this, input, value, 1);
      }
  
      // supports only 2.0-style subtract(1, 's') or subtract(duration)
      function subtract$1(input, value) {
          return addSubtract$1(this, input, value, -1);
      }
  
      function absCeil(number) {
          if (number < 0) {
              return Math.floor(number);
          } else {
              return Math.ceil(number);
          }
      }
  
      function bubble() {
          var milliseconds = this._milliseconds,
              days = this._days,
              months = this._months,
              data = this._data,
              seconds,
              minutes,
              hours,
              years,
              monthsFromDays;
  
          // if we have a mix of positive and negative values, bubble down first
          // check: https://github.com/moment/moment/issues/2166
          if (
              !(
                  (milliseconds >= 0 && days >= 0 && months >= 0) ||
                  (milliseconds <= 0 && days <= 0 && months <= 0)
              )
          ) {
              milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
              days = 0;
              months = 0;
          }
  
          // The following code bubbles up values, see the tests for
          // examples of what that means.
          data.milliseconds = milliseconds % 1000;
  
          seconds = absFloor(milliseconds / 1000);
          data.seconds = seconds % 60;
  
          minutes = absFloor(seconds / 60);
          data.minutes = minutes % 60;
  
          hours = absFloor(minutes / 60);
          data.hours = hours % 24;
  
          days += absFloor(hours / 24);
  
          // convert days to months
          monthsFromDays = absFloor(daysToMonths(days));
          months += monthsFromDays;
          days -= absCeil(monthsToDays(monthsFromDays));
  
          // 12 months -> 1 year
          years = absFloor(months / 12);
          months %= 12;
  
          data.days = days;
          data.months = months;
          data.years = years;
  
          return this;
      }
  
      function daysToMonths(days) {
          // 400 years have 146097 days (taking into account leap year rules)
          // 400 years have 12 months === 4800
          return (days * 4800) / 146097;
      }
  
      function monthsToDays(months) {
          // the reverse of daysToMonths
          return (months * 146097) / 4800;
      }
  
      function as(units) {
          if (!this.isValid()) {
              return NaN;
          }
          var days,
              months,
              milliseconds = this._milliseconds;
  
          units = normalizeUnits(units);
  
          if (units === 'month' || units === 'quarter' || units === 'year') {
              days = this._days + milliseconds / 864e5;
              months = this._months + daysToMonths(days);
              switch (units) {
                  case 'month':
                      return months;
                  case 'quarter':
                      return months / 3;
                  case 'year':
                      return months / 12;
              }
          } else {
              // handle milliseconds separately because of floating point math errors (issue #1867)
              days = this._days + Math.round(monthsToDays(this._months));
              switch (units) {
                  case 'week':
                      return days / 7 + milliseconds / 6048e5;
                  case 'day':
                      return days + milliseconds / 864e5;
                  case 'hour':
                      return days * 24 + milliseconds / 36e5;
                  case 'minute':
                      return days * 1440 + milliseconds / 6e4;
                  case 'second':
                      return days * 86400 + milliseconds / 1000;
                  // Math.floor prevents floating point math errors here
                  case 'millisecond':
                      return Math.floor(days * 864e5) + milliseconds;
                  default:
                      throw new Error('Unknown unit ' + units);
              }
          }
      }
  
      // TODO: Use this.as('ms')?
      function valueOf$1() {
          if (!this.isValid()) {
              return NaN;
          }
          return (
              this._milliseconds +
              this._days * 864e5 +
              (this._months % 12) * 2592e6 +
              toInt(this._months / 12) * 31536e6
          );
      }
  
      function makeAs(alias) {
          return function () {
              return this.as(alias);
          };
      }
  
      var asMilliseconds = makeAs('ms'),
          asSeconds = makeAs('s'),
          asMinutes = makeAs('m'),
          asHours = makeAs('h'),
          asDays = makeAs('d'),
          asWeeks = makeAs('w'),
          asMonths = makeAs('M'),
          asQuarters = makeAs('Q'),
          asYears = makeAs('y');
  
      function clone$1() {
          return createDuration(this);
      }
  
      function get$2(units) {
          units = normalizeUnits(units);
          return this.isValid() ? this[units + 's']() : NaN;
      }
  
      function makeGetter(name) {
          return function () {
              return this.isValid() ? this._data[name] : NaN;
          };
      }
  
      var milliseconds = makeGetter('milliseconds'),
          seconds = makeGetter('seconds'),
          minutes = makeGetter('minutes'),
          hours = makeGetter('hours'),
          days = makeGetter('days'),
          months = makeGetter('months'),
          years = makeGetter('years');
  
      function weeks() {
          return absFloor(this.days() / 7);
      }
  
      var round = Math.round,
          thresholds = {
              ss: 44, // a few seconds to seconds
              s: 45, // seconds to minute
              m: 45, // minutes to hour
              h: 22, // hours to day
              d: 26, // days to month/week
              w: null, // weeks to month
              M: 11, // months to year
          };
  
      // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
      function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
          return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
      }
  
      function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
          var duration = createDuration(posNegDuration).abs(),
              seconds = round(duration.as('s')),
              minutes = round(duration.as('m')),
              hours = round(duration.as('h')),
              days = round(duration.as('d')),
              months = round(duration.as('M')),
              weeks = round(duration.as('w')),
              years = round(duration.as('y')),
              a =
                  (seconds <= thresholds.ss && ['s', seconds]) ||
                  (seconds < thresholds.s && ['ss', seconds]) ||
                  (minutes <= 1 && ['m']) ||
                  (minutes < thresholds.m && ['mm', minutes]) ||
                  (hours <= 1 && ['h']) ||
                  (hours < thresholds.h && ['hh', hours]) ||
                  (days <= 1 && ['d']) ||
                  (days < thresholds.d && ['dd', days]);
  
          if (thresholds.w != null) {
              a =
                  a ||
                  (weeks <= 1 && ['w']) ||
                  (weeks < thresholds.w && ['ww', weeks]);
          }
          a = a ||
              (months <= 1 && ['M']) ||
              (months < thresholds.M && ['MM', months]) ||
              (years <= 1 && ['y']) || ['yy', years];
  
          a[2] = withoutSuffix;
          a[3] = +posNegDuration > 0;
          a[4] = locale;
          return substituteTimeAgo.apply(null, a);
      }
  
      // This function allows you to set the rounding function for relative time strings
      function getSetRelativeTimeRounding(roundingFunction) {
          if (roundingFunction === undefined) {
              return round;
          }
          if (typeof roundingFunction === 'function') {
              round = roundingFunction;
              return true;
          }
          return false;
      }
  
      // This function allows you to set a threshold for relative time strings
      function getSetRelativeTimeThreshold(threshold, limit) {
          if (thresholds[threshold] === undefined) {
              return false;
          }
          if (limit === undefined) {
              return thresholds[threshold];
          }
          thresholds[threshold] = limit;
          if (threshold === 's') {
              thresholds.ss = limit - 1;
          }
          return true;
      }
  
      function humanize(argWithSuffix, argThresholds) {
          if (!this.isValid()) {
              return this.localeData().invalidDate();
          }
  
          var withSuffix = false,
              th = thresholds,
              locale,
              output;
  
          if (typeof argWithSuffix === 'object') {
              argThresholds = argWithSuffix;
              argWithSuffix = false;
          }
          if (typeof argWithSuffix === 'boolean') {
              withSuffix = argWithSuffix;
          }
          if (typeof argThresholds === 'object') {
              th = Object.assign({}, thresholds, argThresholds);
              if (argThresholds.s != null && argThresholds.ss == null) {
                  th.ss = argThresholds.s - 1;
              }
          }
  
          locale = this.localeData();
          output = relativeTime$1(this, !withSuffix, th, locale);
  
          if (withSuffix) {
              output = locale.pastFuture(+this, output);
          }
  
          return locale.postformat(output);
      }
  
      var abs$1 = Math.abs;
  
      function sign(x) {
          return (x > 0) - (x < 0) || +x;
      }
  
      function toISOString$1() {
          // for ISO strings we do not use the normal bubbling rules:
          //  * milliseconds bubble up until they become hours
          //  * days do not bubble at all
          //  * months bubble up until they become years
          // This is because there is no context-free conversion between hours and days
          // (think of clock changes)
          // and also not between days and months (28-31 days per month)
          if (!this.isValid()) {
              return this.localeData().invalidDate();
          }
  
          var seconds = abs$1(this._milliseconds) / 1000,
              days = abs$1(this._days),
              months = abs$1(this._months),
              minutes,
              hours,
              years,
              s,
              total = this.asSeconds(),
              totalSign,
              ymSign,
              daysSign,
              hmsSign;
  
          if (!total) {
              // this is the same as C#'s (Noda) and python (isodate)...
              // but not other JS (goog.date)
              return 'P0D';
          }
  
          // 3600 seconds -> 60 minutes -> 1 hour
          minutes = absFloor(seconds / 60);
          hours = absFloor(minutes / 60);
          seconds %= 60;
          minutes %= 60;
  
          // 12 months -> 1 year
          years = absFloor(months / 12);
          months %= 12;
  
          // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
          s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
  
          totalSign = total < 0 ? '-' : '';
          ymSign = sign(this._months) !== sign(total) ? '-' : '';
          daysSign = sign(this._days) !== sign(total) ? '-' : '';
          hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
  
          return (
              totalSign +
              'P' +
              (years ? ymSign + years + 'Y' : '') +
              (months ? ymSign + months + 'M' : '') +
              (days ? daysSign + days + 'D' : '') +
              (hours || minutes || seconds ? 'T' : '') +
              (hours ? hmsSign + hours + 'H' : '') +
              (minutes ? hmsSign + minutes + 'M' : '') +
              (seconds ? hmsSign + s + 'S' : '')
          );
      }
  
      var proto$2 = Duration.prototype;
  
      proto$2.isValid = isValid$1;
      proto$2.abs = abs;
      proto$2.add = add$1;
      proto$2.subtract = subtract$1;
      proto$2.as = as;
      proto$2.asMilliseconds = asMilliseconds;
      proto$2.asSeconds = asSeconds;
      proto$2.asMinutes = asMinutes;
      proto$2.asHours = asHours;
      proto$2.asDays = asDays;
      proto$2.asWeeks = asWeeks;
      proto$2.asMonths = asMonths;
      proto$2.asQuarters = asQuarters;
      proto$2.asYears = asYears;
      proto$2.valueOf = valueOf$1;
      proto$2._bubble = bubble;
      proto$2.clone = clone$1;
      proto$2.get = get$2;
      proto$2.milliseconds = milliseconds;
      proto$2.seconds = seconds;
      proto$2.minutes = minutes;
      proto$2.hours = hours;
      proto$2.days = days;
      proto$2.weeks = weeks;
      proto$2.months = months;
      proto$2.years = years;
      proto$2.humanize = humanize;
      proto$2.toISOString = toISOString$1;
      proto$2.toString = toISOString$1;
      proto$2.toJSON = toISOString$1;
      proto$2.locale = locale;
      proto$2.localeData = localeData;
  
      proto$2.toIsoString = deprecate(
          'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
          toISOString$1
      );
      proto$2.lang = lang;
  
      // FORMATTING
  
      addFormatToken('X', 0, 0, 'unix');
      addFormatToken('x', 0, 0, 'valueOf');
  
      // PARSING
  
      addRegexToken('x', matchSigned);
      addRegexToken('X', matchTimestamp);
      addParseToken('X', function (input, array, config) {
          config._d = new Date(parseFloat(input) * 1000);
      });
      addParseToken('x', function (input, array, config) {
          config._d = new Date(toInt(input));
      });
  
      //! moment.js
  
      hooks.version = '2.27.0';
  
      setHookCallback(createLocal);
  
      hooks.fn = proto;
      hooks.min = min;
      hooks.max = max;
      hooks.now = now;
      hooks.utc = createUTC;
      hooks.unix = createUnix;
      hooks.months = listMonths;
      hooks.isDate = isDate;
      hooks.locale = getSetGlobalLocale;
      hooks.invalid = createInvalid;
      hooks.duration = createDuration;
      hooks.isMoment = isMoment;
      hooks.weekdays = listWeekdays;
      hooks.parseZone = createInZone;
      hooks.localeData = getLocale;
      hooks.isDuration = isDuration;
      hooks.monthsShort = listMonthsShort;
      hooks.weekdaysMin = listWeekdaysMin;
      hooks.defineLocale = defineLocale;
      hooks.updateLocale = updateLocale;
      hooks.locales = listLocales;
      hooks.weekdaysShort = listWeekdaysShort;
      hooks.normalizeUnits = normalizeUnits;
      hooks.relativeTimeRounding = getSetRelativeTimeRounding;
      hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
      hooks.calendarFormat = getCalendarFormat;
      hooks.prototype = proto;
  
      // currently HTML5 input type only supports 24-hour formats
      hooks.HTML5_FMT = {
          DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
          DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
          DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
          DATE: 'YYYY-MM-DD', // <input type="date" />
          TIME: 'HH:mm', // <input type="time" />
          TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
          TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
          WEEK: 'GGGG-[W]WW', // <input type="week" />
          MONTH: 'YYYY-MM', // <input type="month" />
      };
  
      return hooks;
  
  })));
  
  //! moment.js locale configuration
  //! locale : German [de]
  //! author : lluchs : https://github.com/lluchs
  //! author: Menelion Elensúle: https://github.com/Oire
  //! author : Mikolaj Dadela : https://github.com/mik01aj
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      function processRelativeTime(number, withoutSuffix, key, isFuture) {
          var format = {
              m: ['eine Minute', 'einer Minute'],
              h: ['eine Stunde', 'einer Stunde'],
              d: ['ein Tag', 'einem Tag'],
              dd: [number + ' Tage', number + ' Tagen'],
              w: ['eine Woche', 'einer Woche'],
              M: ['ein Monat', 'einem Monat'],
              MM: [number + ' Monate', number + ' Monaten'],
              y: ['ein Jahr', 'einem Jahr'],
              yy: [number + ' Jahre', number + ' Jahren'],
          };
          return withoutSuffix ? format[key][0] : format[key][1];
      }
  
      var de = moment.defineLocale('de', {
          months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
              '_'
          ),
          monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
              '_'
          ),
          monthsParseExact: true,
          weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
              '_'
          ),
          weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
          weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
          weekdaysParseExact: true,
          longDateFormat: {
              LT: 'HH:mm',
              LTS: 'HH:mm:ss',
              L: 'DD.MM.YYYY',
              LL: 'D. MMMM YYYY',
              LLL: 'D. MMMM YYYY HH:mm',
              LLLL: 'dddd, D. MMMM YYYY HH:mm',
          },
          calendar: {
              sameDay: '[heute um] LT [Uhr]',
              sameElse: 'L',
              nextDay: '[morgen um] LT [Uhr]',
              nextWeek: 'dddd [um] LT [Uhr]',
              lastDay: '[gestern um] LT [Uhr]',
              lastWeek: '[letzten] dddd [um] LT [Uhr]',
          },
          relativeTime: {
              future: 'in %s',
              past: 'vor %s',
              s: 'ein paar Sekunden',
              ss: '%d Sekunden',
              m: processRelativeTime,
              mm: '%d Minuten',
              h: processRelativeTime,
              hh: '%d Stunden',
              d: processRelativeTime,
              dd: processRelativeTime,
              w: processRelativeTime,
              ww: '%d Wochen',
              M: processRelativeTime,
              MM: processRelativeTime,
              y: processRelativeTime,
              yy: processRelativeTime,
          },
          dayOfMonthOrdinalParse: /\d{1,2}\./,
          ordinal: '%d.',
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 4, // The week that contains Jan 4th is the first week of the year.
          },
      });
  
      return de;
  
  })));
  
  //! moment.js locale configuration
  //! locale : Spanish [es]
  //! author : Julio Napurí : https://github.com/julionc
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
              '_'
          ),
          monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
          monthsParse = [
              /^ene/i,
              /^feb/i,
              /^mar/i,
              /^abr/i,
              /^may/i,
              /^jun/i,
              /^jul/i,
              /^ago/i,
              /^sep/i,
              /^oct/i,
              /^nov/i,
              /^dic/i,
          ],
          monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
  
      var es = moment.defineLocale('es', {
          months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
              '_'
          ),
          monthsShort: function (m, format) {
              if (!m) {
                  return monthsShortDot;
              } else if (/-MMM-/.test(format)) {
                  return monthsShort[m.month()];
              } else {
                  return monthsShortDot[m.month()];
              }
          },
          monthsRegex: monthsRegex,
          monthsShortRegex: monthsRegex,
          monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
          monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
          monthsParse: monthsParse,
          longMonthsParse: monthsParse,
          shortMonthsParse: monthsParse,
          weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
          weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
          weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
          weekdaysParseExact: true,
          longDateFormat: {
              LT: 'H:mm',
              LTS: 'H:mm:ss',
              L: 'DD/MM/YYYY',
              LL: 'D [de] MMMM [de] YYYY',
              LLL: 'D [de] MMMM [de] YYYY H:mm',
              LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
          },
          calendar: {
              sameDay: function () {
                  return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
              },
              nextDay: function () {
                  return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
              },
              nextWeek: function () {
                  return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
              },
              lastDay: function () {
                  return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
              },
              lastWeek: function () {
                  return (
                      '[el] dddd [pasado a la' +
                      (this.hours() !== 1 ? 's' : '') +
                      '] LT'
                  );
              },
              sameElse: 'L',
          },
          relativeTime: {
              future: 'en %s',
              past: 'hace %s',
              s: 'unos segundos',
              ss: '%d segundos',
              m: 'un minuto',
              mm: '%d minutos',
              h: 'una hora',
              hh: '%d horas',
              d: 'un día',
              dd: '%d días',
              M: 'un mes',
              MM: '%d meses',
              y: 'un año',
              yy: '%d años',
          },
          dayOfMonthOrdinalParse: /\d{1,2}º/,
          ordinal: '%dº',
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 4, // The week that contains Jan 4th is the first week of the year.
          },
          invalidDate: 'Fecha invalida',
      });
  
      return es;
  
  })));
  
  //! moment.js locale configuration
  //! locale : Finnish [fi]
  //! author : Tarmo Aidantausta : https://github.com/bleadof
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(
              ' '
          ),
          numbersFuture = [
              'nolla',
              'yhden',
              'kahden',
              'kolmen',
              'neljän',
              'viiden',
              'kuuden',
              numbersPast[7],
              numbersPast[8],
              numbersPast[9],
          ];
      function translate(number, withoutSuffix, key, isFuture) {
          var result = '';
          switch (key) {
              case 's':
                  return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
              case 'ss':
                  result = isFuture ? 'sekunnin' : 'sekuntia';
                  break;
              case 'm':
                  return isFuture ? 'minuutin' : 'minuutti';
              case 'mm':
                  result = isFuture ? 'minuutin' : 'minuuttia';
                  break;
              case 'h':
                  return isFuture ? 'tunnin' : 'tunti';
              case 'hh':
                  result = isFuture ? 'tunnin' : 'tuntia';
                  break;
              case 'd':
                  return isFuture ? 'päivän' : 'päivä';
              case 'dd':
                  result = isFuture ? 'päivän' : 'päivää';
                  break;
              case 'M':
                  return isFuture ? 'kuukauden' : 'kuukausi';
              case 'MM':
                  result = isFuture ? 'kuukauden' : 'kuukautta';
                  break;
              case 'y':
                  return isFuture ? 'vuoden' : 'vuosi';
              case 'yy':
                  result = isFuture ? 'vuoden' : 'vuotta';
                  break;
          }
          result = verbalNumber(number, isFuture) + ' ' + result;
          return result;
      }
      function verbalNumber(number, isFuture) {
          return number < 10
              ? isFuture
                  ? numbersFuture[number]
                  : numbersPast[number]
              : number;
      }
  
      var fi = moment.defineLocale('fi', {
          months: 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split(
              '_'
          ),
          monthsShort: 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split(
              '_'
          ),
          weekdays: 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split(
              '_'
          ),
          weekdaysShort: 'su_ma_ti_ke_to_pe_la'.split('_'),
          weekdaysMin: 'su_ma_ti_ke_to_pe_la'.split('_'),
          longDateFormat: {
              LT: 'HH.mm',
              LTS: 'HH.mm.ss',
              L: 'DD.MM.YYYY',
              LL: 'Do MMMM[ta] YYYY',
              LLL: 'Do MMMM[ta] YYYY, [klo] HH.mm',
              LLLL: 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
              l: 'D.M.YYYY',
              ll: 'Do MMM YYYY',
              lll: 'Do MMM YYYY, [klo] HH.mm',
              llll: 'ddd, Do MMM YYYY, [klo] HH.mm',
          },
          calendar: {
              sameDay: '[tänään] [klo] LT',
              nextDay: '[huomenna] [klo] LT',
              nextWeek: 'dddd [klo] LT',
              lastDay: '[eilen] [klo] LT',
              lastWeek: '[viime] dddd[na] [klo] LT',
              sameElse: 'L',
          },
          relativeTime: {
              future: '%s päästä',
              past: '%s sitten',
              s: translate,
              ss: translate,
              m: translate,
              mm: translate,
              h: translate,
              hh: translate,
              d: translate,
              dd: translate,
              M: translate,
              MM: translate,
              y: translate,
              yy: translate,
          },
          dayOfMonthOrdinalParse: /\d{1,2}\./,
          ordinal: '%d.',
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 4, // The week that contains Jan 4th is the first week of the year.
          },
      });
  
      return fi;
  
  })));
  
  //! moment.js locale configuration
  //! locale : French [fr]
  //! author : John Fischer : https://github.com/jfroffice
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      var monthsStrictRegex = /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
          monthsShortStrictRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,
          monthsRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
          monthsParse = [
              /^janv/i,
              /^févr/i,
              /^mars/i,
              /^avr/i,
              /^mai/i,
              /^juin/i,
              /^juil/i,
              /^août/i,
              /^sept/i,
              /^oct/i,
              /^nov/i,
              /^déc/i,
          ];
  
      var fr = moment.defineLocale('fr', {
          months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
              '_'
          ),
          monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
              '_'
          ),
          monthsRegex: monthsRegex,
          monthsShortRegex: monthsRegex,
          monthsStrictRegex: monthsStrictRegex,
          monthsShortStrictRegex: monthsShortStrictRegex,
          monthsParse: monthsParse,
          longMonthsParse: monthsParse,
          shortMonthsParse: monthsParse,
          weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
          weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
          weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
          weekdaysParseExact: true,
          longDateFormat: {
              LT: 'HH:mm',
              LTS: 'HH:mm:ss',
              L: 'DD/MM/YYYY',
              LL: 'D MMMM YYYY',
              LLL: 'D MMMM YYYY HH:mm',
              LLLL: 'dddd D MMMM YYYY HH:mm',
          },
          calendar: {
              sameDay: '[Aujourd’hui à] LT',
              nextDay: '[Demain à] LT',
              nextWeek: 'dddd [à] LT',
              lastDay: '[Hier à] LT',
              lastWeek: 'dddd [dernier à] LT',
              sameElse: 'L',
          },
          relativeTime: {
              future: 'dans %s',
              past: 'il y a %s',
              s: 'quelques secondes',
              ss: '%d secondes',
              m: 'une minute',
              mm: '%d minutes',
              h: 'une heure',
              hh: '%d heures',
              d: 'un jour',
              dd: '%d jours',
              M: 'un mois',
              MM: '%d mois',
              y: 'un an',
              yy: '%d ans',
          },
          dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
          ordinal: function (number, period) {
              switch (period) {
                  // TODO: Return 'e' when day of month > 1. Move this case inside
                  // block for masculine words below.
                  // See https://github.com/moment/moment/issues/3375
                  case 'D':
                      return number + (number === 1 ? 'er' : '');
  
                  // Words with masculine grammatical gender: mois, trimestre, jour
                  default:
                  case 'M':
                  case 'Q':
                  case 'DDD':
                  case 'd':
                      return number + (number === 1 ? 'er' : 'e');
  
                  // Words with feminine grammatical gender: semaine
                  case 'w':
                  case 'W':
                      return number + (number === 1 ? 're' : 'e');
              }
          },
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 4, // The week that contains Jan 4th is the first week of the year.
          },
      });
  
      return fr;
  
  })));
  
  //! moment.js locale configuration
  //! locale : Swedish [sv]
  //! author : Jens Alm : https://github.com/ulmus
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      var sv = moment.defineLocale('sv', {
          months: 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split(
              '_'
          ),
          monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
          weekdays: 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
          weekdaysShort: 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
          weekdaysMin: 'sö_må_ti_on_to_fr_lö'.split('_'),
          longDateFormat: {
              LT: 'HH:mm',
              LTS: 'HH:mm:ss',
              L: 'YYYY-MM-DD',
              LL: 'D MMMM YYYY',
              LLL: 'D MMMM YYYY [kl.] HH:mm',
              LLLL: 'dddd D MMMM YYYY [kl.] HH:mm',
              lll: 'D MMM YYYY HH:mm',
              llll: 'ddd D MMM YYYY HH:mm',
          },
          calendar: {
              sameDay: '[Idag] LT',
              nextDay: '[Imorgon] LT',
              lastDay: '[Igår] LT',
              nextWeek: '[På] dddd LT',
              lastWeek: '[I] dddd[s] LT',
              sameElse: 'L',
          },
          relativeTime: {
              future: 'om %s',
              past: 'för %s sedan',
              s: 'några sekunder',
              ss: '%d sekunder',
              m: 'en minut',
              mm: '%d minuter',
              h: 'en timme',
              hh: '%d timmar',
              d: 'en dag',
              dd: '%d dagar',
              M: 'en månad',
              MM: '%d månader',
              y: 'ett år',
              yy: '%d år',
          },
          dayOfMonthOrdinalParse: /\d{1,2}(\:e|\:a)/,
          ordinal: function (number) {
              var b = number % 10,
                  output =
                      ~~((number % 100) / 10) === 1
                          ? ':e'
                          : b === 1
                          ? ':a'
                          : b === 2
                          ? ':a'
                          : b === 3
                          ? ':e'
                          : ':e';
              return number + output;
          },
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 4, // The week that contains Jan 4th is the first week of the year.
          },
      });
  
      return sv;
  
  })));
  
  //! moment.js locale configuration
  //! locale : Turkish [tr]
  //! authors : Erhan Gundogan : https://github.com/erhangundogan,
  //!           Burak Yiğit Kaya: https://github.com/BYK
  
  ;(function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined'
         && typeof require === 'function' ? factory(require('../moment')) :
     typeof define === 'function' && define.amd ? define(['../moment'], factory) :
     factory(global.moment)
  }(this, (function (moment) { 'use strict';
  
      //! moment.js locale configuration
  
      var suffixes = {
          1: "'inci",
          5: "'inci",
          8: "'inci",
          70: "'inci",
          80: "'inci",
          2: "'nci",
          7: "'nci",
          20: "'nci",
          50: "'nci",
          3: "'üncü",
          4: "'üncü",
          100: "'üncü",
          6: "'ncı",
          9: "'uncu",
          10: "'uncu",
          30: "'uncu",
          60: "'ıncı",
          90: "'ıncı",
      };
  
      var tr = moment.defineLocale('tr', {
          months: 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split(
              '_'
          ),
          monthsShort: 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
          weekdays: 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split(
              '_'
          ),
          weekdaysShort: 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
          weekdaysMin: 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
          meridiem: function (hours, minutes, isLower) {
              if (hours < 12) {
                  return isLower ? 'öö' : 'ÖÖ';
              } else {
                  return isLower ? 'ös' : 'ÖS';
              }
          },
          meridiemParse: /öö|ÖÖ|ös|ÖS/,
          isPM: function (input) {
              return input === 'ös' || input === 'ÖS';
          },
          longDateFormat: {
              LT: 'HH:mm',
              LTS: 'HH:mm:ss',
              L: 'DD.MM.YYYY',
              LL: 'D MMMM YYYY',
              LLL: 'D MMMM YYYY HH:mm',
              LLLL: 'dddd, D MMMM YYYY HH:mm',
          },
          calendar: {
              sameDay: '[bugün saat] LT',
              nextDay: '[yarın saat] LT',
              nextWeek: '[gelecek] dddd [saat] LT',
              lastDay: '[dün] LT',
              lastWeek: '[geçen] dddd [saat] LT',
              sameElse: 'L',
          },
          relativeTime: {
              future: '%s sonra',
              past: '%s önce',
              s: 'birkaç saniye',
              ss: '%d saniye',
              m: 'bir dakika',
              mm: '%d dakika',
              h: 'bir saat',
              hh: '%d saat',
              d: 'bir gün',
              dd: '%d gün',
              M: 'bir ay',
              MM: '%d ay',
              y: 'bir yıl',
              yy: '%d yıl',
          },
          ordinal: function (number, period) {
              switch (period) {
                  case 'd':
                  case 'D':
                  case 'Do':
                  case 'DD':
                      return number;
                  default:
                      if (number === 0) {
                          // special case for zero
                          return number + "'ıncı";
                      }
                      var a = number % 10,
                          b = (number % 100) - a,
                          c = number >= 100 ? 100 : null;
                      return number + (suffixes[a] || suffixes[b] || suffixes[c]);
              }
          },
          week: {
              dow: 1, // Monday is the first day of the week.
              doy: 7, // The week that contains Jan 7th is the first week of the year.
          },
      });
  
      return tr;
  
  })));
  
  //! moment-timezone.js
  //! version : 0.5.31
  //! Copyright (c) JS Foundation and other contributors
  //! license : MIT
  //! github.com/moment/moment-timezone
  
  (function (root, factory) {
  	"use strict";
  
  	/*global define*/
  	if (typeof module === 'object' && module.exports) {
  		module.exports = factory(require('moment')); // Node
  	} else if (typeof define === 'function' && define.amd) {
  		define(['moment'], factory);                 // AMD
  	} else {
  		factory(root.moment);                        // Browser
  	}
  }(this, function (moment) {
  	"use strict";
  
  	// Resolves es6 module loading issue
  	if (moment.version === undefined && moment.default) {
  		moment = moment.default;
  	}
  
  	// Do not load moment-timezone a second time.
  	// if (moment.tz !== undefined) {
  	// 	logError('Moment Timezone ' + moment.tz.version + ' was already loaded ' + (moment.tz.dataVersion ? 'with data from ' : 'without any data') + moment.tz.dataVersion);
  	// 	return moment;
  	// }
  
  	var VERSION = "0.5.31",
  		zones = {},
  		links = {},
  		countries = {},
  		names = {},
  		guesses = {},
  		cachedGuess;
  
  	if (!moment || typeof moment.version !== 'string') {
  		logError('Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/');
  	}
  
  	var momentVersion = moment.version.split('.'),
  		major = +momentVersion[0],
  		minor = +momentVersion[1];
  
  	// Moment.js version check
  	if (major < 2 || (major === 2 && minor < 6)) {
  		logError('Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js ' + moment.version + '. See momentjs.com');
  	}
  
  	/************************************
  		Unpacking
  	************************************/
  
  	function charCodeToInt(charCode) {
  		if (charCode > 96) {
  			return charCode - 87;
  		} else if (charCode > 64) {
  			return charCode - 29;
  		}
  		return charCode - 48;
  	}
  
  	function unpackBase60(string) {
  		var i = 0,
  			parts = string.split('.'),
  			whole = parts[0],
  			fractional = parts[1] || '',
  			multiplier = 1,
  			num,
  			out = 0,
  			sign = 1;
  
  		// handle negative numbers
  		if (string.charCodeAt(0) === 45) {
  			i = 1;
  			sign = -1;
  		}
  
  		// handle digits before the decimal
  		for (i; i < whole.length; i++) {
  			num = charCodeToInt(whole.charCodeAt(i));
  			out = 60 * out + num;
  		}
  
  		// handle digits after the decimal
  		for (i = 0; i < fractional.length; i++) {
  			multiplier = multiplier / 60;
  			num = charCodeToInt(fractional.charCodeAt(i));
  			out += num * multiplier;
  		}
  
  		return out * sign;
  	}
  
  	function arrayToInt (array) {
  		for (var i = 0; i < array.length; i++) {
  			array[i] = unpackBase60(array[i]);
  		}
  	}
  
  	function intToUntil (array, length) {
  		for (var i = 0; i < length; i++) {
  			array[i] = Math.round((array[i - 1] || 0) + (array[i] * 60000)); // minutes to milliseconds
  		}
  
  		array[length - 1] = Infinity;
  	}
  
  	function mapIndices (source, indices) {
  		var out = [], i;
  
  		for (i = 0; i < indices.length; i++) {
  			out[i] = source[indices[i]];
  		}
  
  		return out;
  	}
  
  	function unpack (string) {
  		var data = string.split('|'),
  			offsets = data[2].split(' '),
  			indices = data[3].split(''),
  			untils  = data[4].split(' ');
  
  		arrayToInt(offsets);
  		arrayToInt(indices);
  		arrayToInt(untils);
  
  		intToUntil(untils, indices.length);
  
  		return {
  			name       : data[0],
  			abbrs      : mapIndices(data[1].split(' '), indices),
  			offsets    : mapIndices(offsets, indices),
  			untils     : untils,
  			population : data[5] | 0
  		};
  	}
  
  	/************************************
  		Zone object
  	************************************/
  
  	function Zone (packedString) {
  		if (packedString) {
  			this._set(unpack(packedString));
  		}
  	}
  
  	Zone.prototype = {
  		_set : function (unpacked) {
  			this.name       = unpacked.name;
  			this.abbrs      = unpacked.abbrs;
  			this.untils     = unpacked.untils;
  			this.offsets    = unpacked.offsets;
  			this.population = unpacked.population;
  		},
  
  		_index : function (timestamp) {
  			var target = +timestamp,
  				untils = this.untils,
  				i;
  
  			for (i = 0; i < untils.length; i++) {
  				if (target < untils[i]) {
  					return i;
  				}
  			}
  		},
  
  		countries : function () {
  			var zone_name = this.name;
  			return Object.keys(countries).filter(function (country_code) {
  				return countries[country_code].zones.indexOf(zone_name) !== -1;
  			});
  		},
  
  		parse : function (timestamp) {
  			var target  = +timestamp,
  				offsets = this.offsets,
  				untils  = this.untils,
  				max     = untils.length - 1,
  				offset, offsetNext, offsetPrev, i;
  
  			for (i = 0; i < max; i++) {
  				offset     = offsets[i];
  				offsetNext = offsets[i + 1];
  				offsetPrev = offsets[i ? i - 1 : i];
  
  				if (offset < offsetNext && tz.moveAmbiguousForward) {
  					offset = offsetNext;
  				} else if (offset > offsetPrev && tz.moveInvalidForward) {
  					offset = offsetPrev;
  				}
  
  				if (target < untils[i] - (offset * 60000)) {
  					return offsets[i];
  				}
  			}
  
  			return offsets[max];
  		},
  
  		abbr : function (mom) {
  			return this.abbrs[this._index(mom)];
  		},
  
  		offset : function (mom) {
  			logError("zone.offset has been deprecated in favor of zone.utcOffset");
  			return this.offsets[this._index(mom)];
  		},
  
  		utcOffset : function (mom) {
  			return this.offsets[this._index(mom)];
  		}
  	};
  
  	/************************************
  		Country object
  	************************************/
  
  	function Country (country_name, zone_names) {
  		this.name = country_name;
  		this.zones = zone_names;
  	}
  
  	/************************************
  		Current Timezone
  	************************************/
  
  	function OffsetAt(at) {
  		var timeString = at.toTimeString();
  		var abbr = timeString.match(/\([a-z ]+\)/i);
  		if (abbr && abbr[0]) {
  			// 17:56:31 GMT-0600 (CST)
  			// 17:56:31 GMT-0600 (Central Standard Time)
  			abbr = abbr[0].match(/[A-Z]/g);
  			abbr = abbr ? abbr.join('') : undefined;
  		} else {
  			// 17:56:31 CST
  			// 17:56:31 GMT+0800 (台北標準時間)
  			abbr = timeString.match(/[A-Z]{3,5}/g);
  			abbr = abbr ? abbr[0] : undefined;
  		}
  
  		if (abbr === 'GMT') {
  			abbr = undefined;
  		}
  
  		this.at = +at;
  		this.abbr = abbr;
  		this.offset = at.getTimezoneOffset();
  	}
  
  	function ZoneScore(zone) {
  		this.zone = zone;
  		this.offsetScore = 0;
  		this.abbrScore = 0;
  	}
  
  	ZoneScore.prototype.scoreOffsetAt = function (offsetAt) {
  		this.offsetScore += Math.abs(this.zone.utcOffset(offsetAt.at) - offsetAt.offset);
  		if (this.zone.abbr(offsetAt.at).replace(/[^A-Z]/g, '') !== offsetAt.abbr) {
  			this.abbrScore++;
  		}
  	};
  
  	function findChange(low, high) {
  		var mid, diff;
  
  		while ((diff = ((high.at - low.at) / 12e4 | 0) * 6e4)) {
  			mid = new OffsetAt(new Date(low.at + diff));
  			if (mid.offset === low.offset) {
  				low = mid;
  			} else {
  				high = mid;
  			}
  		}
  
  		return low;
  	}
  
  	function userOffsets() {
  		var startYear = new Date().getFullYear() - 2,
  			last = new OffsetAt(new Date(startYear, 0, 1)),
  			offsets = [last],
  			change, next, i;
  
  		for (i = 1; i < 48; i++) {
  			next = new OffsetAt(new Date(startYear, i, 1));
  			if (next.offset !== last.offset) {
  				change = findChange(last, next);
  				offsets.push(change);
  				offsets.push(new OffsetAt(new Date(change.at + 6e4)));
  			}
  			last = next;
  		}
  
  		for (i = 0; i < 4; i++) {
  			offsets.push(new OffsetAt(new Date(startYear + i, 0, 1)));
  			offsets.push(new OffsetAt(new Date(startYear + i, 6, 1)));
  		}
  
  		return offsets;
  	}
  
  	function sortZoneScores (a, b) {
  		if (a.offsetScore !== b.offsetScore) {
  			return a.offsetScore - b.offsetScore;
  		}
  		if (a.abbrScore !== b.abbrScore) {
  			return a.abbrScore - b.abbrScore;
  		}
  		if (a.zone.population !== b.zone.population) {
  			return b.zone.population - a.zone.population;
  		}
  		return b.zone.name.localeCompare(a.zone.name);
  	}
  
  	function addToGuesses (name, offsets) {
  		var i, offset;
  		arrayToInt(offsets);
  		for (i = 0; i < offsets.length; i++) {
  			offset = offsets[i];
  			guesses[offset] = guesses[offset] || {};
  			guesses[offset][name] = true;
  		}
  	}
  
  	function guessesForUserOffsets (offsets) {
  		var offsetsLength = offsets.length,
  			filteredGuesses = {},
  			out = [],
  			i, j, guessesOffset;
  
  		for (i = 0; i < offsetsLength; i++) {
  			guessesOffset = guesses[offsets[i].offset] || {};
  			for (j in guessesOffset) {
  				if (guessesOffset.hasOwnProperty(j)) {
  					filteredGuesses[j] = true;
  				}
  			}
  		}
  
  		for (i in filteredGuesses) {
  			if (filteredGuesses.hasOwnProperty(i)) {
  				out.push(names[i]);
  			}
  		}
  
  		return out;
  	}
  
  	function rebuildGuess () {
  
  		// use Intl API when available and returning valid time zone
  		try {
  			var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone;
  			if (intlName && intlName.length > 3) {
  				var name = names[normalizeName(intlName)];
  				if (name) {
  					return name;
  				}
  				logError("Moment Timezone found " + intlName + " from the Intl api, but did not have that data loaded.");
  			}
  		} catch (e) {
  			// Intl unavailable, fall back to manual guessing.
  		}
  
  		var offsets = userOffsets(),
  			offsetsLength = offsets.length,
  			guesses = guessesForUserOffsets(offsets),
  			zoneScores = [],
  			zoneScore, i, j;
  
  		for (i = 0; i < guesses.length; i++) {
  			zoneScore = new ZoneScore(getZone(guesses[i]), offsetsLength);
  			for (j = 0; j < offsetsLength; j++) {
  				zoneScore.scoreOffsetAt(offsets[j]);
  			}
  			zoneScores.push(zoneScore);
  		}
  
  		zoneScores.sort(sortZoneScores);
  
  		return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined;
  	}
  
  	function guess (ignoreCache) {
  		if (!cachedGuess || ignoreCache) {
  			cachedGuess = rebuildGuess();
  		}
  		return cachedGuess;
  	}
  
  	/************************************
  		Global Methods
  	************************************/
  
  	function normalizeName (name) {
  		return (name || '').toLowerCase().replace(/\//g, '_');
  	}
  
  	function addZone (packed) {
  		var i, name, split, normalized;
  
  		if (typeof packed === "string") {
  			packed = [packed];
  		}
  
  		for (i = 0; i < packed.length; i++) {
  			split = packed[i].split('|');
  			name = split[0];
  			normalized = normalizeName(name);
  			zones[normalized] = packed[i];
  			names[normalized] = name;
  			addToGuesses(normalized, split[2].split(' '));
  		}
  	}
  
  	function getZone (name, caller) {
  
  		name = normalizeName(name);
  
  		var zone = zones[name];
  		var link;
  
  		if (zone instanceof Zone) {
  			return zone;
  		}
  
  		if (typeof zone === 'string') {
  			zone = new Zone(zone);
  			zones[name] = zone;
  			return zone;
  		}
  
  		// Pass getZone to prevent recursion more than 1 level deep
  		if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) {
  			zone = zones[name] = new Zone();
  			zone._set(link);
  			zone.name = names[name];
  			return zone;
  		}
  
  		return null;
  	}
  
  	function getNames () {
  		var i, out = [];
  
  		for (i in names) {
  			if (names.hasOwnProperty(i) && (zones[i] || zones[links[i]]) && names[i]) {
  				out.push(names[i]);
  			}
  		}
  
  		return out.sort();
  	}
  
  	function getCountryNames () {
  		return Object.keys(countries);
  	}
  
  	function addLink (aliases) {
  		var i, alias, normal0, normal1;
  
  		if (typeof aliases === "string") {
  			aliases = [aliases];
  		}
  
  		for (i = 0; i < aliases.length; i++) {
  			alias = aliases[i].split('|');
  
  			normal0 = normalizeName(alias[0]);
  			normal1 = normalizeName(alias[1]);
  
  			links[normal0] = normal1;
  			names[normal0] = alias[0];
  
  			links[normal1] = normal0;
  			names[normal1] = alias[1];
  		}
  	}
  
  	function addCountries (data) {
  		var i, country_code, country_zones, split;
  		if (!data || !data.length) return;
  		for (i = 0; i < data.length; i++) {
  			split = data[i].split('|');
  			country_code = split[0].toUpperCase();
  			country_zones = split[1].split(' ');
  			countries[country_code] = new Country(
  				country_code,
  				country_zones
  			);
  		}
  	}
  
  	function getCountry (name) {
  		name = name.toUpperCase();
  		return countries[name] || null;
  	}
  
  	function zonesForCountry(country, with_offset) {
  		country = getCountry(country);
  
  		if (!country) return null;
  
  		var zones = country.zones.sort();
  
  		if (with_offset) {
  			return zones.map(function (zone_name) {
  				var zone = getZone(zone_name);
  				return {
  					name: zone_name,
  					offset: zone.utcOffset(new Date())
  				};
  			});
  		}
  
  		return zones;
  	}
  
  	function loadData (data) {
  		addZone(data.zones);
  		addLink(data.links);
  		addCountries(data.countries);
  		tz.dataVersion = data.version;
  	}
  
  	function zoneExists (name) {
  		if (!zoneExists.didShowError) {
  			zoneExists.didShowError = true;
  				logError("moment.tz.zoneExists('" + name + "') has been deprecated in favor of !moment.tz.zone('" + name + "')");
  		}
  		return !!getZone(name);
  	}
  
  	function needsOffset (m) {
  		var isUnixTimestamp = (m._f === 'X' || m._f === 'x');
  		return !!(m._a && (m._tzm === undefined) && !isUnixTimestamp);
  	}
  
  	function logError (message) {
  		if (typeof console !== 'undefined' && typeof console.error === 'function') {
  			console.error(message);
  		}
  	}
  
  	/************************************
  		moment.tz namespace
  	************************************/
  
  	function tz (input) {
  		var args = Array.prototype.slice.call(arguments, 0, -1),
  			name = arguments[arguments.length - 1],
  			zone = getZone(name),
  			out  = moment.utc.apply(null, args);
  
  		if (zone && !moment.isMoment(input) && needsOffset(out)) {
  			out.add(zone.parse(out), 'minutes');
  		}
  
  		out.tz(name);
  
  		return out;
  	}
  
  	tz.version      = VERSION;
  	tz.dataVersion  = '';
  	tz._zones       = zones;
  	tz._links       = links;
  	tz._names       = names;
  	tz._countries	= countries;
  	tz.add          = addZone;
  	tz.link         = addLink;
  	tz.load         = loadData;
  	tz.zone         = getZone;
  	tz.zoneExists   = zoneExists; // deprecated in 0.1.0
  	tz.guess        = guess;
  	tz.names        = getNames;
  	tz.Zone         = Zone;
  	tz.unpack       = unpack;
  	tz.unpackBase60 = unpackBase60;
  	tz.needsOffset  = needsOffset;
  	tz.moveInvalidForward   = true;
  	tz.moveAmbiguousForward = false;
  	tz.countries    = getCountryNames;
  	tz.zonesForCountry = zonesForCountry;
  
  	/************************************
  		Interface with Moment.js
  	************************************/
  
  	var fn = moment.fn;
  
  	moment.tz = tz;
  
  	moment.defaultZone = null;
  
  	moment.updateOffset = function (mom, keepTime) {
  		var zone = moment.defaultZone,
  			offset;
  
  		if (mom._z === undefined) {
  			if (zone && needsOffset(mom) && !mom._isUTC) {
  				mom._d = moment.utc(mom._a)._d;
  				mom.utc().add(zone.parse(mom), 'minutes');
  			}
  			mom._z = zone;
  		}
  		if (mom._z) {
  			offset = mom._z.utcOffset(mom);
  			if (Math.abs(offset) < 16) {
  				offset = offset / 60;
  			}
  			if (mom.utcOffset !== undefined) {
  				var z = mom._z;
  				mom.utcOffset(-offset, keepTime);
  				mom._z = z;
  			} else {
  				mom.zone(offset, keepTime);
  			}
  		}
  	};
  
  	fn.tz = function (name, keepTime) {
  		if (name) {
  			if (typeof name !== 'string') {
  				throw new Error('Time zone name must be a string, got ' + name + ' [' + typeof name + ']');
  			}
  			this._z = getZone(name);
  			if (this._z) {
  				moment.updateOffset(this, keepTime);
  			} else {
  				logError("Moment Timezone has no data for " + name + ". See http://momentjs.com/timezone/docs/#/data-loading/.");
  			}
  			return this;
  		}
  		if (this._z) { return this._z.name; }
  	};
  
  	function abbrWrap (old) {
  		return function () {
  			if (this._z) { return this._z.abbr(this); }
  			return old.call(this);
  		};
  	}
  
  	function resetZoneWrap (old) {
  		return function () {
  			this._z = null;
  			return old.apply(this, arguments);
  		};
  	}
  
  	function resetZoneWrap2 (old) {
  		return function () {
  			if (arguments.length > 0) this._z = null;
  			return old.apply(this, arguments);
  		};
  	}
  
  	fn.zoneName  = abbrWrap(fn.zoneName);
  	fn.zoneAbbr  = abbrWrap(fn.zoneAbbr);
  	fn.utc       = resetZoneWrap(fn.utc);
  	fn.local     = resetZoneWrap(fn.local);
  	fn.utcOffset = resetZoneWrap2(fn.utcOffset);
  
  	moment.tz.setDefault = function(name) {
  		if (major < 2 || (major === 2 && minor < 9)) {
  			logError('Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js ' + moment.version + '.');
  		}
  		moment.defaultZone = name ? getZone(name) : null;
  		return moment;
  	};
  
  	// Cloning a moment should include the _z property.
  	var momentProperties = moment.momentProperties;
  	if (Object.prototype.toString.call(momentProperties) === '[object Array]') {
  		// moment 2.8.1+
  		momentProperties.push('_z');
  		momentProperties.push('_a');
  	} else if (momentProperties) {
  		// moment 2.7.0
  		momentProperties._z = null;
  	}
  
  	loadData({
  		"version": "2020a",
  		"zones": [
  			"Africa/Abidjan|GMT|0|0||48e5",
  			"Africa/Nairobi|EAT|-30|0||47e5",
  			"Africa/Algiers|CET|-10|0||26e5",
  			"Africa/Lagos|WAT|-10|0||17e6",
  			"Africa/Maputo|CAT|-20|0||26e5",
  			"Africa/Cairo|EET|-20|0||15e6",
  			"Africa/Casablanca|+00 +01|0 -10|010101010101010101010101010101|1O9e0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0|32e5",
  			"Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|11e6",
  			"Africa/Johannesburg|SAST|-20|0||84e5",
  			"Africa/Khartoum|EAT CAT|-30 -20|01|1Usl0|51e5",
  			"Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00|",
  			"Africa/Windhoek|CAT WAT|-20 -10|0101010|1Oc00 11B0 1nX0 11B0 1nX0 11B0|32e4",
  			"America/Adak|HST HDT|a0 90|01010101010101010101010|1O100 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326",
  			"America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1O0X0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4",
  			"America/Santo_Domingo|AST|40|0||29e5",
  			"America/Fortaleza|-03|30|0||34e5",
  			"America/Asuncion|-03 -04|30 40|01010101010101010101010|1O6r0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0|28e5",
  			"America/Panama|EST|50|0||15e5",
  			"America/Mexico_City|CST CDT|60 50|01010101010101010101010|1Oc80 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|20e6",
  			"America/Managua|CST|60|0||22e5",
  			"America/La_Paz|-04|40|0||19e5",
  			"America/Lima|-05|50|0||11e6",
  			"America/Denver|MST MDT|70 60|01010101010101010101010|1O0V0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5",
  			"America/Campo_Grande|-03 -04|30 40|0101010101|1NTf0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|77e4",
  			"America/Cancun|CST EST|60 50|01|1NKU0|63e4",
  			"America/Caracas|-0430 -04|4u 40|01|1QMT0|29e5",
  			"America/Chicago|CST CDT|60 50|01010101010101010101010|1O0U0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5",
  			"America/Chihuahua|MST MDT|70 60|01010101010101010101010|1Oc90 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|81e4",
  			"America/Phoenix|MST|70|0||42e5",
  			"America/Whitehorse|PST PDT MST|80 70 70|010101010102|1O0W0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|23e3",
  			"America/New_York|EST EDT|50 40|01010101010101010101010|1O0T0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6",
  			"America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1O0W0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6",
  			"America/Fort_Nelson|PST MST|80 70|01|1O0W0|39e2",
  			"America/Halifax|AST ADT|40 30|01010101010101010101010|1O0S0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4",
  			"America/Godthab|-03 -02|30 20|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|17e3",
  			"America/Grand_Turk|EST EDT AST|50 40 40|0121010101010101010|1O0T0 1zb0 5Ip0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2",
  			"America/Havana|CST CDT|50 40|01010101010101010101010|1O0R0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5",
  			"America/Metlakatla|PST AKST AKDT|80 90 80|01212120121212121212121|1PAa0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2",
  			"America/Miquelon|-03 -02|30 20|01010101010101010101010|1O0R0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2",
  			"America/Montevideo|-02 -03|20 30|01|1O0Q0|17e5",
  			"America/Noronha|-02|20|0||30e2",
  			"America/Port-au-Prince|EST EDT|50 40|010101010101010101010|1O0T0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5",
  			"Antarctica/Palmer|-03 -04|30 40|010|1QSr0 Ap0|40",
  			"America/Santiago|-03 -04|30 40|010101010101010101010|1QSr0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0|62e5",
  			"America/Sao_Paulo|-02 -03|20 30|0101010101|1NTe0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|20e6",
  			"Atlantic/Azores|-01 +00|10 0|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|25e4",
  			"America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1O0Ru 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4",
  			"Antarctica/Casey|+08 +11|-80 -b0|010|1RWg0 3m10|10",
  			"Asia/Bangkok|+07|-70|0||15e6",
  			"Asia/Vladivostok|+10|-a0|0||60e4",
  			"Pacific/Bougainville|+11|-b0|0||18e4",
  			"Asia/Tashkent|+05|-50|0||23e5",
  			"Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1ObO0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00|14e5",
  			"Asia/Baghdad|+03|-30|0||66e5",
  			"Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|40",
  			"Asia/Dhaka|+06|-60|0||16e6",
  			"Asia/Amman|EET EEST|-20 -30|01010101010101010101010|1O8m0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|25e5",
  			"Asia/Kamchatka|+12|-c0|0||18e4",
  			"Asia/Baku|+04 +05|-40 -50|010|1O9c0 1o00|27e5",
  			"Asia/Barnaul|+06 +07|-60 -70|01|1QyI0|",
  			"Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1O9a0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0|22e5",
  			"Asia/Kuala_Lumpur|+08|-80|0||71e5",
  			"Asia/Kolkata|IST|-5u|0||15e6",
  			"Asia/Chita|+08 +09|-80 -90|01|1QyG0|33e4",
  			"Asia/Ulaanbaatar|+08 +09|-80 -90|01010|1O8G0 1cJ0 1cP0 1cJ0|12e5",
  			"Asia/Shanghai|CST|-80|0||23e6",
  			"Asia/Colombo|+0530|-5u|0||22e5",
  			"Asia/Damascus|EET EEST|-20 -30|01010101010101010101010|1O8m0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0|26e5",
  			"Asia/Yakutsk|+09|-90|0||28e4",
  			"Asia/Dubai|+04|-40|0||39e5",
  			"Asia/Famagusta|EET EEST +03|-20 -30 -30|0101201010101010101010|1O9d0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|",
  			"Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1O8K0 1nz0 1220 1qL0 WN0 1qL0 WN0 1qL0 11c0 1oo0 11c0 1rc0 Wo0 1rc0 Wo0 1rc0 11c0 1oo0 11c0 1oo0 11c0 1oo0|18e5",
  			"Asia/Hong_Kong|HKT|-80|0||73e5",
  			"Asia/Hovd|+07 +08|-70 -80|01010|1O8H0 1cJ0 1cP0 1cJ0|81e3",
  			"Europe/Istanbul|EET EEST +03|-20 -30 -30|01012|1O9d0 1tA0 U00 15w0|13e6",
  			"Asia/Jakarta|WIB|-70|0||31e6",
  			"Asia/Jayapura|WIT|-90|0||26e4",
  			"Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1O8o0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0|81e4",
  			"Asia/Kabul|+0430|-4u|0||46e5",
  			"Asia/Karachi|PKT|-50|0||24e6",
  			"Asia/Kathmandu|+0545|-5J|0||12e5",
  			"Asia/Magadan|+10 +11|-a0 -b0|01|1QJQ0|95e3",
  			"Asia/Makassar|WITA|-80|0||15e5",
  			"Asia/Manila|PST|-80|0||24e6",
  			"Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|35e5",
  			"Asia/Novosibirsk|+06 +07|-60 -70|01|1Rmk0|15e5",
  			"Asia/Pyongyang|KST KST|-90 -8u|010|1P4D0 6BA0|29e5",
  			"Asia/Qyzylorda|+06 +05|-60 -50|01|1Xei0|73e4",
  			"Asia/Rangoon|+0630|-6u|0||48e5",
  			"Asia/Sakhalin|+10 +11|-a0 -b0|01|1QyE0|58e4",
  			"Asia/Seoul|KST|-90|0||23e6",
  			"Asia/Tehran|+0330 +0430|-3u -4u|01010101010101010101010|1O6ku 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0|14e6",
  			"Asia/Tokyo|JST|-90|0||38e6",
  			"Asia/Tomsk|+06 +07|-60 -70|01|1QXU0|10e5",
  			"Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|27e5",
  			"Atlantic/Cape_Verde|-01|10|0||50e4",
  			"Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1ObQ0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0|40e5",
  			"Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1ObQu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0|11e5",
  			"Australia/Brisbane|AEST|-a0|0||20e5",
  			"Australia/Darwin|ACST|-9u|0||12e4",
  			"Australia/Eucla|+0845|-8J|0||368",
  			"Australia/Lord_Howe|+11 +1030|-b0 -au|01010101010101010101010|1ObP0 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu|347",
  			"Australia/Perth|AWST|-80|0||18e5",
  			"Pacific/Easter|-05 -06|50 60|010101010101010101010|1QSr0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0|30e2",
  			"Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5",
  			"Etc/GMT-1|+01|-10|0||",
  			"Pacific/Fakaofo|+13|-d0|0||483",
  			"Pacific/Kiritimati|+14|-e0|0||51e2",
  			"Etc/GMT-2|+02|-20|0||",
  			"Pacific/Tahiti|-10|a0|0||18e4",
  			"Pacific/Niue|-11|b0|0||12e2",
  			"Etc/GMT+12|-12|c0|0||",
  			"Pacific/Galapagos|-06|60|0||25e3",
  			"Etc/GMT+7|-07|70|0||",
  			"Pacific/Pitcairn|-08|80|0||56",
  			"Pacific/Gambier|-09|90|0||125",
  			"Etc/UTC|UTC|0|0||",
  			"Europe/Ulyanovsk|+03 +04|-30 -40|01|1QyL0|13e5",
  			"Europe/London|GMT BST|0 -10|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|10e6",
  			"Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1O9c0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|67e4",
  			"Europe/Moscow|MSK|-30|0||16e6",
  			"Europe/Saratov|+03 +04|-30 -40|01|1Sfz0|",
  			"Europe/Volgograd|+03 +04|-30 -40|01|1WQL0|10e5",
  			"Pacific/Honolulu|HST|a0|0||37e4",
  			"MET|MET MEST|-10 -20|01010101010101010101010|1O9d0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|",
  			"Pacific/Chatham|+1345 +1245|-dJ -cJ|01010101010101010101010|1ObO0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00|600",
  			"Pacific/Apia|+14 +13|-e0 -d0|01010101010101010101010|1ObO0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00|37e3",
  			"Pacific/Fiji|+13 +12|-d0 -c0|01010101010101010101010|1NF20 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 20o0 pc0 20o0 s00 20o0 pc0 20o0 pc0 20o0 pc0 20o0 pc0 20o0|88e4",
  			"Pacific/Guam|ChST|-a0|0||17e4",
  			"Pacific/Marquesas|-0930|9u|0||86e2",
  			"Pacific/Pago_Pago|SST|b0|0||37e2",
  			"Pacific/Norfolk|+1130 +11 +12|-bu -b0 -c0|012121212121212|1PoCu 9Jcu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0|25e4",
  			"Pacific/Tongatapu|+13 +14|-d0 -e0|010|1S4d0 s00|75e3"
  		],
  		"links": [
  			"Africa/Abidjan|Africa/Accra",
  			"Africa/Abidjan|Africa/Bamako",
  			"Africa/Abidjan|Africa/Banjul",
  			"Africa/Abidjan|Africa/Bissau",
  			"Africa/Abidjan|Africa/Conakry",
  			"Africa/Abidjan|Africa/Dakar",
  			"Africa/Abidjan|Africa/Freetown",
  			"Africa/Abidjan|Africa/Lome",
  			"Africa/Abidjan|Africa/Monrovia",
  			"Africa/Abidjan|Africa/Nouakchott",
  			"Africa/Abidjan|Africa/Ouagadougou",
  			"Africa/Abidjan|Africa/Timbuktu",
  			"Africa/Abidjan|America/Danmarkshavn",
  			"Africa/Abidjan|Atlantic/Reykjavik",
  			"Africa/Abidjan|Atlantic/St_Helena",
  			"Africa/Abidjan|Etc/GMT",
  			"Africa/Abidjan|Etc/GMT+0",
  			"Africa/Abidjan|Etc/GMT-0",
  			"Africa/Abidjan|Etc/GMT0",
  			"Africa/Abidjan|Etc/Greenwich",
  			"Africa/Abidjan|GMT",
  			"Africa/Abidjan|GMT+0",
  			"Africa/Abidjan|GMT-0",
  			"Africa/Abidjan|GMT0",
  			"Africa/Abidjan|Greenwich",
  			"Africa/Abidjan|Iceland",
  			"Africa/Algiers|Africa/Tunis",
  			"Africa/Cairo|Africa/Tripoli",
  			"Africa/Cairo|Egypt",
  			"Africa/Cairo|Europe/Kaliningrad",
  			"Africa/Cairo|Libya",
  			"Africa/Casablanca|Africa/El_Aaiun",
  			"Africa/Johannesburg|Africa/Maseru",
  			"Africa/Johannesburg|Africa/Mbabane",
  			"Africa/Lagos|Africa/Bangui",
  			"Africa/Lagos|Africa/Brazzaville",
  			"Africa/Lagos|Africa/Douala",
  			"Africa/Lagos|Africa/Kinshasa",
  			"Africa/Lagos|Africa/Libreville",
  			"Africa/Lagos|Africa/Luanda",
  			"Africa/Lagos|Africa/Malabo",
  			"Africa/Lagos|Africa/Ndjamena",
  			"Africa/Lagos|Africa/Niamey",
  			"Africa/Lagos|Africa/Porto-Novo",
  			"Africa/Maputo|Africa/Blantyre",
  			"Africa/Maputo|Africa/Bujumbura",
  			"Africa/Maputo|Africa/Gaborone",
  			"Africa/Maputo|Africa/Harare",
  			"Africa/Maputo|Africa/Kigali",
  			"Africa/Maputo|Africa/Lubumbashi",
  			"Africa/Maputo|Africa/Lusaka",
  			"Africa/Nairobi|Africa/Addis_Ababa",
  			"Africa/Nairobi|Africa/Asmara",
  			"Africa/Nairobi|Africa/Asmera",
  			"Africa/Nairobi|Africa/Dar_es_Salaam",
  			"Africa/Nairobi|Africa/Djibouti",
  			"Africa/Nairobi|Africa/Juba",
  			"Africa/Nairobi|Africa/Kampala",
  			"Africa/Nairobi|Africa/Mogadishu",
  			"Africa/Nairobi|Indian/Antananarivo",
  			"Africa/Nairobi|Indian/Comoro",
  			"Africa/Nairobi|Indian/Mayotte",
  			"America/Adak|America/Atka",
  			"America/Adak|US/Aleutian",
  			"America/Anchorage|America/Juneau",
  			"America/Anchorage|America/Nome",
  			"America/Anchorage|America/Sitka",
  			"America/Anchorage|America/Yakutat",
  			"America/Anchorage|US/Alaska",
  			"America/Campo_Grande|America/Cuiaba",
  			"America/Chicago|America/Indiana/Knox",
  			"America/Chicago|America/Indiana/Tell_City",
  			"America/Chicago|America/Knox_IN",
  			"America/Chicago|America/Matamoros",
  			"America/Chicago|America/Menominee",
  			"America/Chicago|America/North_Dakota/Beulah",
  			"America/Chicago|America/North_Dakota/Center",
  			"America/Chicago|America/North_Dakota/New_Salem",
  			"America/Chicago|America/Rainy_River",
  			"America/Chicago|America/Rankin_Inlet",
  			"America/Chicago|America/Resolute",
  			"America/Chicago|America/Winnipeg",
  			"America/Chicago|CST6CDT",
  			"America/Chicago|Canada/Central",
  			"America/Chicago|US/Central",
  			"America/Chicago|US/Indiana-Starke",
  			"America/Chihuahua|America/Mazatlan",
  			"America/Chihuahua|Mexico/BajaSur",
  			"America/Denver|America/Boise",
  			"America/Denver|America/Cambridge_Bay",
  			"America/Denver|America/Edmonton",
  			"America/Denver|America/Inuvik",
  			"America/Denver|America/Ojinaga",
  			"America/Denver|America/Shiprock",
  			"America/Denver|America/Yellowknife",
  			"America/Denver|Canada/Mountain",
  			"America/Denver|MST7MDT",
  			"America/Denver|Navajo",
  			"America/Denver|US/Mountain",
  			"America/Fortaleza|America/Araguaina",
  			"America/Fortaleza|America/Argentina/Buenos_Aires",
  			"America/Fortaleza|America/Argentina/Catamarca",
  			"America/Fortaleza|America/Argentina/ComodRivadavia",
  			"America/Fortaleza|America/Argentina/Cordoba",
  			"America/Fortaleza|America/Argentina/Jujuy",
  			"America/Fortaleza|America/Argentina/La_Rioja",
  			"America/Fortaleza|America/Argentina/Mendoza",
  			"America/Fortaleza|America/Argentina/Rio_Gallegos",
  			"America/Fortaleza|America/Argentina/Salta",
  			"America/Fortaleza|America/Argentina/San_Juan",
  			"America/Fortaleza|America/Argentina/San_Luis",
  			"America/Fortaleza|America/Argentina/Tucuman",
  			"America/Fortaleza|America/Argentina/Ushuaia",
  			"America/Fortaleza|America/Bahia",
  			"America/Fortaleza|America/Belem",
  			"America/Fortaleza|America/Buenos_Aires",
  			"America/Fortaleza|America/Catamarca",
  			"America/Fortaleza|America/Cayenne",
  			"America/Fortaleza|America/Cordoba",
  			"America/Fortaleza|America/Jujuy",
  			"America/Fortaleza|America/Maceio",
  			"America/Fortaleza|America/Mendoza",
  			"America/Fortaleza|America/Paramaribo",
  			"America/Fortaleza|America/Recife",
  			"America/Fortaleza|America/Rosario",
  			"America/Fortaleza|America/Santarem",
  			"America/Fortaleza|Antarctica/Rothera",
  			"America/Fortaleza|Atlantic/Stanley",
  			"America/Fortaleza|Etc/GMT+3",
  			"America/Godthab|America/Nuuk",
  			"America/Halifax|America/Glace_Bay",
  			"America/Halifax|America/Goose_Bay",
  			"America/Halifax|America/Moncton",
  			"America/Halifax|America/Thule",
  			"America/Halifax|Atlantic/Bermuda",
  			"America/Halifax|Canada/Atlantic",
  			"America/Havana|Cuba",
  			"America/La_Paz|America/Boa_Vista",
  			"America/La_Paz|America/Guyana",
  			"America/La_Paz|America/Manaus",
  			"America/La_Paz|America/Porto_Velho",
  			"America/La_Paz|Brazil/West",
  			"America/La_Paz|Etc/GMT+4",
  			"America/Lima|America/Bogota",
  			"America/Lima|America/Eirunepe",
  			"America/Lima|America/Guayaquil",
  			"America/Lima|America/Porto_Acre",
  			"America/Lima|America/Rio_Branco",
  			"America/Lima|Brazil/Acre",
  			"America/Lima|Etc/GMT+5",
  			"America/Los_Angeles|America/Ensenada",
  			"America/Los_Angeles|America/Santa_Isabel",
  			"America/Los_Angeles|America/Tijuana",
  			"America/Los_Angeles|America/Vancouver",
  			"America/Los_Angeles|Canada/Pacific",
  			"America/Los_Angeles|Mexico/BajaNorte",
  			"America/Los_Angeles|PST8PDT",
  			"America/Los_Angeles|US/Pacific",
  			"America/Los_Angeles|US/Pacific-New",
  			"America/Managua|America/Belize",
  			"America/Managua|America/Costa_Rica",
  			"America/Managua|America/El_Salvador",
  			"America/Managua|America/Guatemala",
  			"America/Managua|America/Regina",
  			"America/Managua|America/Swift_Current",
  			"America/Managua|America/Tegucigalpa",
  			"America/Managua|Canada/Saskatchewan",
  			"America/Mexico_City|America/Bahia_Banderas",
  			"America/Mexico_City|America/Merida",
  			"America/Mexico_City|America/Monterrey",
  			"America/Mexico_City|Mexico/General",
  			"America/New_York|America/Detroit",
  			"America/New_York|America/Fort_Wayne",
  			"America/New_York|America/Indiana/Indianapolis",
  			"America/New_York|America/Indiana/Marengo",
  			"America/New_York|America/Indiana/Petersburg",
  			"America/New_York|America/Indiana/Vevay",
  			"America/New_York|America/Indiana/Vincennes",
  			"America/New_York|America/Indiana/Winamac",
  			"America/New_York|America/Indianapolis",
  			"America/New_York|America/Iqaluit",
  			"America/New_York|America/Kentucky/Louisville",
  			"America/New_York|America/Kentucky/Monticello",
  			"America/New_York|America/Louisville",
  			"America/New_York|America/Montreal",
  			"America/New_York|America/Nassau",
  			"America/New_York|America/Nipigon",
  			"America/New_York|America/Pangnirtung",
  			"America/New_York|America/Thunder_Bay",
  			"America/New_York|America/Toronto",
  			"America/New_York|Canada/Eastern",
  			"America/New_York|EST5EDT",
  			"America/New_York|US/East-Indiana",
  			"America/New_York|US/Eastern",
  			"America/New_York|US/Michigan",
  			"America/Noronha|Atlantic/South_Georgia",
  			"America/Noronha|Brazil/DeNoronha",
  			"America/Noronha|Etc/GMT+2",
  			"America/Panama|America/Atikokan",
  			"America/Panama|America/Cayman",
  			"America/Panama|America/Coral_Harbour",
  			"America/Panama|America/Jamaica",
  			"America/Panama|EST",
  			"America/Panama|Jamaica",
  			"America/Phoenix|America/Creston",
  			"America/Phoenix|America/Dawson_Creek",
  			"America/Phoenix|America/Hermosillo",
  			"America/Phoenix|MST",
  			"America/Phoenix|US/Arizona",
  			"America/Santiago|Chile/Continental",
  			"America/Santo_Domingo|America/Anguilla",
  			"America/Santo_Domingo|America/Antigua",
  			"America/Santo_Domingo|America/Aruba",
  			"America/Santo_Domingo|America/Barbados",
  			"America/Santo_Domingo|America/Blanc-Sablon",
  			"America/Santo_Domingo|America/Curacao",
  			"America/Santo_Domingo|America/Dominica",
  			"America/Santo_Domingo|America/Grenada",
  			"America/Santo_Domingo|America/Guadeloupe",
  			"America/Santo_Domingo|America/Kralendijk",
  			"America/Santo_Domingo|America/Lower_Princes",
  			"America/Santo_Domingo|America/Marigot",
  			"America/Santo_Domingo|America/Martinique",
  			"America/Santo_Domingo|America/Montserrat",
  			"America/Santo_Domingo|America/Port_of_Spain",
  			"America/Santo_Domingo|America/Puerto_Rico",
  			"America/Santo_Domingo|America/St_Barthelemy",
  			"America/Santo_Domingo|America/St_Kitts",
  			"America/Santo_Domingo|America/St_Lucia",
  			"America/Santo_Domingo|America/St_Thomas",
  			"America/Santo_Domingo|America/St_Vincent",
  			"America/Santo_Domingo|America/Tortola",
  			"America/Santo_Domingo|America/Virgin",
  			"America/Sao_Paulo|Brazil/East",
  			"America/St_Johns|Canada/Newfoundland",
  			"America/Whitehorse|America/Dawson",
  			"America/Whitehorse|Canada/Yukon",
  			"Antarctica/Palmer|America/Punta_Arenas",
  			"Asia/Baghdad|Antarctica/Syowa",
  			"Asia/Baghdad|Asia/Aden",
  			"Asia/Baghdad|Asia/Bahrain",
  			"Asia/Baghdad|Asia/Kuwait",
  			"Asia/Baghdad|Asia/Qatar",
  			"Asia/Baghdad|Asia/Riyadh",
  			"Asia/Baghdad|Etc/GMT-3",
  			"Asia/Baghdad|Europe/Kirov",
  			"Asia/Baghdad|Europe/Minsk",
  			"Asia/Bangkok|Antarctica/Davis",
  			"Asia/Bangkok|Asia/Ho_Chi_Minh",
  			"Asia/Bangkok|Asia/Krasnoyarsk",
  			"Asia/Bangkok|Asia/Novokuznetsk",
  			"Asia/Bangkok|Asia/Phnom_Penh",
  			"Asia/Bangkok|Asia/Saigon",
  			"Asia/Bangkok|Asia/Vientiane",
  			"Asia/Bangkok|Etc/GMT-7",
  			"Asia/Bangkok|Indian/Christmas",
  			"Asia/Dhaka|Antarctica/Vostok",
  			"Asia/Dhaka|Asia/Almaty",
  			"Asia/Dhaka|Asia/Bishkek",
  			"Asia/Dhaka|Asia/Dacca",
  			"Asia/Dhaka|Asia/Kashgar",
  			"Asia/Dhaka|Asia/Omsk",
  			"Asia/Dhaka|Asia/Qostanay",
  			"Asia/Dhaka|Asia/Thimbu",
  			"Asia/Dhaka|Asia/Thimphu",
  			"Asia/Dhaka|Asia/Urumqi",
  			"Asia/Dhaka|Etc/GMT-6",
  			"Asia/Dhaka|Indian/Chagos",
  			"Asia/Dubai|Asia/Muscat",
  			"Asia/Dubai|Asia/Tbilisi",
  			"Asia/Dubai|Asia/Yerevan",
  			"Asia/Dubai|Etc/GMT-4",
  			"Asia/Dubai|Europe/Samara",
  			"Asia/Dubai|Indian/Mahe",
  			"Asia/Dubai|Indian/Mauritius",
  			"Asia/Dubai|Indian/Reunion",
  			"Asia/Gaza|Asia/Hebron",
  			"Asia/Hong_Kong|Hongkong",
  			"Asia/Jakarta|Asia/Pontianak",
  			"Asia/Jerusalem|Asia/Tel_Aviv",
  			"Asia/Jerusalem|Israel",
  			"Asia/Kamchatka|Asia/Anadyr",
  			"Asia/Kamchatka|Etc/GMT-12",
  			"Asia/Kamchatka|Kwajalein",
  			"Asia/Kamchatka|Pacific/Funafuti",
  			"Asia/Kamchatka|Pacific/Kwajalein",
  			"Asia/Kamchatka|Pacific/Majuro",
  			"Asia/Kamchatka|Pacific/Nauru",
  			"Asia/Kamchatka|Pacific/Tarawa",
  			"Asia/Kamchatka|Pacific/Wake",
  			"Asia/Kamchatka|Pacific/Wallis",
  			"Asia/Kathmandu|Asia/Katmandu",
  			"Asia/Kolkata|Asia/Calcutta",
  			"Asia/Kuala_Lumpur|Asia/Brunei",
  			"Asia/Kuala_Lumpur|Asia/Irkutsk",
  			"Asia/Kuala_Lumpur|Asia/Kuching",
  			"Asia/Kuala_Lumpur|Asia/Singapore",
  			"Asia/Kuala_Lumpur|Etc/GMT-8",
  			"Asia/Kuala_Lumpur|Singapore",
  			"Asia/Makassar|Asia/Ujung_Pandang",
  			"Asia/Rangoon|Asia/Yangon",
  			"Asia/Rangoon|Indian/Cocos",
  			"Asia/Seoul|ROK",
  			"Asia/Shanghai|Asia/Chongqing",
  			"Asia/Shanghai|Asia/Chungking",
  			"Asia/Shanghai|Asia/Harbin",
  			"Asia/Shanghai|Asia/Macao",
  			"Asia/Shanghai|Asia/Macau",
  			"Asia/Shanghai|Asia/Taipei",
  			"Asia/Shanghai|PRC",
  			"Asia/Shanghai|ROC",
  			"Asia/Tashkent|Antarctica/Mawson",
  			"Asia/Tashkent|Asia/Aqtau",
  			"Asia/Tashkent|Asia/Aqtobe",
  			"Asia/Tashkent|Asia/Ashgabat",
  			"Asia/Tashkent|Asia/Ashkhabad",
  			"Asia/Tashkent|Asia/Atyrau",
  			"Asia/Tashkent|Asia/Dushanbe",
  			"Asia/Tashkent|Asia/Oral",
  			"Asia/Tashkent|Asia/Samarkand",
  			"Asia/Tashkent|Asia/Yekaterinburg",
  			"Asia/Tashkent|Etc/GMT-5",
  			"Asia/Tashkent|Indian/Kerguelen",
  			"Asia/Tashkent|Indian/Maldives",
  			"Asia/Tehran|Iran",
  			"Asia/Tokyo|Japan",
  			"Asia/Ulaanbaatar|Asia/Choibalsan",
  			"Asia/Ulaanbaatar|Asia/Ulan_Bator",
  			"Asia/Vladivostok|Antarctica/DumontDUrville",
  			"Asia/Vladivostok|Asia/Ust-Nera",
  			"Asia/Vladivostok|Etc/GMT-10",
  			"Asia/Vladivostok|Pacific/Chuuk",
  			"Asia/Vladivostok|Pacific/Port_Moresby",
  			"Asia/Vladivostok|Pacific/Truk",
  			"Asia/Vladivostok|Pacific/Yap",
  			"Asia/Yakutsk|Asia/Dili",
  			"Asia/Yakutsk|Asia/Khandyga",
  			"Asia/Yakutsk|Etc/GMT-9",
  			"Asia/Yakutsk|Pacific/Palau",
  			"Atlantic/Azores|America/Scoresbysund",
  			"Atlantic/Cape_Verde|Etc/GMT+1",
  			"Australia/Adelaide|Australia/Broken_Hill",
  			"Australia/Adelaide|Australia/South",
  			"Australia/Adelaide|Australia/Yancowinna",
  			"Australia/Brisbane|Australia/Lindeman",
  			"Australia/Brisbane|Australia/Queensland",
  			"Australia/Darwin|Australia/North",
  			"Australia/Lord_Howe|Australia/LHI",
  			"Australia/Perth|Australia/West",
  			"Australia/Sydney|Australia/ACT",
  			"Australia/Sydney|Australia/Canberra",
  			"Australia/Sydney|Australia/Currie",
  			"Australia/Sydney|Australia/Hobart",
  			"Australia/Sydney|Australia/Melbourne",
  			"Australia/Sydney|Australia/NSW",
  			"Australia/Sydney|Australia/Tasmania",
  			"Australia/Sydney|Australia/Victoria",
  			"Etc/UTC|Etc/UCT",
  			"Etc/UTC|Etc/Universal",
  			"Etc/UTC|Etc/Zulu",
  			"Etc/UTC|UCT",
  			"Etc/UTC|UTC",
  			"Etc/UTC|Universal",
  			"Etc/UTC|Zulu",
  			"Europe/Athens|Asia/Nicosia",
  			"Europe/Athens|EET",
  			"Europe/Athens|Europe/Bucharest",
  			"Europe/Athens|Europe/Helsinki",
  			"Europe/Athens|Europe/Kiev",
  			"Europe/Athens|Europe/Mariehamn",
  			"Europe/Athens|Europe/Nicosia",
  			"Europe/Athens|Europe/Riga",
  			"Europe/Athens|Europe/Sofia",
  			"Europe/Athens|Europe/Tallinn",
  			"Europe/Athens|Europe/Uzhgorod",
  			"Europe/Athens|Europe/Vilnius",
  			"Europe/Athens|Europe/Zaporozhye",
  			"Europe/Chisinau|Europe/Tiraspol",
  			"Europe/Dublin|Eire",
  			"Europe/Istanbul|Asia/Istanbul",
  			"Europe/Istanbul|Turkey",
  			"Europe/Lisbon|Atlantic/Canary",
  			"Europe/Lisbon|Atlantic/Faeroe",
  			"Europe/Lisbon|Atlantic/Faroe",
  			"Europe/Lisbon|Atlantic/Madeira",
  			"Europe/Lisbon|Portugal",
  			"Europe/Lisbon|WET",
  			"Europe/London|Europe/Belfast",
  			"Europe/London|Europe/Guernsey",
  			"Europe/London|Europe/Isle_of_Man",
  			"Europe/London|Europe/Jersey",
  			"Europe/London|GB",
  			"Europe/London|GB-Eire",
  			"Europe/Moscow|Europe/Simferopol",
  			"Europe/Moscow|W-SU",
  			"Europe/Paris|Africa/Ceuta",
  			"Europe/Paris|Arctic/Longyearbyen",
  			"Europe/Paris|Atlantic/Jan_Mayen",
  			"Europe/Paris|CET",
  			"Europe/Paris|Europe/Amsterdam",
  			"Europe/Paris|Europe/Andorra",
  			"Europe/Paris|Europe/Belgrade",
  			"Europe/Paris|Europe/Berlin",
  			"Europe/Paris|Europe/Bratislava",
  			"Europe/Paris|Europe/Brussels",
  			"Europe/Paris|Europe/Budapest",
  			"Europe/Paris|Europe/Busingen",
  			"Europe/Paris|Europe/Copenhagen",
  			"Europe/Paris|Europe/Gibraltar",
  			"Europe/Paris|Europe/Ljubljana",
  			"Europe/Paris|Europe/Luxembourg",
  			"Europe/Paris|Europe/Madrid",
  			"Europe/Paris|Europe/Malta",
  			"Europe/Paris|Europe/Monaco",
  			"Europe/Paris|Europe/Oslo",
  			"Europe/Paris|Europe/Podgorica",
  			"Europe/Paris|Europe/Prague",
  			"Europe/Paris|Europe/Rome",
  			"Europe/Paris|Europe/San_Marino",
  			"Europe/Paris|Europe/Sarajevo",
  			"Europe/Paris|Europe/Skopje",
  			"Europe/Paris|Europe/Stockholm",
  			"Europe/Paris|Europe/Tirane",
  			"Europe/Paris|Europe/Vaduz",
  			"Europe/Paris|Europe/Vatican",
  			"Europe/Paris|Europe/Vienna",
  			"Europe/Paris|Europe/Warsaw",
  			"Europe/Paris|Europe/Zagreb",
  			"Europe/Paris|Europe/Zurich",
  			"Europe/Paris|Poland",
  			"Europe/Ulyanovsk|Europe/Astrakhan",
  			"Pacific/Auckland|Antarctica/McMurdo",
  			"Pacific/Auckland|Antarctica/South_Pole",
  			"Pacific/Auckland|NZ",
  			"Pacific/Bougainville|Antarctica/Macquarie",
  			"Pacific/Bougainville|Asia/Srednekolymsk",
  			"Pacific/Bougainville|Etc/GMT-11",
  			"Pacific/Bougainville|Pacific/Efate",
  			"Pacific/Bougainville|Pacific/Guadalcanal",
  			"Pacific/Bougainville|Pacific/Kosrae",
  			"Pacific/Bougainville|Pacific/Noumea",
  			"Pacific/Bougainville|Pacific/Pohnpei",
  			"Pacific/Bougainville|Pacific/Ponape",
  			"Pacific/Chatham|NZ-CHAT",
  			"Pacific/Easter|Chile/EasterIsland",
  			"Pacific/Fakaofo|Etc/GMT-13",
  			"Pacific/Fakaofo|Pacific/Enderbury",
  			"Pacific/Galapagos|Etc/GMT+6",
  			"Pacific/Gambier|Etc/GMT+9",
  			"Pacific/Guam|Pacific/Saipan",
  			"Pacific/Honolulu|HST",
  			"Pacific/Honolulu|Pacific/Johnston",
  			"Pacific/Honolulu|US/Hawaii",
  			"Pacific/Kiritimati|Etc/GMT-14",
  			"Pacific/Niue|Etc/GMT+11",
  			"Pacific/Pago_Pago|Pacific/Midway",
  			"Pacific/Pago_Pago|Pacific/Samoa",
  			"Pacific/Pago_Pago|US/Samoa",
  			"Pacific/Pitcairn|Etc/GMT+8",
  			"Pacific/Tahiti|Etc/GMT+10",
  			"Pacific/Tahiti|Pacific/Rarotonga"
  		],
  		"countries": [
  			"AD|Europe/Andorra",
  			"AE|Asia/Dubai",
  			"AF|Asia/Kabul",
  			"AG|America/Port_of_Spain America/Antigua",
  			"AI|America/Port_of_Spain America/Anguilla",
  			"AL|Europe/Tirane",
  			"AM|Asia/Yerevan",
  			"AO|Africa/Lagos Africa/Luanda",
  			"AQ|Antarctica/Casey Antarctica/Davis Antarctica/DumontDUrville Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Syowa Antarctica/Troll Antarctica/Vostok Pacific/Auckland Antarctica/McMurdo",
  			"AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia",
  			"AS|Pacific/Pago_Pago",
  			"AT|Europe/Vienna",
  			"AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Currie Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla",
  			"AW|America/Curacao America/Aruba",
  			"AX|Europe/Helsinki Europe/Mariehamn",
  			"AZ|Asia/Baku",
  			"BA|Europe/Belgrade Europe/Sarajevo",
  			"BB|America/Barbados",
  			"BD|Asia/Dhaka",
  			"BE|Europe/Brussels",
  			"BF|Africa/Abidjan Africa/Ouagadougou",
  			"BG|Europe/Sofia",
  			"BH|Asia/Qatar Asia/Bahrain",
  			"BI|Africa/Maputo Africa/Bujumbura",
  			"BJ|Africa/Lagos Africa/Porto-Novo",
  			"BL|America/Port_of_Spain America/St_Barthelemy",
  			"BM|Atlantic/Bermuda",
  			"BN|Asia/Brunei",
  			"BO|America/La_Paz",
  			"BQ|America/Curacao America/Kralendijk",
  			"BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco",
  			"BS|America/Nassau",
  			"BT|Asia/Thimphu",
  			"BW|Africa/Maputo Africa/Gaborone",
  			"BY|Europe/Minsk",
  			"BZ|America/Belize",
  			"CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Blanc-Sablon America/Toronto America/Nipigon America/Thunder_Bay America/Iqaluit America/Pangnirtung America/Atikokan America/Winnipeg America/Rainy_River America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Yellowknife America/Inuvik America/Creston America/Dawson_Creek America/Fort_Nelson America/Vancouver America/Whitehorse America/Dawson",
  			"CC|Indian/Cocos",
  			"CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi",
  			"CF|Africa/Lagos Africa/Bangui",
  			"CG|Africa/Lagos Africa/Brazzaville",
  			"CH|Europe/Zurich",
  			"CI|Africa/Abidjan",
  			"CK|Pacific/Rarotonga",
  			"CL|America/Santiago America/Punta_Arenas Pacific/Easter",
  			"CM|Africa/Lagos Africa/Douala",
  			"CN|Asia/Shanghai Asia/Urumqi",
  			"CO|America/Bogota",
  			"CR|America/Costa_Rica",
  			"CU|America/Havana",
  			"CV|Atlantic/Cape_Verde",
  			"CW|America/Curacao",
  			"CX|Indian/Christmas",
  			"CY|Asia/Nicosia Asia/Famagusta",
  			"CZ|Europe/Prague",
  			"DE|Europe/Zurich Europe/Berlin Europe/Busingen",
  			"DJ|Africa/Nairobi Africa/Djibouti",
  			"DK|Europe/Copenhagen",
  			"DM|America/Port_of_Spain America/Dominica",
  			"DO|America/Santo_Domingo",
  			"DZ|Africa/Algiers",
  			"EC|America/Guayaquil Pacific/Galapagos",
  			"EE|Europe/Tallinn",
  			"EG|Africa/Cairo",
  			"EH|Africa/El_Aaiun",
  			"ER|Africa/Nairobi Africa/Asmara",
  			"ES|Europe/Madrid Africa/Ceuta Atlantic/Canary",
  			"ET|Africa/Nairobi Africa/Addis_Ababa",
  			"FI|Europe/Helsinki",
  			"FJ|Pacific/Fiji",
  			"FK|Atlantic/Stanley",
  			"FM|Pacific/Chuuk Pacific/Pohnpei Pacific/Kosrae",
  			"FO|Atlantic/Faroe",
  			"FR|Europe/Paris",
  			"GA|Africa/Lagos Africa/Libreville",
  			"GB|Europe/London",
  			"GD|America/Port_of_Spain America/Grenada",
  			"GE|Asia/Tbilisi",
  			"GF|America/Cayenne",
  			"GG|Europe/London Europe/Guernsey",
  			"GH|Africa/Accra",
  			"GI|Europe/Gibraltar",
  			"GL|America/Godthab America/Danmarkshavn America/Scoresbysund America/Thule",
  			"GM|Africa/Abidjan Africa/Banjul",
  			"GN|Africa/Abidjan Africa/Conakry",
  			"GP|America/Port_of_Spain America/Guadeloupe",
  			"GQ|Africa/Lagos Africa/Malabo",
  			"GR|Europe/Athens",
  			"GS|Atlantic/South_Georgia",
  			"GT|America/Guatemala",
  			"GU|Pacific/Guam",
  			"GW|Africa/Bissau",
  			"GY|America/Guyana",
  			"HK|Asia/Hong_Kong",
  			"HN|America/Tegucigalpa",
  			"HR|Europe/Belgrade Europe/Zagreb",
  			"HT|America/Port-au-Prince",
  			"HU|Europe/Budapest",
  			"ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura",
  			"IE|Europe/Dublin",
  			"IL|Asia/Jerusalem",
  			"IM|Europe/London Europe/Isle_of_Man",
  			"IN|Asia/Kolkata",
  			"IO|Indian/Chagos",
  			"IQ|Asia/Baghdad",
  			"IR|Asia/Tehran",
  			"IS|Atlantic/Reykjavik",
  			"IT|Europe/Rome",
  			"JE|Europe/London Europe/Jersey",
  			"JM|America/Jamaica",
  			"JO|Asia/Amman",
  			"JP|Asia/Tokyo",
  			"KE|Africa/Nairobi",
  			"KG|Asia/Bishkek",
  			"KH|Asia/Bangkok Asia/Phnom_Penh",
  			"KI|Pacific/Tarawa Pacific/Enderbury Pacific/Kiritimati",
  			"KM|Africa/Nairobi Indian/Comoro",
  			"KN|America/Port_of_Spain America/St_Kitts",
  			"KP|Asia/Pyongyang",
  			"KR|Asia/Seoul",
  			"KW|Asia/Riyadh Asia/Kuwait",
  			"KY|America/Panama America/Cayman",
  			"KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral",
  			"LA|Asia/Bangkok Asia/Vientiane",
  			"LB|Asia/Beirut",
  			"LC|America/Port_of_Spain America/St_Lucia",
  			"LI|Europe/Zurich Europe/Vaduz",
  			"LK|Asia/Colombo",
  			"LR|Africa/Monrovia",
  			"LS|Africa/Johannesburg Africa/Maseru",
  			"LT|Europe/Vilnius",
  			"LU|Europe/Luxembourg",
  			"LV|Europe/Riga",
  			"LY|Africa/Tripoli",
  			"MA|Africa/Casablanca",
  			"MC|Europe/Monaco",
  			"MD|Europe/Chisinau",
  			"ME|Europe/Belgrade Europe/Podgorica",
  			"MF|America/Port_of_Spain America/Marigot",
  			"MG|Africa/Nairobi Indian/Antananarivo",
  			"MH|Pacific/Majuro Pacific/Kwajalein",
  			"MK|Europe/Belgrade Europe/Skopje",
  			"ML|Africa/Abidjan Africa/Bamako",
  			"MM|Asia/Yangon",
  			"MN|Asia/Ulaanbaatar Asia/Hovd Asia/Choibalsan",
  			"MO|Asia/Macau",
  			"MP|Pacific/Guam Pacific/Saipan",
  			"MQ|America/Martinique",
  			"MR|Africa/Abidjan Africa/Nouakchott",
  			"MS|America/Port_of_Spain America/Montserrat",
  			"MT|Europe/Malta",
  			"MU|Indian/Mauritius",
  			"MV|Indian/Maldives",
  			"MW|Africa/Maputo Africa/Blantyre",
  			"MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Mazatlan America/Chihuahua America/Ojinaga America/Hermosillo America/Tijuana America/Bahia_Banderas",
  			"MY|Asia/Kuala_Lumpur Asia/Kuching",
  			"MZ|Africa/Maputo",
  			"NA|Africa/Windhoek",
  			"NC|Pacific/Noumea",
  			"NE|Africa/Lagos Africa/Niamey",
  			"NF|Pacific/Norfolk",
  			"NG|Africa/Lagos",
  			"NI|America/Managua",
  			"NL|Europe/Amsterdam",
  			"NO|Europe/Oslo",
  			"NP|Asia/Kathmandu",
  			"NR|Pacific/Nauru",
  			"NU|Pacific/Niue",
  			"NZ|Pacific/Auckland Pacific/Chatham",
  			"OM|Asia/Dubai Asia/Muscat",
  			"PA|America/Panama",
  			"PE|America/Lima",
  			"PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier",
  			"PG|Pacific/Port_Moresby Pacific/Bougainville",
  			"PH|Asia/Manila",
  			"PK|Asia/Karachi",
  			"PL|Europe/Warsaw",
  			"PM|America/Miquelon",
  			"PN|Pacific/Pitcairn",
  			"PR|America/Puerto_Rico",
  			"PS|Asia/Gaza Asia/Hebron",
  			"PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores",
  			"PW|Pacific/Palau",
  			"PY|America/Asuncion",
  			"QA|Asia/Qatar",
  			"RE|Indian/Reunion",
  			"RO|Europe/Bucharest",
  			"RS|Europe/Belgrade",
  			"RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Astrakhan Europe/Volgograd Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr",
  			"RW|Africa/Maputo Africa/Kigali",
  			"SA|Asia/Riyadh",
  			"SB|Pacific/Guadalcanal",
  			"SC|Indian/Mahe",
  			"SD|Africa/Khartoum",
  			"SE|Europe/Stockholm",
  			"SG|Asia/Singapore",
  			"SH|Africa/Abidjan Atlantic/St_Helena",
  			"SI|Europe/Belgrade Europe/Ljubljana",
  			"SJ|Europe/Oslo Arctic/Longyearbyen",
  			"SK|Europe/Prague Europe/Bratislava",
  			"SL|Africa/Abidjan Africa/Freetown",
  			"SM|Europe/Rome Europe/San_Marino",
  			"SN|Africa/Abidjan Africa/Dakar",
  			"SO|Africa/Nairobi Africa/Mogadishu",
  			"SR|America/Paramaribo",
  			"SS|Africa/Juba",
  			"ST|Africa/Sao_Tome",
  			"SV|America/El_Salvador",
  			"SX|America/Curacao America/Lower_Princes",
  			"SY|Asia/Damascus",
  			"SZ|Africa/Johannesburg Africa/Mbabane",
  			"TC|America/Grand_Turk",
  			"TD|Africa/Ndjamena",
  			"TF|Indian/Reunion Indian/Kerguelen",
  			"TG|Africa/Abidjan Africa/Lome",
  			"TH|Asia/Bangkok",
  			"TJ|Asia/Dushanbe",
  			"TK|Pacific/Fakaofo",
  			"TL|Asia/Dili",
  			"TM|Asia/Ashgabat",
  			"TN|Africa/Tunis",
  			"TO|Pacific/Tongatapu",
  			"TR|Europe/Istanbul",
  			"TT|America/Port_of_Spain",
  			"TV|Pacific/Funafuti",
  			"TW|Asia/Taipei",
  			"TZ|Africa/Nairobi Africa/Dar_es_Salaam",
  			"UA|Europe/Simferopol Europe/Kiev Europe/Uzhgorod Europe/Zaporozhye",
  			"UG|Africa/Nairobi Africa/Kampala",
  			"UM|Pacific/Pago_Pago Pacific/Wake Pacific/Honolulu Pacific/Midway",
  			"US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu",
  			"UY|America/Montevideo",
  			"UZ|Asia/Samarkand Asia/Tashkent",
  			"VA|Europe/Rome Europe/Vatican",
  			"VC|America/Port_of_Spain America/St_Vincent",
  			"VE|America/Caracas",
  			"VG|America/Port_of_Spain America/Tortola",
  			"VI|America/Port_of_Spain America/St_Thomas",
  			"VN|Asia/Bangkok Asia/Ho_Chi_Minh",
  			"VU|Pacific/Efate",
  			"WF|Pacific/Wallis",
  			"WS|Pacific/Apia",
  			"YE|Asia/Riyadh Asia/Aden",
  			"YT|Africa/Nairobi Indian/Mayotte",
  			"ZA|Africa/Johannesburg",
  			"ZM|Africa/Maputo Africa/Lusaka",
  			"ZW|Africa/Maputo Africa/Harare"
  		]
  	});
  
  
  	return moment;
  }));
  
  /*@preserve
   * Tempus Dominus Bootstrap4 v5.1.2 (https://tempusdominus.github.io/bootstrap-4/)
   * Copyright 2016-2018 Jonathan Peterson
   * Licensed under MIT (https://github.com/tempusdominus/bootstrap-3/blob/master/LICENSE)
   */
  
  if (typeof jQuery === 'undefined') {
    throw new Error('Tempus Dominus Bootstrap4\'s requires jQuery. jQuery must be included before Tempus Dominus Bootstrap4\'s JavaScript.');
  }
  
  +function ($) {
    var version = $.fn.jquery.split(' ')[0].split('.');
    if ((version[0] < 2 && version[1] < 9) || (version[0] === 1 && version[1] === 9 && version[2] < 1) || (version[0] >= 4)) {
      throw new Error('Tempus Dominus Bootstrap4\'s requires at least jQuery v3.0.0 but less than v4.0.0');
    }
  }(jQuery);
  
  
  if (typeof moment === 'undefined') {
    throw new Error('Tempus Dominus Bootstrap4\'s requires moment.js. Moment.js must be included before Tempus Dominus Bootstrap4\'s JavaScript.');
  }
  
  var version = moment.version.split('.')
  if ((version[0] <= 2 && version[1] < 17) || (version[0] >= 3)) {
    throw new Error('Tempus Dominus Bootstrap4\'s requires at least moment.js v2.17.0 but less than v3.0.0');
  }
  
  +function () {
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  // ReSharper disable once InconsistentNaming
  var DateTimePicker = function ($, moment) {
      // ReSharper disable InconsistentNaming
      var NAME = 'datetimepicker',
          DATA_KEY = '' + NAME,
          EVENT_KEY = '.' + DATA_KEY,
          DATA_API_KEY = '.data-api',
          Selector = {
          DATA_TOGGLE: '[data-toggle="' + DATA_KEY + '"]'
      },
          ClassName = {
          INPUT: NAME + '-input'
      },
          Event = {
          CHANGE: 'change' + EVENT_KEY,
          BLUR: 'blur' + EVENT_KEY,
          KEYUP: 'keyup' + EVENT_KEY,
          KEYDOWN: 'keydown' + EVENT_KEY,
          FOCUS: 'focus' + EVENT_KEY,
          CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
          //emitted
          UPDATE: 'update' + EVENT_KEY,
          ERROR: 'error' + EVENT_KEY,
          HIDE: 'hide' + EVENT_KEY,
          SHOW: 'show' + EVENT_KEY
      },
          DatePickerModes = [{
          CLASS_NAME: 'days',
          NAV_FUNCTION: 'M',
          NAV_STEP: 1
      }, {
          CLASS_NAME: 'months',
          NAV_FUNCTION: 'y',
          NAV_STEP: 1
      }, {
          CLASS_NAME: 'years',
          NAV_FUNCTION: 'y',
          NAV_STEP: 10
      }, {
          CLASS_NAME: 'decades',
          NAV_FUNCTION: 'y',
          NAV_STEP: 100
      }],
          KeyMap = {
          'up': 38,
          38: 'up',
          'down': 40,
          40: 'down',
          'left': 37,
          37: 'left',
          'right': 39,
          39: 'right',
          'tab': 9,
          9: 'tab',
          'escape': 27,
          27: 'escape',
          'enter': 13,
          13: 'enter',
          'pageUp': 33,
          33: 'pageUp',
          'pageDown': 34,
          34: 'pageDown',
          'shift': 16,
          16: 'shift',
          'control': 17,
          17: 'control',
          'space': 32,
          32: 'space',
          't': 84,
          84: 't',
          'delete': 46,
          46: 'delete'
      },
          ViewModes = ['times', 'days', 'months', 'years', 'decades'],
          keyState = {},
          keyPressHandled = {};
  
      var Default = {
          timeZone: '',
          format: false,
          dayViewHeaderFormat: 'MMMM YYYY',
          extraFormats: false,
          stepping: 1,
          minDate: false,
          maxDate: false,
          useCurrent: true,
          collapse: true,
          locale: moment.locale(),
          defaultDate: false,
          disabledDates: false,
          enabledDates: false,
          icons: {
              time: 'fa fa-clock-o',
              date: 'fa fa-calendar',
              up: 'fa fa-arrow-up',
              down: 'fa fa-arrow-down',
              previous: 'fa fa-chevron-left',
              next: 'fa fa-chevron-right',
              today: 'fa fa-calendar-check-o',
              clear: 'fa fa-delete',
              close: 'fa fa-times'
          },
          tooltips: {
              today: 'Go to today',
              clear: 'Clear selection',
              close: 'Close the picker',
              selectMonth: 'Select Month',
              prevMonth: 'Previous Month',
              nextMonth: 'Next Month',
              selectYear: 'Select Year',
              prevYear: 'Previous Year',
              nextYear: 'Next Year',
              selectDecade: 'Select Decade',
              prevDecade: 'Previous Decade',
              nextDecade: 'Next Decade',
              prevCentury: 'Previous Century',
              nextCentury: 'Next Century',
              pickHour: 'Pick Hour',
              incrementHour: 'Increment Hour',
              decrementHour: 'Decrement Hour',
              pickMinute: 'Pick Minute',
              incrementMinute: 'Increment Minute',
              decrementMinute: 'Decrement Minute',
              pickSecond: 'Pick Second',
              incrementSecond: 'Increment Second',
              decrementSecond: 'Decrement Second',
              togglePeriod: 'Toggle Period',
              selectTime: 'Select Time',
              selectDate: 'Select Date'
          },
          useStrict: false,
          sideBySide: false,
          daysOfWeekDisabled: false,
          calendarWeeks: false,
          viewMode: 'days',
          toolbarPlacement: 'default',
          buttons: {
              showToday: false,
              showClear: false,
              showClose: false
          },
          widgetPositioning: {
              horizontal: 'auto',
              vertical: 'auto'
          },
          widgetParent: null,
          ignoreReadonly: false,
          keepOpen: false,
          focusOnShow: true,
          inline: false,
          keepInvalid: false,
          keyBinds: {
              up: function up() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().subtract(7, 'd'));
                  } else {
                      this.date(d.clone().add(this.stepping(), 'm'));
                  }
                  return true;
              },
              down: function down() {
                  if (!this.widget) {
                      this.show();
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().add(7, 'd'));
                  } else {
                      this.date(d.clone().subtract(this.stepping(), 'm'));
                  }
                  return true;
              },
              'control up': function controlUp() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().subtract(1, 'y'));
                  } else {
                      this.date(d.clone().add(1, 'h'));
                  }
                  return true;
              },
              'control down': function controlDown() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().add(1, 'y'));
                  } else {
                      this.date(d.clone().subtract(1, 'h'));
                  }
                  return true;
              },
              left: function left() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().subtract(1, 'd'));
                  }
                  return true;
              },
              right: function right() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().add(1, 'd'));
                  }
                  return true;
              },
              pageUp: function pageUp() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().subtract(1, 'M'));
                  }
                  return true;
              },
              pageDown: function pageDown() {
                  if (!this.widget) {
                      return false;
                  }
                  var d = this._dates[0] || this.getMoment();
                  if (this.widget.find('.datepicker').is(':visible')) {
                      this.date(d.clone().add(1, 'M'));
                  }
                  return true;
              },
              enter: function enter() {
                  if (!this.widget) {
                      return false;
                  }
                  this.hide();
                  return true;
              },
              escape: function escape() {
                  if (!this.widget) {
                      return false;
                  }
                  this.hide();
                  return true;
              },
              'control space': function controlSpace() {
                  if (!this.widget) {
                      return false;
                  }
                  if (this.widget.find('.timepicker').is(':visible')) {
                      this.widget.find('.btn[data-action="togglePeriod"]').click();
                  }
                  return true;
              },
              t: function t() {
                  if (!this.widget) {
                      return false;
                  }
                  this.date(this.getMoment());
                  return true;
              },
              'delete': function _delete() {
                  if (!this.widget) {
                      return false;
                  }
                  this.clear();
                  return true;
              }
          },
          debug: false,
          allowInputToggle: false,
          disabledTimeIntervals: false,
          disabledHours: false,
          enabledHours: false,
          viewDate: false,
          allowMultidate: false,
          multidateSeparator: ','
      };
  
      // ReSharper restore InconsistentNaming
  
      // ReSharper disable once DeclarationHides
      // ReSharper disable once InconsistentNaming
  
      var DateTimePicker = function () {
          /** @namespace eData.dateOptions */
          /** @namespace moment.tz */
  
          function DateTimePicker(element, options) {
              _classCallCheck(this, DateTimePicker);
  
              this._options = this._getOptions(options);
              this._element = element;
              this._dates = [];
              this._datesFormatted = [];
              this._viewDate = null;
              this.unset = true;
              this.component = false;
              this.widget = false;
              this.use24Hours = null;
              this.actualFormat = null;
              this.parseFormats = null;
              this.currentViewMode = null;
              this.MinViewModeNumber = 0;
  
              this._int();
          }
  
          /**
           * @return {string}
           */
  
  
          //private
  
          DateTimePicker.prototype._int = function _int() {
              var targetInput = this._element.data('target-input');
              if (this._element.is('input')) {
                  this.input = this._element;
              } else if (targetInput !== undefined) {
                  if (targetInput === 'nearest') {
                      this.input = this._element.find('input');
                  } else {
                      this.input = $(targetInput);
                  }
              }
  
              this._dates = [];
              this._dates[0] = this.getMoment();
              this._viewDate = this.getMoment().clone();
  
              $.extend(true, this._options, this._dataToOptions());
  
              this.options(this._options);
  
              this._initFormatting();
  
              if (this.input !== undefined && this.input.is('input') && this.input.val().trim().length !== 0) {
                  this._setValue(this._parseInputDate(this.input.val().trim()), 0);
              } else if (this._options.defaultDate && this.input !== undefined && this.input.attr('placeholder') === undefined) {
                  this._setValue(this._options.defaultDate, 0);
              }
              if (this._options.inline) {
                  this.show();
              }
          };
  
          DateTimePicker.prototype._update = function _update() {
              if (!this.widget) {
                  return;
              }
              this._fillDate();
              this._fillTime();
          };
  
          DateTimePicker.prototype._setValue = function _setValue(targetMoment, index) {
              var oldDate = this.unset ? null : this._dates[index];
              var outpValue = '';
              // case of calling setValue(null or false)
              if (!targetMoment) {
                  if (!this._options.allowMultidate || this._dates.length === 1) {
                      this.unset = true;
                      this._dates = [];
                      this._datesFormatted = [];
                  } else {
                      outpValue = this._element.data('date') + ',';
                      outpValue = outpValue.replace(oldDate.format(this.actualFormat) + ',', '').replace(',,', '').replace(/,\s*$/, '');
                      this._dates.splice(index, 1);
                      this._datesFormatted.splice(index, 1);
                  }
                  if (this.input !== undefined) {
                      this.input.val(outpValue);
                      this.input.trigger('input');
                  }
                  this._element.data('date', outpValue);
                  this._notifyEvent({
                      type: DateTimePicker.Event.CHANGE,
                      date: false,
                      oldDate: oldDate
                  });
                  this._update();
                  return;
              }
  
              targetMoment = targetMoment.clone().locale(this._options.locale);
  
              if (this._hasTimeZone()) {
                  targetMoment.tz(this._options.timeZone);
              }
  
              if (this._options.stepping !== 1) {
                  targetMoment.minutes(Math.round(targetMoment.minutes() / this._options.stepping) * this._options.stepping).seconds(0);
              }
  
              if (this._isValid(targetMoment)) {
                  this._dates[index] = targetMoment;
                  this._datesFormatted[index] = targetMoment.format('YYYY-MM-DD');
                  this._viewDate = targetMoment.clone();
                  if (this._options.allowMultidate && this._dates.length > 1) {
                      for (var i = 0; i < this._dates.length; i++) {
                          outpValue += '' + this._dates[i].format(this.actualFormat) + this._options.multidateSeparator;
                      }
                      outpValue = outpValue.replace(/,\s*$/, '');
                  } else {
                      outpValue = this._dates[index].format(this.actualFormat);
                  }
                  if (this.input !== undefined) {
                      this.input.val(outpValue);
                      this.input.trigger('input');
                  }
                  this._element.data('date', outpValue);
  
                  this.unset = false;
                  this._update();
                  this._notifyEvent({
                      type: DateTimePicker.Event.CHANGE,
                      date: this._dates[index].clone(),
                      oldDate: oldDate
                  });
              } else {
                  if (!this._options.keepInvalid) {
                      if (this.input !== undefined) {
                          this.input.val('' + (this.unset ? '' : this._dates[index].format(this.actualFormat)));
                          this.input.trigger('input');
                      }
                  } else {
                      this._notifyEvent({
                          type: DateTimePicker.Event.CHANGE,
                          date: targetMoment,
                          oldDate: oldDate
                      });
                  }
                  this._notifyEvent({
                      type: DateTimePicker.Event.ERROR,
                      date: targetMoment,
                      oldDate: oldDate
                  });
              }
          };
  
          DateTimePicker.prototype._change = function _change(e) {
              var val = $(e.target).val().trim(),
                  parsedDate = val ? this._parseInputDate(val) : null;
              this._setValue(parsedDate);
              e.stopImmediatePropagation();
              return false;
          };
  
          //noinspection JSMethodCanBeStatic
  
  
          DateTimePicker.prototype._getOptions = function _getOptions(options) {
              options = $.extend(true, {}, Default, options);
              return options;
          };
  
          DateTimePicker.prototype._hasTimeZone = function _hasTimeZone() {
              return moment.tz !== undefined && this._options.timeZone !== undefined && this._options.timeZone !== null && this._options.timeZone !== '';
          };
  
          DateTimePicker.prototype._isEnabled = function _isEnabled(granularity) {
              if (typeof granularity !== 'string' || granularity.length > 1) {
                  throw new TypeError('isEnabled expects a single character string parameter');
              }
              switch (granularity) {
                  case 'y':
                      return this.actualFormat.indexOf('Y') !== -1;
                  case 'M':
                      return this.actualFormat.indexOf('M') !== -1;
                  case 'd':
                      return this.actualFormat.toLowerCase().indexOf('d') !== -1;
                  case 'h':
                  case 'H':
                      return this.actualFormat.toLowerCase().indexOf('h') !== -1;
                  case 'm':
                      return this.actualFormat.indexOf('m') !== -1;
                  case 's':
                      return this.actualFormat.indexOf('s') !== -1;
                  case 'a':
                  case 'A':
                      return this.actualFormat.toLowerCase().indexOf('a') !== -1;
                  default:
                      return false;
              }
          };
  
          DateTimePicker.prototype._hasTime = function _hasTime() {
              return this._isEnabled('h') || this._isEnabled('m') || this._isEnabled('s');
          };
  
          DateTimePicker.prototype._hasDate = function _hasDate() {
              return this._isEnabled('y') || this._isEnabled('M') || this._isEnabled('d');
          };
  
          DateTimePicker.prototype._dataToOptions = function _dataToOptions() {
              var eData = this._element.data();
              var dataOptions = {};
  
              if (eData.dateOptions && eData.dateOptions instanceof Object) {
                  dataOptions = $.extend(true, dataOptions, eData.dateOptions);
              }
  
              $.each(this._options, function (key) {
                  var attributeName = 'date' + key.charAt(0).toUpperCase() + key.slice(1); //todo data api key
                  if (eData[attributeName] !== undefined) {
                      dataOptions[key] = eData[attributeName];
                  } else {
                      delete dataOptions[key];
                  }
              });
              return dataOptions;
          };
  
          DateTimePicker.prototype._notifyEvent = function _notifyEvent(e) {
              if (e.type === DateTimePicker.Event.CHANGE && (e.date && e.date.isSame(e.oldDate)) || !e.date && !e.oldDate) {
                  return;
              }
              this._element.trigger(e);
          };
  
          DateTimePicker.prototype._viewUpdate = function _viewUpdate(e) {
              if (e === 'y') {
                  e = 'YYYY';
              }
              this._notifyEvent({
                  type: DateTimePicker.Event.UPDATE,
                  change: e,
                  viewDate: this._viewDate.clone()
              });
          };
  
          DateTimePicker.prototype._showMode = function _showMode(dir) {
              if (!this.widget) {
                  return;
              }
              if (dir) {
                  this.currentViewMode = Math.max(this.MinViewModeNumber, Math.min(3, this.currentViewMode + dir));
              }
              this.widget.find('.datepicker > div').hide().filter('.datepicker-' + DatePickerModes[this.currentViewMode].CLASS_NAME).show();
          };
  
          DateTimePicker.prototype._isInDisabledDates = function _isInDisabledDates(testDate) {
              return this._options.disabledDates[testDate.format('YYYY-MM-DD')] === true;
          };
  
          DateTimePicker.prototype._isInEnabledDates = function _isInEnabledDates(testDate) {
              return this._options.enabledDates[testDate.format('YYYY-MM-DD')] === true;
          };
  
          DateTimePicker.prototype._isInDisabledHours = function _isInDisabledHours(testDate) {
              return this._options.disabledHours[testDate.format('H')] === true;
          };
  
          DateTimePicker.prototype._isInEnabledHours = function _isInEnabledHours(testDate) {
              return this._options.enabledHours[testDate.format('H')] === true;
          };
  
          DateTimePicker.prototype._isValid = function _isValid(targetMoment, granularity) {
              if (!targetMoment.isValid()) {
                  return false;
              }
              if (this._options.disabledDates && granularity === 'd' && this._isInDisabledDates(targetMoment)) {
                  return false;
              }
              if (this._options.enabledDates && granularity === 'd' && !this._isInEnabledDates(targetMoment)) {
                  return false;
              }
              if (this._options.minDate && targetMoment.isBefore(this._options.minDate, granularity)) {
                  return false;
              }
              if (this._options.maxDate && targetMoment.isAfter(this._options.maxDate, granularity)) {
                  return false;
              }
              if (this._options.daysOfWeekDisabled && granularity === 'd' && this._options.daysOfWeekDisabled.indexOf(targetMoment.day()) !== -1) {
                  return false;
              }
              if (this._options.disabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && this._isInDisabledHours(targetMoment)) {
                  return false;
              }
              if (this._options.enabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && !this._isInEnabledHours(targetMoment)) {
                  return false;
              }
              if (this._options.disabledTimeIntervals && (granularity === 'h' || granularity === 'm' || granularity === 's')) {
                  var found = false;
                  $.each(this._options.disabledTimeIntervals, function () {
                      if (targetMoment.isBetween(this[0], this[1])) {
                          found = true;
                          return false;
                      }
                  });
                  if (found) {
                      return false;
                  }
              }
              return true;
          };
  
          DateTimePicker.prototype._parseInputDate = function _parseInputDate(inputDate) {
              if (this._options.parseInputDate === undefined) {
                  if (!moment.isMoment(inputDate)) {
                      inputDate = this.getMoment(inputDate);
                  }
              } else {
                  inputDate = this._options.parseInputDate(inputDate);
              }
              //inputDate.locale(this.options.locale);
              return inputDate;
          };
  
          DateTimePicker.prototype._keydown = function _keydown(e) {
              var handler = null,
                  index = void 0,
                  index2 = void 0,
                  keyBindKeys = void 0,
                  allModifiersPressed = void 0;
              var pressedKeys = [],
                  pressedModifiers = {},
                  currentKey = e.which,
                  pressed = 'p';
  
              keyState[currentKey] = pressed;
  
              for (index in keyState) {
                  if (keyState.hasOwnProperty(index) && keyState[index] === pressed) {
                      pressedKeys.push(index);
                      if (parseInt(index, 10) !== currentKey) {
                          pressedModifiers[index] = true;
                      }
                  }
              }
  
              for (index in this._options.keyBinds) {
                  if (this._options.keyBinds.hasOwnProperty(index) && typeof this._options.keyBinds[index] === 'function') {
                      keyBindKeys = index.split(' ');
                      if (keyBindKeys.length === pressedKeys.length && KeyMap[currentKey] === keyBindKeys[keyBindKeys.length - 1]) {
                          allModifiersPressed = true;
                          for (index2 = keyBindKeys.length - 2; index2 >= 0; index2--) {
                              if (!(KeyMap[keyBindKeys[index2]] in pressedModifiers)) {
                                  allModifiersPressed = false;
                                  break;
                              }
                          }
                          if (allModifiersPressed) {
                              handler = this._options.keyBinds[index];
                              break;
                          }
                      }
                  }
              }
  
              if (handler) {
                  if (handler.call(this)) {
                      e.stopPropagation();
                      e.preventDefault();
                  }
              }
          };
  
          //noinspection JSMethodCanBeStatic,SpellCheckingInspection
  
  
          DateTimePicker.prototype._keyup = function _keyup(e) {
              keyState[e.which] = 'r';
              if (keyPressHandled[e.which]) {
                  keyPressHandled[e.which] = false;
                  e.stopPropagation();
                  e.preventDefault();
              }
          };
  
          DateTimePicker.prototype._indexGivenDates = function _indexGivenDates(givenDatesArray) {
              // Store given enabledDates and disabledDates as keys.
              // This way we can check their existence in O(1) time instead of looping through whole array.
              // (for example: options.enabledDates['2014-02-27'] === true)
              var givenDatesIndexed = {},
                  self = this;
              $.each(givenDatesArray, function () {
                  var dDate = self._parseInputDate(this);
                  if (dDate.isValid()) {
                      givenDatesIndexed[dDate.format('YYYY-MM-DD')] = true;
                  }
              });
              return Object.keys(givenDatesIndexed).length ? givenDatesIndexed : false;
          };
  
          DateTimePicker.prototype._indexGivenHours = function _indexGivenHours(givenHoursArray) {
              // Store given enabledHours and disabledHours as keys.
              // This way we can check their existence in O(1) time instead of looping through whole array.
              // (for example: options.enabledHours['2014-02-27'] === true)
              var givenHoursIndexed = {};
              $.each(givenHoursArray, function () {
                  givenHoursIndexed[this] = true;
              });
              return Object.keys(givenHoursIndexed).length ? givenHoursIndexed : false;
          };
  
          DateTimePicker.prototype._initFormatting = function _initFormatting() {
              var format = this._options.format || 'L LT',
                  self = this;
  
              this.actualFormat = format.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, function (formatInput) {
                  return self._dates[0].localeData().longDateFormat(formatInput) || formatInput; //todo taking the first date should be ok
              });
  
              this.parseFormats = this._options.extraFormats ? this._options.extraFormats.slice() : [];
              if (this.parseFormats.indexOf(format) < 0 && this.parseFormats.indexOf(this.actualFormat) < 0) {
                  this.parseFormats.push(this.actualFormat);
              }
  
              this.use24Hours = this.actualFormat.toLowerCase().indexOf('a') < 1 && this.actualFormat.replace(/\[.*?]/g, '').indexOf('h') < 1;
  
              if (this._isEnabled('y')) {
                  this.MinViewModeNumber = 2;
              }
              if (this._isEnabled('M')) {
                  this.MinViewModeNumber = 1;
              }
              if (this._isEnabled('d')) {
                  this.MinViewModeNumber = 0;
              }
  
              this.currentViewMode = Math.max(this.MinViewModeNumber, this.currentViewMode);
  
              if (!this.unset) {
                  this._setValue(this._dates[0], 0);
              }
          };
  
          DateTimePicker.prototype._getLastPickedDate = function _getLastPickedDate() {
              return this._dates[this._getLastPickedDateIndex()];
          };
  
          DateTimePicker.prototype._getLastPickedDateIndex = function _getLastPickedDateIndex() {
              return this._dates.length - 1;
          };
  
          //public
  
  
          DateTimePicker.prototype.getMoment = function getMoment(d) {
              var returnMoment = void 0;
  
              if (d === undefined || d === null) {
                  returnMoment = moment(); //TODO should this use format? and locale?
              } else if (this._hasTimeZone()) {
                  // There is a string to parse and a default time zone
                  // parse with the tz function which takes a default time zone if it is not in the format string
                  returnMoment = moment.tz(d, this.parseFormats, this._options.locale, this._options.useStrict, this._options.timeZone);
              } else {
                  returnMoment = moment(d, this.parseFormats, this._options.locale, this._options.useStrict);
              }
  
              if (this._hasTimeZone()) {
                  returnMoment.tz(this._options.timeZone);
              }
  
              return returnMoment;
          };
  
          DateTimePicker.prototype.toggle = function toggle() {
              return this.widget ? this.hide() : this.show();
          };
  
          DateTimePicker.prototype.ignoreReadonly = function ignoreReadonly(_ignoreReadonly) {
              if (arguments.length === 0) {
                  return this._options.ignoreReadonly;
              }
              if (typeof _ignoreReadonly !== 'boolean') {
                  throw new TypeError('ignoreReadonly () expects a boolean parameter');
              }
              this._options.ignoreReadonly = _ignoreReadonly;
          };
  
          DateTimePicker.prototype.options = function options(newOptions) {
              if (arguments.length === 0) {
                  return $.extend(true, {}, this._options);
              }
  
              if (!(newOptions instanceof Object)) {
                  throw new TypeError('options() this.options parameter should be an object');
              }
              $.extend(true, this._options, newOptions);
              var self = this;
              $.each(this._options, function (key, value) {
                  if (self[key] !== undefined) {
                      self[key](value);
                  }
              });
          };
  
          DateTimePicker.prototype.date = function date(newDate, index) {
              index = index || 0;
              if (arguments.length === 0) {
                  if (this.unset) {
                      return null;
                  }
                  if (this._options.allowMultidate) {
                      return this._dates.join(this._options.multidateSeparator);
                  } else {
                      return this._dates[index].clone();
                  }
              }
  
              if (newDate !== null && typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
                  throw new TypeError('date() parameter must be one of [null, string, moment or Date]');
              }
  
              this._setValue(newDate === null ? null : this._parseInputDate(newDate), index);
          };
  
          DateTimePicker.prototype.format = function format(newFormat) {
              if (arguments.length === 0) {
                  return this._options.format;
              }
  
              if (typeof newFormat !== 'string' && (typeof newFormat !== 'boolean' || newFormat !== false)) {
                  throw new TypeError('format() expects a string or boolean:false parameter ' + newFormat);
              }
  
              this._options.format = newFormat;
              if (this.actualFormat) {
                  this._initFormatting(); // reinitialize formatting
              }
          };
  
          DateTimePicker.prototype.timeZone = function timeZone(newZone) {
              if (arguments.length === 0) {
                  return this._options.timeZone;
              }
  
              if (typeof newZone !== 'string') {
                  throw new TypeError('newZone() expects a string parameter');
              }
  
              this._options.timeZone = newZone;
          };
  
          DateTimePicker.prototype.dayViewHeaderFormat = function dayViewHeaderFormat(newFormat) {
              if (arguments.length === 0) {
                  return this._options.dayViewHeaderFormat;
              }
  
              if (typeof newFormat !== 'string') {
                  throw new TypeError('dayViewHeaderFormat() expects a string parameter');
              }
  
              this._options.dayViewHeaderFormat = newFormat;
          };
  
          DateTimePicker.prototype.extraFormats = function extraFormats(formats) {
              if (arguments.length === 0) {
                  return this._options.extraFormats;
              }
  
              if (formats !== false && !(formats instanceof Array)) {
                  throw new TypeError('extraFormats() expects an array or false parameter');
              }
  
              this._options.extraFormats = formats;
              if (this.parseFormats) {
                  this._initFormatting(); // reinit formatting
              }
          };
  
          DateTimePicker.prototype.disabledDates = function disabledDates(dates) {
              if (arguments.length === 0) {
                  return this._options.disabledDates ? $.extend({}, this._options.disabledDates) : this._options.disabledDates;
              }
  
              if (!dates) {
                  this._options.disabledDates = false;
                  this._update();
                  return true;
              }
              if (!(dates instanceof Array)) {
                  throw new TypeError('disabledDates() expects an array parameter');
              }
              this._options.disabledDates = this._indexGivenDates(dates);
              this._options.enabledDates = false;
              this._update();
          };
  
          DateTimePicker.prototype.enabledDates = function enabledDates(dates) {
              if (arguments.length === 0) {
                  return this._options.enabledDates ? $.extend({}, this._options.enabledDates) : this._options.enabledDates;
              }
  
              if (!dates) {
                  this._options.enabledDates = false;
                  this._update();
                  return true;
              }
              if (!(dates instanceof Array)) {
                  throw new TypeError('enabledDates() expects an array parameter');
              }
              this._options.enabledDates = this._indexGivenDates(dates);
              this._options.disabledDates = false;
              this._update();
          };
  
          DateTimePicker.prototype.daysOfWeekDisabled = function daysOfWeekDisabled(_daysOfWeekDisabled) {
              if (arguments.length === 0) {
                  return this._options.daysOfWeekDisabled.splice(0);
              }
  
              if (typeof _daysOfWeekDisabled === 'boolean' && !_daysOfWeekDisabled) {
                  this._options.daysOfWeekDisabled = false;
                  this._update();
                  return true;
              }
  
              if (!(_daysOfWeekDisabled instanceof Array)) {
                  throw new TypeError('daysOfWeekDisabled() expects an array parameter');
              }
              this._options.daysOfWeekDisabled = _daysOfWeekDisabled.reduce(function (previousValue, currentValue) {
                  currentValue = parseInt(currentValue, 10);
                  if (currentValue > 6 || currentValue < 0 || isNaN(currentValue)) {
                      return previousValue;
                  }
                  if (previousValue.indexOf(currentValue) === -1) {
                      previousValue.push(currentValue);
                  }
                  return previousValue;
              }, []).sort();
              if (this._options.useCurrent && !this._options.keepInvalid) {
                  for (var i = 0; i < this._dates.length; i++) {
                      var tries = 0;
                      while (!this._isValid(this._dates[i], 'd')) {
                          this._dates[i].add(1, 'd');
                          if (tries === 31) {
                              throw 'Tried 31 times to find a valid date';
                          }
                          tries++;
                      }
                      this._setValue(this._dates[i], i);
                  }
              }
              this._update();
          };
  
          DateTimePicker.prototype.maxDate = function maxDate(_maxDate) {
              if (arguments.length === 0) {
                  return this._options.maxDate ? this._options.maxDate.clone() : this._options.maxDate;
              }
  
              if (typeof _maxDate === 'boolean' && _maxDate === false) {
                  this._options.maxDate = false;
                  this._update();
                  return true;
              }
  
              if (typeof _maxDate === 'string') {
                  if (_maxDate === 'now' || _maxDate === 'moment') {
                      _maxDate = this.getMoment();
                  }
              }
  
              var parsedDate = this._parseInputDate(_maxDate);
  
              if (!parsedDate.isValid()) {
                  throw new TypeError('maxDate() Could not parse date parameter: ' + _maxDate);
              }
              if (this._options.minDate && parsedDate.isBefore(this._options.minDate)) {
                  throw new TypeError('maxDate() date parameter is before this.options.minDate: ' + parsedDate.format(this.actualFormat));
              }
              this._options.maxDate = parsedDate;
              for (var i = 0; i < this._dates.length; i++) {
                  if (this._options.useCurrent && !this._options.keepInvalid && this._dates[i].isAfter(_maxDate)) {
                      this._setValue(this._options.maxDate, i);
                  }
              }
              if (this._viewDate.isAfter(parsedDate)) {
                  this._viewDate = parsedDate.clone().subtract(this._options.stepping, 'm');
              }
              this._update();
          };
  
          DateTimePicker.prototype.minDate = function minDate(_minDate) {
              if (arguments.length === 0) {
                  return this._options.minDate ? this._options.minDate.clone() : this._options.minDate;
              }
  
              if (typeof _minDate === 'boolean' && _minDate === false) {
                  this._options.minDate = false;
                  this._update();
                  return true;
              }
  
              if (typeof _minDate === 'string') {
                  if (_minDate === 'now' || _minDate === 'moment') {
                      _minDate = this.getMoment();
                  }
              }
  
              var parsedDate = this._parseInputDate(_minDate);
  
              if (!parsedDate.isValid()) {
                  throw new TypeError('minDate() Could not parse date parameter: ' + _minDate);
              }
              if (this._options.maxDate && parsedDate.isAfter(this._options.maxDate)) {
                  throw new TypeError('minDate() date parameter is after this.options.maxDate: ' + parsedDate.format(this.actualFormat));
              }
              this._options.minDate = parsedDate;
              for (var i = 0; i < this._dates.length; i++) {
                  if (this._options.useCurrent && !this._options.keepInvalid && this._dates[i].isBefore(_minDate)) {
                      this._setValue(this._options.minDate, i);
                  }
              }
              if (this._viewDate.isBefore(parsedDate)) {
                  this._viewDate = parsedDate.clone().add(this._options.stepping, 'm');
              }
              this._update();
          };
  
          DateTimePicker.prototype.defaultDate = function defaultDate(_defaultDate) {
              if (arguments.length === 0) {
                  return this._options.defaultDate ? this._options.defaultDate.clone() : this._options.defaultDate;
              }
              if (!_defaultDate) {
                  this._options.defaultDate = false;
                  return true;
              }
  
              if (typeof _defaultDate === 'string') {
                  if (_defaultDate === 'now' || _defaultDate === 'moment') {
                      _defaultDate = this.getMoment();
                  } else {
                      _defaultDate = this.getMoment(_defaultDate);
                  }
              }
  
              var parsedDate = this._parseInputDate(_defaultDate);
              if (!parsedDate.isValid()) {
                  throw new TypeError('defaultDate() Could not parse date parameter: ' + _defaultDate);
              }
              if (!this._isValid(parsedDate)) {
                  throw new TypeError('defaultDate() date passed is invalid according to component setup validations');
              }
  
              this._options.defaultDate = parsedDate;
  
              if (this._options.defaultDate && this._options.inline || this.input !== undefined && this.input.val().trim() === '') {
                  this._setValue(this._options.defaultDate, 0);
              }
          };
  
          DateTimePicker.prototype.locale = function locale(_locale) {
              if (arguments.length === 0) {
                  return this._options.locale;
              }
  
              if (!moment.localeData(_locale)) {
                  throw new TypeError('locale() locale ' + _locale + ' is not loaded from moment locales!');
              }
  
              this._options.locale = _locale;
  
              for (var i = 0; i < this._dates.length; i++) {
                  this._dates[i].locale(this._options.locale);
              }
              this._viewDate.locale(this._options.locale);
  
              if (this.actualFormat) {
                  this._initFormatting(); // reinitialize formatting
              }
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.stepping = function stepping(_stepping) {
              if (arguments.length === 0) {
                  return this._options.stepping;
              }
  
              _stepping = parseInt(_stepping, 10);
              if (isNaN(_stepping) || _stepping < 1) {
                  _stepping = 1;
              }
              this._options.stepping = _stepping;
          };
  
          DateTimePicker.prototype.useCurrent = function useCurrent(_useCurrent) {
              var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];
              if (arguments.length === 0) {
                  return this._options.useCurrent;
              }
  
              if (typeof _useCurrent !== 'boolean' && typeof _useCurrent !== 'string') {
                  throw new TypeError('useCurrent() expects a boolean or string parameter');
              }
              if (typeof _useCurrent === 'string' && useCurrentOptions.indexOf(_useCurrent.toLowerCase()) === -1) {
                  throw new TypeError('useCurrent() expects a string parameter of ' + useCurrentOptions.join(', '));
              }
              this._options.useCurrent = _useCurrent;
          };
  
          DateTimePicker.prototype.collapse = function collapse(_collapse) {
              if (arguments.length === 0) {
                  return this._options.collapse;
              }
  
              if (typeof _collapse !== 'boolean') {
                  throw new TypeError('collapse() expects a boolean parameter');
              }
              if (this._options.collapse === _collapse) {
                  return true;
              }
              this._options.collapse = _collapse;
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.icons = function icons(_icons) {
              if (arguments.length === 0) {
                  return $.extend({}, this._options.icons);
              }
  
              if (!(_icons instanceof Object)) {
                  throw new TypeError('icons() expects parameter to be an Object');
              }
  
              $.extend(this._options.icons, _icons);
  
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.tooltips = function tooltips(_tooltips) {
              if (arguments.length === 0) {
                  return $.extend({}, this._options.tooltips);
              }
  
              if (!(_tooltips instanceof Object)) {
                  throw new TypeError('tooltips() expects parameter to be an Object');
              }
              $.extend(this._options.tooltips, _tooltips);
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.useStrict = function useStrict(_useStrict) {
              if (arguments.length === 0) {
                  return this._options.useStrict;
              }
  
              if (typeof _useStrict !== 'boolean') {
                  throw new TypeError('useStrict() expects a boolean parameter');
              }
              this._options.useStrict = _useStrict;
          };
  
          DateTimePicker.prototype.sideBySide = function sideBySide(_sideBySide) {
              if (arguments.length === 0) {
                  return this._options.sideBySide;
              }
  
              if (typeof _sideBySide !== 'boolean') {
                  throw new TypeError('sideBySide() expects a boolean parameter');
              }
              this._options.sideBySide = _sideBySide;
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.viewMode = function viewMode(_viewMode) {
              if (arguments.length === 0) {
                  return this._options.viewMode;
              }
  
              if (typeof _viewMode !== 'string') {
                  throw new TypeError('viewMode() expects a string parameter');
              }
  
              if (DateTimePicker.ViewModes.indexOf(_viewMode) === -1) {
                  throw new TypeError('viewMode() parameter must be one of (' + DateTimePicker.ViewModes.join(', ') + ') value');
              }
  
              this._options.viewMode = _viewMode;
              this.currentViewMode = Math.max(DateTimePicker.ViewModes.indexOf(_viewMode) - 1, this.MinViewModeNumber);
  
              this._showMode();
          };
  
          DateTimePicker.prototype.calendarWeeks = function calendarWeeks(_calendarWeeks) {
              if (arguments.length === 0) {
                  return this._options.calendarWeeks;
              }
  
              if (typeof _calendarWeeks !== 'boolean') {
                  throw new TypeError('calendarWeeks() expects parameter to be a boolean value');
              }
  
              this._options.calendarWeeks = _calendarWeeks;
              this._update();
          };
  
          DateTimePicker.prototype.buttons = function buttons(_buttons) {
              if (arguments.length === 0) {
                  return $.extend({}, this._options.buttons);
              }
  
              if (!(_buttons instanceof Object)) {
                  throw new TypeError('buttons() expects parameter to be an Object');
              }
  
              $.extend(this._options.buttons, _buttons);
  
              if (typeof this._options.buttons.showToday !== 'boolean') {
                  throw new TypeError('buttons.showToday expects a boolean parameter');
              }
              if (typeof this._options.buttons.showClear !== 'boolean') {
                  throw new TypeError('buttons.showClear expects a boolean parameter');
              }
              if (typeof this._options.buttons.showClose !== 'boolean') {
                  throw new TypeError('buttons.showClose expects a boolean parameter');
              }
  
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          DateTimePicker.prototype.keepOpen = function keepOpen(_keepOpen) {
              if (arguments.length === 0) {
                  return this._options.keepOpen;
              }
  
              if (typeof _keepOpen !== 'boolean') {
                  throw new TypeError('keepOpen() expects a boolean parameter');
              }
  
              this._options.keepOpen = _keepOpen;
          };
  
          DateTimePicker.prototype.focusOnShow = function focusOnShow(_focusOnShow) {
              if (arguments.length === 0) {
                  return this._options.focusOnShow;
              }
  
              if (typeof _focusOnShow !== 'boolean') {
                  throw new TypeError('focusOnShow() expects a boolean parameter');
              }
  
              this._options.focusOnShow = _focusOnShow;
          };
  
          DateTimePicker.prototype.inline = function inline(_inline) {
              if (arguments.length === 0) {
                  return this._options.inline;
              }
  
              if (typeof _inline !== 'boolean') {
                  throw new TypeError('inline() expects a boolean parameter');
              }
  
              this._options.inline = _inline;
          };
  
          DateTimePicker.prototype.clear = function clear() {
              this._setValue(null); //todo
          };
  
          DateTimePicker.prototype.keyBinds = function keyBinds(_keyBinds) {
              if (arguments.length === 0) {
                  return this._options.keyBinds;
              }
  
              this._options.keyBinds = _keyBinds;
          };
  
          DateTimePicker.prototype.debug = function debug(_debug) {
              if (typeof _debug !== 'boolean') {
                  throw new TypeError('debug() expects a boolean parameter');
              }
  
              this._options.debug = _debug;
          };
  
          DateTimePicker.prototype.allowInputToggle = function allowInputToggle(_allowInputToggle) {
              if (arguments.length === 0) {
                  return this._options.allowInputToggle;
              }
  
              if (typeof _allowInputToggle !== 'boolean') {
                  throw new TypeError('allowInputToggle() expects a boolean parameter');
              }
  
              this._options.allowInputToggle = _allowInputToggle;
          };
  
          DateTimePicker.prototype.keepInvalid = function keepInvalid(_keepInvalid) {
              if (arguments.length === 0) {
                  return this._options.keepInvalid;
              }
  
              if (typeof _keepInvalid !== 'boolean') {
                  throw new TypeError('keepInvalid() expects a boolean parameter');
              }
              this._options.keepInvalid = _keepInvalid;
          };
  
          DateTimePicker.prototype.datepickerInput = function datepickerInput(_datepickerInput) {
              if (arguments.length === 0) {
                  return this._options.datepickerInput;
              }
  
              if (typeof _datepickerInput !== 'string') {
                  throw new TypeError('datepickerInput() expects a string parameter');
              }
  
              this._options.datepickerInput = _datepickerInput;
          };
  
          DateTimePicker.prototype.parseInputDate = function parseInputDate(_parseInputDate2) {
              if (arguments.length === 0) {
                  return this._options.parseInputDate;
              }
  
              if (typeof _parseInputDate2 !== 'function') {
                  throw new TypeError('parseInputDate() should be as function');
              }
  
              this._options.parseInputDate = _parseInputDate2;
          };
  
          DateTimePicker.prototype.disabledTimeIntervals = function disabledTimeIntervals(_disabledTimeIntervals) {
              if (arguments.length === 0) {
                  return this._options.disabledTimeIntervals ? $.extend({}, this._options.disabledTimeIntervals) : this._options.disabledTimeIntervals;
              }
  
              if (!_disabledTimeIntervals) {
                  this._options.disabledTimeIntervals = false;
                  this._update();
                  return true;
              }
              if (!(_disabledTimeIntervals instanceof Array)) {
                  throw new TypeError('disabledTimeIntervals() expects an array parameter');
              }
              this._options.disabledTimeIntervals = _disabledTimeIntervals;
              this._update();
          };
  
          DateTimePicker.prototype.disabledHours = function disabledHours(hours) {
              if (arguments.length === 0) {
                  return this._options.disabledHours ? $.extend({}, this._options.disabledHours) : this._options.disabledHours;
              }
  
              if (!hours) {
                  this._options.disabledHours = false;
                  this._update();
                  return true;
              }
              if (!(hours instanceof Array)) {
                  throw new TypeError('disabledHours() expects an array parameter');
              }
              this._options.disabledHours = this._indexGivenHours(hours);
              this._options.enabledHours = false;
              if (this._options.useCurrent && !this._options.keepInvalid) {
                  for (var i = 0; i < this._dates.length; i++) {
                      var tries = 0;
                      while (!this._isValid(this._dates[i], 'h')) {
                          this._dates[i].add(1, 'h');
                          if (tries === 24) {
                              throw 'Tried 24 times to find a valid date';
                          }
                          tries++;
                      }
                      this._setValue(this._dates[i], i);
                  }
              }
              this._update();
          };
  
          DateTimePicker.prototype.enabledHours = function enabledHours(hours) {
              if (arguments.length === 0) {
                  return this._options.enabledHours ? $.extend({}, this._options.enabledHours) : this._options.enabledHours;
              }
  
              if (!hours) {
                  this._options.enabledHours = false;
                  this._update();
                  return true;
              }
              if (!(hours instanceof Array)) {
                  throw new TypeError('enabledHours() expects an array parameter');
              }
              this._options.enabledHours = this._indexGivenHours(hours);
              this._options.disabledHours = false;
              if (this._options.useCurrent && !this._options.keepInvalid) {
                  for (var i = 0; i < this._dates.length; i++) {
                      var tries = 0;
                      while (!this._isValid(this._dates[i], 'h')) {
                          this._dates[i].add(1, 'h');
                          if (tries === 24) {
                              throw 'Tried 24 times to find a valid date';
                          }
                          tries++;
                      }
                      this._setValue(this._dates[i], i);
                  }
              }
              this._update();
          };
  
          DateTimePicker.prototype.viewDate = function viewDate(newDate) {
              if (arguments.length === 0) {
                  return this._viewDate.clone();
              }
  
              if (!newDate) {
                  this._viewDate = (this._dates[0] || this.getMoment()).clone();
                  return true;
              }
  
              if (typeof newDate !== 'string' && !moment.isMoment(newDate) && !(newDate instanceof Date)) {
                  throw new TypeError('viewDate() parameter must be one of [string, moment or Date]');
              }
  
              this._viewDate = this._parseInputDate(newDate);
              this._viewUpdate();
          };
  
          DateTimePicker.prototype.allowMultidate = function allowMultidate(_allowMultidate) {
              if (typeof _allowMultidate !== 'boolean') {
                  throw new TypeError('allowMultidate() expects a boolean parameter');
              }
  
              this._options.allowMultidate = _allowMultidate;
          };
  
          DateTimePicker.prototype.multidateSeparator = function multidateSeparator(_multidateSeparator) {
              if (arguments.length === 0) {
                  return this._options.multidateSeparator;
              }
  
              if (typeof _multidateSeparator !== 'string' || _multidateSeparator.length > 1) {
                  throw new TypeError('multidateSeparator expects a single character string parameter');
              }
  
              this._options.multidateSeparator = _multidateSeparator;
          };
  
          _createClass(DateTimePicker, null, [{
              key: 'NAME',
              get: function get() {
                  return NAME;
              }
  
              /**
               * @return {string}
               */
  
          }, {
              key: 'DATA_KEY',
              get: function get() {
                  return DATA_KEY;
              }
  
              /**
               * @return {string}
               */
  
          }, {
              key: 'EVENT_KEY',
              get: function get() {
                  return EVENT_KEY;
              }
  
              /**
               * @return {string}
               */
  
          }, {
              key: 'DATA_API_KEY',
              get: function get() {
                  return DATA_API_KEY;
              }
          }, {
              key: 'DatePickerModes',
              get: function get() {
                  return DatePickerModes;
              }
          }, {
              key: 'ViewModes',
              get: function get() {
                  return ViewModes;
              }
          }, {
              key: 'Event',
              get: function get() {
                  return Event;
              }
          }, {
              key: 'Selector',
              get: function get() {
                  return Selector;
              }
          }, {
              key: 'Default',
              get: function get() {
                  return Default;
              },
              set: function set(value) {
                  Default = value;
              }
          }, {
              key: 'ClassName',
              get: function get() {
                  return ClassName;
              }
          }]);
  
          return DateTimePicker;
      }();
  
      return DateTimePicker;
  }(jQuery, moment);
  
  //noinspection JSUnusedGlobalSymbols
  /* global DateTimePicker */
  var TempusDominusBootstrap4 = function ($) {
      // eslint-disable-line no-unused-vars
      // ReSharper disable once InconsistentNaming
      var JQUERY_NO_CONFLICT = $.fn[DateTimePicker.NAME],
          verticalModes = ['top', 'bottom', 'auto'],
          horizontalModes = ['left', 'right', 'auto'],
          toolbarPlacements = ['default', 'top', 'bottom'],
          getSelectorFromElement = function getSelectorFromElement($element) {
          var selector = $element.data('target'),
              $selector = void 0;
  
          if (!selector) {
              selector = $element.attr('href') || '';
              selector = /^#[a-z]/i.test(selector) ? selector : null;
          }
          $selector = $(selector);
          if ($selector.length === 0) {
              return $selector;
          }
  
          if (!$selector.data(DateTimePicker.DATA_KEY)) {
              $.extend({}, $selector.data(), $(this).data());
          }
  
          return $selector;
      };
  
      // ReSharper disable once InconsistentNaming
  
      var TempusDominusBootstrap4 = function (_DateTimePicker) {
          _inherits(TempusDominusBootstrap4, _DateTimePicker);
  
          function TempusDominusBootstrap4(element, options) {
              _classCallCheck(this, TempusDominusBootstrap4);
  
              var _this = _possibleConstructorReturn(this, _DateTimePicker.call(this, element, options));
  
              _this._init();
              return _this;
          }
  
          TempusDominusBootstrap4.prototype._init = function _init() {
              if (this._element.hasClass('input-group')) {
                  var datepickerButton = this._element.find('.datepickerbutton');
                  if (datepickerButton.length === 0) {
                      this.component = this._element.find('[data-toggle="datetimepicker"]');
                  } else {
                      this.component = datepickerButton;
                  }
              }
          };
  
          TempusDominusBootstrap4.prototype._getDatePickerTemplate = function _getDatePickerTemplate() {
              var headTemplate = $('<thead>').append($('<tr>').append($('<th>').addClass('prev').attr('data-action', 'previous').append($('<span>').addClass(this._options.icons.previous))).append($('<th>').addClass('picker-switch').attr('data-action', 'pickerSwitch').attr('colspan', '' + (this._options.calendarWeeks ? '6' : '5'))).append($('<th>').addClass('next').attr('data-action', 'next').append($('<span>').addClass(this._options.icons.next)))),
                  contTemplate = $('<tbody>').append($('<tr>').append($('<td>').attr('colspan', '' + (this._options.calendarWeeks ? '8' : '7'))));
  
              return [$('<div>').addClass('datepicker-days').append($('<table>').addClass('table table-sm').append(headTemplate).append($('<tbody>'))), $('<div>').addClass('datepicker-months').append($('<table>').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('<div>').addClass('datepicker-years').append($('<table>').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('<div>').addClass('datepicker-decades').append($('<table>').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone()))];
          };
  
          TempusDominusBootstrap4.prototype._getTimePickerMainTemplate = function _getTimePickerMainTemplate() {
              var topRow = $('<tr>'),
                  middleRow = $('<tr>'),
                  bottomRow = $('<tr>');
  
              if (this._isEnabled('h')) {
                  topRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.incrementHour
                  }).addClass('btn').attr('data-action', 'incrementHours').append($('<span>').addClass(this._options.icons.up))));
                  middleRow.append($('<td>').append($('<span>').addClass('timepicker-hour').attr({
                      'data-time-component': 'hours',
                      'title': this._options.tooltips.pickHour
                  }).attr('data-action', 'showHours')));
                  bottomRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.decrementHour
                  }).addClass('btn').attr('data-action', 'decrementHours').append($('<span>').addClass(this._options.icons.down))));
              }
              if (this._isEnabled('m')) {
                  if (this._isEnabled('h')) {
                      topRow.append($('<td>').addClass('separator'));
                      middleRow.append($('<td>').addClass('separator').html(':'));
                      bottomRow.append($('<td>').addClass('separator'));
                  }
                  topRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.incrementMinute
                  }).addClass('btn').attr('data-action', 'incrementMinutes').append($('<span>').addClass(this._options.icons.up))));
                  middleRow.append($('<td>').append($('<span>').addClass('timepicker-minute').attr({
                      'data-time-component': 'minutes',
                      'title': this._options.tooltips.pickMinute
                  }).attr('data-action', 'showMinutes')));
                  bottomRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.decrementMinute
                  }).addClass('btn').attr('data-action', 'decrementMinutes').append($('<span>').addClass(this._options.icons.down))));
              }
              if (this._isEnabled('s')) {
                  if (this._isEnabled('m')) {
                      topRow.append($('<td>').addClass('separator'));
                      middleRow.append($('<td>').addClass('separator').html(':'));
                      bottomRow.append($('<td>').addClass('separator'));
                  }
                  topRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.incrementSecond
                  }).addClass('btn').attr('data-action', 'incrementSeconds').append($('<span>').addClass(this._options.icons.up))));
                  middleRow.append($('<td>').append($('<span>').addClass('timepicker-second').attr({
                      'data-time-component': 'seconds',
                      'title': this._options.tooltips.pickSecond
                  }).attr('data-action', 'showSeconds')));
                  bottomRow.append($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'title': this._options.tooltips.decrementSecond
                  }).addClass('btn').attr('data-action', 'decrementSeconds').append($('<span>').addClass(this._options.icons.down))));
              }
  
              if (!this.use24Hours) {
                  topRow.append($('<td>').addClass('separator'));
                  middleRow.append($('<td>').append($('<button>').addClass('btn btn-primary').attr({
                      'data-action': 'togglePeriod',
                      tabindex: '-1',
                      'title': this._options.tooltips.togglePeriod
                  })));
                  bottomRow.append($('<td>').addClass('separator'));
              }
  
              return $('<div>').addClass('timepicker-picker').append($('<table>').addClass('table-condensed').append([topRow, middleRow, bottomRow]));
          };
  
          TempusDominusBootstrap4.prototype._getTimePickerTemplate = function _getTimePickerTemplate() {
              var hoursView = $('<div>').addClass('timepicker-hours').append($('<table>').addClass('table-condensed')),
                  minutesView = $('<div>').addClass('timepicker-minutes').append($('<table>').addClass('table-condensed')),
                  secondsView = $('<div>').addClass('timepicker-seconds').append($('<table>').addClass('table-condensed')),
                  ret = [this._getTimePickerMainTemplate()];
  
              if (this._isEnabled('h')) {
                  ret.push(hoursView);
              }
              if (this._isEnabled('m')) {
                  ret.push(minutesView);
              }
              if (this._isEnabled('s')) {
                  ret.push(secondsView);
              }
  
              return ret;
          };
  
          TempusDominusBootstrap4.prototype._getToolbar = function _getToolbar() {
              var row = [];
              if (this._options.buttons.showToday) {
                  row.push($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'data-action': 'today',
                      'title': this._options.tooltips.today
                  }).append($('<span>').addClass(this._options.icons.today))));
              }
              if (!this._options.sideBySide && this._hasDate() && this._hasTime()) {
                  var title = void 0,
                      icon = void 0;
                  if (this._options.viewMode === 'times') {
                      title = this._options.tooltips.selectDate;
                      icon = this._options.icons.date;
                  } else {
                      title = this._options.tooltips.selectTime;
                      icon = this._options.icons.time;
                  }
                  row.push($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'data-action': 'togglePicker',
                      'title': title
                  }).append($('<span>').addClass(icon))));
              }
              if (this._options.buttons.showClear) {
                  row.push($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'data-action': 'clear',
                      'title': this._options.tooltips.clear
                  }).append($('<span>').addClass(this._options.icons.clear))));
              }
              if (this._options.buttons.showClose) {
                  row.push($('<td>').append($('<a>').attr({
                      href: '#',
                      tabindex: '-1',
                      'data-action': 'close',
                      'title': this._options.tooltips.close
                  }).append($('<span>').addClass(this._options.icons.close))));
              }
              return row.length === 0 ? '' : $('<table>').addClass('table-condensed').append($('<tbody>').append($('<tr>').append(row)));
          };
  
          TempusDominusBootstrap4.prototype._getTemplate = function _getTemplate() {
              var template = $('<div>').addClass('bootstrap-datetimepicker-widget dropdown-menu'),
                  dateView = $('<div>').addClass('datepicker').append(this._getDatePickerTemplate()),
                  timeView = $('<div>').addClass('timepicker').append(this._getTimePickerTemplate()),
                  content = $('<ul>').addClass('list-unstyled'),
                  toolbar = $('<li>').addClass('picker-switch' + (this._options.collapse ? ' accordion-toggle' : '')).append(this._getToolbar());
  
              if (this._options.inline) {
                  template.removeClass('dropdown-menu');
              }
  
              if (this.use24Hours) {
                  template.addClass('usetwentyfour');
              }
              if (this._isEnabled('s') && !this.use24Hours) {
                  template.addClass('wider');
              }
  
              if (this._options.sideBySide && this._hasDate() && this._hasTime()) {
                  template.addClass('timepicker-sbs');
                  if (this._options.toolbarPlacement === 'top') {
                      template.append(toolbar);
                  }
                  template.append($('<div>').addClass('row').append(dateView.addClass('col-md-6')).append(timeView.addClass('col-md-6')));
                  if (this._options.toolbarPlacement === 'bottom' || this._options.toolbarPlacement === 'default') {
                      template.append(toolbar);
                  }
                  return template;
              }
  
              if (this._options.toolbarPlacement === 'top') {
                  content.append(toolbar);
              }
              if (this._hasDate()) {
                  content.append($('<li>').addClass(this._options.collapse && this._hasTime() ? 'collapse' : '').addClass(this._options.collapse && this._hasTime() && this._options.viewMode === 'times' ? '' : 'show').append(dateView));
              }
              if (this._options.toolbarPlacement === 'default') {
                  content.append(toolbar);
              }
              if (this._hasTime()) {
                  content.append($('<li>').addClass(this._options.collapse && this._hasDate() ? 'collapse' : '').addClass(this._options.collapse && this._hasDate() && this._options.viewMode === 'times' ? 'show' : '').append(timeView));
              }
              if (this._options.toolbarPlacement === 'bottom') {
                  content.append(toolbar);
              }
              return template.append(content);
          };
  
          TempusDominusBootstrap4.prototype._place = function _place(e) {
              var self = e && e.data && e.data.picker || this,
                  vertical = self._options.widgetPositioning.vertical,
                  horizontal = self._options.widgetPositioning.horizontal,
                  parent = void 0;
              var position = (self.component && self.component.length ? self.component : self._element).position(),
                  offset = (self.component && self.component.length ? self.component : self._element).offset();
              if (self._options.widgetParent) {
                  parent = self._options.widgetParent.append(self.widget);
              } else if (self._element.is('input')) {
                  parent = self._element.after(self.widget).parent();
              } else if (self._options.inline) {
                  parent = self._element.append(self.widget);
                  return;
              } else {
                  parent = self._element;
                  self._element.children().first().after(self.widget);
              }
  
              // Top and bottom logic
              if (vertical === 'auto') {
                  //noinspection JSValidateTypes
                  if (offset.top + self.widget.height() * 1.5 >= $(window).height() + $(window).scrollTop() && self.widget.height() + self._element.outerHeight() < offset.top) {
                      vertical = 'top';
                  } else {
                      vertical = 'bottom';
                  }
              }
  
              // Left and right logic
              if (horizontal === 'auto') {
                  if (parent.width() < offset.left + self.widget.outerWidth() / 2 && offset.left + self.widget.outerWidth() > $(window).width()) {
                      horizontal = 'right';
                  } else {
                      horizontal = 'left';
                  }
              }
  
              if (vertical === 'top') {
                  self.widget.addClass('top').removeClass('bottom');
              } else {
                  self.widget.addClass('bottom').removeClass('top');
              }
  
              if (horizontal === 'right') {
                  self.widget.addClass('float-right');
              } else {
                  self.widget.removeClass('float-right');
              }
  
              // find the first parent element that has a relative css positioning
              if (parent.css('position') !== 'relative') {
                  parent = parent.parents().filter(function () {
                      return $(this).css('position') === 'relative';
                  }).first();
              }
  
              if (parent.length === 0) {
                  throw new Error('datetimepicker component should be placed within a relative positioned container');
              }
  
              self.widget.css({
                  top: vertical === 'top' ? 'auto' : position.top + self._element.outerHeight() + 'px',
                  bottom: vertical === 'top' ? parent.outerHeight() - (parent === self._element ? 0 : position.top) + 'px' : 'auto',
                  left: horizontal === 'left' ? (parent === self._element ? 0 : position.left) + 'px' : 'auto',
                  right: horizontal === 'left' ? 'auto' : parent.outerWidth() - self._element.outerWidth() - (parent === self._element ? 0 : position.left) + 'px'
              });
          };
  
          TempusDominusBootstrap4.prototype._fillDow = function _fillDow() {
              var row = $('<tr>'),
                  currentDate = this._viewDate.clone().startOf('w').startOf('d');
  
              if (this._options.calendarWeeks === true) {
                  row.append($('<th>').addClass('cw').text('#'));
              }
  
              while (currentDate.isBefore(this._viewDate.clone().endOf('w'))) {
                  row.append($('<th>').addClass('dow').text(currentDate.format('dd')));
                  currentDate.add(1, 'd');
              }
              this.widget.find('.datepicker-days thead').append(row);
          };
  
          TempusDominusBootstrap4.prototype._fillMonths = function _fillMonths() {
              var spans = [],
                  monthsShort = this._viewDate.clone().startOf('y').startOf('d');
              while (monthsShort.isSame(this._viewDate, 'y')) {
                  spans.push($('<span>').attr('data-action', 'selectMonth').addClass('month').text(monthsShort.format('MMM')));
                  monthsShort.add(1, 'M');
              }
              this.widget.find('.datepicker-months td').empty().append(spans);
          };
  
          TempusDominusBootstrap4.prototype._updateMonths = function _updateMonths() {
              var monthsView = this.widget.find('.datepicker-months'),
                  monthsViewHeader = monthsView.find('th'),
                  months = monthsView.find('tbody').find('span'),
                  self = this;
  
              monthsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevYear);
              monthsViewHeader.eq(1).attr('title', this._options.tooltips.selectYear);
              monthsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextYear);
  
              monthsView.find('.disabled').removeClass('disabled');
  
              if (!this._isValid(this._viewDate.clone().subtract(1, 'y'), 'y')) {
                  monthsViewHeader.eq(0).addClass('disabled');
              }
  
              monthsViewHeader.eq(1).text(this._viewDate.year());
  
              if (!this._isValid(this._viewDate.clone().add(1, 'y'), 'y')) {
                  monthsViewHeader.eq(2).addClass('disabled');
              }
  
              months.removeClass('active');
              if (this._getLastPickedDate().isSame(this._viewDate, 'y') && !this.unset) {
                  months.eq(this._getLastPickedDate().month()).addClass('active');
              }
  
              months.each(function (index) {
                  if (!self._isValid(self._viewDate.clone().month(index), 'M')) {
                      $(this).addClass('disabled');
                  }
              });
          };
  
          TempusDominusBootstrap4.prototype._getStartEndYear = function _getStartEndYear(factor, year) {
              var step = factor / 10,
                  startYear = Math.floor(year / factor) * factor,
                  endYear = startYear + step * 9,
                  focusValue = Math.floor(year / step) * step;
              return [startYear, endYear, focusValue];
          };
  
          TempusDominusBootstrap4.prototype._updateYears = function _updateYears() {
              var yearsView = this.widget.find('.datepicker-years'),
                  yearsViewHeader = yearsView.find('th'),
                  yearCaps = this._getStartEndYear(10, this._viewDate.year()),
                  startYear = this._viewDate.clone().year(yearCaps[0]),
                  endYear = this._viewDate.clone().year(yearCaps[1]);
              var html = '';
  
              yearsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevDecade);
              yearsViewHeader.eq(1).attr('title', this._options.tooltips.selectDecade);
              yearsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextDecade);
  
              yearsView.find('.disabled').removeClass('disabled');
  
              if (this._options.minDate && this._options.minDate.isAfter(startYear, 'y')) {
                  yearsViewHeader.eq(0).addClass('disabled');
              }
  
              yearsViewHeader.eq(1).text(startYear.year() + '-' + endYear.year());
  
              if (this._options.maxDate && this._options.maxDate.isBefore(endYear, 'y')) {
                  yearsViewHeader.eq(2).addClass('disabled');
              }
  
              html += '<span data-action="selectYear" class="year old' + (!this._isValid(startYear, 'y') ? ' disabled' : '') + '">' + (startYear.year() - 1) + '</span>';
              while (!startYear.isAfter(endYear, 'y')) {
                  html += '<span data-action="selectYear" class="year' + (startYear.isSame(this._getLastPickedDate(), 'y') && !this.unset ? ' active' : '') + (!this._isValid(startYear, 'y') ? ' disabled' : '') + '">' + startYear.year() + '</span>';
                  startYear.add(1, 'y');
              }
              html += '<span data-action="selectYear" class="year old' + (!this._isValid(startYear, 'y') ? ' disabled' : '') + '">' + startYear.year() + '</span>';
  
              yearsView.find('td').html(html);
          };
  
          TempusDominusBootstrap4.prototype._updateDecades = function _updateDecades() {
              var decadesView = this.widget.find('.datepicker-decades'),
                  decadesViewHeader = decadesView.find('th'),
                  yearCaps = this._getStartEndYear(100, this._viewDate.year()),
                  startDecade = this._viewDate.clone().year(yearCaps[0]),
                  endDecade = this._viewDate.clone().year(yearCaps[1]);
              var minDateDecade = false,
                  maxDateDecade = false,
                  endDecadeYear = void 0,
                  html = '';
  
              decadesViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevCentury);
              decadesViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextCentury);
  
              decadesView.find('.disabled').removeClass('disabled');
  
              if (startDecade.year() === 0 || this._options.minDate && this._options.minDate.isAfter(startDecade, 'y')) {
                  decadesViewHeader.eq(0).addClass('disabled');
              }
  
              decadesViewHeader.eq(1).text(startDecade.year() + '-' + endDecade.year());
  
              if (this._options.maxDate && this._options.maxDate.isBefore(endDecade, 'y')) {
                  decadesViewHeader.eq(2).addClass('disabled');
              }
  
              if (startDecade.year() - 10 < 0) {
                  html += '<span>&nbsp;</span>';
              } else {
                  html += '<span data-action="selectDecade" class="decade old" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() - 10) + '</span>';
              }
  
              while (!startDecade.isAfter(endDecade, 'y')) {
                  endDecadeYear = startDecade.year() + 11;
                  minDateDecade = this._options.minDate && this._options.minDate.isAfter(startDecade, 'y') && this._options.minDate.year() <= endDecadeYear;
                  maxDateDecade = this._options.maxDate && this._options.maxDate.isAfter(startDecade, 'y') && this._options.maxDate.year() <= endDecadeYear;
                  html += '<span data-action="selectDecade" class="decade' + (this._getLastPickedDate().isAfter(startDecade) && this._getLastPickedDate().year() <= endDecadeYear ? ' active' : '') + (!this._isValid(startDecade, 'y') && !minDateDecade && !maxDateDecade ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + startDecade.year() + '</span>';
                  startDecade.add(10, 'y');
              }
              html += '<span data-action="selectDecade" class="decade old" data-selection="' + (startDecade.year() + 6) + '">' + startDecade.year() + '</span>';
  
              decadesView.find('td').html(html);
          };
  
          TempusDominusBootstrap4.prototype._fillDate = function _fillDate() {
              var daysView = this.widget.find('.datepicker-days'),
                  daysViewHeader = daysView.find('th'),
                  html = [];
              var currentDate = void 0,
                  row = void 0,
                  clsName = void 0,
                  i = void 0;
  
              if (!this._hasDate()) {
                  return;
              }
  
              daysViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevMonth);
              daysViewHeader.eq(1).attr('title', this._options.tooltips.selectMonth);
              daysViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextMonth);
  
              daysView.find('.disabled').removeClass('disabled');
              daysViewHeader.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat));
  
              if (!this._isValid(this._viewDate.clone().subtract(1, 'M'), 'M')) {
                  daysViewHeader.eq(0).addClass('disabled');
              }
              if (!this._isValid(this._viewDate.clone().add(1, 'M'), 'M')) {
                  daysViewHeader.eq(2).addClass('disabled');
              }
  
              currentDate = this._viewDate.clone().startOf('M').startOf('w').startOf('d');
  
              for (i = 0; i < 42; i++) {
                  //always display 42 days (should show 6 weeks)
                  if (currentDate.weekday() === 0) {
                      row = $('<tr>');
                      if (this._options.calendarWeeks) {
                          row.append('<td class="cw">' + currentDate.week() + '</td>');
                      }
                      html.push(row);
                  }
                  clsName = '';
                  if (currentDate.isBefore(this._viewDate, 'M')) {
                      clsName += ' old';
                  }
                  if (currentDate.isAfter(this._viewDate, 'M')) {
                      clsName += ' new';
                  }
                  if (this._options.allowMultidate) {
                      var index = this._datesFormatted.indexOf(currentDate.format('YYYY-MM-DD'));
                      if (index !== -1) {
                          if (currentDate.isSame(this._datesFormatted[index], 'd') && !this.unset) {
                              clsName += ' active';
                          }
                      }
                  } else {
                      if (currentDate.isSame(this._getLastPickedDate(), 'd') && !this.unset) {
                          clsName += ' active';
                      }
                  }
                  if (!this._isValid(currentDate, 'd')) {
                      clsName += ' disabled';
                  }
                  if (currentDate.isSame(this.getMoment(), 'd')) {
                      clsName += ' today';
                  }
                  if (currentDate.day() === 0 || currentDate.day() === 6) {
                      clsName += ' weekend';
                  }
                  row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="day' + clsName + '">' + currentDate.date() + '</td>');
                  currentDate.add(1, 'd');
              }
  
              daysView.find('tbody').empty().append(html);
  
              this._updateMonths();
  
              this._updateYears();
  
              this._updateDecades();
          };
  
          TempusDominusBootstrap4.prototype._fillHours = function _fillHours() {
              var table = this.widget.find('.timepicker-hours table'),
                  currentHour = this._viewDate.clone().startOf('d'),
                  html = [];
              var row = $('<tr>');
  
              if (this._viewDate.hour() > 11 && !this.use24Hours) {
                  currentHour.hour(12);
              }
              while (currentHour.isSame(this._viewDate, 'd') && (this.use24Hours || this._viewDate.hour() < 12 && currentHour.hour() < 12 || this._viewDate.hour() > 11)) {
                  if (currentHour.hour() % 4 === 0) {
                      row = $('<tr>');
                      html.push(row);
                  }
                  row.append('<td data-action="selectHour" class="hour' + (!this._isValid(currentHour, 'h') ? ' disabled' : '') + '">' + currentHour.format(this.use24Hours ? 'HH' : 'hh') + '</td>');
                  currentHour.add(1, 'h');
              }
              table.empty().append(html);
          };
  
          TempusDominusBootstrap4.prototype._fillMinutes = function _fillMinutes() {
              var table = this.widget.find('.timepicker-minutes table'),
                  currentMinute = this._viewDate.clone().startOf('h'),
                  html = [],
                  step = this._options.stepping === 1 ? 5 : this._options.stepping;
              var row = $('<tr>');
  
              while (this._viewDate.isSame(currentMinute, 'h')) {
                  if (currentMinute.minute() % (step * 4) === 0) {
                      row = $('<tr>');
                      html.push(row);
                  }
                  row.append('<td data-action="selectMinute" class="minute' + (!this._isValid(currentMinute, 'm') ? ' disabled' : '') + '">' + currentMinute.format('mm') + '</td>');
                  currentMinute.add(step, 'm');
              }
              table.empty().append(html);
          };
  
          TempusDominusBootstrap4.prototype._fillSeconds = function _fillSeconds() {
              var table = this.widget.find('.timepicker-seconds table'),
                  currentSecond = this._viewDate.clone().startOf('m'),
                  html = [];
              var row = $('<tr>');
  
              while (this._viewDate.isSame(currentSecond, 'm')) {
                  if (currentSecond.second() % 20 === 0) {
                      row = $('<tr>');
                      html.push(row);
                  }
                  row.append('<td data-action="selectSecond" class="second' + (!this._isValid(currentSecond, 's') ? ' disabled' : '') + '">' + currentSecond.format('ss') + '</td>');
                  currentSecond.add(5, 's');
              }
  
              table.empty().append(html);
          };
  
          TempusDominusBootstrap4.prototype._fillTime = function _fillTime() {
              var toggle = void 0,
                  newDate = void 0;
              var timeComponents = this.widget.find('.timepicker span[data-time-component]');
  
              if (!this.use24Hours) {
                  toggle = this.widget.find('.timepicker [data-action=togglePeriod]');
                  newDate = this._getLastPickedDate().clone().add(this._getLastPickedDate().hours() >= 12 ? -12 : 12, 'h');
  
                  toggle.text(this._getLastPickedDate().format('A'));
  
                  if (this._isValid(newDate, 'h')) {
                      toggle.removeClass('disabled');
                  } else {
                      toggle.addClass('disabled');
                  }
              }
              timeComponents.filter('[data-time-component=hours]').text(this._getLastPickedDate().format('' + (this.use24Hours ? 'HH' : 'hh')));
              timeComponents.filter('[data-time-component=minutes]').text(this._getLastPickedDate().format('mm'));
              timeComponents.filter('[data-time-component=seconds]').text(this._getLastPickedDate().format('ss'));
  
              this._fillHours();
              this._fillMinutes();
              this._fillSeconds();
          };
  
          TempusDominusBootstrap4.prototype._doAction = function _doAction(e, action) {
              var lastPicked = this._getLastPickedDate();
              if ($(e.currentTarget).is('.disabled')) {
                  return false;
              }
              action = action || $(e.currentTarget).data('action');
              switch (action) {
                  case 'next':
                      {
                          var navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION;
                          this._viewDate.add(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, navFnc);
                          this._fillDate();
                          this._viewUpdate(navFnc);
                          break;
                      }
                  case 'previous':
                      {
                          var _navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION;
                          this._viewDate.subtract(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, _navFnc);
                          this._fillDate();
                          this._viewUpdate(_navFnc);
                          break;
                      }
                  case 'pickerSwitch':
                      this._showMode(1);
                      break;
                  case 'selectMonth':
                      {
                          var month = $(e.target).closest('tbody').find('span').index($(e.target));
                          this._viewDate.month(month);
                          if (this.currentViewMode === this.MinViewModeNumber) {
                              this._setValue(lastPicked.clone().year(this._viewDate.year()).month(this._viewDate.month()), this._getLastPickedDateIndex());
                              if (!this._options.inline) {
                                  this.hide();
                              }
                          } else {
                              this._showMode(-1);
                              this._fillDate();
                          }
                          this._viewUpdate('M');
                          break;
                      }
                  case 'selectYear':
                      {
                          var year = parseInt($(e.target).text(), 10) || 0;
                          this._viewDate.year(year);
                          if (this.currentViewMode === this.MinViewModeNumber) {
                              this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex());
                              if (!this._options.inline) {
                                  this.hide();
                              }
                          } else {
                              this._showMode(-1);
                              this._fillDate();
                          }
                          this._viewUpdate('YYYY');
                          break;
                      }
                  case 'selectDecade':
                      {
                          var _year = parseInt($(e.target).data('selection'), 10) || 0;
                          this._viewDate.year(_year);
                          if (this.currentViewMode === this.MinViewModeNumber) {
                              this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex());
                              if (!this._options.inline) {
                                  this.hide();
                              }
                          } else {
                              this._showMode(-1);
                              this._fillDate();
                          }
                          this._viewUpdate('YYYY');
                          break;
                      }
                  case 'selectDay':
                      {
                          var day = this._viewDate.clone();
                          if ($(e.target).is('.old')) {
                              day.subtract(1, 'M');
                          }
                          if ($(e.target).is('.new')) {
                              day.add(1, 'M');
                          }
  
                          var selectDate = day.date(parseInt($(e.target).text(), 10)),
                              index = 0;
                          if (this._options.allowMultidate) {
                              index = this._datesFormatted.indexOf(selectDate.format('YYYY-MM-DD'));
                              if (index !== -1) {
                                  this._setValue(null, index); //deselect multidate
                              } else {
                                  this._setValue(selectDate, this._getLastPickedDateIndex() + 1);
                              }
                          } else {
                              this._setValue(selectDate, this._getLastPickedDateIndex());
                          }
  
                          if (!this._hasTime() && !this._options.keepOpen && !this._options.inline && !this._options.allowMultidate) {
                              this.hide();
                          }
                          break;
                      }
                  case 'incrementHours':
                      {
                          var newDate = lastPicked.clone().add(1, 'h');
                          if (this._isValid(newDate, 'h')) {
                              this._setValue(newDate, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'incrementMinutes':
                      {
                          var _newDate = lastPicked.clone().add(this._options.stepping, 'm');
                          if (this._isValid(_newDate, 'm')) {
                              this._setValue(_newDate, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'incrementSeconds':
                      {
                          var _newDate2 = lastPicked.clone().add(1, 's');
                          if (this._isValid(_newDate2, 's')) {
                              this._setValue(_newDate2, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'decrementHours':
                      {
                          var _newDate3 = lastPicked.clone().subtract(1, 'h');
                          if (this._isValid(_newDate3, 'h')) {
                              this._setValue(_newDate3, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'decrementMinutes':
                      {
                          var _newDate4 = lastPicked.clone().subtract(this._options.stepping, 'm');
                          if (this._isValid(_newDate4, 'm')) {
                              this._setValue(_newDate4, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'decrementSeconds':
                      {
                          var _newDate5 = lastPicked.clone().subtract(1, 's');
                          if (this._isValid(_newDate5, 's')) {
                              this._setValue(_newDate5, this._getLastPickedDateIndex());
                          }
                          break;
                      }
                  case 'togglePeriod':
                      {
                          this._setValue(lastPicked.clone().add(lastPicked.hours() >= 12 ? -12 : 12, 'h'), this._getLastPickedDateIndex());
                          break;
                      }
                  case 'togglePicker':
                      {
                          var $this = $(e.target),
                              $link = $this.closest('a'),
                              $parent = $this.closest('ul'),
                              expanded = $parent.find('.show'),
                              closed = $parent.find('.collapse:not(.show)'),
                              $span = $this.is('span') ? $this : $this.find('span');
                          var collapseData = void 0;
  
                          if (expanded && expanded.length) {
                              collapseData = expanded.data('collapse');
                              if (collapseData && collapseData.transitioning) {
                                  return true;
                              }
                              if (expanded.collapse) {
                                  // if collapse plugin is available through bootstrap.js then use it
                                  expanded.collapse('hide');
                                  closed.collapse('show');
                              } else {
                                  // otherwise just toggle in class on the two views
                                  expanded.removeClass('show');
                                  closed.addClass('show');
                              }
                              $span.toggleClass(this._options.icons.time + ' ' + this._options.icons.date);
  
                              if ($span.hasClass(this._options.icons.date)) {
                                  $link.attr('title', this._options.tooltips.selectDate);
                              } else {
                                  $link.attr('title', this._options.tooltips.selectTime);
                              }
                          }
                      }
                      break;
                  case 'showPicker':
                      this.widget.find('.timepicker > div:not(.timepicker-picker)').hide();
                      this.widget.find('.timepicker .timepicker-picker').show();
                      break;
                  case 'showHours':
                      this.widget.find('.timepicker .timepicker-picker').hide();
                      this.widget.find('.timepicker .timepicker-hours').show();
                      break;
                  case 'showMinutes':
                      this.widget.find('.timepicker .timepicker-picker').hide();
                      this.widget.find('.timepicker .timepicker-minutes').show();
                      break;
                  case 'showSeconds':
                      this.widget.find('.timepicker .timepicker-picker').hide();
                      this.widget.find('.timepicker .timepicker-seconds').show();
                      break;
                  case 'selectHour':
                      {
                          var hour = parseInt($(e.target).text(), 10);
  
                          if (!this.use24Hours) {
                              if (lastPicked.hours() >= 12) {
                                  if (hour !== 12) {
                                      hour += 12;
                                  }
                              } else {
                                  if (hour === 12) {
                                      hour = 0;
                                  }
                              }
                          }
                          this._setValue(lastPicked.clone().hours(hour), this._getLastPickedDateIndex());
                          if (!this._isEnabled('a') && !this._isEnabled('m') && !this._options.keepOpen && !this._options.inline) {
                              this.hide();
                          } else {
                              this._doAction(e, 'showPicker');
                          }
                          break;
                      }
                  case 'selectMinute':
                      this._setValue(lastPicked.clone().minutes(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex());
                      if (!this._isEnabled('a') && !this._isEnabled('s') && !this._options.keepOpen && !this._options.inline) {
                          this.hide();
                      } else {
                          this._doAction(e, 'showPicker');
                      }
                      break;
                  case 'selectSecond':
                      this._setValue(lastPicked.clone().seconds(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex());
                      if (!this._isEnabled('a') && !this._options.keepOpen && !this._options.inline) {
                          this.hide();
                      } else {
                          this._doAction(e, 'showPicker');
                      }
                      break;
                  case 'clear':
                      this.clear();
                      break;
                  case 'close':
                      this.hide();
                      break;
                  case 'today':
                      {
                          var todaysDate = this.getMoment();
                          if (this._isValid(todaysDate, 'd')) {
                              this._setValue(todaysDate, this._getLastPickedDateIndex());
                          }
                          break;
                      }
              }
              return false;
          };
  
          //public
  
  
          TempusDominusBootstrap4.prototype.hide = function hide() {
              var transitioning = false;
              if (!this.widget) {
                  return;
              }
              // Ignore event if in the middle of a picker transition
              this.widget.find('.collapse').each(function () {
                  var collapseData = $(this).data('collapse');
                  if (collapseData && collapseData.transitioning) {
                      transitioning = true;
                      return false;
                  }
                  return true;
              });
              if (transitioning) {
                  return;
              }
              if (this.component && this.component.hasClass('btn')) {
                  this.component.toggleClass('active');
              }
              this.widget.hide();
  
              $(window).off('resize', this._place());
              this.widget.off('click', '[data-action]');
              this.widget.off('mousedown', false);
  
              this.widget.remove();
              this.widget = false;
  
              this._notifyEvent({
                  type: DateTimePicker.Event.HIDE,
                  date: this._getLastPickedDate().clone()
              });
  
              if (this.input !== undefined) {
                  this.input.blur();
              }
  
              this._viewDate = this._getLastPickedDate().clone();
          };
  
          TempusDominusBootstrap4.prototype.show = function show() {
              var currentMoment = void 0;
              var useCurrentGranularity = {
                  'year': function year(m) {
                      return m.month(0).date(1).hours(0).seconds(0).minutes(0);
                  },
                  'month': function month(m) {
                      return m.date(1).hours(0).seconds(0).minutes(0);
                  },
                  'day': function day(m) {
                      return m.hours(0).seconds(0).minutes(0);
                  },
                  'hour': function hour(m) {
                      return m.seconds(0).minutes(0);
                  },
                  'minute': function minute(m) {
                      return m.seconds(0);
                  }
              };
  
              if (this.input !== undefined) {
                  if (this.input.prop('disabled') || !this._options.ignoreReadonly && this.input.prop('readonly') || this.widget) {
                      return;
                  }
                  if (this.input.val() !== undefined && this.input.val().trim().length !== 0) {
                      this._setValue(this._parseInputDate(this.input.val().trim()), 0);
                  } else if (this.unset && this._options.useCurrent) {
                      currentMoment = this.getMoment();
                      if (typeof this._options.useCurrent === 'string') {
                          currentMoment = useCurrentGranularity[this._options.useCurrent](currentMoment);
                      }
                      this._setValue(currentMoment, 0);
                  }
              } else if (this.unset && this._options.useCurrent) {
                  currentMoment = this.getMoment();
                  if (typeof this._options.useCurrent === 'string') {
                      currentMoment = useCurrentGranularity[this._options.useCurrent](currentMoment);
                  }
                  this._setValue(currentMoment, 0);
              }
  
              this.widget = this._getTemplate();
  
              this._fillDow();
              this._fillMonths();
  
              this.widget.find('.timepicker-hours').hide();
              this.widget.find('.timepicker-minutes').hide();
              this.widget.find('.timepicker-seconds').hide();
  
              this._update();
              this._showMode();
  
              $(window).on('resize', { picker: this }, this._place);
              this.widget.on('click', '[data-action]', $.proxy(this._doAction, this)); // this handles clicks on the widget
              this.widget.on('mousedown', false);
  
              if (this.component && this.component.hasClass('btn')) {
                  this.component.toggleClass('active');
              }
              this._place();
              this.widget.show();
              if (this.input !== undefined && this._options.focusOnShow && !this.input.is(':focus')) {
                  this.input.focus();
              }
  
              this._notifyEvent({
                  type: DateTimePicker.Event.SHOW
              });
          };
  
          TempusDominusBootstrap4.prototype.destroy = function destroy() {
              this.hide();
              //todo doc off?
              this._element.removeData(DateTimePicker.DATA_KEY);
              this._element.removeData('date');
          };
  
          TempusDominusBootstrap4.prototype.disable = function disable() {
              this.hide();
              if (this.component && this.component.hasClass('btn')) {
                  this.component.addClass('disabled');
              }
              if (this.input !== undefined) {
                  this.input.prop('disabled', true); //todo disable this/comp if input is null
              }
          };
  
          TempusDominusBootstrap4.prototype.enable = function enable() {
              if (this.component && this.component.hasClass('btn')) {
                  this.component.removeClass('disabled');
              }
              if (this.input !== undefined) {
                  this.input.prop('disabled', false); //todo enable comp/this if input is null
              }
          };
  
          TempusDominusBootstrap4.prototype.toolbarPlacement = function toolbarPlacement(_toolbarPlacement) {
              if (arguments.length === 0) {
                  return this._options.toolbarPlacement;
              }
  
              if (typeof _toolbarPlacement !== 'string') {
                  throw new TypeError('toolbarPlacement() expects a string parameter');
              }
              if (toolbarPlacements.indexOf(_toolbarPlacement) === -1) {
                  throw new TypeError('toolbarPlacement() parameter must be one of (' + toolbarPlacements.join(', ') + ') value');
              }
              this._options.toolbarPlacement = _toolbarPlacement;
  
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          TempusDominusBootstrap4.prototype.widgetPositioning = function widgetPositioning(_widgetPositioning) {
              if (arguments.length === 0) {
                  return $.extend({}, this._options.widgetPositioning);
              }
  
              if ({}.toString.call(_widgetPositioning) !== '[object Object]') {
                  throw new TypeError('widgetPositioning() expects an object variable');
              }
              if (_widgetPositioning.horizontal) {
                  if (typeof _widgetPositioning.horizontal !== 'string') {
                      throw new TypeError('widgetPositioning() horizontal variable must be a string');
                  }
                  _widgetPositioning.horizontal = _widgetPositioning.horizontal.toLowerCase();
                  if (horizontalModes.indexOf(_widgetPositioning.horizontal) === -1) {
                      throw new TypeError('widgetPositioning() expects horizontal parameter to be one of (' + horizontalModes.join(', ') + ')');
                  }
                  this._options.widgetPositioning.horizontal = _widgetPositioning.horizontal;
              }
              if (_widgetPositioning.vertical) {
                  if (typeof _widgetPositioning.vertical !== 'string') {
                      throw new TypeError('widgetPositioning() vertical variable must be a string');
                  }
                  _widgetPositioning.vertical = _widgetPositioning.vertical.toLowerCase();
                  if (verticalModes.indexOf(_widgetPositioning.vertical) === -1) {
                      throw new TypeError('widgetPositioning() expects vertical parameter to be one of (' + verticalModes.join(', ') + ')');
                  }
                  this._options.widgetPositioning.vertical = _widgetPositioning.vertical;
              }
              this._update();
          };
  
          TempusDominusBootstrap4.prototype.widgetParent = function widgetParent(_widgetParent) {
              if (arguments.length === 0) {
                  return this._options.widgetParent;
              }
  
              if (typeof _widgetParent === 'string') {
                  _widgetParent = $(_widgetParent);
              }
  
              if (_widgetParent !== null && typeof _widgetParent !== 'string' && !(_widgetParent instanceof $)) {
                  throw new TypeError('widgetParent() expects a string or a jQuery object parameter');
              }
  
              this._options.widgetParent = _widgetParent;
              if (this.widget) {
                  this.hide();
                  this.show();
              }
          };
  
          //static
  
  
          TempusDominusBootstrap4._jQueryHandleThis = function _jQueryHandleThis(me, option, argument) {
              var data = $(me).data(DateTimePicker.DATA_KEY);
              if ((typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object') {
                  $.extend({}, DateTimePicker.Default, option);
              }
  
              if (!data) {
                  data = new TempusDominusBootstrap4($(me), option);
                  $(me).data(DateTimePicker.DATA_KEY, data);
              }
  
              if (typeof option === 'string') {
                  if (data[option] === undefined) {
                      throw new Error('No method named "' + option + '"');
                  }
                  if (argument === undefined) {
                      return data[option]();
                  } else {
                      return data[option](argument);
                  }
              }
          };
  
          TempusDominusBootstrap4._jQueryInterface = function _jQueryInterface(option, argument) {
              if (this.length === 1) {
                  return TempusDominusBootstrap4._jQueryHandleThis(this[0], option, argument);
              }
              return this.each(function () {
                  TempusDominusBootstrap4._jQueryHandleThis(this, option, argument);
              });
          };
  
          return TempusDominusBootstrap4;
      }(DateTimePicker);
  
      /**
      * ------------------------------------------------------------------------
      * jQuery
      * ------------------------------------------------------------------------
      */
  
  
      $(document).on(DateTimePicker.Event.CLICK_DATA_API, DateTimePicker.Selector.DATA_TOGGLE, function () {
          var $target = getSelectorFromElement($(this));
          if ($target.length === 0) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, 'toggle');
      }).on(DateTimePicker.Event.CHANGE, '.' + DateTimePicker.ClassName.INPUT, function (event) {
          var $target = getSelectorFromElement($(this));
          if ($target.length === 0) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, '_change', event);
      }).on(DateTimePicker.Event.BLUR, '.' + DateTimePicker.ClassName.INPUT, function (event) {
          var $target = getSelectorFromElement($(this)),
              config = $target.data(DateTimePicker.DATA_KEY);
          if ($target.length === 0) {
              return;
          }
          if (config._options.debug || window.debug) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, 'hide', event);
      }).on(DateTimePicker.Event.KEYDOWN, '.' + DateTimePicker.ClassName.INPUT, function (event) {
          var $target = getSelectorFromElement($(this));
          if ($target.length === 0) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, '_keydown', event);
      }).on(DateTimePicker.Event.KEYUP, '.' + DateTimePicker.ClassName.INPUT, function (event) {
          var $target = getSelectorFromElement($(this));
          if ($target.length === 0) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, '_keyup', event);
      }).on(DateTimePicker.Event.FOCUS, '.' + DateTimePicker.ClassName.INPUT, function (event) {
          var $target = getSelectorFromElement($(this)),
              config = $target.data(DateTimePicker.DATA_KEY);
          if ($target.length === 0) {
              return;
          }
          if (!config._options.allowInputToggle) {
              return;
          }
          TempusDominusBootstrap4._jQueryInterface.call($target, 'show', event);
      });
  
      $.fn[DateTimePicker.NAME] = TempusDominusBootstrap4._jQueryInterface;
      $.fn[DateTimePicker.NAME].Constructor = TempusDominusBootstrap4;
      $.fn[DateTimePicker.NAME].noConflict = function () {
          $.fn[DateTimePicker.NAME] = JQUERY_NO_CONFLICT;
          return TempusDominusBootstrap4._jQueryInterface;
      };
  
      return TempusDominusBootstrap4;
  }(jQuery);
  
  }();
  