text: /******/ (function() { // webpackBootstrap
  /******/ 	var __webpack_modules__ = ({
  
  /***/ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js":
  /*!******************************************************************!*\
    !*** ./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js ***!
    \******************************************************************/
  /***/ (function() {
  
  // ==================================================
  // fancyBox v3.5.7
  //
  // Licensed GPLv3 for open source use
  // or fancyBox Commercial License for commercial use
  //
  // http://fancyapps.com/fancybox/
  // Copyright 2019 fancyApps
  //
  // ==================================================
  (function (window, document, $, undefined) {
    "use strict";
  
    window.console = window.console || {
      info: function (stuff) {}
    };
  
    // If there's no jQuery, fancyBox can't work
    // =========================================
  
    if (!$) {
      return;
    }
  
    // Check if fancyBox is already initialized
    // ========================================
  
    if ($.fn.fancybox) {
      console.info("fancyBox already initialized");
  
      return;
    }
  
    // Private default settings
    // ========================
  
    var defaults = {
      // Close existing modals
      // Set this to false if you do not need to stack multiple instances
      closeExisting: false,
  
      // Enable infinite gallery navigation
      loop: false,
  
      // Horizontal space between slides
      gutter: 50,
  
      // Enable keyboard navigation
      keyboard: true,
  
      // Should allow caption to overlap the content
      preventCaptionOverlap: true,
  
      // Should display navigation arrows at the screen edges
      arrows: true,
  
      // Should display counter at the top left corner
      infobar: true,
  
      // Should display close button (using `btnTpl.smallBtn` template) over the content
      // Can be true, false, "auto"
      // If "auto" - will be automatically enabled for "html", "inline" or "ajax" items
      smallBtn: "auto",
  
      // Should display toolbar (buttons at the top)
      // Can be true, false, "auto"
      // If "auto" - will be automatically hidden if "smallBtn" is enabled
      toolbar: "auto",
  
      // What buttons should appear in the top right corner.
      // Buttons will be created using templates from `btnTpl` option
      // and they will be placed into toolbar (class="fancybox-toolbar"` element)
      buttons: [
        "zoom",
        //"share",
        "slideShow",
        //"fullScreen",
        //"download",
        "thumbs",
        "close"
      ],
  
      // Detect "idle" time in seconds
      idleTime: 3,
  
      // Disable right-click and use simple image protection for images
      protect: false,
  
      // Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc
      modal: false,
  
      image: {
        // Wait for images to load before displaying
        //   true  - wait for image to load and then display;
        //   false - display thumbnail and load the full-sized image over top,
        //           requires predefined image dimensions (`data-width` and `data-height` attributes)
        preload: false
      },
  
      ajax: {
        // Object containing settings for ajax request
        settings: {
          // This helps to indicate that request comes from the modal
          // Feel free to change naming
          data: {
            fancybox: true
          }
        }
      },
  
      iframe: {
        // Iframe template
        tpl: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen="allowfullscreen" allow="autoplay; fullscreen" src=""></iframe>',
  
        // Preload iframe before displaying it
        // This allows to calculate iframe content width and height
        // (note: Due to "Same Origin Policy", you can't get cross domain data).
        preload: true,
  
        // Custom CSS styling for iframe wrapping element
        // You can use this to set custom iframe dimensions
        css: {},
  
        // Iframe tag attributes
        attr: {
          scrolling: "auto"
        }
      },
  
      // For HTML5 video only
      video: {
        tpl: '<video class="fancybox-video" controls controlsList="nodownload" poster="{{poster}}">' +
          '<source src="{{src}}" type="{{format}}" />' +
          'Sorry, your browser doesn\'t support embedded videos, <a href="{{src}}">download</a> and watch with your favorite video player!' +
          "</video>",
        format: "", // custom video format
        autoStart: true
      },
  
      // Default content type if cannot be detected automatically
      defaultType: "image",
  
      // Open/close animation type
      // Possible values:
      //   false            - disable
      //   "zoom"           - zoom images from/to thumbnail
      //   "fade"
      //   "zoom-in-out"
      //
      animationEffect: "zoom",
  
      // Duration in ms for open/close animation
      animationDuration: 366,
  
      // Should image change opacity while zooming
      // If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios
      zoomOpacity: "auto",
  
      // Transition effect between slides
      //
      // Possible values:
      //   false            - disable
      //   "fade'
      //   "slide'
      //   "circular'
      //   "tube'
      //   "zoom-in-out'
      //   "rotate'
      //
      transitionEffect: "fade",
  
      // Duration in ms for transition animation
      transitionDuration: 366,
  
      // Custom CSS class for slide element
      slideClass: "",
  
      // Custom CSS class for layout
      baseClass: "",
  
      // Base template for layout
      baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' +
        '<div class="fancybox-bg"></div>' +
        '<div class="fancybox-inner">' +
        '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' +
        '<div class="fancybox-toolbar">{{buttons}}</div>' +
        '<div class="fancybox-navigation">{{arrows}}</div>' +
        '<div class="fancybox-stage"></div>' +
        '<div class="fancybox-caption"><div class="fancybox-caption__body"></div></div>' +
        "</div>" +
        "</div>",
  
      // Loading indicator template
      spinnerTpl: '<div class="fancybox-loading"></div>',
  
      // Error message template
      errorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>',
  
      btnTpl: {
        download: '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg>' +
          "</a>",
  
        zoom: '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg>' +
          "</button>",
  
        close: '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +
          "</button>",
  
        // Arrows
        arrowLeft: '<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' +
          '<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div>' +
          "</button>",
  
        arrowRight: '<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' +
          '<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div>' +
          "</button>",
  
        // This small close button will be appended to your html/inline/ajax content by default,
        // if "smallBtn" option is not set to false
        smallBtn: '<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}">' +
          '<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg>' +
          "</button>"
      },
  
      // Container is injected into this element
      parentEl: "body",
  
      // Hide browser vertical scrollbars; use at your own risk
      hideScrollbar: true,
  
      // Focus handling
      // ==============
  
      // Try to focus on the first focusable element after opening
      autoFocus: true,
  
      // Put focus back to active element after closing
      backFocus: true,
  
      // Do not let user to focus on element outside modal content
      trapFocus: true,
  
      // Module specific options
      // =======================
  
      fullScreen: {
        autoStart: false
      },
  
      // Set `touch: false` to disable panning/swiping
      touch: {
        vertical: true, // Allow to drag content vertically
        momentum: true // Continue movement after releasing mouse/touch when panning
      },
  
      // Hash value when initializing manually,
      // set `false` to disable hash change
      hash: null,
  
      // Customize or add new media types
      // Example:
      /*
        media : {
          youtube : {
            params : {
              autoplay : 0
            }
          }
        }
      */
      media: {},
  
      slideShow: {
        autoStart: false,
        speed: 3000
      },
  
      thumbs: {
        autoStart: false, // Display thumbnails on opening
        hideOnClose: true, // Hide thumbnail grid when closing animation starts
        parentEl: ".fancybox-container", // Container is injected into this element
        axis: "y" // Vertical (y) or horizontal (x) scrolling
      },
  
      // Use mousewheel to navigate gallery
      // If 'auto' - enabled for images only
      wheel: "auto",
  
      // Callbacks
      //==========
  
      // See Documentation/API/Events for more information
      // Example:
      /*
        afterShow: function( instance, current ) {
          console.info( 'Clicked element:' );
          console.info( current.opts.$orig );
        }
      */
  
      onInit: $.noop, // When instance has been initialized
  
      beforeLoad: $.noop, // Before the content of a slide is being loaded
      afterLoad: $.noop, // When the content of a slide is done loading
  
      beforeShow: $.noop, // Before open animation starts
      afterShow: $.noop, // When content is done loading and animating
  
      beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.
      afterClose: $.noop, // After instance has been closed
  
      onActivate: $.noop, // When instance is brought to front
      onDeactivate: $.noop, // When other instance has been activated
  
      // Interaction
      // ===========
  
      // Use options below to customize taken action when user clicks or double clicks on the fancyBox area,
      // each option can be string or method that returns value.
      //
      // Possible values:
      //   "close"           - close instance
      //   "next"            - move to next gallery item
      //   "nextOrClose"     - move to next gallery item or close if gallery has only one item
      //   "toggleControls"  - show/hide controls
      //   "zoom"            - zoom image (if loaded)
      //   false             - do nothing
  
      // Clicked on the content
      clickContent: function (current, event) {
        return current.type === "image" ? "zoom" : false;
      },
  
      // Clicked on the slide
      clickSlide: "close",
  
      // Clicked on the background (backdrop) element;
      // if you have not changed the layout, then most likely you need to use `clickSlide` option
      clickOutside: "close",
  
      // Same as previous two, but for double click
      dblclickContent: false,
      dblclickSlide: false,
      dblclickOutside: false,
  
      // Custom options when mobile device is detected
      // =============================================
  
      mobile: {
        preventCaptionOverlap: false,
        idleTime: false,
        clickContent: function (current, event) {
          return current.type === "image" ? "toggleControls" : false;
        },
        clickSlide: function (current, event) {
          return current.type === "image" ? "toggleControls" : "close";
        },
        dblclickContent: function (current, event) {
          return current.type === "image" ? "zoom" : false;
        },
        dblclickSlide: function (current, event) {
          return current.type === "image" ? "zoom" : false;
        }
      },
  
      // Internationalization
      // ====================
  
      lang: "en",
      i18n: {
        en: {
          CLOSE: "Close",
          NEXT: "Next",
          PREV: "Previous",
          ERROR: "The requested content cannot be loaded. <br/> Please try again later.",
          PLAY_START: "Start slideshow",
          PLAY_STOP: "Pause slideshow",
          FULL_SCREEN: "Full screen",
          THUMBS: "Thumbnails",
          DOWNLOAD: "Download",
          SHARE: "Share",
          ZOOM: "Zoom"
        },
        de: {
          CLOSE: "Schlie&szlig;en",
          NEXT: "Weiter",
          PREV: "Zur&uuml;ck",
          ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es sp&auml;ter nochmal.",
          PLAY_START: "Diaschau starten",
          PLAY_STOP: "Diaschau beenden",
          FULL_SCREEN: "Vollbild",
          THUMBS: "Vorschaubilder",
          DOWNLOAD: "Herunterladen",
          SHARE: "Teilen",
          ZOOM: "Vergr&ouml;&szlig;ern"
        }
      }
    };
  
    // Few useful variables and methods
    // ================================
  
    var $W = $(window);
    var $D = $(document);
  
    var called = 0;
  
    // Check if an object is a jQuery object and not a native JavaScript object
    // ========================================================================
    var isQuery = function (obj) {
      return obj && obj.hasOwnProperty && obj instanceof $;
    };
  
    // Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"
    // ===============================================================================
    var requestAFrame = (function () {
      return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        // if all else fails, use setTimeout
        function (callback) {
          return window.setTimeout(callback, 1000 / 60);
        }
      );
    })();
  
    var cancelAFrame = (function () {
      return (
        window.cancelAnimationFrame ||
        window.webkitCancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        window.oCancelAnimationFrame ||
        function (id) {
          window.clearTimeout(id);
        }
      );
    })();
  
    // Detect the supported transition-end event property name
    // =======================================================
    var transitionEnd = (function () {
      var el = document.createElement("fakeelement"),
        t;
  
      var transitions = {
        transition: "transitionend",
        OTransition: "oTransitionEnd",
        MozTransition: "transitionend",
        WebkitTransition: "webkitTransitionEnd"
      };
  
      for (t in transitions) {
        if (el.style[t] !== undefined) {
          return transitions[t];
        }
      }
  
      return "transitionend";
    })();
  
    // Force redraw on an element.
    // This helps in cases where the browser doesn't redraw an updated element properly
    // ================================================================================
    var forceRedraw = function ($el) {
      return $el && $el.length && $el[0].offsetHeight;
    };
  
    // Exclude array (`buttons`) options from deep merging
    // ===================================================
    var mergeOpts = function (opts1, opts2) {
      var rez = $.extend(true, {}, opts1, opts2);
  
      $.each(opts2, function (key, value) {
        if ($.isArray(value)) {
          rez[key] = value;
        }
      });
  
      return rez;
    };
  
    // How much of an element is visible in viewport
    // =============================================
  
    var inViewport = function (elem) {
      var elemCenter, rez;
  
      if (!elem || elem.ownerDocument !== document) {
        return false;
      }
  
      $(".fancybox-container").css("pointer-events", "none");
  
      elemCenter = {
        x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
        y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
      };
  
      rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;
  
      $(".fancybox-container").css("pointer-events", "");
  
      return rez;
    };
  
    // Class definition
    // ================
  
    var FancyBox = function (content, opts, index) {
      var self = this;
  
      self.opts = mergeOpts({
        index: index
      }, $.fancybox.defaults);
  
      if ($.isPlainObject(opts)) {
        self.opts = mergeOpts(self.opts, opts);
      }
  
      if ($.fancybox.isMobile) {
        self.opts = mergeOpts(self.opts, self.opts.mobile);
      }
  
      self.id = self.opts.id || ++called;
  
      self.currIndex = parseInt(self.opts.index, 10) || 0;
      self.prevIndex = null;
  
      self.prevPos = null;
      self.currPos = 0;
  
      self.firstRun = true;
  
      // All group items
      self.group = [];
  
      // Existing slides (for current, next and previous gallery items)
      self.slides = {};
  
      // Create group elements
      self.addContent(content);
  
      if (!self.group.length) {
        return;
      }
  
      self.init();
    };
  
    $.extend(FancyBox.prototype, {
      // Create DOM structure
      // ====================
  
      init: function () {
        var self = this,
          firstItem = self.group[self.currIndex],
          firstItemOpts = firstItem.opts,
          $container,
          buttonStr;
  
        if (firstItemOpts.closeExisting) {
          $.fancybox.close(true);
        }
  
        // Hide scrollbars
        // ===============
  
        $("body").addClass("fancybox-active");
  
        if (
          !$.fancybox.getInstance() &&
          firstItemOpts.hideScrollbar !== false &&
          !$.fancybox.isMobile &&
          document.body.scrollHeight > window.innerHeight
        ) {
          $("head").append(
            '<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:' +
            (window.innerWidth - document.documentElement.clientWidth) +
            "px;}</style>"
          );
  
          $("body").addClass("compensate-for-scrollbar");
        }
  
        // Build html markup and set references
        // ====================================
  
        // Build html code for buttons and insert into main template
        buttonStr = "";
  
        $.each(firstItemOpts.buttons, function (index, value) {
          buttonStr += firstItemOpts.btnTpl[value] || "";
        });
  
        // Create markup from base template, it will be initially hidden to
        // avoid unnecessary work like painting while initializing is not complete
        $container = $(
            self.translate(
              self,
              firstItemOpts.baseTpl
              .replace("{{buttons}}", buttonStr)
              .replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight)
            )
          )
          .attr("id", "fancybox-container-" + self.id)
          .addClass(firstItemOpts.baseClass)
          .data("FancyBox", self)
          .appendTo(firstItemOpts.parentEl);
  
        // Create object holding references to jQuery wrapped nodes
        self.$refs = {
          container: $container
        };
  
        ["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function (item) {
          self.$refs[item] = $container.find(".fancybox-" + item);
        });
  
        self.trigger("onInit");
  
        // Enable events, deactive previous instances
        self.activate();
  
        // Build slides, load and reveal content
        self.jumpTo(self.currIndex);
      },
  
      // Simple i18n support - replaces object keys found in template
      // with corresponding values
      // ============================================================
  
      translate: function (obj, str) {
        var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;
  
        return str.replace(/\{\{(\w+)\}\}/g, function (match, n) {
          return arr[n] === undefined ? match : arr[n];
        });
      },
  
      // Populate current group with fresh content
      // Check if each object has valid type and content
      // ===============================================
  
      addContent: function (content) {
        var self = this,
          items = $.makeArray(content),
          thumbs;
  
        $.each(items, function (i, item) {
          var obj = {},
            opts = {},
            $item,
            type,
            found,
            src,
            srcParts;
  
          // Step 1 - Make sure we have an object
          // ====================================
  
          if ($.isPlainObject(item)) {
            // We probably have manual usage here, something like
            // $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )
  
            obj = item;
            opts = item.opts || item;
          } else if ($.type(item) === "object" && $(item).length) {
            // Here we probably have jQuery collection returned by some selector
            $item = $(item);
  
            // Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'`
            opts = $item.data() || {};
            opts = $.extend(true, {}, opts, opts.options);
  
            // Here we store clicked element
            opts.$orig = $item;
  
            obj.src = self.opts.src || opts.src || $item.attr("href");
  
            // Assume that simple syntax is used, for example:
            //   `$.fancybox.open( $("#test"), {} );`
            if (!obj.type && !obj.src) {
              obj.type = "inline";
              obj.src = item;
            }
          } else {
            // Assume we have a simple html code, for example:
            //   $.fancybox.open( '<div><h1>Hi!</h1></div>' );
            obj = {
              type: "html",
              src: item + ""
            };
          }
  
          // Each gallery object has full collection of options
          obj.opts = $.extend(true, {}, self.opts, opts);
  
          // Do not merge buttons array
          if ($.isArray(opts.buttons)) {
            obj.opts.buttons = opts.buttons;
          }
  
          if ($.fancybox.isMobile && obj.opts.mobile) {
            obj.opts = mergeOpts(obj.opts, obj.opts.mobile);
          }
  
          // Step 2 - Make sure we have content type, if not - try to guess
          // ==============================================================
  
          type = obj.type || obj.opts.type;
          src = obj.src || "";
  
          if (!type && src) {
            if ((found = src.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))) {
              type = "video";
  
              if (!obj.opts.video.format) {
                obj.opts.video.format = "video/" + (found[1] === "ogv" ? "ogg" : found[1]);
              }
            } else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {
              type = "image";
            } else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {
              type = "iframe";
              obj = $.extend(true, obj, {
                contentType: "pdf",
                opts: {
                  iframe: {
                    preload: false
                  }
                }
              });
            } else if (src.charAt(0) === "#") {
              type = "inline";
            }
          }
  
          if (type) {
            obj.type = type;
          } else {
            self.trigger("objectNeedsType", obj);
          }
  
          if (!obj.contentType) {
            obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type;
          }
  
          // Step 3 - Some adjustments
          // =========================
  
          obj.index = self.group.length;
  
          if (obj.opts.smallBtn == "auto") {
            obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1;
          }
  
          if (obj.opts.toolbar === "auto") {
            obj.opts.toolbar = !obj.opts.smallBtn;
          }
  
          // Find thumbnail image, check if exists and if is in the viewport
          obj.$thumb = obj.opts.$thumb || null;
  
          if (obj.opts.$trigger && obj.index === self.opts.index) {
            obj.$thumb = obj.opts.$trigger.find("img:first");
  
            if (obj.$thumb.length) {
              obj.opts.$orig = obj.opts.$trigger;
            }
          }
  
          if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {
            obj.$thumb = obj.opts.$orig.find("img:first");
          }
  
          if (obj.$thumb && !obj.$thumb.length) {
            obj.$thumb = null;
          }
  
          obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null);
  
          // "caption" is a "special" option, it can be used to customize caption per gallery item
          if ($.type(obj.opts.caption) === "function") {
            obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);
          }
  
          if ($.type(self.opts.caption) === "function") {
            obj.opts.caption = self.opts.caption.apply(item, [self, obj]);
          }
  
          // Make sure we have caption as a string or jQuery object
          if (!(obj.opts.caption instanceof $)) {
            obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + "";
          }
  
          // Check if url contains "filter" used to filter the content
          // Example: "ajax.html #something"
          if (obj.type === "ajax") {
            srcParts = src.split(/\s+/, 2);
  
            if (srcParts.length > 1) {
              obj.src = srcParts.shift();
  
              obj.opts.filter = srcParts.shift();
            }
          }
  
          // Hide all buttons and disable interactivity for modal items
          if (obj.opts.modal) {
            obj.opts = $.extend(true, obj.opts, {
              trapFocus: true,
              // Remove buttons
              infobar: 0,
              toolbar: 0,
  
              smallBtn: 0,
  
              // Disable keyboard navigation
              keyboard: 0,
  
              // Disable some modules
              slideShow: 0,
              fullScreen: 0,
              thumbs: 0,
              touch: 0,
  
              // Disable click event handlers
              clickContent: false,
              clickSlide: false,
              clickOutside: false,
              dblclickContent: false,
              dblclickSlide: false,
              dblclickOutside: false
            });
          }
  
          // Step 4 - Add processed object to group
          // ======================================
  
          self.group.push(obj);
        });
  
        // Update controls if gallery is already opened
        if (Object.keys(self.slides).length) {
          self.updateControls();
  
          // Update thumbnails, if needed
          thumbs = self.Thumbs;
  
          if (thumbs && thumbs.isActive) {
            thumbs.create();
  
            thumbs.focus();
          }
        }
      },
  
      // Attach an event handler functions for:
      //   - navigation buttons
      //   - browser scrolling, resizing;
      //   - focusing
      //   - keyboard
      //   - detecting inactivity
      // ======================================
  
      addEvents: function () {
        var self = this;
  
        self.removeEvents();
  
        // Make navigation elements clickable
        // ==================================
  
        self.$refs.container
          .on("click.fb-close", "[data-fancybox-close]", function (e) {
            e.stopPropagation();
            e.preventDefault();
  
            self.close(e);
          })
          .on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function (e) {
            e.stopPropagation();
            e.preventDefault();
  
            self.previous();
          })
          .on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function (e) {
            e.stopPropagation();
            e.preventDefault();
  
            self.next();
          })
          .on("click.fb", "[data-fancybox-zoom]", function (e) {
            // Click handler for zoom button
            self[self.isScaledDown() ? "scaleToActual" : "scaleToFit"]();
          });
  
        // Handle page scrolling and browser resizing
        // ==========================================
  
        $W.on("orientationchange.fb resize.fb", function (e) {
          if (e && e.originalEvent && e.originalEvent.type === "resize") {
            if (self.requestId) {
              cancelAFrame(self.requestId);
            }
  
            self.requestId = requestAFrame(function () {
              self.update(e);
            });
          } else {
            if (self.current && self.current.type === "iframe") {
              self.$refs.stage.hide();
            }
  
            setTimeout(
              function () {
                self.$refs.stage.show();
  
                self.update(e);
              },
              $.fancybox.isMobile ? 600 : 250
            );
          }
        });
  
        $D.on("keydown.fb", function (e) {
          var instance = $.fancybox ? $.fancybox.getInstance() : null,
            current = instance.current,
            keycode = e.keyCode || e.which;
  
          // Trap keyboard focus inside of the modal
          // =======================================
  
          if (keycode == 9) {
            if (current.opts.trapFocus) {
              self.focus(e);
            }
  
            return;
          }
  
          // Enable keyboard navigation
          // ==========================
  
          if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input,textarea,video,audio,select")) {
            return;
          }
  
          // Backspace and Esc keys
          if (keycode === 8 || keycode === 27) {
            e.preventDefault();
  
            self.close(e);
  
            return;
          }
  
          // Left arrow and Up arrow
          if (keycode === 37 || keycode === 38) {
            e.preventDefault();
  
            self.previous();
  
            return;
          }
  
          // Righ arrow and Down arrow
          if (keycode === 39 || keycode === 40) {
            e.preventDefault();
  
            self.next();
  
            return;
          }
  
          self.trigger("afterKeydown", e, keycode);
        });
  
        // Hide controls after some inactivity period
        if (self.group[self.currIndex].opts.idleTime) {
          self.idleSecondsCounter = 0;
  
          $D.on(
            "mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",
            function (e) {
              self.idleSecondsCounter = 0;
  
              if (self.isIdle) {
                self.showControls();
              }
  
              self.isIdle = false;
            }
          );
  
          self.idleInterval = window.setInterval(function () {
            self.idleSecondsCounter++;
  
            if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {
              self.isIdle = true;
              self.idleSecondsCounter = 0;
  
              self.hideControls();
            }
          }, 1000);
        }
      },
  
      // Remove events added by the core
      // ===============================
  
      removeEvents: function () {
        var self = this;
  
        $W.off("orientationchange.fb resize.fb");
        $D.off("keydown.fb .fb-idle");
  
        this.$refs.container.off(".fb-close .fb-prev .fb-next");
  
        if (self.idleInterval) {
          window.clearInterval(self.idleInterval);
  
          self.idleInterval = null;
        }
      },
  
      // Change to previous gallery item
      // ===============================
  
      previous: function (duration) {
        return this.jumpTo(this.currPos - 1, duration);
      },
  
      // Change to next gallery item
      // ===========================
  
      next: function (duration) {
        return this.jumpTo(this.currPos + 1, duration);
      },
  
      // Switch to selected gallery item
      // ===============================
  
      jumpTo: function (pos, duration) {
        var self = this,
          groupLen = self.group.length,
          firstRun,
          isMoved,
          loop,
          current,
          previous,
          slidePos,
          stagePos,
          prop,
          diff;
  
        if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {
          return;
        }
  
        // Should loop?
        pos = parseInt(pos, 10);
        loop = self.current ? self.current.opts.loop : self.opts.loop;
  
        if (!loop && (pos < 0 || pos >= groupLen)) {
          return false;
        }
  
        // Check if opening for the first time; this helps to speed things up
        firstRun = self.firstRun = !Object.keys(self.slides).length;
  
        // Create slides
        previous = self.current;
  
        self.prevIndex = self.currIndex;
        self.prevPos = self.currPos;
  
        current = self.createSlide(pos);
  
        if (groupLen > 1) {
          if (loop || current.index < groupLen - 1) {
            self.createSlide(pos + 1);
          }
  
          if (loop || current.index > 0) {
            self.createSlide(pos - 1);
          }
        }
  
        self.current = current;
        self.currIndex = current.index;
        self.currPos = current.pos;
  
        self.trigger("beforeShow", firstRun);
  
        self.updateControls();
  
        // Validate duration length
        current.forcedDuration = undefined;
  
        if ($.isNumeric(duration)) {
          current.forcedDuration = duration;
        } else {
          duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"];
        }
  
        duration = parseInt(duration, 10);
  
        // Check if user has swiped the slides or if still animating
        isMoved = self.isMoved(current);
  
        // Make sure current slide is visible
        current.$slide.addClass("fancybox-slide--current");
  
        // Fresh start - reveal container, current slide and start loading content
        if (firstRun) {
          if (current.opts.animationEffect && duration) {
            self.$refs.container.css("transition-duration", duration + "ms");
          }
  
          self.$refs.container.addClass("fancybox-is-open").trigger("focus");
  
          // Attempt to load content into slide
          // This will later call `afterLoad` -> `revealContent`
          self.loadSlide(current);
  
          self.preload("image");
  
          return;
        }
  
        // Get actual slide/stage positions (before cleaning up)
        slidePos = $.fancybox.getTranslate(previous.$slide);
        stagePos = $.fancybox.getTranslate(self.$refs.stage);
  
        // Clean up all slides
        $.each(self.slides, function (index, slide) {
          $.fancybox.stop(slide.$slide, true);
        });
  
        if (previous.pos !== current.pos) {
          previous.isComplete = false;
        }
  
        previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current");
  
        // If slides are out of place, then animate them to correct position
        if (isMoved) {
          // Calculate horizontal swipe distance
          diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);
  
          $.each(self.slides, function (index, slide) {
            slide.$slide.removeClass("fancybox-animated").removeClass(function (index, className) {
              return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
            });
  
            // Make sure that each slide is in equal distance
            // This is mostly needed for freshly added slides, because they are not yet positioned
            var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;
  
            $.fancybox.setTranslate(slide.$slide, {
              top: 0,
              left: leftPos - stagePos.left + diff
            });
  
            if (slide.pos !== current.pos) {
              slide.$slide.addClass("fancybox-slide--" + (slide.pos > current.pos ? "next" : "previous"));
            }
  
            // Redraw to make sure that transition will start
            forceRedraw(slide.$slide);
  
            // Animate the slide
            $.fancybox.animate(
              slide.$slide, {
                top: 0,
                left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter
              },
              duration,
              function () {
                slide.$slide
                  .css({
                    transform: "",
                    opacity: ""
                  })
                  .removeClass("fancybox-slide--next fancybox-slide--previous");
  
                if (slide.pos === self.currPos) {
                  self.complete();
                }
              }
            );
          });
        } else if (duration && current.opts.transitionEffect) {
          // Set transition effect for previously active slide
          prop = "fancybox-animated fancybox-fx-" + current.opts.transitionEffect;
  
          previous.$slide.addClass("fancybox-slide--" + (previous.pos > current.pos ? "next" : "previous"));
  
          $.fancybox.animate(
            previous.$slide,
            prop,
            duration,
            function () {
              previous.$slide.removeClass(prop).removeClass("fancybox-slide--next fancybox-slide--previous");
            },
            false
          );
        }
  
        if (current.isLoaded) {
          self.revealContent(current);
        } else {
          self.loadSlide(current);
        }
  
        self.preload("image");
      },
  
      // Create new "slide" element
      // These are gallery items  that are actually added to DOM
      // =======================================================
  
      createSlide: function (pos) {
        var self = this,
          $slide,
          index;
  
        index = pos % self.group.length;
        index = index < 0 ? self.group.length + index : index;
  
        if (!self.slides[pos] && self.group[index]) {
          $slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);
  
          self.slides[pos] = $.extend(true, {}, self.group[index], {
            pos: pos,
            $slide: $slide,
            isLoaded: false
          });
  
          self.updateSlide(self.slides[pos]);
        }
  
        return self.slides[pos];
      },
  
      // Scale image to the actual size of the image;
      // x and y values should be relative to the slide
      // ==============================================
  
      scaleToActual: function (x, y, duration) {
        var self = this,
          current = self.current,
          $content = current.$content,
          canvasWidth = $.fancybox.getTranslate(current.$slide).width,
          canvasHeight = $.fancybox.getTranslate(current.$slide).height,
          newImgWidth = current.width,
          newImgHeight = current.height,
          imgPos,
          posX,
          posY,
          scaleX,
          scaleY;
  
        if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
          return;
        }
  
        self.isAnimating = true;
  
        $.fancybox.stop($content);
  
        x = x === undefined ? canvasWidth * 0.5 : x;
        y = y === undefined ? canvasHeight * 0.5 : y;
  
        imgPos = $.fancybox.getTranslate($content);
  
        imgPos.top -= $.fancybox.getTranslate(current.$slide).top;
        imgPos.left -= $.fancybox.getTranslate(current.$slide).left;
  
        scaleX = newImgWidth / imgPos.width;
        scaleY = newImgHeight / imgPos.height;
  
        // Get center position for original image
        posX = canvasWidth * 0.5 - newImgWidth * 0.5;
        posY = canvasHeight * 0.5 - newImgHeight * 0.5;
  
        // Make sure image does not move away from edges
        if (newImgWidth > canvasWidth) {
          posX = imgPos.left * scaleX - (x * scaleX - x);
  
          if (posX > 0) {
            posX = 0;
          }
  
          if (posX < canvasWidth - newImgWidth) {
            posX = canvasWidth - newImgWidth;
          }
        }
  
        if (newImgHeight > canvasHeight) {
          posY = imgPos.top * scaleY - (y * scaleY - y);
  
          if (posY > 0) {
            posY = 0;
          }
  
          if (posY < canvasHeight - newImgHeight) {
            posY = canvasHeight - newImgHeight;
          }
        }
  
        self.updateCursor(newImgWidth, newImgHeight);
  
        $.fancybox.animate(
          $content, {
            top: posY,
            left: posX,
            scaleX: scaleX,
            scaleY: scaleY
          },
          duration || 366,
          function () {
            self.isAnimating = false;
          }
        );
  
        // Stop slideshow
        if (self.SlideShow && self.SlideShow.isActive) {
          self.SlideShow.stop();
        }
      },
  
      // Scale image to fit inside parent element
      // ========================================
  
      scaleToFit: function (duration) {
        var self = this,
          current = self.current,
          $content = current.$content,
          end;
  
        if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
          return;
        }
  
        self.isAnimating = true;
  
        $.fancybox.stop($content);
  
        end = self.getFitPos(current);
  
        self.updateCursor(end.width, end.height);
  
        $.fancybox.animate(
          $content, {
            top: end.top,
            left: end.left,
            scaleX: end.width / $content.width(),
            scaleY: end.height / $content.height()
          },
          duration || 366,
          function () {
            self.isAnimating = false;
          }
        );
      },
  
      // Calculate image size to fit inside viewport
      // ===========================================
  
      getFitPos: function (slide) {
        var self = this,
          $content = slide.$content,
          $slide = slide.$slide,
          width = slide.width || slide.opts.width,
          height = slide.height || slide.opts.height,
          maxWidth,
          maxHeight,
          minRatio,
          aspectRatio,
          rez = {};
  
        if (!slide.isLoaded || !$content || !$content.length) {
          return false;
        }
  
        maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;
        maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;
  
        maxWidth -=
          parseFloat($slide.css("paddingLeft")) +
          parseFloat($slide.css("paddingRight")) +
          parseFloat($content.css("marginLeft")) +
          parseFloat($content.css("marginRight"));
  
        maxHeight -=
          parseFloat($slide.css("paddingTop")) +
          parseFloat($slide.css("paddingBottom")) +
          parseFloat($content.css("marginTop")) +
          parseFloat($content.css("marginBottom"));
  
        if (!width || !height) {
          width = maxWidth;
          height = maxHeight;
        }
  
        minRatio = Math.min(1, maxWidth / width, maxHeight / height);
  
        width = minRatio * width;
        height = minRatio * height;
  
        // Adjust width/height to precisely fit into container
        if (width > maxWidth - 0.5) {
          width = maxWidth;
        }
  
        if (height > maxHeight - 0.5) {
          height = maxHeight;
        }
  
        if (slide.type === "image") {
          rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css("paddingTop"));
          rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css("paddingLeft"));
        } else if (slide.contentType === "video") {
          // Force aspect ratio for the video
          // "I say the whole world must learn of our peaceful ways… by force!"
          aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;
  
          if (height > width / aspectRatio) {
            height = width / aspectRatio;
          } else if (width > height * aspectRatio) {
            width = height * aspectRatio;
          }
        }
  
        rez.width = width;
        rez.height = height;
  
        return rez;
      },
  
      // Update content size and position for all slides
      // ==============================================
  
      update: function (e) {
        var self = this;
  
        $.each(self.slides, function (key, slide) {
          self.updateSlide(slide, e);
        });
      },
  
      // Update slide content position and size
      // ======================================
  
      updateSlide: function (slide, e) {
        var self = this,
          $content = slide && slide.$content,
          width = slide.width || slide.opts.width,
          height = slide.height || slide.opts.height,
          $slide = slide.$slide;
  
        // First, prevent caption overlap, if needed
        self.adjustCaption(slide);
  
        // Then resize content to fit inside the slide
        if ($content && (width || height || slide.contentType === "video") && !slide.hasError) {
          $.fancybox.stop($content);
  
          $.fancybox.setTranslate($content, self.getFitPos(slide));
  
          if (slide.pos === self.currPos) {
            self.isAnimating = false;
  
            self.updateCursor();
          }
        }
  
        // Then some adjustments
        self.adjustLayout(slide);
  
        if ($slide.length) {
          $slide.trigger("refresh");
  
          if (slide.pos === self.currPos) {
            self.$refs.toolbar
              .add(self.$refs.navigation.find(".fancybox-button--arrow_right"))
              .toggleClass("compensate-for-scrollbar", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);
          }
        }
  
        self.trigger("onUpdate", slide, e);
      },
  
      // Horizontally center slide
      // =========================
  
      centerSlide: function (duration) {
        var self = this,
          current = self.current,
          $slide = current.$slide;
  
        if (self.isClosing || !current) {
          return;
        }
  
        $slide.siblings().css({
          transform: "",
          opacity: ""
        });
  
        $slide
          .parent()
          .children()
          .removeClass("fancybox-slide--previous fancybox-slide--next");
  
        $.fancybox.animate(
          $slide, {
            top: 0,
            left: 0,
            opacity: 1
          },
          duration === undefined ? 0 : duration,
          function () {
            // Clean up
            $slide.css({
              transform: "",
              opacity: ""
            });
  
            if (!current.isComplete) {
              self.complete();
            }
          },
          false
        );
      },
  
      // Check if current slide is moved (swiped)
      // ========================================
  
      isMoved: function (slide) {
        var current = slide || this.current,
          slidePos,
          stagePos;
  
        if (!current) {
          return false;
        }
  
        stagePos = $.fancybox.getTranslate(this.$refs.stage);
        slidePos = $.fancybox.getTranslate(current.$slide);
  
        return (
          !current.$slide.hasClass("fancybox-animated") &&
          (Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5)
        );
      },
  
      // Update cursor style depending if content can be zoomed
      // ======================================================
  
      updateCursor: function (nextWidth, nextHeight) {
        var self = this,
          current = self.current,
          $container = self.$refs.container,
          canPan,
          isZoomable;
  
        if (!current || self.isClosing || !self.Guestures) {
          return;
        }
  
        $container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan");
  
        canPan = self.canPan(nextWidth, nextHeight);
  
        isZoomable = canPan ? true : self.isZoomable();
  
        $container.toggleClass("fancybox-is-zoomable", isZoomable);
  
        $("[data-fancybox-zoom]").prop("disabled", !isZoomable);
  
        if (canPan) {
          $container.addClass("fancybox-can-pan");
        } else if (
          isZoomable &&
          (current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == "zoom"))
        ) {
          $container.addClass("fancybox-can-zoomIn");
        } else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== "video") {
          $container.addClass("fancybox-can-swipe");
        }
      },
  
      // Check if current slide is zoomable
      // ==================================
  
      isZoomable: function () {
        var self = this,
          current = self.current,
          fitPos;
  
        // Assume that slide is zoomable if:
        //   - image is still loading
        //   - actual size of the image is smaller than available area
        if (current && !self.isClosing && current.type === "image" && !current.hasError) {
          if (!current.isLoaded) {
            return true;
          }
  
          fitPos = self.getFitPos(current);
  
          if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {
            return true;
          }
        }
  
        return false;
      },
  
      // Check if current image dimensions are smaller than actual
      // =========================================================
  
      isScaledDown: function (nextWidth, nextHeight) {
        var self = this,
          rez = false,
          current = self.current,
          $content = current.$content;
  
        if (nextWidth !== undefined && nextHeight !== undefined) {
          rez = nextWidth < current.width && nextHeight < current.height;
        } else if ($content) {
          rez = $.fancybox.getTranslate($content);
          rez = rez.width < current.width && rez.height < current.height;
        }
  
        return rez;
      },
  
      // Check if image dimensions exceed parent element
      // ===============================================
  
      canPan: function (nextWidth, nextHeight) {
        var self = this,
          current = self.current,
          pos = null,
          rez = false;
  
        if (current.type === "image" && (current.isComplete || (nextWidth && nextHeight)) && !current.hasError) {
          rez = self.getFitPos(current);
  
          if (nextWidth !== undefined && nextHeight !== undefined) {
            pos = {
              width: nextWidth,
              height: nextHeight
            };
          } else if (current.isComplete) {
            pos = $.fancybox.getTranslate(current.$content);
          }
  
          if (pos && rez) {
            rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;
          }
        }
  
        return rez;
      },
  
      // Load content into the slide
      // ===========================
  
      loadSlide: function (slide) {
        var self = this,
          type,
          $slide,
          ajaxLoad;
  
        if (slide.isLoading || slide.isLoaded) {
          return;
        }
  
        slide.isLoading = true;
  
        if (self.trigger("beforeLoad", slide) === false) {
          slide.isLoading = false;
  
          return false;
        }
  
        type = slide.type;
        $slide = slide.$slide;
  
        $slide
          .off("refresh")
          .trigger("onReset")
          .addClass(slide.opts.slideClass);
  
        // Create content depending on the type
        switch (type) {
          case "image":
            self.setImage(slide);
  
            break;
  
          case "iframe":
            self.setIframe(slide);
  
            break;
  
          case "html":
            self.setContent(slide, slide.src || slide.content);
  
            break;
  
          case "video":
            self.setContent(
              slide,
              slide.opts.video.tpl
              .replace(/\{\{src\}\}/gi, slide.src)
              .replace("{{format}}", slide.opts.videoFormat || slide.opts.video.format || "")
              .replace("{{poster}}", slide.thumb || "")
            );
  
            break;
  
          case "inline":
            if ($(slide.src).length) {
              self.setContent(slide, $(slide.src));
            } else {
              self.setError(slide);
            }
  
            break;
  
          case "ajax":
            self.showLoading(slide);
  
            ajaxLoad = $.ajax(
              $.extend({}, slide.opts.ajax.settings, {
                url: slide.src,
                success: function (data, textStatus) {
                  if (textStatus === "success") {
                    self.setContent(slide, data);
                  }
                },
                error: function (jqXHR, textStatus) {
                  if (jqXHR && textStatus !== "abort") {
                    self.setError(slide);
                  }
                }
              })
            );
  
            $slide.one("onReset", function () {
              ajaxLoad.abort();
            });
  
            break;
  
          default:
            self.setError(slide);
  
            break;
        }
  
        return true;
      },
  
      // Use thumbnail image, if possible
      // ================================
  
      setImage: function (slide) {
        var self = this,
          ghost;
  
        // Check if need to show loading icon
        setTimeout(function () {
          var $img = slide.$image;
  
          if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {
            self.showLoading(slide);
          }
        }, 50);
  
        //Check if image has srcset
        self.checkSrcset(slide);
  
        // This will be wrapper containing both ghost and actual image
        slide.$content = $('<div class="fancybox-content"></div>')
          .addClass("fancybox-is-hidden")
          .appendTo(slide.$slide.addClass("fancybox-slide--image"));
  
        // If we have a thumbnail, we can display it while actual image is loading
        // Users will not stare at black screen and actual image will appear gradually
        if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {
          slide.width = slide.opts.width;
          slide.height = slide.opts.height;
  
          ghost = document.createElement("img");
  
          ghost.onerror = function () {
            $(this).remove();
  
            slide.$ghost = null;
          };
  
          ghost.onload = function () {
            self.afterLoad(slide);
          };
  
          slide.$ghost = $(ghost)
            .addClass("fancybox-image")
            .appendTo(slide.$content)
            .attr("src", slide.thumb);
        }
  
        // Start loading actual image
        self.setBigImage(slide);
      },
  
      // Check if image has srcset and get the source
      // ============================================
      checkSrcset: function (slide) {
        var srcset = slide.opts.srcset || slide.opts.image.srcset,
          found,
          temp,
          pxRatio,
          windowWidth;
  
        // If we have "srcset", then we need to find first matching "src" value.
        // This is necessary, because when you set an src attribute, the browser will preload the image
        // before any javascript or even CSS is applied.
        if (srcset) {
          pxRatio = window.devicePixelRatio || 1;
          windowWidth = window.innerWidth * pxRatio;
  
          temp = srcset.split(",").map(function (el) {
            var ret = {};
  
            el.trim()
              .split(/\s+/)
              .forEach(function (el, i) {
                var value = parseInt(el.substring(0, el.length - 1), 10);
  
                if (i === 0) {
                  return (ret.url = el);
                }
  
                if (value) {
                  ret.value = value;
                  ret.postfix = el[el.length - 1];
                }
              });
  
            return ret;
          });
  
          // Sort by value
          temp.sort(function (a, b) {
            return a.value - b.value;
          });
  
          // Ok, now we have an array of all srcset values
          for (var j = 0; j < temp.length; j++) {
            var el = temp[j];
  
            if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) {
              found = el;
              break;
            }
          }
  
          // If not found, take the last one
          if (!found && temp.length) {
            found = temp[temp.length - 1];
          }
  
          if (found) {
            slide.src = found.url;
  
            // If we have default width/height values, we can calculate height for matching source
            if (slide.width && slide.height && found.postfix == "w") {
              slide.height = (slide.width / slide.height) * found.value;
              slide.width = found.value;
            }
  
            slide.opts.srcset = srcset;
          }
        }
      },
  
      // Create full-size image
      // ======================
  
      setBigImage: function (slide) {
        var self = this,
          img = document.createElement("img"),
          $img = $(img);
  
        slide.$image = $img
          .one("error", function () {
            self.setError(slide);
          })
          .one("load", function () {
            var sizes;
  
            if (!slide.$ghost) {
              self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);
  
              self.afterLoad(slide);
            }
  
            if (self.isClosing) {
              return;
            }
  
            if (slide.opts.srcset) {
              sizes = slide.opts.sizes;
  
              if (!sizes || sizes === "auto") {
                sizes =
                  (slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round((slide.width / slide.height) * 100)) +
                  "vw";
              }
  
              $img.attr("sizes", sizes).attr("srcset", slide.opts.srcset);
            }
  
            // Hide temporary image after some delay
            if (slide.$ghost) {
              setTimeout(function () {
                if (slide.$ghost && !self.isClosing) {
                  slide.$ghost.hide();
                }
              }, Math.min(300, Math.max(1000, slide.height / 1600)));
            }
  
            self.hideLoading(slide);
          })
          .addClass("fancybox-image")
          .attr("src", slide.src)
          .appendTo(slide.$content);
  
        if ((img.complete || img.readyState == "complete") && $img.naturalWidth && $img.naturalHeight) {
          $img.trigger("load");
        } else if (img.error) {
          $img.trigger("error");
        }
      },
  
      // Computes the slide size from image size and maxWidth/maxHeight
      // ==============================================================
  
      resolveImageSlideSize: function (slide, imgWidth, imgHeight) {
        var maxWidth = parseInt(slide.opts.width, 10),
          maxHeight = parseInt(slide.opts.height, 10);
  
        // Sets the default values from the image
        slide.width = imgWidth;
        slide.height = imgHeight;
  
        if (maxWidth > 0) {
          slide.width = maxWidth;
          slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);
        }
  
        if (maxHeight > 0) {
          slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);
          slide.height = maxHeight;
        }
      },
  
      // Create iframe wrapper, iframe and bindings
      // ==========================================
  
      setIframe: function (slide) {
        var self = this,
          opts = slide.opts.iframe,
          $slide = slide.$slide,
          $iframe;
  
        slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>')
          .css(opts.css)
          .appendTo($slide);
  
        $slide.addClass("fancybox-slide--" + slide.contentType);
  
        slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime()))
          .attr(opts.attr)
          .appendTo(slide.$content);
  
        if (opts.preload) {
          self.showLoading(slide);
  
          // Unfortunately, it is not always possible to determine if iframe is successfully loaded
          // (due to browser security policy)
  
          $iframe.on("load.fb error.fb", function (e) {
            this.isReady = 1;
  
            slide.$slide.trigger("refresh");
  
            self.afterLoad(slide);
          });
  
          // Recalculate iframe content size
          // ===============================
  
          $slide.on("refresh.fb", function () {
            var $content = slide.$content,
              frameWidth = opts.css.width,
              frameHeight = opts.css.height,
              $contents,
              $body;
  
            if ($iframe[0].isReady !== 1) {
              return;
            }
  
            try {
              $contents = $iframe.contents();
              $body = $contents.find("body");
            } catch (ignore) {}
  
            // Calculate content dimensions, if it is accessible
            if ($body && $body.length && $body.children().length) {
              // Avoid scrolling to top (if multiple instances)
              $slide.css("overflow", "visible");
  
              $content.css({
                width: "100%",
                "max-width": "100%",
                height: "9999px"
              });
  
              if (frameWidth === undefined) {
                frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));
              }
  
              $content.css("width", frameWidth ? frameWidth : "").css("max-width", "");
  
              if (frameHeight === undefined) {
                frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));
              }
  
              $content.css("height", frameHeight ? frameHeight : "");
  
              $slide.css("overflow", "auto");
            }
  
            $content.removeClass("fancybox-is-hidden");
          });
        } else {
          self.afterLoad(slide);
        }
  
        $iframe.attr("src", slide.src);
  
        // Remove iframe if closing or changing gallery item
        $slide.one("onReset", function () {
          // This helps IE not to throw errors when closing
          try {
            $(this)
              .find("iframe")
              .hide()
              .unbind()
              .attr("src", "//about:blank");
          } catch (ignore) {}
  
          $(this)
            .off("refresh.fb")
            .empty();
  
          slide.isLoaded = false;
          slide.isRevealed = false;
        });
      },
  
      // Wrap and append content to the slide
      // ======================================
  
      setContent: function (slide, content) {
        var self = this;
  
        if (self.isClosing) {
          return;
        }
  
        self.hideLoading(slide);
  
        if (slide.$content) {
          $.fancybox.stop(slide.$content);
        }
  
        slide.$slide.empty();
  
        // If content is a jQuery object, then it will be moved to the slide.
        // The placeholder is created so we will know where to put it back.
        if (isQuery(content) && content.parent().length) {
          // Make sure content is not already moved to fancyBox
          if (content.hasClass("fancybox-content") || content.parent().hasClass("fancybox-content")) {
            content.parents(".fancybox-slide").trigger("onReset");
          }
  
          // Create temporary element marking original place of the content
          slide.$placeholder = $("<div>")
            .hide()
            .insertAfter(content);
  
          // Make sure content is visible
          content.css("display", "inline-block");
        } else if (!slide.hasError) {
          // If content is just a plain text, try to convert it to html
          if ($.type(content) === "string") {
            content = $("<div>")
              .append($.trim(content))
              .contents();
          }
  
          // If "filter" option is provided, then filter content
          if (slide.opts.filter) {
            content = $("<div>")
              .html(content)
              .find(slide.opts.filter);
          }
        }
  
        slide.$slide.one("onReset", function () {
          // Pause all html5 video/audio
          $(this)
            .find("video,audio")
            .trigger("pause");
  
          // Put content back
          if (slide.$placeholder) {
            slide.$placeholder.after(content.removeClass("fancybox-content").hide()).remove();
  
            slide.$placeholder = null;
          }
  
          // Remove custom close button
          if (slide.$smallBtn) {
            slide.$smallBtn.remove();
  
            slide.$smallBtn = null;
          }
  
          // Remove content and mark slide as not loaded
          if (!slide.hasError) {
            $(this).empty();
  
            slide.isLoaded = false;
            slide.isRevealed = false;
          }
        });
  
        $(content).appendTo(slide.$slide);
  
        if ($(content).is("video,audio")) {
          $(content).addClass("fancybox-video");
  
          $(content).wrap("<div></div>");
  
          slide.contentType = "video";
  
          slide.opts.width = slide.opts.width || $(content).attr("width");
          slide.opts.height = slide.opts.height || $(content).attr("height");
        }
  
        slide.$content = slide.$slide
          .children()
          .filter("div,form,main,video,audio,article,.fancybox-content")
          .first();
  
        slide.$content.siblings().hide();
  
        // Re-check if there is a valid content
        // (in some cases, ajax response can contain various elements or plain text)
        if (!slide.$content.length) {
          slide.$content = slide.$slide
            .wrapInner("<div></div>")
            .children()
            .first();
        }
  
        slide.$content.addClass("fancybox-content");
  
        slide.$slide.addClass("fancybox-slide--" + slide.contentType);
  
        self.afterLoad(slide);
      },
  
      // Display error message
      // =====================
  
      setError: function (slide) {
        slide.hasError = true;
  
        slide.$slide
          .trigger("onReset")
          .removeClass("fancybox-slide--" + slide.contentType)
          .addClass("fancybox-slide--error");
  
        slide.contentType = "html";
  
        this.setContent(slide, this.translate(slide, slide.opts.errorTpl));
  
        if (slide.pos === this.currPos) {
          this.isAnimating = false;
        }
      },
  
      // Show loading icon inside the slide
      // ==================================
  
      showLoading: function (slide) {
        var self = this;
  
        slide = slide || self.current;
  
        if (slide && !slide.$spinner) {
          slide.$spinner = $(self.translate(self, self.opts.spinnerTpl))
            .appendTo(slide.$slide)
            .hide()
            .fadeIn("fast");
        }
      },
  
      // Remove loading icon from the slide
      // ==================================
  
      hideLoading: function (slide) {
        var self = this;
  
        slide = slide || self.current;
  
        if (slide && slide.$spinner) {
          slide.$spinner.stop().remove();
  
          delete slide.$spinner;
        }
      },
  
      // Adjustments after slide content has been loaded
      // ===============================================
  
      afterLoad: function (slide) {
        var self = this;
  
        if (self.isClosing) {
          return;
        }
  
        slide.isLoading = false;
        slide.isLoaded = true;
  
        self.trigger("afterLoad", slide);
  
        self.hideLoading(slide);
  
        // Add small close button
        if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {
          slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);
        }
  
        // Disable right click
        if (slide.opts.protect && slide.$content && !slide.hasError) {
          slide.$content.on("contextmenu.fb", function (e) {
            if (e.button == 2) {
              e.preventDefault();
            }
  
            return true;
          });
  
          // Add fake element on top of the image
          // This makes a bit harder for user to select image
          if (slide.type === "image") {
            $('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);
          }
        }
  
        self.adjustCaption(slide);
  
        self.adjustLayout(slide);
  
        if (slide.pos === self.currPos) {
          self.updateCursor();
        }
  
        self.revealContent(slide);
      },
  
      // Prevent caption overlap,
      // fix css inconsistency across browsers
      // =====================================
  
      adjustCaption: function (slide) {
        var self = this,
          current = slide || self.current,
          caption = current.opts.caption,
          preventOverlap = current.opts.preventCaptionOverlap,
          $caption = self.$refs.caption,
          $clone,
          captionH = false;
  
        $caption.toggleClass("fancybox-caption--separate", preventOverlap);
  
        if (preventOverlap && caption && caption.length) {
          if (current.pos !== self.currPos) {
            $clone = $caption.clone().appendTo($caption.parent());
  
            $clone
              .children()
              .eq(0)
              .empty()
              .html(caption);
  
            captionH = $clone.outerHeight(true);
  
            $clone.empty().remove();
          } else if (self.$caption) {
            captionH = self.$caption.outerHeight(true);
          }
  
          current.$slide.css("padding-bottom", captionH || "");
        }
      },
  
      // Simple hack to fix inconsistency across browsers, described here (affects Edge, too):
      // https://bugzilla.mozilla.org/show_bug.cgi?id=748518
      // ====================================================================================
  
      adjustLayout: function (slide) {
        var self = this,
          current = slide || self.current,
          scrollHeight,
          marginBottom,
          inlinePadding,
          actualPadding;
  
        if (current.isLoaded && current.opts.disableLayoutFix !== true) {
          current.$content.css("margin-bottom", "");
  
          // If we would always set margin-bottom for the content,
          // then it would potentially break vertical align
          if (current.$content.outerHeight() > current.$slide.height() + 0.5) {
            inlinePadding = current.$slide[0].style["padding-bottom"];
            actualPadding = current.$slide.css("padding-bottom");
  
            if (parseFloat(actualPadding) > 0) {
              scrollHeight = current.$slide[0].scrollHeight;
  
              current.$slide.css("padding-bottom", 0);
  
              if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {
                marginBottom = actualPadding;
              }
  
              current.$slide.css("padding-bottom", inlinePadding);
            }
          }
  
          current.$content.css("margin-bottom", marginBottom);
        }
      },
  
      // Make content visible
      // This method is called right after content has been loaded or
      // user navigates gallery and transition should start
      // ============================================================
  
      revealContent: function (slide) {
        var self = this,
          $slide = slide.$slide,
          end = false,
          start = false,
          isMoved = self.isMoved(slide),
          isRevealed = slide.isRevealed,
          effect,
          effectClassName,
          duration,
          opacity;
  
        slide.isRevealed = true;
  
        effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"];
        duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"];
  
        duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);
  
        if (isMoved || slide.pos !== self.currPos || !duration) {
          effect = false;
        }
  
        // Check if can zoom
        if (effect === "zoom") {
          if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) {
            end = self.getFitPos(slide);
          } else {
            effect = "fade";
          }
        }
  
        // Zoom animation
        // ==============
        if (effect === "zoom") {
          self.isAnimating = true;
  
          end.scaleX = end.width / start.width;
          end.scaleY = end.height / start.height;
  
          // Check if we need to animate opacity
          opacity = slide.opts.zoomOpacity;
  
          if (opacity == "auto") {
            opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;
          }
  
          if (opacity) {
            start.opacity = 0.1;
            end.opacity = 1;
          }
  
          // Draw image at start position
          $.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start);
  
          forceRedraw(slide.$content);
  
          // Start animation
          $.fancybox.animate(slide.$content, end, duration, function () {
            self.isAnimating = false;
  
            self.complete();
          });
  
          return;
        }
  
        self.updateSlide(slide);
  
        // Simply show content if no effect
        // ================================
        if (!effect) {
          slide.$content.removeClass("fancybox-is-hidden");
  
          if (!isRevealed && isMoved && slide.type === "image" && !slide.hasError) {
            slide.$content.hide().fadeIn("fast");
          }
  
          if (slide.pos === self.currPos) {
            self.complete();
          }
  
          return;
        }
  
        // Prepare for CSS transiton
        // =========================
        $.fancybox.stop($slide);
  
        //effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect;
        effectClassName = "fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-animated fancybox-fx-" + effect;
  
        $slide.addClass(effectClassName).removeClass("fancybox-slide--current"); //.addClass(effectClassName);
  
        slide.$content.removeClass("fancybox-is-hidden");
  
        // Force reflow
        forceRedraw($slide);
  
        if (slide.type !== "image") {
          slide.$content.hide().show(0);
        }
  
        $.fancybox.animate(
          $slide,
          "fancybox-slide--current",
          duration,
          function () {
            $slide.removeClass(effectClassName).css({
              transform: "",
              opacity: ""
            });
  
            if (slide.pos === self.currPos) {
              self.complete();
            }
          },
          true
        );
      },
  
      // Check if we can and have to zoom from thumbnail
      //================================================
  
      getThumbPos: function (slide) {
        var rez = false,
          $thumb = slide.$thumb,
          thumbPos,
          btw,
          brw,
          bbw,
          blw;
  
        if (!$thumb || !inViewport($thumb[0])) {
          return false;
        }
  
        thumbPos = $.fancybox.getTranslate($thumb);
  
        btw = parseFloat($thumb.css("border-top-width") || 0);
        brw = parseFloat($thumb.css("border-right-width") || 0);
        bbw = parseFloat($thumb.css("border-bottom-width") || 0);
        blw = parseFloat($thumb.css("border-left-width") || 0);
  
        rez = {
          top: thumbPos.top + btw,
          left: thumbPos.left + blw,
          width: thumbPos.width - brw - blw,
          height: thumbPos.height - btw - bbw,
          scaleX: 1,
          scaleY: 1
        };
  
        return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;
      },
  
      // Final adjustments after current gallery item is moved to position
      // and it`s content is loaded
      // ==================================================================
  
      complete: function () {
        var self = this,
          current = self.current,
          slides = {},
          $el;
  
        if (self.isMoved() || !current.isLoaded) {
          return;
        }
  
        if (!current.isComplete) {
          current.isComplete = true;
  
          current.$slide.siblings().trigger("onReset");
  
          self.preload("inline");
  
          // Trigger any CSS transiton inside the slide
          forceRedraw(current.$slide);
  
          current.$slide.addClass("fancybox-slide--complete");
  
          // Remove unnecessary slides
          $.each(self.slides, function (key, slide) {
            if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {
              slides[slide.pos] = slide;
            } else if (slide) {
              $.fancybox.stop(slide.$slide);
  
              slide.$slide.off().remove();
            }
          });
  
          self.slides = slides;
        }
  
        self.isAnimating = false;
  
        self.updateCursor();
  
        self.trigger("afterShow");
  
        // Autoplay first html5 video/audio
        if (!!current.opts.video.autoStart) {
          current.$slide
            .find("video,audio")
            .filter(":visible:first")
            .trigger("play")
            .one("ended", function () {
              if (Document.exitFullscreen) {
                Document.exitFullscreen();
              } else if (this.webkitExitFullscreen) {
                this.webkitExitFullscreen();
              }
  
              self.next();
            });
        }
  
        // Try to focus on the first focusable element
        if (current.opts.autoFocus && current.contentType === "html") {
          // Look for the first input with autofocus attribute
          $el = current.$content.find("input[autofocus]:enabled:visible:first");
  
          if ($el.length) {
            $el.trigger("focus");
          } else {
            self.focus(null, true);
          }
        }
  
        // Avoid jumping
        current.$slide.scrollTop(0).scrollLeft(0);
      },
  
      // Preload next and previous slides
      // ================================
  
      preload: function (type) {
        var self = this,
          prev,
          next;
  
        if (self.group.length < 2) {
          return;
        }
  
        next = self.slides[self.currPos + 1];
        prev = self.slides[self.currPos - 1];
  
        if (prev && prev.type === type) {
          self.loadSlide(prev);
        }
  
        if (next && next.type === type) {
          self.loadSlide(next);
        }
      },
  
      // Try to find and focus on the first focusable element
      // ====================================================
  
      focus: function (e, firstRun) {
        var self = this,
          focusableStr = [
            "a[href]",
            "area[href]",
            'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
            "select:not([disabled]):not([aria-hidden])",
            "textarea:not([disabled]):not([aria-hidden])",
            "button:not([disabled]):not([aria-hidden])",
            "iframe",
            "object",
            "embed",
            "video",
            "audio",
            "[contenteditable]",
            '[tabindex]:not([tabindex^="-"])'
          ].join(","),
          focusableItems,
          focusedItemIndex;
  
        if (self.isClosing) {
          return;
        }
  
        if (e || !self.current || !self.current.isComplete) {
          // Focus on any element inside fancybox
          focusableItems = self.$refs.container.find("*:visible");
        } else {
          // Focus inside current slide
          focusableItems = self.current.$slide.find("*:visible" + (firstRun ? ":not(.fancybox-close-small)" : ""));
        }
  
        focusableItems = focusableItems.filter(focusableStr).filter(function () {
          return $(this).css("visibility") !== "hidden" && !$(this).hasClass("disabled");
        });
  
        if (focusableItems.length) {
          focusedItemIndex = focusableItems.index(document.activeElement);
  
          if (e && e.shiftKey) {
            // Back tab
            if (focusedItemIndex < 0 || focusedItemIndex == 0) {
              e.preventDefault();
  
              focusableItems.eq(focusableItems.length - 1).trigger("focus");
            }
          } else {
            // Outside or Forward tab
            if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {
              if (e) {
                e.preventDefault();
              }
  
              focusableItems.eq(0).trigger("focus");
            }
          }
        } else {
          self.$refs.container.trigger("focus");
        }
      },
  
      // Activates current instance - brings container to the front and enables keyboard,
      // notifies other instances about deactivating
      // =================================================================================
  
      activate: function () {
        var self = this;
  
        // Deactivate all instances
        $(".fancybox-container").each(function () {
          var instance = $(this).data("FancyBox");
  
          // Skip self and closing instances
          if (instance && instance.id !== self.id && !instance.isClosing) {
            instance.trigger("onDeactivate");
  
            instance.removeEvents();
  
            instance.isVisible = false;
          }
        });
  
        self.isVisible = true;
  
        if (self.current || self.isIdle) {
          self.update();
  
          self.updateControls();
        }
  
        self.trigger("onActivate");
  
        self.addEvents();
      },
  
      // Start closing procedure
      // This will start "zoom-out" animation if needed and clean everything up afterwards
      // =================================================================================
  
      close: function (e, d) {
        var self = this,
          current = self.current,
          effect,
          duration,
          $content,
          domRect,
          opacity,
          start,
          end;
  
        var done = function () {
          self.cleanUp(e);
        };
  
        if (self.isClosing) {
          return false;
        }
  
        self.isClosing = true;
  
        // If beforeClose callback prevents closing, make sure content is centered
        if (self.trigger("beforeClose", e) === false) {
          self.isClosing = false;
  
          requestAFrame(function () {
            self.update();
          });
  
          return false;
        }
  
        // Remove all events
        // If there are multiple instances, they will be set again by "activate" method
        self.removeEvents();
  
        $content = current.$content;
        effect = current.opts.animationEffect;
        duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;
  
        current.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated");
  
        if (e !== true) {
          $.fancybox.stop(current.$slide);
        } else {
          effect = false;
        }
  
        // Remove other slides
        current.$slide
          .siblings()
          .trigger("onReset")
          .remove();
  
        // Trigger animations
        if (duration) {
          self.$refs.container
            .removeClass("fancybox-is-open")
            .addClass("fancybox-is-closing")
            .css("transition-duration", duration + "ms");
        }
  
        // Clean up
        self.hideLoading(current);
  
        self.hideControls(true);
  
        self.updateCursor();
  
        // Check if possible to zoom-out
        if (
          effect === "zoom" &&
          !($content && duration && current.type === "image" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))
        ) {
          effect = "fade";
        }
  
        if (effect === "zoom") {
          $.fancybox.stop($content);
  
          domRect = $.fancybox.getTranslate($content);
  
          start = {
            top: domRect.top,
            left: domRect.left,
            scaleX: domRect.width / end.width,
            scaleY: domRect.height / end.height,
            width: end.width,
            height: end.height
          };
  
          // Check if we need to animate opacity
          opacity = current.opts.zoomOpacity;
  
          if (opacity == "auto") {
            opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;
          }
  
          if (opacity) {
            end.opacity = 0;
          }
  
          $.fancybox.setTranslate($content, start);
  
          forceRedraw($content);
  
          $.fancybox.animate($content, end, duration, done);
  
          return true;
        }
  
        if (effect && duration) {
          $.fancybox.animate(
            current.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),
            "fancybox-animated fancybox-fx-" + effect,
            duration,
            done
          );
        } else {
          // If skip animation
          if (e === true) {
            setTimeout(done, duration);
          } else {
            done();
          }
        }
  
        return true;
      },
  
      // Final adjustments after removing the instance
      // =============================================
  
      cleanUp: function (e) {
        var self = this,
          instance,
          $focus = self.current.opts.$orig,
          x,
          y;
  
        self.current.$slide.trigger("onReset");
  
        self.$refs.container.empty().remove();
  
        self.trigger("afterClose", e);
  
        // Place back focus
        if (!!self.current.opts.backFocus) {
          if (!$focus || !$focus.length || !$focus.is(":visible")) {
            $focus = self.$trigger;
          }
  
          if ($focus && $focus.length) {
            x = window.scrollX;
            y = window.scrollY;
  
            $focus.trigger("focus");
  
            $("html, body")
              .scrollTop(y)
              .scrollLeft(x);
          }
        }
  
        self.current = null;
  
        // Check if there are other instances
        instance = $.fancybox.getInstance();
  
        if (instance) {
          instance.activate();
        } else {
          $("body").removeClass("fancybox-active compensate-for-scrollbar");
  
          $("#fancybox-style-noscroll").remove();
        }
      },
  
      // Call callback and trigger an event
      // ==================================
  
      trigger: function (name, slide) {
        var args = Array.prototype.slice.call(arguments, 1),
          self = this,
          obj = slide && slide.opts ? slide : self.current,
          rez;
  
        if (obj) {
          args.unshift(obj);
        } else {
          obj = self;
        }
  
        args.unshift(self);
  
        if ($.isFunction(obj.opts[name])) {
          rez = obj.opts[name].apply(obj, args);
        }
  
        if (rez === false) {
          return rez;
        }
  
        if (name === "afterClose" || !self.$refs) {
          $D.trigger(name + ".fb", args);
        } else {
          self.$refs.container.trigger(name + ".fb", args);
        }
      },
  
      // Update infobar values, navigation button states and reveal caption
      // ==================================================================
  
      updateControls: function () {
        var self = this,
          current = self.current,
          index = current.index,
          $container = self.$refs.container,
          $caption = self.$refs.caption,
          caption = current.opts.caption;
  
        // Recalculate content dimensions
        current.$slide.trigger("refresh");
  
        // Set caption
        if (caption && caption.length) {
          self.$caption = $caption;
  
          $caption
            .children()
            .eq(0)
            .html(caption);
        } else {
          self.$caption = null;
        }
  
        if (!self.hasHiddenControls && !self.isIdle) {
          self.showControls();
        }
  
        // Update info and navigation elements
        $container.find("[data-fancybox-count]").html(self.group.length);
        $container.find("[data-fancybox-index]").html(index + 1);
  
        $container.find("[data-fancybox-prev]").prop("disabled", !current.opts.loop && index <= 0);
        $container.find("[data-fancybox-next]").prop("disabled", !current.opts.loop && index >= self.group.length - 1);
  
        if (current.type === "image") {
          // Re-enable buttons; update download button source
          $container
            .find("[data-fancybox-zoom]")
            .show()
            .end()
            .find("[data-fancybox-download]")
            .attr("href", current.opts.image.src || current.src)
            .show();
        } else if (current.opts.toolbar) {
          $container.find("[data-fancybox-download],[data-fancybox-zoom]").hide();
        }
  
        // Make sure focus is not on disabled button/element
        if ($(document.activeElement).is(":hidden,[disabled]")) {
          self.$refs.container.trigger("focus");
        }
      },
  
      // Hide toolbar and caption
      // ========================
  
      hideControls: function (andCaption) {
        var self = this,
          arr = ["infobar", "toolbar", "nav"];
  
        if (andCaption || !self.current.opts.preventCaptionOverlap) {
          arr.push("caption");
        }
  
        this.$refs.container.removeClass(
          arr
          .map(function (i) {
            return "fancybox-show-" + i;
          })
          .join(" ")
        );
  
        this.hasHiddenControls = true;
      },
  
      showControls: function () {
        var self = this,
          opts = self.current ? self.current.opts : self.opts,
          $container = self.$refs.container;
  
        self.hasHiddenControls = false;
        self.idleSecondsCounter = 0;
  
        $container
          .toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons))
          .toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1))
          .toggleClass("fancybox-show-caption", !!self.$caption)
          .toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1))
          .toggleClass("fancybox-is-modal", !!opts.modal);
      },
  
      // Toggle toolbar and caption
      // ==========================
  
      toggleControls: function () {
        if (this.hasHiddenControls) {
          this.showControls();
        } else {
          this.hideControls();
        }
      }
    });
  
    $.fancybox = {
      version: "3.5.7",
      defaults: defaults,
  
      // Get current instance and execute a command.
      //
      // Examples of usage:
      //
      //   $instance = $.fancybox.getInstance();
      //   $.fancybox.getInstance().jumpTo( 1 );
      //   $.fancybox.getInstance( 'jumpTo', 1 );
      //   $.fancybox.getInstance( function() {
      //       console.info( this.currIndex );
      //   });
      // ======================================================
  
      getInstance: function (command) {
        var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),
          args = Array.prototype.slice.call(arguments, 1);
  
        if (instance instanceof FancyBox) {
          if ($.type(command) === "string") {
            instance[command].apply(instance, args);
          } else if ($.type(command) === "function") {
            command.apply(instance, args);
          }
  
          return instance;
        }
  
        return false;
      },
  
      // Create new instance
      // ===================
  
      open: function (items, opts, index) {
        return new FancyBox(items, opts, index);
      },
  
      // Close current or all instances
      // ==============================
  
      close: function (all) {
        var instance = this.getInstance();
  
        if (instance) {
          instance.close();
  
          // Try to find and close next instance
          if (all === true) {
            this.close(all);
          }
        }
      },
  
      // Close all instances and unbind all events
      // =========================================
  
      destroy: function () {
        this.close(true);
  
        $D.add("body").off("click.fb-start", "**");
      },
  
      // Try to detect mobile devices
      // ============================
  
      isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
  
      // Detect if 'translate3d' support is available
      // ============================================
  
      use3d: (function () {
        var div = document.createElement("div");
  
        return (
          window.getComputedStyle &&
          window.getComputedStyle(div) &&
          window.getComputedStyle(div).getPropertyValue("transform") &&
          !(document.documentMode && document.documentMode < 11)
        );
      })(),
  
      // Helper function to get current visual state of an element
      // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
      // =====================================================================
  
      getTranslate: function ($el) {
        var domRect;
  
        if (!$el || !$el.length) {
          return false;
        }
  
        domRect = $el[0].getBoundingClientRect();
  
        return {
          top: domRect.top || 0,
          left: domRect.left || 0,
          width: domRect.width,
          height: domRect.height,
          opacity: parseFloat($el.css("opacity"))
        };
      },
  
      // Shortcut for setting "translate3d" properties for element
      // Can set be used to set opacity, too
      // ========================================================
  
      setTranslate: function ($el, props) {
        var str = "",
          css = {};
  
        if (!$el || !props) {
          return;
        }
  
        if (props.left !== undefined || props.top !== undefined) {
          str =
            (props.left === undefined ? $el.position().left : props.left) +
            "px, " +
            (props.top === undefined ? $el.position().top : props.top) +
            "px";
  
          if (this.use3d) {
            str = "translate3d(" + str + ", 0px)";
          } else {
            str = "translate(" + str + ")";
          }
        }
  
        if (props.scaleX !== undefined && props.scaleY !== undefined) {
          str += " scale(" + props.scaleX + ", " + props.scaleY + ")";
        } else if (props.scaleX !== undefined) {
          str += " scaleX(" + props.scaleX + ")";
        }
  
        if (str.length) {
          css.transform = str;
        }
  
        if (props.opacity !== undefined) {
          css.opacity = props.opacity;
        }
  
        if (props.width !== undefined) {
          css.width = props.width;
        }
  
        if (props.height !== undefined) {
          css.height = props.height;
        }
  
        return $el.css(css);
      },
  
      // Simple CSS transition handler
      // =============================
  
      animate: function ($el, to, duration, callback, leaveAnimationName) {
        var self = this,
          from;
  
        if ($.isFunction(duration)) {
          callback = duration;
          duration = null;
        }
  
        self.stop($el);
  
        from = self.getTranslate($el);
  
        $el.on(transitionEnd, function (e) {
          // Skip events from child elements and z-index change
          if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) {
            return;
          }
  
          self.stop($el);
  
          if ($.isNumeric(duration)) {
            $el.css("transition-duration", "");
          }
  
          if ($.isPlainObject(to)) {
            if (to.scaleX !== undefined && to.scaleY !== undefined) {
              self.setTranslate($el, {
                top: to.top,
                left: to.left,
                width: from.width * to.scaleX,
                height: from.height * to.scaleY,
                scaleX: 1,
                scaleY: 1
              });
            }
          } else if (leaveAnimationName !== true) {
            $el.removeClass(to);
          }
  
          if ($.isFunction(callback)) {
            callback(e);
          }
        });
  
        if ($.isNumeric(duration)) {
          $el.css("transition-duration", duration + "ms");
        }
  
        // Start animation by changing CSS properties or class name
        if ($.isPlainObject(to)) {
          if (to.scaleX !== undefined && to.scaleY !== undefined) {
            delete to.width;
            delete to.height;
  
            if ($el.parent().hasClass("fancybox-slide--image")) {
              $el.parent().addClass("fancybox-is-scaling");
            }
          }
  
          $.fancybox.setTranslate($el, to);
        } else {
          $el.addClass(to);
        }
  
        // Make sure that `transitionend` callback gets fired
        $el.data(
          "timer",
          setTimeout(function () {
            $el.trigger(transitionEnd);
          }, duration + 33)
        );
      },
  
      stop: function ($el, callCallback) {
        if ($el && $el.length) {
          clearTimeout($el.data("timer"));
  
          if (callCallback) {
            $el.trigger(transitionEnd);
          }
  
          $el.off(transitionEnd).css("transition-duration", "");
  
          $el.parent().removeClass("fancybox-is-scaling");
        }
      }
    };
  
    // Default click handler for "fancyboxed" links
    // ============================================
  
    function _run(e, opts) {
      var items = [],
        index = 0,
        $target,
        value,
        instance;
  
      // Avoid opening multiple times
      if (e && e.isDefaultPrevented()) {
        return;
      }
  
      e.preventDefault();
  
      opts = opts || {};
  
      if (e && e.data) {
        opts = mergeOpts(e.data.options, opts);
      }
  
      $target = opts.$target || $(e.currentTarget).trigger("blur");
      instance = $.fancybox.getInstance();
  
      if (instance && instance.$trigger && instance.$trigger.is($target)) {
        return;
      }
  
      if (opts.selector) {
        items = $(opts.selector);
      } else {
        // Get all related items and find index for clicked one
        value = $target.attr("data-fancybox") || "";
  
        if (value) {
          items = e.data ? e.data.items : [];
          items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');
        } else {
          items = [$target];
        }
      }
  
      index = $(items).index($target);
  
      // Sometimes current item can not be found
      if (index < 0) {
        index = 0;
      }
  
      instance = $.fancybox.open(items, opts, index);
  
      // Save last active element
      instance.$trigger = $target;
    }
  
    // Create a jQuery plugin
    // ======================
  
    $.fn.fancybox = function (options) {
      var selector;
  
      options = options || {};
      selector = options.selector || false;
  
      if (selector) {
        // Use body element instead of document so it executes first
        $("body")
          .off("click.fb-start", selector)
          .on("click.fb-start", selector, {
            options: options
          }, _run);
      } else {
        this.off("click.fb-start").on(
          "click.fb-start", {
            items: this,
            options: options
          },
          _run
        );
      }
  
      return this;
    };
  
    // Self initializing plugin for all elements having `data-fancybox` attribute
    // ==========================================================================
  
    $D.on("click.fb-start", "[data-fancybox]", _run);
  
    // Enable "trigger elements"
    // =========================
  
    $D.on("click.fb-start", "[data-fancybox-trigger]", function (e) {
      $('[data-fancybox="' + $(this).attr("data-fancybox-trigger") + '"]')
        .eq($(this).attr("data-fancybox-index") || 0)
        .trigger("click.fb-start", {
          $trigger: $(this)
        });
    });
  
    // Track focus event for better accessibility styling
    // ==================================================
    (function () {
      var buttonStr = ".fancybox-button",
        focusStr = "fancybox-focus",
        $pressed = null;
  
      $D.on("mousedown mouseup focus blur", buttonStr, function (e) {
        switch (e.type) {
          case "mousedown":
            $pressed = $(this);
            break;
          case "mouseup":
            $pressed = null;
            break;
          case "focusin":
            $(buttonStr).removeClass(focusStr);
  
            if (!$(this).is($pressed) && !$(this).is("[disabled]")) {
              $(this).addClass(focusStr);
            }
            break;
          case "focusout":
            $(buttonStr).removeClass(focusStr);
            break;
        }
      });
    })();
  })(window, document, jQuery);
  // ==========================================================================
  //
  // Media
  // Adds additional media type support
  //
  // ==========================================================================
  (function ($) {
    "use strict";
  
    // Object containing properties for each media type
    var defaults = {
      youtube: {
        matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
        params: {
          autoplay: 1,
          autohide: 1,
          fs: 1,
          rel: 0,
          hd: 1,
          wmode: "transparent",
          enablejsapi: 1,
          html5: 1
        },
        paramPlace: 8,
        type: "iframe",
        url: "https://www.youtube-nocookie.com/embed/$4",
        thumb: "https://img.youtube.com/vi/$4/hqdefault.jpg"
      },
  
      vimeo: {
        matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
        params: {
          autoplay: 1,
          hd: 1,
          show_title: 1,
          show_byline: 1,
          show_portrait: 0,
          fullscreen: 1
        },
        paramPlace: 3,
        type: "iframe",
        url: "//player.vimeo.com/video/$2"
      },
  
      instagram: {
        matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
        type: "image",
        url: "//$1/p/$2/media/?size=l"
      },
  
      // Examples:
      // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
      // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z
      // https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en
      // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
      gmap_place: {
        matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
        type: "iframe",
        url: function (rez) {
          return (
            "//maps.google." +
            rez[2] +
            "/?ll=" +
            (rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") +
            "&output=" +
            (rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed")
          );
        }
      },
  
      // Examples:
      // https://www.google.com/maps/search/Empire+State+Building/
      // https://www.google.com/maps/search/?api=1&query=centurylink+field
      // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393
      gmap_search: {
        matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,
        type: "iframe",
        url: function (rez) {
          return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed";
        }
      }
    };
  
    // Formats matching url to final form
    var format = function (url, rez, params) {
      if (!url) {
        return;
      }
  
      params = params || "";
  
      if ($.type(params) === "object") {
        params = $.param(params, true);
      }
  
      $.each(rez, function (key, value) {
        url = url.replace("$" + key, value || "");
      });
  
      if (params.length) {
        url += (url.indexOf("?") > 0 ? "&" : "?") + params;
      }
  
      return url;
    };
  
    $(document).on("objectNeedsType.fb", function (e, instance, item) {
      var url = item.src || "",
        type = false,
        media,
        thumb,
        rez,
        params,
        urlParams,
        paramObj,
        provider;
  
      media = $.extend(true, {}, defaults, item.opts.media);
  
      // Look for any matching media type
      $.each(media, function (providerName, providerOpts) {
        rez = url.match(providerOpts.matcher);
  
        if (!rez) {
          return;
        }
  
        type = providerOpts.type;
        provider = providerName;
        paramObj = {};
  
        if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {
          urlParams = rez[providerOpts.paramPlace];
  
          if (urlParams[0] == "?") {
            urlParams = urlParams.substring(1);
          }
  
          urlParams = urlParams.split("&");
  
          for (var m = 0; m < urlParams.length; ++m) {
            var p = urlParams[m].split("=", 2);
  
            if (p.length == 2) {
              paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
            }
          }
        }
  
        params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);
  
        url =
          $.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);
  
        thumb =
          $.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);
  
        if (providerName === "youtube") {
          url = url.replace(/&t=((\d+)m)?(\d+)s/, function (match, p1, m, s) {
            return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));
          });
        } else if (providerName === "vimeo") {
          url = url.replace("&%23", "#");
        }
  
        return false;
      });
  
      // If it is found, then change content type and update the url
  
      if (type) {
        if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {
          item.opts.thumb = thumb;
        }
  
        if (type === "iframe") {
          item.opts = $.extend(true, item.opts, {
            iframe: {
              preload: false,
              attr: {
                scrolling: "no"
              }
            }
          });
        }
  
        $.extend(item, {
          type: type,
          src: url,
          origSrc: item.src,
          contentSource: provider,
          contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video"
        });
      } else if (url) {
        item.type = item.opts.defaultType;
      }
    });
  
    // Load YouTube/Video API on request to detect when video finished playing
    var VideoAPILoader = {
      youtube: {
        src: "https://www.youtube.com/iframe_api",
        class: "YT",
        loading: false,
        loaded: false
      },
  
      vimeo: {
        src: "https://player.vimeo.com/api/player.js",
        class: "Vimeo",
        loading: false,
        loaded: false
      },
  
      load: function (vendor) {
        var _this = this,
          script;
  
        if (this[vendor].loaded) {
          setTimeout(function () {
            _this.done(vendor);
          });
          return;
        }
  
        if (this[vendor].loading) {
          return;
        }
  
        this[vendor].loading = true;
  
        script = document.createElement("script");
        script.type = "text/javascript";
        script.src = this[vendor].src;
  
        if (vendor === "youtube") {
          window.onYouTubeIframeAPIReady = function () {
            _this[vendor].loaded = true;
            _this.done(vendor);
          };
        } else {
          script.onload = function () {
            _this[vendor].loaded = true;
            _this.done(vendor);
          };
        }
  
        document.body.appendChild(script);
      },
      done: function (vendor) {
        var instance, $el, player;
  
        if (vendor === "youtube") {
          delete window.onYouTubeIframeAPIReady;
        }
  
        instance = $.fancybox.getInstance();
  
        if (instance) {
          $el = instance.current.$content.find("iframe");
  
          if (vendor === "youtube" && YT !== undefined && YT) {
            player = new YT.Player($el.attr("id"), {
              events: {
                onStateChange: function (e) {
                  if (e.data == 0) {
                    instance.next();
                  }
                }
              }
            });
          } else if (vendor === "vimeo" && Vimeo !== undefined && Vimeo) {
            player = new Vimeo.Player($el);
  
            player.on("ended", function () {
              instance.next();
            });
          }
        }
      }
    };
  
    $(document).on({
      "afterShow.fb": function (e, instance, current) {
        if (instance.group.length > 1 && (current.contentSource === "youtube" || current.contentSource === "vimeo")) {
          VideoAPILoader.load(current.contentSource);
        }
      }
    });
  })(jQuery);
  // ==========================================================================
  //
  // Guestures
  // Adds touch guestures, handles click and tap events
  //
  // ==========================================================================
  (function (window, document, $) {
    "use strict";
  
    var requestAFrame = (function () {
      return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        // if all else fails, use setTimeout
        function (callback) {
          return window.setTimeout(callback, 1000 / 60);
        }
      );
    })();
  
    var cancelAFrame = (function () {
      return (
        window.cancelAnimationFrame ||
        window.webkitCancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        window.oCancelAnimationFrame ||
        function (id) {
          window.clearTimeout(id);
        }
      );
    })();
  
    var getPointerXY = function (e) {
      var result = [];
  
      e = e.originalEvent || e || window.e;
      e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];
  
      for (var key in e) {
        if (e[key].pageX) {
          result.push({
            x: e[key].pageX,
            y: e[key].pageY
          });
        } else if (e[key].clientX) {
          result.push({
            x: e[key].clientX,
            y: e[key].clientY
          });
        }
      }
  
      return result;
    };
  
    var distance = function (point2, point1, what) {
      if (!point1 || !point2) {
        return 0;
      }
  
      if (what === "x") {
        return point2.x - point1.x;
      } else if (what === "y") {
        return point2.y - point1.y;
      }
  
      return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
    };
  
    var isClickable = function ($el) {
      if (
        $el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') ||
        $.isFunction($el.get(0).onclick) ||
        $el.data("selectable")
      ) {
        return true;
      }
  
      // Check for attributes like data-fancybox-next or data-fancybox-close
      for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {
        if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") {
          return true;
        }
      }
  
      return false;
    };
  
    var hasScrollbars = function (el) {
      var overflowY = window.getComputedStyle(el)["overflow-y"],
        overflowX = window.getComputedStyle(el)["overflow-x"],
        vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight,
        horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth;
  
      return vertical || horizontal;
    };
  
    var isScrollable = function ($el) {
      var rez = false;
  
      while (true) {
        rez = hasScrollbars($el.get(0));
  
        if (rez) {
          break;
        }
  
        $el = $el.parent();
  
        if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) {
          break;
        }
      }
  
      return rez;
    };
  
    var Guestures = function (instance) {
      var self = this;
  
      self.instance = instance;
  
      self.$bg = instance.$refs.bg;
      self.$stage = instance.$refs.stage;
      self.$container = instance.$refs.container;
  
      self.destroy();
  
      self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart"));
    };
  
    Guestures.prototype.destroy = function () {
      var self = this;
  
      self.$container.off(".fb.touch");
  
      $(document).off(".fb.touch");
  
      if (self.requestId) {
        cancelAFrame(self.requestId);
        self.requestId = null;
      }
  
      if (self.tapped) {
        clearTimeout(self.tapped);
        self.tapped = null;
      }
    };
  
    Guestures.prototype.ontouchstart = function (e) {
      var self = this,
        $target = $(e.target),
        instance = self.instance,
        current = instance.current,
        $slide = current.$slide,
        $content = current.$content,
        isTouchDevice = e.type == "touchstart";
  
      // Do not respond to both (touch and mouse) events
      if (isTouchDevice) {
        self.$container.off("mousedown.fb.touch");
      }
  
      // Ignore right click
      if (e.originalEvent && e.originalEvent.button == 2) {
        return;
      }
  
      // Ignore taping on links, buttons, input elements
      if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {
        return;
      }
      // Ignore clicks on the scrollbar
      if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {
        return;
      }
  
      // Ignore clicks while zooming or closing
      if (!current || instance.isAnimating || current.$slide.hasClass("fancybox-animated")) {
        e.stopPropagation();
        e.preventDefault();
  
        return;
      }
  
      self.realPoints = self.startPoints = getPointerXY(e);
  
      if (!self.startPoints.length) {
        return;
      }
  
      // Allow other scripts to catch touch event if "touch" is set to false
      if (current.touch) {
        e.stopPropagation();
      }
  
      self.startEvent = e;
  
      self.canTap = true;
      self.$target = $target;
      self.$content = $content;
      self.opts = current.opts.touch;
  
      self.isPanning = false;
      self.isSwiping = false;
      self.isZooming = false;
      self.isScrolling = false;
      self.canPan = instance.canPan();
  
      self.startTime = new Date().getTime();
      self.distanceX = self.distanceY = self.distance = 0;
  
      self.canvasWidth = Math.round($slide[0].clientWidth);
      self.canvasHeight = Math.round($slide[0].clientHeight);
  
      self.contentLastPos = null;
      self.contentStartPos = $.fancybox.getTranslate(self.$content) || {
        top: 0,
        left: 0
      };
      self.sliderStartPos = $.fancybox.getTranslate($slide);
  
      // Since position will be absolute, but we need to make it relative to the stage
      self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);
  
      self.sliderStartPos.top -= self.stagePos.top;
      self.sliderStartPos.left -= self.stagePos.left;
  
      self.contentStartPos.top -= self.stagePos.top;
      self.contentStartPos.left -= self.stagePos.left;
  
      $(document)
        .off(".fb.touch")
        .on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend"))
        .on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove"));
  
      if ($.fancybox.isMobile) {
        document.addEventListener("scroll", self.onscroll, true);
      }
  
      // Skip if clicked outside the sliding area
      if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {
        if ($target.is(".fancybox-image")) {
          e.preventDefault();
        }
  
        if (!($.fancybox.isMobile && $target.parents(".fancybox-caption").length)) {
          return;
        }
      }
  
      self.isScrollable = isScrollable($target) || isScrollable($target.parent());
  
      // Check if element is scrollable and try to prevent default behavior (scrolling)
      if (!($.fancybox.isMobile && self.isScrollable)) {
        e.preventDefault();
      }
  
      // One finger or mouse click - swipe or pan an image
      if (self.startPoints.length === 1 || current.hasError) {
        if (self.canPan) {
          $.fancybox.stop(self.$content);
  
          self.isPanning = true;
        } else {
          self.isSwiping = true;
        }
  
        self.$container.addClass("fancybox-is-grabbing");
      }
  
      // Two fingers - zoom image
      if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) {
        self.canTap = false;
        self.isSwiping = false;
        self.isPanning = false;
  
        self.isZooming = true;
  
        $.fancybox.stop(self.$content);
  
        self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();
        self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();
  
        self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;
        self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;
  
        self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);
      }
    };
  
    Guestures.prototype.onscroll = function (e) {
      var self = this;
  
      self.isScrolling = true;
  
      document.removeEventListener("scroll", self.onscroll, true);
    };
  
    Guestures.prototype.ontouchmove = function (e) {
      var self = this;
  
      // Make sure user has not released over iframe or disabled element
      if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {
        self.ontouchend(e);
        return;
      }
  
      if (self.isScrolling) {
        self.canTap = false;
        return;
      }
  
      self.newPoints = getPointerXY(e);
  
      if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {
        return;
      }
  
      if (!(self.isSwiping && self.isSwiping === true)) {
        e.preventDefault();
      }
  
      self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x");
      self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y");
  
      self.distance = distance(self.newPoints[0], self.startPoints[0]);
  
      // Skip false ontouchmove events (Chrome)
      if (self.distance > 0) {
        if (self.isSwiping) {
          self.onSwipe(e);
        } else if (self.isPanning) {
          self.onPan();
        } else if (self.isZooming) {
          self.onZoom();
        }
      }
    };
  
    Guestures.prototype.onSwipe = function (e) {
      var self = this,
        instance = self.instance,
        swiping = self.isSwiping,
        left = self.sliderStartPos.left || 0,
        angle;
  
      // If direction is not yet determined
      if (swiping === true) {
        // We need at least 10px distance to correctly calculate an angle
        if (Math.abs(self.distance) > 10) {
          self.canTap = false;
  
          if (instance.group.length < 2 && self.opts.vertical) {
            self.isSwiping = "y";
          } else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) {
            self.isSwiping = "x";
          } else {
            angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);
  
            self.isSwiping = angle > 45 && angle < 135 ? "y" : "x";
          }
  
          if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) {
            self.isScrolling = true;
  
            return;
          }
  
          instance.isDragging = self.isSwiping;
  
          // Reset points to avoid jumping, because we dropped first swipes to calculate the angle
          self.startPoints = self.newPoints;
  
          $.each(instance.slides, function (index, slide) {
            var slidePos, stagePos;
  
            $.fancybox.stop(slide.$slide);
  
            slidePos = $.fancybox.getTranslate(slide.$slide);
            stagePos = $.fancybox.getTranslate(instance.$refs.stage);
  
            slide.$slide
              .css({
                transform: "",
                opacity: "",
                "transition-duration": ""
              })
              .removeClass("fancybox-animated")
              .removeClass(function (index, className) {
                return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
              });
  
            if (slide.pos === instance.current.pos) {
              self.sliderStartPos.top = slidePos.top - stagePos.top;
              self.sliderStartPos.left = slidePos.left - stagePos.left;
            }
  
            $.fancybox.setTranslate(slide.$slide, {
              top: slidePos.top - stagePos.top,
              left: slidePos.left - stagePos.left
            });
          });
  
          // Stop slideshow
          if (instance.SlideShow && instance.SlideShow.isActive) {
            instance.SlideShow.stop();
          }
        }
  
        return;
      }
  
      // Sticky edges
      if (swiping == "x") {
        if (
          self.distanceX > 0 &&
          (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))
        ) {
          left = left + Math.pow(self.distanceX, 0.8);
        } else if (
          self.distanceX < 0 &&
          (self.instance.group.length < 2 ||
            (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))
        ) {
          left = left - Math.pow(-self.distanceX, 0.8);
        } else {
          left = left + self.distanceX;
        }
      }
  
      self.sliderLastPos = {
        top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY,
        left: left
      };
  
      if (self.requestId) {
        cancelAFrame(self.requestId);
  
        self.requestId = null;
      }
  
      self.requestId = requestAFrame(function () {
        if (self.sliderLastPos) {
          $.each(self.instance.slides, function (index, slide) {
            var pos = slide.pos - self.instance.currPos;
  
            $.fancybox.setTranslate(slide.$slide, {
              top: self.sliderLastPos.top,
              left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter
            });
          });
  
          self.$container.addClass("fancybox-is-sliding");
        }
      });
    };
  
    Guestures.prototype.onPan = function () {
      var self = this;
  
      // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)
      if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {
        self.startPoints = self.newPoints;
        return;
      }
  
      self.canTap = false;
  
      self.contentLastPos = self.limitMovement();
  
      if (self.requestId) {
        cancelAFrame(self.requestId);
      }
  
      self.requestId = requestAFrame(function () {
        $.fancybox.setTranslate(self.$content, self.contentLastPos);
      });
    };
  
    // Make panning sticky to the edges
    Guestures.prototype.limitMovement = function () {
      var self = this;
  
      var canvasWidth = self.canvasWidth;
      var canvasHeight = self.canvasHeight;
  
      var distanceX = self.distanceX;
      var distanceY = self.distanceY;
  
      var contentStartPos = self.contentStartPos;
  
      var currentOffsetX = contentStartPos.left;
      var currentOffsetY = contentStartPos.top;
  
      var currentWidth = contentStartPos.width;
      var currentHeight = contentStartPos.height;
  
      var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;
  
      if (currentWidth > canvasWidth) {
        newOffsetX = currentOffsetX + distanceX;
      } else {
        newOffsetX = currentOffsetX;
      }
  
      newOffsetY = currentOffsetY + distanceY;
  
      // Slow down proportionally to traveled distance
      minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);
      minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);
  
      maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);
      maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);
  
      //   ->
      if (distanceX > 0 && newOffsetX > minTranslateX) {
        newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;
      }
  
      //    <-
      if (distanceX < 0 && newOffsetX < maxTranslateX) {
        newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;
      }
  
      //   \/
      if (distanceY > 0 && newOffsetY > minTranslateY) {
        newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;
      }
  
      //   /\
      if (distanceY < 0 && newOffsetY < maxTranslateY) {
        newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;
      }
  
      return {
        top: newOffsetY,
        left: newOffsetX
      };
    };
  
    Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {
      var self = this;
  
      var canvasWidth = self.canvasWidth;
      var canvasHeight = self.canvasHeight;
  
      if (newWidth > canvasWidth) {
        newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
        newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;
      } else {
        // Center horizontally
        newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);
      }
  
      if (newHeight > canvasHeight) {
        newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
        newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;
      } else {
        // Center vertically
        newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);
      }
  
      return {
        top: newOffsetY,
        left: newOffsetX
      };
    };
  
    Guestures.prototype.onZoom = function () {
      var self = this;
  
      // Calculate current distance between points to get pinch ratio and new width and height
      var contentStartPos = self.contentStartPos;
  
      var currentWidth = contentStartPos.width;
      var currentHeight = contentStartPos.height;
  
      var currentOffsetX = contentStartPos.left;
      var currentOffsetY = contentStartPos.top;
  
      var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);
  
      var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;
  
      var newWidth = Math.floor(currentWidth * pinchRatio);
      var newHeight = Math.floor(currentHeight * pinchRatio);
  
      // This is the translation due to pinch-zooming
      var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;
      var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;
  
      // Point between the two touches
      var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();
      var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();
  
      // And this is the translation due to translation of the centerpoint
      // between the two fingers
      var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
      var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;
  
      // The new offset is the old/current one plus the total translation
      var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);
      var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);
  
      var newPos = {
        top: newOffsetY,
        left: newOffsetX,
        scaleX: pinchRatio,
        scaleY: pinchRatio
      };
  
      self.canTap = false;
  
      self.newWidth = newWidth;
      self.newHeight = newHeight;
  
      self.contentLastPos = newPos;
  
      if (self.requestId) {
        cancelAFrame(self.requestId);
      }
  
      self.requestId = requestAFrame(function () {
        $.fancybox.setTranslate(self.$content, self.contentLastPos);
      });
    };
  
    Guestures.prototype.ontouchend = function (e) {
      var self = this;
  
      var swiping = self.isSwiping;
      var panning = self.isPanning;
      var zooming = self.isZooming;
      var scrolling = self.isScrolling;
  
      self.endPoints = getPointerXY(e);
      self.dMs = Math.max(new Date().getTime() - self.startTime, 1);
  
      self.$container.removeClass("fancybox-is-grabbing");
  
      $(document).off(".fb.touch");
  
      document.removeEventListener("scroll", self.onscroll, true);
  
      if (self.requestId) {
        cancelAFrame(self.requestId);
  
        self.requestId = null;
      }
  
      self.isSwiping = false;
      self.isPanning = false;
      self.isZooming = false;
      self.isScrolling = false;
  
      self.instance.isDragging = false;
  
      if (self.canTap) {
        return self.onTap(e);
      }
  
      self.speed = 100;
  
      // Speed in px/ms
      self.velocityX = (self.distanceX / self.dMs) * 0.5;
      self.velocityY = (self.distanceY / self.dMs) * 0.5;
  
      if (panning) {
        self.endPanning();
      } else if (zooming) {
        self.endZooming();
      } else {
        self.endSwiping(swiping, scrolling);
      }
  
      return;
    };
  
    Guestures.prototype.endSwiping = function (swiping, scrolling) {
      var self = this,
        ret = false,
        len = self.instance.group.length,
        distanceX = Math.abs(self.distanceX),
        canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),
        speedX = 300;
  
      self.sliderLastPos = null;
  
      // Close if swiped vertically / navigate if horizontally
      if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) {
        // Continue vertical movement
        $.fancybox.animate(
          self.instance.current.$slide, {
            top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,
            opacity: 0
          },
          200
        );
        ret = self.instance.close(true, 250);
      } else if (canAdvance && self.distanceX > 0) {
        ret = self.instance.previous(speedX);
      } else if (canAdvance && self.distanceX < 0) {
        ret = self.instance.next(speedX);
      }
  
      if (ret === false && (swiping == "x" || swiping == "y")) {
        self.instance.centerSlide(200);
      }
  
      self.$container.removeClass("fancybox-is-sliding");
    };
  
    // Limit panning from edges
    // ========================
    Guestures.prototype.endPanning = function () {
      var self = this,
        newOffsetX,
        newOffsetY,
        newPos;
  
      if (!self.contentLastPos) {
        return;
      }
  
      if (self.opts.momentum === false || self.dMs > 350) {
        newOffsetX = self.contentLastPos.left;
        newOffsetY = self.contentLastPos.top;
      } else {
        // Continue movement
        newOffsetX = self.contentLastPos.left + self.velocityX * 500;
        newOffsetY = self.contentLastPos.top + self.velocityY * 500;
      }
  
      newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
  
      newPos.width = self.contentStartPos.width;
      newPos.height = self.contentStartPos.height;
  
      $.fancybox.animate(self.$content, newPos, 366);
    };
  
    Guestures.prototype.endZooming = function () {
      var self = this;
  
      var current = self.instance.current;
  
      var newOffsetX, newOffsetY, newPos, reset;
  
      var newWidth = self.newWidth;
      var newHeight = self.newHeight;
  
      if (!self.contentLastPos) {
        return;
      }
  
      newOffsetX = self.contentLastPos.left;
      newOffsetY = self.contentLastPos.top;
  
      reset = {
        top: newOffsetY,
        left: newOffsetX,
        width: newWidth,
        height: newHeight,
        scaleX: 1,
        scaleY: 1
      };
  
      // Reset scalex/scaleY values; this helps for perfomance and does not break animation
      $.fancybox.setTranslate(self.$content, reset);
  
      if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {
        self.instance.scaleToFit(150);
      } else if (newWidth > current.width || newHeight > current.height) {
        self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);
      } else {
        newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);
  
        $.fancybox.animate(self.$content, newPos, 150);
      }
    };
  
    Guestures.prototype.onTap = function (e) {
      var self = this;
      var $target = $(e.target);
  
      var instance = self.instance;
      var current = instance.current;
  
      var endPoints = (e && getPointerXY(e)) || self.startPoints;
  
      var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;
      var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;
  
      var where;
  
      var process = function (prefix) {
        var action = current.opts[prefix];
  
        if ($.isFunction(action)) {
          action = action.apply(instance, [current, e]);
        }
  
        if (!action) {
          return;
        }
  
        switch (action) {
          case "close":
            instance.close(self.startEvent);
  
            break;
  
          case "toggleControls":
            instance.toggleControls();
  
            break;
  
          case "next":
            instance.next();
  
            break;
  
          case "nextOrClose":
            if (instance.group.length > 1) {
              instance.next();
            } else {
              instance.close(self.startEvent);
            }
  
            break;
  
          case "zoom":
            if (current.type == "image" && (current.isLoaded || current.$ghost)) {
              if (instance.canPan()) {
                instance.scaleToFit();
              } else if (instance.isScaledDown()) {
                instance.scaleToActual(tapX, tapY);
              } else if (instance.group.length < 2) {
                instance.close(self.startEvent);
              }
            }
  
            break;
        }
      };
  
      // Ignore right click
      if (e.originalEvent && e.originalEvent.button == 2) {
        return;
      }
  
      // Skip if clicked on the scrollbar
      if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) {
        return;
      }
  
      // Check where is clicked
      if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) {
        where = "Outside";
      } else if ($target.is(".fancybox-slide")) {
        where = "Slide";
      } else if (
        instance.current.$content &&
        instance.current.$content
        .find($target)
        .addBack()
        .filter($target).length
      ) {
        where = "Content";
      } else {
        return;
      }
  
      // Check if this is a double tap
      if (self.tapped) {
        // Stop previously created single tap
        clearTimeout(self.tapped);
        self.tapped = null;
  
        // Skip if distance between taps is too big
        if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {
          return this;
        }
  
        // OK, now we assume that this is a double-tap
        process("dblclick" + where);
      } else {
        // Single tap will be processed if user has not clicked second time within 300ms
        // or there is no need to wait for double-tap
        self.tapX = tapX;
        self.tapY = tapY;
  
        if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) {
          self.tapped = setTimeout(function () {
            self.tapped = null;
  
            if (!instance.isAnimating) {
              process("click" + where);
            }
          }, 500);
        } else {
          process("click" + where);
        }
      }
  
      return this;
    };
  
    $(document)
      .on("onActivate.fb", function (e, instance) {
        if (instance && !instance.Guestures) {
          instance.Guestures = new Guestures(instance);
        }
      })
      .on("beforeClose.fb", function (e, instance) {
        if (instance && instance.Guestures) {
          instance.Guestures.destroy();
        }
      });
  })(window, document, jQuery);
  // ==========================================================================
  //
  // SlideShow
  // Enables slideshow functionality
  //
  // Example of usage:
  // $.fancybox.getInstance().SlideShow.start()
  //
  // ==========================================================================
  (function (document, $) {
    "use strict";
  
    $.extend(true, $.fancybox.defaults, {
      btnTpl: {
        slideShow: '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg>' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg>' +
          "</button>"
      },
      slideShow: {
        autoStart: false,
        speed: 3000,
        progress: true
      }
    });
  
    var SlideShow = function (instance) {
      this.instance = instance;
      this.init();
    };
  
    $.extend(SlideShow.prototype, {
      timer: null,
      isActive: false,
      $button: null,
  
      init: function () {
        var self = this,
          instance = self.instance,
          opts = instance.group[instance.currIndex].opts.slideShow;
  
        self.$button = instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function () {
          self.toggle();
        });
  
        if (instance.group.length < 2 || !opts) {
          self.$button.hide();
        } else if (opts.progress) {
          self.$progress = $('<div class="fancybox-progress"></div>').appendTo(instance.$refs.inner);
        }
      },
  
      set: function (force) {
        var self = this,
          instance = self.instance,
          current = instance.current;
  
        // Check if reached last element
        if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {
          if (self.isActive && current.contentType !== "video") {
            if (self.$progress) {
              $.fancybox.animate(self.$progress.show(), {
                scaleX: 1
              }, current.opts.slideShow.speed);
            }
  
            self.timer = setTimeout(function () {
              if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {
                instance.jumpTo(0);
              } else {
                instance.next();
              }
            }, current.opts.slideShow.speed);
          }
        } else {
          self.stop();
          instance.idleSecondsCounter = 0;
          instance.showControls();
        }
      },
  
      clear: function () {
        var self = this;
  
        clearTimeout(self.timer);
  
        self.timer = null;
  
        if (self.$progress) {
          self.$progress.removeAttr("style").hide();
        }
      },
  
      start: function () {
        var self = this,
          current = self.instance.current;
  
        if (current) {
          self.$button
            .attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP)
            .removeClass("fancybox-button--play")
            .addClass("fancybox-button--pause");
  
          self.isActive = true;
  
          if (current.isComplete) {
            self.set(true);
          }
  
          self.instance.trigger("onSlideShowChange", true);
        }
      },
  
      stop: function () {
        var self = this,
          current = self.instance.current;
  
        self.clear();
  
        self.$button
          .attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START)
          .removeClass("fancybox-button--pause")
          .addClass("fancybox-button--play");
  
        self.isActive = false;
  
        self.instance.trigger("onSlideShowChange", false);
  
        if (self.$progress) {
          self.$progress.removeAttr("style").hide();
        }
      },
  
      toggle: function () {
        var self = this;
  
        if (self.isActive) {
          self.stop();
        } else {
          self.start();
        }
      }
    });
  
    $(document).on({
      "onInit.fb": function (e, instance) {
        if (instance && !instance.SlideShow) {
          instance.SlideShow = new SlideShow(instance);
        }
      },
  
      "beforeShow.fb": function (e, instance, current, firstRun) {
        var SlideShow = instance && instance.SlideShow;
  
        if (firstRun) {
          if (SlideShow && current.opts.slideShow.autoStart) {
            SlideShow.start();
          }
        } else if (SlideShow && SlideShow.isActive) {
          SlideShow.clear();
        }
      },
  
      "afterShow.fb": function (e, instance, current) {
        var SlideShow = instance && instance.SlideShow;
  
        if (SlideShow && SlideShow.isActive) {
          SlideShow.set();
        }
      },
  
      "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
        var SlideShow = instance && instance.SlideShow;
  
        // "P" or Spacebar
        if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) {
          keypress.preventDefault();
  
          SlideShow.toggle();
        }
      },
  
      "beforeClose.fb onDeactivate.fb": function (e, instance) {
        var SlideShow = instance && instance.SlideShow;
  
        if (SlideShow) {
          SlideShow.stop();
        }
      }
    });
  
    // Page Visibility API to pause slideshow when window is not active
    $(document).on("visibilitychange", function () {
      var instance = $.fancybox.getInstance(),
        SlideShow = instance && instance.SlideShow;
  
      if (SlideShow && SlideShow.isActive) {
        if (document.hidden) {
          SlideShow.clear();
        } else {
          SlideShow.set();
        }
      }
    });
  })(document, jQuery);
  // ==========================================================================
  //
  // FullScreen
  // Adds fullscreen functionality
  //
  // ==========================================================================
  (function (document, $) {
    "use strict";
  
    // Collection of methods supported by user browser
    var fn = (function () {
      var fnMap = [
        ["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"],
        // new WebKit
        [
          "webkitRequestFullscreen",
          "webkitExitFullscreen",
          "webkitFullscreenElement",
          "webkitFullscreenEnabled",
          "webkitfullscreenchange",
          "webkitfullscreenerror"
        ],
        // old WebKit (Safari 5.1)
        [
          "webkitRequestFullScreen",
          "webkitCancelFullScreen",
          "webkitCurrentFullScreenElement",
          "webkitCancelFullScreen",
          "webkitfullscreenchange",
          "webkitfullscreenerror"
        ],
        [
          "mozRequestFullScreen",
          "mozCancelFullScreen",
          "mozFullScreenElement",
          "mozFullScreenEnabled",
          "mozfullscreenchange",
          "mozfullscreenerror"
        ],
        ["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"]
      ];
  
      var ret = {};
  
      for (var i = 0; i < fnMap.length; i++) {
        var val = fnMap[i];
  
        if (val && val[1] in document) {
          for (var j = 0; j < val.length; j++) {
            ret[fnMap[0][j]] = val[j];
          }
  
          return ret;
        }
      }
  
      return false;
    })();
  
    if (fn) {
      var FullScreen = {
        request: function (elem) {
          elem = elem || document.documentElement;
  
          elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);
        },
        exit: function () {
          document[fn.exitFullscreen]();
        },
        toggle: function (elem) {
          elem = elem || document.documentElement;
  
          if (this.isFullscreen()) {
            this.exit();
          } else {
            this.request(elem);
          }
        },
        isFullscreen: function () {
          return Boolean(document[fn.fullscreenElement]);
        },
        enabled: function () {
          return Boolean(document[fn.fullscreenEnabled]);
        }
      };
  
      $.extend(true, $.fancybox.defaults, {
        btnTpl: {
          fullScreen: '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}">' +
            '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>' +
            '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg>' +
            "</button>"
        },
        fullScreen: {
          autoStart: false
        }
      });
  
      $(document).on(fn.fullscreenchange, function () {
        var isFullscreen = FullScreen.isFullscreen(),
          instance = $.fancybox.getInstance();
  
        if (instance) {
          // If image is zooming, then force to stop and reposition properly
          if (instance.current && instance.current.type === "image" && instance.isAnimating) {
            instance.isAnimating = false;
  
            instance.update(true, true, 0);
  
            if (!instance.isComplete) {
              instance.complete();
            }
          }
  
          instance.trigger("onFullscreenChange", isFullscreen);
  
          instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen);
  
          instance.$refs.toolbar
            .find("[data-fancybox-fullscreen]")
            .toggleClass("fancybox-button--fsenter", !isFullscreen)
            .toggleClass("fancybox-button--fsexit", isFullscreen);
        }
      });
    }
  
    $(document).on({
      "onInit.fb": function (e, instance) {
        var $container;
  
        if (!fn) {
          instance.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();
  
          return;
        }
  
        if (instance && instance.group[instance.currIndex].opts.fullScreen) {
          $container = instance.$refs.container;
  
          $container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function (e) {
            e.stopPropagation();
            e.preventDefault();
  
            FullScreen.toggle();
          });
  
          if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {
            FullScreen.request();
          }
  
          // Expose API
          instance.FullScreen = FullScreen;
        } else if (instance) {
          instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide();
        }
      },
  
      "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
        // "F"
        if (instance && instance.FullScreen && keycode === 70) {
          keypress.preventDefault();
  
          instance.FullScreen.toggle();
        }
      },
  
      "beforeClose.fb": function (e, instance) {
        if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) {
          FullScreen.exit();
        }
      }
    });
  })(document, jQuery);
  // ==========================================================================
  //
  // Thumbs
  // Displays thumbnails in a grid
  //
  // ==========================================================================
  (function (document, $) {
    "use strict";
  
    var CLASS = "fancybox-thumbs",
      CLASS_ACTIVE = CLASS + "-active";
  
    // Make sure there are default values
    $.fancybox.defaults = $.extend(
      true, {
        btnTpl: {
          thumbs: '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' +
            '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg>' +
            "</button>"
        },
        thumbs: {
          autoStart: false, // Display thumbnails on opening
          hideOnClose: true, // Hide thumbnail grid when closing animation starts
          parentEl: ".fancybox-container", // Container is injected into this element
          axis: "y" // Vertical (y) or horizontal (x) scrolling
        }
      },
      $.fancybox.defaults
    );
  
    var FancyThumbs = function (instance) {
      this.init(instance);
    };
  
    $.extend(FancyThumbs.prototype, {
      $button: null,
      $grid: null,
      $list: null,
      isVisible: false,
      isActive: false,
  
      init: function (instance) {
        var self = this,
          group = instance.group,
          enabled = 0;
  
        self.instance = instance;
        self.opts = group[instance.currIndex].opts.thumbs;
  
        instance.Thumbs = self;
  
        self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]");
  
        // Enable thumbs if at least two group items have thumbnails
        for (var i = 0, len = group.length; i < len; i++) {
          if (group[i].thumb) {
            enabled++;
          }
  
          if (enabled > 1) {
            break;
          }
        }
  
        if (enabled > 1 && !!self.opts) {
          self.$button.removeAttr("style").on("click", function () {
            self.toggle();
          });
  
          self.isActive = true;
        } else {
          self.$button.hide();
        }
      },
  
      create: function () {
        var self = this,
          instance = self.instance,
          parentEl = self.opts.parentEl,
          list = [],
          src;
  
        if (!self.$grid) {
          // Create main element
          self.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo(
            instance.$refs.container
            .find(parentEl)
            .addBack()
            .filter(parentEl)
          );
  
          // Add "click" event that performs gallery navigation
          self.$grid.on("click", "a", function () {
            instance.jumpTo($(this).attr("data-index"));
          });
        }
  
        // Build the list
        if (!self.$list) {
          self.$list = $('<div class="' + CLASS + '__list">').appendTo(self.$grid);
        }
  
        $.each(instance.group, function (i, item) {
          src = item.thumb;
  
          if (!src && item.type === "image") {
            src = item.src;
          }
  
          list.push(
            '<a href="javascript:;" tabindex="0" data-index="' +
            i +
            '"' +
            (src && src.length ? ' style="background-image:url(' + src + ')"' : 'class="fancybox-thumbs-missing"') +
            "></a>"
          );
        });
  
        self.$list[0].innerHTML = list.join("");
  
        if (self.opts.axis === "x") {
          // Set fixed width for list element to enable horizontal scrolling
          self.$list.width(
            parseInt(self.$grid.css("padding-right"), 10) +
            instance.group.length *
            self.$list
            .children()
            .eq(0)
            .outerWidth(true)
          );
        }
      },
  
      focus: function (duration) {
        var self = this,
          $list = self.$list,
          $grid = self.$grid,
          thumb,
          thumbPos;
  
        if (!self.instance.current) {
          return;
        }
  
        thumb = $list
          .children()
          .removeClass(CLASS_ACTIVE)
          .filter('[data-index="' + self.instance.current.index + '"]')
          .addClass(CLASS_ACTIVE);
  
        thumbPos = thumb.position();
  
        // Check if need to scroll to make current thumb visible
        if (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {
          $list.stop().animate({
              scrollTop: $list.scrollTop() + thumbPos.top
            },
            duration
          );
        } else if (
          self.opts.axis === "x" &&
          (thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))
        ) {
          $list
            .parent()
            .stop()
            .animate({
                scrollLeft: thumbPos.left
              },
              duration
            );
        }
      },
  
      update: function () {
        var that = this;
        that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible);
  
        if (that.isVisible) {
          if (!that.$grid) {
            that.create();
          }
  
          that.instance.trigger("onThumbsShow");
  
          that.focus(0);
        } else if (that.$grid) {
          that.instance.trigger("onThumbsHide");
        }
  
        // Update content position
        that.instance.update();
      },
  
      hide: function () {
        this.isVisible = false;
        this.update();
      },
  
      show: function () {
        this.isVisible = true;
        this.update();
      },
  
      toggle: function () {
        this.isVisible = !this.isVisible;
        this.update();
      }
    });
  
    $(document).on({
      "onInit.fb": function (e, instance) {
        var Thumbs;
  
        if (instance && !instance.Thumbs) {
          Thumbs = new FancyThumbs(instance);
  
          if (Thumbs.isActive && Thumbs.opts.autoStart === true) {
            Thumbs.show();
          }
        }
      },
  
      "beforeShow.fb": function (e, instance, item, firstRun) {
        var Thumbs = instance && instance.Thumbs;
  
        if (Thumbs && Thumbs.isVisible) {
          Thumbs.focus(firstRun ? 0 : 250);
        }
      },
  
      "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
        var Thumbs = instance && instance.Thumbs;
  
        // "G"
        if (Thumbs && Thumbs.isActive && keycode === 71) {
          keypress.preventDefault();
  
          Thumbs.toggle();
        }
      },
  
      "beforeClose.fb": function (e, instance) {
        var Thumbs = instance && instance.Thumbs;
  
        if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {
          Thumbs.$grid.hide();
        }
      }
    });
  })(document, jQuery);
  //// ==========================================================================
  //
  // Share
  // Displays simple form for sharing current url
  //
  // ==========================================================================
  (function (document, $) {
    "use strict";
  
    $.extend(true, $.fancybox.defaults, {
      btnTpl: {
        share: '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' +
          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg>' +
          "</button>"
      },
      share: {
        url: function (instance, item) {
          return (
            (!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location
          );
        },
        tpl: '<div class="fancybox-share">' +
          "<h1>{{SHARE}}</h1>" +
          "<p>" +
          '<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' +
          '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' +
          "<span>Facebook</span>" +
          "</a>" +
          '<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' +
          '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' +
          "<span>Twitter</span>" +
          "</a>" +
          '<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' +
          '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' +
          "<span>Pinterest</span>" +
          "</a>" +
          "</p>" +
          '<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p>' +
          "</div>"
      }
    });
  
    function escapeHtml(string) {
      var entityMap = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        '"': "&quot;",
        "'": "&#39;",
        "/": "&#x2F;",
        "`": "&#x60;",
        "=": "&#x3D;"
      };
  
      return String(string).replace(/[&<>"'`=\/]/g, function (s) {
        return entityMap[s];
      });
    }
  
    $(document).on("click", "[data-fancybox-share]", function () {
      var instance = $.fancybox.getInstance(),
        current = instance.current || null,
        url,
        tpl;
  
      if (!current) {
        return;
      }
  
      if ($.type(current.opts.share.url) === "function") {
        url = current.opts.share.url.apply(current, [instance, current]);
      }
  
      tpl = current.opts.share.tpl
        .replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "")
        .replace(/\{\{url\}\}/g, encodeURIComponent(url))
        .replace(/\{\{url_raw\}\}/g, escapeHtml(url))
        .replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : "");
  
      $.fancybox.open({
        src: instance.translate(instance, tpl),
        type: "html",
        opts: {
          touch: false,
          animationEffect: false,
          afterLoad: function (shareInstance, shareCurrent) {
            // Close self if parent instance is closing
            instance.$refs.container.one("beforeClose.fb", function () {
              shareInstance.close(null, 0);
            });
  
            // Opening links in a popup window
            shareCurrent.$content.find(".fancybox-share__button").click(function () {
              window.open(this.href, "Share", "width=550, height=450");
              return false;
            });
          },
          mobile: {
            autoFocus: false
          }
        }
      });
    });
  })(document, jQuery);
  // ==========================================================================
  //
  // Hash
  // Enables linking to each modal
  //
  // ==========================================================================
  (function (window, document, $) {
    "use strict";
  
    // Simple $.escapeSelector polyfill (for jQuery prior v3)
    if (!$.escapeSelector) {
      $.escapeSelector = function (sel) {
        var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
        var 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;
        };
  
        return (sel + "").replace(rcssescape, fcssescape);
      };
    }
  
    // Get info about gallery name and current index from url
    function parseUrl() {
      var hash = window.location.hash.substr(1),
        rez = hash.split("-"),
        index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,
        gallery = rez.join("-");
  
      return {
        hash: hash,
        /* Index is starting from 1 */
        index: index < 1 ? 1 : index,
        gallery: gallery
      };
    }
  
    // Trigger click evnt on links to open new fancyBox instance
    function triggerFromUrl(url) {
      if (url.gallery !== "") {
        // If we can find element matching 'data-fancybox' atribute,
        // then triggering click event should start fancyBox
        $("[data-fancybox='" + $.escapeSelector(url.gallery) + "']")
          .eq(url.index - 1)
          .focus()
          .trigger("click.fb-start");
      }
    }
  
    // Get gallery name from current instance
    function getGalleryID(instance) {
      var opts, ret;
  
      if (!instance) {
        return false;
      }
  
      opts = instance.current ? instance.current.opts : instance.opts;
      ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") || opts.$orig.data("fancybox-trigger") : "");
  
      return ret === "" ? false : ret;
    }
  
    // Start when DOM becomes ready
    $(function () {
      // Check if user has disabled this module
      if ($.fancybox.defaults.hash === false) {
        return;
      }
  
      // Update hash when opening/closing fancyBox
      $(document).on({
        "onInit.fb": function (e, instance) {
          var url, gallery;
  
          if (instance.group[instance.currIndex].opts.hash === false) {
            return;
          }
  
          url = parseUrl();
          gallery = getGalleryID(instance);
  
          // Make sure gallery start index matches index from hash
          if (gallery && url.gallery && gallery == url.gallery) {
            instance.currIndex = url.index - 1;
          }
        },
  
        "beforeShow.fb": function (e, instance, current, firstRun) {
          var gallery;
  
          if (!current || current.opts.hash === false) {
            return;
          }
  
          // Check if need to update window hash
          gallery = getGalleryID(instance);
  
          if (!gallery) {
            return;
          }
  
          // Variable containing last hash value set by fancyBox
          // It will be used to determine if fancyBox needs to close after hash change is detected
          instance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : "");
  
          // If current hash is the same (this instance most likely is opened by hashchange), then do nothing
          if (window.location.hash === "#" + instance.currentHash) {
            return;
          }
  
          if (firstRun && !instance.origHash) {
            instance.origHash = window.location.hash;
          }
  
          if (instance.hashTimer) {
            clearTimeout(instance.hashTimer);
          }
  
          // Update hash
          instance.hashTimer = setTimeout(function () {
            if ("replaceState" in window.history) {
              window.history[firstRun ? "pushState" : "replaceState"]({},
                document.title,
                window.location.pathname + window.location.search + "#" + instance.currentHash
              );
  
              if (firstRun) {
                instance.hasCreatedHistory = true;
              }
            } else {
              window.location.hash = instance.currentHash;
            }
  
            instance.hashTimer = null;
          }, 300);
        },
  
        "beforeClose.fb": function (e, instance, current) {
          if (!current || current.opts.hash === false) {
            return;
          }
  
          clearTimeout(instance.hashTimer);
  
          // Goto previous history entry
          if (instance.currentHash && instance.hasCreatedHistory) {
            window.history.back();
          } else if (instance.currentHash) {
            if ("replaceState" in window.history) {
              window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || ""));
            } else {
              window.location.hash = instance.origHash;
            }
          }
  
          instance.currentHash = null;
        }
      });
  
      // Check if need to start/close after url has changed
      $(window).on("hashchange.fb", function () {
        var url = parseUrl(),
          fb = null;
  
        // Find last fancyBox instance that has "hash"
        $.each(
          $(".fancybox-container")
          .get()
          .reverse(),
          function (index, value) {
            var tmp = $(value).data("FancyBox");
  
            if (tmp && tmp.currentHash) {
              fb = tmp;
              return false;
            }
          }
        );
  
        if (fb) {
          // Now, compare hash values
          if (fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {
            fb.currentHash = null;
  
            fb.close();
          }
        } else if (url.gallery !== "") {
          triggerFromUrl(url);
        }
      });
  
      // Check current hash and trigger click event on matching element to start fancyBox, if needed
      setTimeout(function () {
        if (!$.fancybox.getInstance()) {
          triggerFromUrl(parseUrl());
        }
      }, 50);
    });
  })(window, document, jQuery);
  // ==========================================================================
  //
  // Wheel
  // Basic mouse weheel support for gallery navigation
  //
  // ==========================================================================
  (function (document, $) {
    "use strict";
  
    var prevTime = new Date().getTime();
  
    $(document).on({
      "onInit.fb": function (e, instance, current) {
        instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function (e) {
          var current = instance.current,
            currTime = new Date().getTime();
  
          if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) {
            return;
          }
  
          e.preventDefault();
          e.stopPropagation();
  
          if (current.$slide.hasClass("fancybox-animated")) {
            return;
          }
  
          e = e.originalEvent || e;
  
          if (currTime - prevTime < 250) {
            return;
          }
  
          prevTime = currTime;
  
          instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"]();
        });
      }
    });
  })(document, jQuery);
  
  /***/ }),
  
  /***/ "./resources/js/app.js":
  /*!*****************************!*\
    !*** ./resources/js/app.js ***!
    \*****************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var _import_jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./import-jquery */ "./resources/js/import-jquery.js");
  /* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! slick-carousel */ "./node_modules/slick-carousel/slick/slick.js");
  /* harmony import */ var slick_carousel__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(slick_carousel__WEBPACK_IMPORTED_MODULE_1__);
  /* harmony import */ var simplebar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! simplebar */ "./node_modules/simplebar/dist/simplebar.esm.js");
  /* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @fancyapps/fancybox */ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js");
  /* harmony import */ var _fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_fancyapps_fancybox__WEBPACK_IMPORTED_MODULE_3__);
  /* harmony import */ var lozad__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lozad */ "./node_modules/lozad/dist/lozad.min.js");
  /* harmony import */ var lozad__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(lozad__WEBPACK_IMPORTED_MODULE_4__);
  /* harmony import */ var ion_rangeslider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ion-rangeslider */ "./node_modules/ion-rangeslider/js/ion.rangeSlider.js");
  /* harmony import */ var ion_rangeslider__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(ion_rangeslider__WEBPACK_IMPORTED_MODULE_5__);
  /* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! mobile-detect */ "./node_modules/mobile-detect/mobile-detect.js");
  /* harmony import */ var mobile_detect__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(mobile_detect__WEBPACK_IMPORTED_MODULE_6__);
  
  
  
  
  
  
  
  var md = new (mobile_detect__WEBPACK_IMPORTED_MODULE_6___default())(window.navigator.userAgent);
  $(document).ready(function () {
    // Create an observer for lazyload
    var observer = lozad__WEBPACK_IMPORTED_MODULE_4___default()();
    observer.observe(); // Check if browser supports WebP
  
    testWebP(function (support) {
      if (support === true) {
        document.querySelector("body").classList.add("webp");
      } else {
        document.querySelector("body").classList.add("no-webp");
      }
    }); // Check if user uses mobile device
  
    if (!md.mobile()) {
      var scrollbar = document.querySelector(".js-scrollbar"); // Create a scrollbar component
  
      if (scrollbar) {
        new simplebar__WEBPACK_IMPORTED_MODULE_2__.default(scrollbar);
      } // Show cart info on mouseenter or hide cart info on mouseleave
  
  
      $(".js-cart-button").hover(function () {
        $(this).find(".js-cart-info").addClass("active");
      }, function () {
        $(this).find(".js-cart-info").removeClass("active");
      });
    } else if (md.mobile()) {
      var handleGesture = function handleGesture(event) {
        var sliderArea = event.target.closest(".js-categories-list");
        var scrollbarArea = event.target.closest(".js-scrollbar");
        var diff = touchstartY - touchendY; // Don't recognize gestures on slider or scrollbar areas
  
        if (sliderArea || scrollbarArea) return; // Don't recognize gestures when popup is shown
  
        if ($("body").hasClass("fancybox-active")) return; // Don't recognize horizontal gestures on vertical gestures
  
        if (diff < -10 || diff > 10) return; // Swiped left
  
        if (touchendX < touchstartX) {
          if (burger.hasClass("active")) {
            burger.removeClass("active");
            mobileMenu.removeClass("active");
            blur.removeClass("active");
            $(".js-mobile-sublist.mobile-sublist_opened").removeClass("mobile-sublist_opened");
            bodyUnlock();
          }
        } // Swiped right
  
  
        if (touchendX > touchstartX) {
          if (!burger.hasClass("active")) {
            burger.addClass("active");
            mobileMenu.addClass("active");
            blur.addClass("active");
            bodyLock();
          }
        }
      };
  
      // Create gestures events
      var mobileMenu = $(".js-mobile");
      var burger = $(".js-main-hamburger");
      var blur = $(".js-main-blur");
      var gestureZone = document; // Coordinates of a gesture
  
      var touchstartX = 0;
      var touchstartY = 0;
      var touchendX = 0;
      var touchendY = 0;
      gestureZone.addEventListener("touchstart", function (event) {
        touchstartX = event.changedTouches[0].screenX;
        touchstartY = event.changedTouches[0].screenY;
      }, false);
      gestureZone.addEventListener("touchend", function (event) {
        touchendX = event.changedTouches[0].screenX;
        touchendY = event.changedTouches[0].screenY;
        handleGesture(event);
      }, false);
    } // Open basket popup
  
  
    $(".js-popup").fancybox({
      touch: false,
      beforeShow: function beforeShow() {
        $("html").css({
          "overflow-y": "hidden"
        });
      },
      afterClose: function afterClose() {
        $("html").css({
          "overflow-y": "visible"
        });
      }
    }); // Disable scroll when popup gallery is shown
  
    $(".js-category-image").fancybox({
      beforeShow: function beforeShow() {
        $("html").css({
          "overflow-y": "hidden"
        });
      },
      afterClose: function afterClose() {
        $("html").css({
          "overflow-y": "visible"
        });
      }
    }); // Initialize slider
  
    var categoriesSlider = $(".categories__list");
  
    if (categoriesSlider) {
      categoriesSlider.slick({
        slidesToShow: 6,
        arrows: false,
        variableWidth: true,
        responsive: [{
          breakpoint: 1501,
          settings: {
            slidesToShow: 5,
            arrows: false
          }
        }, {
          breakpoint: 769,
          settings: {
            slidesToShow: 3,
            arrows: false,
            dots: true,
            variableWidth: false
          }
        }, {
          breakpoint: 577,
          settings: {
            slidesToShow: 2,
            arrows: false,
            dots: true,
            variableWidth: false
          }
        }, {
          breakpoint: 350,
          settings: {
            slidesToShow: 1,
            arrows: false,
            dots: true,
            variableWidth: false
          }
        }]
      });
      categoriesSlider.on("afterChange", function () {
        observer.observe();
      });
    } // Sidebar's toggle blocks
  
  
    $(".js-sidebar-header").on("click", function () {
      var targetNode = $(this).siblings(".js-sidebar-body");
  
      if (targetNode.is(":visible")) {
        $(this).removeClass("active");
        targetNode.slideUp();
      } else {
        $(this).addClass("active");
        targetNode.slideDown({
          start: function start() {
            $(this).css({
              display: "flex"
            });
          }
        });
      }
    }); // Accordion
  
    $(".js-accordion-btn").on("click", function (event) {
      var accordionHeader = $(this).parents(".js-accordion-header");
      var group = $(this).parents(".js-accordion-group");
      var targetNode = accordionHeader.siblings(".js-accordion-body");
  
      if (targetNode.is(":visible")) {
        accordionHeader.removeClass("active");
        targetNode.slideUp();
      } else {
        group.find(".js-accordion-header.active").removeClass("active");
        group.find(".js-accordion-body").slideUp();
        accordionHeader.addClass("active");
        targetNode.slideDown({
          start: function start() {
            $(this).css({
              display: "flex"
            });
          }
        });
      }
    });
    var accordionContainer = $(".js-accordion-header-to-hide");
    var catalogContainer = $(".js-catalog-action");
    var selectContainer = $(".js-select__header");
  
    if (window.innerWidth >= 1200) {
      $(document).on("mouseup", function (e) {
        var accordion = $(".js-accordion-body-to-hide");
        var catalog = $(".js-main-list");
        var select = $(".js-select__body");
  
        if (accordionContainer.has(e.target).length === 0 && accordion.has(e.target).length === 0) {
          $(accordion).slideUp();
          $(accordionContainer).removeClass("active");
        }
  
        if (catalogContainer.has(e.target).length === 0 && catalog.has(e.target).length === 0) {
          catalog.removeClass("active");
          $(".js-hamburger").removeClass("active");
        }
  
        if (selectContainer.has(e.target).length === 0 && select.has(e.target).length === 0) {
          select.removeClass("active");
        }
      });
    } else {
      $(document).off("mouseup");
    } // Search form submit
  
  
    $(".js-search-submit").on("click", function () {
      $(this).parents("form").submit();
    }); // Hamburger
  
    $(".js-main-hamburger").on("click", function () {
      var mobileMenu = $(".js-mobile");
      var blur = $(".js-main-blur");
  
      if (!$(this).hasClass("active")) {
        $(this).addClass("active");
        mobileMenu.addClass("active");
        blur.addClass("active");
        bodyLock();
      } else {
        $(this).removeClass("active");
        mobileMenu.removeClass("active");
        blur.removeClass("active");
        $(".js-mobile-sublist.mobile-sublist_opened").removeClass("mobile-sublist_opened");
        bodyUnlock();
      }
    }); // Scroll to button
  
    $(".js-scroll-to").on("click", function (e) {
      e.preventDefault();
      var target = $(this).attr("href");
      document.querySelector(target).scrollIntoView({
        behavior: "smooth"
      });
    }); // Hide coockie message
  
    $(".js-coockie-btn").on("click", function () {
      $(this).parents(".js-coockie").removeClass("active");
    }); // Show coockie message
  
    setTimeout(function () {
      $(".js-coockie").addClass("active");
    }, 2000);
    $(window).on("resize", function () {
      $(".js-footer .js-accordion").each(function () {
        var body = $(this).find(".js-accordion-body");
        var header = $(this).find(".js-accordion-header");
  
        if (window.innerWidth >= 450) {
          if (!body.is(":visible")) {
            body.css("display", "flex");
          }
        } else if (window.innerWidth < 450) {
          if (body.is(":visible")) {
            body.css("display", "none");
            header.removeClass("active");
          }
        }
      });
    }); // Close the hamburger when blur area was clicked
  
    $(".js-main-blur").on("click", function () {
      var mobileMenu = $(".js-mobile");
      var hamburger = $(".js-main-hamburger");
      mobileMenu.removeClass("active");
      hamburger.removeClass("active");
      $(this).removeClass("active");
      $(".js-mobile-sublist.mobile-sublist_opened").removeClass("mobile-sublist_opened");
      bodyUnlock();
    }); // Remove an item from the basket
  
    $(".js-basket-popup-remove").on("click", function () {
      var elem = $(".js-cart-button .js-cart-count");
      var count = +elem.text();
      $(this).parents(".js-basket-popup-item").remove();
      elem.text(count - 1);
  
      if (+elem.text() <= 0) {
        elem.addClass("hidden");
      }
    }); // Change amount of the product
  
    $(".js-basket-popup-button").on("click", function () {
      var action = $(this).attr("data-basket-action");
      var elem = $(this).siblings(".js-basket-popup-text").find("span");
      var val = +elem.text();
  
      if (action == "plus") {
        val++;
      } else if (action == "minus" && val > 0) {
        val--;
      }
  
      if (val != +elem.text()) {
        elem.text(val);
      }
    }); // Show catalog menu
  
    $(".js-catalog-action").on("click", function () {
      var menu = $(this).siblings(".js-main-list");
      var hamburger = $(this).find(".js-hamburger");
  
      if (!menu.hasClass("active")) {
        menu.addClass("active");
        hamburger.addClass("active");
      } else {
        menu.removeClass("active");
        hamburger.removeClass("active");
      }
    }); // Show catalog submenu
  
    $(".js-main-list-item").on("mouseenter", function () {
      var id = $(this).attr("data-category-id");
      var target = $(".js-main-sublist-item[data-category-id='".concat(id, "']"));
  
      if (!target.hasClass("active")) {
        $(".js-main-sublist-item.active").removeClass("active");
        target.addClass("active");
      }
    }); // Show mobile submenu
  
    $(".js-main-mobile-list-item").on("click", function (event) {
      var menu = $(this).attr("data-menu");
      var target = $(".js-mobile-sublist[data-menu=\"".concat(menu, "\"]"));
      var link = event.target.closest("a");
      if (link) return;
      target.addClass("mobile-sublist_opened");
    }); // Hide mobile submenu
  
    $(".js-mobile-sublist-back").on("click", function () {
      $(this).parents(".js-mobile-sublist").removeClass("mobile-sublist_opened");
    }); // Custom select
  
    $(".js-select").on("click", function () {
      var selectBody = $(this).find(".js-select__body");
  
      if (!selectBody.hasClass("active")) {
        $(".js-select").find(".js-select__body").removeClass("active");
        selectBody.addClass("active");
      } else {
        selectBody.removeClass("active");
      }
    }); // Change a value of custom select
  
    $(".js-select-item").on("click", function () {
      var text = $(this).children("span").text();
      var parent = $(this).parents(".js-select").children(".js-select__header");
      parent.children("span").text(text);
    }); // Create price's range slider
  
    var range = $(".js-range-slider");
    var inputFrom = $(".js-range-from");
    var inputTo = $(".js-range-to");
    var instance;
    var min = 1847;
    var max = 19717;
    var from = 0;
    var to = 0;
    range.ionRangeSlider({
      skin: "round",
      type: "double",
      min: 1847,
      max: 19717,
      from: 1847,
      to: 19717,
      grid: false,
      hide_from_to: true,
      hide_min_max: true,
      onStart: updateInputs,
      onChange: updateInputs,
      onFinish: updateInputs
    });
    instance = range.data("ionRangeSlider"); // Update input fields when price's range slider is changed
  
    function updateInputs(data) {
      from = data.from;
      to = data.to;
      inputFrom.prop("value", from);
      inputTo.prop("value", to);
    } // Update price's range slider when input fields are changed
  
  
    inputFrom.on("change", function () {
      var val = $(this).prop("value");
  
      if (val < min) {
        val = min;
      } else if (val > to) {
        val = to;
      }
  
      instance.update({
        from: val
      });
      $(this).prop("value", val);
    }); // Update price's range slider when input fields are changed
  
    inputTo.on("change", function () {
      var val = $(this).prop("value");
  
      if (val < from) {
        val = from;
      } else if (val > max) {
        val = max;
      }
  
      instance.update({
        to: val
      });
      $(this).prop("value", val);
    });
  });
  
  function testWebP(callback) {
    var webP = new Image();
  
    webP.onload = webP.onerror = function () {
      callback(webP.height === 2);
    };
  
    webP.src = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
  }
  
  var unlock = true;
  var timeout = 200;
  var root = document.querySelector("html");
  var lockPadding = document.querySelectorAll(".lock-padding"); // Compensate scroll width
  
  function bodyLock() {
    var lockPaddingValue = window.innerWidth - document.querySelector("body").offsetWidth + "px";
  
    if (lockPadding.length > 0) {
      for (var i = 0; i < lockPadding.length; i++) {
        var el = lockPadding[i];
        el.style.paddingRight = lockPaddingValue;
      }
    }
  
    root.style.paddingRight = lockPaddingValue;
    root.classList.add("lock");
    unlock = false;
    setTimeout(function () {
      unlock = true;
    }, timeout);
  }
  
  function bodyUnlock() {
    setTimeout(function () {
      for (var i = 0; i < lockPadding.length; i++) {
        var el = lockPadding[i];
        el.style.paddingRight = "0px";
      }
  
      root.style.paddingRight = "0px";
      root.classList.remove("lock");
    }, timeout);
    unlock = false;
    setTimeout(function () {
      unlock = true;
    }, timeout);
  }
  
  /***/ }),
  
  /***/ "./resources/js/import-jquery.js":
  /*!***************************************!*\
    !*** ./resources/js/import-jquery.js ***!
    \***************************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
  /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
  
  /* harmony default export */ __webpack_exports__["default"] = (window.$ = window.jQuery = (jquery__WEBPACK_IMPORTED_MODULE_0___default()));
  
  /***/ }),
  
  /***/ "./node_modules/can-use-dom/index.js":
  /*!*******************************************!*\
    !*** ./node_modules/can-use-dom/index.js ***!
    \*******************************************/
  /***/ (function(module) {
  
  var canUseDOM = !!(
    typeof window !== 'undefined' &&
    window.document &&
    window.document.createElement
  );
  
  module.exports = canUseDOM;
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/a-function.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/internals/a-function.js ***!
    \******************************************************/
  /***/ (function(module) {
  
  module.exports = function (it) {
    if (typeof it != 'function') {
      throw TypeError(String(it) + ' is not a function');
    } return it;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/a-possible-prototype.js":
  /*!****************************************************************!*\
    !*** ./node_modules/core-js/internals/a-possible-prototype.js ***!
    \****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  
  module.exports = function (it) {
    if (!isObject(it) && it !== null) {
      throw TypeError("Can't set " + String(it) + ' as a prototype');
    } return it;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/add-to-unscopables.js":
  /*!**************************************************************!*\
    !*** ./node_modules/core-js/internals/add-to-unscopables.js ***!
    \**************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var create = __webpack_require__(/*! ../internals/object-create */ "./node_modules/core-js/internals/object-create.js");
  var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js");
  
  var UNSCOPABLES = wellKnownSymbol('unscopables');
  var ArrayPrototype = Array.prototype;
  
  // Array.prototype[@@unscopables]
  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
  if (ArrayPrototype[UNSCOPABLES] == undefined) {
    definePropertyModule.f(ArrayPrototype, UNSCOPABLES, {
      configurable: true,
      value: create(null)
    });
  }
  
  // add a key to Array.prototype[@@unscopables]
  module.exports = function (key) {
    ArrayPrototype[UNSCOPABLES][key] = true;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/advance-string-index.js":
  /*!****************************************************************!*\
    !*** ./node_modules/core-js/internals/advance-string-index.js ***!
    \****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var charAt = __webpack_require__(/*! ../internals/string-multibyte */ "./node_modules/core-js/internals/string-multibyte.js").charAt;
  
  // `AdvanceStringIndex` abstract operation
  // https://tc39.es/ecma262/#sec-advancestringindex
  module.exports = function (S, index, unicode) {
    return index + (unicode ? charAt(S, index).length : 1);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/an-instance.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/an-instance.js ***!
    \*******************************************************/
  /***/ (function(module) {
  
  module.exports = function (it, Constructor, name) {
    if (!(it instanceof Constructor)) {
      throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
    } return it;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/an-object.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/an-object.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  
  module.exports = function (it) {
    if (!isObject(it)) {
      throw TypeError(String(it) + ' is not an object');
    } return it;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-for-each.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/array-for-each.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $forEach = __webpack_require__(/*! ../internals/array-iteration */ "./node_modules/core-js/internals/array-iteration.js").forEach;
  var arrayMethodIsStrict = __webpack_require__(/*! ../internals/array-method-is-strict */ "./node_modules/core-js/internals/array-method-is-strict.js");
  
  var STRICT_METHOD = arrayMethodIsStrict('forEach');
  
  // `Array.prototype.forEach` method implementation
  // https://tc39.es/ecma262/#sec-array.prototype.foreach
  module.exports = !STRICT_METHOD ? function forEach(callbackfn /* , thisArg */) {
    return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  // eslint-disable-next-line es/no-array-prototype-foreach -- safe
  } : [].forEach;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-includes.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/array-includes.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "./node_modules/core-js/internals/to-indexed-object.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  var toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ "./node_modules/core-js/internals/to-absolute-index.js");
  
  // `Array.prototype.{ indexOf, includes }` methods implementation
  var createMethod = function (IS_INCLUDES) {
    return function ($this, el, fromIndex) {
      var O = toIndexedObject($this);
      var length = toLength(O.length);
      var index = toAbsoluteIndex(fromIndex, length);
      var value;
      // Array#includes uses SameValueZero equality algorithm
      // eslint-disable-next-line no-self-compare -- NaN check
      if (IS_INCLUDES && el != el) while (length > index) {
        value = O[index++];
        // eslint-disable-next-line no-self-compare -- NaN check
        if (value != value) return true;
      // Array#indexOf ignores holes, Array#includes - not
      } else for (;length > index; index++) {
        if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
      } return !IS_INCLUDES && -1;
    };
  };
  
  module.exports = {
    // `Array.prototype.includes` method
    // https://tc39.es/ecma262/#sec-array.prototype.includes
    includes: createMethod(true),
    // `Array.prototype.indexOf` method
    // https://tc39.es/ecma262/#sec-array.prototype.indexof
    indexOf: createMethod(false)
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-iteration.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/internals/array-iteration.js ***!
    \***********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var bind = __webpack_require__(/*! ../internals/function-bind-context */ "./node_modules/core-js/internals/function-bind-context.js");
  var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "./node_modules/core-js/internals/indexed-object.js");
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  var arraySpeciesCreate = __webpack_require__(/*! ../internals/array-species-create */ "./node_modules/core-js/internals/array-species-create.js");
  
  var push = [].push;
  
  // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
  var createMethod = function (TYPE) {
    var IS_MAP = TYPE == 1;
    var IS_FILTER = TYPE == 2;
    var IS_SOME = TYPE == 3;
    var IS_EVERY = TYPE == 4;
    var IS_FIND_INDEX = TYPE == 6;
    var IS_FILTER_OUT = TYPE == 7;
    var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
    return function ($this, callbackfn, that, specificCreate) {
      var O = toObject($this);
      var self = IndexedObject(O);
      var boundFunction = bind(callbackfn, that, 3);
      var length = toLength(self.length);
      var index = 0;
      var create = specificCreate || arraySpeciesCreate;
      var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
      var value, result;
      for (;length > index; index++) if (NO_HOLES || index in self) {
        value = self[index];
        result = boundFunction(value, index, O);
        if (TYPE) {
          if (IS_MAP) target[index] = result; // map
          else if (result) switch (TYPE) {
            case 3: return true;              // some
            case 5: return value;             // find
            case 6: return index;             // findIndex
            case 2: push.call(target, value); // filter
          } else switch (TYPE) {
            case 4: return false;             // every
            case 7: push.call(target, value); // filterOut
          }
        }
      }
      return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
    };
  };
  
  module.exports = {
    // `Array.prototype.forEach` method
    // https://tc39.es/ecma262/#sec-array.prototype.foreach
    forEach: createMethod(0),
    // `Array.prototype.map` method
    // https://tc39.es/ecma262/#sec-array.prototype.map
    map: createMethod(1),
    // `Array.prototype.filter` method
    // https://tc39.es/ecma262/#sec-array.prototype.filter
    filter: createMethod(2),
    // `Array.prototype.some` method
    // https://tc39.es/ecma262/#sec-array.prototype.some
    some: createMethod(3),
    // `Array.prototype.every` method
    // https://tc39.es/ecma262/#sec-array.prototype.every
    every: createMethod(4),
    // `Array.prototype.find` method
    // https://tc39.es/ecma262/#sec-array.prototype.find
    find: createMethod(5),
    // `Array.prototype.findIndex` method
    // https://tc39.es/ecma262/#sec-array.prototype.findIndex
    findIndex: createMethod(6),
    // `Array.prototype.filterOut` method
    // https://github.com/tc39/proposal-array-filtering
    filterOut: createMethod(7)
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-method-has-species-support.js":
  /*!****************************************************************************!*\
    !*** ./node_modules/core-js/internals/array-method-has-species-support.js ***!
    \****************************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var V8_VERSION = __webpack_require__(/*! ../internals/engine-v8-version */ "./node_modules/core-js/internals/engine-v8-version.js");
  
  var SPECIES = wellKnownSymbol('species');
  
  module.exports = function (METHOD_NAME) {
    // We can't use this feature detection in V8 since it causes
    // deoptimization and serious performance degradation
    // https://github.com/zloirock/core-js/issues/677
    return V8_VERSION >= 51 || !fails(function () {
      var array = [];
      var constructor = array.constructor = {};
      constructor[SPECIES] = function () {
        return { foo: 1 };
      };
      return array[METHOD_NAME](Boolean).foo !== 1;
    });
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-method-is-strict.js":
  /*!******************************************************************!*\
    !*** ./node_modules/core-js/internals/array-method-is-strict.js ***!
    \******************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  module.exports = function (METHOD_NAME, argument) {
    var method = [][METHOD_NAME];
    return !!method && fails(function () {
      // eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing
      method.call(null, argument || function () { throw 1; }, 1);
    });
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-reduce.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/array-reduce.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var aFunction = __webpack_require__(/*! ../internals/a-function */ "./node_modules/core-js/internals/a-function.js");
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "./node_modules/core-js/internals/indexed-object.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  
  // `Array.prototype.{ reduce, reduceRight }` methods implementation
  var createMethod = function (IS_RIGHT) {
    return function (that, callbackfn, argumentsLength, memo) {
      aFunction(callbackfn);
      var O = toObject(that);
      var self = IndexedObject(O);
      var length = toLength(O.length);
      var index = IS_RIGHT ? length - 1 : 0;
      var i = IS_RIGHT ? -1 : 1;
      if (argumentsLength < 2) while (true) {
        if (index in self) {
          memo = self[index];
          index += i;
          break;
        }
        index += i;
        if (IS_RIGHT ? index < 0 : length <= index) {
          throw TypeError('Reduce of empty array with no initial value');
        }
      }
      for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
        memo = callbackfn(memo, self[index], index, O);
      }
      return memo;
    };
  };
  
  module.exports = {
    // `Array.prototype.reduce` method
    // https://tc39.es/ecma262/#sec-array.prototype.reduce
    left: createMethod(false),
    // `Array.prototype.reduceRight` method
    // https://tc39.es/ecma262/#sec-array.prototype.reduceright
    right: createMethod(true)
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/array-species-create.js":
  /*!****************************************************************!*\
    !*** ./node_modules/core-js/internals/array-species-create.js ***!
    \****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var isArray = __webpack_require__(/*! ../internals/is-array */ "./node_modules/core-js/internals/is-array.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var SPECIES = wellKnownSymbol('species');
  
  // `ArraySpeciesCreate` abstract operation
  // https://tc39.es/ecma262/#sec-arrayspeciescreate
  module.exports = function (originalArray, length) {
    var C;
    if (isArray(originalArray)) {
      C = originalArray.constructor;
      // cross-realm fallback
      if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
      else if (isObject(C)) {
        C = C[SPECIES];
        if (C === null) C = undefined;
      }
    } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/check-correctness-of-iteration.js":
  /*!**************************************************************************!*\
    !*** ./node_modules/core-js/internals/check-correctness-of-iteration.js ***!
    \**************************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var ITERATOR = wellKnownSymbol('iterator');
  var SAFE_CLOSING = false;
  
  try {
    var called = 0;
    var iteratorWithReturn = {
      next: function () {
        return { done: !!called++ };
      },
      'return': function () {
        SAFE_CLOSING = true;
      }
    };
    iteratorWithReturn[ITERATOR] = function () {
      return this;
    };
    // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing
    Array.from(iteratorWithReturn, function () { throw 2; });
  } catch (error) { /* empty */ }
  
  module.exports = function (exec, SKIP_CLOSING) {
    if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
    var ITERATION_SUPPORT = false;
    try {
      var object = {};
      object[ITERATOR] = function () {
        return {
          next: function () {
            return { done: ITERATION_SUPPORT = true };
          }
        };
      };
      exec(object);
    } catch (error) { /* empty */ }
    return ITERATION_SUPPORT;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/classof-raw.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/classof-raw.js ***!
    \*******************************************************/
  /***/ (function(module) {
  
  var toString = {}.toString;
  
  module.exports = function (it) {
    return toString.call(it).slice(8, -1);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/classof.js":
  /*!***************************************************!*\
    !*** ./node_modules/core-js/internals/classof.js ***!
    \***************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var TO_STRING_TAG_SUPPORT = __webpack_require__(/*! ../internals/to-string-tag-support */ "./node_modules/core-js/internals/to-string-tag-support.js");
  var classofRaw = __webpack_require__(/*! ../internals/classof-raw */ "./node_modules/core-js/internals/classof-raw.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  // ES3 wrong here
  var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
  
  // fallback for IE11 Script Access Denied error
  var tryGet = function (it, key) {
    try {
      return it[key];
    } catch (error) { /* empty */ }
  };
  
  // getting tag from ES6+ `Object.prototype.toString`
  module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {
    var O, tag, result;
    return it === undefined ? 'Undefined' : it === null ? 'Null'
      // @@toStringTag case
      : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag
      // builtinTag case
      : CORRECT_ARGUMENTS ? classofRaw(O)
      // ES3 arguments fallback
      : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/collection-weak.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/internals/collection-weak.js ***!
    \***********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var redefineAll = __webpack_require__(/*! ../internals/redefine-all */ "./node_modules/core-js/internals/redefine-all.js");
  var getWeakData = __webpack_require__(/*! ../internals/internal-metadata */ "./node_modules/core-js/internals/internal-metadata.js").getWeakData;
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var anInstance = __webpack_require__(/*! ../internals/an-instance */ "./node_modules/core-js/internals/an-instance.js");
  var iterate = __webpack_require__(/*! ../internals/iterate */ "./node_modules/core-js/internals/iterate.js");
  var ArrayIterationModule = __webpack_require__(/*! ../internals/array-iteration */ "./node_modules/core-js/internals/array-iteration.js");
  var $has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "./node_modules/core-js/internals/internal-state.js");
  
  var setInternalState = InternalStateModule.set;
  var internalStateGetterFor = InternalStateModule.getterFor;
  var find = ArrayIterationModule.find;
  var findIndex = ArrayIterationModule.findIndex;
  var id = 0;
  
  // fallback for uncaught frozen keys
  var uncaughtFrozenStore = function (store) {
    return store.frozen || (store.frozen = new UncaughtFrozenStore());
  };
  
  var UncaughtFrozenStore = function () {
    this.entries = [];
  };
  
  var findUncaughtFrozen = function (store, key) {
    return find(store.entries, function (it) {
      return it[0] === key;
    });
  };
  
  UncaughtFrozenStore.prototype = {
    get: function (key) {
      var entry = findUncaughtFrozen(this, key);
      if (entry) return entry[1];
    },
    has: function (key) {
      return !!findUncaughtFrozen(this, key);
    },
    set: function (key, value) {
      var entry = findUncaughtFrozen(this, key);
      if (entry) entry[1] = value;
      else this.entries.push([key, value]);
    },
    'delete': function (key) {
      var index = findIndex(this.entries, function (it) {
        return it[0] === key;
      });
      if (~index) this.entries.splice(index, 1);
      return !!~index;
    }
  };
  
  module.exports = {
    getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
      var C = wrapper(function (that, iterable) {
        anInstance(that, C, CONSTRUCTOR_NAME);
        setInternalState(that, {
          type: CONSTRUCTOR_NAME,
          id: id++,
          frozen: undefined
        });
        if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
      });
  
      var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
  
      var define = function (that, key, value) {
        var state = getInternalState(that);
        var data = getWeakData(anObject(key), true);
        if (data === true) uncaughtFrozenStore(state).set(key, value);
        else data[state.id] = value;
        return that;
      };
  
      redefineAll(C.prototype, {
        // 23.3.3.2 WeakMap.prototype.delete(key)
        // 23.4.3.3 WeakSet.prototype.delete(value)
        'delete': function (key) {
          var state = getInternalState(this);
          if (!isObject(key)) return false;
          var data = getWeakData(key);
          if (data === true) return uncaughtFrozenStore(state)['delete'](key);
          return data && $has(data, state.id) && delete data[state.id];
        },
        // 23.3.3.4 WeakMap.prototype.has(key)
        // 23.4.3.4 WeakSet.prototype.has(value)
        has: function has(key) {
          var state = getInternalState(this);
          if (!isObject(key)) return false;
          var data = getWeakData(key);
          if (data === true) return uncaughtFrozenStore(state).has(key);
          return data && $has(data, state.id);
        }
      });
  
      redefineAll(C.prototype, IS_MAP ? {
        // 23.3.3.3 WeakMap.prototype.get(key)
        get: function get(key) {
          var state = getInternalState(this);
          if (isObject(key)) {
            var data = getWeakData(key);
            if (data === true) return uncaughtFrozenStore(state).get(key);
            return data ? data[state.id] : undefined;
          }
        },
        // 23.3.3.5 WeakMap.prototype.set(key, value)
        set: function set(key, value) {
          return define(this, key, value);
        }
      } : {
        // 23.4.3.1 WeakSet.prototype.add(value)
        add: function add(value) {
          return define(this, value, true);
        }
      });
  
      return C;
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/collection.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/internals/collection.js ***!
    \******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var isForced = __webpack_require__(/*! ../internals/is-forced */ "./node_modules/core-js/internals/is-forced.js");
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  var InternalMetadataModule = __webpack_require__(/*! ../internals/internal-metadata */ "./node_modules/core-js/internals/internal-metadata.js");
  var iterate = __webpack_require__(/*! ../internals/iterate */ "./node_modules/core-js/internals/iterate.js");
  var anInstance = __webpack_require__(/*! ../internals/an-instance */ "./node_modules/core-js/internals/an-instance.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var checkCorrectnessOfIteration = __webpack_require__(/*! ../internals/check-correctness-of-iteration */ "./node_modules/core-js/internals/check-correctness-of-iteration.js");
  var setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ "./node_modules/core-js/internals/set-to-string-tag.js");
  var inheritIfRequired = __webpack_require__(/*! ../internals/inherit-if-required */ "./node_modules/core-js/internals/inherit-if-required.js");
  
  module.exports = function (CONSTRUCTOR_NAME, wrapper, common) {
    var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1;
    var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1;
    var ADDER = IS_MAP ? 'set' : 'add';
    var NativeConstructor = global[CONSTRUCTOR_NAME];
    var NativePrototype = NativeConstructor && NativeConstructor.prototype;
    var Constructor = NativeConstructor;
    var exported = {};
  
    var fixMethod = function (KEY) {
      var nativeMethod = NativePrototype[KEY];
      redefine(NativePrototype, KEY,
        KEY == 'add' ? function add(value) {
          nativeMethod.call(this, value === 0 ? 0 : value);
          return this;
        } : KEY == 'delete' ? function (key) {
          return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
        } : KEY == 'get' ? function get(key) {
          return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);
        } : KEY == 'has' ? function has(key) {
          return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
        } : function set(key, value) {
          nativeMethod.call(this, key === 0 ? 0 : key, value);
          return this;
        }
      );
    };
  
    var REPLACE = isForced(
      CONSTRUCTOR_NAME,
      typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
        new NativeConstructor().entries().next();
      }))
    );
  
    if (REPLACE) {
      // create collection constructor
      Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
      InternalMetadataModule.REQUIRED = true;
    } else if (isForced(CONSTRUCTOR_NAME, true)) {
      var instance = new Constructor();
      // early implementations not supports chaining
      var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
      // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
      var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
      // most early implementations doesn't supports iterables, most modern - not close it correctly
      // eslint-disable-next-line no-new -- required for testing
      var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
      // for early implementations -0 and +0 not the same
      var BUGGY_ZERO = !IS_WEAK && fails(function () {
        // V8 ~ Chromium 42- fails only with 5+ elements
        var $instance = new NativeConstructor();
        var index = 5;
        while (index--) $instance[ADDER](index, index);
        return !$instance.has(-0);
      });
  
      if (!ACCEPT_ITERABLES) {
        Constructor = wrapper(function (dummy, iterable) {
          anInstance(dummy, Constructor, CONSTRUCTOR_NAME);
          var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
          if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
          return that;
        });
        Constructor.prototype = NativePrototype;
        NativePrototype.constructor = Constructor;
      }
  
      if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
        fixMethod('delete');
        fixMethod('has');
        IS_MAP && fixMethod('get');
      }
  
      if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
  
      // weak collections should not contains .clear method
      if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
    }
  
    exported[CONSTRUCTOR_NAME] = Constructor;
    $({ global: true, forced: Constructor != NativeConstructor }, exported);
  
    setToStringTag(Constructor, CONSTRUCTOR_NAME);
  
    if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
  
    return Constructor;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/copy-constructor-properties.js":
  /*!***********************************************************************!*\
    !*** ./node_modules/core-js/internals/copy-constructor-properties.js ***!
    \***********************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var ownKeys = __webpack_require__(/*! ../internals/own-keys */ "./node_modules/core-js/internals/own-keys.js");
  var getOwnPropertyDescriptorModule = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "./node_modules/core-js/internals/object-get-own-property-descriptor.js");
  var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js");
  
  module.exports = function (target, source) {
    var keys = ownKeys(source);
    var defineProperty = definePropertyModule.f;
    var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/correct-prototype-getter.js":
  /*!********************************************************************!*\
    !*** ./node_modules/core-js/internals/correct-prototype-getter.js ***!
    \********************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  module.exports = !fails(function () {
    function F() { /* empty */ }
    F.prototype.constructor = null;
    // eslint-disable-next-line es/no-object-getprototypeof -- required for testing
    return Object.getPrototypeOf(new F()) !== F.prototype;
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/create-iterator-constructor.js":
  /*!***********************************************************************!*\
    !*** ./node_modules/core-js/internals/create-iterator-constructor.js ***!
    \***********************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var IteratorPrototype = __webpack_require__(/*! ../internals/iterators-core */ "./node_modules/core-js/internals/iterators-core.js").IteratorPrototype;
  var create = __webpack_require__(/*! ../internals/object-create */ "./node_modules/core-js/internals/object-create.js");
  var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "./node_modules/core-js/internals/create-property-descriptor.js");
  var setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ "./node_modules/core-js/internals/set-to-string-tag.js");
  var Iterators = __webpack_require__(/*! ../internals/iterators */ "./node_modules/core-js/internals/iterators.js");
  
  var returnThis = function () { return this; };
  
  module.exports = function (IteratorConstructor, NAME, next) {
    var TO_STRING_TAG = NAME + ' Iterator';
    IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(1, next) });
    setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);
    Iterators[TO_STRING_TAG] = returnThis;
    return IteratorConstructor;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/create-non-enumerable-property.js":
  /*!**************************************************************************!*\
    !*** ./node_modules/core-js/internals/create-non-enumerable-property.js ***!
    \**************************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js");
  var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "./node_modules/core-js/internals/create-property-descriptor.js");
  
  module.exports = DESCRIPTORS ? function (object, key, value) {
    return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
  } : function (object, key, value) {
    object[key] = value;
    return object;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/create-property-descriptor.js":
  /*!**********************************************************************!*\
    !*** ./node_modules/core-js/internals/create-property-descriptor.js ***!
    \**********************************************************************/
  /***/ (function(module) {
  
  module.exports = function (bitmap, value) {
    return {
      enumerable: !(bitmap & 1),
      configurable: !(bitmap & 2),
      writable: !(bitmap & 4),
      value: value
    };
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/define-iterator.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/internals/define-iterator.js ***!
    \***********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var createIteratorConstructor = __webpack_require__(/*! ../internals/create-iterator-constructor */ "./node_modules/core-js/internals/create-iterator-constructor.js");
  var getPrototypeOf = __webpack_require__(/*! ../internals/object-get-prototype-of */ "./node_modules/core-js/internals/object-get-prototype-of.js");
  var setPrototypeOf = __webpack_require__(/*! ../internals/object-set-prototype-of */ "./node_modules/core-js/internals/object-set-prototype-of.js");
  var setToStringTag = __webpack_require__(/*! ../internals/set-to-string-tag */ "./node_modules/core-js/internals/set-to-string-tag.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "./node_modules/core-js/internals/is-pure.js");
  var Iterators = __webpack_require__(/*! ../internals/iterators */ "./node_modules/core-js/internals/iterators.js");
  var IteratorsCore = __webpack_require__(/*! ../internals/iterators-core */ "./node_modules/core-js/internals/iterators-core.js");
  
  var IteratorPrototype = IteratorsCore.IteratorPrototype;
  var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
  var ITERATOR = wellKnownSymbol('iterator');
  var KEYS = 'keys';
  var VALUES = 'values';
  var ENTRIES = 'entries';
  
  var returnThis = function () { return this; };
  
  module.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
    createIteratorConstructor(IteratorConstructor, NAME, next);
  
    var getIterationMethod = function (KIND) {
      if (KIND === DEFAULT && defaultIterator) return defaultIterator;
      if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];
      switch (KIND) {
        case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
        case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
        case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
      } return function () { return new IteratorConstructor(this); };
    };
  
    var TO_STRING_TAG = NAME + ' Iterator';
    var INCORRECT_VALUES_NAME = false;
    var IterablePrototype = Iterable.prototype;
    var nativeIterator = IterablePrototype[ITERATOR]
      || IterablePrototype['@@iterator']
      || DEFAULT && IterablePrototype[DEFAULT];
    var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
    var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
    var CurrentIteratorPrototype, methods, KEY;
  
    // fix native
    if (anyNativeIterator) {
      CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));
      if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
        if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {
          if (setPrototypeOf) {
            setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);
          } else if (typeof CurrentIteratorPrototype[ITERATOR] != 'function') {
            createNonEnumerableProperty(CurrentIteratorPrototype, ITERATOR, returnThis);
          }
        }
        // Set @@toStringTag to native iterators
        setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
        if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;
      }
    }
  
    // fix Array#{values, @@iterator}.name in V8 / FF
    if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
      INCORRECT_VALUES_NAME = true;
      defaultIterator = function values() { return nativeIterator.call(this); };
    }
  
    // define iterator
    if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {
      createNonEnumerableProperty(IterablePrototype, ITERATOR, defaultIterator);
    }
    Iterators[NAME] = defaultIterator;
  
    // export additional methods
    if (DEFAULT) {
      methods = {
        values: getIterationMethod(VALUES),
        keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
        entries: getIterationMethod(ENTRIES)
      };
      if (FORCED) for (KEY in methods) {
        if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
          redefine(IterablePrototype, KEY, methods[KEY]);
        }
      } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
    }
  
    return methods;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/descriptors.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/descriptors.js ***!
    \*******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  // Detect IE8's incomplete defineProperty implementation
  module.exports = !fails(function () {
    // eslint-disable-next-line es/no-object-defineproperty -- required for testing
    return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/document-create-element.js":
  /*!*******************************************************************!*\
    !*** ./node_modules/core-js/internals/document-create-element.js ***!
    \*******************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  
  var document = global.document;
  // typeof document.createElement is 'object' in old IE
  var EXISTS = isObject(document) && isObject(document.createElement);
  
  module.exports = function (it) {
    return EXISTS ? document.createElement(it) : {};
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/dom-iterables.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/internals/dom-iterables.js ***!
    \*********************************************************/
  /***/ (function(module) {
  
  // iterable DOM collections
  // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
  module.exports = {
    CSSRuleList: 0,
    CSSStyleDeclaration: 0,
    CSSValueList: 0,
    ClientRectList: 0,
    DOMRectList: 0,
    DOMStringList: 0,
    DOMTokenList: 1,
    DataTransferItemList: 0,
    FileList: 0,
    HTMLAllCollection: 0,
    HTMLCollection: 0,
    HTMLFormElement: 0,
    HTMLSelectElement: 0,
    MediaList: 0,
    MimeTypeArray: 0,
    NamedNodeMap: 0,
    NodeList: 1,
    PaintRequestList: 0,
    Plugin: 0,
    PluginArray: 0,
    SVGLengthList: 0,
    SVGNumberList: 0,
    SVGPathSegList: 0,
    SVGPointList: 0,
    SVGStringList: 0,
    SVGTransformList: 0,
    SourceBufferList: 0,
    StyleSheetList: 0,
    TextTrackCueList: 0,
    TextTrackList: 0,
    TouchList: 0
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/engine-is-node.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/engine-is-node.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var classof = __webpack_require__(/*! ../internals/classof-raw */ "./node_modules/core-js/internals/classof-raw.js");
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  
  module.exports = classof(global.process) == 'process';
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/engine-user-agent.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/engine-user-agent.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "./node_modules/core-js/internals/get-built-in.js");
  
  module.exports = getBuiltIn('navigator', 'userAgent') || '';
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/engine-v8-version.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/engine-v8-version.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var userAgent = __webpack_require__(/*! ../internals/engine-user-agent */ "./node_modules/core-js/internals/engine-user-agent.js");
  
  var process = global.process;
  var versions = process && process.versions;
  var v8 = versions && versions.v8;
  var match, version;
  
  if (v8) {
    match = v8.split('.');
    version = match[0] + match[1];
  } else if (userAgent) {
    match = userAgent.match(/Edge\/(\d+)/);
    if (!match || match[1] >= 74) {
      match = userAgent.match(/Chrome\/(\d+)/);
      if (match) version = match[1];
    }
  }
  
  module.exports = version && +version;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/enum-bug-keys.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/internals/enum-bug-keys.js ***!
    \*********************************************************/
  /***/ (function(module) {
  
  // IE8- don't enum bug keys
  module.exports = [
    'constructor',
    'hasOwnProperty',
    'isPrototypeOf',
    'propertyIsEnumerable',
    'toLocaleString',
    'toString',
    'valueOf'
  ];
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/export.js":
  /*!**************************************************!*\
    !*** ./node_modules/core-js/internals/export.js ***!
    \**************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var getOwnPropertyDescriptor = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "./node_modules/core-js/internals/object-get-own-property-descriptor.js").f;
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  var setGlobal = __webpack_require__(/*! ../internals/set-global */ "./node_modules/core-js/internals/set-global.js");
  var copyConstructorProperties = __webpack_require__(/*! ../internals/copy-constructor-properties */ "./node_modules/core-js/internals/copy-constructor-properties.js");
  var isForced = __webpack_require__(/*! ../internals/is-forced */ "./node_modules/core-js/internals/is-forced.js");
  
  /*
    options.target      - name of the target object
    options.global      - target is the global object
    options.stat        - export as static methods of target
    options.proto       - export as prototype methods of target
    options.real        - real prototype method for the `pure` version
    options.forced      - export even if the native feature is available
    options.bind        - bind methods to the target, required for the `pure` version
    options.wrap        - wrap constructors to preventing global pollution, required for the `pure` version
    options.unsafe      - use the simple assignment of property instead of delete + defineProperty
    options.sham        - add a flag to not completely full polyfills
    options.enumerable  - export as enumerable property
    options.noTargetGet - prevent calling a getter on target
  */
  module.exports = function (options, source) {
    var TARGET = options.target;
    var GLOBAL = options.global;
    var STATIC = options.stat;
    var FORCED, target, key, targetProperty, sourceProperty, descriptor;
    if (GLOBAL) {
      target = global;
    } else if (STATIC) {
      target = global[TARGET] || setGlobal(TARGET, {});
    } else {
      target = (global[TARGET] || {}).prototype;
    }
    if (target) for (key in source) {
      sourceProperty = source[key];
      if (options.noTargetGet) {
        descriptor = getOwnPropertyDescriptor(target, key);
        targetProperty = descriptor && descriptor.value;
      } else targetProperty = target[key];
      FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
      // contained in target
      if (!FORCED && targetProperty !== undefined) {
        if (typeof sourceProperty === typeof targetProperty) continue;
        copyConstructorProperties(sourceProperty, targetProperty);
      }
      // add a flag to not completely full polyfills
      if (options.sham || (targetProperty && targetProperty.sham)) {
        createNonEnumerableProperty(sourceProperty, 'sham', true);
      }
      // extend global
      redefine(target, key, sourceProperty, options);
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/fails.js":
  /*!*************************************************!*\
    !*** ./node_modules/core-js/internals/fails.js ***!
    \*************************************************/
  /***/ (function(module) {
  
  module.exports = function (exec) {
    try {
      return !!exec();
    } catch (error) {
      return true;
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js":
  /*!******************************************************************************!*\
    !*** ./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js ***!
    \******************************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  // TODO: Remove from `core-js@4` since it's moved to entry points
  __webpack_require__(/*! ../modules/es.regexp.exec */ "./node_modules/core-js/modules/es.regexp.exec.js");
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  
  var SPECIES = wellKnownSymbol('species');
  
  var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
    // #replace needs built-in support for named groups.
    // #match works fine because it just return the exec results, even if it has
    // a "grops" property.
    var re = /./;
    re.exec = function () {
      var result = [];
      result.groups = { a: '7' };
      return result;
    };
    return ''.replace(re, '$<a>') !== '7';
  });
  
  // IE <= 11 replaces $0 with the whole match, as if it was $&
  // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
  var REPLACE_KEEPS_$0 = (function () {
    // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing
    return 'a'.replace(/./, '$0') === '$0';
  })();
  
  var REPLACE = wellKnownSymbol('replace');
  // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
  var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
    if (/./[REPLACE]) {
      return /./[REPLACE]('a', '$0') === '';
    }
    return false;
  })();
  
  // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
  // Weex JS has frozen built-in prototypes, so use try / catch wrapper
  var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
    // eslint-disable-next-line regexp/no-empty-group -- required for testing
    var re = /(?:)/;
    var originalExec = re.exec;
    re.exec = function () { return originalExec.apply(this, arguments); };
    var result = 'ab'.split(re);
    return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
  });
  
  module.exports = function (KEY, length, exec, sham) {
    var SYMBOL = wellKnownSymbol(KEY);
  
    var DELEGATES_TO_SYMBOL = !fails(function () {
      // String methods call symbol-named RegEp methods
      var O = {};
      O[SYMBOL] = function () { return 7; };
      return ''[KEY](O) != 7;
    });
  
    var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
      // Symbol-named RegExp methods call .exec
      var execCalled = false;
      var re = /a/;
  
      if (KEY === 'split') {
        // We can't use real regex here since it causes deoptimization
        // and serious performance degradation in V8
        // https://github.com/zloirock/core-js/issues/306
        re = {};
        // RegExp[@@split] doesn't call the regex's exec method, but first creates
        // a new one. We need to return the patched regex when creating the new one.
        re.constructor = {};
        re.constructor[SPECIES] = function () { return re; };
        re.flags = '';
        re[SYMBOL] = /./[SYMBOL];
      }
  
      re.exec = function () { execCalled = true; return null; };
  
      re[SYMBOL]('');
      return !execCalled;
    });
  
    if (
      !DELEGATES_TO_SYMBOL ||
      !DELEGATES_TO_EXEC ||
      (KEY === 'replace' && !(
        REPLACE_SUPPORTS_NAMED_GROUPS &&
        REPLACE_KEEPS_$0 &&
        !REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
      )) ||
      (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
    ) {
      var nativeRegExpMethod = /./[SYMBOL];
      var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
        if (regexp.exec === RegExp.prototype.exec) {
          if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
            // The native String method already delegates to @@method (this
            // polyfilled function), leasing to infinite recursion.
            // We avoid it by directly calling the native @@method method.
            return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
          }
          return { done: true, value: nativeMethod.call(str, regexp, arg2) };
        }
        return { done: false };
      }, {
        REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,
        REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
      });
      var stringMethod = methods[0];
      var regexMethod = methods[1];
  
      redefine(String.prototype, KEY, stringMethod);
      redefine(RegExp.prototype, SYMBOL, length == 2
        // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
        // 21.2.5.11 RegExp.prototype[@@split](string, limit)
        ? function (string, arg) { return regexMethod.call(string, this, arg); }
        // 21.2.5.6 RegExp.prototype[@@match](string)
        // 21.2.5.9 RegExp.prototype[@@search](string)
        : function (string) { return regexMethod.call(string, this); }
      );
    }
  
    if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/freezing.js":
  /*!****************************************************!*\
    !*** ./node_modules/core-js/internals/freezing.js ***!
    \****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  module.exports = !fails(function () {
    // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing
    return Object.isExtensible(Object.preventExtensions({}));
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/function-bind-context.js":
  /*!*****************************************************************!*\
    !*** ./node_modules/core-js/internals/function-bind-context.js ***!
    \*****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var aFunction = __webpack_require__(/*! ../internals/a-function */ "./node_modules/core-js/internals/a-function.js");
  
  // optional / simple context binding
  module.exports = function (fn, that, length) {
    aFunction(fn);
    if (that === undefined) return fn;
    switch (length) {
      case 0: return function () {
        return fn.call(that);
      };
      case 1: return function (a) {
        return fn.call(that, a);
      };
      case 2: return function (a, b) {
        return fn.call(that, a, b);
      };
      case 3: return function (a, b, c) {
        return fn.call(that, a, b, c);
      };
    }
    return function (/* ...args */) {
      return fn.apply(that, arguments);
    };
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/get-built-in.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/get-built-in.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var path = __webpack_require__(/*! ../internals/path */ "./node_modules/core-js/internals/path.js");
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  
  var aFunction = function (variable) {
    return typeof variable == 'function' ? variable : undefined;
  };
  
  module.exports = function (namespace, method) {
    return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])
      : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/get-iterator-method.js":
  /*!***************************************************************!*\
    !*** ./node_modules/core-js/internals/get-iterator-method.js ***!
    \***************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var classof = __webpack_require__(/*! ../internals/classof */ "./node_modules/core-js/internals/classof.js");
  var Iterators = __webpack_require__(/*! ../internals/iterators */ "./node_modules/core-js/internals/iterators.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var ITERATOR = wellKnownSymbol('iterator');
  
  module.exports = function (it) {
    if (it != undefined) return it[ITERATOR]
      || it['@@iterator']
      || Iterators[classof(it)];
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/get-substitution.js":
  /*!************************************************************!*\
    !*** ./node_modules/core-js/internals/get-substitution.js ***!
    \************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  
  var floor = Math.floor;
  var replace = ''.replace;
  var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g;
  var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g;
  
  // https://tc39.es/ecma262/#sec-getsubstitution
  module.exports = function (matched, str, position, captures, namedCaptures, replacement) {
    var tailPos = position + matched.length;
    var m = captures.length;
    var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
    if (namedCaptures !== undefined) {
      namedCaptures = toObject(namedCaptures);
      symbols = SUBSTITUTION_SYMBOLS;
    }
    return replace.call(replacement, symbols, function (match, ch) {
      var capture;
      switch (ch.charAt(0)) {
        case '$': return '$';
        case '&': return matched;
        case '`': return str.slice(0, position);
        case "'": return str.slice(tailPos);
        case '<':
          capture = namedCaptures[ch.slice(1, -1)];
          break;
        default: // \d\d?
          var n = +ch;
          if (n === 0) return match;
          if (n > m) {
            var f = floor(n / 10);
            if (f === 0) return match;
            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
            return match;
          }
          capture = captures[n - 1];
      }
      return capture === undefined ? '' : capture;
    });
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/global.js":
  /*!**************************************************!*\
    !*** ./node_modules/core-js/internals/global.js ***!
    \**************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var check = function (it) {
    return it && it.Math == Math && it;
  };
  
  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
  module.exports =
    // eslint-disable-next-line es/no-global-this -- safe
    check(typeof globalThis == 'object' && globalThis) ||
    check(typeof window == 'object' && window) ||
    // eslint-disable-next-line no-restricted-globals -- safe
    check(typeof self == 'object' && self) ||
    check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||
    // eslint-disable-next-line no-new-func -- fallback
    (function () { return this; })() || Function('return this')();
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/has.js":
  /*!***********************************************!*\
    !*** ./node_modules/core-js/internals/has.js ***!
    \***********************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  
  var hasOwnProperty = {}.hasOwnProperty;
  
  module.exports = function hasOwn(it, key) {
    return hasOwnProperty.call(toObject(it), key);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/hidden-keys.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/hidden-keys.js ***!
    \*******************************************************/
  /***/ (function(module) {
  
  module.exports = {};
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/html.js":
  /*!************************************************!*\
    !*** ./node_modules/core-js/internals/html.js ***!
    \************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "./node_modules/core-js/internals/get-built-in.js");
  
  module.exports = getBuiltIn('document', 'documentElement');
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/ie8-dom-define.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/ie8-dom-define.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var createElement = __webpack_require__(/*! ../internals/document-create-element */ "./node_modules/core-js/internals/document-create-element.js");
  
  // Thank's IE8 for his funny defineProperty
  module.exports = !DESCRIPTORS && !fails(function () {
    // eslint-disable-next-line es/no-object-defineproperty -- requied for testing
    return Object.defineProperty(createElement('div'), 'a', {
      get: function () { return 7; }
    }).a != 7;
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/indexed-object.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/indexed-object.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var classof = __webpack_require__(/*! ../internals/classof-raw */ "./node_modules/core-js/internals/classof-raw.js");
  
  var split = ''.split;
  
  // fallback for non-array-like ES3 and non-enumerable old V8 strings
  module.exports = fails(function () {
    // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
    // eslint-disable-next-line no-prototype-builtins -- safe
    return !Object('z').propertyIsEnumerable(0);
  }) ? function (it) {
    return classof(it) == 'String' ? split.call(it, '') : Object(it);
  } : Object;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/inherit-if-required.js":
  /*!***************************************************************!*\
    !*** ./node_modules/core-js/internals/inherit-if-required.js ***!
    \***************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var setPrototypeOf = __webpack_require__(/*! ../internals/object-set-prototype-of */ "./node_modules/core-js/internals/object-set-prototype-of.js");
  
  // makes subclassing work correct for wrapped built-ins
  module.exports = function ($this, dummy, Wrapper) {
    var NewTarget, NewTargetPrototype;
    if (
      // it can work only with native `setPrototypeOf`
      setPrototypeOf &&
      // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
      typeof (NewTarget = dummy.constructor) == 'function' &&
      NewTarget !== Wrapper &&
      isObject(NewTargetPrototype = NewTarget.prototype) &&
      NewTargetPrototype !== Wrapper.prototype
    ) setPrototypeOf($this, NewTargetPrototype);
    return $this;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/inspect-source.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/inspect-source.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var store = __webpack_require__(/*! ../internals/shared-store */ "./node_modules/core-js/internals/shared-store.js");
  
  var functionToString = Function.toString;
  
  // this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
  if (typeof store.inspectSource != 'function') {
    store.inspectSource = function (it) {
      return functionToString.call(it);
    };
  }
  
  module.exports = store.inspectSource;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/internal-metadata.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/internal-metadata.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "./node_modules/core-js/internals/hidden-keys.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var defineProperty = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js").f;
  var uid = __webpack_require__(/*! ../internals/uid */ "./node_modules/core-js/internals/uid.js");
  var FREEZING = __webpack_require__(/*! ../internals/freezing */ "./node_modules/core-js/internals/freezing.js");
  
  var METADATA = uid('meta');
  var id = 0;
  
  // eslint-disable-next-line es/no-object-isextensible -- safe
  var isExtensible = Object.isExtensible || function () {
    return true;
  };
  
  var setMetadata = function (it) {
    defineProperty(it, METADATA, { value: {
      objectID: 'O' + ++id, // object ID
      weakData: {}          // weak collections IDs
    } });
  };
  
  var fastKey = function (it, create) {
    // return a primitive with prefix
    if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
    if (!has(it, METADATA)) {
      // can't set metadata to uncaught frozen object
      if (!isExtensible(it)) return 'F';
      // not necessary to add metadata
      if (!create) return 'E';
      // add missing metadata
      setMetadata(it);
    // return object ID
    } return it[METADATA].objectID;
  };
  
  var getWeakData = function (it, create) {
    if (!has(it, METADATA)) {
      // can't set metadata to uncaught frozen object
      if (!isExtensible(it)) return true;
      // not necessary to add metadata
      if (!create) return false;
      // add missing metadata
      setMetadata(it);
    // return the store of weak collections IDs
    } return it[METADATA].weakData;
  };
  
  // add metadata on freeze-family methods calling
  var onFreeze = function (it) {
    if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
    return it;
  };
  
  var meta = module.exports = {
    REQUIRED: false,
    fastKey: fastKey,
    getWeakData: getWeakData,
    onFreeze: onFreeze
  };
  
  hiddenKeys[METADATA] = true;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/internal-state.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/internal-state.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/native-weak-map */ "./node_modules/core-js/internals/native-weak-map.js");
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var objectHas = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var shared = __webpack_require__(/*! ../internals/shared-store */ "./node_modules/core-js/internals/shared-store.js");
  var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "./node_modules/core-js/internals/shared-key.js");
  var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "./node_modules/core-js/internals/hidden-keys.js");
  
  var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
  var WeakMap = global.WeakMap;
  var set, get, has;
  
  var enforce = function (it) {
    return has(it) ? get(it) : set(it, {});
  };
  
  var getterFor = function (TYPE) {
    return function (it) {
      var state;
      if (!isObject(it) || (state = get(it)).type !== TYPE) {
        throw TypeError('Incompatible receiver, ' + TYPE + ' required');
      } return state;
    };
  };
  
  if (NATIVE_WEAK_MAP) {
    var store = shared.state || (shared.state = new WeakMap());
    var wmget = store.get;
    var wmhas = store.has;
    var wmset = store.set;
    set = function (it, metadata) {
      if (wmhas.call(store, it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
      metadata.facade = it;
      wmset.call(store, it, metadata);
      return metadata;
    };
    get = function (it) {
      return wmget.call(store, it) || {};
    };
    has = function (it) {
      return wmhas.call(store, it);
    };
  } else {
    var STATE = sharedKey('state');
    hiddenKeys[STATE] = true;
    set = function (it, metadata) {
      if (objectHas(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
      metadata.facade = it;
      createNonEnumerableProperty(it, STATE, metadata);
      return metadata;
    };
    get = function (it) {
      return objectHas(it, STATE) ? it[STATE] : {};
    };
    has = function (it) {
      return objectHas(it, STATE);
    };
  }
  
  module.exports = {
    set: set,
    get: get,
    has: has,
    enforce: enforce,
    getterFor: getterFor
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/is-array-iterator-method.js":
  /*!********************************************************************!*\
    !*** ./node_modules/core-js/internals/is-array-iterator-method.js ***!
    \********************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var Iterators = __webpack_require__(/*! ../internals/iterators */ "./node_modules/core-js/internals/iterators.js");
  
  var ITERATOR = wellKnownSymbol('iterator');
  var ArrayPrototype = Array.prototype;
  
  // check on default Array iterator
  module.exports = function (it) {
    return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/is-array.js":
  /*!****************************************************!*\
    !*** ./node_modules/core-js/internals/is-array.js ***!
    \****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var classof = __webpack_require__(/*! ../internals/classof-raw */ "./node_modules/core-js/internals/classof-raw.js");
  
  // `IsArray` abstract operation
  // https://tc39.es/ecma262/#sec-isarray
  // eslint-disable-next-line es/no-array-isarray -- safe
  module.exports = Array.isArray || function isArray(arg) {
    return classof(arg) == 'Array';
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/is-forced.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/is-forced.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  var replacement = /#|\.prototype\./;
  
  var isForced = function (feature, detection) {
    var value = data[normalize(feature)];
    return value == POLYFILL ? true
      : value == NATIVE ? false
      : typeof detection == 'function' ? fails(detection)
      : !!detection;
  };
  
  var normalize = isForced.normalize = function (string) {
    return String(string).replace(replacement, '.').toLowerCase();
  };
  
  var data = isForced.data = {};
  var NATIVE = isForced.NATIVE = 'N';
  var POLYFILL = isForced.POLYFILL = 'P';
  
  module.exports = isForced;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/is-object.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/is-object.js ***!
    \*****************************************************/
  /***/ (function(module) {
  
  module.exports = function (it) {
    return typeof it === 'object' ? it !== null : typeof it === 'function';
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/is-pure.js":
  /*!***************************************************!*\
    !*** ./node_modules/core-js/internals/is-pure.js ***!
    \***************************************************/
  /***/ (function(module) {
  
  module.exports = false;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/iterate.js":
  /*!***************************************************!*\
    !*** ./node_modules/core-js/internals/iterate.js ***!
    \***************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var isArrayIteratorMethod = __webpack_require__(/*! ../internals/is-array-iterator-method */ "./node_modules/core-js/internals/is-array-iterator-method.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  var bind = __webpack_require__(/*! ../internals/function-bind-context */ "./node_modules/core-js/internals/function-bind-context.js");
  var getIteratorMethod = __webpack_require__(/*! ../internals/get-iterator-method */ "./node_modules/core-js/internals/get-iterator-method.js");
  var iteratorClose = __webpack_require__(/*! ../internals/iterator-close */ "./node_modules/core-js/internals/iterator-close.js");
  
  var Result = function (stopped, result) {
    this.stopped = stopped;
    this.result = result;
  };
  
  module.exports = function (iterable, unboundFunction, options) {
    var that = options && options.that;
    var AS_ENTRIES = !!(options && options.AS_ENTRIES);
    var IS_ITERATOR = !!(options && options.IS_ITERATOR);
    var INTERRUPTED = !!(options && options.INTERRUPTED);
    var fn = bind(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED);
    var iterator, iterFn, index, length, result, next, step;
  
    var stop = function (condition) {
      if (iterator) iteratorClose(iterator);
      return new Result(true, condition);
    };
  
    var callFn = function (value) {
      if (AS_ENTRIES) {
        anObject(value);
        return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
      } return INTERRUPTED ? fn(value, stop) : fn(value);
    };
  
    if (IS_ITERATOR) {
      iterator = iterable;
    } else {
      iterFn = getIteratorMethod(iterable);
      if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
      // optimisation for array iterators
      if (isArrayIteratorMethod(iterFn)) {
        for (index = 0, length = toLength(iterable.length); length > index; index++) {
          result = callFn(iterable[index]);
          if (result && result instanceof Result) return result;
        } return new Result(false);
      }
      iterator = iterFn.call(iterable);
    }
  
    next = iterator.next;
    while (!(step = next.call(iterator)).done) {
      try {
        result = callFn(step.value);
      } catch (error) {
        iteratorClose(iterator);
        throw error;
      }
      if (typeof result == 'object' && result && result instanceof Result) return result;
    } return new Result(false);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/iterator-close.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/iterator-close.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  
  module.exports = function (iterator) {
    var returnMethod = iterator['return'];
    if (returnMethod !== undefined) {
      return anObject(returnMethod.call(iterator)).value;
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/iterators-core.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/internals/iterators-core.js ***!
    \**********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var getPrototypeOf = __webpack_require__(/*! ../internals/object-get-prototype-of */ "./node_modules/core-js/internals/object-get-prototype-of.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "./node_modules/core-js/internals/is-pure.js");
  
  var ITERATOR = wellKnownSymbol('iterator');
  var BUGGY_SAFARI_ITERATORS = false;
  
  var returnThis = function () { return this; };
  
  // `%IteratorPrototype%` object
  // https://tc39.es/ecma262/#sec-%iteratorprototype%-object
  var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;
  
  /* eslint-disable es/no-array-prototype-keys -- safe */
  if ([].keys) {
    arrayIterator = [].keys();
    // Safari 8 has buggy iterators w/o `next`
    if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
    else {
      PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));
      if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
    }
  }
  
  var NEW_ITERATOR_PROTOTYPE = IteratorPrototype == undefined || fails(function () {
    var test = {};
    // FF44- legacy iterators case
    return IteratorPrototype[ITERATOR].call(test) !== test;
  });
  
  if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {};
  
  // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
  if ((!IS_PURE || NEW_ITERATOR_PROTOTYPE) && !has(IteratorPrototype, ITERATOR)) {
    createNonEnumerableProperty(IteratorPrototype, ITERATOR, returnThis);
  }
  
  module.exports = {
    IteratorPrototype: IteratorPrototype,
    BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/iterators.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/iterators.js ***!
    \*****************************************************/
  /***/ (function(module) {
  
  module.exports = {};
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/native-symbol.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/internals/native-symbol.js ***!
    \*********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var IS_NODE = __webpack_require__(/*! ../internals/engine-is-node */ "./node_modules/core-js/internals/engine-is-node.js");
  var V8_VERSION = __webpack_require__(/*! ../internals/engine-v8-version */ "./node_modules/core-js/internals/engine-v8-version.js");
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  
  // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
  module.exports = !!Object.getOwnPropertySymbols && !fails(function () {
    // eslint-disable-next-line es/no-symbol -- required for testing
    return !Symbol.sham &&
      // Chrome 38 Symbol has incorrect toString conversion
      // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
      (IS_NODE ? V8_VERSION === 38 : V8_VERSION > 37 && V8_VERSION < 41);
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/native-weak-map.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/internals/native-weak-map.js ***!
    \***********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var inspectSource = __webpack_require__(/*! ../internals/inspect-source */ "./node_modules/core-js/internals/inspect-source.js");
  
  var WeakMap = global.WeakMap;
  
  module.exports = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/number-parse-int.js":
  /*!************************************************************!*\
    !*** ./node_modules/core-js/internals/number-parse-int.js ***!
    \************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var trim = __webpack_require__(/*! ../internals/string-trim */ "./node_modules/core-js/internals/string-trim.js").trim;
  var whitespaces = __webpack_require__(/*! ../internals/whitespaces */ "./node_modules/core-js/internals/whitespaces.js");
  
  var $parseInt = global.parseInt;
  var hex = /^[+-]?0[Xx]/;
  var FORCED = $parseInt(whitespaces + '08') !== 8 || $parseInt(whitespaces + '0x16') !== 22;
  
  // `parseInt` method
  // https://tc39.es/ecma262/#sec-parseint-string-radix
  module.exports = FORCED ? function parseInt(string, radix) {
    var S = trim(String(string));
    return $parseInt(S, (radix >>> 0) || (hex.test(S) ? 16 : 10));
  } : $parseInt;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-assign.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/internals/object-assign.js ***!
    \*********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var fails = __webpack_require__(/*! ../internals/fails */ "./node_modules/core-js/internals/fails.js");
  var objectKeys = __webpack_require__(/*! ../internals/object-keys */ "./node_modules/core-js/internals/object-keys.js");
  var getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ "./node_modules/core-js/internals/object-get-own-property-symbols.js");
  var propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ "./node_modules/core-js/internals/object-property-is-enumerable.js");
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "./node_modules/core-js/internals/indexed-object.js");
  
  // eslint-disable-next-line es/no-object-assign -- safe
  var $assign = Object.assign;
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
  var defineProperty = Object.defineProperty;
  
  // `Object.assign` method
  // https://tc39.es/ecma262/#sec-object.assign
  module.exports = !$assign || fails(function () {
    // should have correct order of operations (Edge bug)
    if (DESCRIPTORS && $assign({ b: 1 }, $assign(defineProperty({}, 'a', {
      enumerable: true,
      get: function () {
        defineProperty(this, 'b', {
          value: 3,
          enumerable: false
        });
      }
    }), { b: 2 })).b !== 1) return true;
    // should work with symbols and should have deterministic property order (V8 bug)
    var A = {};
    var B = {};
    // eslint-disable-next-line es/no-symbol -- safe
    var symbol = Symbol();
    var alphabet = 'abcdefghijklmnopqrst';
    A[symbol] = 7;
    alphabet.split('').forEach(function (chr) { B[chr] = chr; });
    return $assign({}, A)[symbol] != 7 || objectKeys($assign({}, B)).join('') != alphabet;
  }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length`
    var T = toObject(target);
    var argumentsLength = arguments.length;
    var index = 1;
    var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
    var propertyIsEnumerable = propertyIsEnumerableModule.f;
    while (argumentsLength > index) {
      var S = IndexedObject(arguments[index++]);
      var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
      var length = keys.length;
      var j = 0;
      var key;
      while (length > j) {
        key = keys[j++];
        if (!DESCRIPTORS || propertyIsEnumerable.call(S, key)) T[key] = S[key];
      }
    } return T;
  } : $assign;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-create.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/internals/object-create.js ***!
    \*********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var defineProperties = __webpack_require__(/*! ../internals/object-define-properties */ "./node_modules/core-js/internals/object-define-properties.js");
  var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "./node_modules/core-js/internals/enum-bug-keys.js");
  var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "./node_modules/core-js/internals/hidden-keys.js");
  var html = __webpack_require__(/*! ../internals/html */ "./node_modules/core-js/internals/html.js");
  var documentCreateElement = __webpack_require__(/*! ../internals/document-create-element */ "./node_modules/core-js/internals/document-create-element.js");
  var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "./node_modules/core-js/internals/shared-key.js");
  
  var GT = '>';
  var LT = '<';
  var PROTOTYPE = 'prototype';
  var SCRIPT = 'script';
  var IE_PROTO = sharedKey('IE_PROTO');
  
  var EmptyConstructor = function () { /* empty */ };
  
  var scriptTag = function (content) {
    return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
  };
  
  // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
  var NullProtoObjectViaActiveX = function (activeXDocument) {
    activeXDocument.write(scriptTag(''));
    activeXDocument.close();
    var temp = activeXDocument.parentWindow.Object;
    activeXDocument = null; // avoid memory leak
    return temp;
  };
  
  // Create object with fake `null` prototype: use iframe Object with cleared prototype
  var NullProtoObjectViaIFrame = function () {
    // Thrash, waste and sodomy: IE GC bug
    var iframe = documentCreateElement('iframe');
    var JS = 'java' + SCRIPT + ':';
    var iframeDocument;
    iframe.style.display = 'none';
    html.appendChild(iframe);
    // https://github.com/zloirock/core-js/issues/475
    iframe.src = String(JS);
    iframeDocument = iframe.contentWindow.document;
    iframeDocument.open();
    iframeDocument.write(scriptTag('document.F=Object'));
    iframeDocument.close();
    return iframeDocument.F;
  };
  
  // Check for document.domain and active x support
  // No need to use active x approach when document.domain is not set
  // see https://github.com/es-shims/es5-shim/issues/150
  // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
  // avoid IE GC bug
  var activeXDocument;
  var NullProtoObject = function () {
    try {
      /* global ActiveXObject -- old IE */
      activeXDocument = document.domain && new ActiveXObject('htmlfile');
    } catch (error) { /* ignore */ }
    NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
    var length = enumBugKeys.length;
    while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
    return NullProtoObject();
  };
  
  hiddenKeys[IE_PROTO] = true;
  
  // `Object.create` method
  // https://tc39.es/ecma262/#sec-object.create
  module.exports = Object.create || function create(O, Properties) {
    var result;
    if (O !== null) {
      EmptyConstructor[PROTOTYPE] = anObject(O);
      result = new EmptyConstructor();
      EmptyConstructor[PROTOTYPE] = null;
      // add "__proto__" for Object.getPrototypeOf polyfill
      result[IE_PROTO] = O;
    } else result = NullProtoObject();
    return Properties === undefined ? result : defineProperties(result, Properties);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-define-properties.js":
  /*!********************************************************************!*\
    !*** ./node_modules/core-js/internals/object-define-properties.js ***!
    \********************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js");
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var objectKeys = __webpack_require__(/*! ../internals/object-keys */ "./node_modules/core-js/internals/object-keys.js");
  
  // `Object.defineProperties` method
  // https://tc39.es/ecma262/#sec-object.defineproperties
  // eslint-disable-next-line es/no-object-defineproperties -- safe
  module.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) {
    anObject(O);
    var keys = objectKeys(Properties);
    var length = keys.length;
    var index = 0;
    var key;
    while (length > index) definePropertyModule.f(O, key = keys[index++], Properties[key]);
    return O;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-define-property.js":
  /*!******************************************************************!*\
    !*** ./node_modules/core-js/internals/object-define-property.js ***!
    \******************************************************************/
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "./node_modules/core-js/internals/ie8-dom-define.js");
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ "./node_modules/core-js/internals/to-primitive.js");
  
  // eslint-disable-next-line es/no-object-defineproperty -- safe
  var $defineProperty = Object.defineProperty;
  
  // `Object.defineProperty` method
  // https://tc39.es/ecma262/#sec-object.defineproperty
  exports.f = DESCRIPTORS ? $defineProperty : function defineProperty(O, P, Attributes) {
    anObject(O);
    P = toPrimitive(P, true);
    anObject(Attributes);
    if (IE8_DOM_DEFINE) try {
      return $defineProperty(O, P, Attributes);
    } catch (error) { /* empty */ }
    if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
    if ('value' in Attributes) O[P] = Attributes.value;
    return O;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-get-own-property-descriptor.js":
  /*!******************************************************************************!*\
    !*** ./node_modules/core-js/internals/object-get-own-property-descriptor.js ***!
    \******************************************************************************/
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ "./node_modules/core-js/internals/object-property-is-enumerable.js");
  var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "./node_modules/core-js/internals/create-property-descriptor.js");
  var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "./node_modules/core-js/internals/to-indexed-object.js");
  var toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ "./node_modules/core-js/internals/to-primitive.js");
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "./node_modules/core-js/internals/ie8-dom-define.js");
  
  // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
  var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  
  // `Object.getOwnPropertyDescriptor` method
  // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
  exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
    O = toIndexedObject(O);
    P = toPrimitive(P, true);
    if (IE8_DOM_DEFINE) try {
      return $getOwnPropertyDescriptor(O, P);
    } catch (error) { /* empty */ }
    if (has(O, P)) return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-get-own-property-names.js":
  /*!*************************************************************************!*\
    !*** ./node_modules/core-js/internals/object-get-own-property-names.js ***!
    \*************************************************************************/
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
  
  var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ "./node_modules/core-js/internals/object-keys-internal.js");
  var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "./node_modules/core-js/internals/enum-bug-keys.js");
  
  var hiddenKeys = enumBugKeys.concat('length', 'prototype');
  
  // `Object.getOwnPropertyNames` method
  // https://tc39.es/ecma262/#sec-object.getownpropertynames
  // eslint-disable-next-line es/no-object-getownpropertynames -- safe
  exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
    return internalObjectKeys(O, hiddenKeys);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-get-own-property-symbols.js":
  /*!***************************************************************************!*\
    !*** ./node_modules/core-js/internals/object-get-own-property-symbols.js ***!
    \***************************************************************************/
  /***/ (function(__unused_webpack_module, exports) {
  
  // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
  exports.f = Object.getOwnPropertySymbols;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-get-prototype-of.js":
  /*!*******************************************************************!*\
    !*** ./node_modules/core-js/internals/object-get-prototype-of.js ***!
    \*******************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var toObject = __webpack_require__(/*! ../internals/to-object */ "./node_modules/core-js/internals/to-object.js");
  var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "./node_modules/core-js/internals/shared-key.js");
  var CORRECT_PROTOTYPE_GETTER = __webpack_require__(/*! ../internals/correct-prototype-getter */ "./node_modules/core-js/internals/correct-prototype-getter.js");
  
  var IE_PROTO = sharedKey('IE_PROTO');
  var ObjectPrototype = Object.prototype;
  
  // `Object.getPrototypeOf` method
  // https://tc39.es/ecma262/#sec-object.getprototypeof
  // eslint-disable-next-line es/no-object-getprototypeof -- safe
  module.exports = CORRECT_PROTOTYPE_GETTER ? Object.getPrototypeOf : function (O) {
    O = toObject(O);
    if (has(O, IE_PROTO)) return O[IE_PROTO];
    if (typeof O.constructor == 'function' && O instanceof O.constructor) {
      return O.constructor.prototype;
    } return O instanceof Object ? ObjectPrototype : null;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-keys-internal.js":
  /*!****************************************************************!*\
    !*** ./node_modules/core-js/internals/object-keys-internal.js ***!
    \****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "./node_modules/core-js/internals/to-indexed-object.js");
  var indexOf = __webpack_require__(/*! ../internals/array-includes */ "./node_modules/core-js/internals/array-includes.js").indexOf;
  var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "./node_modules/core-js/internals/hidden-keys.js");
  
  module.exports = function (object, names) {
    var O = toIndexedObject(object);
    var i = 0;
    var result = [];
    var key;
    for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
    // Don't enum bug & hidden keys
    while (names.length > i) if (has(O, key = names[i++])) {
      ~indexOf(result, key) || result.push(key);
    }
    return result;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-keys.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/object-keys.js ***!
    \*******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ "./node_modules/core-js/internals/object-keys-internal.js");
  var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "./node_modules/core-js/internals/enum-bug-keys.js");
  
  // `Object.keys` method
  // https://tc39.es/ecma262/#sec-object.keys
  // eslint-disable-next-line es/no-object-keys -- safe
  module.exports = Object.keys || function keys(O) {
    return internalObjectKeys(O, enumBugKeys);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-property-is-enumerable.js":
  /*!*************************************************************************!*\
    !*** ./node_modules/core-js/internals/object-property-is-enumerable.js ***!
    \*************************************************************************/
  /***/ (function(__unused_webpack_module, exports) {
  
  "use strict";
  
  var $propertyIsEnumerable = {}.propertyIsEnumerable;
  // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  
  // Nashorn ~ JDK8 bug
  var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);
  
  // `Object.prototype.propertyIsEnumerable` method implementation
  // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
  exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
    var descriptor = getOwnPropertyDescriptor(this, V);
    return !!descriptor && descriptor.enumerable;
  } : $propertyIsEnumerable;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-set-prototype-of.js":
  /*!*******************************************************************!*\
    !*** ./node_modules/core-js/internals/object-set-prototype-of.js ***!
    \*******************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  /* eslint-disable no-proto -- safe */
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var aPossiblePrototype = __webpack_require__(/*! ../internals/a-possible-prototype */ "./node_modules/core-js/internals/a-possible-prototype.js");
  
  // `Object.setPrototypeOf` method
  // https://tc39.es/ecma262/#sec-object.setprototypeof
  // Works with __proto__ only. Old v8 can't work with null proto objects.
  // eslint-disable-next-line es/no-object-setprototypeof -- safe
  module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {
    var CORRECT_SETTER = false;
    var test = {};
    var setter;
    try {
      // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
      setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
      setter.call(test, []);
      CORRECT_SETTER = test instanceof Array;
    } catch (error) { /* empty */ }
    return function setPrototypeOf(O, proto) {
      anObject(O);
      aPossiblePrototype(proto);
      if (CORRECT_SETTER) setter.call(O, proto);
      else O.__proto__ = proto;
      return O;
    };
  }() : undefined);
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/object-to-string.js":
  /*!************************************************************!*\
    !*** ./node_modules/core-js/internals/object-to-string.js ***!
    \************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var TO_STRING_TAG_SUPPORT = __webpack_require__(/*! ../internals/to-string-tag-support */ "./node_modules/core-js/internals/to-string-tag-support.js");
  var classof = __webpack_require__(/*! ../internals/classof */ "./node_modules/core-js/internals/classof.js");
  
  // `Object.prototype.toString` method implementation
  // https://tc39.es/ecma262/#sec-object.prototype.tostring
  module.exports = TO_STRING_TAG_SUPPORT ? {}.toString : function toString() {
    return '[object ' + classof(this) + ']';
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/own-keys.js":
  /*!****************************************************!*\
    !*** ./node_modules/core-js/internals/own-keys.js ***!
    \****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "./node_modules/core-js/internals/get-built-in.js");
  var getOwnPropertyNamesModule = __webpack_require__(/*! ../internals/object-get-own-property-names */ "./node_modules/core-js/internals/object-get-own-property-names.js");
  var getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ "./node_modules/core-js/internals/object-get-own-property-symbols.js");
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  
  // all object keys, includes non-enumerable and symbols
  module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
    var keys = getOwnPropertyNamesModule.f(anObject(it));
    var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
    return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/path.js":
  /*!************************************************!*\
    !*** ./node_modules/core-js/internals/path.js ***!
    \************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  
  module.exports = global;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/redefine-all.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/redefine-all.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  
  module.exports = function (target, src, options) {
    for (var key in src) redefine(target, key, src[key], options);
    return target;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/redefine.js":
  /*!****************************************************!*\
    !*** ./node_modules/core-js/internals/redefine.js ***!
    \****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var setGlobal = __webpack_require__(/*! ../internals/set-global */ "./node_modules/core-js/internals/set-global.js");
  var inspectSource = __webpack_require__(/*! ../internals/inspect-source */ "./node_modules/core-js/internals/inspect-source.js");
  var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "./node_modules/core-js/internals/internal-state.js");
  
  var getInternalState = InternalStateModule.get;
  var enforceInternalState = InternalStateModule.enforce;
  var TEMPLATE = String(String).split('String');
  
  (module.exports = function (O, key, value, options) {
    var unsafe = options ? !!options.unsafe : false;
    var simple = options ? !!options.enumerable : false;
    var noTargetGet = options ? !!options.noTargetGet : false;
    var state;
    if (typeof value == 'function') {
      if (typeof key == 'string' && !has(value, 'name')) {
        createNonEnumerableProperty(value, 'name', key);
      }
      state = enforceInternalState(value);
      if (!state.source) {
        state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
      }
    }
    if (O === global) {
      if (simple) O[key] = value;
      else setGlobal(key, value);
      return;
    } else if (!unsafe) {
      delete O[key];
    } else if (!noTargetGet && O[key]) {
      simple = true;
    }
    if (simple) O[key] = value;
    else createNonEnumerableProperty(O, key, value);
  // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
  })(Function.prototype, 'toString', function toString() {
    return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/regexp-exec-abstract.js":
  /*!****************************************************************!*\
    !*** ./node_modules/core-js/internals/regexp-exec-abstract.js ***!
    \****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var classof = __webpack_require__(/*! ./classof-raw */ "./node_modules/core-js/internals/classof-raw.js");
  var regexpExec = __webpack_require__(/*! ./regexp-exec */ "./node_modules/core-js/internals/regexp-exec.js");
  
  // `RegExpExec` abstract operation
  // https://tc39.es/ecma262/#sec-regexpexec
  module.exports = function (R, S) {
    var exec = R.exec;
    if (typeof exec === 'function') {
      var result = exec.call(R, S);
      if (typeof result !== 'object') {
        throw TypeError('RegExp exec method returned something other than an Object or null');
      }
      return result;
    }
  
    if (classof(R) !== 'RegExp') {
      throw TypeError('RegExp#exec called on incompatible receiver');
    }
  
    return regexpExec.call(R, S);
  };
  
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/regexp-exec.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/regexp-exec.js ***!
    \*******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var regexpFlags = __webpack_require__(/*! ./regexp-flags */ "./node_modules/core-js/internals/regexp-flags.js");
  var stickyHelpers = __webpack_require__(/*! ./regexp-sticky-helpers */ "./node_modules/core-js/internals/regexp-sticky-helpers.js");
  var shared = __webpack_require__(/*! ./shared */ "./node_modules/core-js/internals/shared.js");
  
  var nativeExec = RegExp.prototype.exec;
  var nativeReplace = shared('native-string-replace', String.prototype.replace);
  
  var patchedExec = nativeExec;
  
  var UPDATES_LAST_INDEX_WRONG = (function () {
    var re1 = /a/;
    var re2 = /b*/g;
    nativeExec.call(re1, 'a');
    nativeExec.call(re2, 'a');
    return re1.lastIndex !== 0 || re2.lastIndex !== 0;
  })();
  
  var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y || stickyHelpers.BROKEN_CARET;
  
  // nonparticipating capturing group, copied from es5-shim's String#split patch.
  // eslint-disable-next-line regexp/no-assertion-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing
  var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
  
  var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y;
  
  if (PATCH) {
    patchedExec = function exec(str) {
      var re = this;
      var lastIndex, reCopy, match, i;
      var sticky = UNSUPPORTED_Y && re.sticky;
      var flags = regexpFlags.call(re);
      var source = re.source;
      var charsAdded = 0;
      var strCopy = str;
  
      if (sticky) {
        flags = flags.replace('y', '');
        if (flags.indexOf('g') === -1) {
          flags += 'g';
        }
  
        strCopy = String(str).slice(re.lastIndex);
        // Support anchored sticky behavior.
        if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\n')) {
          source = '(?: ' + source + ')';
          strCopy = ' ' + strCopy;
          charsAdded++;
        }
        // ^(? + rx + ) is needed, in combination with some str slicing, to
        // simulate the 'y' flag.
        reCopy = new RegExp('^(?:' + source + ')', flags);
      }
  
      if (NPCG_INCLUDED) {
        reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
      }
      if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
  
      match = nativeExec.call(sticky ? reCopy : re, strCopy);
  
      if (sticky) {
        if (match) {
          match.input = match.input.slice(charsAdded);
          match[0] = match[0].slice(charsAdded);
          match.index = re.lastIndex;
          re.lastIndex += match[0].length;
        } else re.lastIndex = 0;
      } else if (UPDATES_LAST_INDEX_WRONG && match) {
        re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
      }
      if (NPCG_INCLUDED && match && match.length > 1) {
        // Fix browsers whose `exec` methods don't consistently return `undefined`
        // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
        nativeReplace.call(match[0], reCopy, function () {
          for (i = 1; i < arguments.length - 2; i++) {
            if (arguments[i] === undefined) match[i] = undefined;
          }
        });
      }
  
      return match;
    };
  }
  
  module.exports = patchedExec;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/regexp-flags.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/regexp-flags.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  
  // `RegExp.prototype.flags` getter implementation
  // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
  module.exports = function () {
    var that = anObject(this);
    var result = '';
    if (that.global) result += 'g';
    if (that.ignoreCase) result += 'i';
    if (that.multiline) result += 'm';
    if (that.dotAll) result += 's';
    if (that.unicode) result += 'u';
    if (that.sticky) result += 'y';
    return result;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/regexp-sticky-helpers.js":
  /*!*****************************************************************!*\
    !*** ./node_modules/core-js/internals/regexp-sticky-helpers.js ***!
    \*****************************************************************/
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
  
  "use strict";
  
  
  var fails = __webpack_require__(/*! ./fails */ "./node_modules/core-js/internals/fails.js");
  
  // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError,
  // so we use an intermediate function.
  function RE(s, f) {
    return RegExp(s, f);
  }
  
  exports.UNSUPPORTED_Y = fails(function () {
    // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
    var re = RE('a', 'y');
    re.lastIndex = 2;
    return re.exec('abcd') != null;
  });
  
  exports.BROKEN_CARET = fails(function () {
    // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
    var re = RE('^r', 'gy');
    re.lastIndex = 2;
    return re.exec('str') != null;
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/require-object-coercible.js":
  /*!********************************************************************!*\
    !*** ./node_modules/core-js/internals/require-object-coercible.js ***!
    \********************************************************************/
  /***/ (function(module) {
  
  // `RequireObjectCoercible` abstract operation
  // https://tc39.es/ecma262/#sec-requireobjectcoercible
  module.exports = function (it) {
    if (it == undefined) throw TypeError("Can't call method on " + it);
    return it;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/set-global.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/internals/set-global.js ***!
    \******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  
  module.exports = function (key, value) {
    try {
      createNonEnumerableProperty(global, key, value);
    } catch (error) {
      global[key] = value;
    } return value;
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/set-to-string-tag.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/set-to-string-tag.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var defineProperty = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js").f;
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  
  module.exports = function (it, TAG, STATIC) {
    if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
      defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG });
    }
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/shared-key.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/internals/shared-key.js ***!
    \******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var shared = __webpack_require__(/*! ../internals/shared */ "./node_modules/core-js/internals/shared.js");
  var uid = __webpack_require__(/*! ../internals/uid */ "./node_modules/core-js/internals/uid.js");
  
  var keys = shared('keys');
  
  module.exports = function (key) {
    return keys[key] || (keys[key] = uid(key));
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/shared-store.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/shared-store.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var setGlobal = __webpack_require__(/*! ../internals/set-global */ "./node_modules/core-js/internals/set-global.js");
  
  var SHARED = '__core-js_shared__';
  var store = global[SHARED] || setGlobal(SHARED, {});
  
  module.exports = store;
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/shared.js":
  /*!**************************************************!*\
    !*** ./node_modules/core-js/internals/shared.js ***!
    \**************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "./node_modules/core-js/internals/is-pure.js");
  var store = __webpack_require__(/*! ../internals/shared-store */ "./node_modules/core-js/internals/shared-store.js");
  
  (module.exports = function (key, value) {
    return store[key] || (store[key] = value !== undefined ? value : {});
  })('versions', []).push({
    version: '3.11.0',
    mode: IS_PURE ? 'pure' : 'global',
    copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/string-multibyte.js":
  /*!************************************************************!*\
    !*** ./node_modules/core-js/internals/string-multibyte.js ***!
    \************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toInteger = __webpack_require__(/*! ../internals/to-integer */ "./node_modules/core-js/internals/to-integer.js");
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  
  // `String.prototype.{ codePointAt, at }` methods implementation
  var createMethod = function (CONVERT_TO_STRING) {
    return function ($this, pos) {
      var S = String(requireObjectCoercible($this));
      var position = toInteger(pos);
      var size = S.length;
      var first, second;
      if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
      first = S.charCodeAt(position);
      return first < 0xD800 || first > 0xDBFF || position + 1 === size
        || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
          ? CONVERT_TO_STRING ? S.charAt(position) : first
          : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
    };
  };
  
  module.exports = {
    // `String.prototype.codePointAt` method
    // https://tc39.es/ecma262/#sec-string.prototype.codepointat
    codeAt: createMethod(false),
    // `String.prototype.at` method
    // https://github.com/mathiasbynens/String.prototype.at
    charAt: createMethod(true)
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/string-trim.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/string-trim.js ***!
    \*******************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  var whitespaces = __webpack_require__(/*! ../internals/whitespaces */ "./node_modules/core-js/internals/whitespaces.js");
  
  var whitespace = '[' + whitespaces + ']';
  var ltrim = RegExp('^' + whitespace + whitespace + '*');
  var rtrim = RegExp(whitespace + whitespace + '*$');
  
  // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
  var createMethod = function (TYPE) {
    return function ($this) {
      var string = String(requireObjectCoercible($this));
      if (TYPE & 1) string = string.replace(ltrim, '');
      if (TYPE & 2) string = string.replace(rtrim, '');
      return string;
    };
  };
  
  module.exports = {
    // `String.prototype.{ trimLeft, trimStart }` methods
    // https://tc39.es/ecma262/#sec-string.prototype.trimstart
    start: createMethod(1),
    // `String.prototype.{ trimRight, trimEnd }` methods
    // https://tc39.es/ecma262/#sec-string.prototype.trimend
    end: createMethod(2),
    // `String.prototype.trim` method
    // https://tc39.es/ecma262/#sec-string.prototype.trim
    trim: createMethod(3)
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-absolute-index.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/to-absolute-index.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toInteger = __webpack_require__(/*! ../internals/to-integer */ "./node_modules/core-js/internals/to-integer.js");
  
  var max = Math.max;
  var min = Math.min;
  
  // Helper for a popular repeating case of the spec:
  // Let integer be ? ToInteger(index).
  // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
  module.exports = function (index, length) {
    var integer = toInteger(index);
    return integer < 0 ? max(integer + length, 0) : min(integer, length);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-indexed-object.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/to-indexed-object.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  // toObject with fallback for non-array-like ES3 strings
  var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "./node_modules/core-js/internals/indexed-object.js");
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  
  module.exports = function (it) {
    return IndexedObject(requireObjectCoercible(it));
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-integer.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/internals/to-integer.js ***!
    \******************************************************/
  /***/ (function(module) {
  
  var ceil = Math.ceil;
  var floor = Math.floor;
  
  // `ToInteger` abstract operation
  // https://tc39.es/ecma262/#sec-tointeger
  module.exports = function (argument) {
    return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-length.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/to-length.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var toInteger = __webpack_require__(/*! ../internals/to-integer */ "./node_modules/core-js/internals/to-integer.js");
  
  var min = Math.min;
  
  // `ToLength` abstract operation
  // https://tc39.es/ecma262/#sec-tolength
  module.exports = function (argument) {
    return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-object.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/internals/to-object.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  
  // `ToObject` abstract operation
  // https://tc39.es/ecma262/#sec-toobject
  module.exports = function (argument) {
    return Object(requireObjectCoercible(argument));
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-primitive.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/internals/to-primitive.js ***!
    \********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  
  // `ToPrimitive` abstract operation
  // https://tc39.es/ecma262/#sec-toprimitive
  // instead of the ES6 spec version, we didn't implement @@toPrimitive case
  // and the second argument - flag - preferred type is a string
  module.exports = function (input, PREFERRED_STRING) {
    if (!isObject(input)) return input;
    var fn, val;
    if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
    if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
    if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
    throw TypeError("Can't convert object to primitive value");
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/to-string-tag-support.js":
  /*!*****************************************************************!*\
    !*** ./node_modules/core-js/internals/to-string-tag-support.js ***!
    \*****************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  var test = {};
  
  test[TO_STRING_TAG] = 'z';
  
  module.exports = String(test) === '[object z]';
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/uid.js":
  /*!***********************************************!*\
    !*** ./node_modules/core-js/internals/uid.js ***!
    \***********************************************/
  /***/ (function(module) {
  
  var id = 0;
  var postfix = Math.random();
  
  module.exports = function (key) {
    return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/use-symbol-as-uid.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/use-symbol-as-uid.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  /* eslint-disable es/no-symbol -- required for testing */
  var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/native-symbol */ "./node_modules/core-js/internals/native-symbol.js");
  
  module.exports = NATIVE_SYMBOL
    && !Symbol.sham
    && typeof Symbol.iterator == 'symbol';
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/well-known-symbol.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/internals/well-known-symbol.js ***!
    \*************************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var shared = __webpack_require__(/*! ../internals/shared */ "./node_modules/core-js/internals/shared.js");
  var has = __webpack_require__(/*! ../internals/has */ "./node_modules/core-js/internals/has.js");
  var uid = __webpack_require__(/*! ../internals/uid */ "./node_modules/core-js/internals/uid.js");
  var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/native-symbol */ "./node_modules/core-js/internals/native-symbol.js");
  var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "./node_modules/core-js/internals/use-symbol-as-uid.js");
  
  var WellKnownSymbolsStore = shared('wks');
  var Symbol = global.Symbol;
  var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol : Symbol && Symbol.withoutSetter || uid;
  
  module.exports = function (name) {
    if (!has(WellKnownSymbolsStore, name) || !(NATIVE_SYMBOL || typeof WellKnownSymbolsStore[name] == 'string')) {
      if (NATIVE_SYMBOL && has(Symbol, name)) {
        WellKnownSymbolsStore[name] = Symbol[name];
      } else {
        WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
      }
    } return WellKnownSymbolsStore[name];
  };
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/internals/whitespaces.js":
  /*!*******************************************************!*\
    !*** ./node_modules/core-js/internals/whitespaces.js ***!
    \*******************************************************/
  /***/ (function(module) {
  
  // a string of all valid unicode whitespaces
  module.exports = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' +
    '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.array.filter.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/modules/es.array.filter.js ***!
    \*********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var $filter = __webpack_require__(/*! ../internals/array-iteration */ "./node_modules/core-js/internals/array-iteration.js").filter;
  var arrayMethodHasSpeciesSupport = __webpack_require__(/*! ../internals/array-method-has-species-support */ "./node_modules/core-js/internals/array-method-has-species-support.js");
  
  var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter');
  
  // `Array.prototype.filter` method
  // https://tc39.es/ecma262/#sec-array.prototype.filter
  // with adding support of @@species
  $({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
    filter: function filter(callbackfn /* , thisArg */) {
      return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    }
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.array.for-each.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/modules/es.array.for-each.js ***!
    \***********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var forEach = __webpack_require__(/*! ../internals/array-for-each */ "./node_modules/core-js/internals/array-for-each.js");
  
  // `Array.prototype.forEach` method
  // https://tc39.es/ecma262/#sec-array.prototype.foreach
  // eslint-disable-next-line es/no-array-prototype-foreach -- safe
  $({ target: 'Array', proto: true, forced: [].forEach != forEach }, {
    forEach: forEach
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.array.iterator.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/modules/es.array.iterator.js ***!
    \***********************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "./node_modules/core-js/internals/to-indexed-object.js");
  var addToUnscopables = __webpack_require__(/*! ../internals/add-to-unscopables */ "./node_modules/core-js/internals/add-to-unscopables.js");
  var Iterators = __webpack_require__(/*! ../internals/iterators */ "./node_modules/core-js/internals/iterators.js");
  var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "./node_modules/core-js/internals/internal-state.js");
  var defineIterator = __webpack_require__(/*! ../internals/define-iterator */ "./node_modules/core-js/internals/define-iterator.js");
  
  var ARRAY_ITERATOR = 'Array Iterator';
  var setInternalState = InternalStateModule.set;
  var getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);
  
  // `Array.prototype.entries` method
  // https://tc39.es/ecma262/#sec-array.prototype.entries
  // `Array.prototype.keys` method
  // https://tc39.es/ecma262/#sec-array.prototype.keys
  // `Array.prototype.values` method
  // https://tc39.es/ecma262/#sec-array.prototype.values
  // `Array.prototype[@@iterator]` method
  // https://tc39.es/ecma262/#sec-array.prototype-@@iterator
  // `CreateArrayIterator` internal method
  // https://tc39.es/ecma262/#sec-createarrayiterator
  module.exports = defineIterator(Array, 'Array', function (iterated, kind) {
    setInternalState(this, {
      type: ARRAY_ITERATOR,
      target: toIndexedObject(iterated), // target
      index: 0,                          // next index
      kind: kind                         // kind
    });
  // `%ArrayIteratorPrototype%.next` method
  // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
  }, function () {
    var state = getInternalState(this);
    var target = state.target;
    var kind = state.kind;
    var index = state.index++;
    if (!target || index >= target.length) {
      state.target = undefined;
      return { value: undefined, done: true };
    }
    if (kind == 'keys') return { value: index, done: false };
    if (kind == 'values') return { value: target[index], done: false };
    return { value: [index, target[index]], done: false };
  }, 'values');
  
  // argumentsList[@@iterator] is %ArrayProto_values%
  // https://tc39.es/ecma262/#sec-createunmappedargumentsobject
  // https://tc39.es/ecma262/#sec-createmappedargumentsobject
  Iterators.Arguments = Iterators.Array;
  
  // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
  addToUnscopables('keys');
  addToUnscopables('values');
  addToUnscopables('entries');
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.array.reduce.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/modules/es.array.reduce.js ***!
    \*********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var $reduce = __webpack_require__(/*! ../internals/array-reduce */ "./node_modules/core-js/internals/array-reduce.js").left;
  var arrayMethodIsStrict = __webpack_require__(/*! ../internals/array-method-is-strict */ "./node_modules/core-js/internals/array-method-is-strict.js");
  var CHROME_VERSION = __webpack_require__(/*! ../internals/engine-v8-version */ "./node_modules/core-js/internals/engine-v8-version.js");
  var IS_NODE = __webpack_require__(/*! ../internals/engine-is-node */ "./node_modules/core-js/internals/engine-is-node.js");
  
  var STRICT_METHOD = arrayMethodIsStrict('reduce');
  // Chrome 80-82 has a critical bug
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
  var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83;
  
  // `Array.prototype.reduce` method
  // https://tc39.es/ecma262/#sec-array.prototype.reduce
  $({ target: 'Array', proto: true, forced: !STRICT_METHOD || CHROME_BUG }, {
    reduce: function reduce(callbackfn /* , initialValue */) {
      return $reduce(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
    }
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.function.name.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/modules/es.function.name.js ***!
    \**********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "./node_modules/core-js/internals/descriptors.js");
  var defineProperty = __webpack_require__(/*! ../internals/object-define-property */ "./node_modules/core-js/internals/object-define-property.js").f;
  
  var FunctionPrototype = Function.prototype;
  var FunctionPrototypeToString = FunctionPrototype.toString;
  var nameRE = /^\s*function ([^ (]*)/;
  var NAME = 'name';
  
  // Function instances `.name` property
  // https://tc39.es/ecma262/#sec-function-instances-name
  if (DESCRIPTORS && !(NAME in FunctionPrototype)) {
    defineProperty(FunctionPrototype, NAME, {
      configurable: true,
      get: function () {
        try {
          return FunctionPrototypeToString.call(this).match(nameRE)[1];
        } catch (error) {
          return '';
        }
      }
    });
  }
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.object.assign.js":
  /*!**********************************************************!*\
    !*** ./node_modules/core-js/modules/es.object.assign.js ***!
    \**********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var assign = __webpack_require__(/*! ../internals/object-assign */ "./node_modules/core-js/internals/object-assign.js");
  
  // `Object.assign` method
  // https://tc39.es/ecma262/#sec-object.assign
  // eslint-disable-next-line es/no-object-assign -- required for testing
  $({ target: 'Object', stat: true, forced: Object.assign !== assign }, {
    assign: assign
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.object.to-string.js":
  /*!*************************************************************!*\
    !*** ./node_modules/core-js/modules/es.object.to-string.js ***!
    \*************************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var TO_STRING_TAG_SUPPORT = __webpack_require__(/*! ../internals/to-string-tag-support */ "./node_modules/core-js/internals/to-string-tag-support.js");
  var redefine = __webpack_require__(/*! ../internals/redefine */ "./node_modules/core-js/internals/redefine.js");
  var toString = __webpack_require__(/*! ../internals/object-to-string */ "./node_modules/core-js/internals/object-to-string.js");
  
  // `Object.prototype.toString` method
  // https://tc39.es/ecma262/#sec-object.prototype.tostring
  if (!TO_STRING_TAG_SUPPORT) {
    redefine(Object.prototype, 'toString', toString, { unsafe: true });
  }
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.parse-int.js":
  /*!******************************************************!*\
    !*** ./node_modules/core-js/modules/es.parse-int.js ***!
    \******************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var parseIntImplementation = __webpack_require__(/*! ../internals/number-parse-int */ "./node_modules/core-js/internals/number-parse-int.js");
  
  // `parseInt` method
  // https://tc39.es/ecma262/#sec-parseint-string-radix
  $({ global: true, forced: parseInt != parseIntImplementation }, {
    parseInt: parseIntImplementation
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.regexp.exec.js":
  /*!********************************************************!*\
    !*** ./node_modules/core-js/modules/es.regexp.exec.js ***!
    \********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var $ = __webpack_require__(/*! ../internals/export */ "./node_modules/core-js/internals/export.js");
  var exec = __webpack_require__(/*! ../internals/regexp-exec */ "./node_modules/core-js/internals/regexp-exec.js");
  
  // `RegExp.prototype.exec` method
  // https://tc39.es/ecma262/#sec-regexp.prototype.exec
  $({ target: 'RegExp', proto: true, forced: /./.exec !== exec }, {
    exec: exec
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.string.iterator.js":
  /*!************************************************************!*\
    !*** ./node_modules/core-js/modules/es.string.iterator.js ***!
    \************************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var charAt = __webpack_require__(/*! ../internals/string-multibyte */ "./node_modules/core-js/internals/string-multibyte.js").charAt;
  var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "./node_modules/core-js/internals/internal-state.js");
  var defineIterator = __webpack_require__(/*! ../internals/define-iterator */ "./node_modules/core-js/internals/define-iterator.js");
  
  var STRING_ITERATOR = 'String Iterator';
  var setInternalState = InternalStateModule.set;
  var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);
  
  // `String.prototype[@@iterator]` method
  // https://tc39.es/ecma262/#sec-string.prototype-@@iterator
  defineIterator(String, 'String', function (iterated) {
    setInternalState(this, {
      type: STRING_ITERATOR,
      string: String(iterated),
      index: 0
    });
  // `%StringIteratorPrototype%.next` method
  // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next
  }, function next() {
    var state = getInternalState(this);
    var string = state.string;
    var index = state.index;
    var point;
    if (index >= string.length) return { value: undefined, done: true };
    point = charAt(string, index);
    state.index += point.length;
    return { value: point, done: false };
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.string.match.js":
  /*!*********************************************************!*\
    !*** ./node_modules/core-js/modules/es.string.match.js ***!
    \*********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ "./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js");
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  var advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ "./node_modules/core-js/internals/advance-string-index.js");
  var regExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ "./node_modules/core-js/internals/regexp-exec-abstract.js");
  
  // @@match logic
  fixRegExpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
    return [
      // `String.prototype.match` method
      // https://tc39.es/ecma262/#sec-string.prototype.match
      function match(regexp) {
        var O = requireObjectCoercible(this);
        var matcher = regexp == undefined ? undefined : regexp[MATCH];
        return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
      },
      // `RegExp.prototype[@@match]` method
      // https://tc39.es/ecma262/#sec-regexp.prototype-@@match
      function (regexp) {
        var res = maybeCallNative(nativeMatch, regexp, this);
        if (res.done) return res.value;
  
        var rx = anObject(regexp);
        var S = String(this);
  
        if (!rx.global) return regExpExec(rx, S);
  
        var fullUnicode = rx.unicode;
        rx.lastIndex = 0;
        var A = [];
        var n = 0;
        var result;
        while ((result = regExpExec(rx, S)) !== null) {
          var matchStr = String(result[0]);
          A[n] = matchStr;
          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
          n++;
        }
        return n === 0 ? null : A;
      }
    ];
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.string.replace.js":
  /*!***********************************************************!*\
    !*** ./node_modules/core-js/modules/es.string.replace.js ***!
    \***********************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var fixRegExpWellKnownSymbolLogic = __webpack_require__(/*! ../internals/fix-regexp-well-known-symbol-logic */ "./node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js");
  var anObject = __webpack_require__(/*! ../internals/an-object */ "./node_modules/core-js/internals/an-object.js");
  var toLength = __webpack_require__(/*! ../internals/to-length */ "./node_modules/core-js/internals/to-length.js");
  var toInteger = __webpack_require__(/*! ../internals/to-integer */ "./node_modules/core-js/internals/to-integer.js");
  var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "./node_modules/core-js/internals/require-object-coercible.js");
  var advanceStringIndex = __webpack_require__(/*! ../internals/advance-string-index */ "./node_modules/core-js/internals/advance-string-index.js");
  var getSubstitution = __webpack_require__(/*! ../internals/get-substitution */ "./node_modules/core-js/internals/get-substitution.js");
  var regExpExec = __webpack_require__(/*! ../internals/regexp-exec-abstract */ "./node_modules/core-js/internals/regexp-exec-abstract.js");
  
  var max = Math.max;
  var min = Math.min;
  
  var maybeToString = function (it) {
    return it === undefined ? it : String(it);
  };
  
  // @@replace logic
  fixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
    var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
    var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
    var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';
  
    return [
      // `String.prototype.replace` method
      // https://tc39.es/ecma262/#sec-string.prototype.replace
      function replace(searchValue, replaceValue) {
        var O = requireObjectCoercible(this);
        var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
        return replacer !== undefined
          ? replacer.call(searchValue, O, replaceValue)
          : nativeReplace.call(String(O), searchValue, replaceValue);
      },
      // `RegExp.prototype[@@replace]` method
      // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
      function (regexp, replaceValue) {
        if (
          (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0) ||
          (typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1)
        ) {
          var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
          if (res.done) return res.value;
        }
  
        var rx = anObject(regexp);
        var S = String(this);
  
        var functionalReplace = typeof replaceValue === 'function';
        if (!functionalReplace) replaceValue = String(replaceValue);
  
        var global = rx.global;
        if (global) {
          var fullUnicode = rx.unicode;
          rx.lastIndex = 0;
        }
        var results = [];
        while (true) {
          var result = regExpExec(rx, S);
          if (result === null) break;
  
          results.push(result);
          if (!global) break;
  
          var matchStr = String(result[0]);
          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
        }
  
        var accumulatedResult = '';
        var nextSourcePosition = 0;
        for (var i = 0; i < results.length; i++) {
          result = results[i];
  
          var matched = String(result[0]);
          var position = max(min(toInteger(result.index), S.length), 0);
          var captures = [];
          // NOTE: This is equivalent to
          //   captures = result.slice(1).map(maybeToString)
          // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
          // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
          // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
          for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
          var namedCaptures = result.groups;
          if (functionalReplace) {
            var replacerArgs = [matched].concat(captures, position, S);
            if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
            var replacement = String(replaceValue.apply(undefined, replacerArgs));
          } else {
            replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
          }
          if (position >= nextSourcePosition) {
            accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
            nextSourcePosition = position + matched.length;
          }
        }
        return accumulatedResult + S.slice(nextSourcePosition);
      }
    ];
  });
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/es.weak-map.js":
  /*!*****************************************************!*\
    !*** ./node_modules/core-js/modules/es.weak-map.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  "use strict";
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var redefineAll = __webpack_require__(/*! ../internals/redefine-all */ "./node_modules/core-js/internals/redefine-all.js");
  var InternalMetadataModule = __webpack_require__(/*! ../internals/internal-metadata */ "./node_modules/core-js/internals/internal-metadata.js");
  var collection = __webpack_require__(/*! ../internals/collection */ "./node_modules/core-js/internals/collection.js");
  var collectionWeak = __webpack_require__(/*! ../internals/collection-weak */ "./node_modules/core-js/internals/collection-weak.js");
  var isObject = __webpack_require__(/*! ../internals/is-object */ "./node_modules/core-js/internals/is-object.js");
  var enforceIternalState = __webpack_require__(/*! ../internals/internal-state */ "./node_modules/core-js/internals/internal-state.js").enforce;
  var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/native-weak-map */ "./node_modules/core-js/internals/native-weak-map.js");
  
  var IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;
  // eslint-disable-next-line es/no-object-isextensible -- safe
  var isExtensible = Object.isExtensible;
  var InternalWeakMap;
  
  var wrapper = function (init) {
    return function WeakMap() {
      return init(this, arguments.length ? arguments[0] : undefined);
    };
  };
  
  // `WeakMap` constructor
  // https://tc39.es/ecma262/#sec-weakmap-constructor
  var $WeakMap = module.exports = collection('WeakMap', wrapper, collectionWeak);
  
  // IE11 WeakMap frozen keys fix
  // We can't use feature detection because it crash some old IE builds
  // https://github.com/zloirock/core-js/issues/485
  if (NATIVE_WEAK_MAP && IS_IE11) {
    InternalWeakMap = collectionWeak.getConstructor(wrapper, 'WeakMap', true);
    InternalMetadataModule.REQUIRED = true;
    var WeakMapPrototype = $WeakMap.prototype;
    var nativeDelete = WeakMapPrototype['delete'];
    var nativeHas = WeakMapPrototype.has;
    var nativeGet = WeakMapPrototype.get;
    var nativeSet = WeakMapPrototype.set;
    redefineAll(WeakMapPrototype, {
      'delete': function (key) {
        if (isObject(key) && !isExtensible(key)) {
          var state = enforceIternalState(this);
          if (!state.frozen) state.frozen = new InternalWeakMap();
          return nativeDelete.call(this, key) || state.frozen['delete'](key);
        } return nativeDelete.call(this, key);
      },
      has: function has(key) {
        if (isObject(key) && !isExtensible(key)) {
          var state = enforceIternalState(this);
          if (!state.frozen) state.frozen = new InternalWeakMap();
          return nativeHas.call(this, key) || state.frozen.has(key);
        } return nativeHas.call(this, key);
      },
      get: function get(key) {
        if (isObject(key) && !isExtensible(key)) {
          var state = enforceIternalState(this);
          if (!state.frozen) state.frozen = new InternalWeakMap();
          return nativeHas.call(this, key) ? nativeGet.call(this, key) : state.frozen.get(key);
        } return nativeGet.call(this, key);
      },
      set: function set(key, value) {
        if (isObject(key) && !isExtensible(key)) {
          var state = enforceIternalState(this);
          if (!state.frozen) state.frozen = new InternalWeakMap();
          nativeHas.call(this, key) ? nativeSet.call(this, key, value) : state.frozen.set(key, value);
        } else nativeSet.call(this, key, value);
        return this;
      }
    });
  }
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/web.dom-collections.for-each.js":
  /*!**********************************************************************!*\
    !*** ./node_modules/core-js/modules/web.dom-collections.for-each.js ***!
    \**********************************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var DOMIterables = __webpack_require__(/*! ../internals/dom-iterables */ "./node_modules/core-js/internals/dom-iterables.js");
  var forEach = __webpack_require__(/*! ../internals/array-for-each */ "./node_modules/core-js/internals/array-for-each.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  
  for (var COLLECTION_NAME in DOMIterables) {
    var Collection = global[COLLECTION_NAME];
    var CollectionPrototype = Collection && Collection.prototype;
    // some Chrome versions have non-configurable methods on DOMTokenList
    if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try {
      createNonEnumerableProperty(CollectionPrototype, 'forEach', forEach);
    } catch (error) {
      CollectionPrototype.forEach = forEach;
    }
  }
  
  
  /***/ }),
  
  /***/ "./node_modules/core-js/modules/web.dom-collections.iterator.js":
  /*!**********************************************************************!*\
    !*** ./node_modules/core-js/modules/web.dom-collections.iterator.js ***!
    \**********************************************************************/
  /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
  
  var global = __webpack_require__(/*! ../internals/global */ "./node_modules/core-js/internals/global.js");
  var DOMIterables = __webpack_require__(/*! ../internals/dom-iterables */ "./node_modules/core-js/internals/dom-iterables.js");
  var ArrayIteratorMethods = __webpack_require__(/*! ../modules/es.array.iterator */ "./node_modules/core-js/modules/es.array.iterator.js");
  var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "./node_modules/core-js/internals/create-non-enumerable-property.js");
  var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "./node_modules/core-js/internals/well-known-symbol.js");
  
  var ITERATOR = wellKnownSymbol('iterator');
  var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  var ArrayValues = ArrayIteratorMethods.values;
  
  for (var COLLECTION_NAME in DOMIterables) {
    var Collection = global[COLLECTION_NAME];
    var CollectionPrototype = Collection && Collection.prototype;
    if (CollectionPrototype) {
      // some Chrome versions have non-configurable methods on DOMTokenList
      if (CollectionPrototype[ITERATOR] !== ArrayValues) try {
        createNonEnumerableProperty(CollectionPrototype, ITERATOR, ArrayValues);
      } catch (error) {
        CollectionPrototype[ITERATOR] = ArrayValues;
      }
      if (!CollectionPrototype[TO_STRING_TAG]) {
        createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);
      }
      if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) {
        // some Chrome versions have non-configurable methods on DOMTokenList
        if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try {
          createNonEnumerableProperty(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]);
        } catch (error) {
          CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME];
        }
      }
    }
  }
  
  
  /***/ }),
  
  /***/ "./node_modules/ion-rangeslider/js/ion.rangeSlider.js":
  /*!************************************************************!*\
    !*** ./node_modules/ion-rangeslider/js/ion.rangeSlider.js ***!
    \************************************************************/
  /***/ (function(module, exports, __webpack_require__) {
  
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Ion.RangeSlider
  // version 2.3.1 Build: 382
  // © Denis Ineshin, 2019
  // https://github.com/IonDen
  //
  // Project page:    http://ionden.com/a/plugins/ion.rangeSlider/en.html
  // GitHub page:     https://github.com/IonDen/ion.rangeSlider
  //
  // Released under MIT licence:
  // http://ionden.com/a/plugins/licence-en.html
  // =====================================================================================================================
  
  ;(function(factory) {
      if ((typeof jQuery === 'undefined' || !jQuery) && "function" === "function" && __webpack_require__.amdO) {
          !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js")], __WEBPACK_AMD_DEFINE_RESULT__ = (function (jQuery) {
              return factory(jQuery, document, window, navigator);
          }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
  		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
      } else if ((typeof jQuery === 'undefined' || !jQuery) && typeof exports === "object") {
          factory(__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"), document, window, navigator);
      } else {
          factory(jQuery, document, window, navigator);
      }
  } (function ($, document, window, navigator, undefined) {
      "use strict";
  
      // =================================================================================================================
      // Service
  
      var plugin_count = 0;
  
      // IE8 fix
      var is_old_ie = (function () {
          var n = navigator.userAgent,
              r = /msie\s\d+/i,
              v;
          if (n.search(r) > 0) {
              v = r.exec(n).toString();
              v = v.split(" ")[1];
              if (v < 9) {
                  $("html").addClass("lt-ie9");
                  return true;
              }
          }
          return false;
      } ());
      if (!Function.prototype.bind) {
          Function.prototype.bind = function bind(that) {
  
              var target = this;
              var slice = [].slice;
  
              if (typeof target != "function") {
                  throw new TypeError();
              }
  
              var args = slice.call(arguments, 1),
                  bound = function () {
  
                      if (this instanceof bound) {
  
                          var F = function(){};
                          F.prototype = target.prototype;
                          var self = new F();
  
                          var result = target.apply(
                              self,
                              args.concat(slice.call(arguments))
                          );
                          if (Object(result) === result) {
                              return result;
                          }
                          return self;
  
                      } else {
  
                          return target.apply(
                              that,
                              args.concat(slice.call(arguments))
                          );
  
                      }
  
                  };
  
              return bound;
          };
      }
      if (!Array.prototype.indexOf) {
          Array.prototype.indexOf = function(searchElement, fromIndex) {
              var k;
              if (this == null) {
                  throw new TypeError('"this" is null or not defined');
              }
              var O = Object(this);
              var len = O.length >>> 0;
              if (len === 0) {
                  return -1;
              }
              var n = +fromIndex || 0;
              if (Math.abs(n) === Infinity) {
                  n = 0;
              }
              if (n >= len) {
                  return -1;
              }
              k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
              while (k < len) {
                  if (k in O && O[k] === searchElement) {
                      return k;
                  }
                  k++;
              }
              return -1;
          };
      }
  
  
  
      // =================================================================================================================
      // Template
  
      var base_html =
          '<span class="irs">' +
          '<span class="irs-line" tabindex="0"></span>' +
          '<span class="irs-min">0</span><span class="irs-max">1</span>' +
          '<span class="irs-from">0</span><span class="irs-to">0</span><span class="irs-single">0</span>' +
          '</span>' +
          '<span class="irs-grid"></span>';
  
      var single_html =
          '<span class="irs-bar irs-bar--single"></span>' +
          '<span class="irs-shadow shadow-single"></span>' +
          '<span class="irs-handle single"><i></i><i></i><i></i></span>';
  
      var double_html =
          '<span class="irs-bar"></span>' +
          '<span class="irs-shadow shadow-from"></span>' +
          '<span class="irs-shadow shadow-to"></span>' +
          '<span class="irs-handle from"><i></i><i></i><i></i></span>' +
          '<span class="irs-handle to"><i></i><i></i><i></i></span>';
  
      var disable_html =
          '<span class="irs-disable-mask"></span>';
  
  
  
      // =================================================================================================================
      // Core
  
      /**
       * Main plugin constructor
       *
       * @param input {Object} link to base input element
       * @param options {Object} slider config
       * @param plugin_count {Number}
       * @constructor
       */
      var IonRangeSlider = function (input, options, plugin_count) {
          this.VERSION = "2.3.1";
          this.input = input;
          this.plugin_count = plugin_count;
          this.current_plugin = 0;
          this.calc_count = 0;
          this.update_tm = 0;
          this.old_from = 0;
          this.old_to = 0;
          this.old_min_interval = null;
          this.raf_id = null;
          this.dragging = false;
          this.force_redraw = false;
          this.no_diapason = false;
          this.has_tab_index = true;
          this.is_key = false;
          this.is_update = false;
          this.is_start = true;
          this.is_finish = false;
          this.is_active = false;
          this.is_resize = false;
          this.is_click = false;
  
          options = options || {};
  
          // cache for links to all DOM elements
          this.$cache = {
              win: $(window),
              body: $(document.body),
              input: $(input),
              cont: null,
              rs: null,
              min: null,
              max: null,
              from: null,
              to: null,
              single: null,
              bar: null,
              line: null,
              s_single: null,
              s_from: null,
              s_to: null,
              shad_single: null,
              shad_from: null,
              shad_to: null,
              edge: null,
              grid: null,
              grid_labels: []
          };
  
          // storage for measure variables
          this.coords = {
              // left
              x_gap: 0,
              x_pointer: 0,
  
              // width
              w_rs: 0,
              w_rs_old: 0,
              w_handle: 0,
  
              // percents
              p_gap: 0,
              p_gap_left: 0,
              p_gap_right: 0,
              p_step: 0,
              p_pointer: 0,
              p_handle: 0,
              p_single_fake: 0,
              p_single_real: 0,
              p_from_fake: 0,
              p_from_real: 0,
              p_to_fake: 0,
              p_to_real: 0,
              p_bar_x: 0,
              p_bar_w: 0,
  
              // grid
              grid_gap: 0,
              big_num: 0,
              big: [],
              big_w: [],
              big_p: [],
              big_x: []
          };
  
          // storage for labels measure variables
          this.labels = {
              // width
              w_min: 0,
              w_max: 0,
              w_from: 0,
              w_to: 0,
              w_single: 0,
  
              // percents
              p_min: 0,
              p_max: 0,
              p_from_fake: 0,
              p_from_left: 0,
              p_to_fake: 0,
              p_to_left: 0,
              p_single_fake: 0,
              p_single_left: 0
          };
  
  
  
          /**
           * get and validate config
           */
          var $inp = this.$cache.input,
              val = $inp.prop("value"),
              config, config_from_data, prop;
  
          // default config
          config = {
              skin: "flat",
              type: "single",
  
              min: 10,
              max: 100,
              from: null,
              to: null,
              step: 1,
  
              min_interval: 0,
              max_interval: 0,
              drag_interval: false,
  
              values: [],
              p_values: [],
  
              from_fixed: false,
              from_min: null,
              from_max: null,
              from_shadow: false,
  
              to_fixed: false,
              to_min: null,
              to_max: null,
              to_shadow: false,
  
              prettify_enabled: true,
              prettify_separator: " ",
              prettify: null,
  
              force_edges: false,
  
              keyboard: true,
  
              grid: false,
              grid_margin: true,
              grid_num: 4,
              grid_snap: false,
  
              hide_min_max: false,
              hide_from_to: false,
  
              prefix: "",
              postfix: "",
              max_postfix: "",
              decorate_both: true,
              values_separator: " — ",
  
              input_values_separator: ";",
  
              disable: false,
              block: false,
  
              extra_classes: "",
  
              scope: null,
              onStart: null,
              onChange: null,
              onFinish: null,
              onUpdate: null
          };
  
  
          // check if base element is input
          if ($inp[0].nodeName !== "INPUT") {
              console && console.warn && console.warn("Base element should be <input>!", $inp[0]);
          }
  
  
          // config from data-attributes extends js config
          config_from_data = {
              skin: $inp.data("skin"),
              type: $inp.data("type"),
  
              min: $inp.data("min"),
              max: $inp.data("max"),
              from: $inp.data("from"),
              to: $inp.data("to"),
              step: $inp.data("step"),
  
              min_interval: $inp.data("minInterval"),
              max_interval: $inp.data("maxInterval"),
              drag_interval: $inp.data("dragInterval"),
  
              values: $inp.data("values"),
  
              from_fixed: $inp.data("fromFixed"),
              from_min: $inp.data("fromMin"),
              from_max: $inp.data("fromMax"),
              from_shadow: $inp.data("fromShadow"),
  
              to_fixed: $inp.data("toFixed"),
              to_min: $inp.data("toMin"),
              to_max: $inp.data("toMax"),
              to_shadow: $inp.data("toShadow"),
  
              prettify_enabled: $inp.data("prettifyEnabled"),
              prettify_separator: $inp.data("prettifySeparator"),
  
              force_edges: $inp.data("forceEdges"),
  
              keyboard: $inp.data("keyboard"),
  
              grid: $inp.data("grid"),
              grid_margin: $inp.data("gridMargin"),
              grid_num: $inp.data("gridNum"),
              grid_snap: $inp.data("gridSnap"),
  
              hide_min_max: $inp.data("hideMinMax"),
              hide_from_to: $inp.data("hideFromTo"),
  
              prefix: $inp.data("prefix"),
              postfix: $inp.data("postfix"),
              max_postfix: $inp.data("maxPostfix"),
              decorate_both: $inp.data("decorateBoth"),
              values_separator: $inp.data("valuesSeparator"),
  
              input_values_separator: $inp.data("inputValuesSeparator"),
  
              disable: $inp.data("disable"),
              block: $inp.data("block"),
  
              extra_classes: $inp.data("extraClasses"),
          };
          config_from_data.values = config_from_data.values && config_from_data.values.split(",");
  
          for (prop in config_from_data) {
              if (config_from_data.hasOwnProperty(prop)) {
                  if (config_from_data[prop] === undefined || config_from_data[prop] === "") {
                      delete config_from_data[prop];
                  }
              }
          }
  
  
          // input value extends default config
          if (val !== undefined && val !== "") {
              val = val.split(config_from_data.input_values_separator || options.input_values_separator || ";");
  
              if (val[0] && val[0] == +val[0]) {
                  val[0] = +val[0];
              }
              if (val[1] && val[1] == +val[1]) {
                  val[1] = +val[1];
              }
  
              if (options && options.values && options.values.length) {
                  config.from = val[0] && options.values.indexOf(val[0]);
                  config.to = val[1] && options.values.indexOf(val[1]);
              } else {
                  config.from = val[0] && +val[0];
                  config.to = val[1] && +val[1];
              }
          }
  
  
  
          // js config extends default config
          $.extend(config, options);
  
  
          // data config extends config
          $.extend(config, config_from_data);
          this.options = config;
  
  
  
          // validate config, to be sure that all data types are correct
          this.update_check = {};
          this.validate();
  
  
  
          // default result object, returned to callbacks
          this.result = {
              input: this.$cache.input,
              slider: null,
  
              min: this.options.min,
              max: this.options.max,
  
              from: this.options.from,
              from_percent: 0,
              from_value: null,
  
              to: this.options.to,
              to_percent: 0,
              to_value: null
          };
  
  
  
          this.init();
      };
  
      IonRangeSlider.prototype = {
  
          /**
           * Starts or updates the plugin instance
           *
           * @param [is_update] {boolean}
           */
          init: function (is_update) {
              this.no_diapason = false;
              this.coords.p_step = this.convertToPercent(this.options.step, true);
  
              this.target = "base";
  
              this.toggleInput();
              this.append();
              this.setMinMax();
  
              if (is_update) {
                  this.force_redraw = true;
                  this.calc(true);
  
                  // callbacks called
                  this.callOnUpdate();
              } else {
                  this.force_redraw = true;
                  this.calc(true);
  
                  // callbacks called
                  this.callOnStart();
              }
  
              this.updateScene();
          },
  
          /**
           * Appends slider template to a DOM
           */
          append: function () {
              var container_html = '<span class="irs irs--' + this.options.skin + ' js-irs-' + this.plugin_count + ' ' + this.options.extra_classes + '"></span>';
              this.$cache.input.before(container_html);
              this.$cache.input.prop("readonly", true);
              this.$cache.cont = this.$cache.input.prev();
              this.result.slider = this.$cache.cont;
  
              this.$cache.cont.html(base_html);
              this.$cache.rs = this.$cache.cont.find(".irs");
              this.$cache.min = this.$cache.cont.find(".irs-min");
              this.$cache.max = this.$cache.cont.find(".irs-max");
              this.$cache.from = this.$cache.cont.find(".irs-from");
              this.$cache.to = this.$cache.cont.find(".irs-to");
              this.$cache.single = this.$cache.cont.find(".irs-single");
              this.$cache.line = this.$cache.cont.find(".irs-line");
              this.$cache.grid = this.$cache.cont.find(".irs-grid");
  
              if (this.options.type === "single") {
                  this.$cache.cont.append(single_html);
                  this.$cache.bar = this.$cache.cont.find(".irs-bar");
                  this.$cache.edge = this.$cache.cont.find(".irs-bar-edge");
                  this.$cache.s_single = this.$cache.cont.find(".single");
                  this.$cache.from[0].style.visibility = "hidden";
                  this.$cache.to[0].style.visibility = "hidden";
                  this.$cache.shad_single = this.$cache.cont.find(".shadow-single");
              } else {
                  this.$cache.cont.append(double_html);
                  this.$cache.bar = this.$cache.cont.find(".irs-bar");
                  this.$cache.s_from = this.$cache.cont.find(".from");
                  this.$cache.s_to = this.$cache.cont.find(".to");
                  this.$cache.shad_from = this.$cache.cont.find(".shadow-from");
                  this.$cache.shad_to = this.$cache.cont.find(".shadow-to");
  
                  this.setTopHandler();
              }
  
              if (this.options.hide_from_to) {
                  this.$cache.from[0].style.display = "none";
                  this.$cache.to[0].style.display = "none";
                  this.$cache.single[0].style.display = "none";
              }
  
              this.appendGrid();
  
              if (this.options.disable) {
                  this.appendDisableMask();
                  this.$cache.input[0].disabled = true;
              } else {
                  this.$cache.input[0].disabled = false;
                  this.removeDisableMask();
                  this.bindEvents();
              }
  
              // block only if not disabled
              if (!this.options.disable) {
                  if (this.options.block) {
                      this.appendDisableMask();
                  } else {
                      this.removeDisableMask();
                  }
              }
  
              if (this.options.drag_interval) {
                  this.$cache.bar[0].style.cursor = "ew-resize";
              }
          },
  
          /**
           * Determine which handler has a priority
           * works only for double slider type
           */
          setTopHandler: function () {
              var min = this.options.min,
                  max = this.options.max,
                  from = this.options.from,
                  to = this.options.to;
  
              if (from > min && to === max) {
                  this.$cache.s_from.addClass("type_last");
              } else if (to < max) {
                  this.$cache.s_to.addClass("type_last");
              }
          },
  
          /**
           * Determine which handles was clicked last
           * and which handler should have hover effect
           *
           * @param target {String}
           */
          changeLevel: function (target) {
              switch (target) {
                  case "single":
                      this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_single_fake);
                      this.$cache.s_single.addClass("state_hover");
                      break;
                  case "from":
                      this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake);
                      this.$cache.s_from.addClass("state_hover");
                      this.$cache.s_from.addClass("type_last");
                      this.$cache.s_to.removeClass("type_last");
                      break;
                  case "to":
                      this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_to_fake);
                      this.$cache.s_to.addClass("state_hover");
                      this.$cache.s_to.addClass("type_last");
                      this.$cache.s_from.removeClass("type_last");
                      break;
                  case "both":
                      this.coords.p_gap_left = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake);
                      this.coords.p_gap_right = this.toFixed(this.coords.p_to_fake - this.coords.p_pointer);
                      this.$cache.s_to.removeClass("type_last");
                      this.$cache.s_from.removeClass("type_last");
                      break;
              }
          },
  
          /**
           * Then slider is disabled
           * appends extra layer with opacity
           */
          appendDisableMask: function () {
              this.$cache.cont.append(disable_html);
              this.$cache.cont.addClass("irs-disabled");
          },
  
          /**
           * Then slider is not disabled
           * remove disable mask
           */
          removeDisableMask: function () {
              this.$cache.cont.remove(".irs-disable-mask");
              this.$cache.cont.removeClass("irs-disabled");
          },
  
          /**
           * Remove slider instance
           * and unbind all events
           */
          remove: function () {
              this.$cache.cont.remove();
              this.$cache.cont = null;
  
              this.$cache.line.off("keydown.irs_" + this.plugin_count);
  
              this.$cache.body.off("touchmove.irs_" + this.plugin_count);
              this.$cache.body.off("mousemove.irs_" + this.plugin_count);
  
              this.$cache.win.off("touchend.irs_" + this.plugin_count);
              this.$cache.win.off("mouseup.irs_" + this.plugin_count);
  
              if (is_old_ie) {
                  this.$cache.body.off("mouseup.irs_" + this.plugin_count);
                  this.$cache.body.off("mouseleave.irs_" + this.plugin_count);
              }
  
              this.$cache.grid_labels = [];
              this.coords.big = [];
              this.coords.big_w = [];
              this.coords.big_p = [];
              this.coords.big_x = [];
  
              cancelAnimationFrame(this.raf_id);
          },
  
          /**
           * bind all slider events
           */
          bindEvents: function () {
              if (this.no_diapason) {
                  return;
              }
  
              this.$cache.body.on("touchmove.irs_" + this.plugin_count, this.pointerMove.bind(this));
              this.$cache.body.on("mousemove.irs_" + this.plugin_count, this.pointerMove.bind(this));
  
              this.$cache.win.on("touchend.irs_" + this.plugin_count, this.pointerUp.bind(this));
              this.$cache.win.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this));
  
              this.$cache.line.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
              this.$cache.line.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
  
              this.$cache.line.on("focus.irs_" + this.plugin_count, this.pointerFocus.bind(this));
  
              if (this.options.drag_interval && this.options.type === "double") {
                  this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "both"));
                  this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "both"));
              } else {
                  this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
                  this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
              }
  
              if (this.options.type === "single") {
                  this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
                  this.$cache.s_single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
                  this.$cache.shad_single.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
  
                  this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
                  this.$cache.s_single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
                  this.$cache.edge.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
                  this.$cache.shad_single.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
              } else {
                  this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, null));
                  this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, null));
  
                  this.$cache.from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
                  this.$cache.s_from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
                  this.$cache.to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
                  this.$cache.s_to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
                  this.$cache.shad_from.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
                  this.$cache.shad_to.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
  
                  this.$cache.from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
                  this.$cache.s_from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
                  this.$cache.to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
                  this.$cache.s_to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
                  this.$cache.shad_from.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
                  this.$cache.shad_to.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
              }
  
              if (this.options.keyboard) {
                  this.$cache.line.on("keydown.irs_" + this.plugin_count, this.key.bind(this, "keyboard"));
              }
  
              if (is_old_ie) {
                  this.$cache.body.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this));
                  this.$cache.body.on("mouseleave.irs_" + this.plugin_count, this.pointerUp.bind(this));
              }
          },
  
          /**
           * Focus with tabIndex
           *
           * @param e {Object} event object
           */
          pointerFocus: function (e) {
              if (!this.target) {
                  var x;
                  var $handle;
  
                  if (this.options.type === "single") {
                      $handle = this.$cache.single;
                  } else {
                      $handle = this.$cache.from;
                  }
  
                  x = $handle.offset().left;
                  x += ($handle.width() / 2) - 1;
  
                  this.pointerClick("single", {preventDefault: function () {}, pageX: x});
              }
          },
  
          /**
           * Mousemove or touchmove
           * only for handlers
           *
           * @param e {Object} event object
           */
          pointerMove: function (e) {
              if (!this.dragging) {
                  return;
              }
  
              var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
              this.coords.x_pointer = x - this.coords.x_gap;
  
              this.calc();
          },
  
          /**
           * Mouseup or touchend
           * only for handlers
           *
           * @param e {Object} event object
           */
          pointerUp: function (e) {
              if (this.current_plugin !== this.plugin_count) {
                  return;
              }
  
              if (this.is_active) {
                  this.is_active = false;
              } else {
                  return;
              }
  
              this.$cache.cont.find(".state_hover").removeClass("state_hover");
  
              this.force_redraw = true;
  
              if (is_old_ie) {
                  $("*").prop("unselectable", false);
              }
  
              this.updateScene();
              this.restoreOriginalMinInterval();
  
              // callbacks call
              if ($.contains(this.$cache.cont[0], e.target) || this.dragging) {
                  this.callOnFinish();
              }
  
              this.dragging = false;
          },
  
          /**
           * Mousedown or touchstart
           * only for handlers
           *
           * @param target {String|null}
           * @param e {Object} event object
           */
          pointerDown: function (target, e) {
              e.preventDefault();
              var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
              if (e.button === 2) {
                  return;
              }
  
              if (target === "both") {
                  this.setTempMinInterval();
              }
  
              if (!target) {
                  target = this.target || "from";
              }
  
              this.current_plugin = this.plugin_count;
              this.target = target;
  
              this.is_active = true;
              this.dragging = true;
  
              this.coords.x_gap = this.$cache.rs.offset().left;
              this.coords.x_pointer = x - this.coords.x_gap;
  
              this.calcPointerPercent();
              this.changeLevel(target);
  
              if (is_old_ie) {
                  $("*").prop("unselectable", true);
              }
  
              this.$cache.line.trigger("focus");
  
              this.updateScene();
          },
  
          /**
           * Mousedown or touchstart
           * for other slider elements, like diapason line
           *
           * @param target {String}
           * @param e {Object} event object
           */
          pointerClick: function (target, e) {
              e.preventDefault();
              var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
              if (e.button === 2) {
                  return;
              }
  
              this.current_plugin = this.plugin_count;
              this.target = target;
  
              this.is_click = true;
              this.coords.x_gap = this.$cache.rs.offset().left;
              this.coords.x_pointer = +(x - this.coords.x_gap).toFixed();
  
              this.force_redraw = true;
              this.calc();
  
              this.$cache.line.trigger("focus");
          },
  
          /**
           * Keyborard controls for focused slider
           *
           * @param target {String}
           * @param e {Object} event object
           * @returns {boolean|undefined}
           */
          key: function (target, e) {
              if (this.current_plugin !== this.plugin_count || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
                  return;
              }
  
              switch (e.which) {
                  case 83: // W
                  case 65: // A
                  case 40: // DOWN
                  case 37: // LEFT
                      e.preventDefault();
                      this.moveByKey(false);
                      break;
  
                  case 87: // S
                  case 68: // D
                  case 38: // UP
                  case 39: // RIGHT
                      e.preventDefault();
                      this.moveByKey(true);
                      break;
              }
  
              return true;
          },
  
          /**
           * Move by key
           *
           * @param right {boolean} direction to move
           */
          moveByKey: function (right) {
              var p = this.coords.p_pointer;
              var p_step = (this.options.max - this.options.min) / 100;
              p_step = this.options.step / p_step;
  
              if (right) {
                  p += p_step;
              } else {
                  p -= p_step;
              }
  
              this.coords.x_pointer = this.toFixed(this.coords.w_rs / 100 * p);
              this.is_key = true;
              this.calc();
          },
  
          /**
           * Set visibility and content
           * of Min and Max labels
           */
          setMinMax: function () {
              if (!this.options) {
                  return;
              }
  
              if (this.options.hide_min_max) {
                  this.$cache.min[0].style.display = "none";
                  this.$cache.max[0].style.display = "none";
                  return;
              }
  
              if (this.options.values.length) {
                  this.$cache.min.html(this.decorate(this.options.p_values[this.options.min]));
                  this.$cache.max.html(this.decorate(this.options.p_values[this.options.max]));
              } else {
                  var min_pretty = this._prettify(this.options.min);
                  var max_pretty = this._prettify(this.options.max);
  
                  this.result.min_pretty = min_pretty;
                  this.result.max_pretty = max_pretty;
  
                  this.$cache.min.html(this.decorate(min_pretty, this.options.min));
                  this.$cache.max.html(this.decorate(max_pretty, this.options.max));
              }
  
              this.labels.w_min = this.$cache.min.outerWidth(false);
              this.labels.w_max = this.$cache.max.outerWidth(false);
          },
  
          /**
           * Then dragging interval, prevent interval collapsing
           * using min_interval option
           */
          setTempMinInterval: function () {
              var interval = this.result.to - this.result.from;
  
              if (this.old_min_interval === null) {
                  this.old_min_interval = this.options.min_interval;
              }
  
              this.options.min_interval = interval;
          },
  
          /**
           * Restore min_interval option to original
           */
          restoreOriginalMinInterval: function () {
              if (this.old_min_interval !== null) {
                  this.options.min_interval = this.old_min_interval;
                  this.old_min_interval = null;
              }
          },
  
  
  
          // =============================================================================================================
          // Calculations
  
          /**
           * All calculations and measures start here
           *
           * @param update {boolean=}
           */
          calc: function (update) {
              if (!this.options) {
                  return;
              }
  
              this.calc_count++;
  
              if (this.calc_count === 10 || update) {
                  this.calc_count = 0;
                  this.coords.w_rs = this.$cache.rs.outerWidth(false);
  
                  this.calcHandlePercent();
              }
  
              if (!this.coords.w_rs) {
                  return;
              }
  
              this.calcPointerPercent();
              var handle_x = this.getHandleX();
  
  
              if (this.target === "both") {
                  this.coords.p_gap = 0;
                  handle_x = this.getHandleX();
              }
  
              if (this.target === "click") {
                  this.coords.p_gap = this.coords.p_handle / 2;
                  handle_x = this.getHandleX();
  
                  if (this.options.drag_interval) {
                      this.target = "both_one";
                  } else {
                      this.target = this.chooseHandle(handle_x);
                  }
              }
  
              switch (this.target) {
                  case "base":
                      var w = (this.options.max - this.options.min) / 100,
                          f = (this.result.from - this.options.min) / w,
                          t = (this.result.to - this.options.min) / w;
  
                      this.coords.p_single_real = this.toFixed(f);
                      this.coords.p_from_real = this.toFixed(f);
                      this.coords.p_to_real = this.toFixed(t);
  
                      this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max);
                      this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
                      this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
  
                      this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real);
                      this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
                      this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
  
                      this.target = null;
  
                      break;
  
                  case "single":
                      if (this.options.from_fixed) {
                          break;
                      }
  
                      this.coords.p_single_real = this.convertToRealPercent(handle_x);
                      this.coords.p_single_real = this.calcWithStep(this.coords.p_single_real);
                      this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max);
  
                      this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real);
  
                      break;
  
                  case "from":
                      if (this.options.from_fixed) {
                          break;
                      }
  
                      this.coords.p_from_real = this.convertToRealPercent(handle_x);
                      this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real);
                      if (this.coords.p_from_real > this.coords.p_to_real) {
                          this.coords.p_from_real = this.coords.p_to_real;
                      }
                      this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
                      this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
                      this.coords.p_from_real = this.checkMaxInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
  
                      this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
  
                      break;
  
                  case "to":
                      if (this.options.to_fixed) {
                          break;
                      }
  
                      this.coords.p_to_real = this.convertToRealPercent(handle_x);
                      this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real);
                      if (this.coords.p_to_real < this.coords.p_from_real) {
                          this.coords.p_to_real = this.coords.p_from_real;
                      }
                      this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
                      this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
                      this.coords.p_to_real = this.checkMaxInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
  
                      this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
  
                      break;
  
                  case "both":
                      if (this.options.from_fixed || this.options.to_fixed) {
                          break;
                      }
  
                      handle_x = this.toFixed(handle_x + (this.coords.p_handle * 0.001));
  
                      this.coords.p_from_real = this.convertToRealPercent(handle_x) - this.coords.p_gap_left;
                      this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real);
                      this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
                      this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
                      this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
  
                      this.coords.p_to_real = this.convertToRealPercent(handle_x) + this.coords.p_gap_right;
                      this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real);
                      this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
                      this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
                      this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
  
                      break;
  
                  case "both_one":
                      if (this.options.from_fixed || this.options.to_fixed) {
                          break;
                      }
  
                      var real_x = this.convertToRealPercent(handle_x),
                          from = this.result.from_percent,
                          to = this.result.to_percent,
                          full = to - from,
                          half = full / 2,
                          new_from = real_x - half,
                          new_to = real_x + half;
  
                      if (new_from < 0) {
                          new_from = 0;
                          new_to = new_from + full;
                      }
  
                      if (new_to > 100) {
                          new_to = 100;
                          new_from = new_to - full;
                      }
  
                      this.coords.p_from_real = this.calcWithStep(new_from);
                      this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
                      this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
  
                      this.coords.p_to_real = this.calcWithStep(new_to);
                      this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
                      this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
  
                      break;
              }
  
              if (this.options.type === "single") {
                  this.coords.p_bar_x = (this.coords.p_handle / 2);
                  this.coords.p_bar_w = this.coords.p_single_fake;
  
                  this.result.from_percent = this.coords.p_single_real;
                  this.result.from = this.convertToValue(this.coords.p_single_real);
                  this.result.from_pretty = this._prettify(this.result.from);
  
                  if (this.options.values.length) {
                      this.result.from_value = this.options.values[this.result.from];
                  }
              } else {
                  this.coords.p_bar_x = this.toFixed(this.coords.p_from_fake + (this.coords.p_handle / 2));
                  this.coords.p_bar_w = this.toFixed(this.coords.p_to_fake - this.coords.p_from_fake);
  
                  this.result.from_percent = this.coords.p_from_real;
                  this.result.from = this.convertToValue(this.coords.p_from_real);
                  this.result.from_pretty = this._prettify(this.result.from);
                  this.result.to_percent = this.coords.p_to_real;
                  this.result.to = this.convertToValue(this.coords.p_to_real);
                  this.result.to_pretty = this._prettify(this.result.to);
  
                  if (this.options.values.length) {
                      this.result.from_value = this.options.values[this.result.from];
                      this.result.to_value = this.options.values[this.result.to];
                  }
              }
  
              this.calcMinMax();
              this.calcLabels();
          },
  
  
          /**
           * calculates pointer X in percent
           */
          calcPointerPercent: function () {
              if (!this.coords.w_rs) {
                  this.coords.p_pointer = 0;
                  return;
              }
  
              if (this.coords.x_pointer < 0 || isNaN(this.coords.x_pointer)  ) {
                  this.coords.x_pointer = 0;
              } else if (this.coords.x_pointer > this.coords.w_rs) {
                  this.coords.x_pointer = this.coords.w_rs;
              }
  
              this.coords.p_pointer = this.toFixed(this.coords.x_pointer / this.coords.w_rs * 100);
          },
  
          convertToRealPercent: function (fake) {
              var full = 100 - this.coords.p_handle;
              return fake / full * 100;
          },
  
          convertToFakePercent: function (real) {
              var full = 100 - this.coords.p_handle;
              return real / 100 * full;
          },
  
          getHandleX: function () {
              var max = 100 - this.coords.p_handle,
                  x = this.toFixed(this.coords.p_pointer - this.coords.p_gap);
  
              if (x < 0) {
                  x = 0;
              } else if (x > max) {
                  x = max;
              }
  
              return x;
          },
  
          calcHandlePercent: function () {
              if (this.options.type === "single") {
                  this.coords.w_handle = this.$cache.s_single.outerWidth(false);
              } else {
                  this.coords.w_handle = this.$cache.s_from.outerWidth(false);
              }
  
              this.coords.p_handle = this.toFixed(this.coords.w_handle / this.coords.w_rs * 100);
          },
  
          /**
           * Find closest handle to pointer click
           *
           * @param real_x {Number}
           * @returns {String}
           */
          chooseHandle: function (real_x) {
              if (this.options.type === "single") {
                  return "single";
              } else {
                  var m_point = this.coords.p_from_real + ((this.coords.p_to_real - this.coords.p_from_real) / 2);
                  if (real_x >= m_point) {
                      return this.options.to_fixed ? "from" : "to";
                  } else {
                      return this.options.from_fixed ? "to" : "from";
                  }
              }
          },
  
          /**
           * Measure Min and Max labels width in percent
           */
          calcMinMax: function () {
              if (!this.coords.w_rs) {
                  return;
              }
  
              this.labels.p_min = this.labels.w_min / this.coords.w_rs * 100;
              this.labels.p_max = this.labels.w_max / this.coords.w_rs * 100;
          },
  
          /**
           * Measure labels width and X in percent
           */
          calcLabels: function () {
              if (!this.coords.w_rs || this.options.hide_from_to) {
                  return;
              }
  
              if (this.options.type === "single") {
  
                  this.labels.w_single = this.$cache.single.outerWidth(false);
                  this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100;
                  this.labels.p_single_left = this.coords.p_single_fake + (this.coords.p_handle / 2) - (this.labels.p_single_fake / 2);
                  this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake);
  
              } else {
  
                  this.labels.w_from = this.$cache.from.outerWidth(false);
                  this.labels.p_from_fake = this.labels.w_from / this.coords.w_rs * 100;
                  this.labels.p_from_left = this.coords.p_from_fake + (this.coords.p_handle / 2) - (this.labels.p_from_fake / 2);
                  this.labels.p_from_left = this.toFixed(this.labels.p_from_left);
                  this.labels.p_from_left = this.checkEdges(this.labels.p_from_left, this.labels.p_from_fake);
  
                  this.labels.w_to = this.$cache.to.outerWidth(false);
                  this.labels.p_to_fake = this.labels.w_to / this.coords.w_rs * 100;
                  this.labels.p_to_left = this.coords.p_to_fake + (this.coords.p_handle / 2) - (this.labels.p_to_fake / 2);
                  this.labels.p_to_left = this.toFixed(this.labels.p_to_left);
                  this.labels.p_to_left = this.checkEdges(this.labels.p_to_left, this.labels.p_to_fake);
  
                  this.labels.w_single = this.$cache.single.outerWidth(false);
                  this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100;
                  this.labels.p_single_left = ((this.labels.p_from_left + this.labels.p_to_left + this.labels.p_to_fake) / 2) - (this.labels.p_single_fake / 2);
                  this.labels.p_single_left = this.toFixed(this.labels.p_single_left);
                  this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake);
  
              }
          },
  
  
  
          // =============================================================================================================
          // Drawings
  
          /**
           * Main function called in request animation frame
           * to update everything
           */
          updateScene: function () {
              if (this.raf_id) {
                  cancelAnimationFrame(this.raf_id);
                  this.raf_id = null;
              }
  
              clearTimeout(this.update_tm);
              this.update_tm = null;
  
              if (!this.options) {
                  return;
              }
  
              this.drawHandles();
  
              if (this.is_active) {
                  this.raf_id = requestAnimationFrame(this.updateScene.bind(this));
              } else {
                  this.update_tm = setTimeout(this.updateScene.bind(this), 300);
              }
          },
  
          /**
           * Draw handles
           */
          drawHandles: function () {
              this.coords.w_rs = this.$cache.rs.outerWidth(false);
  
              if (!this.coords.w_rs) {
                  return;
              }
  
              if (this.coords.w_rs !== this.coords.w_rs_old) {
                  this.target = "base";
                  this.is_resize = true;
              }
  
              if (this.coords.w_rs !== this.coords.w_rs_old || this.force_redraw) {
                  this.setMinMax();
                  this.calc(true);
                  this.drawLabels();
                  if (this.options.grid) {
                      this.calcGridMargin();
                      this.calcGridLabels();
                  }
                  this.force_redraw = true;
                  this.coords.w_rs_old = this.coords.w_rs;
                  this.drawShadow();
              }
  
              if (!this.coords.w_rs) {
                  return;
              }
  
              if (!this.dragging && !this.force_redraw && !this.is_key) {
                  return;
              }
  
              if (this.old_from !== this.result.from || this.old_to !== this.result.to || this.force_redraw || this.is_key) {
  
                  this.drawLabels();
  
                  this.$cache.bar[0].style.left = this.coords.p_bar_x + "%";
                  this.$cache.bar[0].style.width = this.coords.p_bar_w + "%";
  
                  if (this.options.type === "single") {
                      this.$cache.bar[0].style.left = 0;
                      this.$cache.bar[0].style.width = this.coords.p_bar_w + this.coords.p_bar_x + "%";
  
                      this.$cache.s_single[0].style.left = this.coords.p_single_fake + "%";
  
                      this.$cache.single[0].style.left = this.labels.p_single_left + "%";
                  } else {
                      this.$cache.s_from[0].style.left = this.coords.p_from_fake + "%";
                      this.$cache.s_to[0].style.left = this.coords.p_to_fake + "%";
  
                      if (this.old_from !== this.result.from || this.force_redraw) {
                          this.$cache.from[0].style.left = this.labels.p_from_left + "%";
                      }
                      if (this.old_to !== this.result.to || this.force_redraw) {
                          this.$cache.to[0].style.left = this.labels.p_to_left + "%";
                      }
  
                      this.$cache.single[0].style.left = this.labels.p_single_left + "%";
                  }
  
                  this.writeToInput();
  
                  if ((this.old_from !== this.result.from || this.old_to !== this.result.to) && !this.is_start) {
                      this.$cache.input.trigger("change");
                      this.$cache.input.trigger("input");
                  }
  
                  this.old_from = this.result.from;
                  this.old_to = this.result.to;
  
                  // callbacks call
                  if (!this.is_resize && !this.is_update && !this.is_start && !this.is_finish) {
                      this.callOnChange();
                  }
                  if (this.is_key || this.is_click) {
                      this.is_key = false;
                      this.is_click = false;
                      this.callOnFinish();
                  }
  
                  this.is_update = false;
                  this.is_resize = false;
                  this.is_finish = false;
              }
  
              this.is_start = false;
              this.is_key = false;
              this.is_click = false;
              this.force_redraw = false;
          },
  
          /**
           * Draw labels
           * measure labels collisions
           * collapse close labels
           */
          drawLabels: function () {
              if (!this.options) {
                  return;
              }
  
              var values_num = this.options.values.length;
              var p_values = this.options.p_values;
              var text_single;
              var text_from;
              var text_to;
              var from_pretty;
              var to_pretty;
  
              if (this.options.hide_from_to) {
                  return;
              }
  
              if (this.options.type === "single") {
  
                  if (values_num) {
                      text_single = this.decorate(p_values[this.result.from]);
                      this.$cache.single.html(text_single);
                  } else {
                      from_pretty = this._prettify(this.result.from);
  
                      text_single = this.decorate(from_pretty, this.result.from);
                      this.$cache.single.html(text_single);
                  }
  
                  this.calcLabels();
  
                  if (this.labels.p_single_left < this.labels.p_min + 1) {
                      this.$cache.min[0].style.visibility = "hidden";
                  } else {
                      this.$cache.min[0].style.visibility = "visible";
                  }
  
                  if (this.labels.p_single_left + this.labels.p_single_fake > 100 - this.labels.p_max - 1) {
                      this.$cache.max[0].style.visibility = "hidden";
                  } else {
                      this.$cache.max[0].style.visibility = "visible";
                  }
  
              } else {
  
                  if (values_num) {
  
                      if (this.options.decorate_both) {
                          text_single = this.decorate(p_values[this.result.from]);
                          text_single += this.options.values_separator;
                          text_single += this.decorate(p_values[this.result.to]);
                      } else {
                          text_single = this.decorate(p_values[this.result.from] + this.options.values_separator + p_values[this.result.to]);
                      }
                      text_from = this.decorate(p_values[this.result.from]);
                      text_to = this.decorate(p_values[this.result.to]);
  
                      this.$cache.single.html(text_single);
                      this.$cache.from.html(text_from);
                      this.$cache.to.html(text_to);
  
                  } else {
                      from_pretty = this._prettify(this.result.from);
                      to_pretty = this._prettify(this.result.to);
  
                      if (this.options.decorate_both) {
                          text_single = this.decorate(from_pretty, this.result.from);
                          text_single += this.options.values_separator;
                          text_single += this.decorate(to_pretty, this.result.to);
                      } else {
                          text_single = this.decorate(from_pretty + this.options.values_separator + to_pretty, this.result.to);
                      }
                      text_from = this.decorate(from_pretty, this.result.from);
                      text_to = this.decorate(to_pretty, this.result.to);
  
                      this.$cache.single.html(text_single);
                      this.$cache.from.html(text_from);
                      this.$cache.to.html(text_to);
  
                  }
  
                  this.calcLabels();
  
                  var min = Math.min(this.labels.p_single_left, this.labels.p_from_left),
                      single_left = this.labels.p_single_left + this.labels.p_single_fake,
                      to_left = this.labels.p_to_left + this.labels.p_to_fake,
                      max = Math.max(single_left, to_left);
  
                  if (this.labels.p_from_left + this.labels.p_from_fake >= this.labels.p_to_left) {
                      this.$cache.from[0].style.visibility = "hidden";
                      this.$cache.to[0].style.visibility = "hidden";
                      this.$cache.single[0].style.visibility = "visible";
  
                      if (this.result.from === this.result.to) {
                          if (this.target === "from") {
                              this.$cache.from[0].style.visibility = "visible";
                          } else if (this.target === "to") {
                              this.$cache.to[0].style.visibility = "visible";
                          } else if (!this.target) {
                              this.$cache.from[0].style.visibility = "visible";
                          }
                          this.$cache.single[0].style.visibility = "hidden";
                          max = to_left;
                      } else {
                          this.$cache.from[0].style.visibility = "hidden";
                          this.$cache.to[0].style.visibility = "hidden";
                          this.$cache.single[0].style.visibility = "visible";
                          max = Math.max(single_left, to_left);
                      }
                  } else {
                      this.$cache.from[0].style.visibility = "visible";
                      this.$cache.to[0].style.visibility = "visible";
                      this.$cache.single[0].style.visibility = "hidden";
                  }
  
                  if (min < this.labels.p_min + 1) {
                      this.$cache.min[0].style.visibility = "hidden";
                  } else {
                      this.$cache.min[0].style.visibility = "visible";
                  }
  
                  if (max > 100 - this.labels.p_max - 1) {
                      this.$cache.max[0].style.visibility = "hidden";
                  } else {
                      this.$cache.max[0].style.visibility = "visible";
                  }
  
              }
          },
  
          /**
           * Draw shadow intervals
           */
          drawShadow: function () {
              var o = this.options,
                  c = this.$cache,
  
                  is_from_min = typeof o.from_min === "number" && !isNaN(o.from_min),
                  is_from_max = typeof o.from_max === "number" && !isNaN(o.from_max),
                  is_to_min = typeof o.to_min === "number" && !isNaN(o.to_min),
                  is_to_max = typeof o.to_max === "number" && !isNaN(o.to_max),
  
                  from_min,
                  from_max,
                  to_min,
                  to_max;
  
              if (o.type === "single") {
                  if (o.from_shadow && (is_from_min || is_from_max)) {
                      from_min = this.convertToPercent(is_from_min ? o.from_min : o.min);
                      from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min;
                      from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min));
                      from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max));
                      from_min = from_min + (this.coords.p_handle / 2);
  
                      c.shad_single[0].style.display = "block";
                      c.shad_single[0].style.left = from_min + "%";
                      c.shad_single[0].style.width = from_max + "%";
                  } else {
                      c.shad_single[0].style.display = "none";
                  }
              } else {
                  if (o.from_shadow && (is_from_min || is_from_max)) {
                      from_min = this.convertToPercent(is_from_min ? o.from_min : o.min);
                      from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min;
                      from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min));
                      from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max));
                      from_min = from_min + (this.coords.p_handle / 2);
  
                      c.shad_from[0].style.display = "block";
                      c.shad_from[0].style.left = from_min + "%";
                      c.shad_from[0].style.width = from_max + "%";
                  } else {
                      c.shad_from[0].style.display = "none";
                  }
  
                  if (o.to_shadow && (is_to_min || is_to_max)) {
                      to_min = this.convertToPercent(is_to_min ? o.to_min : o.min);
                      to_max = this.convertToPercent(is_to_max ? o.to_max : o.max) - to_min;
                      to_min = this.toFixed(to_min - (this.coords.p_handle / 100 * to_min));
                      to_max = this.toFixed(to_max - (this.coords.p_handle / 100 * to_max));
                      to_min = to_min + (this.coords.p_handle / 2);
  
                      c.shad_to[0].style.display = "block";
                      c.shad_to[0].style.left = to_min + "%";
                      c.shad_to[0].style.width = to_max + "%";
                  } else {
                      c.shad_to[0].style.display = "none";
                  }
              }
          },
  
  
  
          /**
           * Write values to input element
           */
          writeToInput: function () {
              if (this.options.type === "single") {
                  if (this.options.values.length) {
                      this.$cache.input.prop("value", this.result.from_value);
                  } else {
                      this.$cache.input.prop("value", this.result.from);
                  }
                  this.$cache.input.data("from", this.result.from);
              } else {
                  if (this.options.values.length) {
                      this.$cache.input.prop("value", this.result.from_value + this.options.input_values_separator + this.result.to_value);
                  } else {
                      this.$cache.input.prop("value", this.result.from + this.options.input_values_separator + this.result.to);
                  }
                  this.$cache.input.data("from", this.result.from);
                  this.$cache.input.data("to", this.result.to);
              }
          },
  
  
  
          // =============================================================================================================
          // Callbacks
  
          callOnStart: function () {
              this.writeToInput();
  
              if (this.options.onStart && typeof this.options.onStart === "function") {
                  if (this.options.scope) {
                      this.options.onStart.call(this.options.scope, this.result);
                  } else {
                      this.options.onStart(this.result);
                  }
              }
          },
          callOnChange: function () {
              this.writeToInput();
  
              if (this.options.onChange && typeof this.options.onChange === "function") {
                  if (this.options.scope) {
                      this.options.onChange.call(this.options.scope, this.result);
                  } else {
                      this.options.onChange(this.result);
                  }
              }
          },
          callOnFinish: function () {
              this.writeToInput();
  
              if (this.options.onFinish && typeof this.options.onFinish === "function") {
                  if (this.options.scope) {
                      this.options.onFinish.call(this.options.scope, this.result);
                  } else {
                      this.options.onFinish(this.result);
                  }
              }
          },
          callOnUpdate: function () {
              this.writeToInput();
  
              if (this.options.onUpdate && typeof this.options.onUpdate === "function") {
                  if (this.options.scope) {
                      this.options.onUpdate.call(this.options.scope, this.result);
                  } else {
                      this.options.onUpdate(this.result);
                  }
              }
          },
  
  
  
  
          // =============================================================================================================
          // Service methods
  
          toggleInput: function () {
              this.$cache.input.toggleClass("irs-hidden-input");
  
              if (this.has_tab_index) {
                  this.$cache.input.prop("tabindex", -1);
              } else {
                  this.$cache.input.removeProp("tabindex");
              }
  
              this.has_tab_index = !this.has_tab_index;
          },
  
          /**
           * Convert real value to percent
           *
           * @param value {Number} X in real
           * @param no_min {boolean=} don't use min value
           * @returns {Number} X in percent
           */
          convertToPercent: function (value, no_min) {
              var diapason = this.options.max - this.options.min,
                  one_percent = diapason / 100,
                  val, percent;
  
              if (!diapason) {
                  this.no_diapason = true;
                  return 0;
              }
  
              if (no_min) {
                  val = value;
              } else {
                  val = value - this.options.min;
              }
  
              percent = val / one_percent;
  
              return this.toFixed(percent);
          },
  
          /**
           * Convert percent to real values
           *
           * @param percent {Number} X in percent
           * @returns {Number} X in real
           */
          convertToValue: function (percent) {
              var min = this.options.min,
                  max = this.options.max,
                  min_decimals = min.toString().split(".")[1],
                  max_decimals = max.toString().split(".")[1],
                  min_length, max_length,
                  avg_decimals = 0,
                  abs = 0;
  
              if (percent === 0) {
                  return this.options.min;
              }
              if (percent === 100) {
                  return this.options.max;
              }
  
  
              if (min_decimals) {
                  min_length = min_decimals.length;
                  avg_decimals = min_length;
              }
              if (max_decimals) {
                  max_length = max_decimals.length;
                  avg_decimals = max_length;
              }
              if (min_length && max_length) {
                  avg_decimals = (min_length >= max_length) ? min_length : max_length;
              }
  
              if (min < 0) {
                  abs = Math.abs(min);
                  min = +(min + abs).toFixed(avg_decimals);
                  max = +(max + abs).toFixed(avg_decimals);
              }
  
              var number = ((max - min) / 100 * percent) + min,
                  string = this.options.step.toString().split(".")[1],
                  result;
  
              if (string) {
                  number = +number.toFixed(string.length);
              } else {
                  number = number / this.options.step;
                  number = number * this.options.step;
  
                  number = +number.toFixed(0);
              }
  
              if (abs) {
                  number -= abs;
              }
  
              if (string) {
                  result = +number.toFixed(string.length);
              } else {
                  result = this.toFixed(number);
              }
  
              if (result < this.options.min) {
                  result = this.options.min;
              } else if (result > this.options.max) {
                  result = this.options.max;
              }
  
              return result;
          },
  
          /**
           * Round percent value with step
           *
           * @param percent {Number}
           * @returns percent {Number} rounded
           */
          calcWithStep: function (percent) {
              var rounded = Math.round(percent / this.coords.p_step) * this.coords.p_step;
  
              if (rounded > 100) {
                  rounded = 100;
              }
              if (percent === 100) {
                  rounded = 100;
              }
  
              return this.toFixed(rounded);
          },
  
          checkMinInterval: function (p_current, p_next, type) {
              var o = this.options,
                  current,
                  next;
  
              if (!o.min_interval) {
                  return p_current;
              }
  
              current = this.convertToValue(p_current);
              next = this.convertToValue(p_next);
  
              if (type === "from") {
  
                  if (next - current < o.min_interval) {
                      current = next - o.min_interval;
                  }
  
              } else {
  
                  if (current - next < o.min_interval) {
                      current = next + o.min_interval;
                  }
  
              }
  
              return this.convertToPercent(current);
          },
  
          checkMaxInterval: function (p_current, p_next, type) {
              var o = this.options,
                  current,
                  next;
  
              if (!o.max_interval) {
                  return p_current;
              }
  
              current = this.convertToValue(p_current);
              next = this.convertToValue(p_next);
  
              if (type === "from") {
  
                  if (next - current > o.max_interval) {
                      current = next - o.max_interval;
                  }
  
              } else {
  
                  if (current - next > o.max_interval) {
                      current = next + o.max_interval;
                  }
  
              }
  
              return this.convertToPercent(current);
          },
  
          checkDiapason: function (p_num, min, max) {
              var num = this.convertToValue(p_num),
                  o = this.options;
  
              if (typeof min !== "number") {
                  min = o.min;
              }
  
              if (typeof max !== "number") {
                  max = o.max;
              }
  
              if (num < min) {
                  num = min;
              }
  
              if (num > max) {
                  num = max;
              }
  
              return this.convertToPercent(num);
          },
  
          toFixed: function (num) {
              num = num.toFixed(20);
              return +num;
          },
  
          _prettify: function (num) {
              if (!this.options.prettify_enabled) {
                  return num;
              }
  
              if (this.options.prettify && typeof this.options.prettify === "function") {
                  return this.options.prettify(num);
              } else {
                  return this.prettify(num);
              }
          },
  
          prettify: function (num) {
              var n = num.toString();
              return n.replace(/(\d{1,3}(?=(?:\d\d\d)+(?!\d)))/g, "$1" + this.options.prettify_separator);
          },
  
          checkEdges: function (left, width) {
              if (!this.options.force_edges) {
                  return this.toFixed(left);
              }
  
              if (left < 0) {
                  left = 0;
              } else if (left > 100 - width) {
                  left = 100 - width;
              }
  
              return this.toFixed(left);
          },
  
          validate: function () {
              var o = this.options,
                  r = this.result,
                  v = o.values,
                  vl = v.length,
                  value,
                  i;
  
              if (typeof o.min === "string") o.min = +o.min;
              if (typeof o.max === "string") o.max = +o.max;
              if (typeof o.from === "string") o.from = +o.from;
              if (typeof o.to === "string") o.to = +o.to;
              if (typeof o.step === "string") o.step = +o.step;
  
              if (typeof o.from_min === "string") o.from_min = +o.from_min;
              if (typeof o.from_max === "string") o.from_max = +o.from_max;
              if (typeof o.to_min === "string") o.to_min = +o.to_min;
              if (typeof o.to_max === "string") o.to_max = +o.to_max;
  
              if (typeof o.grid_num === "string") o.grid_num = +o.grid_num;
  
              if (o.max < o.min) {
                  o.max = o.min;
              }
  
              if (vl) {
                  o.p_values = [];
                  o.min = 0;
                  o.max = vl - 1;
                  o.step = 1;
                  o.grid_num = o.max;
                  o.grid_snap = true;
  
                  for (i = 0; i < vl; i++) {
                      value = +v[i];
  
                      if (!isNaN(value)) {
                          v[i] = value;
                          value = this._prettify(value);
                      } else {
                          value = v[i];
                      }
  
                      o.p_values.push(value);
                  }
              }
  
              if (typeof o.from !== "number" || isNaN(o.from)) {
                  o.from = o.min;
              }
  
              if (typeof o.to !== "number" || isNaN(o.to)) {
                  o.to = o.max;
              }
  
              if (o.type === "single") {
  
                  if (o.from < o.min) o.from = o.min;
                  if (o.from > o.max) o.from = o.max;
  
              } else {
  
                  if (o.from < o.min) o.from = o.min;
                  if (o.from > o.max) o.from = o.max;
  
                  if (o.to < o.min) o.to = o.min;
                  if (o.to > o.max) o.to = o.max;
  
                  if (this.update_check.from) {
  
                      if (this.update_check.from !== o.from) {
                          if (o.from > o.to) o.from = o.to;
                      }
                      if (this.update_check.to !== o.to) {
                          if (o.to < o.from) o.to = o.from;
                      }
  
                  }
  
                  if (o.from > o.to) o.from = o.to;
                  if (o.to < o.from) o.to = o.from;
  
              }
  
              if (typeof o.step !== "number" || isNaN(o.step) || !o.step || o.step < 0) {
                  o.step = 1;
              }
  
              if (typeof o.from_min === "number" && o.from < o.from_min) {
                  o.from = o.from_min;
              }
  
              if (typeof o.from_max === "number" && o.from > o.from_max) {
                  o.from = o.from_max;
              }
  
              if (typeof o.to_min === "number" && o.to < o.to_min) {
                  o.to = o.to_min;
              }
  
              if (typeof o.to_max === "number" && o.from > o.to_max) {
                  o.to = o.to_max;
              }
  
              if (r) {
                  if (r.min !== o.min) {
                      r.min = o.min;
                  }
  
                  if (r.max !== o.max) {
                      r.max = o.max;
                  }
  
                  if (r.from < r.min || r.from > r.max) {
                      r.from = o.from;
                  }
  
                  if (r.to < r.min || r.to > r.max) {
                      r.to = o.to;
                  }
              }
  
              if (typeof o.min_interval !== "number" || isNaN(o.min_interval) || !o.min_interval || o.min_interval < 0) {
                  o.min_interval = 0;
              }
  
              if (typeof o.max_interval !== "number" || isNaN(o.max_interval) || !o.max_interval || o.max_interval < 0) {
                  o.max_interval = 0;
              }
  
              if (o.min_interval && o.min_interval > o.max - o.min) {
                  o.min_interval = o.max - o.min;
              }
  
              if (o.max_interval && o.max_interval > o.max - o.min) {
                  o.max_interval = o.max - o.min;
              }
          },
  
          decorate: function (num, original) {
              var decorated = "",
                  o = this.options;
  
              if (o.prefix) {
                  decorated += o.prefix;
              }
  
              decorated += num;
  
              if (o.max_postfix) {
                  if (o.values.length && num === o.p_values[o.max]) {
                      decorated += o.max_postfix;
                      if (o.postfix) {
                          decorated += " ";
                      }
                  } else if (original === o.max) {
                      decorated += o.max_postfix;
                      if (o.postfix) {
                          decorated += " ";
                      }
                  }
              }
  
              if (o.postfix) {
                  decorated += o.postfix;
              }
  
              return decorated;
          },
  
          updateFrom: function () {
              this.result.from = this.options.from;
              this.result.from_percent = this.convertToPercent(this.result.from);
              this.result.from_pretty = this._prettify(this.result.from);
              if (this.options.values) {
                  this.result.from_value = this.options.values[this.result.from];
              }
          },
  
          updateTo: function () {
              this.result.to = this.options.to;
              this.result.to_percent = this.convertToPercent(this.result.to);
              this.result.to_pretty = this._prettify(this.result.to);
              if (this.options.values) {
                  this.result.to_value = this.options.values[this.result.to];
              }
          },
  
          updateResult: function () {
              this.result.min = this.options.min;
              this.result.max = this.options.max;
              this.updateFrom();
              this.updateTo();
          },
  
  
          // =============================================================================================================
          // Grid
  
          appendGrid: function () {
              if (!this.options.grid) {
                  return;
              }
  
              var o = this.options,
                  i, z,
  
                  total = o.max - o.min,
                  big_num = o.grid_num,
                  big_p = 0,
                  big_w = 0,
  
                  small_max = 4,
                  local_small_max,
                  small_p,
                  small_w = 0,
  
                  result,
                  html = '';
  
  
  
              this.calcGridMargin();
  
              if (o.grid_snap) {
                  big_num = total / o.step;
              }
  
              if (big_num > 50) big_num = 50;
              big_p = this.toFixed(100 / big_num);
  
              if (big_num > 4) {
                  small_max = 3;
              }
              if (big_num > 7) {
                  small_max = 2;
              }
              if (big_num > 14) {
                  small_max = 1;
              }
              if (big_num > 28) {
                  small_max = 0;
              }
  
              for (i = 0; i < big_num + 1; i++) {
                  local_small_max = small_max;
  
                  big_w = this.toFixed(big_p * i);
  
                  if (big_w > 100) {
                      big_w = 100;
                  }
                  this.coords.big[i] = big_w;
  
                  small_p = (big_w - (big_p * (i - 1))) / (local_small_max + 1);
  
                  for (z = 1; z <= local_small_max; z++) {
                      if (big_w === 0) {
                          break;
                      }
  
                      small_w = this.toFixed(big_w - (small_p * z));
  
                      html += '<span class="irs-grid-pol small" style="left: ' + small_w + '%"></span>';
                  }
  
                  html += '<span class="irs-grid-pol" style="left: ' + big_w + '%"></span>';
  
                  result = this.convertToValue(big_w);
                  if (o.values.length) {
                      result = o.p_values[result];
                  } else {
                      result = this._prettify(result);
                  }
  
                  html += '<span class="irs-grid-text js-grid-text-' + i + '" style="left: ' + big_w + '%">' + result + '</span>';
              }
              this.coords.big_num = Math.ceil(big_num + 1);
  
  
  
              this.$cache.cont.addClass("irs-with-grid");
              this.$cache.grid.html(html);
              this.cacheGridLabels();
          },
  
          cacheGridLabels: function () {
              var $label, i,
                  num = this.coords.big_num;
  
              for (i = 0; i < num; i++) {
                  $label = this.$cache.grid.find(".js-grid-text-" + i);
                  this.$cache.grid_labels.push($label);
              }
  
              this.calcGridLabels();
          },
  
          calcGridLabels: function () {
              var i, label, start = [], finish = [],
                  num = this.coords.big_num;
  
              for (i = 0; i < num; i++) {
                  this.coords.big_w[i] = this.$cache.grid_labels[i].outerWidth(false);
                  this.coords.big_p[i] = this.toFixed(this.coords.big_w[i] / this.coords.w_rs * 100);
                  this.coords.big_x[i] = this.toFixed(this.coords.big_p[i] / 2);
  
                  start[i] = this.toFixed(this.coords.big[i] - this.coords.big_x[i]);
                  finish[i] = this.toFixed(start[i] + this.coords.big_p[i]);
              }
  
              if (this.options.force_edges) {
                  if (start[0] < -this.coords.grid_gap) {
                      start[0] = -this.coords.grid_gap;
                      finish[0] = this.toFixed(start[0] + this.coords.big_p[0]);
  
                      this.coords.big_x[0] = this.coords.grid_gap;
                  }
  
                  if (finish[num - 1] > 100 + this.coords.grid_gap) {
                      finish[num - 1] = 100 + this.coords.grid_gap;
                      start[num - 1] = this.toFixed(finish[num - 1] - this.coords.big_p[num - 1]);
  
                      this.coords.big_x[num - 1] = this.toFixed(this.coords.big_p[num - 1] - this.coords.grid_gap);
                  }
              }
  
              this.calcGridCollision(2, start, finish);
              this.calcGridCollision(4, start, finish);
  
              for (i = 0; i < num; i++) {
                  label = this.$cache.grid_labels[i][0];
  
                  if (this.coords.big_x[i] !== Number.POSITIVE_INFINITY) {
                      label.style.marginLeft = -this.coords.big_x[i] + "%";
                  }
              }
          },
  
          // Collisions Calc Beta
          // TODO: Refactor then have plenty of time
          calcGridCollision: function (step, start, finish) {
              var i, next_i, label,
                  num = this.coords.big_num;
  
              for (i = 0; i < num; i += step) {
                  next_i = i + (step / 2);
                  if (next_i >= num) {
                      break;
                  }
  
                  label = this.$cache.grid_labels[next_i][0];
  
                  if (finish[i] <= start[next_i]) {
                      label.style.visibility = "visible";
                  } else {
                      label.style.visibility = "hidden";
                  }
              }
          },
  
          calcGridMargin: function () {
              if (!this.options.grid_margin) {
                  return;
              }
  
              this.coords.w_rs = this.$cache.rs.outerWidth(false);
              if (!this.coords.w_rs) {
                  return;
              }
  
              if (this.options.type === "single") {
                  this.coords.w_handle = this.$cache.s_single.outerWidth(false);
              } else {
                  this.coords.w_handle = this.$cache.s_from.outerWidth(false);
              }
              this.coords.p_handle = this.toFixed(this.coords.w_handle  / this.coords.w_rs * 100);
              this.coords.grid_gap = this.toFixed((this.coords.p_handle / 2) - 0.1);
  
              this.$cache.grid[0].style.width = this.toFixed(100 - this.coords.p_handle) + "%";
              this.$cache.grid[0].style.left = this.coords.grid_gap + "%";
          },
  
  
  
          // =============================================================================================================
          // Public methods
  
          update: function (options) {
              if (!this.input) {
                  return;
              }
  
              this.is_update = true;
  
              this.options.from = this.result.from;
              this.options.to = this.result.to;
              this.update_check.from = this.result.from;
              this.update_check.to = this.result.to;
  
              this.options = $.extend(this.options, options);
              this.validate();
              this.updateResult(options);
  
              this.toggleInput();
              this.remove();
              this.init(true);
          },
  
          reset: function () {
              if (!this.input) {
                  return;
              }
  
              this.updateResult();
              this.update();
          },
  
          destroy: function () {
              if (!this.input) {
                  return;
              }
  
              this.toggleInput();
              this.$cache.input.prop("readonly", false);
              $.data(this.input, "ionRangeSlider", null);
  
              this.remove();
              this.input = null;
              this.options = null;
          }
      };
  
      $.fn.ionRangeSlider = function (options) {
          return this.each(function() {
              if (!$.data(this, "ionRangeSlider")) {
                  $.data(this, "ionRangeSlider", new IonRangeSlider(this, options, plugin_count++));
              }
          });
      };
  
  
  
      // =================================================================================================================
      // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
      // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  
      // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
  
      // MIT license
  
      (function() {
          var lastTime = 0;
          var vendors = ['ms', 'moz', 'webkit', 'o'];
          for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
              window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
              window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                  || window[vendors[x]+'CancelRequestAnimationFrame'];
          }
  
          if (!window.requestAnimationFrame)
              window.requestAnimationFrame = function(callback, element) {
                  var currTime = new Date().getTime();
                  var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                  var id = window.setTimeout(function() { callback(currTime + timeToCall); },
                      timeToCall);
                  lastTime = currTime + timeToCall;
                  return id;
              };
  
          if (!window.cancelAnimationFrame)
              window.cancelAnimationFrame = function(id) {
                  clearTimeout(id);
              };
      }());
  
  }));
  
  
  /***/ }),
  
  /***/ "./node_modules/jquery/dist/jquery.js":
  /*!********************************************!*\
    !*** ./node_modules/jquery/dist/jquery.js ***!
    \********************************************/
  /***/ (function(module, exports) {
  
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
   * jQuery JavaScript Library v3.6.0
   * https://jquery.com/
   *
   * Includes Sizzle.js
   * https://sizzlejs.com/
   *
   * Copyright OpenJS Foundation and other contributors
   * Released under the MIT license
   * https://jquery.org/license
   *
   * Date: 2021-03-02T17:08Z
   */
  ( function( global, factory ) {
  
  	"use strict";
  
  	if (  true && 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.
  		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
  		// Plus for old WebKit, typeof returns "function" for HTML collections
  		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
  		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
  			typeof obj.item !== "function";
  	};
  
  
  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.6.0",
  
  	// 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.6
   * https://sizzlejs.com/
   *
   * Copyright JS Foundation and other contributors
   * Released under the MIT license
   * https://js.foundation/
   *
   * Date: 2021-02-16
   */
  ( 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 && elem.namespaceURI,
  		docElem = elem && ( 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 primary Deferred
  			primary = 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 ) ) {
  						primary.resolveWith( resolveContexts, resolveValues );
  					}
  				};
  			};
  
  		// Single- and empty arguments are adopted like Promise.resolve
  		if ( remaining <= 1 ) {
  			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
  				!remaining );
  
  			// Use .then() to unwrap secondary thenables (cf. gh-3000)
  			if ( primary.state() === "pending" ||
  				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
  
  				return primary.then();
  			}
  		}
  
  		// Multiple arguments are aggregated like Promise.all array elements
  		while ( i-- ) {
  			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
  		}
  
  		return primary.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 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();
  
  						// Support: Chrome 86+
  						// In Chrome, if an element having a focusout handler is blurred by
  						// clicking outside of it, it invokes the handler synchronously. If
  						// that handler calls `.remove()` on the element, the data is cleared,
  						// leaving `result` undefined. We need to guard against this.
  						return result && 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: true
  }, 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;
  		},
  
  		// Suppress native focus or blur as it's already being fired
  		// in leverageNative.
  		_default: function() {
  			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!
  		//
  		// Support: Firefox 70+
  		// Only Firefox includes border widths
  		// in computed dimensions. (gh-4529)
  		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;border-collapse:separate";
  				tr.style.cssText = "border:1px solid";
  
  				// Support: Chrome 86+
  				// Height set through cssText does not get applied.
  				// Computed height then comes back as 0.
  				tr.style.height = "1px";
  				trChild.style.height = "9px";
  
  				// Support: Android 8 Chrome 86+
  				// In our bodyBackground.html iframe,
  				// display for all div elements is set to "inline",
  				// which causes a problem only in Android 8 Chrome 86.
  				// Ensuring the div is display: block
  				// gets around this issue.
  				trChild.style.display = "block";
  
  				documentElement
  					.appendChild( table )
  					.appendChild( tr )
  					.appendChild( trChild );
  
  				trStyle = window.getComputedStyle( tr );
  				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
  					parseInt( trStyle.borderTopWidth, 10 ) +
  					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
  
  				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, parserErrorElem;
  	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 ) {}
  
  	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
  	if ( !xml || parserErrorElem ) {
  		jQuery.error( "Invalid XML: " + (
  			parserErrorElem ?
  				jQuery.map( parserErrorElem.childNodes, function( el ) {
  					return el.textContent;
  				} ).join( "\n" ) :
  				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 but not if jsonp
  			if ( !isSuccess &&
  				jQuery.inArray( "script", s.dataTypes ) > -1 &&
  				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
  				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 {
  			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 ( true ) {
  	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
  		return jQuery;
  	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
  		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  }
  
  
  
  
  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;
  } );
  
  
  /***/ }),
  
  /***/ "./node_modules/lodash.debounce/index.js":
  /*!***********************************************!*\
    !*** ./node_modules/lodash.debounce/index.js ***!
    \***********************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  /**
   * lodash (Custom Build) <https://lodash.com/>
   * Build: `lodash modularize exports="npm" -o ./`
   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
   * Released under MIT license <https://lodash.com/license>
   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
   */
  
  /** Used as the `TypeError` message for "Functions" methods. */
  var FUNC_ERROR_TEXT = 'Expected a function';
  
  /** Used as references for various `Number` constants. */
  var NAN = 0 / 0;
  
  /** `Object#toString` result references. */
  var symbolTag = '[object Symbol]';
  
  /** Used to match leading and trailing whitespace. */
  var reTrim = /^\s+|\s+$/g;
  
  /** Used to detect bad signed hexadecimal string values. */
  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  
  /** Used to detect binary string values. */
  var reIsBinary = /^0b[01]+$/i;
  
  /** Used to detect octal string values. */
  var reIsOctal = /^0o[0-7]+$/i;
  
  /** Built-in method references without a dependency on `root`. */
  var freeParseInt = parseInt;
  
  /** Detect free variable `global` from Node.js. */
  var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
  
  /** Detect free variable `self`. */
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  
  /** Used as a reference to the global object. */
  var root = freeGlobal || freeSelf || Function('return this')();
  
  /** Used for built-in method references. */
  var objectProto = Object.prototype;
  
  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var objectToString = objectProto.toString;
  
  /* Built-in method references for those with the same name as other `lodash` methods. */
  var nativeMax = Math.max,
      nativeMin = Math.min;
  
  /**
   * Gets the timestamp of the number of milliseconds that have elapsed since
   * the Unix epoch (1 January 1970 00:00:00 UTC).
   *
   * @static
   * @memberOf _
   * @since 2.4.0
   * @category Date
   * @returns {number} Returns the timestamp.
   * @example
   *
   * _.defer(function(stamp) {
   *   console.log(_.now() - stamp);
   * }, _.now());
   * // => Logs the number of milliseconds it took for the deferred invocation.
   */
  var now = function() {
    return root.Date.now();
  };
  
  /**
   * Creates a debounced function that delays invoking `func` until after `wait`
   * milliseconds have elapsed since the last time the debounced function was
   * invoked. The debounced function comes with a `cancel` method to cancel
   * delayed `func` invocations and a `flush` method to immediately invoke them.
   * Provide `options` to indicate whether `func` should be invoked on the
   * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
   * with the last arguments provided to the debounced function. Subsequent
   * calls to the debounced function return the result of the last `func`
   * invocation.
   *
   * **Note:** If `leading` and `trailing` options are `true`, `func` is
   * invoked on the trailing edge of the timeout only if the debounced function
   * is invoked more than once during the `wait` timeout.
   *
   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
   *
   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
   * for details over the differences between `_.debounce` and `_.throttle`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to debounce.
   * @param {number} [wait=0] The number of milliseconds to delay.
   * @param {Object} [options={}] The options object.
   * @param {boolean} [options.leading=false]
   *  Specify invoking on the leading edge of the timeout.
   * @param {number} [options.maxWait]
   *  The maximum time `func` is allowed to be delayed before it's invoked.
   * @param {boolean} [options.trailing=true]
   *  Specify invoking on the trailing edge of the timeout.
   * @returns {Function} Returns the new debounced function.
   * @example
   *
   * // Avoid costly calculations while the window size is in flux.
   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
   *
   * // Invoke `sendMail` when clicked, debouncing subsequent calls.
   * jQuery(element).on('click', _.debounce(sendMail, 300, {
   *   'leading': true,
   *   'trailing': false
   * }));
   *
   * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
   * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
   * var source = new EventSource('/stream');
   * jQuery(source).on('message', debounced);
   *
   * // Cancel the trailing debounced invocation.
   * jQuery(window).on('popstate', debounced.cancel);
   */
  function debounce(func, wait, options) {
    var lastArgs,
        lastThis,
        maxWait,
        result,
        timerId,
        lastCallTime,
        lastInvokeTime = 0,
        leading = false,
        maxing = false,
        trailing = true;
  
    if (typeof func != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    wait = toNumber(wait) || 0;
    if (isObject(options)) {
      leading = !!options.leading;
      maxing = 'maxWait' in options;
      maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
      trailing = 'trailing' in options ? !!options.trailing : trailing;
    }
  
    function invokeFunc(time) {
      var args = lastArgs,
          thisArg = lastThis;
  
      lastArgs = lastThis = undefined;
      lastInvokeTime = time;
      result = func.apply(thisArg, args);
      return result;
    }
  
    function leadingEdge(time) {
      // Reset any `maxWait` timer.
      lastInvokeTime = time;
      // Start the timer for the trailing edge.
      timerId = setTimeout(timerExpired, wait);
      // Invoke the leading edge.
      return leading ? invokeFunc(time) : result;
    }
  
    function remainingWait(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime,
          result = wait - timeSinceLastCall;
  
      return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
    }
  
    function shouldInvoke(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime;
  
      // Either this is the first call, activity has stopped and we're at the
      // trailing edge, the system time has gone backwards and we're treating
      // it as the trailing edge, or we've hit the `maxWait` limit.
      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
    }
  
    function timerExpired() {
      var time = now();
      if (shouldInvoke(time)) {
        return trailingEdge(time);
      }
      // Restart the timer.
      timerId = setTimeout(timerExpired, remainingWait(time));
    }
  
    function trailingEdge(time) {
      timerId = undefined;
  
      // Only invoke if we have `lastArgs` which means `func` has been
      // debounced at least once.
      if (trailing && lastArgs) {
        return invokeFunc(time);
      }
      lastArgs = lastThis = undefined;
      return result;
    }
  
    function cancel() {
      if (timerId !== undefined) {
        clearTimeout(timerId);
      }
      lastInvokeTime = 0;
      lastArgs = lastCallTime = lastThis = timerId = undefined;
    }
  
    function flush() {
      return timerId === undefined ? result : trailingEdge(now());
    }
  
    function debounced() {
      var time = now(),
          isInvoking = shouldInvoke(time);
  
      lastArgs = arguments;
      lastThis = this;
      lastCallTime = time;
  
      if (isInvoking) {
        if (timerId === undefined) {
          return leadingEdge(lastCallTime);
        }
        if (maxing) {
          // Handle invocations in a tight loop.
          timerId = setTimeout(timerExpired, wait);
          return invokeFunc(lastCallTime);
        }
      }
      if (timerId === undefined) {
        timerId = setTimeout(timerExpired, wait);
      }
      return result;
    }
    debounced.cancel = cancel;
    debounced.flush = flush;
    return debounced;
  }
  
  /**
   * Checks if `value` is the
   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
   * @example
   *
   * _.isObject({});
   * // => true
   *
   * _.isObject([1, 2, 3]);
   * // => true
   *
   * _.isObject(_.noop);
   * // => true
   *
   * _.isObject(null);
   * // => false
   */
  function isObject(value) {
    var type = typeof value;
    return !!value && (type == 'object' || type == 'function');
  }
  
  /**
   * Checks if `value` is object-like. A value is object-like if it's not `null`
   * and has a `typeof` result of "object".
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   * @example
   *
   * _.isObjectLike({});
   * // => true
   *
   * _.isObjectLike([1, 2, 3]);
   * // => true
   *
   * _.isObjectLike(_.noop);
   * // => false
   *
   * _.isObjectLike(null);
   * // => false
   */
  function isObjectLike(value) {
    return !!value && typeof value == 'object';
  }
  
  /**
   * Checks if `value` is classified as a `Symbol` primitive or object.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
   * @example
   *
   * _.isSymbol(Symbol.iterator);
   * // => true
   *
   * _.isSymbol('abc');
   * // => false
   */
  function isSymbol(value) {
    return typeof value == 'symbol' ||
      (isObjectLike(value) && objectToString.call(value) == symbolTag);
  }
  
  /**
   * Converts `value` to a number.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to process.
   * @returns {number} Returns the number.
   * @example
   *
   * _.toNumber(3.2);
   * // => 3.2
   *
   * _.toNumber(Number.MIN_VALUE);
   * // => 5e-324
   *
   * _.toNumber(Infinity);
   * // => Infinity
   *
   * _.toNumber('3.2');
   * // => 3.2
   */
  function toNumber(value) {
    if (typeof value == 'number') {
      return value;
    }
    if (isSymbol(value)) {
      return NAN;
    }
    if (isObject(value)) {
      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
      value = isObject(other) ? (other + '') : other;
    }
    if (typeof value != 'string') {
      return value === 0 ? value : +value;
    }
    value = value.replace(reTrim, '');
    var isBinary = reIsBinary.test(value);
    return (isBinary || reIsOctal.test(value))
      ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
      : (reIsBadHex.test(value) ? NAN : +value);
  }
  
  module.exports = debounce;
  
  
  /***/ }),
  
  /***/ "./node_modules/lodash.memoize/index.js":
  /*!**********************************************!*\
    !*** ./node_modules/lodash.memoize/index.js ***!
    \**********************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  /**
   * lodash (Custom Build) <https://lodash.com/>
   * Build: `lodash modularize exports="npm" -o ./`
   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
   * Released under MIT license <https://lodash.com/license>
   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
   */
  
  /** Used as the `TypeError` message for "Functions" methods. */
  var FUNC_ERROR_TEXT = 'Expected a function';
  
  /** Used to stand-in for `undefined` hash values. */
  var HASH_UNDEFINED = '__lodash_hash_undefined__';
  
  /** `Object#toString` result references. */
  var funcTag = '[object Function]',
      genTag = '[object GeneratorFunction]';
  
  /**
   * Used to match `RegExp`
   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
   */
  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  
  /** Used to detect host constructors (Safari). */
  var reIsHostCtor = /^\[object .+?Constructor\]$/;
  
  /** Detect free variable `global` from Node.js. */
  var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
  
  /** Detect free variable `self`. */
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  
  /** Used as a reference to the global object. */
  var root = freeGlobal || freeSelf || Function('return this')();
  
  /**
   * Gets the value at `key` of `object`.
   *
   * @private
   * @param {Object} [object] The object to query.
   * @param {string} key The key of the property to get.
   * @returns {*} Returns the property value.
   */
  function getValue(object, key) {
    return object == null ? undefined : object[key];
  }
  
  /**
   * Checks if `value` is a host object in IE < 9.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
   */
  function isHostObject(value) {
    // Many host objects are `Object` objects that can coerce to strings
    // despite having improperly defined `toString` methods.
    var result = false;
    if (value != null && typeof value.toString != 'function') {
      try {
        result = !!(value + '');
      } catch (e) {}
    }
    return result;
  }
  
  /** Used for built-in method references. */
  var arrayProto = Array.prototype,
      funcProto = Function.prototype,
      objectProto = Object.prototype;
  
  /** Used to detect overreaching core-js shims. */
  var coreJsData = root['__core-js_shared__'];
  
  /** Used to detect methods masquerading as native. */
  var maskSrcKey = (function() {
    var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
    return uid ? ('Symbol(src)_1.' + uid) : '';
  }());
  
  /** Used to resolve the decompiled source of functions. */
  var funcToString = funcProto.toString;
  
  /** Used to check objects for own properties. */
  var hasOwnProperty = objectProto.hasOwnProperty;
  
  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var objectToString = objectProto.toString;
  
  /** Used to detect if a method is native. */
  var reIsNative = RegExp('^' +
    funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  );
  
  /** Built-in value references. */
  var splice = arrayProto.splice;
  
  /* Built-in method references that are verified to be native. */
  var Map = getNative(root, 'Map'),
      nativeCreate = getNative(Object, 'create');
  
  /**
   * Creates a hash object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function Hash(entries) {
    var index = -1,
        length = entries ? entries.length : 0;
  
    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }
  
  /**
   * Removes all key-value entries from the hash.
   *
   * @private
   * @name clear
   * @memberOf Hash
   */
  function hashClear() {
    this.__data__ = nativeCreate ? nativeCreate(null) : {};
  }
  
  /**
   * Removes `key` and its value from the hash.
   *
   * @private
   * @name delete
   * @memberOf Hash
   * @param {Object} hash The hash to modify.
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function hashDelete(key) {
    return this.has(key) && delete this.__data__[key];
  }
  
  /**
   * Gets the hash value for `key`.
   *
   * @private
   * @name get
   * @memberOf Hash
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function hashGet(key) {
    var data = this.__data__;
    if (nativeCreate) {
      var result = data[key];
      return result === HASH_UNDEFINED ? undefined : result;
    }
    return hasOwnProperty.call(data, key) ? data[key] : undefined;
  }
  
  /**
   * Checks if a hash value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf Hash
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function hashHas(key) {
    var data = this.__data__;
    return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
  }
  
  /**
   * Sets the hash `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf Hash
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the hash instance.
   */
  function hashSet(key, value) {
    var data = this.__data__;
    data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
    return this;
  }
  
  // Add methods to `Hash`.
  Hash.prototype.clear = hashClear;
  Hash.prototype['delete'] = hashDelete;
  Hash.prototype.get = hashGet;
  Hash.prototype.has = hashHas;
  Hash.prototype.set = hashSet;
  
  /**
   * Creates an list cache object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function ListCache(entries) {
    var index = -1,
        length = entries ? entries.length : 0;
  
    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }
  
  /**
   * Removes all key-value entries from the list cache.
   *
   * @private
   * @name clear
   * @memberOf ListCache
   */
  function listCacheClear() {
    this.__data__ = [];
  }
  
  /**
   * Removes `key` and its value from the list cache.
   *
   * @private
   * @name delete
   * @memberOf ListCache
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function listCacheDelete(key) {
    var data = this.__data__,
        index = assocIndexOf(data, key);
  
    if (index < 0) {
      return false;
    }
    var lastIndex = data.length - 1;
    if (index == lastIndex) {
      data.pop();
    } else {
      splice.call(data, index, 1);
    }
    return true;
  }
  
  /**
   * Gets the list cache value for `key`.
   *
   * @private
   * @name get
   * @memberOf ListCache
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function listCacheGet(key) {
    var data = this.__data__,
        index = assocIndexOf(data, key);
  
    return index < 0 ? undefined : data[index][1];
  }
  
  /**
   * Checks if a list cache value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf ListCache
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function listCacheHas(key) {
    return assocIndexOf(this.__data__, key) > -1;
  }
  
  /**
   * Sets the list cache `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf ListCache
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the list cache instance.
   */
  function listCacheSet(key, value) {
    var data = this.__data__,
        index = assocIndexOf(data, key);
  
    if (index < 0) {
      data.push([key, value]);
    } else {
      data[index][1] = value;
    }
    return this;
  }
  
  // Add methods to `ListCache`.
  ListCache.prototype.clear = listCacheClear;
  ListCache.prototype['delete'] = listCacheDelete;
  ListCache.prototype.get = listCacheGet;
  ListCache.prototype.has = listCacheHas;
  ListCache.prototype.set = listCacheSet;
  
  /**
   * Creates a map cache object to store key-value pairs.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function MapCache(entries) {
    var index = -1,
        length = entries ? entries.length : 0;
  
    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }
  
  /**
   * Removes all key-value entries from the map.
   *
   * @private
   * @name clear
   * @memberOf MapCache
   */
  function mapCacheClear() {
    this.__data__ = {
      'hash': new Hash,
      'map': new (Map || ListCache),
      'string': new Hash
    };
  }
  
  /**
   * Removes `key` and its value from the map.
   *
   * @private
   * @name delete
   * @memberOf MapCache
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function mapCacheDelete(key) {
    return getMapData(this, key)['delete'](key);
  }
  
  /**
   * Gets the map value for `key`.
   *
   * @private
   * @name get
   * @memberOf MapCache
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function mapCacheGet(key) {
    return getMapData(this, key).get(key);
  }
  
  /**
   * Checks if a map value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf MapCache
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function mapCacheHas(key) {
    return getMapData(this, key).has(key);
  }
  
  /**
   * Sets the map `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf MapCache
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the map cache instance.
   */
  function mapCacheSet(key, value) {
    getMapData(this, key).set(key, value);
    return this;
  }
  
  // Add methods to `MapCache`.
  MapCache.prototype.clear = mapCacheClear;
  MapCache.prototype['delete'] = mapCacheDelete;
  MapCache.prototype.get = mapCacheGet;
  MapCache.prototype.has = mapCacheHas;
  MapCache.prototype.set = mapCacheSet;
  
  /**
   * Gets the index at which the `key` is found in `array` of key-value pairs.
   *
   * @private
   * @param {Array} array The array to inspect.
   * @param {*} key The key to search for.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function assocIndexOf(array, key) {
    var length = array.length;
    while (length--) {
      if (eq(array[length][0], key)) {
        return length;
      }
    }
    return -1;
  }
  
  /**
   * The base implementation of `_.isNative` without bad shim checks.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a native function,
   *  else `false`.
   */
  function baseIsNative(value) {
    if (!isObject(value) || isMasked(value)) {
      return false;
    }
    var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
    return pattern.test(toSource(value));
  }
  
  /**
   * Gets the data for `map`.
   *
   * @private
   * @param {Object} map The map to query.
   * @param {string} key The reference key.
   * @returns {*} Returns the map data.
   */
  function getMapData(map, key) {
    var data = map.__data__;
    return isKeyable(key)
      ? data[typeof key == 'string' ? 'string' : 'hash']
      : data.map;
  }
  
  /**
   * Gets the native function at `key` of `object`.
   *
   * @private
   * @param {Object} object The object to query.
   * @param {string} key The key of the method to get.
   * @returns {*} Returns the function if it's native, else `undefined`.
   */
  function getNative(object, key) {
    var value = getValue(object, key);
    return baseIsNative(value) ? value : undefined;
  }
  
  /**
   * Checks if `value` is suitable for use as unique object key.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
   */
  function isKeyable(value) {
    var type = typeof value;
    return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
      ? (value !== '__proto__')
      : (value === null);
  }
  
  /**
   * Checks if `func` has its source masked.
   *
   * @private
   * @param {Function} func The function to check.
   * @returns {boolean} Returns `true` if `func` is masked, else `false`.
   */
  function isMasked(func) {
    return !!maskSrcKey && (maskSrcKey in func);
  }
  
  /**
   * Converts `func` to its source code.
   *
   * @private
   * @param {Function} func The function to process.
   * @returns {string} Returns the source code.
   */
  function toSource(func) {
    if (func != null) {
      try {
        return funcToString.call(func);
      } catch (e) {}
      try {
        return (func + '');
      } catch (e) {}
    }
    return '';
  }
  
  /**
   * Creates a function that memoizes the result of `func`. If `resolver` is
   * provided, it determines the cache key for storing the result based on the
   * arguments provided to the memoized function. By default, the first argument
   * provided to the memoized function is used as the map cache key. The `func`
   * is invoked with the `this` binding of the memoized function.
   *
   * **Note:** The cache is exposed as the `cache` property on the memoized
   * function. Its creation may be customized by replacing the `_.memoize.Cache`
   * constructor with one whose instances implement the
   * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
   * method interface of `delete`, `get`, `has`, and `set`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to have its output memoized.
   * @param {Function} [resolver] The function to resolve the cache key.
   * @returns {Function} Returns the new memoized function.
   * @example
   *
   * var object = { 'a': 1, 'b': 2 };
   * var other = { 'c': 3, 'd': 4 };
   *
   * var values = _.memoize(_.values);
   * values(object);
   * // => [1, 2]
   *
   * values(other);
   * // => [3, 4]
   *
   * object.a = 2;
   * values(object);
   * // => [1, 2]
   *
   * // Modify the result cache.
   * values.cache.set(object, ['a', 'b']);
   * values(object);
   * // => ['a', 'b']
   *
   * // Replace `_.memoize.Cache`.
   * _.memoize.Cache = WeakMap;
   */
  function memoize(func, resolver) {
    if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    var memoized = function() {
      var args = arguments,
          key = resolver ? resolver.apply(this, args) : args[0],
          cache = memoized.cache;
  
      if (cache.has(key)) {
        return cache.get(key);
      }
      var result = func.apply(this, args);
      memoized.cache = cache.set(key, result);
      return result;
    };
    memoized.cache = new (memoize.Cache || MapCache);
    return memoized;
  }
  
  // Assign cache to `_.memoize`.
  memoize.Cache = MapCache;
  
  /**
   * Performs a
   * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
   * comparison between two values to determine if they are equivalent.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to compare.
   * @param {*} other The other value to compare.
   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
   * @example
   *
   * var object = { 'a': 1 };
   * var other = { 'a': 1 };
   *
   * _.eq(object, object);
   * // => true
   *
   * _.eq(object, other);
   * // => false
   *
   * _.eq('a', 'a');
   * // => true
   *
   * _.eq('a', Object('a'));
   * // => false
   *
   * _.eq(NaN, NaN);
   * // => true
   */
  function eq(value, other) {
    return value === other || (value !== value && other !== other);
  }
  
  /**
   * Checks if `value` is classified as a `Function` object.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a function, else `false`.
   * @example
   *
   * _.isFunction(_);
   * // => true
   *
   * _.isFunction(/abc/);
   * // => false
   */
  function isFunction(value) {
    // The use of `Object#toString` avoids issues with the `typeof` operator
    // in Safari 8-9 which returns 'object' for typed array and other constructors.
    var tag = isObject(value) ? objectToString.call(value) : '';
    return tag == funcTag || tag == genTag;
  }
  
  /**
   * Checks if `value` is the
   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
   * @example
   *
   * _.isObject({});
   * // => true
   *
   * _.isObject([1, 2, 3]);
   * // => true
   *
   * _.isObject(_.noop);
   * // => true
   *
   * _.isObject(null);
   * // => false
   */
  function isObject(value) {
    var type = typeof value;
    return !!value && (type == 'object' || type == 'function');
  }
  
  module.exports = memoize;
  
  
  /***/ }),
  
  /***/ "./node_modules/lodash.throttle/index.js":
  /*!***********************************************!*\
    !*** ./node_modules/lodash.throttle/index.js ***!
    \***********************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  /**
   * lodash (Custom Build) <https://lodash.com/>
   * Build: `lodash modularize exports="npm" -o ./`
   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
   * Released under MIT license <https://lodash.com/license>
   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
   */
  
  /** Used as the `TypeError` message for "Functions" methods. */
  var FUNC_ERROR_TEXT = 'Expected a function';
  
  /** Used as references for various `Number` constants. */
  var NAN = 0 / 0;
  
  /** `Object#toString` result references. */
  var symbolTag = '[object Symbol]';
  
  /** Used to match leading and trailing whitespace. */
  var reTrim = /^\s+|\s+$/g;
  
  /** Used to detect bad signed hexadecimal string values. */
  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  
  /** Used to detect binary string values. */
  var reIsBinary = /^0b[01]+$/i;
  
  /** Used to detect octal string values. */
  var reIsOctal = /^0o[0-7]+$/i;
  
  /** Built-in method references without a dependency on `root`. */
  var freeParseInt = parseInt;
  
  /** Detect free variable `global` from Node.js. */
  var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
  
  /** Detect free variable `self`. */
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  
  /** Used as a reference to the global object. */
  var root = freeGlobal || freeSelf || Function('return this')();
  
  /** Used for built-in method references. */
  var objectProto = Object.prototype;
  
  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var objectToString = objectProto.toString;
  
  /* Built-in method references for those with the same name as other `lodash` methods. */
  var nativeMax = Math.max,
      nativeMin = Math.min;
  
  /**
   * Gets the timestamp of the number of milliseconds that have elapsed since
   * the Unix epoch (1 January 1970 00:00:00 UTC).
   *
   * @static
   * @memberOf _
   * @since 2.4.0
   * @category Date
   * @returns {number} Returns the timestamp.
   * @example
   *
   * _.defer(function(stamp) {
   *   console.log(_.now() - stamp);
   * }, _.now());
   * // => Logs the number of milliseconds it took for the deferred invocation.
   */
  var now = function() {
    return root.Date.now();
  };
  
  /**
   * Creates a debounced function that delays invoking `func` until after `wait`
   * milliseconds have elapsed since the last time the debounced function was
   * invoked. The debounced function comes with a `cancel` method to cancel
   * delayed `func` invocations and a `flush` method to immediately invoke them.
   * Provide `options` to indicate whether `func` should be invoked on the
   * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
   * with the last arguments provided to the debounced function. Subsequent
   * calls to the debounced function return the result of the last `func`
   * invocation.
   *
   * **Note:** If `leading` and `trailing` options are `true`, `func` is
   * invoked on the trailing edge of the timeout only if the debounced function
   * is invoked more than once during the `wait` timeout.
   *
   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
   *
   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
   * for details over the differences between `_.debounce` and `_.throttle`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to debounce.
   * @param {number} [wait=0] The number of milliseconds to delay.
   * @param {Object} [options={}] The options object.
   * @param {boolean} [options.leading=false]
   *  Specify invoking on the leading edge of the timeout.
   * @param {number} [options.maxWait]
   *  The maximum time `func` is allowed to be delayed before it's invoked.
   * @param {boolean} [options.trailing=true]
   *  Specify invoking on the trailing edge of the timeout.
   * @returns {Function} Returns the new debounced function.
   * @example
   *
   * // Avoid costly calculations while the window size is in flux.
   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
   *
   * // Invoke `sendMail` when clicked, debouncing subsequent calls.
   * jQuery(element).on('click', _.debounce(sendMail, 300, {
   *   'leading': true,
   *   'trailing': false
   * }));
   *
   * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
   * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
   * var source = new EventSource('/stream');
   * jQuery(source).on('message', debounced);
   *
   * // Cancel the trailing debounced invocation.
   * jQuery(window).on('popstate', debounced.cancel);
   */
  function debounce(func, wait, options) {
    var lastArgs,
        lastThis,
        maxWait,
        result,
        timerId,
        lastCallTime,
        lastInvokeTime = 0,
        leading = false,
        maxing = false,
        trailing = true;
  
    if (typeof func != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    wait = toNumber(wait) || 0;
    if (isObject(options)) {
      leading = !!options.leading;
      maxing = 'maxWait' in options;
      maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
      trailing = 'trailing' in options ? !!options.trailing : trailing;
    }
  
    function invokeFunc(time) {
      var args = lastArgs,
          thisArg = lastThis;
  
      lastArgs = lastThis = undefined;
      lastInvokeTime = time;
      result = func.apply(thisArg, args);
      return result;
    }
  
    function leadingEdge(time) {
      // Reset any `maxWait` timer.
      lastInvokeTime = time;
      // Start the timer for the trailing edge.
      timerId = setTimeout(timerExpired, wait);
      // Invoke the leading edge.
      return leading ? invokeFunc(time) : result;
    }
  
    function remainingWait(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime,
          result = wait - timeSinceLastCall;
  
      return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
    }
  
    function shouldInvoke(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime;
  
      // Either this is the first call, activity has stopped and we're at the
      // trailing edge, the system time has gone backwards and we're treating
      // it as the trailing edge, or we've hit the `maxWait` limit.
      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
    }
  
    function timerExpired() {
      var time = now();
      if (shouldInvoke(time)) {
        return trailingEdge(time);
      }
      // Restart the timer.
      timerId = setTimeout(timerExpired, remainingWait(time));
    }
  
    function trailingEdge(time) {
      timerId = undefined;
  
      // Only invoke if we have `lastArgs` which means `func` has been
      // debounced at least once.
      if (trailing && lastArgs) {
        return invokeFunc(time);
      }
      lastArgs = lastThis = undefined;
      return result;
    }
  
    function cancel() {
      if (timerId !== undefined) {
        clearTimeout(timerId);
      }
      lastInvokeTime = 0;
      lastArgs = lastCallTime = lastThis = timerId = undefined;
    }
  
    function flush() {
      return timerId === undefined ? result : trailingEdge(now());
    }
  
    function debounced() {
      var time = now(),
          isInvoking = shouldInvoke(time);
  
      lastArgs = arguments;
      lastThis = this;
      lastCallTime = time;
  
      if (isInvoking) {
        if (timerId === undefined) {
          return leadingEdge(lastCallTime);
        }
        if (maxing) {
          // Handle invocations in a tight loop.
          timerId = setTimeout(timerExpired, wait);
          return invokeFunc(lastCallTime);
        }
      }
      if (timerId === undefined) {
        timerId = setTimeout(timerExpired, wait);
      }
      return result;
    }
    debounced.cancel = cancel;
    debounced.flush = flush;
    return debounced;
  }
  
  /**
   * Creates a throttled function that only invokes `func` at most once per
   * every `wait` milliseconds. The throttled function comes with a `cancel`
   * method to cancel delayed `func` invocations and a `flush` method to
   * immediately invoke them. Provide `options` to indicate whether `func`
   * should be invoked on the leading and/or trailing edge of the `wait`
   * timeout. The `func` is invoked with the last arguments provided to the
   * throttled function. Subsequent calls to the throttled function return the
   * result of the last `func` invocation.
   *
   * **Note:** If `leading` and `trailing` options are `true`, `func` is
   * invoked on the trailing edge of the timeout only if the throttled function
   * is invoked more than once during the `wait` timeout.
   *
   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
   *
   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
   * for details over the differences between `_.throttle` and `_.debounce`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to throttle.
   * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
   * @param {Object} [options={}] The options object.
   * @param {boolean} [options.leading=true]
   *  Specify invoking on the leading edge of the timeout.
   * @param {boolean} [options.trailing=true]
   *  Specify invoking on the trailing edge of the timeout.
   * @returns {Function} Returns the new throttled function.
   * @example
   *
   * // Avoid excessively updating the position while scrolling.
   * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
   *
   * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
   * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
   * jQuery(element).on('click', throttled);
   *
   * // Cancel the trailing throttled invocation.
   * jQuery(window).on('popstate', throttled.cancel);
   */
  function throttle(func, wait, options) {
    var leading = true,
        trailing = true;
  
    if (typeof func != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    if (isObject(options)) {
      leading = 'leading' in options ? !!options.leading : leading;
      trailing = 'trailing' in options ? !!options.trailing : trailing;
    }
    return debounce(func, wait, {
      'leading': leading,
      'maxWait': wait,
      'trailing': trailing
    });
  }
  
  /**
   * Checks if `value` is the
   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
   * @example
   *
   * _.isObject({});
   * // => true
   *
   * _.isObject([1, 2, 3]);
   * // => true
   *
   * _.isObject(_.noop);
   * // => true
   *
   * _.isObject(null);
   * // => false
   */
  function isObject(value) {
    var type = typeof value;
    return !!value && (type == 'object' || type == 'function');
  }
  
  /**
   * Checks if `value` is object-like. A value is object-like if it's not `null`
   * and has a `typeof` result of "object".
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   * @example
   *
   * _.isObjectLike({});
   * // => true
   *
   * _.isObjectLike([1, 2, 3]);
   * // => true
   *
   * _.isObjectLike(_.noop);
   * // => false
   *
   * _.isObjectLike(null);
   * // => false
   */
  function isObjectLike(value) {
    return !!value && typeof value == 'object';
  }
  
  /**
   * Checks if `value` is classified as a `Symbol` primitive or object.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
   * @example
   *
   * _.isSymbol(Symbol.iterator);
   * // => true
   *
   * _.isSymbol('abc');
   * // => false
   */
  function isSymbol(value) {
    return typeof value == 'symbol' ||
      (isObjectLike(value) && objectToString.call(value) == symbolTag);
  }
  
  /**
   * Converts `value` to a number.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to process.
   * @returns {number} Returns the number.
   * @example
   *
   * _.toNumber(3.2);
   * // => 3.2
   *
   * _.toNumber(Number.MIN_VALUE);
   * // => 5e-324
   *
   * _.toNumber(Infinity);
   * // => Infinity
   *
   * _.toNumber('3.2');
   * // => 3.2
   */
  function toNumber(value) {
    if (typeof value == 'number') {
      return value;
    }
    if (isSymbol(value)) {
      return NAN;
    }
    if (isObject(value)) {
      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
      value = isObject(other) ? (other + '') : other;
    }
    if (typeof value != 'string') {
      return value === 0 ? value : +value;
    }
    value = value.replace(reTrim, '');
    var isBinary = reIsBinary.test(value);
    return (isBinary || reIsOctal.test(value))
      ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
      : (reIsBadHex.test(value) ? NAN : +value);
  }
  
  module.exports = throttle;
  
  
  /***/ }),
  
  /***/ "./node_modules/lozad/dist/lozad.min.js":
  /*!**********************************************!*\
    !*** ./node_modules/lozad/dist/lozad.min.js ***!
    \**********************************************/
  /***/ (function(module) {
  
  /*! lozad.js - v1.16.0 - 2020-09-06
  * https://github.com/ApoorvSaxena/lozad.js
  * Copyright (c) 2020 Apoorv Saxena; Licensed MIT */
  !function(t,e){ true?module.exports=e():0}(this,function(){"use strict";
  /**
     * Detect IE browser
     * @const {boolean}
     * @private
     */var g="undefined"!=typeof document&&document.documentMode,f={rootMargin:"0px",threshold:0,load:function(t){if("picture"===t.nodeName.toLowerCase()){var e=t.querySelector("img"),r=!1;null===e&&(e=document.createElement("img"),r=!0),g&&t.getAttribute("data-iesrc")&&(e.src=t.getAttribute("data-iesrc")),t.getAttribute("data-alt")&&(e.alt=t.getAttribute("data-alt")),r&&t.append(e)}if("video"===t.nodeName.toLowerCase()&&!t.getAttribute("data-src")&&t.children){for(var a=t.children,o=void 0,i=0;i<=a.length-1;i++)(o=a[i].getAttribute("data-src"))&&(a[i].src=o);t.load()}t.getAttribute("data-poster")&&(t.poster=t.getAttribute("data-poster")),t.getAttribute("data-src")&&(t.src=t.getAttribute("data-src")),t.getAttribute("data-srcset")&&t.setAttribute("srcset",t.getAttribute("data-srcset"));var n=",";if(t.getAttribute("data-background-delimiter")&&(n=t.getAttribute("data-background-delimiter")),t.getAttribute("data-background-image"))t.style.backgroundImage="url('"+t.getAttribute("data-background-image").split(n).join("'),url('")+"')";else if(t.getAttribute("data-background-image-set")){var d=t.getAttribute("data-background-image-set").split(n),u=d[0].substr(0,d[0].indexOf(" "))||d[0];// Substring before ... 1x
  u=-1===u.indexOf("url(")?"url("+u+")":u,1===d.length?t.style.backgroundImage=u:t.setAttribute("style",(t.getAttribute("style")||"")+"background-image: "+u+"; background-image: -webkit-image-set("+d+"); background-image: image-set("+d+")")}t.getAttribute("data-toggle-class")&&t.classList.toggle(t.getAttribute("data-toggle-class"))},loaded:function(){}};function A(t){t.setAttribute("data-loaded",!0)}var m=function(t){return"true"===t.getAttribute("data-loaded")},v=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:document;return t instanceof Element?[t]:t instanceof NodeList?t:e.querySelectorAll(t)};return function(){var r,a,o=0<arguments.length&&void 0!==arguments[0]?arguments[0]:".lozad",t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=Object.assign({},f,t),i=e.root,n=e.rootMargin,d=e.threshold,u=e.load,g=e.loaded,s=void 0;"undefined"!=typeof window&&window.IntersectionObserver&&(s=new IntersectionObserver((r=u,a=g,function(t,e){t.forEach(function(t){(0<t.intersectionRatio||t.isIntersecting)&&(e.unobserve(t.target),m(t.target)||(r(t.target),A(t.target),a(t.target)))})}),{root:i,rootMargin:n,threshold:d}));for(var c,l=v(o,i),b=0;b<l.length;b++)(c=l[b]).getAttribute("data-placeholder-background")&&(c.style.background=c.getAttribute("data-placeholder-background"));return{observe:function(){for(var t=v(o,i),e=0;e<t.length;e++)m(t[e])||(s?s.observe(t[e]):(u(t[e]),A(t[e]),g(t[e])))},triggerLoad:function(t){m(t)||(u(t),A(t),g(t))},observer:s}}});
  
  
  /***/ }),
  
  /***/ "./resources/css/home.scss":
  /*!*********************************!*\
    !*** ./resources/css/home.scss ***!
    \*********************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  // extracted by mini-css-extract-plugin
  
  
  /***/ }),
  
  /***/ "./resources/css/catalog.scss":
  /*!************************************!*\
    !*** ./resources/css/catalog.scss ***!
    \************************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  // extracted by mini-css-extract-plugin
  
  
  /***/ }),
  
  /***/ "./node_modules/mobile-detect/mobile-detect.js":
  /*!*****************************************************!*\
    !*** ./node_modules/mobile-detect/mobile-detect.js ***!
    \*****************************************************/
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  
  // THIS FILE IS GENERATED - DO NOT EDIT!
  /*!mobile-detect v1.4.5 2021-03-13*/
  /*global module:false, define:false*/
  /*jshint latedef:false*/
  /*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
  (function (define, undefined) {
  define(function () {
      'use strict';
  
      var impl = {};
  
      impl.mobileDetectRules = {
      "phones": {
          "iPhone": "\\biPhone\\b|\\biPod\\b",
          "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+",
          "Pixel": "; \\bPixel\\b",
          "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel",
          "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6",
          "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",
          "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052",
          "Samsung": "\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F",
          "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710",
          "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332",
          "Asus": "Asus.*Galaxy|PadFone.*Mobile",
          "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G",
          "NokiaLumia": "Lumia [0-9]{3,4}",
          "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",
          "Palm": "PalmSource|Palm",
          "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",
          "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",
          "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",
          "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",
          "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",
          "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",
          "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",
          "Alcatel": "Alcatel",
          "Nintendo": "Nintendo (3DS|Switch)",
          "Amoi": "Amoi",
          "INQ": "INQ",
          "OnePlus": "ONEPLUS",
          "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"
      },
      "tablets": {
          "iPad": "iPad|iPad.*Mobile",
          "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)",
          "GoogleTablet": "Android.*Pixel C",
          "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860",
          "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)",
          "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",
          "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",
          "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b",
          "BlackBerryTablet": "PlayBook|RIM Tablet",
          "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",
          "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",
          "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",
          "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40",
          "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",
          "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",
          "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",
          "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",
          "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L",
          "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",
          "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",
          "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",
          "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",
          "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",
          "IRUTablet": "M702pro",
          "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",
          "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",
          "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",
          "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",
          "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",
          "NokiaLumiaTablet": "Lumia 2520",
          "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712",
          "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",
          "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",
          "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",
          "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",
          "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",
          "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",
          "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",
          "FlyTablet": "IQ310|Fly Vision",
          "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus",
          "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19",
          "NecTablet": "\\bN-06D|\\bN-08D",
          "PantechTablet": "Pantech.*P4100",
          "BronchoTablet": "Broncho.*(N701|N708|N802|a710)",
          "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",
          "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900",
          "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA",
          "NabiTablet": "Android.*\\bNabi",
          "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",
          "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",
          "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",
          "PlaystationTablet": "Playstation.*(Portable|Vita)",
          "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",
          "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",
          "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",
          "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",
          "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b",
          "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",
          "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",
          "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",
          "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",
          "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",
          "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",
          "GUTablet": "TX-A1301|TX-M9002|Q702|kf026",
          "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",
          "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027",
          "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",
          "DPSTablet": "DPS Dream 9|DPS Dual 7",
          "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",
          "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",
          "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b",
          "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan",
          "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",
          "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",
          "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",
          "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1",
          "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",
          "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400",
          "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",
          "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",
          "iMobileTablet": "i-mobile i-note",
          "TolinoTablet": "tolino tab [0-9.]+|tolino shine",
          "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b",
          "AMPETablet": "Android.* A78 ",
          "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)",
          "TecnoTablet": "TECNO P9|TECNO DP8D",
          "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",
          "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",
          "FX2Tablet": "FX2 PAD7|FX2 PAD10",
          "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",
          "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",
          "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1",
          "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",
          "CaptivaTablet": "CAPTIVA PAD",
          "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",
          "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",
          "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b",
          "JaytechTablet": "TPC-PA762",
          "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010",
          "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",
          "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",
          "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",
          "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",
          "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",
          "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",
          "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",
          "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA",
          "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b",
          "NibiruTablet": "Nibiru M1|Nibiru Jupiter One",
          "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",
          "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",
          "UbislateTablet": "UbiSlate[\\s]?7C",
          "PocketBookTablet": "Pocketbook",
          "KocasoTablet": "\\b(TB-1207)\\b",
          "HisenseTablet": "\\b(F5281|E2371)\\b",
          "Hudl": "Hudl HT7S3|Hudl 2",
          "TelstraTablet": "T-Hub2",
          "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"
      },
      "oss": {
          "AndroidOS": "Android",
          "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os",
          "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",
          "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",
          "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;",
          "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",
          "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia",
          "iPadOS": "CPU OS 13",
          "SailfishOS": "Sailfish",
          "MeeGoOS": "MeeGo",
          "MaemoOS": "Maemo",
          "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b",
          "webOS": "webOS|hpwOS",
          "badaOS": "\\bBada\\b",
          "BREWOS": "BREW"
      },
      "uas": {
          "Chrome": "\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?",
          "Dolfin": "\\bDolfin\\b",
          "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+",
          "Skyfire": "Skyfire",
          "Edge": "\\bEdgiOS\\b|Mobile Safari\/[.0-9]* Edge",
          "IE": "IEMobile|MSIEMobile",
          "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",
          "Bolt": "bolt",
          "TeaShark": "teashark",
          "Blazer": "Blazer",
          "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari",
          "WeChat": "\\bMicroMessenger\\b",
          "UCBrowser": "UC.*Browser|UCWEB",
          "baiduboxapp": "baiduboxapp",
          "baidubrowser": "baidubrowser",
          "DiigoBrowser": "DiigoBrowser",
          "Mercury": "\\bMercury\\b",
          "ObigoBrowser": "Obigo",
          "NetFront": "NF-Browser",
          "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",
          "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon"
      },
      "props": {
          "Mobile": "Mobile\/[VER]",
          "Build": "Build\/[VER]",
          "Version": "Version\/[VER]",
          "VendorID": "VendorID\/[VER]",
          "iPad": "iPad.*CPU[a-z ]+[VER]",
          "iPhone": "iPhone.*CPU[a-z ]+[VER]",
          "iPod": "iPod.*CPU[a-z ]+[VER]",
          "Kindle": "Kindle\/[VER]",
          "Chrome": [
              "Chrome\/[VER]",
              "CriOS\/[VER]",
              "CrMo\/[VER]"
          ],
          "Coast": [
              "Coast\/[VER]"
          ],
          "Dolfin": "Dolfin\/[VER]",
          "Firefox": [
              "Firefox\/[VER]",
              "FxiOS\/[VER]"
          ],
          "Fennec": "Fennec\/[VER]",
          "Edge": "Edge\/[VER]",
          "IE": [
              "IEMobile\/[VER];",
              "IEMobile [VER]",
              "MSIE [VER];",
              "Trident\/[0-9.]+;.*rv:[VER]"
          ],
          "NetFront": "NetFront\/[VER]",
          "NokiaBrowser": "NokiaBrowser\/[VER]",
          "Opera": [
              " OPR\/[VER]",
              "Opera Mini\/[VER]",
              "Version\/[VER]"
          ],
          "Opera Mini": "Opera Mini\/[VER]",
          "Opera Mobi": "Version\/[VER]",
          "UCBrowser": [
              "UCWEB[VER]",
              "UC.*Browser\/[VER]"
          ],
          "MQQBrowser": "MQQBrowser\/[VER]",
          "MicroMessenger": "MicroMessenger\/[VER]",
          "baiduboxapp": "baiduboxapp\/[VER]",
          "baidubrowser": "baidubrowser\/[VER]",
          "SamsungBrowser": "SamsungBrowser\/[VER]",
          "Iron": "Iron\/[VER]",
          "Safari": [
              "Version\/[VER]",
              "Safari\/[VER]"
          ],
          "Skyfire": "Skyfire\/[VER]",
          "Tizen": "Tizen\/[VER]",
          "Webkit": "webkit[ \/][VER]",
          "PaleMoon": "PaleMoon\/[VER]",
          "SailfishBrowser": "SailfishBrowser\/[VER]",
          "Gecko": "Gecko\/[VER]",
          "Trident": "Trident\/[VER]",
          "Presto": "Presto\/[VER]",
          "Goanna": "Goanna\/[VER]",
          "iOS": " \\bi?OS\\b [VER][ ;]{1}",
          "Android": "Android [VER]",
          "Sailfish": "Sailfish [VER]",
          "BlackBerry": [
              "BlackBerry[\\w]+\/[VER]",
              "BlackBerry.*Version\/[VER]",
              "Version\/[VER]"
          ],
          "BREW": "BREW [VER]",
          "Java": "Java\/[VER]",
          "Windows Phone OS": [
              "Windows Phone OS [VER]",
              "Windows Phone [VER]"
          ],
          "Windows Phone": "Windows Phone [VER]",
          "Windows CE": "Windows CE\/[VER]",
          "Windows NT": "Windows NT [VER]",
          "Symbian": [
              "SymbianOS\/[VER]",
              "Symbian\/[VER]"
          ],
          "webOS": [
              "webOS\/[VER]",
              "hpwOS\/[VER];"
          ]
      },
      "utils": {
          "Bot": "Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot",
          "MobileBot": "Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2",
          "DesktopMode": "WPDesktop",
          "TV": "SonyDTV|HbbTV",
          "WebKit": "(webkit)[ \/]([\\w.]+)",
          "Console": "\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b",
          "Watch": "SM-V700"
      }
  };
  
      // following patterns come from http://detectmobilebrowsers.com/
      impl.detectMobileBrowsers = {
          fullPattern: /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,
          shortPattern: /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,
          tabletPattern: /android|ipad|playbook|silk/i
      };
  
      var hasOwnProp = Object.prototype.hasOwnProperty,
          isArray;
  
      impl.FALLBACK_PHONE = 'UnknownPhone';
      impl.FALLBACK_TABLET = 'UnknownTablet';
      impl.FALLBACK_MOBILE = 'UnknownMobile';
  
      isArray = ('isArray' in Array) ?
          Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
  
      function equalIC(a, b) {
          return a != null && b != null && a.toLowerCase() === b.toLowerCase();
      }
  
      function containsIC(array, value) {
          var valueLC, i, len = array.length;
          if (!len || !value) {
              return false;
          }
          valueLC = value.toLowerCase();
          for (i = 0; i < len; ++i) {
              if (valueLC === array[i].toLowerCase()) {
                  return true;
              }
          }
          return false;
      }
  
      function convertPropsToRegExp(object) {
          for (var key in object) {
              if (hasOwnProp.call(object, key)) {
                  object[key] = new RegExp(object[key], 'i');
              }
          }
      }
  
      function prepareUserAgent(userAgent) {
          return (userAgent || '').substr(0, 500); // mitigate vulnerable to ReDoS
      }
  
      (function init() {
          var key, values, value, i, len, verPos, mobileDetectRules = impl.mobileDetectRules;
          for (key in mobileDetectRules.props) {
              if (hasOwnProp.call(mobileDetectRules.props, key)) {
                  values = mobileDetectRules.props[key];
                  if (!isArray(values)) {
                      values = [values];
                  }
                  len = values.length;
                  for (i = 0; i < len; ++i) {
                      value = values[i];
                      verPos = value.indexOf('[VER]');
                      if (verPos >= 0) {
                          value = value.substring(0, verPos) + '([\\w._\\+]+)' + value.substring(verPos + 5);
                      }
                      values[i] = new RegExp(value, 'i');
                  }
                  mobileDetectRules.props[key] = values;
              }
          }
          convertPropsToRegExp(mobileDetectRules.oss);
          convertPropsToRegExp(mobileDetectRules.phones);
          convertPropsToRegExp(mobileDetectRules.tablets);
          convertPropsToRegExp(mobileDetectRules.uas);
          convertPropsToRegExp(mobileDetectRules.utils);
  
          // copy some patterns to oss0 which are tested first (see issue#15)
          mobileDetectRules.oss0 = {
              WindowsPhoneOS: mobileDetectRules.oss.WindowsPhoneOS,
              WindowsMobileOS: mobileDetectRules.oss.WindowsMobileOS
          };
      }());
  
      /**
       * Test userAgent string against a set of rules and find the first matched key.
       * @param {Object} rules (key is String, value is RegExp)
       * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
       * @returns {String|null} the matched key if found, otherwise <tt>null</tt>
       * @private
       */
      impl.findMatch = function(rules, userAgent) {
          for (var key in rules) {
              if (hasOwnProp.call(rules, key)) {
                  if (rules[key].test(userAgent)) {
                      return key;
                  }
              }
          }
          return null;
      };
  
      /**
       * Test userAgent string against a set of rules and return an array of matched keys.
       * @param {Object} rules (key is String, value is RegExp)
       * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
       * @returns {Array} an array of matched keys, may be empty when there is no match, but not <tt>null</tt>
       * @private
       */
      impl.findMatches = function(rules, userAgent) {
          var result = [];
          for (var key in rules) {
              if (hasOwnProp.call(rules, key)) {
                  if (rules[key].test(userAgent)) {
                      result.push(key);
                  }
              }
          }
          return result;
      };
  
      /**
       * Check the version of the given property in the User-Agent.
       *
       * @param {String} propertyName
       * @param {String} userAgent
       * @return {String} version or <tt>null</tt> if version not found
       * @private
       */
      impl.getVersionStr = function (propertyName, userAgent) {
          var props = impl.mobileDetectRules.props, patterns, i, len, match;
          if (hasOwnProp.call(props, propertyName)) {
              patterns = props[propertyName];
              len = patterns.length;
              for (i = 0; i < len; ++i) {
                  match = patterns[i].exec(userAgent);
                  if (match !== null) {
                      return match[1];
                  }
              }
          }
          return null;
      };
  
      /**
       * Check the version of the given property in the User-Agent.
       * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
       *
       * @param {String} propertyName
       * @param {String} userAgent
       * @return {Number} version or <tt>NaN</tt> if version not found
       * @private
       */
      impl.getVersion = function (propertyName, userAgent) {
          var version = impl.getVersionStr(propertyName, userAgent);
          return version ? impl.prepareVersionNo(version) : NaN;
      };
  
      /**
       * Prepare the version number.
       *
       * @param {String} version
       * @return {Number} the version number as a floating number
       * @private
       */
      impl.prepareVersionNo = function (version) {
          var numbers;
  
          numbers = version.split(/[a-z._ \/\-]/i);
          if (numbers.length === 1) {
              version = numbers[0];
          }
          if (numbers.length > 1) {
              version = numbers[0] + '.';
              numbers.shift();
              version += numbers.join('');
          }
          return Number(version);
      };
  
      impl.isMobileFallback = function (userAgent) {
          return impl.detectMobileBrowsers.fullPattern.test(userAgent) ||
              impl.detectMobileBrowsers.shortPattern.test(userAgent.substr(0,4));
      };
  
      impl.isTabletFallback = function (userAgent) {
          return impl.detectMobileBrowsers.tabletPattern.test(userAgent);
      };
  
      impl.prepareDetectionCache = function (cache, userAgent, maxPhoneWidth) {
          if (cache.mobile !== undefined) {
              return;
          }
          var phone, tablet, phoneSized;
  
          // first check for stronger tablet rules, then phone (see issue#5)
          tablet = impl.findMatch(impl.mobileDetectRules.tablets, userAgent);
          if (tablet) {
              cache.mobile = cache.tablet = tablet;
              cache.phone = null;
              return; // unambiguously identified as tablet
          }
  
          phone = impl.findMatch(impl.mobileDetectRules.phones, userAgent);
          if (phone) {
              cache.mobile = cache.phone = phone;
              cache.tablet = null;
              return; // unambiguously identified as phone
          }
  
          // our rules haven't found a match -> try more general fallback rules
          if (impl.isMobileFallback(userAgent)) {
              phoneSized = MobileDetect.isPhoneSized(maxPhoneWidth);
              if (phoneSized === undefined) {
                  cache.mobile = impl.FALLBACK_MOBILE;
                  cache.tablet = cache.phone = null;
              } else if (phoneSized) {
                  cache.mobile = cache.phone = impl.FALLBACK_PHONE;
                  cache.tablet = null;
              } else {
                  cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
                  cache.phone = null;
              }
          } else if (impl.isTabletFallback(userAgent)) {
              cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
              cache.phone = null;
          } else {
              // not mobile at all!
              cache.mobile = cache.tablet = cache.phone = null;
          }
      };
  
      // t is a reference to a MobileDetect instance
      impl.mobileGrade = function (t) {
          // impl note:
          // To keep in sync w/ Mobile_Detect.php easily, the following code is tightly aligned to the PHP version.
          // When changes are made in Mobile_Detect.php, copy this method and replace:
          //     $this-> / t.
          //     self::MOBILE_GRADE_(.) / '$1'
          //     , self::VERSION_TYPE_FLOAT / (nothing)
          //     isIOS() / os('iOS')
          //     [reg] / (nothing)   <-- jsdelivr complaining about unescaped unicode character U+00AE
          var $isMobile = t.mobile() !== null;
  
          if (
              // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
              t.os('iOS') && t.version('iPad')>=4.3 ||
              t.os('iOS') && t.version('iPhone')>=3.1 ||
              t.os('iOS') && t.version('iPod')>=3.1 ||
  
              // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
              // Android 3.1 (Honeycomb)  - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
              // Android 4.0 (ICS)  - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
              // Android 4.1 (Jelly Bean)  - Tested on a Galaxy Nexus and Galaxy 7
              ( t.version('Android')>2.1 && t.is('Webkit') ) ||
  
              // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
              t.version('Windows Phone OS')>=7.0 ||
  
              // Blackberry 7 - Tested on BlackBerry Torch 9810
              // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
              t.is('BlackBerry') && t.version('BlackBerry')>=6.0 ||
              // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
              t.match('Playbook.*Tablet') ||
  
              // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
              ( t.version('webOS')>=1.4 && t.match('Palm|Pre|Pixi') ) ||
              // Palm WebOS 3.0  - Tested on HP TouchPad
              t.match('hp.*TouchPad') ||
  
              // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
              ( t.is('Firefox') && t.version('Firefox')>=12 ) ||
  
              // Chrome for Android - Tested on Android 4.0, 4.1 device
              ( t.is('Chrome') && t.is('AndroidOS') && t.version('Android')>=4.0 ) ||
  
              // Skyfire 4.1 - Tested on Android 2.3 device
              ( t.is('Skyfire') && t.version('Skyfire')>=4.1 && t.is('AndroidOS') && t.version('Android')>=2.3 ) ||
  
              // Opera Mobile 11.5-12: Tested on Android 2.3
              ( t.is('Opera') && t.version('Opera Mobi')>11 && t.is('AndroidOS') ) ||
  
              // Meego 1.2 - Tested on Nokia 950 and N9
              t.is('MeeGoOS') ||
  
              // Tizen (pre-release) - Tested on early hardware
              t.is('Tizen') ||
  
              // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
              // @todo: more tests here!
              t.is('Dolfin') && t.version('Bada')>=2.0 ||
  
              // UC Browser - Tested on Android 2.3 device
              ( (t.is('UC Browser') || t.is('Dolfin')) && t.version('Android')>=2.3 ) ||
  
              // Kindle 3 and Fire  - Tested on the built-in WebKit browser for each
              ( t.match('Kindle Fire') ||
                  t.is('Kindle') && t.version('Kindle')>=3.0 ) ||
  
              // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
              t.is('AndroidOS') && t.is('NookTablet') ||
  
              // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
              t.version('Chrome')>=11 && !$isMobile ||
  
              // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
              t.version('Safari')>=5.0 && !$isMobile ||
  
              // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
              t.version('Firefox')>=4.0 && !$isMobile ||
  
              // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
              t.version('MSIE')>=7.0 && !$isMobile ||
  
              // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
              // @reference: http://my.opera.com/community/openweb/idopera/
              t.version('Opera')>=10 && !$isMobile
  
              ){
              return 'A';
          }
  
          if (
              t.os('iOS') && t.version('iPad')<4.3 ||
              t.os('iOS') && t.version('iPhone')<3.1 ||
              t.os('iOS') && t.version('iPod')<3.1 ||
  
              // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
              t.is('Blackberry') && t.version('BlackBerry')>=5 && t.version('BlackBerry')<6 ||
  
              //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
              ( t.version('Opera Mini')>=5.0 && t.version('Opera Mini')<=6.5 &&
                  (t.version('Android')>=2.3 || t.is('iOS')) ) ||
  
              // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
              t.match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
  
              // @todo: report this (tested on Nokia N71)
              t.version('Opera Mobi')>=11 && t.is('SymbianOS')
              ){
              return 'B';
          }
  
          if (
          // Blackberry 4.x - Tested on the Curve 8330
              t.version('BlackBerry')<5.0 ||
              // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
              t.match('MSIEMobile|Windows CE.*Mobile') || t.version('Windows Mobile')<=5.2
  
              ){
              return 'C';
          }
  
          //All older smartphone platforms and featurephones - Any device that doesn't support media queries
          //will receive the basic, C grade experience.
          return 'C';
      };
  
      impl.detectOS = function (ua) {
          return impl.findMatch(impl.mobileDetectRules.oss0, ua) ||
              impl.findMatch(impl.mobileDetectRules.oss, ua);
      };
  
      impl.getDeviceSmallerSide = function () {
          return window.screen.width < window.screen.height ?
              window.screen.width :
              window.screen.height;
      };
  
      /**
       * Constructor for MobileDetect object.
       * <br>
       * Such an object will keep a reference to the given user-agent string and cache most of the detect queries.<br>
       * <div style="background-color: #d9edf7; border: 1px solid #bce8f1; color: #3a87ad; padding: 14px; border-radius: 2px; margin-top: 20px">
       *     <strong>Find information how to download and install:</strong>
       *     <a href="https://github.com/hgoebl/mobile-detect.js/">github.com/hgoebl/mobile-detect.js/</a>
       * </div>
       *
       * @example <pre>
       *     var md = new MobileDetect(window.navigator.userAgent);
       *     if (md.mobile()) {
       *         location.href = (md.mobileGrade() === 'A') ? '/mobile/' : '/lynx/';
       *     }
       * </pre>
       *
       * @param {string} userAgent typically taken from window.navigator.userAgent or http_header['User-Agent']
       * @param {number} [maxPhoneWidth=600] <strong>only for browsers</strong> specify a value for the maximum
       *        width of smallest device side (in logical "CSS" pixels) until a device detected as mobile will be handled
       *        as phone.
       *        This is only used in cases where the device cannot be classified as phone or tablet.<br>
       *        See <a href="http://developer.android.com/guide/practices/screens_support.html">Declaring Tablet Layouts
       *        for Android</a>.<br>
       *        If you provide a value < 0, then this "fuzzy" check is disabled.
       * @constructor
       * @global
       */
      function MobileDetect(userAgent, maxPhoneWidth) {
          this.ua = prepareUserAgent(userAgent);
          this._cache = {};
          //600dp is typical 7" tablet minimum width
          this.maxPhoneWidth = maxPhoneWidth || 600;
      }
  
      MobileDetect.prototype = {
          constructor: MobileDetect,
  
          /**
           * Returns the detected phone or tablet type or <tt>null</tt> if it is not a mobile device.
           * <br>
           * For a list of possible return values see {@link MobileDetect#phone} and {@link MobileDetect#tablet}.<br>
           * <br>
           * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
           * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
           * is positive, a value of <code>UnknownPhone</code>, <code>UnknownTablet</code> or
           * <code>UnknownMobile</code> is returned.<br>
           * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
           * <br>
           * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
           * and <code>UnknownMobile</code>, so you will get <code>UnknownMobile</code> here.<br>
           * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
           * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
           * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
           * <br>
           * In most cases you will use the return value just as a boolean.
           *
           * @returns {String} the key for the phone family or tablet family, e.g. "Nexus".
           * @function MobileDetect#mobile
           */
          mobile: function () {
              impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
              return this._cache.mobile;
          },
  
          /**
           * Returns the detected phone type/family string or <tt>null</tt>.
           * <br>
           * The returned tablet (family or producer) is one of following keys:<br>
           * <br><tt>iPhone, BlackBerry, Pixel, HTC, Nexus, Dell, Motorola, Samsung, LG, Sony, Asus,
           * Xiaomi, NokiaLumia, Micromax, Palm, Vertu, Pantech, Fly, Wiko, iMobile,
           * SimValley, Wolfgang, Alcatel, Nintendo, Amoi, INQ, OnePlus, GenericPhone</tt><br>
           * <br>
           * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
           * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
           * is positive, a value of <code>UnknownPhone</code> or <code>UnknownMobile</code> is returned.<br>
           * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
           * <br>
           * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
           * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
           * will return <code>UnknownMobile</code>.<br>
           * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
           * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
           * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
           * <br>
           * In most cases you will use the return value just as a boolean.
           *
           * @returns {String} the key of the phone family or producer, e.g. "iPhone"
           * @function MobileDetect#phone
           */
          phone: function () {
              impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
              return this._cache.phone;
          },
  
          /**
           * Returns the detected tablet type/family string or <tt>null</tt>.
           * <br>
           * The returned tablet (family or producer) is one of following keys:<br>
           * <br><tt>iPad, NexusTablet, GoogleTablet, SamsungTablet, Kindle, SurfaceTablet,
           * HPTablet, AsusTablet, BlackBerryTablet, HTCtablet, MotorolaTablet, NookTablet,
           * AcerTablet, ToshibaTablet, LGTablet, FujitsuTablet, PrestigioTablet,
           * LenovoTablet, DellTablet, YarvikTablet, MedionTablet, ArnovaTablet,
           * IntensoTablet, IRUTablet, MegafonTablet, EbodaTablet, AllViewTablet,
           * ArchosTablet, AinolTablet, NokiaLumiaTablet, SonyTablet, PhilipsTablet,
           * CubeTablet, CobyTablet, MIDTablet, MSITablet, SMiTTablet, RockChipTablet,
           * FlyTablet, bqTablet, HuaweiTablet, NecTablet, PantechTablet, BronchoTablet,
           * VersusTablet, ZyncTablet, PositivoTablet, NabiTablet, KoboTablet, DanewTablet,
           * TexetTablet, PlaystationTablet, TrekstorTablet, PyleAudioTablet, AdvanTablet,
           * DanyTechTablet, GalapadTablet, MicromaxTablet, KarbonnTablet, AllFineTablet,
           * PROSCANTablet, YONESTablet, ChangJiaTablet, GUTablet, PointOfViewTablet,
           * OvermaxTablet, HCLTablet, DPSTablet, VistureTablet, CrestaTablet,
           * MediatekTablet, ConcordeTablet, GoCleverTablet, ModecomTablet, VoninoTablet,
           * ECSTablet, StorexTablet, VodafoneTablet, EssentielBTablet, RossMoorTablet,
           * iMobileTablet, TolinoTablet, AudioSonicTablet, AMPETablet, SkkTablet,
           * TecnoTablet, JXDTablet, iJoyTablet, FX2Tablet, XoroTablet, ViewsonicTablet,
           * VerizonTablet, OdysTablet, CaptivaTablet, IconbitTablet, TeclastTablet,
           * OndaTablet, JaytechTablet, BlaupunktTablet, DigmaTablet, EvolioTablet,
           * LavaTablet, AocTablet, MpmanTablet, CelkonTablet, WolderTablet, MediacomTablet,
           * MiTablet, NibiruTablet, NexoTablet, LeaderTablet, UbislateTablet,
           * PocketBookTablet, KocasoTablet, HisenseTablet, Hudl, TelstraTablet,
           * GenericTablet</tt><br>
           * <br>
           * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
           * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
           * is positive, a value of <code>UnknownTablet</code> or <code>UnknownMobile</code> is returned.<br>
           * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
           * <br>
           * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
           * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
           * will return <code>UnknownMobile</code>.<br>
           * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
           * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
           * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
           * <br>
           * In most cases you will use the return value just as a boolean.
           *
           * @returns {String} the key of the tablet family or producer, e.g. "SamsungTablet"
           * @function MobileDetect#tablet
           */
          tablet: function () {
              impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
              return this._cache.tablet;
          },
  
          /**
           * Returns the (first) detected user-agent string or <tt>null</tt>.
           * <br>
           * The returned user-agent is one of following keys:<br>
           * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
           * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
           * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
           * <br>
           * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
           * cases where a mobile device pretends to be more than one particular browser. You can get the
           * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
           * providing one of the defined keys as first argument to {@link MobileDetect#is}.
           *
           * @returns {String} the key for the detected user-agent or <tt>null</tt>
           * @function MobileDetect#userAgent
           */
          userAgent: function () {
              if (this._cache.userAgent === undefined) {
                  this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua);
              }
              return this._cache.userAgent;
          },
  
          /**
           * Returns all detected user-agent strings.
           * <br>
           * The array is empty or contains one or more of following keys:<br>
           * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
           * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
           * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
           * <br>
           * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
           * cases where a mobile device pretends to be more than one particular browser. You can get the
           * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
           * providing one of the defined keys as first argument to {@link MobileDetect#is}.
           *
           * @returns {Array} the array of detected user-agent keys or <tt>[]</tt>
           * @function MobileDetect#userAgents
           */
          userAgents: function () {
              if (this._cache.userAgents === undefined) {
                  this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua);
              }
              return this._cache.userAgents;
          },
  
          /**
           * Returns the detected operating system string or <tt>null</tt>.
           * <br>
           * The operating system is one of following keys:<br>
           * <br><tt>AndroidOS, BlackBerryOS, PalmOS, SymbianOS, WindowsMobileOS, WindowsPhoneOS,
           * iOS, iPadOS, SailfishOS, MeeGoOS, MaemoOS, JavaOS, webOS, badaOS, BREWOS</tt><br>
           *
           * @returns {String} the key for the detected operating system.
           * @function MobileDetect#os
           */
          os: function () {
              if (this._cache.os === undefined) {
                  this._cache.os = impl.detectOS(this.ua);
              }
              return this._cache.os;
          },
  
          /**
           * Get the version (as Number) of the given property in the User-Agent.
           * <br>
           * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
           *
           * @param {String} key a key defining a thing which has a version.<br>
           *        You can use one of following keys:<br>
           * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
           * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
           * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
           * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
           * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
           * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
           * NT, Symbian, webOS</tt><br>
           *
           * @returns {Number} the version as float or <tt>NaN</tt> if User-Agent doesn't contain this version.
           *          Be careful when comparing this value with '==' operator!
           * @function MobileDetect#version
           */
          version: function (key) {
              return impl.getVersion(key, this.ua);
          },
  
          /**
           * Get the version (as String) of the given property in the User-Agent.
           * <br>
           *
           * @param {String} key a key defining a thing which has a version.<br>
           *        You can use one of following keys:<br>
           * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
           * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
           * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
           * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
           * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
           * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
           * NT, Symbian, webOS</tt><br>
           *
           * @returns {String} the "raw" version as String or <tt>null</tt> if User-Agent doesn't contain this version.
           *
           * @function MobileDetect#versionStr
           */
          versionStr: function (key) {
              return impl.getVersionStr(key, this.ua);
          },
  
          /**
           * Global test key against userAgent, os, phone, tablet and some other properties of userAgent string.
           *
           * @param {String} key the key (case-insensitive) of a userAgent, an operating system, phone or
           *        tablet family.<br>
           *        For a complete list of possible values, see {@link MobileDetect#userAgent},
           *        {@link MobileDetect#os}, {@link MobileDetect#phone}, {@link MobileDetect#tablet}.<br>
           *        Additionally you have following keys:<br>
           * <br><tt>Bot, MobileBot, DesktopMode, TV, WebKit, Console, Watch</tt><br>
           *
           * @returns {boolean} <tt>true</tt> when the given key is one of the defined keys of userAgent, os, phone,
           *                    tablet or one of the listed additional keys, otherwise <tt>false</tt>
           * @function MobileDetect#is
           */
          is: function (key) {
              return containsIC(this.userAgents(), key) ||
                     equalIC(key, this.os()) ||
                     equalIC(key, this.phone()) ||
                     equalIC(key, this.tablet()) ||
                     containsIC(impl.findMatches(impl.mobileDetectRules.utils, this.ua), key);
          },
  
          /**
           * Do a quick test against navigator::userAgent.
           *
           * @param {String|RegExp} pattern the pattern, either as String or RegExp
           *                        (a string will be converted to a case-insensitive RegExp).
           * @returns {boolean} <tt>true</tt> when the pattern matches, otherwise <tt>false</tt>
           * @function MobileDetect#match
           */
          match: function (pattern) {
              if (!(pattern instanceof RegExp)) {
                  pattern = new RegExp(pattern, 'i');
              }
              return pattern.test(this.ua);
          },
  
          /**
           * Checks whether the mobile device can be considered as phone regarding <code>screen.width</code>.
           * <br>
           * Obviously this method makes sense in browser environments only (not for Node.js)!
           * @param {number} [maxPhoneWidth] the maximum logical pixels (aka. CSS-pixels) to be considered as phone.<br>
           *        The argument is optional and if not present or falsy, the value of the constructor is taken.
           * @returns {boolean|undefined} <code>undefined</code> if screen size wasn't detectable, else <code>true</code>
           *          when screen.width is less or equal to maxPhoneWidth, otherwise <code>false</code>.<br>
           *          Will always return <code>undefined</code> server-side.
           */
          isPhoneSized: function (maxPhoneWidth) {
              return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth);
          },
  
          /**
           * Returns the mobile grade ('A', 'B', 'C').
           *
           * @returns {String} one of the mobile grades ('A', 'B', 'C').
           * @function MobileDetect#mobileGrade
           */
          mobileGrade: function () {
              if (this._cache.grade === undefined) {
                  this._cache.grade = impl.mobileGrade(this);
              }
              return this._cache.grade;
          }
      };
  
      // environment-dependent
      if (typeof window !== 'undefined' && window.screen) {
          MobileDetect.isPhoneSized = function (maxPhoneWidth) {
              return maxPhoneWidth < 0 ? undefined : impl.getDeviceSmallerSide() <= maxPhoneWidth;
          };
      } else {
          MobileDetect.isPhoneSized = function () {};
      }
  
      // should not be replaced by a completely new object - just overwrite existing methods
      MobileDetect._impl = impl;
      
      MobileDetect.version = '1.4.5 2021-03-13';
  
      return MobileDetect;
  }); // end of call of define()
  })((function (undefined) {
      if ( true && module.exports) {
          return function (factory) { module.exports = factory(); };
      } else if (true) {
          return __webpack_require__.amdD;
      } else {}
  })());
  
  /***/ }),
  
  /***/ "./node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js":
  /*!*************************************************************************!*\
    !*** ./node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js ***!
    \*************************************************************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  /**
   * A collection of shims that provide minimal functionality of the ES6 collections.
   *
   * These implementations are not meant to be used outside of the ResizeObserver
   * modules as they cover only a limited range of use cases.
   */
  /* eslint-disable require-jsdoc, valid-jsdoc */
  var MapShim = (function () {
      if (typeof Map !== 'undefined') {
          return Map;
      }
      /**
       * Returns index in provided array that matches the specified key.
       *
       * @param {Array<Array>} arr
       * @param {*} key
       * @returns {number}
       */
      function getIndex(arr, key) {
          var result = -1;
          arr.some(function (entry, index) {
              if (entry[0] === key) {
                  result = index;
                  return true;
              }
              return false;
          });
          return result;
      }
      return /** @class */ (function () {
          function class_1() {
              this.__entries__ = [];
          }
          Object.defineProperty(class_1.prototype, "size", {
              /**
               * @returns {boolean}
               */
              get: function () {
                  return this.__entries__.length;
              },
              enumerable: true,
              configurable: true
          });
          /**
           * @param {*} key
           * @returns {*}
           */
          class_1.prototype.get = function (key) {
              var index = getIndex(this.__entries__, key);
              var entry = this.__entries__[index];
              return entry && entry[1];
          };
          /**
           * @param {*} key
           * @param {*} value
           * @returns {void}
           */
          class_1.prototype.set = function (key, value) {
              var index = getIndex(this.__entries__, key);
              if (~index) {
                  this.__entries__[index][1] = value;
              }
              else {
                  this.__entries__.push([key, value]);
              }
          };
          /**
           * @param {*} key
           * @returns {void}
           */
          class_1.prototype.delete = function (key) {
              var entries = this.__entries__;
              var index = getIndex(entries, key);
              if (~index) {
                  entries.splice(index, 1);
              }
          };
          /**
           * @param {*} key
           * @returns {void}
           */
          class_1.prototype.has = function (key) {
              return !!~getIndex(this.__entries__, key);
          };
          /**
           * @returns {void}
           */
          class_1.prototype.clear = function () {
              this.__entries__.splice(0);
          };
          /**
           * @param {Function} callback
           * @param {*} [ctx=null]
           * @returns {void}
           */
          class_1.prototype.forEach = function (callback, ctx) {
              if (ctx === void 0) { ctx = null; }
              for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {
                  var entry = _a[_i];
                  callback.call(ctx, entry[1], entry[0]);
              }
          };
          return class_1;
      }());
  })();
  
  /**
   * Detects whether window and document objects are available in current environment.
   */
  var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
  
  // Returns global object of a current environment.
  var global$1 = (function () {
      if (typeof __webpack_require__.g !== 'undefined' && __webpack_require__.g.Math === Math) {
          return __webpack_require__.g;
      }
      if (typeof self !== 'undefined' && self.Math === Math) {
          return self;
      }
      if (typeof window !== 'undefined' && window.Math === Math) {
          return window;
      }
      // eslint-disable-next-line no-new-func
      return Function('return this')();
  })();
  
  /**
   * A shim for the requestAnimationFrame which falls back to the setTimeout if
   * first one is not supported.
   *
   * @returns {number} Requests' identifier.
   */
  var requestAnimationFrame$1 = (function () {
      if (typeof requestAnimationFrame === 'function') {
          // It's required to use a bounded function because IE sometimes throws
          // an "Invalid calling object" error if rAF is invoked without the global
          // object on the left hand side.
          return requestAnimationFrame.bind(global$1);
      }
      return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
  })();
  
  // Defines minimum timeout before adding a trailing call.
  var trailingTimeout = 2;
  /**
   * Creates a wrapper function which ensures that provided callback will be
   * invoked only once during the specified delay period.
   *
   * @param {Function} callback - Function to be invoked after the delay period.
   * @param {number} delay - Delay after which to invoke callback.
   * @returns {Function}
   */
  function throttle (callback, delay) {
      var leadingCall = false, trailingCall = false, lastCallTime = 0;
      /**
       * Invokes the original callback function and schedules new invocation if
       * the "proxy" was called during current request.
       *
       * @returns {void}
       */
      function resolvePending() {
          if (leadingCall) {
              leadingCall = false;
              callback();
          }
          if (trailingCall) {
              proxy();
          }
      }
      /**
       * Callback invoked after the specified delay. It will further postpone
       * invocation of the original function delegating it to the
       * requestAnimationFrame.
       *
       * @returns {void}
       */
      function timeoutCallback() {
          requestAnimationFrame$1(resolvePending);
      }
      /**
       * Schedules invocation of the original function.
       *
       * @returns {void}
       */
      function proxy() {
          var timeStamp = Date.now();
          if (leadingCall) {
              // Reject immediately following calls.
              if (timeStamp - lastCallTime < trailingTimeout) {
                  return;
              }
              // Schedule new call to be in invoked when the pending one is resolved.
              // This is important for "transitions" which never actually start
              // immediately so there is a chance that we might miss one if change
              // happens amids the pending invocation.
              trailingCall = true;
          }
          else {
              leadingCall = true;
              trailingCall = false;
              setTimeout(timeoutCallback, delay);
          }
          lastCallTime = timeStamp;
      }
      return proxy;
  }
  
  // Minimum delay before invoking the update of observers.
  var REFRESH_DELAY = 20;
  // A list of substrings of CSS properties used to find transition events that
  // might affect dimensions of observed elements.
  var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
  // Check if MutationObserver is available.
  var mutationObserverSupported = typeof MutationObserver !== 'undefined';
  /**
   * Singleton controller class which handles updates of ResizeObserver instances.
   */
  var ResizeObserverController = /** @class */ (function () {
      /**
       * Creates a new instance of ResizeObserverController.
       *
       * @private
       */
      function ResizeObserverController() {
          /**
           * Indicates whether DOM listeners have been added.
           *
           * @private {boolean}
           */
          this.connected_ = false;
          /**
           * Tells that controller has subscribed for Mutation Events.
           *
           * @private {boolean}
           */
          this.mutationEventsAdded_ = false;
          /**
           * Keeps reference to the instance of MutationObserver.
           *
           * @private {MutationObserver}
           */
          this.mutationsObserver_ = null;
          /**
           * A list of connected observers.
           *
           * @private {Array<ResizeObserverSPI>}
           */
          this.observers_ = [];
          this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
          this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);
      }
      /**
       * Adds observer to observers list.
       *
       * @param {ResizeObserverSPI} observer - Observer to be added.
       * @returns {void}
       */
      ResizeObserverController.prototype.addObserver = function (observer) {
          if (!~this.observers_.indexOf(observer)) {
              this.observers_.push(observer);
          }
          // Add listeners if they haven't been added yet.
          if (!this.connected_) {
              this.connect_();
          }
      };
      /**
       * Removes observer from observers list.
       *
       * @param {ResizeObserverSPI} observer - Observer to be removed.
       * @returns {void}
       */
      ResizeObserverController.prototype.removeObserver = function (observer) {
          var observers = this.observers_;
          var index = observers.indexOf(observer);
          // Remove observer if it's present in registry.
          if (~index) {
              observers.splice(index, 1);
          }
          // Remove listeners if controller has no connected observers.
          if (!observers.length && this.connected_) {
              this.disconnect_();
          }
      };
      /**
       * Invokes the update of observers. It will continue running updates insofar
       * it detects changes.
       *
       * @returns {void}
       */
      ResizeObserverController.prototype.refresh = function () {
          var changesDetected = this.updateObservers_();
          // Continue running updates if changes have been detected as there might
          // be future ones caused by CSS transitions.
          if (changesDetected) {
              this.refresh();
          }
      };
      /**
       * Updates every observer from observers list and notifies them of queued
       * entries.
       *
       * @private
       * @returns {boolean} Returns "true" if any observer has detected changes in
       *      dimensions of it's elements.
       */
      ResizeObserverController.prototype.updateObservers_ = function () {
          // Collect observers that have active observations.
          var activeObservers = this.observers_.filter(function (observer) {
              return observer.gatherActive(), observer.hasActive();
          });
          // Deliver notifications in a separate cycle in order to avoid any
          // collisions between observers, e.g. when multiple instances of
          // ResizeObserver are tracking the same element and the callback of one
          // of them changes content dimensions of the observed target. Sometimes
          // this may result in notifications being blocked for the rest of observers.
          activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
          return activeObservers.length > 0;
      };
      /**
       * Initializes DOM listeners.
       *
       * @private
       * @returns {void}
       */
      ResizeObserverController.prototype.connect_ = function () {
          // Do nothing if running in a non-browser environment or if listeners
          // have been already added.
          if (!isBrowser || this.connected_) {
              return;
          }
          // Subscription to the "Transitionend" event is used as a workaround for
          // delayed transitions. This way it's possible to capture at least the
          // final state of an element.
          document.addEventListener('transitionend', this.onTransitionEnd_);
          window.addEventListener('resize', this.refresh);
          if (mutationObserverSupported) {
              this.mutationsObserver_ = new MutationObserver(this.refresh);
              this.mutationsObserver_.observe(document, {
                  attributes: true,
                  childList: true,
                  characterData: true,
                  subtree: true
              });
          }
          else {
              document.addEventListener('DOMSubtreeModified', this.refresh);
              this.mutationEventsAdded_ = true;
          }
          this.connected_ = true;
      };
      /**
       * Removes DOM listeners.
       *
       * @private
       * @returns {void}
       */
      ResizeObserverController.prototype.disconnect_ = function () {
          // Do nothing if running in a non-browser environment or if listeners
          // have been already removed.
          if (!isBrowser || !this.connected_) {
              return;
          }
          document.removeEventListener('transitionend', this.onTransitionEnd_);
          window.removeEventListener('resize', this.refresh);
          if (this.mutationsObserver_) {
              this.mutationsObserver_.disconnect();
          }
          if (this.mutationEventsAdded_) {
              document.removeEventListener('DOMSubtreeModified', this.refresh);
          }
          this.mutationsObserver_ = null;
          this.mutationEventsAdded_ = false;
          this.connected_ = false;
      };
      /**
       * "Transitionend" event handler.
       *
       * @private
       * @param {TransitionEvent} event
       * @returns {void}
       */
      ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {
          var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;
          // Detect whether transition may affect dimensions of an element.
          var isReflowProperty = transitionKeys.some(function (key) {
              return !!~propertyName.indexOf(key);
          });
          if (isReflowProperty) {
              this.refresh();
          }
      };
      /**
       * Returns instance of the ResizeObserverController.
       *
       * @returns {ResizeObserverController}
       */
      ResizeObserverController.getInstance = function () {
          if (!this.instance_) {
              this.instance_ = new ResizeObserverController();
          }
          return this.instance_;
      };
      /**
       * Holds reference to the controller's instance.
       *
       * @private {ResizeObserverController}
       */
      ResizeObserverController.instance_ = null;
      return ResizeObserverController;
  }());
  
  /**
   * Defines non-writable/enumerable properties of the provided target object.
   *
   * @param {Object} target - Object for which to define properties.
   * @param {Object} props - Properties to be defined.
   * @returns {Object} Target object.
   */
  var defineConfigurable = (function (target, props) {
      for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {
          var key = _a[_i];
          Object.defineProperty(target, key, {
              value: props[key],
              enumerable: false,
              writable: false,
              configurable: true
          });
      }
      return target;
  });
  
  /**
   * Returns the global object associated with provided element.
   *
   * @param {Object} target
   * @returns {Object}
   */
  var getWindowOf = (function (target) {
      // Assume that the element is an instance of Node, which means that it
      // has the "ownerDocument" property from which we can retrieve a
      // corresponding global object.
      var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
      // Return the local global object if it's not possible extract one from
      // provided element.
      return ownerGlobal || global$1;
  });
  
  // Placeholder of an empty content rectangle.
  var emptyRect = createRectInit(0, 0, 0, 0);
  /**
   * Converts provided string to a number.
   *
   * @param {number|string} value
   * @returns {number}
   */
  function toFloat(value) {
      return parseFloat(value) || 0;
  }
  /**
   * Extracts borders size from provided styles.
   *
   * @param {CSSStyleDeclaration} styles
   * @param {...string} positions - Borders positions (top, right, ...)
   * @returns {number}
   */
  function getBordersSize(styles) {
      var positions = [];
      for (var _i = 1; _i < arguments.length; _i++) {
          positions[_i - 1] = arguments[_i];
      }
      return positions.reduce(function (size, position) {
          var value = styles['border-' + position + '-width'];
          return size + toFloat(value);
      }, 0);
  }
  /**
   * Extracts paddings sizes from provided styles.
   *
   * @param {CSSStyleDeclaration} styles
   * @returns {Object} Paddings box.
   */
  function getPaddings(styles) {
      var positions = ['top', 'right', 'bottom', 'left'];
      var paddings = {};
      for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
          var position = positions_1[_i];
          var value = styles['padding-' + position];
          paddings[position] = toFloat(value);
      }
      return paddings;
  }
  /**
   * Calculates content rectangle of provided SVG element.
   *
   * @param {SVGGraphicsElement} target - Element content rectangle of which needs
   *      to be calculated.
   * @returns {DOMRectInit}
   */
  function getSVGContentRect(target) {
      var bbox = target.getBBox();
      return createRectInit(0, 0, bbox.width, bbox.height);
  }
  /**
   * Calculates content rectangle of provided HTMLElement.
   *
   * @param {HTMLElement} target - Element for which to calculate the content rectangle.
   * @returns {DOMRectInit}
   */
  function getHTMLElementContentRect(target) {
      // Client width & height properties can't be
      // used exclusively as they provide rounded values.
      var clientWidth = target.clientWidth, clientHeight = target.clientHeight;
      // By this condition we can catch all non-replaced inline, hidden and
      // detached elements. Though elements with width & height properties less
      // than 0.5 will be discarded as well.
      //
      // Without it we would need to implement separate methods for each of
      // those cases and it's not possible to perform a precise and performance
      // effective test for hidden elements. E.g. even jQuery's ':visible' filter
      // gives wrong results for elements with width & height less than 0.5.
      if (!clientWidth && !clientHeight) {
          return emptyRect;
      }
      var styles = getWindowOf(target).getComputedStyle(target);
      var paddings = getPaddings(styles);
      var horizPad = paddings.left + paddings.right;
      var vertPad = paddings.top + paddings.bottom;
      // Computed styles of width & height are being used because they are the
      // only dimensions available to JS that contain non-rounded values. It could
      // be possible to utilize the getBoundingClientRect if only it's data wasn't
      // affected by CSS transformations let alone paddings, borders and scroll bars.
      var width = toFloat(styles.width), height = toFloat(styles.height);
      // Width & height include paddings and borders when the 'border-box' box
      // model is applied (except for IE).
      if (styles.boxSizing === 'border-box') {
          // Following conditions are required to handle Internet Explorer which
          // doesn't include paddings and borders to computed CSS dimensions.
          //
          // We can say that if CSS dimensions + paddings are equal to the "client"
          // properties then it's either IE, and thus we don't need to subtract
          // anything, or an element merely doesn't have paddings/borders styles.
          if (Math.round(width + horizPad) !== clientWidth) {
              width -= getBordersSize(styles, 'left', 'right') + horizPad;
          }
          if (Math.round(height + vertPad) !== clientHeight) {
              height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
          }
      }
      // Following steps can't be applied to the document's root element as its
      // client[Width/Height] properties represent viewport area of the window.
      // Besides, it's as well not necessary as the <html> itself neither has
      // rendered scroll bars nor it can be clipped.
      if (!isDocumentElement(target)) {
          // In some browsers (only in Firefox, actually) CSS width & height
          // include scroll bars size which can be removed at this step as scroll
          // bars are the only difference between rounded dimensions + paddings
          // and "client" properties, though that is not always true in Chrome.
          var vertScrollbar = Math.round(width + horizPad) - clientWidth;
          var horizScrollbar = Math.round(height + vertPad) - clientHeight;
          // Chrome has a rather weird rounding of "client" properties.
          // E.g. for an element with content width of 314.2px it sometimes gives
          // the client width of 315px and for the width of 314.7px it may give
          // 314px. And it doesn't happen all the time. So just ignore this delta
          // as a non-relevant.
          if (Math.abs(vertScrollbar) !== 1) {
              width -= vertScrollbar;
          }
          if (Math.abs(horizScrollbar) !== 1) {
              height -= horizScrollbar;
          }
      }
      return createRectInit(paddings.left, paddings.top, width, height);
  }
  /**
   * Checks whether provided element is an instance of the SVGGraphicsElement.
   *
   * @param {Element} target - Element to be checked.
   * @returns {boolean}
   */
  var isSVGGraphicsElement = (function () {
      // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
      // interface.
      if (typeof SVGGraphicsElement !== 'undefined') {
          return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
      }
      // If it's so, then check that element is at least an instance of the
      // SVGElement and that it has the "getBBox" method.
      // eslint-disable-next-line no-extra-parens
      return function (target) { return (target instanceof getWindowOf(target).SVGElement &&
          typeof target.getBBox === 'function'); };
  })();
  /**
   * Checks whether provided element is a document element (<html>).
   *
   * @param {Element} target - Element to be checked.
   * @returns {boolean}
   */
  function isDocumentElement(target) {
      return target === getWindowOf(target).document.documentElement;
  }
  /**
   * Calculates an appropriate content rectangle for provided html or svg element.
   *
   * @param {Element} target - Element content rectangle of which needs to be calculated.
   * @returns {DOMRectInit}
   */
  function getContentRect(target) {
      if (!isBrowser) {
          return emptyRect;
      }
      if (isSVGGraphicsElement(target)) {
          return getSVGContentRect(target);
      }
      return getHTMLElementContentRect(target);
  }
  /**
   * Creates rectangle with an interface of the DOMRectReadOnly.
   * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
   *
   * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
   * @returns {DOMRectReadOnly}
   */
  function createReadOnlyRect(_a) {
      var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
      // If DOMRectReadOnly is available use it as a prototype for the rectangle.
      var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
      var rect = Object.create(Constr.prototype);
      // Rectangle's properties are not writable and non-enumerable.
      defineConfigurable(rect, {
          x: x, y: y, width: width, height: height,
          top: y,
          right: x + width,
          bottom: height + y,
          left: x
      });
      return rect;
  }
  /**
   * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
   * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
   *
   * @param {number} x - X coordinate.
   * @param {number} y - Y coordinate.
   * @param {number} width - Rectangle's width.
   * @param {number} height - Rectangle's height.
   * @returns {DOMRectInit}
   */
  function createRectInit(x, y, width, height) {
      return { x: x, y: y, width: width, height: height };
  }
  
  /**
   * Class that is responsible for computations of the content rectangle of
   * provided DOM element and for keeping track of it's changes.
   */
  var ResizeObservation = /** @class */ (function () {
      /**
       * Creates an instance of ResizeObservation.
       *
       * @param {Element} target - Element to be observed.
       */
      function ResizeObservation(target) {
          /**
           * Broadcasted width of content rectangle.
           *
           * @type {number}
           */
          this.broadcastWidth = 0;
          /**
           * Broadcasted height of content rectangle.
           *
           * @type {number}
           */
          this.broadcastHeight = 0;
          /**
           * Reference to the last observed content rectangle.
           *
           * @private {DOMRectInit}
           */
          this.contentRect_ = createRectInit(0, 0, 0, 0);
          this.target = target;
      }
      /**
       * Updates content rectangle and tells whether it's width or height properties
       * have changed since the last broadcast.
       *
       * @returns {boolean}
       */
      ResizeObservation.prototype.isActive = function () {
          var rect = getContentRect(this.target);
          this.contentRect_ = rect;
          return (rect.width !== this.broadcastWidth ||
              rect.height !== this.broadcastHeight);
      };
      /**
       * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
       * from the corresponding properties of the last observed content rectangle.
       *
       * @returns {DOMRectInit} Last observed content rectangle.
       */
      ResizeObservation.prototype.broadcastRect = function () {
          var rect = this.contentRect_;
          this.broadcastWidth = rect.width;
          this.broadcastHeight = rect.height;
          return rect;
      };
      return ResizeObservation;
  }());
  
  var ResizeObserverEntry = /** @class */ (function () {
      /**
       * Creates an instance of ResizeObserverEntry.
       *
       * @param {Element} target - Element that is being observed.
       * @param {DOMRectInit} rectInit - Data of the element's content rectangle.
       */
      function ResizeObserverEntry(target, rectInit) {
          var contentRect = createReadOnlyRect(rectInit);
          // According to the specification following properties are not writable
          // and are also not enumerable in the native implementation.
          //
          // Property accessors are not being used as they'd require to define a
          // private WeakMap storage which may cause memory leaks in browsers that
          // don't support this type of collections.
          defineConfigurable(this, { target: target, contentRect: contentRect });
      }
      return ResizeObserverEntry;
  }());
  
  var ResizeObserverSPI = /** @class */ (function () {
      /**
       * Creates a new instance of ResizeObserver.
       *
       * @param {ResizeObserverCallback} callback - Callback function that is invoked
       *      when one of the observed elements changes it's content dimensions.
       * @param {ResizeObserverController} controller - Controller instance which
       *      is responsible for the updates of observer.
       * @param {ResizeObserver} callbackCtx - Reference to the public
       *      ResizeObserver instance which will be passed to callback function.
       */
      function ResizeObserverSPI(callback, controller, callbackCtx) {
          /**
           * Collection of resize observations that have detected changes in dimensions
           * of elements.
           *
           * @private {Array<ResizeObservation>}
           */
          this.activeObservations_ = [];
          /**
           * Registry of the ResizeObservation instances.
           *
           * @private {Map<Element, ResizeObservation>}
           */
          this.observations_ = new MapShim();
          if (typeof callback !== 'function') {
              throw new TypeError('The callback provided as parameter 1 is not a function.');
          }
          this.callback_ = callback;
          this.controller_ = controller;
          this.callbackCtx_ = callbackCtx;
      }
      /**
       * Starts observing provided element.
       *
       * @param {Element} target - Element to be observed.
       * @returns {void}
       */
      ResizeObserverSPI.prototype.observe = function (target) {
          if (!arguments.length) {
              throw new TypeError('1 argument required, but only 0 present.');
          }
          // Do nothing if current environment doesn't have the Element interface.
          if (typeof Element === 'undefined' || !(Element instanceof Object)) {
              return;
          }
          if (!(target instanceof getWindowOf(target).Element)) {
              throw new TypeError('parameter 1 is not of type "Element".');
          }
          var observations = this.observations_;
          // Do nothing if element is already being observed.
          if (observations.has(target)) {
              return;
          }
          observations.set(target, new ResizeObservation(target));
          this.controller_.addObserver(this);
          // Force the update of observations.
          this.controller_.refresh();
      };
      /**
       * Stops observing provided element.
       *
       * @param {Element} target - Element to stop observing.
       * @returns {void}
       */
      ResizeObserverSPI.prototype.unobserve = function (target) {
          if (!arguments.length) {
              throw new TypeError('1 argument required, but only 0 present.');
          }
          // Do nothing if current environment doesn't have the Element interface.
          if (typeof Element === 'undefined' || !(Element instanceof Object)) {
              return;
          }
          if (!(target instanceof getWindowOf(target).Element)) {
              throw new TypeError('parameter 1 is not of type "Element".');
          }
          var observations = this.observations_;
          // Do nothing if element is not being observed.
          if (!observations.has(target)) {
              return;
          }
          observations.delete(target);
          if (!observations.size) {
              this.controller_.removeObserver(this);
          }
      };
      /**
       * Stops observing all elements.
       *
       * @returns {void}
       */
      ResizeObserverSPI.prototype.disconnect = function () {
          this.clearActive();
          this.observations_.clear();
          this.controller_.removeObserver(this);
      };
      /**
       * Collects observation instances the associated element of which has changed
       * it's content rectangle.
       *
       * @returns {void}
       */
      ResizeObserverSPI.prototype.gatherActive = function () {
          var _this = this;
          this.clearActive();
          this.observations_.forEach(function (observation) {
              if (observation.isActive()) {
                  _this.activeObservations_.push(observation);
              }
          });
      };
      /**
       * Invokes initial callback function with a list of ResizeObserverEntry
       * instances collected from active resize observations.
       *
       * @returns {void}
       */
      ResizeObserverSPI.prototype.broadcastActive = function () {
          // Do nothing if observer doesn't have active observations.
          if (!this.hasActive()) {
              return;
          }
          var ctx = this.callbackCtx_;
          // Create ResizeObserverEntry instance for every active observation.
          var entries = this.activeObservations_.map(function (observation) {
              return new ResizeObserverEntry(observation.target, observation.broadcastRect());
          });
          this.callback_.call(ctx, entries, ctx);
          this.clearActive();
      };
      /**
       * Clears the collection of active observations.
       *
       * @returns {void}
       */
      ResizeObserverSPI.prototype.clearActive = function () {
          this.activeObservations_.splice(0);
      };
      /**
       * Tells whether observer has active observations.
       *
       * @returns {boolean}
       */
      ResizeObserverSPI.prototype.hasActive = function () {
          return this.activeObservations_.length > 0;
      };
      return ResizeObserverSPI;
  }());
  
  // Registry of internal observers. If WeakMap is not available use current shim
  // for the Map collection as it has all required methods and because WeakMap
  // can't be fully polyfilled anyway.
  var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
  /**
   * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
   * exposing only those methods and properties that are defined in the spec.
   */
  var ResizeObserver = /** @class */ (function () {
      /**
       * Creates a new instance of ResizeObserver.
       *
       * @param {ResizeObserverCallback} callback - Callback that is invoked when
       *      dimensions of the observed elements change.
       */
      function ResizeObserver(callback) {
          if (!(this instanceof ResizeObserver)) {
              throw new TypeError('Cannot call a class as a function.');
          }
          if (!arguments.length) {
              throw new TypeError('1 argument required, but only 0 present.');
          }
          var controller = ResizeObserverController.getInstance();
          var observer = new ResizeObserverSPI(callback, controller, this);
          observers.set(this, observer);
      }
      return ResizeObserver;
  }());
  // Expose public methods of ResizeObserver.
  [
      'observe',
      'unobserve',
      'disconnect'
  ].forEach(function (method) {
      ResizeObserver.prototype[method] = function () {
          var _a;
          return (_a = observers.get(this))[method].apply(_a, arguments);
      };
  });
  
  var index = (function () {
      // Export existing implementation if available.
      if (typeof global$1.ResizeObserver !== 'undefined') {
          return global$1.ResizeObserver;
      }
      return ResizeObserver;
  })();
  
  /* harmony default export */ __webpack_exports__["default"] = (index);
  
  
  /***/ }),
  
  /***/ "./node_modules/simplebar/dist/simplebar.esm.js":
  /*!******************************************************!*\
    !*** ./node_modules/simplebar/dist/simplebar.esm.js ***!
    \******************************************************/
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var core_js_modules_es_array_for_each__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.for-each */ "./node_modules/core-js/modules/es.array.for-each.js");
  /* harmony import */ var core_js_modules_es_array_for_each__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_for_each__WEBPACK_IMPORTED_MODULE_0__);
  /* harmony import */ var core_js_modules_web_dom_collections_for_each__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/web.dom-collections.for-each */ "./node_modules/core-js/modules/web.dom-collections.for-each.js");
  /* harmony import */ var core_js_modules_web_dom_collections_for_each__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_for_each__WEBPACK_IMPORTED_MODULE_1__);
  /* harmony import */ var can_use_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! can-use-dom */ "./node_modules/can-use-dom/index.js");
  /* harmony import */ var can_use_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(can_use_dom__WEBPACK_IMPORTED_MODULE_2__);
  /* harmony import */ var core_js_modules_es_array_filter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.array.filter */ "./node_modules/core-js/modules/es.array.filter.js");
  /* harmony import */ var core_js_modules_es_array_filter__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_filter__WEBPACK_IMPORTED_MODULE_3__);
  /* harmony import */ var core_js_modules_es_array_iterator__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.array.iterator */ "./node_modules/core-js/modules/es.array.iterator.js");
  /* harmony import */ var core_js_modules_es_array_iterator__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_iterator__WEBPACK_IMPORTED_MODULE_4__);
  /* harmony import */ var core_js_modules_es_object_assign__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.object.assign */ "./node_modules/core-js/modules/es.object.assign.js");
  /* harmony import */ var core_js_modules_es_object_assign__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_assign__WEBPACK_IMPORTED_MODULE_5__);
  /* harmony import */ var core_js_modules_es_object_to_string__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.object.to-string */ "./node_modules/core-js/modules/es.object.to-string.js");
  /* harmony import */ var core_js_modules_es_object_to_string__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_to_string__WEBPACK_IMPORTED_MODULE_6__);
  /* harmony import */ var core_js_modules_es_parse_int__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.parse-int */ "./node_modules/core-js/modules/es.parse-int.js");
  /* harmony import */ var core_js_modules_es_parse_int__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_parse_int__WEBPACK_IMPORTED_MODULE_7__);
  /* harmony import */ var core_js_modules_es_string_iterator__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.string.iterator */ "./node_modules/core-js/modules/es.string.iterator.js");
  /* harmony import */ var core_js_modules_es_string_iterator__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_iterator__WEBPACK_IMPORTED_MODULE_8__);
  /* harmony import */ var core_js_modules_es_weak_map__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.weak-map */ "./node_modules/core-js/modules/es.weak-map.js");
  /* harmony import */ var core_js_modules_es_weak_map__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_weak_map__WEBPACK_IMPORTED_MODULE_9__);
  /* harmony import */ var core_js_modules_web_dom_collections_iterator__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator */ "./node_modules/core-js/modules/web.dom-collections.iterator.js");
  /* harmony import */ var core_js_modules_web_dom_collections_iterator__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator__WEBPACK_IMPORTED_MODULE_10__);
  /* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! lodash.throttle */ "./node_modules/lodash.throttle/index.js");
  /* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_11__);
  /* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! lodash.debounce */ "./node_modules/lodash.debounce/index.js");
  /* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_12__);
  /* harmony import */ var lodash_memoize__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! lodash.memoize */ "./node_modules/lodash.memoize/index.js");
  /* harmony import */ var lodash_memoize__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(lodash_memoize__WEBPACK_IMPORTED_MODULE_13__);
  /* harmony import */ var resize_observer_polyfill__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! resize-observer-polyfill */ "./node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js");
  /* harmony import */ var core_js_modules_es_array_reduce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! core-js/modules/es.array.reduce */ "./node_modules/core-js/modules/es.array.reduce.js");
  /* harmony import */ var core_js_modules_es_array_reduce__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_reduce__WEBPACK_IMPORTED_MODULE_15__);
  /* harmony import */ var core_js_modules_es_function_name__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! core-js/modules/es.function.name */ "./node_modules/core-js/modules/es.function.name.js");
  /* harmony import */ var core_js_modules_es_function_name__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_function_name__WEBPACK_IMPORTED_MODULE_16__);
  /* harmony import */ var core_js_modules_es_regexp_exec__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! core-js/modules/es.regexp.exec */ "./node_modules/core-js/modules/es.regexp.exec.js");
  /* harmony import */ var core_js_modules_es_regexp_exec__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_exec__WEBPACK_IMPORTED_MODULE_17__);
  /* harmony import */ var core_js_modules_es_string_match__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! core-js/modules/es.string.match */ "./node_modules/core-js/modules/es.string.match.js");
  /* harmony import */ var core_js_modules_es_string_match__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_match__WEBPACK_IMPORTED_MODULE_18__);
  /* harmony import */ var core_js_modules_es_string_replace__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! core-js/modules/es.string.replace */ "./node_modules/core-js/modules/es.string.replace.js");
  /* harmony import */ var core_js_modules_es_string_replace__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace__WEBPACK_IMPORTED_MODULE_19__);
  /**
   * SimpleBar.js - v5.3.2
   * Scrollbars, simpler.
   * https://grsmto.github.io/simplebar/
   *
   * Made by Adrien Denat from a fork by Jonathan Nicol
   * Under MIT License
   */
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  // Helper function to retrieve options from element attributes
  var getOptions = function getOptions(obj) {
    var options = Array.prototype.reduce.call(obj, function (acc, attribute) {
      var option = attribute.name.match(/data-simplebar-(.+)/);
  
      if (option) {
        var key = option[1].replace(/\W+(.)/g, function (x, chr) {
          return chr.toUpperCase();
        });
  
        switch (attribute.value) {
          case 'true':
            acc[key] = true;
            break;
  
          case 'false':
            acc[key] = false;
            break;
  
          case undefined:
            acc[key] = true;
            break;
  
          default:
            acc[key] = attribute.value;
        }
      }
  
      return acc;
    }, {});
    return options;
  };
  function getElementWindow(element) {
    if (!element || !element.ownerDocument || !element.ownerDocument.defaultView) {
      return window;
    }
  
    return element.ownerDocument.defaultView;
  }
  function getElementDocument(element) {
    if (!element || !element.ownerDocument) {
      return document;
    }
  
    return element.ownerDocument;
  }
  
  var cachedScrollbarWidth = null;
  var cachedDevicePixelRatio = null;
  
  if ((can_use_dom__WEBPACK_IMPORTED_MODULE_2___default())) {
    window.addEventListener('resize', function () {
      if (cachedDevicePixelRatio !== window.devicePixelRatio) {
        cachedDevicePixelRatio = window.devicePixelRatio;
        cachedScrollbarWidth = null;
      }
    });
  }
  
  function scrollbarWidth(el) {
    if (cachedScrollbarWidth === null) {
      var document = getElementDocument(el);
  
      if (typeof document === 'undefined') {
        cachedScrollbarWidth = 0;
        return cachedScrollbarWidth;
      }
  
      var body = document.body;
      var box = document.createElement('div');
      box.classList.add('simplebar-hide-scrollbar');
      body.appendChild(box);
      var width = box.getBoundingClientRect().right;
      body.removeChild(box);
      cachedScrollbarWidth = width;
    }
  
    return cachedScrollbarWidth;
  }
  
  var SimpleBar =
  /*#__PURE__*/
  function () {
    function SimpleBar(element, options) {
      var _this = this;
  
      this.onScroll = function () {
        var elWindow = getElementWindow(_this.el);
  
        if (!_this.scrollXTicking) {
          elWindow.requestAnimationFrame(_this.scrollX);
          _this.scrollXTicking = true;
        }
  
        if (!_this.scrollYTicking) {
          elWindow.requestAnimationFrame(_this.scrollY);
          _this.scrollYTicking = true;
        }
      };
  
      this.scrollX = function () {
        if (_this.axis.x.isOverflowing) {
          _this.showScrollbar('x');
  
          _this.positionScrollbar('x');
        }
  
        _this.scrollXTicking = false;
      };
  
      this.scrollY = function () {
        if (_this.axis.y.isOverflowing) {
          _this.showScrollbar('y');
  
          _this.positionScrollbar('y');
        }
  
        _this.scrollYTicking = false;
      };
  
      this.onMouseEnter = function () {
        _this.showScrollbar('x');
  
        _this.showScrollbar('y');
      };
  
      this.onMouseMove = function (e) {
        _this.mouseX = e.clientX;
        _this.mouseY = e.clientY;
  
        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
          _this.onMouseMoveForAxis('x');
        }
  
        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
          _this.onMouseMoveForAxis('y');
        }
      };
  
      this.onMouseLeave = function () {
        _this.onMouseMove.cancel();
  
        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
          _this.onMouseLeaveForAxis('x');
        }
  
        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
          _this.onMouseLeaveForAxis('y');
        }
  
        _this.mouseX = -1;
        _this.mouseY = -1;
      };
  
      this.onWindowResize = function () {
        // Recalculate scrollbarWidth in case it's a zoom
        _this.scrollbarWidth = _this.getScrollbarWidth();
  
        _this.hideNativeScrollbar();
      };
  
      this.hideScrollbars = function () {
        _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
        _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();
  
        if (!_this.isWithinBounds(_this.axis.y.track.rect)) {
          _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible);
  
          _this.axis.y.isVisible = false;
        }
  
        if (!_this.isWithinBounds(_this.axis.x.track.rect)) {
          _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible);
  
          _this.axis.x.isVisible = false;
        }
      };
  
      this.onPointerEvent = function (e) {
        var isWithinTrackXBounds, isWithinTrackYBounds;
        _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
        _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();
  
        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
          isWithinTrackXBounds = _this.isWithinBounds(_this.axis.x.track.rect);
        }
  
        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
          isWithinTrackYBounds = _this.isWithinBounds(_this.axis.y.track.rect);
        } // If any pointer event is called on the scrollbar
  
  
        if (isWithinTrackXBounds || isWithinTrackYBounds) {
          // Preventing the event's default action stops text being
          // selectable during the drag.
          e.preventDefault(); // Prevent event leaking
  
          e.stopPropagation();
  
          if (e.type === 'mousedown') {
            if (isWithinTrackXBounds) {
              _this.axis.x.scrollbar.rect = _this.axis.x.scrollbar.el.getBoundingClientRect();
  
              if (_this.isWithinBounds(_this.axis.x.scrollbar.rect)) {
                _this.onDragStart(e, 'x');
              } else {
                _this.onTrackClick(e, 'x');
              }
            }
  
            if (isWithinTrackYBounds) {
              _this.axis.y.scrollbar.rect = _this.axis.y.scrollbar.el.getBoundingClientRect();
  
              if (_this.isWithinBounds(_this.axis.y.scrollbar.rect)) {
                _this.onDragStart(e, 'y');
              } else {
                _this.onTrackClick(e, 'y');
              }
            }
          }
        }
      };
  
      this.drag = function (e) {
        var eventOffset;
        var track = _this.axis[_this.draggedAxis].track;
        var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr];
        var scrollbar = _this.axis[_this.draggedAxis].scrollbar;
        var contentSize = _this.contentWrapperEl[_this.axis[_this.draggedAxis].scrollSizeAttr];
        var hostSize = parseInt(_this.elStyles[_this.axis[_this.draggedAxis].sizeAttr], 10);
        e.preventDefault();
        e.stopPropagation();
  
        if (_this.draggedAxis === 'y') {
          eventOffset = e.pageY;
        } else {
          eventOffset = e.pageX;
        } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).
  
  
        var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width.
  
        var dragPerc = dragPos / (trackSize - scrollbar.size); // Scroll the content by the same percentage.
  
        var scrollPos = dragPerc * (contentSize - hostSize); // Fix browsers inconsistency on RTL
  
        if (_this.draggedAxis === 'x') {
          scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos;
          scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos;
        }
  
        _this.contentWrapperEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos;
      };
  
      this.onEndDrag = function (e) {
        var elDocument = getElementDocument(_this.el);
        var elWindow = getElementWindow(_this.el);
        e.preventDefault();
        e.stopPropagation();
  
        _this.el.classList.remove(_this.classNames.dragging);
  
        elDocument.removeEventListener('mousemove', _this.drag, true);
        elDocument.removeEventListener('mouseup', _this.onEndDrag, true);
        _this.removePreventClickId = elWindow.setTimeout(function () {
          // Remove these asynchronously so we still suppress click events
          // generated simultaneously with mouseup.
          elDocument.removeEventListener('click', _this.preventClick, true);
          elDocument.removeEventListener('dblclick', _this.preventClick, true);
          _this.removePreventClickId = null;
        });
      };
  
      this.preventClick = function (e) {
        e.preventDefault();
        e.stopPropagation();
      };
  
      this.el = element;
      this.minScrollbarWidth = 20;
      this.options = Object.assign({}, SimpleBar.defaultOptions, {}, options);
      this.classNames = Object.assign({}, SimpleBar.defaultOptions.classNames, {}, this.options.classNames);
      this.axis = {
        x: {
          scrollOffsetAttr: 'scrollLeft',
          sizeAttr: 'width',
          scrollSizeAttr: 'scrollWidth',
          offsetSizeAttr: 'offsetWidth',
          offsetAttr: 'left',
          overflowAttr: 'overflowX',
          dragOffset: 0,
          isOverflowing: true,
          isVisible: false,
          forceVisible: false,
          track: {},
          scrollbar: {}
        },
        y: {
          scrollOffsetAttr: 'scrollTop',
          sizeAttr: 'height',
          scrollSizeAttr: 'scrollHeight',
          offsetSizeAttr: 'offsetHeight',
          offsetAttr: 'top',
          overflowAttr: 'overflowY',
          dragOffset: 0,
          isOverflowing: true,
          isVisible: false,
          forceVisible: false,
          track: {},
          scrollbar: {}
        }
      };
      this.removePreventClickId = null; // Don't re-instantiate over an existing one
  
      if (SimpleBar.instances.has(this.el)) {
        return;
      }
  
      this.recalculate = lodash_throttle__WEBPACK_IMPORTED_MODULE_11___default()(this.recalculate.bind(this), 64);
      this.onMouseMove = lodash_throttle__WEBPACK_IMPORTED_MODULE_11___default()(this.onMouseMove.bind(this), 64);
      this.hideScrollbars = lodash_debounce__WEBPACK_IMPORTED_MODULE_12___default()(this.hideScrollbars.bind(this), this.options.timeout);
      this.onWindowResize = lodash_debounce__WEBPACK_IMPORTED_MODULE_12___default()(this.onWindowResize.bind(this), 64, {
        leading: true
      });
      SimpleBar.getRtlHelpers = lodash_memoize__WEBPACK_IMPORTED_MODULE_13___default()(SimpleBar.getRtlHelpers);
      this.init();
    }
    /**
     * Static properties
     */
  
    /**
     * Helper to fix browsers inconsistency on RTL:
     *  - Firefox inverts the scrollbar initial position
     *  - IE11 inverts both scrollbar position and scrolling offset
     * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634
     */
  
  
    SimpleBar.getRtlHelpers = function getRtlHelpers() {
      var dummyDiv = document.createElement('div');
      dummyDiv.innerHTML = '<div class="hs-dummy-scrollbar-size"><div style="height: 200%; width: 200%; margin: 10px 0;"></div></div>';
      var scrollbarDummyEl = dummyDiv.firstElementChild;
      document.body.appendChild(scrollbarDummyEl);
      var dummyContainerChild = scrollbarDummyEl.firstElementChild;
      scrollbarDummyEl.scrollLeft = 0;
      var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl);
      var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild);
      scrollbarDummyEl.scrollLeft = 999;
      var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild);
      return {
        // determines if the scrolling is responding with negative values
        isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0,
        // determines if the origin scrollbar position is inverted or not (positioned on left or right)
        isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left
      };
    };
  
    SimpleBar.getOffset = function getOffset(el) {
      var rect = el.getBoundingClientRect();
      var elDocument = getElementDocument(el);
      var elWindow = getElementWindow(el);
      return {
        top: rect.top + (elWindow.pageYOffset || elDocument.documentElement.scrollTop),
        left: rect.left + (elWindow.pageXOffset || elDocument.documentElement.scrollLeft)
      };
    };
  
    var _proto = SimpleBar.prototype;
  
    _proto.init = function init() {
      // Save a reference to the instance, so we know this DOM node has already been instancied
      SimpleBar.instances.set(this.el, this); // We stop here on server-side
  
      if ((can_use_dom__WEBPACK_IMPORTED_MODULE_2___default())) {
        this.initDOM();
        this.scrollbarWidth = this.getScrollbarWidth();
        this.recalculate();
        this.initListeners();
      }
    };
  
    _proto.initDOM = function initDOM() {
      var _this2 = this;
  
      // make sure this element doesn't have the elements yet
      if (Array.prototype.filter.call(this.el.children, function (child) {
        return child.classList.contains(_this2.classNames.wrapper);
      }).length) {
        // assume that element has his DOM already initiated
        this.wrapperEl = this.el.querySelector("." + this.classNames.wrapper);
        this.contentWrapperEl = this.options.scrollableNode || this.el.querySelector("." + this.classNames.contentWrapper);
        this.contentEl = this.options.contentNode || this.el.querySelector("." + this.classNames.contentEl);
        this.offsetEl = this.el.querySelector("." + this.classNames.offset);
        this.maskEl = this.el.querySelector("." + this.classNames.mask);
        this.placeholderEl = this.findChild(this.wrapperEl, "." + this.classNames.placeholder);
        this.heightAutoObserverWrapperEl = this.el.querySelector("." + this.classNames.heightAutoObserverWrapperEl);
        this.heightAutoObserverEl = this.el.querySelector("." + this.classNames.heightAutoObserverEl);
        this.axis.x.track.el = this.findChild(this.el, "." + this.classNames.track + "." + this.classNames.horizontal);
        this.axis.y.track.el = this.findChild(this.el, "." + this.classNames.track + "." + this.classNames.vertical);
      } else {
        // Prepare DOM
        this.wrapperEl = document.createElement('div');
        this.contentWrapperEl = document.createElement('div');
        this.offsetEl = document.createElement('div');
        this.maskEl = document.createElement('div');
        this.contentEl = document.createElement('div');
        this.placeholderEl = document.createElement('div');
        this.heightAutoObserverWrapperEl = document.createElement('div');
        this.heightAutoObserverEl = document.createElement('div');
        this.wrapperEl.classList.add(this.classNames.wrapper);
        this.contentWrapperEl.classList.add(this.classNames.contentWrapper);
        this.offsetEl.classList.add(this.classNames.offset);
        this.maskEl.classList.add(this.classNames.mask);
        this.contentEl.classList.add(this.classNames.contentEl);
        this.placeholderEl.classList.add(this.classNames.placeholder);
        this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl);
        this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl);
  
        while (this.el.firstChild) {
          this.contentEl.appendChild(this.el.firstChild);
        }
  
        this.contentWrapperEl.appendChild(this.contentEl);
        this.offsetEl.appendChild(this.contentWrapperEl);
        this.maskEl.appendChild(this.offsetEl);
        this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl);
        this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl);
        this.wrapperEl.appendChild(this.maskEl);
        this.wrapperEl.appendChild(this.placeholderEl);
        this.el.appendChild(this.wrapperEl);
      }
  
      if (!this.axis.x.track.el || !this.axis.y.track.el) {
        var track = document.createElement('div');
        var scrollbar = document.createElement('div');
        track.classList.add(this.classNames.track);
        scrollbar.classList.add(this.classNames.scrollbar);
        track.appendChild(scrollbar);
        this.axis.x.track.el = track.cloneNode(true);
        this.axis.x.track.el.classList.add(this.classNames.horizontal);
        this.axis.y.track.el = track.cloneNode(true);
        this.axis.y.track.el.classList.add(this.classNames.vertical);
        this.el.appendChild(this.axis.x.track.el);
        this.el.appendChild(this.axis.y.track.el);
      }
  
      this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector("." + this.classNames.scrollbar);
      this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector("." + this.classNames.scrollbar);
  
      if (!this.options.autoHide) {
        this.axis.x.scrollbar.el.classList.add(this.classNames.visible);
        this.axis.y.scrollbar.el.classList.add(this.classNames.visible);
      }
  
      this.el.setAttribute('data-simplebar', 'init');
    };
  
    _proto.initListeners = function initListeners() {
      var _this3 = this;
  
      var elWindow = getElementWindow(this.el); // Event listeners
  
      if (this.options.autoHide) {
        this.el.addEventListener('mouseenter', this.onMouseEnter);
      }
  
      ['mousedown', 'click', 'dblclick'].forEach(function (e) {
        _this3.el.addEventListener(e, _this3.onPointerEvent, true);
      });
      ['touchstart', 'touchend', 'touchmove'].forEach(function (e) {
        _this3.el.addEventListener(e, _this3.onPointerEvent, {
          capture: true,
          passive: true
        });
      });
      this.el.addEventListener('mousemove', this.onMouseMove);
      this.el.addEventListener('mouseleave', this.onMouseLeave);
      this.contentWrapperEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize
  
      elWindow.addEventListener('resize', this.onWindowResize); // Hack for https://github.com/WICG/ResizeObserver/issues/38
  
      var resizeObserverStarted = false;
      var resizeObserver = elWindow.ResizeObserver || resize_observer_polyfill__WEBPACK_IMPORTED_MODULE_14__.default;
      this.resizeObserver = new resizeObserver(function () {
        if (!resizeObserverStarted) return;
  
        _this3.recalculate();
      });
      this.resizeObserver.observe(this.el);
      this.resizeObserver.observe(this.contentEl);
      elWindow.requestAnimationFrame(function () {
        resizeObserverStarted = true;
      }); // This is required to detect horizontal scroll. Vertical scroll only needs the resizeObserver.
  
      this.mutationObserver = new elWindow.MutationObserver(this.recalculate);
      this.mutationObserver.observe(this.contentEl, {
        childList: true,
        subtree: true,
        characterData: true
      });
    };
  
    _proto.recalculate = function recalculate() {
      var elWindow = getElementWindow(this.el);
      this.elStyles = elWindow.getComputedStyle(this.el);
      this.isRtl = this.elStyles.direction === 'rtl';
      var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1;
      var isWidthAuto = this.heightAutoObserverEl.offsetWidth <= 1;
      var contentElOffsetWidth = this.contentEl.offsetWidth;
      var contentWrapperElOffsetWidth = this.contentWrapperEl.offsetWidth;
      var elOverflowX = this.elStyles.overflowX;
      var elOverflowY = this.elStyles.overflowY;
      this.contentEl.style.padding = this.elStyles.paddingTop + " " + this.elStyles.paddingRight + " " + this.elStyles.paddingBottom + " " + this.elStyles.paddingLeft;
      this.wrapperEl.style.margin = "-" + this.elStyles.paddingTop + " -" + this.elStyles.paddingRight + " -" + this.elStyles.paddingBottom + " -" + this.elStyles.paddingLeft;
      var contentElScrollHeight = this.contentEl.scrollHeight;
      var contentElScrollWidth = this.contentEl.scrollWidth;
      this.contentWrapperEl.style.height = isHeightAuto ? 'auto' : '100%'; // Determine placeholder size
  
      this.placeholderEl.style.width = isWidthAuto ? contentElOffsetWidth + "px" : 'auto';
      this.placeholderEl.style.height = contentElScrollHeight + "px";
      var contentWrapperElOffsetHeight = this.contentWrapperEl.offsetHeight;
      this.axis.x.isOverflowing = contentElScrollWidth > contentElOffsetWidth;
      this.axis.y.isOverflowing = contentElScrollHeight > contentWrapperElOffsetHeight; // Set isOverflowing to false if user explicitely set hidden overflow
  
      this.axis.x.isOverflowing = elOverflowX === 'hidden' ? false : this.axis.x.isOverflowing;
      this.axis.y.isOverflowing = elOverflowY === 'hidden' ? false : this.axis.y.isOverflowing;
      this.axis.x.forceVisible = this.options.forceVisible === 'x' || this.options.forceVisible === true;
      this.axis.y.forceVisible = this.options.forceVisible === 'y' || this.options.forceVisible === true;
      this.hideNativeScrollbar(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset)
  
      var offsetForXScrollbar = this.axis.x.isOverflowing ? this.scrollbarWidth : 0;
      var offsetForYScrollbar = this.axis.y.isOverflowing ? this.scrollbarWidth : 0;
      this.axis.x.isOverflowing = this.axis.x.isOverflowing && contentElScrollWidth > contentWrapperElOffsetWidth - offsetForYScrollbar;
      this.axis.y.isOverflowing = this.axis.y.isOverflowing && contentElScrollHeight > contentWrapperElOffsetHeight - offsetForXScrollbar;
      this.axis.x.scrollbar.size = this.getScrollbarSize('x');
      this.axis.y.scrollbar.size = this.getScrollbarSize('y');
      this.axis.x.scrollbar.el.style.width = this.axis.x.scrollbar.size + "px";
      this.axis.y.scrollbar.el.style.height = this.axis.y.scrollbar.size + "px";
      this.positionScrollbar('x');
      this.positionScrollbar('y');
      this.toggleTrackVisibility('x');
      this.toggleTrackVisibility('y');
    }
    /**
     * Calculate scrollbar size
     */
    ;
  
    _proto.getScrollbarSize = function getScrollbarSize(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      if (!this.axis[axis].isOverflowing) {
        return 0;
      }
  
      var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr];
      var trackSize = this.axis[axis].track.el[this.axis[axis].offsetSizeAttr];
      var scrollbarSize;
      var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle.
  
      scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize);
  
      if (this.options.scrollbarMaxSize) {
        scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize);
      }
  
      return scrollbarSize;
    };
  
    _proto.positionScrollbar = function positionScrollbar(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      if (!this.axis[axis].isOverflowing) {
        return;
      }
  
      var contentSize = this.contentWrapperEl[this.axis[axis].scrollSizeAttr];
      var trackSize = this.axis[axis].track.el[this.axis[axis].offsetSizeAttr];
      var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
      var scrollbar = this.axis[axis].scrollbar;
      var scrollOffset = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr];
      scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset;
      var scrollPourcent = scrollOffset / (contentSize - hostSize);
      var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent);
      handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset;
      scrollbar.el.style.transform = axis === 'x' ? "translate3d(" + handleOffset + "px, 0, 0)" : "translate3d(0, " + handleOffset + "px, 0)";
    };
  
    _proto.toggleTrackVisibility = function toggleTrackVisibility(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      var track = this.axis[axis].track.el;
      var scrollbar = this.axis[axis].scrollbar.el;
  
      if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) {
        track.style.visibility = 'visible';
        this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'scroll';
      } else {
        track.style.visibility = 'hidden';
        this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'hidden';
      } // Even if forceVisible is enabled, scrollbar itself should be hidden
  
  
      if (this.axis[axis].isOverflowing) {
        scrollbar.style.display = 'block';
      } else {
        scrollbar.style.display = 'none';
      }
    };
  
    _proto.hideNativeScrollbar = function hideNativeScrollbar() {
      this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-" + this.scrollbarWidth + "px" : 0;
      this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-" + this.scrollbarWidth + "px" : 0;
    }
    /**
     * On scroll event handling
     */
    ;
  
    _proto.onMouseMoveForAxis = function onMouseMoveForAxis(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect();
      this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect();
      var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect);
  
      if (isWithinScrollbarBoundsX) {
        this.axis[axis].scrollbar.el.classList.add(this.classNames.hover);
      } else {
        this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
      }
  
      if (this.isWithinBounds(this.axis[axis].track.rect)) {
        this.showScrollbar(axis);
        this.axis[axis].track.el.classList.add(this.classNames.hover);
      } else {
        this.axis[axis].track.el.classList.remove(this.classNames.hover);
      }
    };
  
    _proto.onMouseLeaveForAxis = function onMouseLeaveForAxis(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      this.axis[axis].track.el.classList.remove(this.classNames.hover);
      this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
    };
  
    /**
     * Show scrollbar
     */
    _proto.showScrollbar = function showScrollbar(axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      var scrollbar = this.axis[axis].scrollbar.el;
  
      if (!this.axis[axis].isVisible) {
        scrollbar.classList.add(this.classNames.visible);
        this.axis[axis].isVisible = true;
      }
  
      if (this.options.autoHide) {
        this.hideScrollbars();
      }
    }
    /**
     * Hide Scrollbar
     */
    ;
  
    /**
     * on scrollbar handle drag movement starts
     */
    _proto.onDragStart = function onDragStart(e, axis) {
      if (axis === void 0) {
        axis = 'y';
      }
  
      var elDocument = getElementDocument(this.el);
      var elWindow = getElementWindow(this.el);
      var scrollbar = this.axis[axis].scrollbar; // Measure how far the user's mouse is from the top of the scrollbar drag handle.
  
      var eventOffset = axis === 'y' ? e.pageY : e.pageX;
      this.axis[axis].dragOffset = eventOffset - scrollbar.rect[this.axis[axis].offsetAttr];
      this.draggedAxis = axis;
      this.el.classList.add(this.classNames.dragging);
      elDocument.addEventListener('mousemove', this.drag, true);
      elDocument.addEventListener('mouseup', this.onEndDrag, true);
  
      if (this.removePreventClickId === null) {
        elDocument.addEventListener('click', this.preventClick, true);
        elDocument.addEventListener('dblclick', this.preventClick, true);
      } else {
        elWindow.clearTimeout(this.removePreventClickId);
        this.removePreventClickId = null;
      }
    }
    /**
     * Drag scrollbar handle
     */
    ;
  
    _proto.onTrackClick = function onTrackClick(e, axis) {
      var _this4 = this;
  
      if (axis === void 0) {
        axis = 'y';
      }
  
      if (!this.options.clickOnTrack) return;
      var elWindow = getElementWindow(this.el);
      this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect();
      var scrollbar = this.axis[axis].scrollbar;
      var scrollbarOffset = scrollbar.rect[this.axis[axis].offsetAttr];
      var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
      var scrolled = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr];
      var t = axis === 'y' ? this.mouseY - scrollbarOffset : this.mouseX - scrollbarOffset;
      var dir = t < 0 ? -1 : 1;
      var scrollSize = dir === -1 ? scrolled - hostSize : scrolled + hostSize;
  
      var scrollTo = function scrollTo() {
        if (dir === -1) {
          if (scrolled > scrollSize) {
            var _this4$contentWrapper;
  
            scrolled -= _this4.options.clickOnTrackSpeed;
  
            _this4.contentWrapperEl.scrollTo((_this4$contentWrapper = {}, _this4$contentWrapper[_this4.axis[axis].offsetAttr] = scrolled, _this4$contentWrapper));
  
            elWindow.requestAnimationFrame(scrollTo);
          }
        } else {
          if (scrolled < scrollSize) {
            var _this4$contentWrapper2;
  
            scrolled += _this4.options.clickOnTrackSpeed;
  
            _this4.contentWrapperEl.scrollTo((_this4$contentWrapper2 = {}, _this4$contentWrapper2[_this4.axis[axis].offsetAttr] = scrolled, _this4$contentWrapper2));
  
            elWindow.requestAnimationFrame(scrollTo);
          }
        }
      };
  
      scrollTo();
    }
    /**
     * Getter for content element
     */
    ;
  
    _proto.getContentElement = function getContentElement() {
      return this.contentEl;
    }
    /**
     * Getter for original scrolling element
     */
    ;
  
    _proto.getScrollElement = function getScrollElement() {
      return this.contentWrapperEl;
    };
  
    _proto.getScrollbarWidth = function getScrollbarWidth() {
      // Try/catch for FF 56 throwing on undefined computedStyles
      try {
        // Detect browsers supporting CSS scrollbar styling and do not calculate
        if (getComputedStyle(this.contentWrapperEl, '::-webkit-scrollbar').display === 'none' || 'scrollbarWidth' in document.documentElement.style || '-ms-overflow-style' in document.documentElement.style) {
          return 0;
        } else {
          return scrollbarWidth(this.el);
        }
      } catch (e) {
        return scrollbarWidth(this.el);
      }
    };
  
    _proto.removeListeners = function removeListeners() {
      var _this5 = this;
  
      var elWindow = getElementWindow(this.el); // Event listeners
  
      if (this.options.autoHide) {
        this.el.removeEventListener('mouseenter', this.onMouseEnter);
      }
  
      ['mousedown', 'click', 'dblclick'].forEach(function (e) {
        _this5.el.removeEventListener(e, _this5.onPointerEvent, true);
      });
      ['touchstart', 'touchend', 'touchmove'].forEach(function (e) {
        _this5.el.removeEventListener(e, _this5.onPointerEvent, {
          capture: true,
          passive: true
        });
      });
      this.el.removeEventListener('mousemove', this.onMouseMove);
      this.el.removeEventListener('mouseleave', this.onMouseLeave);
  
      if (this.contentWrapperEl) {
        this.contentWrapperEl.removeEventListener('scroll', this.onScroll);
      }
  
      elWindow.removeEventListener('resize', this.onWindowResize);
  
      if (this.mutationObserver) {
        this.mutationObserver.disconnect();
      }
  
      if (this.resizeObserver) {
        this.resizeObserver.disconnect();
      } // Cancel all debounced functions
  
  
      this.recalculate.cancel();
      this.onMouseMove.cancel();
      this.hideScrollbars.cancel();
      this.onWindowResize.cancel();
    }
    /**
     * UnMount mutation observer and delete SimpleBar instance from DOM element
     */
    ;
  
    _proto.unMount = function unMount() {
      this.removeListeners();
      SimpleBar.instances.delete(this.el);
    }
    /**
     * Check if mouse is within bounds
     */
    ;
  
    _proto.isWithinBounds = function isWithinBounds(bbox) {
      return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height;
    }
    /**
     * Find element children matches query
     */
    ;
  
    _proto.findChild = function findChild(el, query) {
      var matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
      return Array.prototype.filter.call(el.children, function (child) {
        return matches.call(child, query);
      })[0];
    };
  
    return SimpleBar;
  }();
  
  SimpleBar.defaultOptions = {
    autoHide: true,
    forceVisible: false,
    clickOnTrack: true,
    clickOnTrackSpeed: 40,
    classNames: {
      contentEl: 'simplebar-content',
      contentWrapper: 'simplebar-content-wrapper',
      offset: 'simplebar-offset',
      mask: 'simplebar-mask',
      wrapper: 'simplebar-wrapper',
      placeholder: 'simplebar-placeholder',
      scrollbar: 'simplebar-scrollbar',
      track: 'simplebar-track',
      heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper',
      heightAutoObserverEl: 'simplebar-height-auto-observer',
      visible: 'simplebar-visible',
      horizontal: 'simplebar-horizontal',
      vertical: 'simplebar-vertical',
      hover: 'simplebar-hover',
      dragging: 'simplebar-dragging'
    },
    scrollbarMinSize: 25,
    scrollbarMaxSize: 0,
    timeout: 1000
  };
  SimpleBar.instances = new WeakMap();
  
  SimpleBar.initDOMLoadedElements = function () {
    document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements);
    window.removeEventListener('load', this.initDOMLoadedElements);
    Array.prototype.forEach.call(document.querySelectorAll('[data-simplebar]'), function (el) {
      if (el.getAttribute('data-simplebar') !== 'init' && !SimpleBar.instances.has(el)) new SimpleBar(el, getOptions(el.attributes));
    });
  };
  
  SimpleBar.removeObserver = function () {
    this.globalObserver.disconnect();
  };
  
  SimpleBar.initHtmlApi = function () {
    this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+
  
    if (typeof MutationObserver !== 'undefined') {
      // Mutation observer to observe dynamically added elements
      this.globalObserver = new MutationObserver(SimpleBar.handleMutations);
      this.globalObserver.observe(document, {
        childList: true,
        subtree: true
      });
    } // Taken from jQuery `ready` function
    // Instantiate elements already present on the page
  
  
    if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) {
      // Handle it asynchronously to allow scripts the opportunity to delay init
      window.setTimeout(this.initDOMLoadedElements);
    } else {
      document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements);
      window.addEventListener('load', this.initDOMLoadedElements);
    }
  };
  
  SimpleBar.handleMutations = function (mutations) {
    mutations.forEach(function (mutation) {
      Array.prototype.forEach.call(mutation.addedNodes, function (addedNode) {
        if (addedNode.nodeType === 1) {
          if (addedNode.hasAttribute('data-simplebar')) {
            !SimpleBar.instances.has(addedNode) && new SimpleBar(addedNode, getOptions(addedNode.attributes));
          } else {
            Array.prototype.forEach.call(addedNode.querySelectorAll('[data-simplebar]'), function (el) {
              if (el.getAttribute('data-simplebar') !== 'init' && !SimpleBar.instances.has(el)) new SimpleBar(el, getOptions(el.attributes));
            });
          }
        }
      });
      Array.prototype.forEach.call(mutation.removedNodes, function (removedNode) {
        if (removedNode.nodeType === 1) {
          if (removedNode.hasAttribute('[data-simplebar="init"]')) {
            SimpleBar.instances.has(removedNode) && SimpleBar.instances.get(removedNode).unMount();
          } else {
            Array.prototype.forEach.call(removedNode.querySelectorAll('[data-simplebar="init"]'), function (el) {
              SimpleBar.instances.has(el) && SimpleBar.instances.get(el).unMount();
            });
          }
        }
      });
    });
  };
  
  SimpleBar.getOptions = getOptions;
  /**
   * HTML API
   * Called only in a browser env.
   */
  
  if ((can_use_dom__WEBPACK_IMPORTED_MODULE_2___default())) {
    SimpleBar.initHtmlApi();
  }
  
  /* harmony default export */ __webpack_exports__["default"] = (SimpleBar);
  //# sourceMappingURL=simplebar.esm.js.map
  
  
  /***/ }),
  
  /***/ "./node_modules/slick-carousel/slick/slick.js":
  /*!****************************************************!*\
    !*** ./node_modules/slick-carousel/slick/slick.js ***!
    \****************************************************/
  /***/ (function(module, exports, __webpack_require__) {
  
  var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
       _ _      _       _
   ___| (_) ___| | __  (_)___
  / __| | |/ __| |/ /  | / __|
  \__ \ | | (__|   < _ | \__ \
  |___/_|_|\___|_|\_(_)/ |___/
                     |__/
  
   Version: 1.8.1
    Author: Ken Wheeler
   Website: http://kenwheeler.github.io
      Docs: http://kenwheeler.github.io/slick
      Repo: http://github.com/kenwheeler/slick
    Issues: http://github.com/kenwheeler/slick/issues
  
   */
  /* global window, document, define, jQuery, setInterval, clearInterval */
  ;(function(factory) {
      'use strict';
      if (true) {
          !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
  		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
  		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
  		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
      } else {}
  
  }(function($) {
      'use strict';
      var Slick = window.Slick || {};
  
      Slick = (function() {
  
          var instanceUid = 0;
  
          function Slick(element, settings) {
  
              var _ = this, dataSettings;
  
              _.defaults = {
                  accessibility: true,
                  adaptiveHeight: false,
                  appendArrows: $(element),
                  appendDots: $(element),
                  arrows: true,
                  asNavFor: null,
                  prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',
                  nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>',
                  autoplay: false,
                  autoplaySpeed: 3000,
                  centerMode: false,
                  centerPadding: '50px',
                  cssEase: 'ease',
                  customPaging: function(slider, i) {
                      return $('<button type="button" />').text(i + 1);
                  },
                  dots: false,
                  dotsClass: 'slick-dots',
                  draggable: true,
                  easing: 'linear',
                  edgeFriction: 0.35,
                  fade: false,
                  focusOnSelect: false,
                  focusOnChange: false,
                  infinite: true,
                  initialSlide: 0,
                  lazyLoad: 'ondemand',
                  mobileFirst: false,
                  pauseOnHover: true,
                  pauseOnFocus: true,
                  pauseOnDotsHover: false,
                  respondTo: 'window',
                  responsive: null,
                  rows: 1,
                  rtl: false,
                  slide: '',
                  slidesPerRow: 1,
                  slidesToShow: 1,
                  slidesToScroll: 1,
                  speed: 500,
                  swipe: true,
                  swipeToSlide: false,
                  touchMove: true,
                  touchThreshold: 5,
                  useCSS: true,
                  useTransform: true,
                  variableWidth: false,
                  vertical: false,
                  verticalSwiping: false,
                  waitForAnimate: true,
                  zIndex: 1000
              };
  
              _.initials = {
                  animating: false,
                  dragging: false,
                  autoPlayTimer: null,
                  currentDirection: 0,
                  currentLeft: null,
                  currentSlide: 0,
                  direction: 1,
                  $dots: null,
                  listWidth: null,
                  listHeight: null,
                  loadIndex: 0,
                  $nextArrow: null,
                  $prevArrow: null,
                  scrolling: false,
                  slideCount: null,
                  slideWidth: null,
                  $slideTrack: null,
                  $slides: null,
                  sliding: false,
                  slideOffset: 0,
                  swipeLeft: null,
                  swiping: false,
                  $list: null,
                  touchObject: {},
                  transformsEnabled: false,
                  unslicked: false
              };
  
              $.extend(_, _.initials);
  
              _.activeBreakpoint = null;
              _.animType = null;
              _.animProp = null;
              _.breakpoints = [];
              _.breakpointSettings = [];
              _.cssTransitions = false;
              _.focussed = false;
              _.interrupted = false;
              _.hidden = 'hidden';
              _.paused = true;
              _.positionProp = null;
              _.respondTo = null;
              _.rowCount = 1;
              _.shouldClick = true;
              _.$slider = $(element);
              _.$slidesCache = null;
              _.transformType = null;
              _.transitionType = null;
              _.visibilityChange = 'visibilitychange';
              _.windowWidth = 0;
              _.windowTimer = null;
  
              dataSettings = $(element).data('slick') || {};
  
              _.options = $.extend({}, _.defaults, settings, dataSettings);
  
              _.currentSlide = _.options.initialSlide;
  
              _.originalSettings = _.options;
  
              if (typeof document.mozHidden !== 'undefined') {
                  _.hidden = 'mozHidden';
                  _.visibilityChange = 'mozvisibilitychange';
              } else if (typeof document.webkitHidden !== 'undefined') {
                  _.hidden = 'webkitHidden';
                  _.visibilityChange = 'webkitvisibilitychange';
              }
  
              _.autoPlay = $.proxy(_.autoPlay, _);
              _.autoPlayClear = $.proxy(_.autoPlayClear, _);
              _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
              _.changeSlide = $.proxy(_.changeSlide, _);
              _.clickHandler = $.proxy(_.clickHandler, _);
              _.selectHandler = $.proxy(_.selectHandler, _);
              _.setPosition = $.proxy(_.setPosition, _);
              _.swipeHandler = $.proxy(_.swipeHandler, _);
              _.dragHandler = $.proxy(_.dragHandler, _);
              _.keyHandler = $.proxy(_.keyHandler, _);
  
              _.instanceUid = instanceUid++;
  
              // A simple way to check for HTML strings
              // Strict HTML recognition (must start with <)
              // Extracted from jQuery v1.11 source
              _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
  
  
              _.registerBreakpoints();
              _.init(true);
  
          }
  
          return Slick;
  
      }());
  
      Slick.prototype.activateADA = function() {
          var _ = this;
  
          _.$slideTrack.find('.slick-active').attr({
              'aria-hidden': 'false'
          }).find('a, input, button, select').attr({
              'tabindex': '0'
          });
  
      };
  
      Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
  
          var _ = this;
  
          if (typeof(index) === 'boolean') {
              addBefore = index;
              index = null;
          } else if (index < 0 || (index >= _.slideCount)) {
              return false;
          }
  
          _.unload();
  
          if (typeof(index) === 'number') {
              if (index === 0 && _.$slides.length === 0) {
                  $(markup).appendTo(_.$slideTrack);
              } else if (addBefore) {
                  $(markup).insertBefore(_.$slides.eq(index));
              } else {
                  $(markup).insertAfter(_.$slides.eq(index));
              }
          } else {
              if (addBefore === true) {
                  $(markup).prependTo(_.$slideTrack);
              } else {
                  $(markup).appendTo(_.$slideTrack);
              }
          }
  
          _.$slides = _.$slideTrack.children(this.options.slide);
  
          _.$slideTrack.children(this.options.slide).detach();
  
          _.$slideTrack.append(_.$slides);
  
          _.$slides.each(function(index, element) {
              $(element).attr('data-slick-index', index);
          });
  
          _.$slidesCache = _.$slides;
  
          _.reinit();
  
      };
  
      Slick.prototype.animateHeight = function() {
          var _ = this;
          if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
              var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
              _.$list.animate({
                  height: targetHeight
              }, _.options.speed);
          }
      };
  
      Slick.prototype.animateSlide = function(targetLeft, callback) {
  
          var animProps = {},
              _ = this;
  
          _.animateHeight();
  
          if (_.options.rtl === true && _.options.vertical === false) {
              targetLeft = -targetLeft;
          }
          if (_.transformsEnabled === false) {
              if (_.options.vertical === false) {
                  _.$slideTrack.animate({
                      left: targetLeft
                  }, _.options.speed, _.options.easing, callback);
              } else {
                  _.$slideTrack.animate({
                      top: targetLeft
                  }, _.options.speed, _.options.easing, callback);
              }
  
          } else {
  
              if (_.cssTransitions === false) {
                  if (_.options.rtl === true) {
                      _.currentLeft = -(_.currentLeft);
                  }
                  $({
                      animStart: _.currentLeft
                  }).animate({
                      animStart: targetLeft
                  }, {
                      duration: _.options.speed,
                      easing: _.options.easing,
                      step: function(now) {
                          now = Math.ceil(now);
                          if (_.options.vertical === false) {
                              animProps[_.animType] = 'translate(' +
                                  now + 'px, 0px)';
                              _.$slideTrack.css(animProps);
                          } else {
                              animProps[_.animType] = 'translate(0px,' +
                                  now + 'px)';
                              _.$slideTrack.css(animProps);
                          }
                      },
                      complete: function() {
                          if (callback) {
                              callback.call();
                          }
                      }
                  });
  
              } else {
  
                  _.applyTransition();
                  targetLeft = Math.ceil(targetLeft);
  
                  if (_.options.vertical === false) {
                      animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
                  } else {
                      animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
                  }
                  _.$slideTrack.css(animProps);
  
                  if (callback) {
                      setTimeout(function() {
  
                          _.disableTransition();
  
                          callback.call();
                      }, _.options.speed);
                  }
  
              }
  
          }
  
      };
  
      Slick.prototype.getNavTarget = function() {
  
          var _ = this,
              asNavFor = _.options.asNavFor;
  
          if ( asNavFor && asNavFor !== null ) {
              asNavFor = $(asNavFor).not(_.$slider);
          }
  
          return asNavFor;
  
      };
  
      Slick.prototype.asNavFor = function(index) {
  
          var _ = this,
              asNavFor = _.getNavTarget();
  
          if ( asNavFor !== null && typeof asNavFor === 'object' ) {
              asNavFor.each(function() {
                  var target = $(this).slick('getSlick');
                  if(!target.unslicked) {
                      target.slideHandler(index, true);
                  }
              });
          }
  
      };
  
      Slick.prototype.applyTransition = function(slide) {
  
          var _ = this,
              transition = {};
  
          if (_.options.fade === false) {
              transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
          } else {
              transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
          }
  
          if (_.options.fade === false) {
              _.$slideTrack.css(transition);
          } else {
              _.$slides.eq(slide).css(transition);
          }
  
      };
  
      Slick.prototype.autoPlay = function() {
  
          var _ = this;
  
          _.autoPlayClear();
  
          if ( _.slideCount > _.options.slidesToShow ) {
              _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
          }
  
      };
  
      Slick.prototype.autoPlayClear = function() {
  
          var _ = this;
  
          if (_.autoPlayTimer) {
              clearInterval(_.autoPlayTimer);
          }
  
      };
  
      Slick.prototype.autoPlayIterator = function() {
  
          var _ = this,
              slideTo = _.currentSlide + _.options.slidesToScroll;
  
          if ( !_.paused && !_.interrupted && !_.focussed ) {
  
              if ( _.options.infinite === false ) {
  
                  if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
                      _.direction = 0;
                  }
  
                  else if ( _.direction === 0 ) {
  
                      slideTo = _.currentSlide - _.options.slidesToScroll;
  
                      if ( _.currentSlide - 1 === 0 ) {
                          _.direction = 1;
                      }
  
                  }
  
              }
  
              _.slideHandler( slideTo );
  
          }
  
      };
  
      Slick.prototype.buildArrows = function() {
  
          var _ = this;
  
          if (_.options.arrows === true ) {
  
              _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
              _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
  
              if( _.slideCount > _.options.slidesToShow ) {
  
                  _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
                  _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
  
                  if (_.htmlExpr.test(_.options.prevArrow)) {
                      _.$prevArrow.prependTo(_.options.appendArrows);
                  }
  
                  if (_.htmlExpr.test(_.options.nextArrow)) {
                      _.$nextArrow.appendTo(_.options.appendArrows);
                  }
  
                  if (_.options.infinite !== true) {
                      _.$prevArrow
                          .addClass('slick-disabled')
                          .attr('aria-disabled', 'true');
                  }
  
              } else {
  
                  _.$prevArrow.add( _.$nextArrow )
  
                      .addClass('slick-hidden')
                      .attr({
                          'aria-disabled': 'true',
                          'tabindex': '-1'
                      });
  
              }
  
          }
  
      };
  
      Slick.prototype.buildDots = function() {
  
          var _ = this,
              i, dot;
  
          if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
  
              _.$slider.addClass('slick-dotted');
  
              dot = $('<ul />').addClass(_.options.dotsClass);
  
              for (i = 0; i <= _.getDotCount(); i += 1) {
                  dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
              }
  
              _.$dots = dot.appendTo(_.options.appendDots);
  
              _.$dots.find('li').first().addClass('slick-active');
  
          }
  
      };
  
      Slick.prototype.buildOut = function() {
  
          var _ = this;
  
          _.$slides =
              _.$slider
                  .children( _.options.slide + ':not(.slick-cloned)')
                  .addClass('slick-slide');
  
          _.slideCount = _.$slides.length;
  
          _.$slides.each(function(index, element) {
              $(element)
                  .attr('data-slick-index', index)
                  .data('originalStyling', $(element).attr('style') || '');
          });
  
          _.$slider.addClass('slick-slider');
  
          _.$slideTrack = (_.slideCount === 0) ?
              $('<div class="slick-track"/>').appendTo(_.$slider) :
              _.$slides.wrapAll('<div class="slick-track"/>').parent();
  
          _.$list = _.$slideTrack.wrap(
              '<div class="slick-list"/>').parent();
          _.$slideTrack.css('opacity', 0);
  
          if (_.options.centerMode === true || _.options.swipeToSlide === true) {
              _.options.slidesToScroll = 1;
          }
  
          $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
  
          _.setupInfinite();
  
          _.buildArrows();
  
          _.buildDots();
  
          _.updateDots();
  
  
          _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
  
          if (_.options.draggable === true) {
              _.$list.addClass('draggable');
          }
  
      };
  
      Slick.prototype.buildRows = function() {
  
          var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
  
          newSlides = document.createDocumentFragment();
          originalSlides = _.$slider.children();
  
          if(_.options.rows > 0) {
  
              slidesPerSection = _.options.slidesPerRow * _.options.rows;
              numOfSlides = Math.ceil(
                  originalSlides.length / slidesPerSection
              );
  
              for(a = 0; a < numOfSlides; a++){
                  var slide = document.createElement('div');
                  for(b = 0; b < _.options.rows; b++) {
                      var row = document.createElement('div');
                      for(c = 0; c < _.options.slidesPerRow; c++) {
                          var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
                          if (originalSlides.get(target)) {
                              row.appendChild(originalSlides.get(target));
                          }
                      }
                      slide.appendChild(row);
                  }
                  newSlides.appendChild(slide);
              }
  
              _.$slider.empty().append(newSlides);
              _.$slider.children().children().children()
                  .css({
                      'width':(100 / _.options.slidesPerRow) + '%',
                      'display': 'inline-block'
                  });
  
          }
  
      };
  
      Slick.prototype.checkResponsive = function(initial, forceUpdate) {
  
          var _ = this,
              breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
          var sliderWidth = _.$slider.width();
          var windowWidth = window.innerWidth || $(window).width();
  
          if (_.respondTo === 'window') {
              respondToWidth = windowWidth;
          } else if (_.respondTo === 'slider') {
              respondToWidth = sliderWidth;
          } else if (_.respondTo === 'min') {
              respondToWidth = Math.min(windowWidth, sliderWidth);
          }
  
          if ( _.options.responsive &&
              _.options.responsive.length &&
              _.options.responsive !== null) {
  
              targetBreakpoint = null;
  
              for (breakpoint in _.breakpoints) {
                  if (_.breakpoints.hasOwnProperty(breakpoint)) {
                      if (_.originalSettings.mobileFirst === false) {
                          if (respondToWidth < _.breakpoints[breakpoint]) {
                              targetBreakpoint = _.breakpoints[breakpoint];
                          }
                      } else {
                          if (respondToWidth > _.breakpoints[breakpoint]) {
                              targetBreakpoint = _.breakpoints[breakpoint];
                          }
                      }
                  }
              }
  
              if (targetBreakpoint !== null) {
                  if (_.activeBreakpoint !== null) {
                      if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
                          _.activeBreakpoint =
                              targetBreakpoint;
                          if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
                              _.unslick(targetBreakpoint);
                          } else {
                              _.options = $.extend({}, _.originalSettings,
                                  _.breakpointSettings[
                                      targetBreakpoint]);
                              if (initial === true) {
                                  _.currentSlide = _.options.initialSlide;
                              }
                              _.refresh(initial);
                          }
                          triggerBreakpoint = targetBreakpoint;
                      }
                  } else {
                      _.activeBreakpoint = targetBreakpoint;
                      if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
                          _.unslick(targetBreakpoint);
                      } else {
                          _.options = $.extend({}, _.originalSettings,
                              _.breakpointSettings[
                                  targetBreakpoint]);
                          if (initial === true) {
                              _.currentSlide = _.options.initialSlide;
                          }
                          _.refresh(initial);
                      }
                      triggerBreakpoint = targetBreakpoint;
                  }
              } else {
                  if (_.activeBreakpoint !== null) {
                      _.activeBreakpoint = null;
                      _.options = _.originalSettings;
                      if (initial === true) {
                          _.currentSlide = _.options.initialSlide;
                      }
                      _.refresh(initial);
                      triggerBreakpoint = targetBreakpoint;
                  }
              }
  
              // only trigger breakpoints during an actual break. not on initialize.
              if( !initial && triggerBreakpoint !== false ) {
                  _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
              }
          }
  
      };
  
      Slick.prototype.changeSlide = function(event, dontAnimate) {
  
          var _ = this,
              $target = $(event.currentTarget),
              indexOffset, slideOffset, unevenOffset;
  
          // If target is a link, prevent default action.
          if($target.is('a')) {
              event.preventDefault();
          }
  
          // If target is not the <li> element (ie: a child), find the <li>.
          if(!$target.is('li')) {
              $target = $target.closest('li');
          }
  
          unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
          indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
  
          switch (event.data.message) {
  
              case 'previous':
                  slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
                  if (_.slideCount > _.options.slidesToShow) {
                      _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
                  }
                  break;
  
              case 'next':
                  slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
                  if (_.slideCount > _.options.slidesToShow) {
                      _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
                  }
                  break;
  
              case 'index':
                  var index = event.data.index === 0 ? 0 :
                      event.data.index || $target.index() * _.options.slidesToScroll;
  
                  _.slideHandler(_.checkNavigable(index), false, dontAnimate);
                  $target.children().trigger('focus');
                  break;
  
              default:
                  return;
          }
  
      };
  
      Slick.prototype.checkNavigable = function(index) {
  
          var _ = this,
              navigables, prevNavigable;
  
          navigables = _.getNavigableIndexes();
          prevNavigable = 0;
          if (index > navigables[navigables.length - 1]) {
              index = navigables[navigables.length - 1];
          } else {
              for (var n in navigables) {
                  if (index < navigables[n]) {
                      index = prevNavigable;
                      break;
                  }
                  prevNavigable = navigables[n];
              }
          }
  
          return index;
      };
  
      Slick.prototype.cleanUpEvents = function() {
  
          var _ = this;
  
          if (_.options.dots && _.$dots !== null) {
  
              $('li', _.$dots)
                  .off('click.slick', _.changeSlide)
                  .off('mouseenter.slick', $.proxy(_.interrupt, _, true))
                  .off('mouseleave.slick', $.proxy(_.interrupt, _, false));
  
              if (_.options.accessibility === true) {
                  _.$dots.off('keydown.slick', _.keyHandler);
              }
          }
  
          _.$slider.off('focus.slick blur.slick');
  
          if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
              _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
              _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
  
              if (_.options.accessibility === true) {
                  _.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler);
                  _.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler);
              }
          }
  
          _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
          _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
          _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
          _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
  
          _.$list.off('click.slick', _.clickHandler);
  
          $(document).off(_.visibilityChange, _.visibility);
  
          _.cleanUpSlideEvents();
  
          if (_.options.accessibility === true) {
              _.$list.off('keydown.slick', _.keyHandler);
          }
  
          if (_.options.focusOnSelect === true) {
              $(_.$slideTrack).children().off('click.slick', _.selectHandler);
          }
  
          $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
  
          $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
  
          $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
  
          $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
  
      };
  
      Slick.prototype.cleanUpSlideEvents = function() {
  
          var _ = this;
  
          _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
          _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
  
      };
  
      Slick.prototype.cleanUpRows = function() {
  
          var _ = this, originalSlides;
  
          if(_.options.rows > 0) {
              originalSlides = _.$slides.children().children();
              originalSlides.removeAttr('style');
              _.$slider.empty().append(originalSlides);
          }
  
      };
  
      Slick.prototype.clickHandler = function(event) {
  
          var _ = this;
  
          if (_.shouldClick === false) {
              event.stopImmediatePropagation();
              event.stopPropagation();
              event.preventDefault();
          }
  
      };
  
      Slick.prototype.destroy = function(refresh) {
  
          var _ = this;
  
          _.autoPlayClear();
  
          _.touchObject = {};
  
          _.cleanUpEvents();
  
          $('.slick-cloned', _.$slider).detach();
  
          if (_.$dots) {
              _.$dots.remove();
          }
  
          if ( _.$prevArrow && _.$prevArrow.length ) {
  
              _.$prevArrow
                  .removeClass('slick-disabled slick-arrow slick-hidden')
                  .removeAttr('aria-hidden aria-disabled tabindex')
                  .css('display','');
  
              if ( _.htmlExpr.test( _.options.prevArrow )) {
                  _.$prevArrow.remove();
              }
          }
  
          if ( _.$nextArrow && _.$nextArrow.length ) {
  
              _.$nextArrow
                  .removeClass('slick-disabled slick-arrow slick-hidden')
                  .removeAttr('aria-hidden aria-disabled tabindex')
                  .css('display','');
  
              if ( _.htmlExpr.test( _.options.nextArrow )) {
                  _.$nextArrow.remove();
              }
          }
  
  
          if (_.$slides) {
  
              _.$slides
                  .removeClass('slick-slide slick-active slick-center slick-visible slick-current')
                  .removeAttr('aria-hidden')
                  .removeAttr('data-slick-index')
                  .each(function(){
                      $(this).attr('style', $(this).data('originalStyling'));
                  });
  
              _.$slideTrack.children(this.options.slide).detach();
  
              _.$slideTrack.detach();
  
              _.$list.detach();
  
              _.$slider.append(_.$slides);
          }
  
          _.cleanUpRows();
  
          _.$slider.removeClass('slick-slider');
          _.$slider.removeClass('slick-initialized');
          _.$slider.removeClass('slick-dotted');
  
          _.unslicked = true;
  
          if(!refresh) {
              _.$slider.trigger('destroy', [_]);
          }
  
      };
  
      Slick.prototype.disableTransition = function(slide) {
  
          var _ = this,
              transition = {};
  
          transition[_.transitionType] = '';
  
          if (_.options.fade === false) {
              _.$slideTrack.css(transition);
          } else {
              _.$slides.eq(slide).css(transition);
          }
  
      };
  
      Slick.prototype.fadeSlide = function(slideIndex, callback) {
  
          var _ = this;
  
          if (_.cssTransitions === false) {
  
              _.$slides.eq(slideIndex).css({
                  zIndex: _.options.zIndex
              });
  
              _.$slides.eq(slideIndex).animate({
                  opacity: 1
              }, _.options.speed, _.options.easing, callback);
  
          } else {
  
              _.applyTransition(slideIndex);
  
              _.$slides.eq(slideIndex).css({
                  opacity: 1,
                  zIndex: _.options.zIndex
              });
  
              if (callback) {
                  setTimeout(function() {
  
                      _.disableTransition(slideIndex);
  
                      callback.call();
                  }, _.options.speed);
              }
  
          }
  
      };
  
      Slick.prototype.fadeSlideOut = function(slideIndex) {
  
          var _ = this;
  
          if (_.cssTransitions === false) {
  
              _.$slides.eq(slideIndex).animate({
                  opacity: 0,
                  zIndex: _.options.zIndex - 2
              }, _.options.speed, _.options.easing);
  
          } else {
  
              _.applyTransition(slideIndex);
  
              _.$slides.eq(slideIndex).css({
                  opacity: 0,
                  zIndex: _.options.zIndex - 2
              });
  
          }
  
      };
  
      Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
  
          var _ = this;
  
          if (filter !== null) {
  
              _.$slidesCache = _.$slides;
  
              _.unload();
  
              _.$slideTrack.children(this.options.slide).detach();
  
              _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
  
              _.reinit();
  
          }
  
      };
  
      Slick.prototype.focusHandler = function() {
  
          var _ = this;
  
          _.$slider
              .off('focus.slick blur.slick')
              .on('focus.slick blur.slick', '*', function(event) {
  
              event.stopImmediatePropagation();
              var $sf = $(this);
  
              setTimeout(function() {
  
                  if( _.options.pauseOnFocus ) {
                      _.focussed = $sf.is(':focus');
                      _.autoPlay();
                  }
  
              }, 0);
  
          });
      };
  
      Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
  
          var _ = this;
          return _.currentSlide;
  
      };
  
      Slick.prototype.getDotCount = function() {
  
          var _ = this;
  
          var breakPoint = 0;
          var counter = 0;
          var pagerQty = 0;
  
          if (_.options.infinite === true) {
              if (_.slideCount <= _.options.slidesToShow) {
                   ++pagerQty;
              } else {
                  while (breakPoint < _.slideCount) {
                      ++pagerQty;
                      breakPoint = counter + _.options.slidesToScroll;
                      counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
                  }
              }
          } else if (_.options.centerMode === true) {
              pagerQty = _.slideCount;
          } else if(!_.options.asNavFor) {
              pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
          }else {
              while (breakPoint < _.slideCount) {
                  ++pagerQty;
                  breakPoint = counter + _.options.slidesToScroll;
                  counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
              }
          }
  
          return pagerQty - 1;
  
      };
  
      Slick.prototype.getLeft = function(slideIndex) {
  
          var _ = this,
              targetLeft,
              verticalHeight,
              verticalOffset = 0,
              targetSlide,
              coef;
  
          _.slideOffset = 0;
          verticalHeight = _.$slides.first().outerHeight(true);
  
          if (_.options.infinite === true) {
              if (_.slideCount > _.options.slidesToShow) {
                  _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
                  coef = -1
  
                  if (_.options.vertical === true && _.options.centerMode === true) {
                      if (_.options.slidesToShow === 2) {
                          coef = -1.5;
                      } else if (_.options.slidesToShow === 1) {
                          coef = -2
                      }
                  }
                  verticalOffset = (verticalHeight * _.options.slidesToShow) * coef;
              }
              if (_.slideCount % _.options.slidesToScroll !== 0) {
                  if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
                      if (slideIndex > _.slideCount) {
                          _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
                          verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
                      } else {
                          _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
                          verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
                      }
                  }
              }
          } else {
              if (slideIndex + _.options.slidesToShow > _.slideCount) {
                  _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
                  verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
              }
          }
  
          if (_.slideCount <= _.options.slidesToShow) {
              _.slideOffset = 0;
              verticalOffset = 0;
          }
  
          if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) {
              _.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2);
          } else if (_.options.centerMode === true && _.options.infinite === true) {
              _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
          } else if (_.options.centerMode === true) {
              _.slideOffset = 0;
              _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
          }
  
          if (_.options.vertical === false) {
              targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
          } else {
              targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
          }
  
          if (_.options.variableWidth === true) {
  
              if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
                  targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
              } else {
                  targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
              }
  
              if (_.options.rtl === true) {
                  if (targetSlide[0]) {
                      targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
                  } else {
                      targetLeft =  0;
                  }
              } else {
                  targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
              }
  
              if (_.options.centerMode === true) {
                  if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
                      targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
                  } else {
                      targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
                  }
  
                  if (_.options.rtl === true) {
                      if (targetSlide[0]) {
                          targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
                      } else {
                          targetLeft =  0;
                      }
                  } else {
                      targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
                  }
  
                  targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
              }
          }
  
          return targetLeft;
  
      };
  
      Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
  
          var _ = this;
  
          return _.options[option];
  
      };
  
      Slick.prototype.getNavigableIndexes = function() {
  
          var _ = this,
              breakPoint = 0,
              counter = 0,
              indexes = [],
              max;
  
          if (_.options.infinite === false) {
              max = _.slideCount;
          } else {
              breakPoint = _.options.slidesToScroll * -1;
              counter = _.options.slidesToScroll * -1;
              max = _.slideCount * 2;
          }
  
          while (breakPoint < max) {
              indexes.push(breakPoint);
              breakPoint = counter + _.options.slidesToScroll;
              counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
          }
  
          return indexes;
  
      };
  
      Slick.prototype.getSlick = function() {
  
          return this;
  
      };
  
      Slick.prototype.getSlideCount = function() {
  
          var _ = this,
              slidesTraversed, swipedSlide, centerOffset;
  
          centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
  
          if (_.options.swipeToSlide === true) {
              _.$slideTrack.find('.slick-slide').each(function(index, slide) {
                  if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
                      swipedSlide = slide;
                      return false;
                  }
              });
  
              slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
  
              return slidesTraversed;
  
          } else {
              return _.options.slidesToScroll;
          }
  
      };
  
      Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
  
          var _ = this;
  
          _.changeSlide({
              data: {
                  message: 'index',
                  index: parseInt(slide)
              }
          }, dontAnimate);
  
      };
  
      Slick.prototype.init = function(creation) {
  
          var _ = this;
  
          if (!$(_.$slider).hasClass('slick-initialized')) {
  
              $(_.$slider).addClass('slick-initialized');
  
              _.buildRows();
              _.buildOut();
              _.setProps();
              _.startLoad();
              _.loadSlider();
              _.initializeEvents();
              _.updateArrows();
              _.updateDots();
              _.checkResponsive(true);
              _.focusHandler();
  
          }
  
          if (creation) {
              _.$slider.trigger('init', [_]);
          }
  
          if (_.options.accessibility === true) {
              _.initADA();
          }
  
          if ( _.options.autoplay ) {
  
              _.paused = false;
              _.autoPlay();
  
          }
  
      };
  
      Slick.prototype.initADA = function() {
          var _ = this,
                  numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow),
                  tabControlIndexes = _.getNavigableIndexes().filter(function(val) {
                      return (val >= 0) && (val < _.slideCount);
                  });
  
          _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
              'aria-hidden': 'true',
              'tabindex': '-1'
          }).find('a, input, button, select').attr({
              'tabindex': '-1'
          });
  
          if (_.$dots !== null) {
              _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
                  var slideControlIndex = tabControlIndexes.indexOf(i);
  
                  $(this).attr({
                      'role': 'tabpanel',
                      'id': 'slick-slide' + _.instanceUid + i,
                      'tabindex': -1
                  });
  
                  if (slideControlIndex !== -1) {
                     var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex
                     if ($('#' + ariaButtonControl).length) {
                       $(this).attr({
                           'aria-describedby': ariaButtonControl
                       });
                     }
                  }
              });
  
              _.$dots.attr('role', 'tablist').find('li').each(function(i) {
                  var mappedSlideIndex = tabControlIndexes[i];
  
                  $(this).attr({
                      'role': 'presentation'
                  });
  
                  $(this).find('button').first().attr({
                      'role': 'tab',
                      'id': 'slick-slide-control' + _.instanceUid + i,
                      'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex,
                      'aria-label': (i + 1) + ' of ' + numDotGroups,
                      'aria-selected': null,
                      'tabindex': '-1'
                  });
  
              }).eq(_.currentSlide).find('button').attr({
                  'aria-selected': 'true',
                  'tabindex': '0'
              }).end();
          }
  
          for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) {
            if (_.options.focusOnChange) {
              _.$slides.eq(i).attr({'tabindex': '0'});
            } else {
              _.$slides.eq(i).removeAttr('tabindex');
            }
          }
  
          _.activateADA();
  
      };
  
      Slick.prototype.initArrowEvents = function() {
  
          var _ = this;
  
          if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
              _.$prevArrow
                 .off('click.slick')
                 .on('click.slick', {
                      message: 'previous'
                 }, _.changeSlide);
              _.$nextArrow
                 .off('click.slick')
                 .on('click.slick', {
                      message: 'next'
                 }, _.changeSlide);
  
              if (_.options.accessibility === true) {
                  _.$prevArrow.on('keydown.slick', _.keyHandler);
                  _.$nextArrow.on('keydown.slick', _.keyHandler);
              }
          }
  
      };
  
      Slick.prototype.initDotEvents = function() {
  
          var _ = this;
  
          if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
              $('li', _.$dots).on('click.slick', {
                  message: 'index'
              }, _.changeSlide);
  
              if (_.options.accessibility === true) {
                  _.$dots.on('keydown.slick', _.keyHandler);
              }
          }
  
          if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) {
  
              $('li', _.$dots)
                  .on('mouseenter.slick', $.proxy(_.interrupt, _, true))
                  .on('mouseleave.slick', $.proxy(_.interrupt, _, false));
  
          }
  
      };
  
      Slick.prototype.initSlideEvents = function() {
  
          var _ = this;
  
          if ( _.options.pauseOnHover ) {
  
              _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
              _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
  
          }
  
      };
  
      Slick.prototype.initializeEvents = function() {
  
          var _ = this;
  
          _.initArrowEvents();
  
          _.initDotEvents();
          _.initSlideEvents();
  
          _.$list.on('touchstart.slick mousedown.slick', {
              action: 'start'
          }, _.swipeHandler);
          _.$list.on('touchmove.slick mousemove.slick', {
              action: 'move'
          }, _.swipeHandler);
          _.$list.on('touchend.slick mouseup.slick', {
              action: 'end'
          }, _.swipeHandler);
          _.$list.on('touchcancel.slick mouseleave.slick', {
              action: 'end'
          }, _.swipeHandler);
  
          _.$list.on('click.slick', _.clickHandler);
  
          $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
  
          if (_.options.accessibility === true) {
              _.$list.on('keydown.slick', _.keyHandler);
          }
  
          if (_.options.focusOnSelect === true) {
              $(_.$slideTrack).children().on('click.slick', _.selectHandler);
          }
  
          $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
  
          $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
  
          $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
  
          $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
          $(_.setPosition);
  
      };
  
      Slick.prototype.initUI = function() {
  
          var _ = this;
  
          if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
  
              _.$prevArrow.show();
              _.$nextArrow.show();
  
          }
  
          if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
  
              _.$dots.show();
  
          }
  
      };
  
      Slick.prototype.keyHandler = function(event) {
  
          var _ = this;
           //Dont slide if the cursor is inside the form fields and arrow keys are pressed
          if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
              if (event.keyCode === 37 && _.options.accessibility === true) {
                  _.changeSlide({
                      data: {
                          message: _.options.rtl === true ? 'next' :  'previous'
                      }
                  });
              } else if (event.keyCode === 39 && _.options.accessibility === true) {
                  _.changeSlide({
                      data: {
                          message: _.options.rtl === true ? 'previous' : 'next'
                      }
                  });
              }
          }
  
      };
  
      Slick.prototype.lazyLoad = function() {
  
          var _ = this,
              loadRange, cloneRange, rangeStart, rangeEnd;
  
          function loadImages(imagesScope) {
  
              $('img[data-lazy]', imagesScope).each(function() {
  
                  var image = $(this),
                      imageSource = $(this).attr('data-lazy'),
                      imageSrcSet = $(this).attr('data-srcset'),
                      imageSizes  = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'),
                      imageToLoad = document.createElement('img');
  
                  imageToLoad.onload = function() {
  
                      image
                          .animate({ opacity: 0 }, 100, function() {
  
                              if (imageSrcSet) {
                                  image
                                      .attr('srcset', imageSrcSet );
  
                                  if (imageSizes) {
                                      image
                                          .attr('sizes', imageSizes );
                                  }
                              }
  
                              image
                                  .attr('src', imageSource)
                                  .animate({ opacity: 1 }, 200, function() {
                                      image
                                          .removeAttr('data-lazy data-srcset data-sizes')
                                          .removeClass('slick-loading');
                                  });
                              _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
                          });
  
                  };
  
                  imageToLoad.onerror = function() {
  
                      image
                          .removeAttr( 'data-lazy' )
                          .removeClass( 'slick-loading' )
                          .addClass( 'slick-lazyload-error' );
  
                      _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
  
                  };
  
                  imageToLoad.src = imageSource;
  
              });
  
          }
  
          if (_.options.centerMode === true) {
              if (_.options.infinite === true) {
                  rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
                  rangeEnd = rangeStart + _.options.slidesToShow + 2;
              } else {
                  rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
                  rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
              }
          } else {
              rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
              rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
              if (_.options.fade === true) {
                  if (rangeStart > 0) rangeStart--;
                  if (rangeEnd <= _.slideCount) rangeEnd++;
              }
          }
  
          loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
  
          if (_.options.lazyLoad === 'anticipated') {
              var prevSlide = rangeStart - 1,
                  nextSlide = rangeEnd,
                  $slides = _.$slider.find('.slick-slide');
  
              for (var i = 0; i < _.options.slidesToScroll; i++) {
                  if (prevSlide < 0) prevSlide = _.slideCount - 1;
                  loadRange = loadRange.add($slides.eq(prevSlide));
                  loadRange = loadRange.add($slides.eq(nextSlide));
                  prevSlide--;
                  nextSlide++;
              }
          }
  
          loadImages(loadRange);
  
          if (_.slideCount <= _.options.slidesToShow) {
              cloneRange = _.$slider.find('.slick-slide');
              loadImages(cloneRange);
          } else
          if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
              cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
              loadImages(cloneRange);
          } else if (_.currentSlide === 0) {
              cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
              loadImages(cloneRange);
          }
  
      };
  
      Slick.prototype.loadSlider = function() {
  
          var _ = this;
  
          _.setPosition();
  
          _.$slideTrack.css({
              opacity: 1
          });
  
          _.$slider.removeClass('slick-loading');
  
          _.initUI();
  
          if (_.options.lazyLoad === 'progressive') {
              _.progressiveLazyLoad();
          }
  
      };
  
      Slick.prototype.next = Slick.prototype.slickNext = function() {
  
          var _ = this;
  
          _.changeSlide({
              data: {
                  message: 'next'
              }
          });
  
      };
  
      Slick.prototype.orientationChange = function() {
  
          var _ = this;
  
          _.checkResponsive();
          _.setPosition();
  
      };
  
      Slick.prototype.pause = Slick.prototype.slickPause = function() {
  
          var _ = this;
  
          _.autoPlayClear();
          _.paused = true;
  
      };
  
      Slick.prototype.play = Slick.prototype.slickPlay = function() {
  
          var _ = this;
  
          _.autoPlay();
          _.options.autoplay = true;
          _.paused = false;
          _.focussed = false;
          _.interrupted = false;
  
      };
  
      Slick.prototype.postSlide = function(index) {
  
          var _ = this;
  
          if( !_.unslicked ) {
  
              _.$slider.trigger('afterChange', [_, index]);
  
              _.animating = false;
  
              if (_.slideCount > _.options.slidesToShow) {
                  _.setPosition();
              }
  
              _.swipeLeft = null;
  
              if ( _.options.autoplay ) {
                  _.autoPlay();
              }
  
              if (_.options.accessibility === true) {
                  _.initADA();
  
                  if (_.options.focusOnChange) {
                      var $currentSlide = $(_.$slides.get(_.currentSlide));
                      $currentSlide.attr('tabindex', 0).focus();
                  }
              }
  
          }
  
      };
  
      Slick.prototype.prev = Slick.prototype.slickPrev = function() {
  
          var _ = this;
  
          _.changeSlide({
              data: {
                  message: 'previous'
              }
          });
  
      };
  
      Slick.prototype.preventDefault = function(event) {
  
          event.preventDefault();
  
      };
  
      Slick.prototype.progressiveLazyLoad = function( tryCount ) {
  
          tryCount = tryCount || 1;
  
          var _ = this,
              $imgsToLoad = $( 'img[data-lazy]', _.$slider ),
              image,
              imageSource,
              imageSrcSet,
              imageSizes,
              imageToLoad;
  
          if ( $imgsToLoad.length ) {
  
              image = $imgsToLoad.first();
              imageSource = image.attr('data-lazy');
              imageSrcSet = image.attr('data-srcset');
              imageSizes  = image.attr('data-sizes') || _.$slider.attr('data-sizes');
              imageToLoad = document.createElement('img');
  
              imageToLoad.onload = function() {
  
                  if (imageSrcSet) {
                      image
                          .attr('srcset', imageSrcSet );
  
                      if (imageSizes) {
                          image
                              .attr('sizes', imageSizes );
                      }
                  }
  
                  image
                      .attr( 'src', imageSource )
                      .removeAttr('data-lazy data-srcset data-sizes')
                      .removeClass('slick-loading');
  
                  if ( _.options.adaptiveHeight === true ) {
                      _.setPosition();
                  }
  
                  _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
                  _.progressiveLazyLoad();
  
              };
  
              imageToLoad.onerror = function() {
  
                  if ( tryCount < 3 ) {
  
                      /**
                       * try to load the image 3 times,
                       * leave a slight delay so we don't get
                       * servers blocking the request.
                       */
                      setTimeout( function() {
                          _.progressiveLazyLoad( tryCount + 1 );
                      }, 500 );
  
                  } else {
  
                      image
                          .removeAttr( 'data-lazy' )
                          .removeClass( 'slick-loading' )
                          .addClass( 'slick-lazyload-error' );
  
                      _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
  
                      _.progressiveLazyLoad();
  
                  }
  
              };
  
              imageToLoad.src = imageSource;
  
          } else {
  
              _.$slider.trigger('allImagesLoaded', [ _ ]);
  
          }
  
      };
  
      Slick.prototype.refresh = function( initializing ) {
  
          var _ = this, currentSlide, lastVisibleIndex;
  
          lastVisibleIndex = _.slideCount - _.options.slidesToShow;
  
          // in non-infinite sliders, we don't want to go past the
          // last visible index.
          if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
              _.currentSlide = lastVisibleIndex;
          }
  
          // if less slides than to show, go to start.
          if ( _.slideCount <= _.options.slidesToShow ) {
              _.currentSlide = 0;
  
          }
  
          currentSlide = _.currentSlide;
  
          _.destroy(true);
  
          $.extend(_, _.initials, { currentSlide: currentSlide });
  
          _.init();
  
          if( !initializing ) {
  
              _.changeSlide({
                  data: {
                      message: 'index',
                      index: currentSlide
                  }
              }, false);
  
          }
  
      };
  
      Slick.prototype.registerBreakpoints = function() {
  
          var _ = this, breakpoint, currentBreakpoint, l,
              responsiveSettings = _.options.responsive || null;
  
          if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
  
              _.respondTo = _.options.respondTo || 'window';
  
              for ( breakpoint in responsiveSettings ) {
  
                  l = _.breakpoints.length-1;
  
                  if (responsiveSettings.hasOwnProperty(breakpoint)) {
                      currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
  
                      // loop through the breakpoints and cut out any existing
                      // ones with the same breakpoint number, we don't want dupes.
                      while( l >= 0 ) {
                          if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
                              _.breakpoints.splice(l,1);
                          }
                          l--;
                      }
  
                      _.breakpoints.push(currentBreakpoint);
                      _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
  
                  }
  
              }
  
              _.breakpoints.sort(function(a, b) {
                  return ( _.options.mobileFirst ) ? a-b : b-a;
              });
  
          }
  
      };
  
      Slick.prototype.reinit = function() {
  
          var _ = this;
  
          _.$slides =
              _.$slideTrack
                  .children(_.options.slide)
                  .addClass('slick-slide');
  
          _.slideCount = _.$slides.length;
  
          if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
              _.currentSlide = _.currentSlide - _.options.slidesToScroll;
          }
  
          if (_.slideCount <= _.options.slidesToShow) {
              _.currentSlide = 0;
          }
  
          _.registerBreakpoints();
  
          _.setProps();
          _.setupInfinite();
          _.buildArrows();
          _.updateArrows();
          _.initArrowEvents();
          _.buildDots();
          _.updateDots();
          _.initDotEvents();
          _.cleanUpSlideEvents();
          _.initSlideEvents();
  
          _.checkResponsive(false, true);
  
          if (_.options.focusOnSelect === true) {
              $(_.$slideTrack).children().on('click.slick', _.selectHandler);
          }
  
          _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
  
          _.setPosition();
          _.focusHandler();
  
          _.paused = !_.options.autoplay;
          _.autoPlay();
  
          _.$slider.trigger('reInit', [_]);
  
      };
  
      Slick.prototype.resize = function() {
  
          var _ = this;
  
          if ($(window).width() !== _.windowWidth) {
              clearTimeout(_.windowDelay);
              _.windowDelay = window.setTimeout(function() {
                  _.windowWidth = $(window).width();
                  _.checkResponsive();
                  if( !_.unslicked ) { _.setPosition(); }
              }, 50);
          }
      };
  
      Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
  
          var _ = this;
  
          if (typeof(index) === 'boolean') {
              removeBefore = index;
              index = removeBefore === true ? 0 : _.slideCount - 1;
          } else {
              index = removeBefore === true ? --index : index;
          }
  
          if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
              return false;
          }
  
          _.unload();
  
          if (removeAll === true) {
              _.$slideTrack.children().remove();
          } else {
              _.$slideTrack.children(this.options.slide).eq(index).remove();
          }
  
          _.$slides = _.$slideTrack.children(this.options.slide);
  
          _.$slideTrack.children(this.options.slide).detach();
  
          _.$slideTrack.append(_.$slides);
  
          _.$slidesCache = _.$slides;
  
          _.reinit();
  
      };
  
      Slick.prototype.setCSS = function(position) {
  
          var _ = this,
              positionProps = {},
              x, y;
  
          if (_.options.rtl === true) {
              position = -position;
          }
          x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
          y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
  
          positionProps[_.positionProp] = position;
  
          if (_.transformsEnabled === false) {
              _.$slideTrack.css(positionProps);
          } else {
              positionProps = {};
              if (_.cssTransitions === false) {
                  positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
                  _.$slideTrack.css(positionProps);
              } else {
                  positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
                  _.$slideTrack.css(positionProps);
              }
          }
  
      };
  
      Slick.prototype.setDimensions = function() {
  
          var _ = this;
  
          if (_.options.vertical === false) {
              if (_.options.centerMode === true) {
                  _.$list.css({
                      padding: ('0px ' + _.options.centerPadding)
                  });
              }
          } else {
              _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
              if (_.options.centerMode === true) {
                  _.$list.css({
                      padding: (_.options.centerPadding + ' 0px')
                  });
              }
          }
  
          _.listWidth = _.$list.width();
          _.listHeight = _.$list.height();
  
  
          if (_.options.vertical === false && _.options.variableWidth === false) {
              _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
              _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
  
          } else if (_.options.variableWidth === true) {
              _.$slideTrack.width(5000 * _.slideCount);
          } else {
              _.slideWidth = Math.ceil(_.listWidth);
              _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
          }
  
          var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
          if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
  
      };
  
      Slick.prototype.setFade = function() {
  
          var _ = this,
              targetLeft;
  
          _.$slides.each(function(index, element) {
              targetLeft = (_.slideWidth * index) * -1;
              if (_.options.rtl === true) {
                  $(element).css({
                      position: 'relative',
                      right: targetLeft,
                      top: 0,
                      zIndex: _.options.zIndex - 2,
                      opacity: 0
                  });
              } else {
                  $(element).css({
                      position: 'relative',
                      left: targetLeft,
                      top: 0,
                      zIndex: _.options.zIndex - 2,
                      opacity: 0
                  });
              }
          });
  
          _.$slides.eq(_.currentSlide).css({
              zIndex: _.options.zIndex - 1,
              opacity: 1
          });
  
      };
  
      Slick.prototype.setHeight = function() {
  
          var _ = this;
  
          if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
              var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
              _.$list.css('height', targetHeight);
          }
  
      };
  
      Slick.prototype.setOption =
      Slick.prototype.slickSetOption = function() {
  
          /**
           * accepts arguments in format of:
           *
           *  - for changing a single option's value:
           *     .slick("setOption", option, value, refresh )
           *
           *  - for changing a set of responsive options:
           *     .slick("setOption", 'responsive', [{}, ...], refresh )
           *
           *  - for updating multiple values at once (not responsive)
           *     .slick("setOption", { 'option': value, ... }, refresh )
           */
  
          var _ = this, l, item, option, value, refresh = false, type;
  
          if( $.type( arguments[0] ) === 'object' ) {
  
              option =  arguments[0];
              refresh = arguments[1];
              type = 'multiple';
  
          } else if ( $.type( arguments[0] ) === 'string' ) {
  
              option =  arguments[0];
              value = arguments[1];
              refresh = arguments[2];
  
              if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
  
                  type = 'responsive';
  
              } else if ( typeof arguments[1] !== 'undefined' ) {
  
                  type = 'single';
  
              }
  
          }
  
          if ( type === 'single' ) {
  
              _.options[option] = value;
  
  
          } else if ( type === 'multiple' ) {
  
              $.each( option , function( opt, val ) {
  
                  _.options[opt] = val;
  
              });
  
  
          } else if ( type === 'responsive' ) {
  
              for ( item in value ) {
  
                  if( $.type( _.options.responsive ) !== 'array' ) {
  
                      _.options.responsive = [ value[item] ];
  
                  } else {
  
                      l = _.options.responsive.length-1;
  
                      // loop through the responsive object and splice out duplicates.
                      while( l >= 0 ) {
  
                          if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
  
                              _.options.responsive.splice(l,1);
  
                          }
  
                          l--;
  
                      }
  
                      _.options.responsive.push( value[item] );
  
                  }
  
              }
  
          }
  
          if ( refresh ) {
  
              _.unload();
              _.reinit();
  
          }
  
      };
  
      Slick.prototype.setPosition = function() {
  
          var _ = this;
  
          _.setDimensions();
  
          _.setHeight();
  
          if (_.options.fade === false) {
              _.setCSS(_.getLeft(_.currentSlide));
          } else {
              _.setFade();
          }
  
          _.$slider.trigger('setPosition', [_]);
  
      };
  
      Slick.prototype.setProps = function() {
  
          var _ = this,
              bodyStyle = document.body.style;
  
          _.positionProp = _.options.vertical === true ? 'top' : 'left';
  
          if (_.positionProp === 'top') {
              _.$slider.addClass('slick-vertical');
          } else {
              _.$slider.removeClass('slick-vertical');
          }
  
          if (bodyStyle.WebkitTransition !== undefined ||
              bodyStyle.MozTransition !== undefined ||
              bodyStyle.msTransition !== undefined) {
              if (_.options.useCSS === true) {
                  _.cssTransitions = true;
              }
          }
  
          if ( _.options.fade ) {
              if ( typeof _.options.zIndex === 'number' ) {
                  if( _.options.zIndex < 3 ) {
                      _.options.zIndex = 3;
                  }
              } else {
                  _.options.zIndex = _.defaults.zIndex;
              }
          }
  
          if (bodyStyle.OTransform !== undefined) {
              _.animType = 'OTransform';
              _.transformType = '-o-transform';
              _.transitionType = 'OTransition';
              if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
          }
          if (bodyStyle.MozTransform !== undefined) {
              _.animType = 'MozTransform';
              _.transformType = '-moz-transform';
              _.transitionType = 'MozTransition';
              if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
          }
          if (bodyStyle.webkitTransform !== undefined) {
              _.animType = 'webkitTransform';
              _.transformType = '-webkit-transform';
              _.transitionType = 'webkitTransition';
              if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
          }
          if (bodyStyle.msTransform !== undefined) {
              _.animType = 'msTransform';
              _.transformType = '-ms-transform';
              _.transitionType = 'msTransition';
              if (bodyStyle.msTransform === undefined) _.animType = false;
          }
          if (bodyStyle.transform !== undefined && _.animType !== false) {
              _.animType = 'transform';
              _.transformType = 'transform';
              _.transitionType = 'transition';
          }
          _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
      };
  
  
      Slick.prototype.setSlideClasses = function(index) {
  
          var _ = this,
              centerOffset, allSlides, indexOffset, remainder;
  
          allSlides = _.$slider
              .find('.slick-slide')
              .removeClass('slick-active slick-center slick-current')
              .attr('aria-hidden', 'true');
  
          _.$slides
              .eq(index)
              .addClass('slick-current');
  
          if (_.options.centerMode === true) {
  
              var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0;
  
              centerOffset = Math.floor(_.options.slidesToShow / 2);
  
              if (_.options.infinite === true) {
  
                  if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
                      _.$slides
                          .slice(index - centerOffset + evenCoef, index + centerOffset + 1)
                          .addClass('slick-active')
                          .attr('aria-hidden', 'false');
  
                  } else {
  
                      indexOffset = _.options.slidesToShow + index;
                      allSlides
                          .slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2)
                          .addClass('slick-active')
                          .attr('aria-hidden', 'false');
  
                  }
  
                  if (index === 0) {
  
                      allSlides
                          .eq(allSlides.length - 1 - _.options.slidesToShow)
                          .addClass('slick-center');
  
                  } else if (index === _.slideCount - 1) {
  
                      allSlides
                          .eq(_.options.slidesToShow)
                          .addClass('slick-center');
  
                  }
  
              }
  
              _.$slides
                  .eq(index)
                  .addClass('slick-center');
  
          } else {
  
              if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
  
                  _.$slides
                      .slice(index, index + _.options.slidesToShow)
                      .addClass('slick-active')
                      .attr('aria-hidden', 'false');
  
              } else if (allSlides.length <= _.options.slidesToShow) {
  
                  allSlides
                      .addClass('slick-active')
                      .attr('aria-hidden', 'false');
  
              } else {
  
                  remainder = _.slideCount % _.options.slidesToShow;
                  indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
  
                  if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
  
                      allSlides
                          .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
                          .addClass('slick-active')
                          .attr('aria-hidden', 'false');
  
                  } else {
  
                      allSlides
                          .slice(indexOffset, indexOffset + _.options.slidesToShow)
                          .addClass('slick-active')
                          .attr('aria-hidden', 'false');
  
                  }
  
              }
  
          }
  
          if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') {
              _.lazyLoad();
          }
      };
  
      Slick.prototype.setupInfinite = function() {
  
          var _ = this,
              i, slideIndex, infiniteCount;
  
          if (_.options.fade === true) {
              _.options.centerMode = false;
          }
  
          if (_.options.infinite === true && _.options.fade === false) {
  
              slideIndex = null;
  
              if (_.slideCount > _.options.slidesToShow) {
  
                  if (_.options.centerMode === true) {
                      infiniteCount = _.options.slidesToShow + 1;
                  } else {
                      infiniteCount = _.options.slidesToShow;
                  }
  
                  for (i = _.slideCount; i > (_.slideCount -
                          infiniteCount); i -= 1) {
                      slideIndex = i - 1;
                      $(_.$slides[slideIndex]).clone(true).attr('id', '')
                          .attr('data-slick-index', slideIndex - _.slideCount)
                          .prependTo(_.$slideTrack).addClass('slick-cloned');
                  }
                  for (i = 0; i < infiniteCount  + _.slideCount; i += 1) {
                      slideIndex = i;
                      $(_.$slides[slideIndex]).clone(true).attr('id', '')
                          .attr('data-slick-index', slideIndex + _.slideCount)
                          .appendTo(_.$slideTrack).addClass('slick-cloned');
                  }
                  _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
                      $(this).attr('id', '');
                  });
  
              }
  
          }
  
      };
  
      Slick.prototype.interrupt = function( toggle ) {
  
          var _ = this;
  
          if( !toggle ) {
              _.autoPlay();
          }
          _.interrupted = toggle;
  
      };
  
      Slick.prototype.selectHandler = function(event) {
  
          var _ = this;
  
          var targetElement =
              $(event.target).is('.slick-slide') ?
                  $(event.target) :
                  $(event.target).parents('.slick-slide');
  
          var index = parseInt(targetElement.attr('data-slick-index'));
  
          if (!index) index = 0;
  
          if (_.slideCount <= _.options.slidesToShow) {
  
              _.slideHandler(index, false, true);
              return;
  
          }
  
          _.slideHandler(index);
  
      };
  
      Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
  
          var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
              _ = this, navTarget;
  
          sync = sync || false;
  
          if (_.animating === true && _.options.waitForAnimate === true) {
              return;
          }
  
          if (_.options.fade === true && _.currentSlide === index) {
              return;
          }
  
          if (sync === false) {
              _.asNavFor(index);
          }
  
          targetSlide = index;
          targetLeft = _.getLeft(targetSlide);
          slideLeft = _.getLeft(_.currentSlide);
  
          _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
  
          if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
              if (_.options.fade === false) {
                  targetSlide = _.currentSlide;
                  if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
                      _.animateSlide(slideLeft, function() {
                          _.postSlide(targetSlide);
                      });
                  } else {
                      _.postSlide(targetSlide);
                  }
              }
              return;
          } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
              if (_.options.fade === false) {
                  targetSlide = _.currentSlide;
                  if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
                      _.animateSlide(slideLeft, function() {
                          _.postSlide(targetSlide);
                      });
                  } else {
                      _.postSlide(targetSlide);
                  }
              }
              return;
          }
  
          if ( _.options.autoplay ) {
              clearInterval(_.autoPlayTimer);
          }
  
          if (targetSlide < 0) {
              if (_.slideCount % _.options.slidesToScroll !== 0) {
                  animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
              } else {
                  animSlide = _.slideCount + targetSlide;
              }
          } else if (targetSlide >= _.slideCount) {
              if (_.slideCount % _.options.slidesToScroll !== 0) {
                  animSlide = 0;
              } else {
                  animSlide = targetSlide - _.slideCount;
              }
          } else {
              animSlide = targetSlide;
          }
  
          _.animating = true;
  
          _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
  
          oldSlide = _.currentSlide;
          _.currentSlide = animSlide;
  
          _.setSlideClasses(_.currentSlide);
  
          if ( _.options.asNavFor ) {
  
              navTarget = _.getNavTarget();
              navTarget = navTarget.slick('getSlick');
  
              if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
                  navTarget.setSlideClasses(_.currentSlide);
              }
  
          }
  
          _.updateDots();
          _.updateArrows();
  
          if (_.options.fade === true) {
              if (dontAnimate !== true) {
  
                  _.fadeSlideOut(oldSlide);
  
                  _.fadeSlide(animSlide, function() {
                      _.postSlide(animSlide);
                  });
  
              } else {
                  _.postSlide(animSlide);
              }
              _.animateHeight();
              return;
          }
  
          if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
              _.animateSlide(targetLeft, function() {
                  _.postSlide(animSlide);
              });
          } else {
              _.postSlide(animSlide);
          }
  
      };
  
      Slick.prototype.startLoad = function() {
  
          var _ = this;
  
          if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
  
              _.$prevArrow.hide();
              _.$nextArrow.hide();
  
          }
  
          if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
  
              _.$dots.hide();
  
          }
  
          _.$slider.addClass('slick-loading');
  
      };
  
      Slick.prototype.swipeDirection = function() {
  
          var xDist, yDist, r, swipeAngle, _ = this;
  
          xDist = _.touchObject.startX - _.touchObject.curX;
          yDist = _.touchObject.startY - _.touchObject.curY;
          r = Math.atan2(yDist, xDist);
  
          swipeAngle = Math.round(r * 180 / Math.PI);
          if (swipeAngle < 0) {
              swipeAngle = 360 - Math.abs(swipeAngle);
          }
  
          if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
              return (_.options.rtl === false ? 'left' : 'right');
          }
          if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
              return (_.options.rtl === false ? 'left' : 'right');
          }
          if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
              return (_.options.rtl === false ? 'right' : 'left');
          }
          if (_.options.verticalSwiping === true) {
              if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
                  return 'down';
              } else {
                  return 'up';
              }
          }
  
          return 'vertical';
  
      };
  
      Slick.prototype.swipeEnd = function(event) {
  
          var _ = this,
              slideCount,
              direction;
  
          _.dragging = false;
          _.swiping = false;
  
          if (_.scrolling) {
              _.scrolling = false;
              return false;
          }
  
          _.interrupted = false;
          _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
  
          if ( _.touchObject.curX === undefined ) {
              return false;
          }
  
          if ( _.touchObject.edgeHit === true ) {
              _.$slider.trigger('edge', [_, _.swipeDirection() ]);
          }
  
          if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
  
              direction = _.swipeDirection();
  
              switch ( direction ) {
  
                  case 'left':
                  case 'down':
  
                      slideCount =
                          _.options.swipeToSlide ?
                              _.checkNavigable( _.currentSlide + _.getSlideCount() ) :
                              _.currentSlide + _.getSlideCount();
  
                      _.currentDirection = 0;
  
                      break;
  
                  case 'right':
                  case 'up':
  
                      slideCount =
                          _.options.swipeToSlide ?
                              _.checkNavigable( _.currentSlide - _.getSlideCount() ) :
                              _.currentSlide - _.getSlideCount();
  
                      _.currentDirection = 1;
  
                      break;
  
                  default:
  
  
              }
  
              if( direction != 'vertical' ) {
  
                  _.slideHandler( slideCount );
                  _.touchObject = {};
                  _.$slider.trigger('swipe', [_, direction ]);
  
              }
  
          } else {
  
              if ( _.touchObject.startX !== _.touchObject.curX ) {
  
                  _.slideHandler( _.currentSlide );
                  _.touchObject = {};
  
              }
  
          }
  
      };
  
      Slick.prototype.swipeHandler = function(event) {
  
          var _ = this;
  
          if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
              return;
          } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
              return;
          }
  
          _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
              event.originalEvent.touches.length : 1;
  
          _.touchObject.minSwipe = _.listWidth / _.options
              .touchThreshold;
  
          if (_.options.verticalSwiping === true) {
              _.touchObject.minSwipe = _.listHeight / _.options
                  .touchThreshold;
          }
  
          switch (event.data.action) {
  
              case 'start':
                  _.swipeStart(event);
                  break;
  
              case 'move':
                  _.swipeMove(event);
                  break;
  
              case 'end':
                  _.swipeEnd(event);
                  break;
  
          }
  
      };
  
      Slick.prototype.swipeMove = function(event) {
  
          var _ = this,
              edgeWasHit = false,
              curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength;
  
          touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
  
          if (!_.dragging || _.scrolling || touches && touches.length !== 1) {
              return false;
          }
  
          curLeft = _.getLeft(_.currentSlide);
  
          _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
          _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
  
          _.touchObject.swipeLength = Math.round(Math.sqrt(
              Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
  
          verticalSwipeLength = Math.round(Math.sqrt(
              Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
  
          if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) {
              _.scrolling = true;
              return false;
          }
  
          if (_.options.verticalSwiping === true) {
              _.touchObject.swipeLength = verticalSwipeLength;
          }
  
          swipeDirection = _.swipeDirection();
  
          if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
              _.swiping = true;
              event.preventDefault();
          }
  
          positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
          if (_.options.verticalSwiping === true) {
              positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
          }
  
  
          swipeLength = _.touchObject.swipeLength;
  
          _.touchObject.edgeHit = false;
  
          if (_.options.infinite === false) {
              if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
                  swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
                  _.touchObject.edgeHit = true;
              }
          }
  
          if (_.options.vertical === false) {
              _.swipeLeft = curLeft + swipeLength * positionOffset;
          } else {
              _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
          }
          if (_.options.verticalSwiping === true) {
              _.swipeLeft = curLeft + swipeLength * positionOffset;
          }
  
          if (_.options.fade === true || _.options.touchMove === false) {
              return false;
          }
  
          if (_.animating === true) {
              _.swipeLeft = null;
              return false;
          }
  
          _.setCSS(_.swipeLeft);
  
      };
  
      Slick.prototype.swipeStart = function(event) {
  
          var _ = this,
              touches;
  
          _.interrupted = true;
  
          if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
              _.touchObject = {};
              return false;
          }
  
          if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
              touches = event.originalEvent.touches[0];
          }
  
          _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
          _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
  
          _.dragging = true;
  
      };
  
      Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
  
          var _ = this;
  
          if (_.$slidesCache !== null) {
  
              _.unload();
  
              _.$slideTrack.children(this.options.slide).detach();
  
              _.$slidesCache.appendTo(_.$slideTrack);
  
              _.reinit();
  
          }
  
      };
  
      Slick.prototype.unload = function() {
  
          var _ = this;
  
          $('.slick-cloned', _.$slider).remove();
  
          if (_.$dots) {
              _.$dots.remove();
          }
  
          if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
              _.$prevArrow.remove();
          }
  
          if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
              _.$nextArrow.remove();
          }
  
          _.$slides
              .removeClass('slick-slide slick-active slick-visible slick-current')
              .attr('aria-hidden', 'true')
              .css('width', '');
  
      };
  
      Slick.prototype.unslick = function(fromBreakpoint) {
  
          var _ = this;
          _.$slider.trigger('unslick', [_, fromBreakpoint]);
          _.destroy();
  
      };
  
      Slick.prototype.updateArrows = function() {
  
          var _ = this,
              centerOffset;
  
          centerOffset = Math.floor(_.options.slidesToShow / 2);
  
          if ( _.options.arrows === true &&
              _.slideCount > _.options.slidesToShow &&
              !_.options.infinite ) {
  
              _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
              _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
  
              if (_.currentSlide === 0) {
  
                  _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                  _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
  
              } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
  
                  _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                  _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
  
              } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
  
                  _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                  _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
  
              }
  
          }
  
      };
  
      Slick.prototype.updateDots = function() {
  
          var _ = this;
  
          if (_.$dots !== null) {
  
              _.$dots
                  .find('li')
                      .removeClass('slick-active')
                      .end();
  
              _.$dots
                  .find('li')
                  .eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
                  .addClass('slick-active');
  
          }
  
      };
  
      Slick.prototype.visibility = function() {
  
          var _ = this;
  
          if ( _.options.autoplay ) {
  
              if ( document[_.hidden] ) {
  
                  _.interrupted = true;
  
              } else {
  
                  _.interrupted = false;
  
              }
  
          }
  
      };
  
      $.fn.slick = function() {
          var _ = this,
              opt = arguments[0],
              args = Array.prototype.slice.call(arguments, 1),
              l = _.length,
              i,
              ret;
          for (i = 0; i < l; i++) {
              if (typeof opt == 'object' || typeof opt == 'undefined')
                  _[i].slick = new Slick(_[i], opt);
              else
                  ret = _[i].slick[opt].apply(_[i].slick, args);
              if (typeof ret != 'undefined') return ret;
          }
          return _;
      };
  
  }));
  
  
  /***/ })
  
  /******/ 	});
  /************************************************************************/
  /******/ 	// The module cache
  /******/ 	var __webpack_module_cache__ = {};
  /******/ 	
  /******/ 	// The require function
  /******/ 	function __webpack_require__(moduleId) {
  /******/ 		// Check if module is in cache
  /******/ 		var cachedModule = __webpack_module_cache__[moduleId];
  /******/ 		if (cachedModule !== undefined) {
  /******/ 			return cachedModule.exports;
  /******/ 		}
  /******/ 		// Create a new module (and put it into the cache)
  /******/ 		var module = __webpack_module_cache__[moduleId] = {
  /******/ 			// no module.id needed
  /******/ 			// no module.loaded needed
  /******/ 			exports: {}
  /******/ 		};
  /******/ 	
  /******/ 		// Execute the module function
  /******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  /******/ 	
  /******/ 		// Return the exports of the module
  /******/ 		return module.exports;
  /******/ 	}
  /******/ 	
  /******/ 	// expose the modules object (__webpack_modules__)
  /******/ 	__webpack_require__.m = __webpack_modules__;
  /******/ 	
  /************************************************************************/
  /******/ 	/* webpack/runtime/amd define */
  /******/ 	!function() {
  /******/ 		__webpack_require__.amdD = function () {
  /******/ 			throw new Error('define cannot be used indirect');
  /******/ 		};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/amd options */
  /******/ 	!function() {
  /******/ 		__webpack_require__.amdO = {};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/chunk loaded */
  /******/ 	!function() {
  /******/ 		var deferred = [];
  /******/ 		__webpack_require__.O = function(result, chunkIds, fn, priority) {
  /******/ 			if(chunkIds) {
  /******/ 				priority = priority || 0;
  /******/ 				for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
  /******/ 				deferred[i] = [chunkIds, fn, priority];
  /******/ 				return;
  /******/ 			}
  /******/ 			var notFulfilled = Infinity;
  /******/ 			for (var i = 0; i < deferred.length; i++) {
  /******/ 				var chunkIds = deferred[i][0];
  /******/ 				var fn = deferred[i][1];
  /******/ 				var priority = deferred[i][2];
  /******/ 				var fulfilled = true;
  /******/ 				for (var j = 0; j < chunkIds.length; j++) {
  /******/ 					if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {
  /******/ 						chunkIds.splice(j--, 1);
  /******/ 					} else {
  /******/ 						fulfilled = false;
  /******/ 						if(priority < notFulfilled) notFulfilled = priority;
  /******/ 					}
  /******/ 				}
  /******/ 				if(fulfilled) {
  /******/ 					deferred.splice(i--, 1)
  /******/ 					result = fn();
  /******/ 				}
  /******/ 			}
  /******/ 			return result;
  /******/ 		};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/compat get default export */
  /******/ 	!function() {
  /******/ 		// getDefaultExport function for compatibility with non-harmony modules
  /******/ 		__webpack_require__.n = function(module) {
  /******/ 			var getter = module && module.__esModule ?
  /******/ 				function() { return module['default']; } :
  /******/ 				function() { return module; };
  /******/ 			__webpack_require__.d(getter, { a: getter });
  /******/ 			return getter;
  /******/ 		};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/define property getters */
  /******/ 	!function() {
  /******/ 		// define getter functions for harmony exports
  /******/ 		__webpack_require__.d = function(exports, definition) {
  /******/ 			for(var key in definition) {
  /******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  /******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  /******/ 				}
  /******/ 			}
  /******/ 		};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/global */
  /******/ 	!function() {
  /******/ 		__webpack_require__.g = (function() {
  /******/ 			if (typeof globalThis === 'object') return globalThis;
  /******/ 			try {
  /******/ 				return this || new Function('return this')();
  /******/ 			} catch (e) {
  /******/ 				if (typeof window === 'object') return window;
  /******/ 			}
  /******/ 		})();
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
  /******/ 	!function() {
  /******/ 		__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/make namespace object */
  /******/ 	!function() {
  /******/ 		// define __esModule on exports
  /******/ 		__webpack_require__.r = function(exports) {
  /******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  /******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  /******/ 			}
  /******/ 			Object.defineProperty(exports, '__esModule', { value: true });
  /******/ 		};
  /******/ 	}();
  /******/ 	
  /******/ 	/* webpack/runtime/jsonp chunk loading */
  /******/ 	!function() {
  /******/ 		// no baseURI
  /******/ 		
  /******/ 		// object to store loaded and loading chunks
  /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
  /******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
  /******/ 		var installedChunks = {
  /******/ 			"/js/app": 0,
  /******/ 			"css/catalog": 0,
  /******/ 			"css/home": 0
  /******/ 		};
  /******/ 		
  /******/ 		// no chunk on demand loading
  /******/ 		
  /******/ 		// no prefetching
  /******/ 		
  /******/ 		// no preloaded
  /******/ 		
  /******/ 		// no HMR
  /******/ 		
  /******/ 		// no HMR manifest
  /******/ 		
  /******/ 		__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };
  /******/ 		
  /******/ 		// install a JSONP callback for chunk loading
  /******/ 		var webpackJsonpCallback = function(parentChunkLoadingFunction, data) {
  /******/ 			var chunkIds = data[0];
  /******/ 			var moreModules = data[1];
  /******/ 			var runtime = data[2];
  /******/ 			// add "moreModules" to the modules object,
  /******/ 			// then flag all "chunkIds" as loaded and fire callback
  /******/ 			var moduleId, chunkId, i = 0;
  /******/ 			for(moduleId in moreModules) {
  /******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
  /******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
  /******/ 				}
  /******/ 			}
  /******/ 			if(runtime) runtime(__webpack_require__);
  /******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
  /******/ 			for(;i < chunkIds.length; i++) {
  /******/ 				chunkId = chunkIds[i];
  /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
  /******/ 					installedChunks[chunkId][0]();
  /******/ 				}
  /******/ 				installedChunks[chunkIds[i]] = 0;
  /******/ 			}
  /******/ 			__webpack_require__.O();
  /******/ 		}
  /******/ 		
  /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
  /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
  /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
  /******/ 	}();
  /******/ 	
  /************************************************************************/
  /******/ 	
  /******/ 	// startup
  /******/ 	// Load entry module and return exports
  /******/ 	// This entry module depends on other loaded chunks and execution need to be delayed
  /******/ 	__webpack_require__.O(undefined, ["css/catalog","css/home"], function() { return __webpack_require__("./resources/js/app.js"); })
  /******/ 	__webpack_require__.O(undefined, ["css/catalog","css/home"], function() { return __webpack_require__("./resources/css/home.scss"); })
  /******/ 	var __webpack_exports__ = __webpack_require__.O(undefined, ["css/catalog","css/home"], function() { return __webpack_require__("./resources/css/catalog.scss"); })
  /******/ 	__webpack_exports__ = __webpack_require__.O(__webpack_exports__);
  /******/ 	
  /******/ })()
  ;