PageSourceSearch

https://www.anothermag.com/assets/js/site-bundles/listpage.js?version=20260924-98

js anothermag.com collected 2026-09-24 15:31:57 UTC 725,685 bytes, 1 lines download raw bytes

1!function(){var e={970:function(e){e.exports="/*!\r\n * jQuery Cookie Plugin v1.3.1\r\n * https://github.com/carhartl/jquery-cookie\r\n *\r\n * Copyright 2013 Klaus Hartl\r\n * Released under the MIT license\r\n */\n(function (factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals.\n    factory(jQuery);\n  }\n})(function ($) {\n  var pluses = /\\+/g;\n  function decode(s) {\n    if (config.raw) {\n      return s;\n    }\n    try {\n      // If we can't decode the cookie, ignore it, it's unusable.\n      return decodeURIComponent(s.replace(pluses, ' '));\n    } catch (e) {}\n  }\n  function decodeAndParse(s) {\n    if (s.indexOf('\"') === 0) {\n      // This is a quoted cookie as according to RFC2068, unescape...\n      s = s.slice(1, -1).replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\');\n    }\n    s = decode(s);\n    try {\n      // If we can't parse the cookie, ignore it, it's unusable.\n      return config.json ? JSON.parse(s) : s;\n    } catch (e) {}\n  }\n  var config = $.cookie = function (key, value, options) {\n    // Write\n    if (value !== undefined) {\n      options = $.extend({}, config.defaults, options);\n      if (typeof options.expires === 'number') {\n        var days = options.expires,\n          t = options.expires = new Date();\n        t.setDate(t.getDate() + days);\n      }\n      value = config.json ? JSON.stringify(value) : String(value);\n      return document.cookie = [config.raw ? key : encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), options.expires ? '; expires=' + options.expires.toUTCString() : '',\n      // use expires attribute, max-age is not supported by IE\n      options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : ''].join('');\n    }\n\n    // Read\n\n    var result = key ? undefined : {};\n\n    // To prevent the for loop in the first place assign an empty array\n    // in case there are no cookies at all. Also prevents odd result when\n    // calling $.cookie().\n    var cookies = document.cookie ? document.cookie.split('; ') : [];\n    for (var i = 0, l = cookies.length; i < l; i++) {\n      var parts = cookies[i].split('=');\n      var name = decode(parts.shift());\n      var cookie = parts.join('=');\n      if (key && key === name) {\n        result = decodeAndParse(cookie);\n        break;\n      }\n\n      // Prevent storing a cookie that we couldn't decode.\n      if (!key && (cookie = decodeAndParse(cookie)) !== undefined) {\n        result[name] = cookie;\n      }\n    }\n    return result;\n  };\n  config.defaults = {};\n  $.removeCookie = function (key, options) {\n    if ($.cookie(key) !== undefined) {\n      // Must not alter options, thus extending a fresh object...\n      $.cookie(key, '', $.extend({}, options, {\n        expires: -1\n      }));\n      return true;\n    }\n    return false;\n  };\n});"},1021:function(e){e.exports="function _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\n/*\r\n * ----------------------------- JSTORAGE -------------------------------------\r\n * Simple local storage wrapper to save data on the browser side, supporting\r\n * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+\r\n *\r\n * Author: Andris Reinman, [email protected]\r\n * Project homepage: www.jstorage.info\r\n *\r\n * Licensed under Unlicense:\r\n *\r\n * This is free and unencumbered software released into the public domain.\r\n *\r\n * Anyone is free to copy, modify, publish, use, compile, sell, or\r\n * distribute this software, either in source code form or as a compiled\r\n * binary, for any purpose, commercial or non-commercial, and by any\r\n * means.\r\n *\r\n * In jurisdictions that recognize copyright laws, the author or authors\r\n * of this software dedicate any and all copyright interest in the\r\n * software to the public domain. We make this dedication for the benefit\r\n * of the public at large and to the detriment of our heirs and\r\n * successors. We intend this dedication to be an overt act of\r\n * relinquishment in perpetuity of all present and future rights to this\r\n * software under copyright law.\r\n *\r\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\r\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r\n * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r\n * OTHER DEALINGS IN THE SOFTWARE.\r\n *\r\n * For more information, please refer to <http://unlicense.org/>\r\n */\n\n/* global ActiveXObject: false */\n/* jshint browser: true */\n\n(function () {\n  'use strict';\n\n  var /* jStorage version */\n    JSTORAGE_VERSION = '0.4.12',\n    /* detect a dollar object or create one if not found */\n    $ = window.jQuery || window.$ || (window.$ = {}),\n    /* check for a JSON handling support */\n    JSON = {\n      parse: window.JSON && (window.JSON.parse || window.JSON.decode) || String.prototype.evalJSON && function (str) {\n        return String(str).evalJSON();\n      }
1 || $.parseJSON || $.evalJSON,\n      stringify: Object.toJSON || window.JSON && (window.JSON.stringify || window.JSON.encode) || $.toJSON\n    };\n\n  // Break if no JSON support was found\n  if (typeof JSON.parse !== 'function' || typeof JSON.stringify !== 'function') {\n    throw new Error('No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page');\n  }\n  var /* This is the object, that holds the cached values */\n    _storage = {\n      __jstorage_meta: {\n        CRC32: {}\n      }\n    },\n    /* Actual browser storage (localStorage or globalStorage['domain']) */\n    _storage_service = {\n      jStorage: '{}'\n    },\n    /* DOM element for older IE versions, holds userData behavior */\n    _storage_elm = null,\n    /* How much space does the storage take */\n    _storage_size = 0,\n    /* which backend is currently used */\n    _backend = false,\n    /* onchange observers */\n    _observers = {},\n    /* timeout to wait after onchange event */\n    _observer_timeout = false,\n    /* last update time */\n    _observer_update = 0,\n    /* pubsub observers */\n    _pubsub_observers = {},\n    /* skip published items older than current timestamp */\n    _pubsub_last = +new Date(),\n    /* Next check for TTL */\n    _ttl_timeout,\n    /**\r\n     * XML encoding and decoding as XML nodes can't be JSON'ized\r\n     * XML nodes are encoded and decoded if the node is the value to be saved\r\n     * but not if it's as a property of another object\r\n     * Eg. -\r\n     *   $.jStorage.set('key', xmlNode);        // IS OK\r\n     *   $.jStorage.set('key', {xml: xmlNode}); // NOT OK\r\n     */\n    _XMLService = {\n      /**\r\n       * Validates a XML node to be XML\r\n       * based on jQuery.isXML function\r\n       */\n      isXML: function isXML(elm) {\n        var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;\n        return documentElement ? documentElement.nodeName !== 'HTML' : false;\n      },\n      /**\r\n       * Encodes a XML node to string\r\n       * based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/\r\n       */\n      encode: function encode(xmlNode) {\n        if (!this.isXML(xmlNode)) {\n          return false;\n        }\n        try {\n          // Mozilla, Webkit, Opera\n          return new XMLSerializer().serializeToString(xmlNode);\n        } catch (E1) {\n          try {\n            // IE\n            return xmlNode.xml;\n          } catch (E2) {}\n        }\n        return false;\n      },\n      /**\r\n       * Decodes a XML node from string\r\n       * loosely based on http://outwestmedia.com/jquery-plugins/xmldom/\r\n       */\n      decode: function decode(xmlString) {\n        var dom_parser = 'DOMParser' in window && new DOMParser().parseFromString || window.ActiveXObject && function (_xmlString) {\n            var xml_doc = new ActiveXObject('Microsoft.XMLDOM');\n            xml_doc.async = 'false';\n            xml_doc.loadXML(_xmlString);\n            return xml_doc;\n          },\n          resultXML;\n        if (!dom_parser) {\n          return false;\n        }\n        resultXML = dom_parser.call('DOMParser' in window && new DOMParser() || window, xmlString, 'text/xml');\n        return this.isXML(resultXML) ? resultXML : false;\n      }\n    };\n\n  ////////////////////////// PRIVATE METHODS ////////////////////////\n\n  /**\r\n   * Initialization function. Detects if the browser supports DOM Storage\r\n   * or userData behavior and behaves accordingly.\r\n   */\n  function _init() {\n    /* Check if browser supports localStorage */\n    var localStorageReallyWorks = false;\n    if ('localStorage' in window) {\n      try {\n        window.localStorage.setItem('_tmptest', 'tmpval');\n        localStorageReallyWorks = true;\n        window.localStorage.removeItem('_tmptest');\n      } catch (BogusQuotaExceededErrorOnIos5) {\n        // Thanks be to iOS5 Private Browsing mode which throws\n        // QUOTA_EXCEEDED_ERRROR DOM Exception 22.\n      }\n    }
1\n    if (localStorageReallyWorks) {\n      try {\n        if (window.localStorage) {\n          _storage_service = window.localStorage;\n          _backend = 'localStorage';\n          _observer_update = _storage_service.jStorage_update;\n        }\n      } catch (E3) {/* Firefox fails when touching localStorage and cookies are disabled */}\n    }\n    /* Check if browser supports globalStorage */else if ('globalStorage' in window) {\n      try {\n        if (window.globalStorage) {\n          if (window.location.hostname == 'localhost') {\n            _storage_service = window.globalStorage['localhost.localdomain'];\n          } else {\n            _storage_service = window.globalStorage[window.location.hostname];\n          }\n          _backend = 'globalStorage';\n          _observer_update = _storage_service.jStorage_update;\n        }\n      } catch (E4) {/* Firefox fails when touching localStorage and cookies are disabled */}\n    }\n    /* Check if browser supports userData behavior */else {\n      _storage_elm = document.createElement('link');\n      if (_storage_elm.addBehavior) {\n        /* Use a DOM element to act as userData storage */\n        _storage_elm.style.behavior = 'url(#default#userData)';\n\n        /* userData element needs to be inserted into the DOM! */\n        document.getElementsByTagName('head')[0].appendChild(_storage_elm);\n        try {\n          _storage_elm.load('jStorage');\n        } catch (E) {\n          // try to reset cache\n          _storage_elm.setAttribute('jStorage', '{}');\n          _storage_elm.save('jStorage');\n          _storage_elm.load('jStorage');\n        }\n        var data = '{}';\n        try {\n          data = _storage_elm.getAttribute('jStorage');\n        } catch (E5) {}\n        try {\n          _observer_update = _storage_elm.getAttribute('jStorage_update');\n        } catch (E6) {}\n        _storage_service.jStorage = data;\n        _backend = 'userDataBehavior';\n      } else {\n        _storage_elm = null;\n        return;\n      }\n    }\n\n    // Load data from storage\n    _load_storage();\n\n    // remove dead keys\n    _handleTTL();\n\n    // start listening for changes\n    _setupObserver();\n\n    // initialize publish-subscribe service\n    _handlePubSub();\n\n    // handle cached navigation\n    if ('addEventListener' in window) {\n      window.addEventListener('pageshow', function (event) {\n        if (event.persisted) {\n          _storageObserver();\n        }\n      }, false);\n    }\n  }\n\n  /**\r\n   * Reload data from storage when needed\r\n   */\n  function _reloadData() {\n    var data = '{}';\n    if (_backend == 'userDataBehavior') {\n      _storage_elm.load('jStorage');\n      try {\n        data = _storage_elm.getAttribute('jStorage');\n      } catch (E5) {}\n      try {\n        _observer_update = _storage_elm.getAttribute('jStorage_update');\n      } catch (E6) {}\n      _storage_service.jStorage = data;\n    }\n    _load_storage();\n\n    // remove dead keys\n    _handleTTL();\n    _handlePubSub();\n  }\n\n  /**\r\n   * Sets up a storage change observer\r\n   */\n  function _setupObserver() {\n    if (_backend == 'localStorage' || _backend == 'globalStorage') {\n      if ('addEventListener' in window) {\n        window.addEventListener('storage', _storageObserver, false);\n      } else {\n        document.attachEvent('onstorage', _storageObserver);\n      }\n    } else if (_backend == 'userDataBehavior') {\n      setInterval(_storageObserver, 1000);\n    }\n  }\n\n  /**\r\n   * Fired on any kind of data change, needs to check if anything has\r\n   * really been changed\r\n   */\n  function _storageObserver() {\n    var updateTime;\n    // cumulate change notifications with timeout\n    clearTimeout(_observer_timeout);\n    _observer_timeout = setTimeout(function () {\n      if (_backend == 'localStorage' || _backend == 'globalStorage') {\n        updateTime = _storage_service.jStorage_update;\n      } else if (_backend == 'userDataBehavior') {\n        _storage_elm.load('jStorage');\n        try {\n          updateTime = _storage_elm.getAttribute('jStorage_update');\n        } catch (E5) {}\n      }\n      if (updateTime && updateTime != _observer_update) {\n        _observer_update = updateTime;
1\n        _checkUpdatedKeys();\n      }\n    }, 25);\n  }\n\n  /**\r\n   * Reloads the data and checks if any keys are changed\r\n   */\n  function _checkUpdatedKeys() {\n    var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),\n      newCrc32List;\n    _reloadData();\n    newCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));\n    var key,\n      updated = [],\n      removed = [];\n    for (key in oldCrc32List) {\n      if (oldCrc32List.hasOwnProperty(key)) {\n        if (!newCrc32List[key]) {\n          removed.push(key);\n          continue;\n        }\n        if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == '2.') {\n          updated.push(key);\n        }\n      }\n    }\n    for (key in newCrc32List) {\n      if (newCrc32List.hasOwnProperty(key)) {\n        if (!oldCrc32List[key]) {\n          updated.push(key);\n        }\n      }\n    }\n    _fireObservers(updated, 'updated');\n    _fireObservers(removed, 'deleted');\n  }\n\n  /**\r\n   * Fires observers for updated keys\r\n   *\r\n   * @param {Array|String} keys Array of key names or a key\r\n   * @param {String} action What happened with the value (updated, deleted, flushed)\r\n   */\n  function _fireObservers(keys, action) {\n    keys = [].concat(keys || []);\n    var i, j, len, jlen;\n    if (action == 'flushed') {\n      keys = [];\n      for (var key in _observers) {\n        if (_observers.hasOwnProperty(key)) {\n          keys.push(key);\n        }\n      }\n      action = 'deleted';\n    }\n    for (i = 0, len = keys.length; i < len; i++) {\n      if (_observers[keys[i]]) {\n        for (j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {\n          _observers[keys[i]][j](keys[i], action);\n        }\n      }\n      if (_observers['*']) {\n        for (j = 0, jlen = _observers['*'].length; j < jlen; j++) {\n          _observers['*'][j](keys[i], action);\n        }\n      }\n    }\n  }\n\n  /**\r\n   * Publishes key change to listeners\r\n   */\n  function _publishChange() {\n    var updateTime = (+new Date()).toString();\n    if (_backend == 'localStorage' || _backend == 'globalStorage') {\n      try {\n        _storage_service.jStorage_update = updateTime;\n      } catch (E8) {\n        // safari private mode has been enabled after the jStorage initialization\n        _backend = false;\n      }\n    } else if (_backend == 'userDataBehavior') {\n      _storage_elm.setAttribute('jStorage_update', updateTime);\n      _storage_elm.save('jStorage');\n    }\n    _storageObserver();\n  }\n\n  /**\r\n   * Loads the data from the storage based on the supported mechanism\r\n   */\n  function _load_storage() {\n    /* if jStorage string is retrieved, then decode it */\n    if (_storage_service.jStorage) {\n      try {\n        _storage = JSON.parse(String(_storage_service.jStorage));\n      } catch (E6) {\n        _storage_service.jStorage = '{}';\n      }\n    } else {\n      _storage_service.jStorage = '{}';\n    }\n    _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;\n    if (!_storage.__jstorage_meta) {\n      _storage.__jstorage_meta = {};\n    }\n    if (!_storage.__jstorage_meta.CRC32) {\n      _storage.__jstorage_meta.CRC32 = {};\n    }\n  }\n\n  /**\r\n   * This functions provides the 'save' mechanism to store the jStorage object\r\n   */\n  function _save() {\n    _dropOldEvents(); // remove expired events\n    try {\n      _storage_service.jStorage = JSON.stringify(_storage);\n      // If userData is used as the storage engine, additional\n      if (_storage_elm) {\n        _storage_elm.setAttribute('jStorage', _storage_service.jStorage);\n        _storage_elm.save('jStorage');\n      }\n      _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;\n    } catch (E7) {/* probably cache is full, nothing is saved this way*/}\n  }\n\n  /**\r\n   * Function checks if a key is set and is string or numberic\r\n   *\r\n   * @param {String} key Key name\r\n   */\n  function _checkKey(key) {\n    if (typeof key != 'string' && typeof key != 'number') {\n      throw new TypeError('Key name must be string or numeric');\n    }\n    if (key == '__jstorage_meta') {\n      throw new TypeError('Reserved key name');\n    }\n    return true;\n  }\n\n  /**\r\n   * Removes expired keys\r\n   */\n  function _handleTTL() {\n    var curtime,\n      i,\n      TTL,\n      C
1RC32,\n      nextExpire = Infinity,\n      changed = false,\n      deleted = [];\n    clearTimeout(_ttl_timeout);\n    if (!_storage.__jstorage_meta || _typeof(_storage.__jstorage_meta.TTL) != 'object') {\n      // nothing to do here\n      return;\n    }\n    curtime = +new Date();\n    TTL = _storage.__jstorage_meta.TTL;\n    CRC32 = _storage.__jstorage_meta.CRC32;\n    for (i in TTL) {\n      if (TTL.hasOwnProperty(i)) {\n        if (TTL[i] <= curtime) {\n          delete TTL[i];\n          delete CRC32[i];\n          delete _storage[i];\n          changed = true;\n          deleted.push(i);\n        } else if (TTL[i] < nextExpire) {\n          nextExpire = TTL[i];\n        }\n      }\n    }\n\n    // set next check\n    if (nextExpire != Infinity) {\n      _ttl_timeout = setTimeout(_handleTTL, Math.min(nextExpire - curtime, 0x7FFFFFFF));\n    }\n\n    // save changes\n    if (changed) {\n      _save();\n      _publishChange();\n      _fireObservers(deleted, 'deleted');\n    }\n  }\n\n  /**\r\n   * Checks if there's any events on hold to be fired to listeners\r\n   */\n  function _handlePubSub() {\n    var i, len;\n    if (!_storage.__jstorage_meta.PubSub) {\n      return;\n    }\n    var pubelm,\n      _pubsubCurrent = _pubsub_last,\n      needFired = [];\n    for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {\n      pubelm = _storage.__jstorage_meta.PubSub[i];\n      if (pubelm[0] > _pubsub_last) {\n        _pubsubCurrent = pubelm[0];\n        needFired.unshift(pubelm);\n      }\n    }\n    for (i = needFired.length - 1; i >= 0; i--) {\n      _fireSubscribers(needFired[i][1], needFired[i][2]);\n    }\n    _pubsub_last = _pubsubCurrent;\n  }\n\n  /**\r\n   * Fires all subscriber listeners for a pubsub channel\r\n   *\r\n   * @param {String} channel Channel name\r\n   * @param {Mixed} payload Payload data to deliver\r\n   */\n  function _fireSubscribers(channel, payload) {\n    if (_pubsub_observers[channel]) {\n      for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {\n        // send immutable data that can't be modified by listeners\n        try {\n          _pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));\n        } catch (E) {}\n      }\n    }\n  }\n\n  /**\r\n   * Remove old events from the publish stream (at least 2sec old)\r\n   */\n  function _dropOldEvents() {\n    if (!_storage.__jstorage_meta.PubSub) {\n      return;\n    }\n    var retire = +new Date() - 2000;\n    for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {\n      if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {\n        // deleteCount is needed for IE6\n        _storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);\n        break;\n      }\n    }\n    if (!_storage.__jstorage_meta.PubSub.length) {\n      delete _storage.__jstorage_meta.PubSub;\n    }\n  }\n\n  /**\r\n   * Publish payload to a channel\r\n   *\r\n   * @param {String} channel Channel name\r\n   * @param {Mixed} payload Payload to send to the subscribers\r\n   */\n  function _publish(channel, payload) {\n    if (!_storage.__jstorage_meta) {\n      _storage.__jstorage_meta = {};\n    }\n    if (!_storage.__jstorage_meta.PubSub) {\n      _storage.__jstorage_meta.PubSub = [];\n    }\n    _storage.__jstorage_meta.PubSub.unshift([+new Date(), channel, payload]);\n    _save();\n    _publishChange();\n  }\n\n  /**\r\n   * JS Implementation of MurmurHash2\r\n   *\r\n   *  SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)\r\n   *\r\n   * @author <a href='mailto:[email protected]'>Gary Court</a>\r\n   * @see http://github.com/garycourt/murmurhash-js\r\n   * @author <a href='mailto:[email protected]'>Austin Appleby</a>\r\n   * @see http://sites.google.com/site/murmurhash/\r\n   *\r\n   * @param {string} str ASCII only\r\n   * @param {number} seed Positive integer only\r\n   * @return {number} 32-bit positive integer hash\r\n   */\n\n  function murmurhash2_32_gc(str, seed) {\n    var l = str.length,\n      h = seed ^ l,\n      i = 0,\n      k;\n    while (l >= 4) {\n      k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24;\n      k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n      k ^= k >>> 24;\n      k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n      h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16) ^ k;\n      l -= 4;\n      ++i;\n    }\n    switch (l) {\n      case 3:\n        h ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n      /* falls through */\n      case 2:\n        h ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n      /* falls through */\n      case 1:\n        h ^= str.charCodeAt(i) & 0xff;\n        h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n    }\n    h ^= h >>> 13;\n    h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n    h ^= h >>> 15;\n    return h >>> 0;\n  }\n\n  ////////////////////////// PUBLIC INTERFACE /////////////////////////\n\n  $.jStorage = {\n    /* Version number */\n    version: JSTORAGE_VERSION,\n    /**\r\n     * Sets a key's value.\r\n     *\r\n     * @param {String}
1 key Key to set. If this value is not set or not\r\n     *              a string an exception is raised.\r\n     * @param {Mixed} value Value to set. This can be any value that is JSON\r\n     *              compatible (Numbers, Strings, Objects etc.).\r\n     * @param {Object} [options] - possible options to use\r\n     * @param {Number} [options.TTL] - optional TTL value, in milliseconds\r\n     * @return {Mixed} the used value\r\n     */\n    set: function set(key, value, options) {\n      _checkKey(key);\n      options = options || {};\n\n      // undefined values are deleted automatically\n      if (typeof value == 'undefined') {\n        this.deleteKey(key);\n        return value;\n      }\n      if (_XMLService.isXML(value)) {\n        value = {\n          _is_xml: true,\n          xml: _XMLService.encode(value)\n        };\n      } else if (typeof value == 'function') {\n        return undefined; // functions can't be saved!\n      } else if (value && _typeof(value) == 'object') {\n        // clone the object before saving to _storage tree\n        value = JSON.parse(JSON.stringify(value));\n      }\n      _storage[key] = value;\n      _storage.__jstorage_meta.CRC32[key] = '2.' + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);\n      this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange\n\n      _fireObservers(key, 'updated');\n      return value;\n    },\n    /**\r\n     * Looks up a key in cache\r\n     *\r\n     * @param {String} key - Key to look up.\r\n     * @param {mixed} def - Default value to return, if key didn't exist.\r\n     * @return {Mixed} the key value, default value or null\r\n     */\n    get: function get(key, def) {\n      _checkKey(key);\n      if (key in _storage) {\n        if (_storage[key] && _typeof(_storage[key]) == 'object' && _storage[key]._is_xml) {\n          return _XMLService.decode(_storage[key].xml);\n        } else {\n          return _storage[key];\n        }\n      }\n      return typeof def == 'undefined' ? null : def;\n    },\n    /**\r\n     * Deletes a key from cache.\r\n     *\r\n     * @param {String} key - Key to delete.\r\n     * @return {Boolean} true if key existed or false if it didn't\r\n     */\n    deleteKey: function deleteKey(key) {\n      _checkKey(key);\n      if (key in _storage) {\n        delete _storage[key];\n        // remove from TTL list\n        if (_typeof(_storage.__jstorage_meta.TTL) == 'object' && key in _storage.__jstorage_meta.TTL) {\n          delete _storage.__jstorage_meta.TTL[key];\n        }\n        delete _storage.__jstorage_meta.CRC32[key];\n        _save();\n        _publishChange();\n        _fireObservers(key, 'deleted');\n        return true;\n      }\n      return false;\n    },\n    /**\r\n     * Sets a TTL for a key, or remove it if ttl value is 0 or below\r\n     *\r\n     * @param {String} key - key to set the TTL for\r\n     * @param {Number} ttl - TTL timeout in milliseconds\r\n     * @return {Boolean} true if key existed or false if it didn't\r\n     */\n    setTTL: function setTTL(key, ttl) {\n      var curtime = +new Date();\n      _checkKey(key);\n      ttl = Number(ttl) || 0;\n      if (key in _storage) {\n        if (!_storage.__jstorage_meta.TTL) {\n          _storage.__jstorage_meta.TTL = {};\n        }\n\n        // Set TTL value for the key\n        if (ttl > 0) {\n          _storage.__jstorage_meta.TTL[key] = curtime + ttl;\n        } else {\n          delete _storage.__jstorage_meta.TTL[key];\n        }\n        _save();\n        _handleTTL();\n        _publishChange();\n        return true;\n      }\n      return false;\n    },\n    /**\r\n     * Gets remaining TTL (in milliseconds) for a key or 0 when no TTL has been set\r\n     *\r\n     * @param {String} key Key to check\r\n     * @return {Number} Remaining TTL in milliseconds\r\n     */\n    getTTL: function getTTL(key) {\n      var curtime = +new Date(),\n        ttl;\n      _checkKey(key);\n      if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {\n        ttl = _storage.__jstorage_meta.TTL[key] - curtime;\n        return ttl || 0;\n      }\n      return 0;\n    },\n    /**\r\n     * Deletes everything in cache.\r\n     *\r\n     * @return {Boolean} Always true\r\n     */\n    flush: function flush() {\n      _storage = {\n        __jstorage_meta: {\n          CRC32: {}\n        }\n      };\n      _save();\n      _publishChange();\n      _fireObservers(null, 'flushed');\n      return true;\n    },\n    /**\r\n     * Returns a read-only copy of _storage\r\n     *\r\n     * @return {Object} Read-only copy of _storage\r\n     */\n    storageObj: function storageObj() {\n      function F() {}\n      F.prototype = _storage;\n      return new F();\n    },\n    /**\r\n     * Returns an index of all used keys as an array\r\n     * ['key1', 'ke
1y2',..'keyN']\r\n     *\r\n     * @return {Array} Used keys\r\n     */\n    index: function index() {\n      var index = [],\n        i;\n      for (i in _storage) {\n        if (_storage.hasOwnProperty(i) && i != '__jstorage_meta') {\n          index.push(i);\n        }\n      }\n      return index;\n    },\n    /**\r\n     * How much space in bytes does the storage take?\r\n     *\r\n     * @return {Number} Storage size in chars (not the same as in bytes,\r\n     *                  since some chars may take several bytes)\r\n     */\n    storageSize: function storageSize() {\n      return _storage_size;\n    },\n    /**\r\n     * Which backend is currently in use?\r\n     *\r\n     * @return {String} Backend name\r\n     */\n    currentBackend: function currentBackend() {\n      return _backend;\n    },\n    /**\r\n     * Test if storage is available\r\n     *\r\n     * @return {Boolean} True if storage can be used\r\n     */\n    storageAvailable: function storageAvailable() {\n      return !!_backend;\n    },\n    /**\r\n     * Register change listeners\r\n     *\r\n     * @param {String} key Key name\r\n     * @param {Function} callback Function to run when the key changes\r\n     */\n    listenKeyChange: function listenKeyChange(key, callback) {\n      _checkKey(key);\n      if (!_observers[key]) {\n        _observers[key] = [];\n      }\n      _observers[key].push(callback);\n    },\n    /**\r\n     * Remove change listeners\r\n     *\r\n     * @param {String} key Key name to unregister listeners against\r\n     * @param {Function} [callback] If set, unregister the callback, if not - unregister all\r\n     */\n    stopListening: function stopListening(key, callback) {\n      _checkKey(key);\n      if (!_observers[key]) {\n        return;\n      }\n      if (!callback) {\n        delete _observers[key];\n        return;\n      }\n      for (var i = _observers[key].length - 1; i >= 0; i--) {\n        if (_observers[key][i] == callback) {\n          _observers[key].splice(i, 1);\n        }\n      }\n    },\n    /**\r\n     * Subscribe to a Publish/Subscribe event stream\r\n     *\r\n     * @param {String} channel Channel name\r\n     * @param {Function} callback Function to run when the something is published to the channel\r\n     */\n    subscribe: function subscribe(channel, callback) {\n      channel = (channel || '').toString();\n      if (!channel) {\n        throw new TypeError('Channel not defined');\n      }\n      if (!_pubsub_observers[channel]) {\n        _pubsub_observers[channel] = [];\n      }\n      _pubsub_observers[channel].push(callback);\n    },\n    /**\r\n     * Publish data to an event stream\r\n     *\r\n     * @param {String} channel Channel name\r\n     * @param {Mixed} payload Payload to deliver\r\n     */\n    publish: function publish(channel, payload) {\n      channel = (channel || '').toString();\n      if (!channel) {\n        throw new TypeError('Channel not defined');\n      }\n      _publish(channel, payload);\n    },\n    /**\r\n     * Reloads the data from browser storage\r\n     */\n    reInit: function reInit() {\n      _reloadData();\n    },\n    /**\r\n     * Removes reference from global objects and saves it as jStorage\r\n     *\r\n     * @param {Boolean} option if needed to save object as simple 'jStorage' in windows context\r\n     */\n    noConflict: function noConflict(saveInGlobal) {\n      delete window.$.jStorage;\n      if (saveInGlobal) {\n        window.jStorage = this;\n      }\n      return this;\n    }\n  };\n\n  // Initialize jStorage\n  _init();\n})();"},1073:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  DL.keyFn = DL.keyFn || {};\n  function keydown(e) {\n    var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;\n    if (DL.keyFn.hasOwnProperty(key)) {\n      DL.keyFn[key]();\n    }\n    return key;\n  }\n  DL.keydown = keydown;\n})(DL || (DL = {}));\n$(document).on('keydown.keyboard', function (e) {\n  return DL.keydown(e);\n}); //\tKeyboard integration"},1207:function(e){e.exports="window.AM = window.AM || {};\nAM.menu = function (e) {\n  if (DL.Utilities.isMobile() || DL.Utilities.isTablet()) {\n    var $body = $('body');\n    $body.toggleClass('menu-visible');\n    toggleAdBlock();\n    var action = $body.hasClass('menu-visible') ? 'Menu Button Show' : 'Menu Button Hide';\n    DL.analytics.trackEvent('Header-Mobile', action, window.location.pathname);\n  } else {\n    var $header = $('#header');\n    $header.toggleClass('click-menu-show');\n    var action = $header.hasClass('click-menu-show') ? 'Menu Button Show' : 'Menu Button Hide';\n    DL.analytics.trackEvent('Header', action, window.location.pathname);\n  }\n  toggleAdBlock();\n};\nAM.detectScrollbarWidth = function () {\n  var bodyInnerWidth = $('body').prop('clientWidth');\n  var bodyFullWidth = $(window)[0].innerWidth;\n  var scrollbarWidth = bodyFullWidth - bodyInnerWidth;\n  return scrollbarWidth;\n};\nAM.menu.search = function (e) {\n  e.preventDefault();
1\n  if (!$(document.body).hasClass('search-open')) {\n    $('#search-input').focus();\n  }\n  $(document.body).toggleClass('search-open');\n};\nAM.newsletter = function () {\n  $('.newsletter-opt-input').each(function () {\n    var $this = $(this);\n    var $label = $this.find('label');\n    $label.click(function () {\n      $this.toggleClass(\"not-selected\"); // the default state of the inputs is selected therefore if clicked is not selected    \n      if ($this.hasClass('not-selected')) {\n        $this.find('input').removeClass(\"checked\");\n      } else {\n        $this.find('input').addClass(\"checked\");\n      }\n    });\n  });\n};\nAM.menuhide = function () {\n  //1. Not a longread article\n  //2. Not mobile or tablet\n  if (DL.Utilities.isMobile() || DL.Utilities.isTablet()) {\n    return;\n  }\n\n  // show hide subnav depending on scroll direction\n  var initialPosition = $(window).scrollTop();\n  var isLongread = null;\n  if (AM.Article && AM.Article.Template) {\n    isLongread = AM.Article.Template == 'Longread';\n  }\n  var scrollEvent = function scrollEvent() {\n    var newPosition = $(window).scrollTop();\n    //Menu is visible scenarios:\n\n    //3. User scrolls up\n    if (newPosition > initialPosition) {\n      $('#header').addClass('menu-hidden-desktop').removeClass('click-menu-show');\n      $('.menu-show-hide-checkbox').prop('checked', false);\n    } else {\n      // scrolling upwards \n      $('#header').removeClass('menu-hidden-desktop click-menu-show');\n      $('.menu-show-hide-checkbox').prop('checked', false);\n    }\n    initialPosition = newPosition;\n  };\n  $(window).scroll(_.throttle(scrollEvent, 16));\n};\n\n/* Update on scroll */\n$(window).scroll(function (event) {\n  var headerPos = $('.top-header-container').offset().top;\n  var viewableOffset = $('.top-header-container').offset().top - $(window).scrollTop();\n  var contentOffset = $('#content').offset().top - $(window).scrollTop();\n  //console.log(contentOffset);\n  var isSticky = $('body').hasClass('no-sticky');\n  if (isSticky) {\n    if (contentOffset < 120) {\n      $('#header').css('top', '-90px');\n    } else {\n      $('#header').addClass('top').removeAttr(\"style\");\n    }\n  }\n});\nAM.SwiperCarousel = AM.SwiperCarousel || {};\nAM.SwiperCarousel.defaults = {\n  pagination: '.swiper-pagination',\n  /* String with CSS selector or HTML element of the container with pagination */\n  centeredSlides: false,\n  /* Boolean  - active slide centered */\n  slidesPerView: 'auto',\n  /* Number/'auto' - slides visible at the same time on slider's container */\n  preventClicks: true,\n  /* Boolean  - prevent accidental clicks on links during swiping */\n  roundLengths: true,\n  /* Boolean  - round values of slides width + height prevent blurry texts on usual resolutions */\n  keyboardControl: false,\n  /* Boolean  - navigation through slides using keyboard */\n  loop: false,\n  /* Boolean  - continuous loop mode*/\n  //spaceBetween: 10,                   /* Number   - Distance between slides in px. */\n  //autoplay: 5000,                     /* Number   - Delay ms between transitions. If not specified, autoplay disabled */\n  autoplayDisableOnInteraction: true,\n  /* Boolean  - false, autoplay not disabled after user interactions but restarted after interaction*/\n  iOSEdgeSwipeDetection: true,\n  /* Enable to release Swiper events for swipe-to-go-back work in iOS UIWebView */\n  iOSEdgeSwipeThreshold: 40 /* PX from left edge of the screen to release touch events for swipe-to-go-back in iOS UIWebView */\n  /*observer: true                    /* Boolean  - enable Mutation Observer on elements. Swiper reinitialized each time changed */\n};\nAM.SwiperCarousel.prepForSwiper = function ($el) {\n  $el.addClass('swiper-container');\n  $el.find('.item-list').addClass('swiper-wrapper');\n  $el.find('.list-item').addClass('swiper-slide');\n  //$el.find('.item-list-footer').remove();\n  $el.on('items-loaded', function ($event, $items) {\n    $(this).data('swiper').appendSlide($items.addClass('swiper-slide'));\n  });\n};\n$('.menu-icon').on('click', AM.menu);\n$('#search-btn').on('click', AM.menu.search);\nDL.Utilities.getDocumentElement().ready(function () {\n  AM.newsletter();\n  AM.menuhide();\n  if ($('.parallax-advert').length) {\n    var $parallaxAdvert = $('.parallax-advert');\n    var widthToMinus = AM.detectScrollbarWidth() + 'px';\n    document.documentElement.style.setProperty('--scrollbarWidth', widthToMinus);\n    $parallaxAdvert.addClass('parallax-show');\n  }\n});\nsetTimeout(DL.Utilities.trackGptLoading, 2000);\nDL.Utilities.getWindowElement().one('load.checkGpt', DL.Utilities.trackGptLoading);\n\n/* Sticky Header Script */\nvar vpPoint = 0;\nvar lastScrollTop = 0;\nvar delta = 5;\nvar checkHeaderFunc = function checkHeaderFunc() {\n  if ($('body').hasClass('no-sticky')) return;\n  var nowScrollTop = $(this).scrollTop();\n  if (Math.abs(lastScrollTop - nowScrollTop) >= delta) {}\n  checkScroll();\n  var header = $('#header');\n  // ensuring we have a second ad on page\n  var ele = $('div.advert')[1];\n  if (ele != undefined && !isInViewport(ele) && !header.hasClass('ad-hidden')) {\
1n    vpPoint = $(ele).position().top;\n    header.addClass('ad-hidden');\n    if ($($('#header').find('div.advert')[0]).height() > 80 && $($('#header').find('div.advert')[0]).height() < 90) {\n      header.animate({\n        top: '-150px'\n      });\n    } else if ($($('#header').find('div.advert')[0]).height() >= 90) {\n      header.animate({\n        top: '-130px'\n      });\n    } else {\n      header.animate({\n        top: '-90px'\n      });\n    }\n    return;\n  } else if (ele != undefined && isInViewport(ele) && header.hasClass('ad-hidden')) {\n    vpPoint = 0;\n    header.removeClass('ad-hidden');\n    header.animate({\n      top: '0px'\n    });\n    return;\n  }\n  lastScrollTop = nowScrollTop;\n};\nwindow.addEventListener('scroll', checkHeaderFunc);\nfunction isInViewport(element) {\n  if (element == undefined) {\n    return false;\n  }\n  var bounding = element.getBoundingClientRect();\n  if (bounding.top == 0) {\n    return true;\n  } else if (bounding.top >= window.innerHeight) {\n    return true;\n  } else {\n    return false;\n  }\n}\nfunction toggleAdBlock() {\n  var header = $('#header');\n  if (header.css('top') === '0px') {\n    $('body').css('overflow-y', 'hidden');\n    header.animate({\n      top: '-91px'\n    });\n  } else if (header.css('top') === '-91px') {\n    $('body').css('overflow-y', '');\n    header.animate({\n      top: '0px'\n    });\n  }\n}\n$('body').on('submit', \"form.subscribe-form\", function (f) {\n  f.preventDefault();\n  var ele = this;\n  var em = $(this).find('.email-input')[0].value;\n  var cnEle = $(this).parent().children('.confirmation.newsletter__form-wrapper')[0];\n  if (em != '') {\n    $.ajax({\n      url: \"/klaviyonewsletter/savenewslettersubscription\",\n      type: \"POST\",\n      data: {\n        emailAddress: em\n      },\n      success: function success(response) {\n        $(ele).value = '';\n        $(f.currentTarget).fadeOut();\n        $(cnEle).fadeIn();\n      },\n      error: function error(er) {\n        console.log('Error: ' + er);\n      }\n    });\n  } else {\n    console.log('Error: NO email address provided');\n  }\n});\nvar scrollPosition = window.scrollY || document.documentElement.scrollTop;\nfunction checkScroll() {\n  scrollPosition = window.scrollY || document.documentElement.scrollTop;\n  var nearTopRange = 30;\n  if (document.querySelector(\"#main article .article-wrapper\") && body.classList.contains(\"sticky\")) {\n    nearTopRange = document.querySelector(\"#main article .article-wrapper\").clientHeight / 2;\n  }\n  if (scrollPosition <= nearTopRange) {\n    document.body.classList.add(\"is-near-top\");\n  } else {\n    document.body.classList.remove(\"is-near-top\");\n  }\n}\n;\nvar body = document.body;\nvar header = document.querySelector('#header');
1\nfunction manageHeaderAd() {\n  var firstAdContainer = document.querySelectorAll(\".advert\")[0];\n  var vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);\n\n  // If there are no ads on the page, exit the function early\n  if (!firstAdContainer) {\n    return;\n  }\n\n  // * showHideGlobalHeaderAd\n  // Function to show or hide the header ad based on the ad's visibility in the viewport.\n  function showHideGlobalHeaderAd(entries) {\n    if (!body.classList.contains('no-sticky')) {\n      return;\n    }\n    entries.forEach(function (entry) {\n      var advertIsBelowViewport = entry.boundingClientRect.top > window.innerHeight;\n      if (body.classList.contains(\"sticky\")) {\n        if (advertIsBelowViewport) {\n          body.classList.remove(\"ad-hidden\");\n          body.classList.add(\"ad-shown\");\n          header.animate({\n            top: '0px'\n          });\n          //document.documentElement.style.setProperty(\"--gHeader-ad-shown\", `1`);\n        } else {\n          body.classList.add(\"ad-hidden\");\n          body.classList.add(\"ad-shown\");\n          header.animate({\n            top: '-130px'\n          });\n          //document.documentElement.style.setProperty(\"--gHeader-ad-shown\", `0`);\n        }\n      }\n    });\n  }\n\n  // Create an Intersection Observer to monitor the first ad's visibility\n  var observer = new IntersectionObserver(showHideGlobalHeaderAd);\n\n  // Start observing the first ad container\n  observer.observe(firstAdContainer);\n}\nmanageHeaderAd();\nfunction move(elem) {\n  var left = 0;\n  function frame() {\n    left++; // update parameters\n    elem.style.left = left + 'px'; // show frame\n    if (left == 100)\n      // check finish condition\n      clearInterval(id);\n  }\n  var id = setInterval(frame, 10); // draw every 10ms\n}\n\n// Initialize navbar secondary on document ready\nDL.Utilities.getDocumentElement().ready(function () {\n  if (AM.navbarSecondary && AM.navbarSecondary.init) {\n    AM.navbarSecondary.init();\n  }\n});"},1213:function(e){e.exports="/* ========================================================================\r\n * Twitter Share Helper\r\n * To be edited in Revolution only\r\n * ======================================================================== */\nwindow.DL = window.DL || {};\n+function ($) {\n  \"use strict\";\n\n  DL.twitter = {\n    /**\r\n    * t.co length.\r\n    * \r\n    * Currently a max of 20 but can be updated, see https://dev.twitter.com/docs/tco-link-wrapper/faq\r\n    */\n    tcoLength: 20,\n    /**\r\n    * Creates a URL that allows users to easily share your website with their followers.\r\n    *\r\n    * @param url {Object} URL of the page to share.\r\n    * @param Tweet text.\r\n    * @param twitterName Screen name of the user to attribute the Tweet to.\r\n    * @return result {Object} Share URL\r\n    */\n    shareUrl: function shareUrl(url, text, twitterName) {\n      var twitterCharsLeft = 140 - twitterName.length - DL.twitter.tcoLength - 9; //… https://t.co/123456789 via @twitterName\n      if (text.length > twitterCharsLeft) {\n        text = text.substr(0, twitterCharsLeft - 1) + \"…\"; // -1 more for …\n      }\n\n      /*\r\n       *\tvar characters = quote.substring(0, chars);\r\n      \tcharacters.replace(/&/g, '%26');\r\n      \tcharacters.replace(/#/g, '%23');\r\n       */\n\n      return 'https://twitter.com/share?url=' + encodeURI(url) + '&via=' + encodeURIComponent(twitterName) + '&text=' + encodeURIComponent(text);\n    }\n  };\n}(window.jQuery);"},1735:function(e){e.exports='/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  var querystring;\n  (function (querystring) {\n    function updateParameter(uri, key, value) {\n      var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");\n      var separator = uri.indexOf(\'?\') !== -1 ? "&" : "?";\n      if (uri.match(re)) {\n        return uri.replace(re, \'$1\' + key + "=" + value + \'$2\');\n      } else {\n        return uri + separator + key + "=" + value;\n      }\n    }\n    querystring.updateParameter = updateParameter;\n    function getParameter(key) {\n      if (window.location.search == null || window.location.search.length < 1) {\n        return null;\n      }\n      var querystringKeyValuePairs = window.location.search.substr(1).split(\'&\');\n      if (querystringKeyValuePairs == null || querystringKeyValuePairs.length === 0) {\n        return "";\n      }\n      var b = {};\n      for (var i = 0; i < querystringKeyValuePairs.length; ++i) {\n        var p = querystringKeyValuePairs[i].split(\'=\', 2);\n        if (p.length === 1) {\n          b[p[0]] = "";\n        } else {\n          b[p[0]] = decodeURIComponent(p[1].replace(/\\+/g, " "));\n        }\n      }\n      return b[key];\n    }\n    querystring.getParameter = getParameter;\n  })(querystring = DL.querystring || (DL.querystring = {}));\n})(DL || (DL = {}));'},1962:function(e){e.exports="/* === To be edited in Revolution only === */\n// Polyfill for console functions\nif (!window.console) {\n  window.console = new Console();\n}\nif (!window.console.log) {\n  window.console.log = function () {\n    return false;\n  };\n}\nif (!window.console.info) {\n  window.console.info = window.console.log;\n}\nif (!window.console.warn) {\n  window.console.warn = window.console.info;\n}\nif (!window.console.error) {\n  window.console.error = window.console.warn;\n}\n// Polyfill for console.time/timeEnd\n;\n(function (console) {\n  'use strict';\n\n  var timers;\n  // do we have access to the console?\n  if (!console) {\n    return;\n  }\n  // table of current timers\n  timers = {};\n  /**\r\n   * Stores current time in milliseconds\r\n   * in the timers map\r\n   *\r\n   * @param {string} timer name\r\n   * @return {void}\r\n   */\n  console.time = function (name) {\n    if (name) {\n      timers[name] = Date.now();\n    }\n  };\n  /**\r\n   * Finds difference between when this method\r\n   * was called and when the respective time method\r\n   * was called, then logs out the difference\r\n   * and deletes the original record\r\n   *\r\n   * @param {string} timer name\r\n   * @return {void}\r\n   */\n  console.timeEnd = function (name) {\n    if (timers[name]) {\n      console.log(name + ': ' + (Date.now() - timers[name]) + 'ms');\n      delete timers[name];\n    }\n  };\n})(window.console);\nif (!document.createEvent) {\n  document.createEvent = function (a) {\n    return new Event(a);\n  };\n}\n// IE8 fix for array.indexOf\nif (!Array.prototype.indexOf) {\n  Array.prototype.indexOf = function (what, i) {\n    i = i || 0;\n    var L = this.length;\n    while (i < L) {\n      if (this[i] === what) {\n        return i;\n      }\n      ++i;\n    }\n    return -1;\n  };\n}\n// Removes an element from an array.\n// String value: the value to search and remove.\n// return: an array with the removed element; false otherwise.\nArray.prototype.remove = function (value) {\n  var idx = this.indexOf(value);\n  if (idx !== -1) {\n    this.splice(idx, 1); // The second parameter is the number of elements to remove.\n  }\n  return this;\n};\nArray.prototype.pushUnique = function (item) {\n  if (this.indexOf(item) === -1) {\n    this.push(item);\n  }\n  return this;\n};\n// Polyfill for string startsWith()\nif (!String.prototype.startsWith) {\n  String.prototype.startsWith = function (searchString, position) {\n    if (position === void 0) {\n      position = 0;\n    }\n    return this.substr(position, searchString.length) === searchString;\n  };\n}\n// Polyfill for string replaceAll()\nif (!String.prototype.replaceAll) {\n  String.prototype.replaceAll = function (search, replacement) {\n    var target = this;\n    return target.replace(new RegExp(search, 'g'), replacement);\n  };\n}\n// Add check for position sticky\nModernizr.addTest('csssticky', function () {\n  var bool;\n  Modernizr.testStyles('#modernizr { position: -webkit-sticky;position: -moz-sticky;position: -o-sticky; position: -ms-sticky; position: sticky;}', function (elem, rule) {\n    bool = (window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle)['position'].indexOf('sticky') !== -1;\n  });\n  return bool;\n});\nvar DL;
1\n(function (DL) {\n  DL.localVars = [];\n  DL.TestMode = DL.querystring.getParameter('testmode') === 'true';\n  DL.PreviewMode = !DL.querystring.getParameter('pvw');\n  function BuildIsProduction() {\n    return DL.localVars['BuildIsProduction'] != null ? DL.localVars['BuildIsProduction'] : DL.localVars['BuildIsProduction'] = $('html').attr('data-isproduction') === 'true';\n  }\n  DL.BuildIsProduction = BuildIsProduction;\n  function SiteBaseUrl() {\n    var val = DL.localVars['SiteBaseUrl'] != null ? DL.localVars['SiteBaseUrl'] : DL.localVars['SiteBaseUrl'] = $('html').attr('data-sitebaseurl');\n    if (val == null || val.length == 0) {\n      DL.Utilities.AlertError('DL.SiteBaseUrl() is missing');\n    }\n    return val;\n  }\n  DL.SiteBaseUrl = SiteBaseUrl;\n})(DL || (DL = {}));\nwindow.onerror = function (error, file, line, character, details) {\n  if (DL.BuildIsProduction() === false && file != null && file.length > 0) {\n    alert('Error: ' + error + '\\r\\nFile: ' + file + '\\r\\nLine: ' + line + '\\r\\nChar: ' + character);\n  }\n};\nvar DL;\n(function (DL) {\n  var Utilities;\n  (function (Utilities) {\n    Utilities.$localJqueryVars = [];\n    Utilities.sizeDependantVars = [];\n    function setAllAspectRatio() {\n      getMaintainAspectRatioElements().setAspectRatio();\n    }\n    Utilities.setAllAspectRatio = setAllAspectRatio;\n    function getCachedJqueryElements(key, func) {\n      return Utilities.$localJqueryVars[key] != null ? Utilities.$localJqueryVars[key] : Utilities.$localJqueryVars[key] = func();\n    }\n    Utilities.getCachedJqueryElements = getCachedJqueryElements;\n    function getCachedSizeDependantValues(key, func) {\n      return Utilities.sizeDependantVars[key] != null ? Utilities.sizeDependantVars[key] : Utilities.sizeDependantVars[key] = func();\n    }\n    Utilities.getCachedSizeDependantValues = getCachedSizeDependantValues;\n    function getWindowElement() {\n      return getCachedJqueryElements('window', function () {\n        return $(window);\n      });\n    }\n    Utilities.getWindowElement = getWindowElement;\n    function getDocumentElement() {\n      return getCachedJqueryElements('document', function () {\n        return $(document);\n      });\n    }\n    Utilities.getDocumentElement = getDocumentElement;\n    function getBodyElement() {\n      return getCachedJqueryElements('body', function () {\n        return $(document.body);\n      });\n    }\n    Utilities.getBodyElement = getBodyElement;\n    function getHtmlBodyElement() {\n      return getCachedJqueryElements('html,body', function () {\n        return $('html,body');\n      });\n    }\n    Utilities.getHtmlBodyElement = getHtmlBodyElement;\n    function getMaintainAspectRatioElements() {\n      return getCachedJqueryElements('getMaintainAspectRatioElements', function () {\n        return $('[data-maintain-aspect-ratio]');\n      });\n    }\n    Utilities.getMaintainAspectRatioElements = getMaintainAspectRatioElements;\n    function browserSupportSrcSet() {\n      return Utilities.$localJqueryVars['browserSupportSrcSet'] != null ? Utilities.$localJqueryVars['browserSupportSrcSet'] : Utilities.$localJqueryVars['browserSupportSrcSet'] = 'srcset' in document.createElement('img');\n    }\n    Utilities.browserSupportSrcSet = browserSupportSrcSet;\n    function resetSizeDependentVariables() {\n      Utilities.sizeDependantVars = [];\n    }\n    Utilities.resetSizeDependentVariables = resetSizeDependentVariables;\n    function windowActualHeight() {\n      if (window.innerHeight != null) {\n        return Math.max(getWindowElement().height(), window.innerHeight);\n      }\n      return getWindowElement().height();\n    }\n    function windowActualWidth() {\n      if (window.innerWidth != null) {\n        return Math.max(getWindowElement().width(), window.innerWidth);\n      }\n      return getWindowElement().width();\n    }\n    function getWindowActualHeight() {\n      return getCachedSizeDependantValues('getWindowActualHeight', function () {\n        return windowActualHeight();\n      });\n    }\n    Utilities.getWindowActualHeight = getWindowActualHeight;\n    function getWindowActualWidth() {\n      return getCachedSizeDependantValues('getWindowActualWidth', function () {\n        return windowActualWidth();\n      });\n    }\n    Utilities.getWindowActualWidth = getWindowActualWidth;\n    function getWindowWidth() {\n      return getCachedSizeDependantValues('getWindowWidth', function () {\n        return getWindowElement().width();\n      });\n    }\n    Utilities.getWindowWidth = getWindowWidth;\n    function getWindowHeight() {\n      return getCachedSizeDependantValues('getWindowHeight', function () {\n        return getWindowElement().height();\n      });\n    }\n    Utilities.getWindowHeight = getWindowHeight;\n    function getUserTestId() {\n      DL.Utilities.setUserTestId();\n      return DL.Utilities.UserTestId;\n    }\n    ;\n    Utilities.getUserTestId = getUserTestId;\n    function setUserTestId() {\n      var key = 'DazedUserTestId';\n      if (DL.Utilities.UserTestId == null) {\n        DL.Utilities.UserTestId = $.jStorage.get(key) || Math.floor(Math.random() * 2520);\n        $.jStorage.set(key, DL.Utilities.UserTestId);\n      }\n    }\n    ;\n    Utilities.setUserTestId = setUserTestId;\n    /*\r\n    * Determines whether JavaScript should handle click or not\r\n    * @param e {Event Object}\r\n    * @returns state {Boolean}\r\n    */\n    function handleState(e) {\n      var state = e.which === 1 && !e.metaKey && !e.shiftKey;\n      return state;\n    }\n    Utilities.handleState = handleState;\n    /*\r\n    * Determines whether browser with is mobile-sized\r\n    * @requires underscore\r\n    * @requires Modernizr\r\n    * @returns {Boolean}\r\n    */\n    function isMobile() {\n      return Modernizr.mq('only screen and (max-width: 767px)');\n    }\n    Utilities.isMobile = isMobile;\n    /*\r\n     * Determines whether browser with is tablet-sized\r\n     * @requires underscore\r\n     * @requires Modernizr\r\n     * @returns {Boolean}\r\n     */\n    function isTablet() {\n      return Modernizr.mq('only screen and (min-width: 768px) and (max-width: 1024px)');\n    }\n    Utilities.isTablet = isTablet;\n    function isDesktop() {\n      return Modernizr.mq('only screen and (min-width: 1025px)');\n    }\n    Utilities.isDesktop = isDesktop;\n    // converts a string functionName into a function call.\n    function executeFunctionByName(functionName, context) {\n      if (context === void 0) {\n        context = window;\n      }\n      var args = [];\n      for (var _i = 2; _i < arguments.length;
1 _i++) {\n        args[_i - 2] = arguments[_i];\n      }\n      if (functionName == null || functionName.length === 0) {\n        return false;\n      }\n      // var args = Array.prototype.slice.call(args, 2);\n      var namespaces = functionName.split('.');\n      var func = namespaces.pop();\n      for (var i = 0; i < namespaces.length; i++) {\n        context = context[namespaces[i]];\n      }\n      if (!context) {\n        AlertError('executeFunctionByName: ' + func + ' does not exist');\n        return false;\n      }\n      return context[func].apply(context, args);\n    }\n    Utilities.executeFunctionByName = executeFunctionByName;\n    function getImgUrlForWidth(url, width) {\n      // based on url format: http://dazedimg.dazedgroup.netdna-cdn.com/355/azure/dazed-prod/1130/6/1136001.jpg\n      // based on url format: http://dazedimg.dazedgroup.netdna-cdn.com/320/0-40-640-547/azure/dazed-prod/1150/9/1159280.jpg\n      var regex = /\\/\\d+(\\/([0-9]+[-]){3}[0-9]+)?\\/azure\\//;\n      var matches = url.match(regex);\n      if (matches != null && matches.length > 0) {\n        return url.replace(matches[0], '/' + width + (matches[1] || '') + '/azure/');\n      }\n      return url;\n    }\n    Utilities.getImgUrlForWidth = getImgUrlForWidth;\n    // Obsolete in Typescript\n    function isFunction(possibleFunction) {\n      return possibleFunction != null && typeof possibleFunction === 'function';\n    }\n    Utilities.isFunction = isFunction;\n    // Obsolete in Typescript\n    function executeIfFunction(possibleFunction) {\n      if (isFunction(possibleFunction)) {\n        var args = Array.prototype.slice.call(arguments).splice(1, 256); // second argument required for this to work in IE8 :-/\n        return possibleFunction.apply(this, args);\n      } else {\n        return null;\n      }\n    }\n    Utilities.executeIfFunction = executeIfFunction;\n    function SilenceExceptionsOnLive(functionToExecute) {\n      try {\n        functionToExecute();\n      } catch (exception) {\n        AlertError(exception);\n      }\n    }\n    Utilities.SilenceExceptionsOnLive = SilenceExceptionsOnLive;\n    function AlertError(error) {\n      console.warn(error);\n      if (DL.BuildIsProduction() === false) {\n        alert(error);\n      }\n    }\n    Utilities.AlertError = AlertError;\n    function requestFullScreen(el) {\n      var request = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullScreen;\n      if (request != null) {\n        DL.Utilities.executeIfFunction(request.call(el));\n      }\n    }\n    Utilities.requestFullScreen = requestFullScreen;\n    function consoleLog() {\n      var args = [];\n      for (var _i = 0; _i < arguments.length;
1 _i++) {\n        args[_i - 0] = arguments[_i];\n      }\n      if (DL.BuildIsProduction() === false) {\n        console.info(args);\n      }\n    }\n    Utilities.consoleLog = consoleLog;\n    function trimEnd(input, charToTrim) {\n      if (input.charAt(input.length - 1) === charToTrim) {\n        return input.substr(0, input.length - 1);\n      }\n      return input;\n    }\n    Utilities.trimEnd = trimEnd;\n    function numberAbbreviate(input, decimalPlaces) {\n      if (decimalPlaces === void 0) {\n        decimalPlaces = 0;\n      }\n      var x = ('' + input).length - 1;\n      if (x % 3 > 0 || x > 6) {\n        decimalPlaces = 0;\n      }\n      x = Math.min(x, 6);\n      x -= x % 3;\n      var decimals = Math.pow(10, decimalPlaces);\n      return trimEnd(Math.round(input * decimals / Math.pow(10, x)) / decimals + ' kM'[x / 3], ' ');\n    }\n    Utilities.numberAbbreviate = numberAbbreviate;\n    Utilities.isUserActiveOnPage = null; // document.hasFocus();\n    function UserActiveOnPage(e) {\n      //console.log('UserActiveOnPage: ' + e.type);\n      if (Utilities.isUserActiveOnPage) {\n        return;\n      }\n      Utilities.isUserActiveOnPage = true;\n      getWindowElement().trigger('userActiveOnPage');\n    }\n    Utilities.UserActiveOnPage = UserActiveOnPage;\n    function OnUserActiveOnPage(callback) {\n      if (Utilities.isUserActiveOnPage) {\n        callback();\n      } else {\n        getWindowElement().on('userActiveOnPage', function () {\n          return callback;\n        });\n      }\n    }\n    Utilities.OnUserActiveOnPage = OnUserActiveOnPage;\n    function AsArray(input) {\n      if (Array.isArray(input)) {\n        return input;\n      }\n      return [input];\n    }\n    Utilities.AsArray = AsArray;\n    function NoScrollToggle(element) {\n      if (element === void 0) {\n        element = document.body;\n      }\n      var noScrollClass = 'noscroll';\n      var $element = $(element);\n      $element.toggleClass(noScrollClass);\n      $element.off('touchmove.preventScroll');\n      if ($element.hasClass(noScrollClass)) {\n        $element.on('touchmove.preventScroll', function (e) {\n          e.preventDefault();\n        });\n      }\n    }\n    Utilities.NoScrollToggle = NoScrollToggle;\n    function WindowScrollTop() {\n      return window.pageYOffset !== undefined ? window.pageYOffset : (document.documentElement || document.body).scrollTop;\n    }\n    Utilities.WindowScrollTop = WindowScrollTop;\n    function hasFormChanged($form) {\n      var _this = this;\n      var hasChanges = false;\n      $form.find(':input:not(:button):not([type=hidden])').each(function () {\n        if ((_this.type === 'text' || _this.type === 'textarea' || _this.type === 'hidden') && _this.defaultValue !== _this.value) {\n          hasChanges = true;\n          return false;\n        } else {\n          if ((_this.type === 'radio' || _this.type === 'checkbox') && _this.defaultChecked !== _this.checked) {\n            hasChanges = true;\n            return false;\n          } else {\n            if (_this.type === 'select-one' || _this.type === 'select-multiple') {\n              for (var x = 0; x < _this.length; x++) {\n                if (_this.options[x].selected !== _this.options[x].defaultSelected) {\n                  hasChanges = true;\n                  return false;\n                }\n              }\n            }\n          }\n        }\n      });\n      return hasChanges;\n    }\n    Utilities.hasFormChanged = hasFormChanged;\n    function gptLoaded() {\n      return window.googletag != null && isFunction(window.googletag.openConsole);\n    }\n    Utilities.gptLoaded = gptLoaded;\n    function hasAdBlocker() {\n      if (!gptLoaded()) {\n        return true;\n      }\n      var ad = document.createElement('ins');\n      ad.className = 'AdSense';\n      ad.style.display = 'block';\n      ad.style.position = 'absolute';\n      ad.style.top = '-1px';\n      ad.style.height = '1px';\n      document.body.appendChild(ad);\n      var isAdBlockEnabled = !ad.clientHeight;\n      document.body.removeChild(ad);\n      return isAdBlockEnabled;\n    }\n    Utilities.hasAdBlocker = hasAdBlocker;\n    var trackGptLoadingExecuted = false;\n    function trackGptLoading() {\n      if (!trackGptLoadingExecuted) {\
1n        trackGptLoadingExecuted = true;\n        // do something\n        //console.info('DL.Utilities.trackGptLoading');\n        var gptLoaded = !hasAdBlocker();\n        var state = gptLoaded ? \"Loaded\" : \"Not loaded\";\n        DL.analytics.trackNonInteractionEvent('GPT', state, window.location.pathname);\n        if (!gptLoaded) {\n          console.warn('GPT ' + state);\n        }\n      }\n    }\n    Utilities.trackGptLoading = trackGptLoading;\n    function setGptTargeting(key, value) {\n      window.googletag.cmd.push(function () {\n        window.googletag.pubads().setTargeting(key, value);\n      });\n    }\n    Utilities.setGptTargeting = setGptTargeting;\n    // Still in use?\n    function jsonDateReviver(key, value) {\n      var a;\n      if (typeof value === 'string') {\n        a = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)Z$/.exec(value);\n        if (a) {\n          return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));\n        }\n      }\n      return value;\n    }\n    Utilities.jsonDateReviver = jsonDateReviver;\n  })(Utilities = DL.Utilities || (DL.Utilities = {}));\n})(DL || (DL = {}));\nDL.Utilities.getWindowElement().one('maintainAspectRatio', function () {\n  DL.Utilities.getWindowElement().on('load.maintainAspectRatio', DL.Utilities.setAllAspectRatio).on('resize.maintainAspectRatio', _.debounce(DL.Utilities.setAllAspectRatio, 100));\n});\nDL.Utilities.getWindowElement().on('resize', DL.Utilities.resetSizeDependentVariables);\nDL.Utilities.getWindowElement().one('mousemove keydown touchstart focus scroll', DL.Utilities.UserActiveOnPage);\n$.fn.filterFind = function (selector) {\n  return this.filter(selector).add(this.find(selector));\n};\n// if you need to extend this, use https://github.com/flesler/jquery.scrollTo\n$.fn.scrollTo = function (duration) {\n  if (duration === void 0) {\n    duration = 0;\n  }\n  // TODO: pass in fixed header height calculator\n  var minSpaceFromHeader = 20;\n  var fixedHeaderHeight = 0;\n  if ($('#header').css('position') === 'fixed') {\n    fixedHeaderHeight = $('#header').outerHeight(true);\n  }\n  $(document.body).animate({\n    scrollTop: this.offset().top - fixedHeaderHeight - minSpaceFromHeader\n  }, duration);\n};\n$.fn.iframeBubbleTouchEvents = function (options) {\n  var params = $.extend({}, {\n    trackHorizontal: true,\n    trackVertical: true\n  }, options);\n  var $container = $(this);\n  $.each($('iframe', this), function (i, iframe) {\n    if (iframe.src != null && iframe.src.length > 0 && iframe.src.indexOf(window.location.origin) < 0) {\n      DL.Utilities.consoleLog('iframeBubbleTouchEvents wont run on ' + iframe.src);\n      return;\n    }\n    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;\n    if (iframeDoc == null) {\n      return;\n    }\n    var startPoint = null;\n    var initialDirectionVertical = null;\n    var touchEvents = 'touchstart.bubbleToParent touchmove.bubbleToParent touchend.bubbleToParent touchcancel.bubbleToParent';\n    $(iframeDoc).off(touchEvents).on(touchEvents, function (e) {\n      if (e.type !== 'touchmove') {\n        startPoint = null;\n        initialDirectionVertical = null;\n      }\n      var originalTouchEvent = e.originalEvent;\n      var originalTouch = originalTouchEvent.targetTouches[0];\n      startPoint = startPoint || originalTouch;\n      if (originalTouch == null) {\n        DL.Utilities.consoleLog('No originalTouch', e.type);\n        var ev_1 = document.createEvent('TouchEvent');\n        ev_1.initEvent(e.type, true, true);\n        ev_1.type = e.type;\n        ev_1.cancelable = true;\n        ev_1.bubbles = true;\n        $container[0].dispatchEvent(ev_1);\n      } else {\n        var change = {\n          X: startPoint.screenX - originalTouch.screenX,\n          Y: startPoint.screenY - originalTouch.screenY\n        };\n        if (initialDirectionVertical == null && (change.X !== 0 || change.Y !== 0)) {\n          initialDirectionVertical = Math.abs(change.Y) > Math.abs(change.X);\n        }\n        if (initialDirectionVertical === true) {\n          change.X = 0;\n        } else if (initialDirectionVertical === false) {\n          change.Y = 0;\n        }\n        if (!params.trackHorizontal) {\n          change.X = 0;\n          if (initialDirectionVertical === true) {\n            e.preventDefault();\n          }\n        }\n        if (!params.trackVertical) {\n          change.Y = 0;\n          if (initialDirectionVertical === false) {\n            e.preventDefault();\n          }\n        }\n        var ev = document.createEvent('Event');\n        ev.initEvent(e.type, true, true);\n        ev.pageX = startPoint.pageX - change.X;\n        ev.pageY = startPoint.pageY - change.Y;\n        ev.clientX = startPoint.clientX - change.X;\n        ev.clientY = startPoint.clientY - change.Y;\n        ev.screenX = originalTouch.screenX;\n        ev.screenY = originalTouch.screenY;\n        $container[0].dispatchEvent(ev);\n      }\n    });\n  });\n};\n$.fn.getUniqueSelector = function (options) {\n  options = $.extend({\n    includeParents: false,\n    includeAttributes: false\n  }, options);\n  var id = $(this).attr('id');\n  if (id) {\n    return '#' + id; // ID's should be unique!\n  }\n  var selector = this.prop('tagName');\n  if (options.includeParents === true) {\n    selector = $(this).parents().map(function () {\n      return this.tagName;\n    }).get().reverse().concat([this.nodeName]).join('>');\n  }\n  var classNames = $(this).attr('class');\n  if (classNames) {\n    selector += '.' + $.trim(classNames).replace(/\\s/gi, '.');\n  }\n  if (options.includeAttributes) {}\n  return selector;\n};\n$.fn.getAvailHeight = function () {\n  var el = this.get(0);\n  var elHeight = el.offsetHeight || el.getBoundingClientRect().height;\n  if (elHeight <= el.scrollHeight - 1) {\n    return elHeight - el.scrollHeight;\n  }
1\n  var $div = $('<div/>');\n  $div.height(elHeight);\n  this.append($div);\n  var availHeight = 2 * elHeight - el.scrollHeight;\n  $div.remove();\n  return availHeight;\n};\n$.fn.setAspectRatio = function () {\n  $(this).each(function () {\n    var $this = $(this);\n    var aspectRatio = parseFloat($this.attr('data-maintain-aspect-ratio'));\n    if (!isNaN(aspectRatio)) {\n      $this.css('height', Math.ceil($this.width() / aspectRatio));\n    }\n  });\n};\n$.fn.maintainAspectRatio = function (options) {\n  options = $.extend({\n    width: null,\n    height: null\n  }, options);\n  function getValue(el, selector) {\n    var style = el.style[selector];\n    if (style != null && style.length > 0 && style.indexOf('%') < 0) {\n      return parseInt(style, 10);\n    }\n    var attr = el.getAttribute(selector);\n    if (attr != null && attr.length > 0 && attr.indexOf('%') < 0) {\n      return parseInt(attr, 10);\n    }\n    //var maxStyle = el.style['max-' + selector];\n    //if (maxStyle != null && maxStyle.length > 0 && maxStyle.indexOf('%') < 0) {\n    //    return parseInt(maxStyle);\n    //}\n    return null;\n  }\n  $(this).each(function () {\n    var $this = $(this);\n    if ($this.attr('data-maintain-aspect-ratio') == null) {\n      var width = options.width || getValue(this, 'width');\n      var height = options.height || getValue(this, 'height');\n      if (width != null && !isNaN(width) && height != null && !isNaN(height)) {\n        $this.attr('data-maintain-aspect-ratio', Math.round(width * 100 / height) / 100);\n      }\n    }\n    if ($this.attr('data-maintain-aspect-ratio') != null) {\n      $this.setAspectRatio();\n      DL.Utilities.$localJqueryVars['getMaintainAspectRatioElements'] = null;\n      DL.Utilities.getWindowElement().trigger('maintainAspectRatio');\n    }\n  });\n};\n$.fn.isElementVisibleOnScreen = function () {\n  var elementTop = $(this).offset().top,\n    elementBottom = $(this).offset().top + $(this).outerHeight(),\n    screenTop = $(window).scrollTop(),\n    screenBottom = $(window).scrollTop() + window.innerHeight;\n  return screenBottom > elementTop && screenTop < elementBottom ? true : false;\n};"},2023:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  var social;\n  (function (social) {\n    function _init() {\n      //\tDL.social.facebook._init();\n      //DL.social.twitter._init();\n      pinterest._init();\n    }\n    social._init = _init;\n    var facebook;\n    (function (facebook) {\n      function _init() {\n        var root = this;\n        if (_.isUndefined(window.FB)) {\n          //  Keep 'this' context in check\n          //  https://github.com/jashkenas/underscore/issues/494\n          return _(function () {\n            $.proxy(facebook._init, root)();\n          }).chain().bind(root).delay(100);\n        }\n        //\tFacebook Tracking\n        window.FB.Event.subscribe('edge.create', function (targetUrl, el) {\n          facebook.action('like', targetUrl, el);\n        });\n        window.FB.Event.subscribe('edge.remove', function (targetUrl, el) {\n          facebook.action('unlike', targetUrl, el);\n        });\n        window.FB.getLoginStatus(function (response) {\n          if (response.status === 'connected') {\n            $('.fb-login-item').removeClass('hidden');\n          }\n        });\n        window.FB.Event.subscribe('xfbml.render', function () {\n          $('.fb-social-container').removeClass('invisible');\n        });\n      }\n      facebook._init = _init;\n      function refresh($container) {\n        var root = this;\n        if (_.isUndefined(window.FB)) {\n          //  Keep 'this' context in check\n          //  https://github.com/jashkenas/underscore/issues/494\n          return _(function () {\n            $.proxy(facebook.refresh, root)();\n          }).chain().bind(root).delay(100);\n        }\n        $container = $container || $(document.body);\n        $container.each(function (index, item) {\n          window.FB.XFBML.parse(item.parentNode || item);\n        });\n      }\n      facebook.refresh = refresh;\n      function action(action, targetUrl, el) {\n        action = action || 'like';\n        var $container = $(el).closest('[data-track-category]');\n        var category = 'Facebook';\n        if ($container.length > 0) {\n          category = $container.attr('data-track-category');\n        }\n        DL.analytics.track('_trackSocial', category, action, targetUrl);\n        DL.Utilities.getWindowElement().trigger('facebook.' + action, $(el));\n      }\n      facebook.action = action;\n    })(facebook = social.facebook || (social.facebook = {}));\n    var twitter;\n    (function (twitter) {\n      function _init() {\n        var root = this;\n        if (_.isUndefined(window.twttr)) {\n          //  Keep 'this' context in check\n          //  https://github.com/jashkenas/underscore/issues/494\n          return _(function () {\n            $.proxy(twitter._init, root)();\n          }).chain().bind(root).delay(100);\n        }\n        //\tTwitter Tracking\n        window.twttr.events.bind('tweet', function (e) {\n          if (e) {\n            var targetUrl;\n            if (e.target && e.target.nodeName === 'IFRAME') {\n              targetUrl = window.location.href;\n            }\n            DL.analytics.track('_trackSocial', 'twitter', 'tweet', targetUrl);\n          }\n        });\n        window.twttr.events.bind('rendered', function (e) {\n          var $widget = $(e.target);\n          var $container = $widget.closest('.twttr-social-container');\n          $container.removeClass('invisible');\n        });\n      }\n      twitter._init = _init;\n      function refresh($container) {\n        var root = this;\n        if (_.isUndefined(window.twttr)) {\n          //  Keep 'this' context in check\n          //  https://github.com/jashkenas/underscore/issues/494\n          return _(function () {\n            $.proxy(refresh, root, $container)();\n          }).chain().bind(root).delay(100);\n        }
1\n        if (window.twttr.hasOwnProperty('widgets')) {\n          $container = $container || $(document.body);\n          $container.each(function (index, item) {\n            window.twttr.widgets.load(item);\n          });\n        }\n      }\n      twitter.refresh = refresh;\n    })(twitter = social.twitter || (social.twitter = {}));\n    var pinterest;\n    (function (pinterest) {\n      function _init() {\n        //\tPinterest Tracking\n        DL.Utilities.getDocumentElement().on('click', '.pin-btn a', function (e) {\n          var targetUrl = $(e.currentTarget).attr('href');\n          DL.analytics.track('_trackSocial', 'pinterest', 'pin', targetUrl);\n        });\n      }\n      pinterest._init = _init;\n      function _pinButtonUrl(relativeUrl, imageAbsoluteUrl, description) {\n        return 'https://www.pinterest.com/pin/create/button/?url=' + encodeURIComponent(window.DL.SiteBaseUrl() + relativeUrl) + '&media=' + encodeURIComponent(imageAbsoluteUrl) + (description ? '&desciption=' + encodeURIComponent(description) : '');\n      }\n      pinterest._pinButtonUrl = _pinButtonUrl;\n    })(pinterest = social.pinterest || (social.pinterest = {}));\n  })(social = DL.social || (DL.social = {}));\n})(DL || (DL = {}));"},2448:function(e){e.exports="function _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\n/**\r\n * Swiper 3.4.2\r\n * Most modern mobile touch slider and framework with hardware accelerated transitions\r\n * \r\n * http://www.idangero.us/swiper/\r\n * \r\n * Copyright 2017, Vladimir Kharlampidi\r\n * The iDangero.us\r\n * http://www.idangero.us/\r\n * \r\n * Licensed under MIT\r\n * \r\n * Released on: March 10, 2017\r\n */\n(function () {\n  'use strict';\n\n  var $;\n\n  /*===========================\r\n  Swiper\r\n  ===========================*/\n  var _Swiper = function Swiper(container, params) {\n    if (!(this instanceof _Swiper)) return new _Swiper(container, params);\n    var defaults = {\n      direction: 'horizontal',\n      touchEventsTarget: 'container',\n      initialSlide: 0,\n      speed: 300,\n      // autoplay\n      autoplay: false,\n      autoplayDisableOnInteraction: true,\n      autoplayStopOnLast: false,\n      // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n      iOSEdgeSwipeDetection: false,\n      iOSEdgeSwipeThreshold: 20,\n      // Free mode\n      freeMode: false,\n      freeModeMomentum: true,\n      freeModeMomentumRatio: 1,\n      freeModeMomentumBounce: true,\n      freeModeMomentumBounceRatio: 1,\n      freeModeMomentumVelocityRatio: 1,\n      freeModeSticky: false,\n      freeModeMinimumVelocity: 0.02,\n      // Autoheight\n      autoHeight: false,\n      // Set wrapper width\n      setWrapperSize: false,\n      // Virtual Translate\n      virtualTranslate: false,\n      // Effects\n      effect: 'slide',\n      // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n      coverflow: {\n        rotate: 50,\n        stretch: 0,\n        depth: 100,\n        modifier: 1,\n        slideShadows: true\n      },\n      flip: {\n        slideShadows: true,\n        limitRotation: true\n      },\n      cube: {\n        slideShadows: true,\n        shadow: true,\n        shadowOffset: 20,\n        shadowScale: 0.94\n      },\n      fade: {\n        crossFade: false\n      },\n      // Parallax\n      parallax: false,\n      // Zoom\n      zoom: false,\n      zoomMax: 3,\n      zoomMin: 1,\n      zoomToggle: true,\n      // Scrollbar\n      scrollbar: null,\n      scrollbarHide: true,\n      scrollbarDraggable: false,\n      scrollbarSnapOnRelease: false,\n      // Keyboard Mousewheel\n      keyboardControl: false,\n      mousewheelControl: false,\n      mousewheelReleaseOnEdges: false,\n      mousewheelInvert: false,\n      mousewheelForceToAxis: fal
1se,\n      mousewheelSensitivity: 1,\n      mousewheelEventsTarged: 'container',\n      // Hash Navigation\n      hashnav: false,\n      hashnavWatchState: false,\n      // History\n      history: false,\n      // Commong Nav State\n      replaceState: false,\n      // Breakpoints\n      breakpoints: undefined,\n      // Slides grid\n      spaceBetween: 0,\n      slidesPerView: 1,\n      slidesPerColumn: 1,\n      slidesPerColumnFill: 'column',\n      slidesPerGroup: 1,\n      centeredSlides: false,\n      slidesOffsetBefore: 0,\n      // in px\n      slidesOffsetAfter: 0,\n      // in px\n      // Round length\n      roundLengths: false,\n      // Touches\n      touchRatio: 1,\n      touchAngle: 45,\n      simulateTouch: true,\n      shortSwipes: true,\n      longSwipes: true,\n      longSwipesRatio: 0.5,\n      longSwipesMs: 300,\n      followFinger: true,\n      onlyExternal: false,\n      threshold: 0,\n      touchMoveStopPropagation: true,\n      touchReleaseOnEdges: false,\n      // Unique Navigation Elements\n      uniqueNavElements: true,\n      // Pagination\n      pagination: null,\n      paginationElement: 'span',\n      paginationClickable: false,\n      paginationHide: false,\n      paginationBulletRender: null,\n      paginationProgressRender: null,\n      paginationFractionRender: null,\n      paginationCustomRender: null,\n      paginationType: 'bullets',\n      // 'bullets' or 'progress' or 'fraction' or 'custom'\n      // Resistance\n      resistance: true,\n      resistanceRatio: 0.85,\n      // Next/prev buttons\n      nextButton: null,\n      prevButton: null,\n      // Progress\n      watchSlidesProgress: false,\n      watchSlidesVisibility: false,\n      // Cursor\n      grabCursor: false,\n      // Clicks\n      preventClicks: true,\n      preventClicksPropagation: true,\n      slideToClickedSlide: false,\n      // Lazy Loading\n      lazyLoading: false,\n      lazyLoadingInPrevNext: false,\n      lazyLoadingInPrevNextAmount: 1,\n      lazyLoadingOnTransitionStart: false,\n      // Images\n      preloadImages: true,\n      updateOnImagesReady: true,\n      // loop\n      loop: false,\n      loopAdditionalSlides: 0,\n      loopedSlides: null,\n      // Control\n      control: undefined,\n      controlInverse: false,\n      controlBy: 'slide',\n      //or 'container'\n      normalizeSlideIndex: true,\n      // Swiping/no swiping\n      allowSwipeToPrev: true,\n      allowSwipeToNext: true,\n      swipeHandler: null,\n      //'.swipe-handler',\n      noSwiping: true,\n      noSwipingClass: 'swiper-no-swiping',\n      // Passive Listeners\n      passiveListeners: true,\n      // NS\n      containerModifierClass: 'swiper-container-',\n      // NEW\n      slideClass: 'swiper-slide',\n      slideActiveClass: 'swiper-slide-active',\n      slideDuplicateActiveClass: 'swiper-slide-duplicate-active',\n      slideVisibleClass: 'swiper-slide-visible',\n      slideDuplicateClass: 'swiper-slide-duplicate',\n      slideNextClass: 'swiper-slide-next',\n      slideDuplicateNextClass: 'swiper-slide-duplicate-next',\n      slidePrevClass: 'swiper-slide-prev',\n      slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',\n      wrapperClass: 'swiper-wrapper',\n      bulletClass: 'swiper-pagination-bullet',\n      bulletActiveClass: 'swiper-pagination-bullet-active',\n      buttonDisabledClass: 'swiper-button-disabled',\n      paginationCurrentClass: 'swiper-pagination-current',\n      paginationTotalClass: 'swiper-pagination-total',\n      paginationHiddenClass: 'swiper-pagination-hidden',\n      paginationProgressbarClass: 'swiper-pagination-progressbar',\n      paginationClickableClass: 'swiper-pagination-clickable',\n      // NEW\n      paginationModifierClass: 'swiper-pagination-',\n      // NEW\n      lazyLoadingClass: 'swiper-lazy',\n      lazyStatusLoadingClass: 'swiper-lazy-loading',\n      lazyStatusLoadedClass: 'swiper-lazy-loaded',\n      lazyPreloaderClass: 'swiper-lazy-preloader',\n      notificationClass: 'swiper-notification',\n      preloaderClass: 'preloader',\n      zoomContainerClass: 'swiper-zoom-container',\n      // Observer\n      observer: false,\n      observeParents: false,\n      // Accessibility\n      a11y: fal
1se,\n      prevSlideMessage: 'Previous slide',\n      nextSlideMessage: 'Next slide',\n      firstSlideMessage: 'This is the first slide',\n      lastSlideMessage: 'This is the last slide',\n      paginationBulletMessage: 'Go to slide {{index}}',\n      // Callbacks\n      runCallbacksOnInit: true\n      /*\r\n      Callbacks:\r\n      onInit: function (swiper)\r\n      onDestroy: function (swiper)\r\n      onBeforeResize: function (swiper)\r\n      onAfterResize: function (swiper)\r\n      onClick: function (swiper, e)\r\n      onTap: function (swiper, e)\r\n      onDoubleTap: function (swiper, e)\r\n      onSliderMove: function (swiper, e)\r\n      onSlideChangeStart: function (swiper)\r\n      onSlideChangeEnd: function (swiper)\r\n      onTransitionStart: function (swiper)\r\n      onTransitionEnd: function (swiper)\r\n      onImagesReady: function (swiper)\r\n      onProgress: function (swiper, progress)\r\n      onTouchStart: function (swiper, e)\r\n      onTouchMove: function (swiper, e)\r\n      onTouchMoveOpposite: function (swiper, e)\r\n      onTouchEnd: function (swiper, e)\r\n      onReachBeginning: function (swiper)\r\n      onReachEnd: function (swiper)\r\n      onSetTransition: function (swiper, duration)\r\n      onSetTranslate: function (swiper, translate)\r\n      onAutoplayStart: function (swiper)\r\n      onAutoplayStop: function (swiper),\r\n      onLazyImageLoad: function (swiper, slide, image)\r\n      onLazyImageReady: function (swiper, slide, image)\r\n      onKeyPress: function (swiper, keyCode)\r\n      */\n    };\n    var initialVirtualTranslate = params && params.virtualTranslate;\n    params = params || {};\n    var originalParams = {};\n    for (var param in params) {\n      if (_typeof(params[param]) === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || typeof Dom7 !== 'undefined' && params[param] instanceof Dom7 || typeof jQuery !== 'undefined' && params[param] instanceof jQuery)) {\n        originalParams[param] = {};\n        for (var deepParam in params[param]) {\n          originalParams[param][deepParam] = params[param][deepParam];\n        }\n      } else {\n        originalParams[param] = params[param];\n      }\n    }\n    for (var def in defaults) {\n      if (typeof params[def] === 'undefined') {\n        params[def] = defaults[def];\n      } else if (_typeof(params[def]) === 'object') {\n        for (var deepDef in defaults[def]) {\n          if (typeof params[def][deepDef] === 'undefined') {\n            params[def][deepDef] = defaults[def][deepDef];\n          }\n        }\n      }\n    }\n\n    // Swiper\n    var s = this;\n\n    // Params\n    s.params = params;\n    s.originalParams = originalParams;\n\n    // Classname\n    s.classNames = [];\n    /*=========================\r\n      Dom Library and plugins\r\n      ===========================*/\n    if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined') {\n      $ = Dom7;\n    }\n    if (typeof $ === 'undefined') {\n      if (typeof Dom7 === 'undefined') {\n        $ = window.Dom7 || window.Zepto || window.jQuery;\n      } else {\n        $ = Dom7;\n      }\n      if (!$) return;\n    }\n    // Export it to Swiper instance\n    s.$ = $;\n    s.getTouchEventX = function (e) {\n      return e.type.indexOf('touch') == 0 && e.targetTouches != null && e.targetTouches.length > 0 && e.targetTouches[0].pageX != null ? e.targetTouches[0].pageX : e.pageX || e.clientX;\n    };\n    s.getTouchEventY = function (e) {\n      return e.type.indexOf('touch') == 0 && e.targetTouches != null && e.targetTouches.length > 0 && e.targetTouches[0].pageY != null ? e.targetTouches[0].pageY : e.pageY || e.clientY;\n    };\n    /*=========================\r\n      Breakpoints\r\n      ===========================*/\n    s.currentBreakpoint = undefined;\n    s.getActiveBreakpoint = function () {\n      //Get breakpoint for window width\n      if (!s.params.breakpoints) return false;\n      var breakpoint = false;\n      var points = [],\n        point;\n      for (point in s.params.breakpoints) {\n        if (s.params.breakpoints.hasOwnProperty(point)) {\n          points.push(point);\n        }\n      }\n      points.sort(function (a, b) {\n        return parseInt(a, 10) > parseInt(b, 10);\n      });\n      for (var i = 0; i < points.length;
1 i++) {\n        point = points[i];\n        if (point >= window.innerWidth && !breakpoint) {\n          breakpoint = point;\n        }\n      }\n      return breakpoint || 'max';\n    };\n    s.setBreakpoint = function () {\n      //Set breakpoint for window width and update parameters\n      var breakpoint = s.getActiveBreakpoint();\n      if (breakpoint && s.currentBreakpoint !== breakpoint) {\n        var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n        var needsReLoop = s.params.loop && breakPointsParams.slidesPerView !== s.params.slidesPerView;\n        for (var param in breakPointsParams) {\n          s.params[param] = breakPointsParams[param];\n        }\n        s.currentBreakpoint = breakpoint;\n        if (needsReLoop && s.destroyLoop) {\n          s.reLoop(true);\n        }\n      }\n    };\n    // Set breakpoint on load\n    if (s.params.breakpoints) {\n      s.setBreakpoint();\n    }\n\n    /*=========================\r\n      Preparation - Define Container, Wrapper and Pagination\r\n      ===========================*/\n    s.container = $(container);\n    if (s.container.length === 0) return;\n    if (s.container.length > 1) {\n      var swipers = [];\n      s.container.each(function () {\n        var container = this;\n        swipers.push(new _Swiper(this, params));\n      });\n      return swipers;\n    }\n\n    // Save instance in container HTML Element and in data\n    s.container[0].swiper = s;\n    s.container.data('swiper', s);\n    s.classNames.push(s.params.containerModifierClass + s.params.direction);\n    if (s.params.freeMode) {\n      s.classNames.push(s.params.containerModifierClass + 'free-mode');\n    }\n    if (!s.support.flexbox) {\n      s.classNames.push(s.params.containerModifierClass + 'no-flexbox');\n      s.params.slidesPerColumn = 1;\n    }\n    if (s.params.autoHeight) {\n      s.classNames.push(s.params.containerModifierClass + 'autoheight');\n    }\n    // Enable slides progress when required\n    if (s.params.parallax || s.params.watchSlidesVisibility) {\n      s.params.watchSlidesProgress = true;\n    }\n    // Max resistance when touchReleaseOnEdges\n    if (s.params.touchReleaseOnEdges) {\n      s.params.resistanceRatio = 0;\n    }\n    // Coverflow / 3D\n    if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n      if (s.support.transforms3d) {\n        s.params.watchSlidesProgress = true;\n        s.classNames.push(s.params.containerModifierClass + '3d');\n      } else {\n        s.params.effect = 'slide';\n      }\n    }\n    if (s.params.effect !== 'slide') {\n      s.classNames.push(s.params.containerModifierClass + s.params.effect);\n    }\n    if (s.params.effect === 'cube') {\n      s.params.resistanceRatio = 0;\n      s.params.slidesPerView = 1;\n      s.params.slidesPerColumn = 1;\n      s.params.slidesPerGroup = 1;\n      s.params.centeredSlides = false;\n      s.params.spaceBetween = 0;\n      s.params.virtualTranslate = true;\n    }\n    if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n      s.params.slidesPerView = 1;\n      s.params.slidesPerColumn = 1;\n      s.params.slidesPerGroup = 1;\n      s.params.watchSlidesProgress = true;\n      s.params.spaceBetween = 0;\n      if (typeof initialVirtualTranslate === 'undefined') {\n        s.params.virtualTranslate = true;\n      }\n    }\n\n    // Grab Cursor\n    if (s.params.grabCursor && s.support.touch) {\n      s.params.grabCursor = false;\n    }\n\n    // Wrapper\n    s.wrapper = s.container.children('.' + s.params.wrapperClass);\n\n    // Pagination\n    if (s.params.pagination) {\n      s.paginationContainer = $(s.params.pagination);\n      if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n        s.paginationContainer = s.container.find(s.params.pagination);\n      }\n      if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n        s.paginationContainer.addClass(s.params.paginationModifierClass + 'clickable');\n      } else {\n        s.params.paginationClickable = false;\n      }\n      s.paginationContainer.addClass(s.params.paginationModifierClass + s.params.paginationType);\n    }\n    // Next/Prev Buttons\n    if (s.params.nextButton || s.params.prevButton) {\n      if (s.params.nextButton) {\n        s.nextButton = $(s.params.nextButton);\n        if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n          s.nextButton = s.container.find(s.params.nextButton);\n        }\n      }\n      if (s.params.prevButton) {\n        s.prevButton = $(s.params.prevButton);\n        if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n          s.prevButton = s.container.find(s.params.prevButton);\n        }\n      }\n    }\n\n    // Is Horizontal\n    s.isHorizontal = function () {\n      return s.params.direction === 'horizontal';\n    };\n    // s.isH = isH;\n\n    // RTL\n    s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n    if (s.rtl) {\n      s.classNames.push(s.params.containerModifierClass + 'rtl');\n    }\n\n    // Wrong RTL support\n    if (s.rtl) {\n      s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n    }\n\n    // Columns\n    if (s.params.slidesPerColumn > 1) {\n      s.classNames.push(s.params.containerModifierClass + 'multirow');\n    }\n\n    // Check for Android\n    if (s.device.android) {\n      s.classNames.push(s.params.containerModifierClass + 'android');\n    }\n\n    // Add classes\n    s.container.addClass(s.classNames.join(' '));\n\n    // Translate\n    s.translate = 0;\n\n    // Progress\n    s.progress = 0;\n\n    // Velocity\n    s.velocity = 0;\n\n    /*=========================\r\n      Locks, unlocks\r\n      ===========================*/\n    s.lockSwipeToNext = function () {\n      s.params.allowSwipeToNext = false;\n      if (s.params.allowSwipeToPrev === false && s.params.grabCursor) {\n        s.unsetGrabCursor(
1);\n      }\n    };\n    s.lockSwipeToPrev = function () {\n      s.params.allowSwipeToPrev = false;\n      if (s.params.allowSwipeToNext === false && s.params.grabCursor) {\n        s.unsetGrabCursor();\n      }\n    };\n    s.lockSwipes = function () {\n      s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n      if (s.params.grabCursor) s.unsetGrabCursor();\n    };\n    s.unlockSwipeToNext = function () {\n      s.params.allowSwipeToNext = true;\n      if (s.params.allowSwipeToPrev === true && s.params.grabCursor) {\n        s.setGrabCursor();\n      }\n    };\n    s.unlockSwipeToPrev = function () {\n      s.params.allowSwipeToPrev = true;\n      if (s.params.allowSwipeToNext === true && s.params.grabCursor) {\n        s.setGrabCursor();\n      }\n    };\n    s.unlockSwipes = function () {\n      s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n      if (s.params.grabCursor) s.setGrabCursor();\n    };\n\n    /*=========================\r\n      Round helper\r\n      ===========================*/\n    function round(a) {\n      return Math.floor(a);\n    }\n    /*=========================\r\n      Set grab cursor\r\n      ===========================*/\n    s.setGrabCursor = function (moving) {\n      s.container[0].style.cursor = 'move';\n      s.container[0].style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';\n      s.container[0].style.cursor = moving ? '-moz-grabbin' : '-moz-grab';\n      s.container[0].style.cursor = moving ? 'grabbing' : 'grab';\n    };\n    s.unsetGrabCursor = function () {\n      s.container[0].style.cursor = '';\n    };\n    if (s.params.grabCursor) {\n      s.setGrabCursor();\n    }\n    /*=========================\r\n      Update on Images Ready\r\n      ===========================*/\n    s.imagesToLoad = [];\n    s.imagesLoaded = 0;\n    s.loadImage = function (imgElement, src, srcset, sizes, checkForComplete, callback) {\n      var image;\n      function onReady() {\n        if (callback) callback();\n      }\n      if (!imgElement.complete || !checkForComplete) {\n        if (src) {\n          image = new window.Image();\n          image.onload = onReady;\n          image.onerror = onReady;\n          if (sizes) {\n            image.sizes = sizes;\n          }\n          if (srcset) {\n            image.srcset = srcset;\n          }\n          if (src) {\n            image.src = src;\n          }\n        } else {\n          onReady();\n        }\n      } else {\n        //image already loaded...\n        onReady();\n      }\n    };\n    s.preloadImages = function () {\n      s.imagesToLoad = s.container.find('img');\n      function _onReady() {\n        if (typeof s === 'undefined' || s === null || !s) return;\n        if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n        if (s.imagesLoaded === s.imagesToLoad.length) {\n          if (s.params.updateOnImagesReady) s.update();\n          s.emit('onImagesReady', s);\n        }\n      }\n      for (var i = 0; i < s.imagesToLoad.length; i++) {\n        s.loadImage(s.imagesToLoad[i], s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src'), s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset'), s.imagesToLoad[i].sizes || s.imagesToLoad[i].getAttribute('sizes'), true, _onReady);\n      }\n    };\n\n    /*=========================\r\n      Autoplay\r\n      ===========================*/\n    s.autoplayTimeoutId = undefined;\n    s.autoplaying = false;\n    s.autoplayPaused = false;\n    function autoplay() {\n      var autoplayDelay = s.params.autoplay;\n      var activeSlide = s.slides.eq(s.activeIndex);\n      if (activeSlide.attr('data-swiper-autoplay')) {\n        autoplayDelay = activeSlide.attr('data-swiper-autoplay') || s.params.autoplay;\n      }\n      s.autoplayTimeoutId = setTimeout(function () {\n        if (s.params.loop) {\n          s.fixLoop();\n          s._slideNext();\n          s.emit('onAutoplay', s);\n        } else {\n          if (!s.isEnd) {\n            s._slideNext();\n            s.emit('onAutoplay', s);\n          } else {\n            if (!params.autoplayStopOnLast) {\n              s._slideTo(0);\n              s.emit('onAutoplay', s);\n            } else {\n              s.stopAutoplay();\n            }\n          }\n        }\n      }, autoplayDelay);\n    }\n    s.startAutoplay = function () {\n      if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n      if (!s.params.autoplay) return false;\n      if (s.autoplaying) return false;\n      s.autoplaying = true;\n      s.emit('onAutoplayStart', s);\n      autoplay();\n    };\n    s.stopAutoplay = function (internal) {\n      if (!s.autoplayTimeoutId) return;\n      if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n      s.autoplaying = false;\n      s.autoplayTimeoutId = undefined;\n      s.emit('onAutoplayStop', s);\n    };\n    s.pauseAutoplay = function (speed) {\n      if (s.autoplayPaused) return;\n      if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n      s.autoplayPaused = true;\n      if (speed === 0) {\n        s.autoplayPaused = false;\n        autoplay();\n      } else {\n        s.wrapper.transitionEnd(function () {\n          if (!s) return;\n          s.autoplayPaused = false;\n          if (!s.autoplaying) {\n            s.stopAutoplay();\n          } else {\n            autoplay();\n          }\n        });\n      }\n    };\n    /*=========================\r\n      Min/Max Translate\r\n      ===========================*/\n    s.minTranslate = function () {\n      return -s.snapGrid[0];\n    };\n    s.maxTranslate = function () {\n      return -s.snapGrid[s.snapGrid.length - 1];\n    };\n    /*=========================\r\n      Slider/slides sizes\r\n      ===========================*/\n    s.updateAutoHeight = function () {\n      var activeSlides = [];\n      var newHeight = 0;\n      var i;\n\n      // Find slides currently in view\n      if (s.params.slidesPerView !== 'auto' && s.params.slidesPerView > 1) {\n        for (i = 0;
1 i < Math.ceil(s.params.slidesPerView); i++) {\n          var index = s.activeIndex + i;\n          if (index > s.slides.length) break;\n          activeSlides.push(s.slides.eq(index)[0]);\n        }\n      } else {\n        activeSlides.push(s.slides.eq(s.activeIndex)[0]);\n      }\n\n      // Find new height from heighest slide in view\n      for (i = 0; i < activeSlides.length; i++) {\n        if (typeof activeSlides[i] !== 'undefined') {\n          var height = activeSlides[i].offsetHeight;\n          newHeight = height > newHeight ? height : newHeight;\n        }\n      }\n\n      // Update Height\n      if (newHeight) s.wrapper.css('height', newHeight + 'px');\n    };\n    s.updateContainerSize = function () {\n      var width, height;\n      if (typeof s.params.width !== 'undefined') {\n        width = s.params.width;\n      } else {\n        width = s.container[0].clientWidth;\n      }\n      if (typeof s.params.height !== 'undefined') {\n        height = s.params.height;\n      } else {\n        height = s.container[0].clientHeight;\n      }\n      if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n        return;\n      }\n\n      //Subtract paddings\n      width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n      height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n\n      // Store values\n      s.width = width;\n      s.height = height;\n      s.size = s.isHorizontal() ? s.width : s.height;\n    };\n    s.updateSlidesSize = function () {\n      s.slides = s.wrapper.children('.' + s.params.slideClass);\n      s.snapGrid = [];\n      s.slidesGrid = [];\n      s.slidesSizesGrid = [];\n      var spaceBetween = s.params.spaceBetween,\n        slidePosition = -s.params.slidesOffsetBefore,\n        i,\n        prevSlideSize = 0,\n        index = 0;\n      if (typeof s.size === 'undefined') return;\n      if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n      }\n      s.virtualSize = -spaceBetween;\n      // reset margins\n      if (s.rtl) s.slides.css({\n        marginLeft: '',\n        marginTop: ''\n      });else s.slides.css({\n        marginRight: '',\n        marginBottom: ''\n      });\n      var slidesNumberEvenToRows;\n      if (s.params.slidesPerColumn > 1) {\n        if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n          slidesNumberEvenToRows = s.slides.length;\n        } else {\n          slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n        }\n        if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n          slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n        }\n      }\n\n      // Calc slides\n      var slideSize;\n      var slidesPerColumn = s.params.slidesPerColumn;\n      var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n      var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n      for (i = 0; i < s.slides.length; i++) {\n        slideSize = 0;\n        var slide = s.slides.eq(i);\n        if (s.params.slidesPerColumn > 1) {\n          // Set slides order\n          var newSlideOrderIndex;\n          var column, row;\n          if (s.params.slidesPerColumnFill === 'column') {\n            column = Math.floor(i / slidesPerColumn);\n            row = i - column * slidesPerColumn;\n            if (column > numFullColumns || column === numFullColumns && row === slidesPerColumn - 1) {\n              if (++row >= slidesPerColumn) {\n                row = 0;\n                column++;\n              }\n            }\n            newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n            slide.css({\n              '-webkit-box-ordinal-group': newSlideOrderIndex,\n              '
1-moz-box-ordinal-group': newSlideOrderIndex,\n              '-ms-flex-order': newSlideOrderIndex,\n              '-webkit-order': newSlideOrderIndex,\n              'order': newSlideOrderIndex\n            });\n          } else {\n            row = Math.floor(i / slidesPerRow);\n            column = i - row * slidesPerRow;\n          }\n          slide.css('margin-' + (s.isHorizontal() ? 'top' : 'left'), row !== 0 && s.params.spaceBetween && s.params.spaceBetween + 'px').attr('data-swiper-column', column).attr('data-swiper-row', row);\n        }\n        if (slide.css('display') === 'none') continue;\n        if (s.params.slidesPerView === 'auto') {\n          slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n          if (s.params.roundLengths) slideSize = round(slideSize);\n        } else {\n          slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n          if (s.params.roundLengths) slideSize = round(slideSize);\n          if (s.isHorizontal()) {\n            s.slides[i].style.width = slideSize + 'px';\n          } else {\n            s.slides[i].style.height = slideSize + 'px';\n          }\n        }\n        s.slides[i].swiperSlideSize = slideSize;\n        s.slidesSizesGrid.push(slideSize);\n        if (s.params.centeredSlides) {\n          slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n          if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n          if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n          if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n          if (index % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n          s.slidesGrid.push(slidePosition);\n        } else {\n          if (index % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n          s.slidesGrid.push(slidePosition);\n          slidePosition = slidePosition + slideSize + spaceBetween;\n        }\n        s.virtualSize += slideSize + spaceBetween;\n        prevSlideSize = slideSize;\n        index++;\n      }\n      s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n      var newSlidesGrid;\n      if (s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n        s.wrapper.css({\n          width: s.virtualSize + s.params.spaceBetween + 'px'\n        });\n      }\n      if (!s.support.flexbox || s.params.setWrapperSize) {\n        if (s.isHorizontal()) s.wrapper.css({\n          width: s.virtualSize + s.params.spaceBetween + 'px'\n        });else s.wrapper.css({\n          height: s.virtualSize + s.params.spaceBetween + 'px'\n        });\n      }\n      if (s.params.slidesPerColumn > 1) {\n        s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n        s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n        if (s.isHorizontal()) s.wrapper.css({\n          width: s.virtualSize + s.params.spaceBetween + 'px'\n        });else s.wrapper.css({\n          height: s.virtualSize + s.params.spaceBetween + 'px'\n        });\n        if (s.params.centeredSlides) {\n          newSlidesGrid = [];\n          for (i = 0; i < s.snapGrid.length; i++) {\n            if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n          }\n          s.snapGrid = newSlidesGrid;\n        }\n      }\n\n      // Remove last grid elements depending on width\n      if (!s.params.centeredSlides) {\n        newSlidesGrid = [];\n        for (i = 0; i < s.snapGrid.length; i++) {\n          if (s.snapGrid[i] <= s.virtualSize - s.size) {\n            newSlidesGrid.push(s.snapGrid[i]);\n          }\n        }\n        s.snapGrid = newSlidesGrid;\n        if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n          s.snapGrid.push(s.virtualSize - s.size);\n        }\n      }\n      if (s.snapGrid.length === 0) s.snapGrid = [0];\n      if (s.params.spaceBetween !== 0) {\n        if (s.isHorizontal()) {\n          if (s.rtl) s.slides.css({\n            marginLeft: spaceBetween + 'px'\n          });else s.slides.css({\n            marginRight: spaceBetween + 'px'\n          });\n        } else s.slides.css({\n          marginBottom: spaceBetween + 'px'\n        });\n      }\n      if (s.params.watchSlidesProgress) {\n        s.updateSlidesOffset();\n      }\n    };\n    s.updateSlidesOffset = function () {\n      for (var i = 0; i < s.slides.length;
1 i++) {\n        s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n      }\n    };\n\n    /*=========================\r\n      Dynamic Slides Per View\r\n      ===========================*/\n    s.currentSlidesPerView = function () {\n      var spv = 1,\n        i,\n        j;\n      if (s.params.centeredSlides) {\n        var size = s.slides[s.activeIndex].swiperSlideSize;\n        var breakLoop;\n        for (i = s.activeIndex + 1; i < s.slides.length; i++) {\n          if (s.slides[i] && !breakLoop) {\n            size += s.slides[i].swiperSlideSize;\n            spv++;\n            if (size > s.size) breakLoop = true;\n          }\n        }\n        for (j = s.activeIndex - 1; j >= 0; j--) {\n          if (s.slides[j] && !breakLoop) {\n            size += s.slides[j].swiperSlideSize;\n            spv++;\n            if (size > s.size) breakLoop = true;\n          }\n        }\n      } else {\n        for (i = s.activeIndex + 1; i < s.slides.length; i++) {\n          if (s.slidesGrid[i] - s.slidesGrid[s.activeIndex] < s.size) {\n            spv++;\n          }\n        }\n      }\n      return spv;\n    };\n    /*=========================\r\n      Slider/slides progress\r\n      ===========================*/\n    s.updateSlidesProgress = function (translate) {\n      if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n      }\n      if (s.slides.length === 0) return;\n      if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n      var offsetCenter = -translate;\n      if (s.rtl) offsetCenter = translate;\n\n      // Visible Slides\n      s.slides.removeClass(s.params.slideVisibleClass);\n      for (var i = 0; i < s.slides.length; i++) {\n        var slide = s.slides[i];\n        var slideProgress = (offsetCenter + (s.params.centeredSlides ? s.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n        if (s.params.watchSlidesVisibility) {\n          var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n          var slideAfter = slideBefore + s.slidesSizesGrid[i];\n          var isVisible = slideBefore >= 0 && slideBefore < s.size || slideAfter > 0 && slideAfter <= s.size || slideBefore <= 0 && slideAfter >= s.size;\n          if (isVisible) {\n            s.slides.eq(i).addClass(s.params.slideVisibleClass);\n          }\n        }\n        slide.progress = s.rtl ? -slideProgress : slideProgress;\n      }\n    };\n    s.updateProgress = function (translate) {\n      if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n      }\n      var translatesDiff = s.maxTranslate() - s.minTranslate();\n      var wasBeginning = s.isBeginning;\n      var wasEnd = s.isEnd;\n      if (translatesDiff === 0) {\n        s.progress = 0;\n        s.isBeginning = s.isEnd = true;\n      } else {\n        s.progress = (translate - s.minTranslate()) / translatesDiff;\n        s.isBeginning = s.progress <= 0;\n        s.isEnd = s.progress >= 1;\n      }\n      if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n      if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n      if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n      s.emit('onProgress', s, s.progress);\n    };\n    s.updateActiveIndex = function () {\n      var translate = s.rtl ? s.translate : -s.translate;\n      var newActiveIndex, i, snapIndex;\n      for (i = 0; i < s.slidesGrid.length; i++) {\n        if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n          if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n            newActiveIndex = i;\n          } else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n            newActiveIndex = i + 1;\n          }\n        } else {\n          if (translate >= s.slidesGrid[i]) {\n            newActiveIndex = i;\n          }\n        }\n      }\n      // Normalize slideIndex\n      if (s.params.normalizeSlideIndex) {\n        if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n      }\n      // for (i = 0; i < s.slidesGrid.length;
1 i++) {\n      // if (- translate >= s.slidesGrid[i]) {\n      // newActiveIndex = i;\n      // }\n      // }\n      snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n      if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n      if (newActiveIndex === s.activeIndex) {\n        return;\n      }\n      s.snapIndex = snapIndex;\n      s.previousIndex = s.activeIndex;\n      s.activeIndex = newActiveIndex;\n      s.updateClasses();\n      s.updateRealIndex();\n    };\n    s.updateRealIndex = function () {\n      s.realIndex = parseInt(s.slides.eq(s.activeIndex).attr('data-swiper-slide-index') || s.activeIndex, 10);\n    };\n\n    /*=========================\r\n      Classes\r\n      ===========================*/\n    s.updateClasses = function () {\n      s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass + ' ' + s.params.slideDuplicateActiveClass + ' ' + s.params.slideDuplicateNextClass + ' ' + s.params.slideDuplicatePrevClass);\n      var activeSlide = s.slides.eq(s.activeIndex);\n      // Active classes\n      activeSlide.addClass(s.params.slideActiveClass);\n      if (params.loop) {\n        // Duplicate to all looped slides\n        if (activeSlide.hasClass(s.params.slideDuplicateClass)) {\n          s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index=\"' + s.realIndex + '\"]').addClass(s.params.slideDuplicateActiveClass);\n        } else {\n          s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + s.realIndex + '\"]').addClass(s.params.slideDuplicateActiveClass);\n        }\n      }\n      // Next Slide\n      var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n      if (s.params.loop && nextSlide.length === 0) {\n        nextSlide = s.slides.eq(0);\n        nextSlide.addClass(s.params.slideNextClass);\n      }\n      // Prev Slide\n      var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n      if (s.params.loop && prevSlide.length === 0) {\n        prevSlide = s.slides.eq(-1);\n        prevSlide.addClass(s.params.slidePrevClass);\n      }\n      if (params.loop) {\n        // Duplicate to all looped slides\n        if (nextSlide.hasClass(s.params.slideDuplicateClass)) {\n          s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index=\"' + nextSlide.attr('data-swiper-slide-index') + '\"]').addClass(s.params.slideDuplicateNextClass);\n        } else {\n          s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + nextSlide.attr('data-swiper-slide-index') + '\"]').addClass(s.params.slideDuplicateNextClass);\n        }\n        if (prevSlide.hasClass(s.params.slideDuplicateClass)) {\n          s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index=\"' + prevSlide.attr('data-swiper-slide-index') + '\"]').addClass(s.params.slideDuplicatePrevClass);\n        } else {\n          s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + prevSlide.attr('data-swiper-slide-index') + '\"]').addClass(s.params.slideDuplicatePrevClass);\n        }\n      }\n\n      // Pagination\n      if (s.paginationContainer && s.paginationContainer.length > 0) {\n        // Current/Total\n        var current,\n          total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n        if (s.params.loop) {\n          current = Math.ceil((s.activeIndex - s.loopedSlides) / s.params.slidesPerGroup);\n          if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n            current = current - (s.slides.length - s.loopedSlides * 2);\n          }\n          if (current > total - 1) current = current - total;\n          if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n        } else {\n          if (typeof s.snapIndex !== 'undefined') {\n            current = s.snapIndex;\n          } else {\n            current = s.activeIndex || 0;\n          }\n        }\n        // Types\n        if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n          s.bullets.removeClass(s.params.bulletActiveClass);\n          if (s.paginationContainer.length > 1) {\n            s.bullets.each(function () {\n              if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n            });\n          } else {\n            s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n          }\n        }\n        if (s.params.paginationType === 'fraction') {\n          s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n          s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n        }\n        if (s.params.paginationType === 'progress') {\n          var scale = (current + 1) / total,\n            scaleX = scale,\n            scaleY = 1;\n          if (!s.isHorizontal()) {\n            scaleY = scale;\n            scaleX = 1;\n          }\n          s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,
10,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n        }\n        if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n          s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n          s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n      }\n\n      // Next/active buttons\n      if (!s.params.loop) {\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n          if (s.isBeginning) {\n            s.prevButton.addClass(s.params.buttonDisabledClass);\n            if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n          } else {\n            s.prevButton.removeClass(s.params.buttonDisabledClass);\n            if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n          }\n        }\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n          if (s.isEnd) {\n            s.nextButton.addClass(s.params.buttonDisabledClass);\n            if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n          } else {\n            s.nextButton.removeClass(s.params.buttonDisabledClass);\n            if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n          }\n        }\n      }\n    };\n\n    /*=========================\r\n      Pagination\r\n      ===========================*/\n    s.updatePagination = function () {\n      if (!s.params.pagination) return;\n      if (s.paginationContainer && s.paginationContainer.length > 0) {\n        var paginationHTML = '';\n        if (s.params.paginationType === 'bullets') {\n          var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n          for (var i = 0; i < numberOfBullets; i++) {\n            if (s.params.paginationBulletRender) {\n              paginationHTML += s.params.paginationBulletRender(s, i, s.params.bulletClass);\n            } else {\n              paginationHTML += '<' + s.params.paginationElement + ' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n            }\n          }\n          s.paginationContainer.html(paginationHTML);\n          s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n          if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n            s.a11y.initPagination();\n          }\n        }\n        if (s.params.paginationType === 'fraction') {\n          if (s.params.paginationFractionRender) {\n            paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n          } else {\n            paginationHTML = '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' + ' / ' + '<span class=\"' + s.params.paginationTotalClass + '\"></span>';\n          }\n          s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType === 'progress') {\n          if (s.params.paginationProgressRender) {\n            paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n          } else {\n            paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n          }\n          s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType !== 'custom') {\n          s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n      }\n    };\n    /*=========================\r\n      Common update method\r\n      ===========================*/\n    s.update = function (updateTranslate) {\n      if (!s) return;\n      s.updateContainerSize();\n      s.updateSlidesSize();\n      s.updateProgress();\n      s.updatePagination();\n      s.updateClasses();\n      if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n      }\n      var newTranslate;\n      function forceSetTranslate() {\n        var translate = s.rtl ? -s.translate : s.translate;\n        newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n      }\n      if (updateTranslate) {\n        var translated;\n        if (s.controller && s.controller.spline) {\n          s.controller.spline = undefined;\n        }\n        if (s.params.freeMode) {\n          forceSetTranslate();\n          if (s.params.autoHeight) {\n            s.updateAutoHeight();\n          }\n        } else {\n          if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n            translated = s.slideTo(s.slides.length - 1, 0, false, true);\n          } else {\n            translated = s.slideTo(s.activeIndex, 0, false, true);\n          }\n          if (!translated) {\n            forceSetTranslate();\n          }\n        }\n      } else if (s.params.autoHeight) {\n        s.updateAutoHeight();\n      }\n    };\n\n    /*=========================\r\n      Resize Handler\r\n      ===========================*/\n    s.onResize = function (forceUpdatePagination) {\n      if (s.params.onBeforeResize) s.params.onBeforeResize(s);\n      //Breakpoints\n      if (s.params.breakpoints) {\n        s.setBreakpoint();\n      }\n\n      // Disable locks on resize\n      var allowSwipeToPrev = s.params.allowSwipeToPrev;\n      var allowSwipeToNext = s.params.allowSwipeToNext;\n      s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n      s.updateContainerSize();\n      s.updateSlidesSize();\n      if (s.params.slidesPerView === 'auto' || s.params.freeMode || force
1UpdatePagination) s.updatePagination();\n      if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n      }\n      if (s.controller && s.controller.spline) {\n        s.controller.spline = undefined;\n      }\n      var slideChangedBySlideTo = false;\n      if (s.params.freeMode) {\n        var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n        if (s.params.autoHeight) {\n          s.updateAutoHeight();\n        }\n      } else {\n        s.updateClasses();\n        if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n          slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n        } else {\n          slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n        }\n      }\n      if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n        s.lazy.load();\n      }\n      // Return locks after resize\n      s.params.allowSwipeToPrev = allowSwipeToPrev;\n      s.params.allowSwipeToNext = allowSwipeToNext;\n      if (s.params.onAfterResize) s.params.onAfterResize(s);\n    };\n\n    /*=========================\r\n      Events\r\n      ===========================*/\n\n    //Define Touch Events\n    s.touchEventsDesktop = {\n      start: 'mousedown',\n      move: 'mousemove',\n      end: 'mouseup'\n    };\n    if (window.navigator.pointerEnabled) s.touchEventsDesktop = {\n      start: 'pointerdown',\n      move: 'pointermove',\n      end: 'pointerup'\n    };else if (window.navigator.msPointerEnabled) s.touchEventsDesktop = {\n      start: 'MSPointerDown',\n      move: 'MSPointerMove',\n      end: 'MSPointerUp'\n    };\n    s.touchEvents = {\n      start: s.support.touch || !s.params.simulateTouch ? 'touchstart' : s.touchEventsDesktop.start,\n      move: s.support.touch || !s.params.simulateTouch ? 'touchmove' : s.touchEventsDesktop.move,\n      end: s.support.touch || !s.params.simulateTouch ? 'touchend' : s.touchEventsDesktop.end\n    };\n\n    // WP8 Touch Events Fix\n    if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n      (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n    }\n\n    // Attach/detach events\n    s.initEvents = function (detach) {\n      var actionDom = detach ? 'off' : 'on';\n      var action = detach ? 'removeEventListener' : 'addEventListener';\n      var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n      var target = s.support.touch ? touchEventsTarget : document;\n      var moveCapture = s.params.nested ? true : false;\n\n      //Touch Events\n      if (s.browser.ie) {\n        touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n        target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n        target[action](s.touchEvents.end, s.onTouchEnd, false);\n      } else {\n        if (s.support.touch) {\n          var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {\n            passive: true,\n            capture: false\n          } : false;\n          touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, passiveListener);\n          touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n          touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, passiveListener);\n        }\n        if (params.simulateTouch && !s.device.ios && !s.device.android || params.simulateTouch && !s.support.touch && s.device.ios) {\n          touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n          document[action]('mousemove', s.onTouchMove, moveCapture);\n          document[action]('mouseup', s.onTouchEnd, false);\n        }\n      }\n      window[action]('resize', s.onResize);\n\n      // Next, Prev, Index\n      if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n        s.nextButton[actionDom]('click', s.onClickNext);\n        if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n      }\n      if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n        s.prevButton[actionDom]('click', s.onClickPrev);\n        if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n      }\n      if (s.params.pagination && s.params.paginationClickable) {\n        s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n        if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n      }\n\n      // Prevent Links Clicks\n      if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n    };\n    s.attachEvents = function () {\n      s.initEvents();\n    };\n    s.detachEvents = function () {\n      s.initEvents(true);\n    };\n\n    /*=========================\r\n      Handle Clicks\r\n      ===========================*/\n    // Prevent Clicks\n    s.allowClick = true;\n    s.preventClicks = function (e) {\n      if (!s.allowClick) {\
1n        if (s.params.preventClicks) e.preventDefault();\n        if (s.params.preventClicksPropagation && s.animating) {\n          e.stopPropagation();\n          e.stopImmediatePropagation();\n        }\n      }\n    };\n    // Clicks\n    s.onClickNext = function (e) {\n      e.preventDefault();\n      if (s.isEnd && !s.params.loop) return;\n      s.slideNext();\n    };\n    s.onClickPrev = function (e) {\n      e.preventDefault();\n      if (s.isBeginning && !s.params.loop) return;\n      s.slidePrev();\n    };\n    s.onClickIndex = function (e) {\n      e.preventDefault();\n      var index = $(this).index() * s.params.slidesPerGroup;\n      if (s.params.loop) index = index + s.loopedSlides;\n      s.slideTo(index);\n    };\n\n    /*=========================\r\n      Handle Touches\r\n      ===========================*/\n    function findElementInEvent(e, selector) {\n      var el = $(e.target);\n      if (!el.is(selector)) {\n        if (typeof selector === 'string') {\n          el = el.parents(selector);\n        } else if (selector.nodeType) {\n          var found;\n          el.parents().each(function (index, _el) {\n            if (_el === selector) found = selector;\n          });\n          if (!found) return undefined;else return selector;\n        }\n      }\n      if (el.length === 0) {\n        return undefined;\n      }\n      return el[0];\n    }\n    s.updateClickedSlide = function (e) {\n      var slide = findElementInEvent(e, '.' + s.params.slideClass);\n      var slideFound = false;\n      if (slide) {\n        for (var i = 0; i < s.slides.length; i++) {\n          if (s.slides[i] === slide) slideFound = true;\n        }\n      }\n      if (slide && slideFound) {\n        s.clickedSlide = slide;\n        s.clickedIndex = $(slide).index();\n      } else {\n        s.clickedSlide = undefined;\n        s.clickedIndex = undefined;\n        return;\n      }\n      if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n        var slideToIndex = s.clickedIndex,\n          realIndex,\n          duplicatedSlides,\n          slidesPerView = s.params.slidesPerView === 'auto' ? s.currentSlidesPerView() : s.params.slidesPerView;\n        if (s.params.loop) {\n          if (s.animating) return;\n          realIndex = parseInt($(s.clickedSlide).attr('data-swiper-slide-index'), 10);\n          if (s.params.centeredSlides) {\n            if (slideToIndex < s.loopedSlides - slidesPerView / 2 || slideToIndex > s.slides.length - s.loopedSlides + slidesPerView / 2) {\n              s.fixLoop();\n              slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();\n              setTimeout(function () {\n                s.slideTo(slideToIndex);\n              }, 0);\n            } else {\n              s.slideTo(slideToIndex);\n            }\n          } else {\n            if (slideToIndex > s.slides.length - slidesPerView) {\n              s.fixLoop();\n              slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();\n              setTimeout(function () {\n                s.slideTo(slideToIndex);\n              }, 0);\n            } else {\n              s.slideTo(slideToIndex);\n            }\n          }\n        } else {\n          s.slideTo(slideToIndex);\n        }\n      }\n    };\n    var isTouched,\n      isMoved,\n      allowTouchCallbacks,\n      touchStartTime,\n      isScrolling,\n      currentTranslate,\n      startTranslate,\n      allowThresholdMove,\n      // Form elements to match\n      formElements = 'input, select, textarea, button, video',\n      // Last click time\n      lastClickTime = Date.now(),\n      clickTimeout,\n      //Velocities\n      velocities = [],\n      allowMomentumBounce;\n\n    // Animating Flag\n    s.animating = false;\n\n    // Touches information\n    s.touches = {\n      startX: 0,\n      startY: 0,\n      currentX: 0,\n      currentY: 0,\n      diff: 0\n    };\n\n    // Touch handlers\n    var isTouchEvent, startMoving;\n    s.onTouchStart = function (e) {\n      if (e.originalEvent) e = e.originalEvent;\n      isTouchEvent = e.type === 'touchstart';\n      if (!isTouchEvent && 'which' in e && e.which === 3) return;\n      if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n        s.allowClick = true;\n        return;\n      }\n      if (s.params.swipeHandler) {\n        if (!findElementInEvent(e, s.params.swipeHandler)) return;\n      }\n      var startX = s.touches.currentX = s.getTouchEventX(e);\n      var startY = s.touches.currentY = s.getTouchEventY(e);\n\n      // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n      if (s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n        return;\n      }\n      isTouched = true;\n      isMoved = false;\n      allowTouchCallbacks = true;\n      isScrolling = undefined;\n      startMoving = undefined;\n      s.touches.startX = startX;\n      s.touches.startY = startY;\n      touchStartTime = Date.now();\n      s.allowClick = true;\n      s.updateContainerSize();\n      s.swipeDirection = undefined;\n      if (s.params.threshold > 0) allowThresholdMove = false;\n      if (e.type !== 'touchstart') {\n        var preventDefault = true;\n        if ($(e.target).is(formElements)) preventDefault = false;\n        if (document.activeElement && $(document.activeElement).is(formElements)) {\n          document.activeElement.blur();\n        }\n        if (preventDefault) {\n          e.preventDefault();\n        }\n      }\n      s.emit('onTouchStart', s, e);\n    };\n    s.onTouchMove = function (e) {\n      if (e.originalEvent) e = e.originalEvent;\n      if (isTouchEvent && e.type === 'mousemove') return;\n      if (e.preventedByNestedSwiper) {\n        s.touches.startX = s.getTouchEventX(e);\n        s.touches.startY = s.getTouchEventY(e);\n        return;\n      }\n      if (s.params.onlyExternal) {\n        // isMoved = true;\n        s.allowClick = false;\n        if (isTouched) {\n          s.touches.startX = s.touches.currentX = s.getTouchEventX(e);\n          s.touches.startY = s.touches.currentY = s.getTouchEventY(e);\n          touchStartTime = Date.now();\n        }\n        return;\n      }\n      if (isTouchEvent && s.params.touchReleaseOnEdges && !s.params.loop) {\n        if (!s.isHorizontal()) {\n          // Vertical\n          if (s.touches.currentY < s.touches.startY && s.translate <= s.maxTranslate() || s.touches.currentY > s.touches.startY && s.translate >= s.minTranslate()) {\n            return;\n          }\n        } else {\n          if (s.touches.currentX < s.touches.startX && s.translate <= s.maxTranslate() || s.touches.currentX > s.touches.startX && s.translate >= s.minTranslate()) {\n            return;\n          }\n        }\n      }\n      if (isTouchEvent && document.activeElement) {\n        if (e.target === document.activeElement && $(e.target).is(formElements)) {\n          isMoved = true;\n          s.allowClick = false;\n          return;\n        }\n      }\n      if (allowTouchCallbacks) {\n        s.emit('onTouchMove', s, e);\n      }\n      if (e.targetTouches && e.targetTouches.length > 1) return;\n      s.touches.currentX = s.getTouchEventX(e);\n      s.touches.currentY = s.getTouchEventY(e);\n      if (typeof isScrolling === 'undefined') {\n        var touchAngle;\n        if (s.isHorizontal() && s.touches.currentY === s.touches.startY || !s.isHorizontal() && s.touches.currentX === s.touches.startX) {\n          isScrolling = false;\n        } else {\n          touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n          isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : 90 - touchAngle > s.params.touchAngle;\n        }\n      }\n      if (isScrolling) {\n        s.emit('onTouchMoveOpposite', s, e);\n      }\n      if (typeof startMoving === 'undefined') {\n        if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n          startMoving = true;\n        }\n      }\n      if (!isTouched) return;\n      if (isScrolling) {\n        isTouched = false;\n        return;\n      }\n      if (!startMoving) {\n        return;\n      }\n      s.allowClick = false;\n      s.emit('onSliderMove', s, e);\n      e.preventDefault();\n      if (s.params.touchMoveStopPropagation && !s.params.nested) {\n        e.stopPropagation();\n      }\n      if (!isMoved) {\n        if (params.loop) {\n          s.fixLoop();\n        }\n        startTranslate = s.getWrapperTranslate();\n        s.setWrapperTransition(0);\n        if (s.animating) {\n          s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n        }\n        if (s.params.autoplay && s.autoplaying) {\n          if (s.params.autoplayDisableOnInteraction) {\n            s.stopAutoplay();\n          } else {\n            s.pauseAutoplay();\n          }\n        }\n        allowMomentumBounce = false;\n        //Grab Cursor\n        if (s.params.grabCursor && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {\n          s.setGrabCursor(true);\n        }\n      }\n      isMoved = true;\n      var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n      diff = diff * s.params.touchRatio;\n      if (s.rtl) diff = -diff;\n      s.swipeDirection = diff > 0 ? 'prev' : 'next';\n      currentTranslate = diff + startTranslate;\n      var disableParentSwiper = true;\n      if (diff > 0 && currentTranslate > s.minTranslate()) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n      } else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n      }\n      if (disableParentSwiper) {\n        e.preventedByNestedSwiper = true;\n      }\n\n      // Directions locks\n      if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n        currentTranslate = startTranslate;\n      }\n      if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n        currentTranslate = startTranslate;\n      }\n\n      // Threshold\n      if (s.params.threshold > 0) {\n        if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n          if (!allowThresholdMove) {\n            allowThresholdMove = true;\n            s.touches.startX = s.touches.currentX;\n            s.touches.startY = s.touches.currentY;\n            currentTranslate = startTranslate;\n            s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n            return;\n          }\n        } else {\n          currentTranslate = startTranslate;\n          return;\n        }\n      }\n      if (!s.params.followFinger) return;\n\n      // Update active index in free mode\n      if (s.params.freeMode || s.params.watchSlidesProgress) {\n        s.updateActiveIndex();\n      }\n      if (s.params.freeMode) {\n        //Velocity\n        if (velocities.length === 0) {\n          velocities.push({\n            position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n            time: touchStartTime\n          });\n        }\n        velocities.push({\n          position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n          time: new window.Date().getTime()\n        });\n      }\n      // Update progress\n      s.updateProgress(currentTranslate);\n      // Update translate\n      s.setWrapperTranslate(currentTranslate);\n    };\n    s.onTouchEnd = function (e) {\n      if (e.originalEvent) e = e.originalEvent;\n      if (allowTouchCallbacks) {\n        s.emit('onTouchEnd', s, e);\n      }\n      allowTouchCallbacks = false;\n      if (!isTouched) return;\n      //Return Grab Cursor\n      if (s.params.grabCursor && isMoved && isTouched && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {\n        s.setGrabCursor(false);\n      }\n\n      // Time diff\n      var touchEndTime = Date.now();\n      var timeDiff = touchEndTime - touchStartTime;
1\n\n      // Tap, doubleTap, Click\n      if (s.allowClick) {\n        s.updateClickedSlide(e);\n        s.emit('onTap', s, e);\n        if (timeDiff < 300 && touchEndTime - lastClickTime > 300) {\n          if (clickTimeout) clearTimeout(clickTimeout);\n          clickTimeout = setTimeout(function () {\n            if (!s) return;\n            if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n              s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n            }\n            s.emit('onClick', s, e);\n          }, 300);\n        }\n        if (timeDiff < 300 && touchEndTime - lastClickTime < 300) {\n          if (clickTimeout) clearTimeout(clickTimeout);\n          s.emit('onDoubleTap', s, e);\n        }\n      }\n      lastClickTime = Date.now();\n      setTimeout(function () {\n        if (s) s.allowClick = true;\n      }, 0);\n      if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n        isTouched = isMoved = false;\n        return;\n      }\n      isTouched = isMoved = false;\n      var currentPos;\n      if (s.params.followFinger) {\n        currentPos = s.rtl ? s.translate : -s.translate;\n      } else {\n        currentPos = -currentTranslate;\n      }\n      if (s.params.freeMode) {\n        if (currentPos < -s.minTranslate()) {\n          s.slideTo(s.activeIndex);\n          return;\n        } else if (currentPos > -s.maxTranslate()) {\n          if (s.slides.length < s.snapGrid.length) {\n            s.slideTo(s.snapGrid.length - 1);\n          } else {\n            s.slideTo(s.slides.length - 1);\n          }\n          return;\n        }\n        if (s.params.freeModeMomentum) {\n          if (velocities.length > 1) {\n            var lastMoveEvent = velocities.pop(),\n              velocityEvent = velocities.pop();\n            var distance = lastMoveEvent.position - velocityEvent.position;\n            var time = lastMoveEvent.time - velocityEvent.time;\n            s.velocity = distance / time;\n            s.velocity = s.velocity / 2;\n            if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n              s.velocity = 0;\n            }\n            // this implies that the user stopped moving a finger then released.\n            // There would be no events with distance zero, so the last event is stale.\n            if (time > 150 || new window.Date().getTime() - lastMoveEvent.time > 300) {\n              s.velocity = 0;\n            }\n          } else {\n            s.velocity = 0;\n          }\n          s.velocity = s.velocity * s.params.freeModeMomentumVelocityRatio;\n          velocities.length = 0;\n          var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n          var momentumDistance = s.velocity * momentumDuration;\n          var newPosition = s.translate + momentumDistance;\n          if (s.rtl) newPosition = -newPosition;\n          var doBounce = false;\n          var afterBouncePosition;\n          var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n          if (newPosition < s.maxTranslate()) {\n            if (s.params.freeModeMomentumBounce) {\n              if (newPosition + s.maxTranslate() < -bounceAmount) {\n                newPosition = s.maxTranslate() - bounceAmount;\n              }\n              afterBouncePosition = s.maxTranslate();\n              doBounce = true;\n              allowMomentumBounce = true;\n            } else {\n              newPosition = s.maxTranslate();\n            }\n          } else if (newPosition > s.minTranslate()) {\n            if (s.params.freeModeMomentumBounce) {\n              if (newPosition - s.minTranslate() > bounceAmount) {\n                newPosition = s.minTranslate() + bounceAmount;\n              }\n              afterBouncePosition = s.minTranslate();\n              doBounce = true;\n              allowMomentumBounce = true;\n            } else {\n              newPosition = s.minTranslate();\n            }\n          } else if (s.params.freeModeSticky) {\n            var j = 0,\n              nextSlide;\n            for (j = 0; j < s.snapGrid.length; j += 1) {\n              if (s.snapGrid[j] > -newPosition) {\n                nextSlide = j;\n                break;\n              }\n            }\n            if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n              newPosition = s.snapGrid[nextSlide];\n            } else {\n              newPosition = s.snapGrid[nextSlide - 1];\n            }\n            if (!s.rtl) newPosition = -newPosition;\n          }\n          //Fix duration\n          if (s.velocity !== 0) {\n            if (s.rtl) {\n              momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n            } else {\n              momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n            }\n          } else if (s.params.freeModeSticky) {\n            s.slideReset();\n            return;\n          }\n          if (s.params.freeModeMomentumBounce && doBounce) {\n            s.updateProgress(afterBouncePosition);\n            s.setWrapperTransition(momentumDuration);\n            s.setWrapperTranslate(newPosition);\n            s.onTransitionStart();\n            s.animating = true;\n            s.wrapper.transitionEnd(function () {\n              if (!s || !allowMomentumBounce) return;\n              s.emit('onMomentumBounce', s);\n              s.setWrapperTransition(s.params.speed);\n              s.setWrapperTranslate(afterBouncePosition);\n              s.wrapper.transitionEnd(function () {\n                if (!s) return;\n                s.onTransitionEnd();\n              });\n            });\n          } else if (s.velocity) {\n            s.updateProgress(newPosition);\n            s.setWrapperTransition(momentumDuration);\n            s.setWrapperTranslate(newPosition);\n            s.onTransitionStart();\n            if (!s.animating) {\n              s.animating = true;\n              s.wrapper.transitionEnd(function () {\n                if (!s) return;\n                s.onTransitionEnd();\n              });\n            }\n          } else {\n            s.updateProgress(newPosition);\n          }\n          s.updateActiveIndex();\n        }\n        if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n          s.updateProgress();\n          s.updateActiveIndex();\n        }\n        return;\n      }\n\n      // Find current slide\n      var i,\n        stopIndex = 0,\n        groupSize = s.slidesSizesGrid[0];\n      for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n        if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n          if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n            stopIndex = i;\n            groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n          }\n        } else {\n          if (currentPos >= s.slidesGrid[i]) {\n            stopIndex = i;\n            groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n          }\n        }\n      }\n\n      // Find current slide size\n      var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n      if (timeDiff > s.params.longSwipesMs) {\n        // Long touches\n        if (!s.params.longSwipes) {\n          s.slideTo(s.activeIndex);\n          return;\n        }\n        if (s.swipeDirection === 'next') {\n          if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);else s.slideTo(stopIndex);\n        }\n        if (s.swipeDirection === 'prev') {\n          if (ratio > 1 - s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);else s.slideTo(stopIndex);\n        }\n      } else {\n        // Short swipes\n        if (!s.params.shortSwipes) {\n          s.slideTo(s.activeIndex);\n          return;\n        }\n        if (s.swipeDirection === 'next') {\n          s.slideTo(stopIndex + s.params.slidesPerGroup);\n        }\n        if (s.swipeDirection === 'prev') {\n          s.slideTo(stopIndex);\n        }\n      }\n    };\n    /*=========================\r\n      Transitions\r\n      ===========================*/\n    s._slideTo = function (slideIndex, speed) {\n      return s.slideTo(slideIndex, speed, true, true);\n    };\n    s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n      if (typeof runCallbacks === 'undefined') runCallbacks = true;\n      if (typeof slideIndex === 'undefined') slideIndex = 0;\n      if (slideIndex < 0) slideIndex = 0;\n      s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n      if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n      var translate = -s.snapGrid[s.snapIndex];\n      // Stop autoplay\n      if (s.params.autoplay && s.autoplaying) {\n        if (internal || !s.params.autoplayDisableOnInteraction) {\n          s.pauseAutoplay(speed);\n        } else {\n          s.stopAutoplay();\n        }\n      }\n      // Update progress\n      s.updateProgress(translate);\n\n      // Normalize slideIndex\n      if (s.params.normalizeSlideIndex) {\n        for (var i = 0; i < s.slidesGrid.length;
1 i++) {\n          if (-Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n            slideIndex = i;\n          }\n        }\n      }\n\n      // Directions locks\n      if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n        return false;\n      }\n      if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n        if ((s.activeIndex || 0) !== slideIndex) return false;\n      }\n\n      // Update Index\n      if (typeof speed === 'undefined') speed = s.params.speed;\n      s.previousIndex = s.activeIndex || 0;\n      s.activeIndex = slideIndex;\n      s.updateRealIndex();\n      if (s.rtl && -translate === s.translate || !s.rtl && translate === s.translate) {\n        // Update Height\n        if (s.params.autoHeight) {\n          s.updateAutoHeight();\n        }\n        s.updateClasses();\n        if (s.params.effect !== 'slide') {\n          s.setWrapperTranslate(translate);\n        }\n        return false;\n      }\n      s.updateClasses();\n      s.onTransitionStart(runCallbacks);\n      if (speed === 0 || s.browser.lteIE9) {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(0);\n        s.onTransitionEnd(runCallbacks);\n      } else {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(speed);\n        if (!s.animating) {\n          s.animating = true;\n          s.wrapper.transitionEnd(function () {\n            if (!s) return;\n            s.onTransitionEnd(runCallbacks);\n          });\n        }\n      }\n      return true;\n    };\n    s.onTransitionStart = function (runCallbacks) {\n      if (typeof runCallbacks === 'undefined') runCallbacks = true;\n      if (s.params.autoHeight) {\n        s.updateAutoHeight();\n      }\n      if (s.lazy) s.lazy.onTransitionStart();\n      if (runCallbacks) {\n        s.emit('onTransitionStart', s);\n        if (s.activeIndex !== s.previousIndex) {\n          s.emit('onSlideChangeStart', s);\n          if (s.activeIndex > s.previousIndex) {\n            s.emit('onSlideNextStart', s);\n          } else {\n            s.emit('onSlidePrevStart', s);\n          }\n        }\n      }\n    };\n    s.onTransitionEnd = function (runCallbacks) {\n      s.animating = false;\n      s.setWrapperTransition(0);\n      if (typeof runCallbacks === 'undefined') runCallbacks = true;\n      if (s.lazy) s.lazy.onTransitionEnd();\n      if (runCallbacks) {\n        s.emit('onTransitionEnd', s);\n        if (s.activeIndex !== s.previousIndex) {\n          s.emit('onSlideChangeEnd', s);\n          if (s.activeIndex > s.previousIndex) {\n            s.emit('onSlideNextEnd', s);\n          } else {\n            s.emit('onSlidePrevEnd', s);\n          }\n        }\n      }\n      if (s.params.history && s.history) {\n        s.history.setHistory(s.params.history, s.activeIndex);\n      }\n      if (s.params.hashnav && s.hashnav) {\n        s.hashnav.setHash();\n      }\n    };\n    s.slideNext = function (runCallbacks, speed, internal) {\n      if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n      } else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n    };\n    s._slideNext = function (speed) {\n      return s.slideNext(true, speed, true);\n    };\n    s.slidePrev = function (runCallbacks, speed, internal) {\n      if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n      } else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n    };\n    s._slidePrev = function (speed) {\n      return s.slidePrev(true, speed, true);\n    };\n    s.slideReset = function (runCallbacks, speed, internal) {\n      return s.slideTo(s.activeIndex, speed, runCallbacks);\n    };\n    s.disableTouchControl = function () {\n      s.params.onlyExternal = true;\n      return true;\n    };\n    s.enableTouchControl = function () {\n      s.params.onlyExternal = false;\n      return true;\n    };\n\n    /*=========================\r\n      Translate/transition helpers\r\n      ===========================*/\n    s.setWrapperTransition = function (duration, byController) {\n      s.wrapper.transition(duration);\n      if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTransition(duration);\n      }\n      if (s.params.parallax && s.parallax) {\n        s.parallax.setTransition(duration);\n      }\n      if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTransition(duration);\n      }\n      if (s.params.control && s.controller) {\n        s.controller.setTransition(duration, byController);\n      }\n      s.emit('onSetTransition', s, duration);\n    };\n    s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n      var x = 0,\n        y = 0,\n        z = 0;\n      if (s.isHorizontal()) {\n        x = s.rtl ? -translate : translate;\n      } else {\n        y = translate;\n      }\n      if (s.params.roundLengths) {\n        x = round(x);\n        y = round(y);\n      }\n      if (!s.params.virtualTranslate) {\n        if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n      }\n      s.translate = s.isHorizontal() ? x : y;\n\n      // Check if we need to update progress\n      var progress;\n      var translatesDiff = s.maxTranslate() - s.minTranslate();\n      if (translatesDiff === 0) {\n        progress = 0;\n      } else {\n        progress = (translate - s.minTranslate()) / translatesDiff;\n      }\n      if (progress !== s.progress) {\n        s.updateProgress(translate);\n      }\n      if (updateActiveIndex) s.updateActiveIndex();\n      if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTranslate(s.translate);\n      }\n      if (s.params.parallax && s.parallax) {\n        s.parallax.setTranslate(s.translate);\n      }\n      if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTranslate(s.translate);\n      }\n      if (s.params.control && s.controller) {\n        s.controller.setTranslate(s.translate, byController);\n      }\n      s.emit('onSetTranslate', s, s.translate);\n    };\n    s.getTranslate = function (el, axis) {\n      var matrix, curTransform, curStyle, transformMatrix;\n\n      // automatic axis detection\n      if (typeof axis === 'undefined') {\n        axis = 'x';\n      }\n      if (s.params.virtualTranslate) {\n        return s.rtl ? -s.translate : s.translate;\n      }\n      curStyle = window.getComputedStyle(el, null);\n      if (window.WebKitCSSMatrix) {\n        curTransform = curStyle.transform || curStyle.webkitTransform;\n        if (curTransform.split(',').length > 6) {\n          curTransform = curTransform.split(', ').map(function (a) {\n            return a.replace(',', '.');\n          }).join(', ');\n        }\n        // Some old versions of Webkit choke when 'none' is passed; pass\n        // empty string instead in this case\n        transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n      } else {\n        transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n        matrix = transformMatrix.toString().split(',');\n      }\n      if (axis === 'x') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);\n        //Normal Browsers\n        else curTransform = parseFloat(matrix[4]);\n      }\n      if (axis === 'y') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);\n        //Normal Browsers\n        else curTransform = parseFloat(matrix[5]);\n      }\n      if (s.rtl && curTransform) curTransform = -curTransform;\n      return curTransform || 0;\n    };\n    s.getWrapperTranslate = function (axis) {\n      if (typeof axis === 'undefined') {\n        axis = s.isHorizontal() ? 'x' : 'y';
1\n      }\n      return s.getTranslate(s.wrapper[0], axis);\n    };\n\n    /*=========================\r\n      Observer\r\n      ===========================*/\n    s.observers = [];\n    function initObserver(target, options) {\n      options = options || {};\n      // create an observer instance\n      var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n      var observer = new ObserverFunc(function (mutations) {\n        mutations.forEach(function (mutation) {\n          s.onResize(true);\n          s.emit('onObserverUpdate', s, mutation);\n        });\n      });\n      observer.observe(target, {\n        attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n        childList: typeof options.childList === 'undefined' ? true : options.childList,\n        characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n      });\n      s.observers.push(observer);\n    }\n    s.initObservers = function () {\n      if (s.params.observeParents) {\n        var containerParents = s.container.parents();\n        for (var i = 0; i < containerParents.length; i++) {\n          initObserver(containerParents[i]);\n        }\n      }
1\n\n      // Observe container\n      initObserver(s.container[0], {\n        childList: false\n      });\n\n      // Observe wrapper\n      initObserver(s.wrapper[0], {\n        attributes: false\n      });\n    };\n    s.disconnectObservers = function () {\n      for (var i = 0; i < s.observers.length; i++) {\n        s.observers[i].disconnect();\n      }\n      s.observers = [];\n    };\n    /*=========================\r\n      Loop\r\n      ===========================*/\n    // Create looped slides\n    s.createLoop = function () {\n      // Remove duplicated slides\n      s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n      var slides = s.wrapper.children('.' + s.params.slideClass);\n      if (s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n      s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n      s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n      if (s.loopedSlides > slides.length) {\n        s.loopedSlides = slides.length;\n      }\n      var prependSlides = [],\n        appendSlides = [],\n        i;\n      slides.each(function (index, el) {\n        var slide = $(this);\n        if (index < s.loopedSlides) appendSlides.push(el);\n        if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n        slide.attr('data-swiper-slide-index', index);\n      });\n      for (i = 0; i < appendSlides.length; i++) {\n        s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n      }\n      for (i = prependSlides.length - 1; i >= 0; i--) {\n        s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n      }\n    };\n    s.destroyLoop = function () {\n      s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n      s.slides.removeAttr('data-swiper-slide-index');\n    };\n    s.reLoop = function (updatePosition) {\n      var oldIndex = s.activeIndex - s.loopedSlides;\n      s.destroyLoop();\n      s.createLoop();\n      s.updateSlidesSize();\n      if (updatePosition) {\n        s.slideTo(oldIndex + s.loopedSlides, 0, false);\n      }\n    };\n    s.fixLoop = function () {\n      var newIndex;\n      //Fix For Negative Oversliding\n      if (s.activeIndex < s.loopedSlides) {\n        newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n      }\n      //Fix For Positive Oversliding\n      else if (s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2 || s.activeIndex > s.slides.length - s.params.slidesPerView * 2) {\n        newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n      }\n    };\n    /*=========================\r\n      Append/Prepend/Remove Slides\r\n      ===========================*/\n    s.appendSlide = function (slides) {\n      if (s.params.loop) {\n        s.destroyLoop();\n      }\n      if (_typeof(slides) === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n          if (slides[i]) s.wrapper.append(slides[i]);\n        }\n      } else {\n        s.wrapper.append(slides);\n      }\n      if (s.params.loop) {\n        s.createLoop();\n      }\n      if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n      }\n    };\n    s.prependSlide = function (slides) {\n      if (s.params.loop) {\n        s.destroyLoop();\n      }\n      var newActiveIndex = s.activeIndex + 1;\n      if (_typeof(slides) === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n          if (slides[i]) s.wrapper.prepend(slides[i]);\n        }\n        newActiveIndex = s.activeIndex + slides.length;\n      } else {\n        s.wrapper.prepend(slides);\n      }\n      if (s.params.loop) {\n        s.createLoop();\n      }\n      if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n      }\n      s.slideTo(newActiveIndex, 0, false);\n    };\n    s.removeSlide = function (slidesIndexes) {\n      if (s.params.loop) {\n        s.destroyLoop();\n        s.slides = s.wrapper.children('.' + s.params.slideClass);\n      }\n      var newActiveIndex = s.activeIndex,\n        indexToRemove;\n      if (_typeof(slidesIndexes) === 'object' && slidesIndexes.length) {\n        for (var i = 0; i < slidesIndexes.length;
1 i++) {\n          indexToRemove = slidesIndexes[i];\n          if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n          if (indexToRemove < newActiveIndex) newActiveIndex--;\n        }\n        newActiveIndex = Math.max(newActiveIndex, 0);\n      } else {\n        indexToRemove = slidesIndexes;\n        if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n        if (indexToRemove < newActiveIndex) newActiveIndex--;\n        newActiveIndex = Math.max(newActiveIndex, 0);\n      }\n      if (s.params.loop) {\n        s.createLoop();\n      }\n      if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n      }\n      if (s.params.loop) {\n        s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n      } else {\n        s.slideTo(newActiveIndex, 0, false);\n      }\n    };\n    s.removeAllSlides = function () {\n      var slidesIndexes = [];\n      for (var i = 0; i < s.slides.length; i++) {\n        slidesIndexes.push(i);\n      }\n      s.removeSlide(sli
1desIndexes);\n    };\n\n    /*=========================\r\n      Effects\r\n      ===========================*/\n    s.effects = {\n      fade: {\n        setTranslate: function setTranslate() {\n          for (var i = 0; i < s.slides.length; i++) {\n            var slide = s.slides.eq(i);\n            var offset = slide[0].swiperSlideOffset;\n            var tx = -offset;\n            if (!s.params.virtualTranslate) tx = tx - s.translate;\n            var ty = 0;\n            if (!s.isHorizontal()) {\n              ty = tx;\n              tx = 0;\n            }\n            var slideOpacity = s.params.fade.crossFade ? Math.max(1 - Math.abs(slide[0].progress), 0) : 1 + Math.min(Math.max(slide[0].progress, -1), 0);\n            slide.css({\n              opacity: slideOpacity\n            }).transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n          }\n        },\n        setTransition: function setTransition(duration) {\n          s.slides.transition(duration);\n          if (s.params.virtualTranslate && duration !== 0) {\n            var eventTriggered = false;\n            s.slides.transitionEnd(function () {\n              if (eventTriggered) return;\n              if (!s) return;\n              eventTriggered = true;\n              s.animating = false;\n              var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n              for (var i = 0; i < triggerEvents.length; i++) {\n                s.wrapper.trigger(triggerEvents[i]);\n              }\n            });\n          }\n        }\n      },\n      flip: {\n        setTranslate: function setTranslate() {\n          for (var i = 0; i < s.slides.length; i++) {\n            var slide = s.slides.eq(i);\n            var progress = slide[0].progress;\n            if (s.params.flip.limitRotation) {\n              progress = Math.max(Math.min(slide[0].progress, 1), -1);\n            }\n            var offset = slide[0].swiperSlideOffset;\n            var rotate = -180 * progress,\n              rotateY = rotate,\n              rotateX = 0,\n              tx = -offset,\n              ty = 0;\n            if (!s.isHorizontal()) {\n              ty = tx;\n              tx = 0;\n              rotateX = -rotateY;\n              rotateY = 0;\n            } else if (s.rtl) {\n              rotateY = -rotateY;\n            }\n            slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n            if (s.params.flip.slideShadows) {\n              //Set shadows\n              var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n              var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n              if (shadowBefore.length === 0) {\n                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                slide.append(shadowBefore);\n              }\n              if (shadowAfter.length === 0) {\n                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                slide.append(shadowAfter);\n              }\n              if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n              if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n            }\n            slide.transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n          }\n        },\n        setTransition: function setTransition(duration) {\n          s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n          if (s.params.virtualTranslate && duration !== 0) {\n            var eventTriggered = false;\n            s.slides.eq(s.activeIndex).transitionEnd(function () {\n              if (eventTriggered) return;\n              if (!s) return;\n              if (!$(this).hasClass(s.params.slideActiveClass)) return;\n              eventTriggered = true;\n              s.animating = false;
1\n              var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n              for (var i = 0; i < triggerEvents.length; i++) {\n                s.wrapper.trigger(triggerEvents[i]);\n              }\n            });\n          }\n        }\n      },\n      cube: {\n        setTranslate: function setTranslate() {\n          var wrapperRotate = 0,\n            cubeShadow;\n          if (s.params.cube.shadow) {\n            if (s.isHorizontal()) {\n              cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n              if (cubeShadow.length === 0) {\n                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                s.wrapper.append(cubeShadow);\n              }\n              cubeShadow.css({\n                height: s.width + 'px'\n              });\n            } else {\n              cubeShadow = s.container.find('.swiper-cube-shadow');\n              if (cubeShadow.length === 0) {\n                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                s.container.append(cubeShadow);\n              }\n            }\n          }\n          for (var i = 0; i < s.slides.length; i++) {\n            var slide = s.slides.eq(i);\n            var slideAngle = i * 90;\n            var round = Math.floor(slideAngle / 360);\n            if (s.rtl) {\n              slideAngle = -slideAngle;\n              round = Math.floor(-slideAngle / 360);\n            }\n            var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n            var tx = 0,\n              ty = 0,\n              tz = 0;\n            if (i % 4 === 0) {\n              tx = -round * 4 * s.size;\n              tz = 0;\n            } else if ((i - 1) % 4 === 0) {\n              tx = 0;\n              tz = -round * 4 * s.size;\n            } else if ((i - 2) % 4 === 0) {\n              tx = s.size + round * 4 * s.size;\n              tz = s.size;\n            } else if ((i - 3) % 4 === 0) {\n              tx = -s.size;\n              tz = 3 * s.size + s.size * 4 * round;\n            }\n            if (s.rtl) {\n              tx = -tx;\n            }\n            if (!s.isHorizontal()) {\n              ty = tx;\n              tx = 0;\n            }\n            var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n            if (progress <= 1 && progress > -1) {\n              wrapperRotate = i * 90 + progress * 90;\n              if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n            }\n            slide.transform(transform);\n            if (s.params.cube.slideShadows) {\n              //Set shadows\n              var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n              var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n              if (shadowBefore.length === 0) {\n                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                slide.append(shadowBefore);\n              }\n              if (shadowAfter.length === 0) {\n                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                slide.append(shadowAfter);\n              }\n              if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n              if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n            }\n          }\n          s.wrapper.css({\n            '-webkit-transform-origin': '50% 50% -' + s.size / 2 + 'px',\n            '-moz-transform-origin': '50% 50% -' + s.size / 2 + 'px',\n            '-ms-transform-origin': '50% 50% -' + s.size / 2 + 'px',\n            'transform-origin': '50% 50% -' + s.size / 2 + 'px'\n          });\n          if (s.params.cube.shadow) {\n            if (s.isHorizontal()) {\n              cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + -s.width / 2 + 'px) rotateX(90deg) rotateZ(0deg) scale(' + s.params.cube.shadowScale + ')');\n            } else {\n              var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n              var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n              var scale1 = s.params.cube.shadowScale,\n                scale2 = s.params.cube.shadowScale / multiplier,\n                offset = s.params.cube.shadowOffset;\n              cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + -s.height / 2 / scale2 + 'px) rotateX(-90deg)');\n            }\n          }\n          var zFactor = s.isSafari || s.isUiWebView ? -s.size / 2 : 0;\n          s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n        },\n        setTransition: function setTransition(duration) {\n          s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n          if (s.params.cube.shadow && !s.isHorizontal()) {\n            s.container.find('.swiper-cube-shadow').transition(duration);\n          }\n        }\n      },\n      coverflow: {\n        setTranslate: function setTranslate() {\n          var transform = s.translate;\n          var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n          var rotate = s.isHorizontal() ? s.params.coverflow.rotate : -s.params.coverflow.rotate;\n          var translate = s.params.coverflow.depth;\n          //Each slide offset from center\n          for (var i = 0, length = s.slides.length; i < length;
1 i++) {\n            var slide = s.slides.eq(i);\n            var slideSize = s.slidesSizesGrid[i];\n            var slideOffset = slide[0].swiperSlideOffset;\n            var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n            var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n            var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n            // var rotateZ = 0\n            var translateZ = -translate * Math.abs(offsetMultiplier);\n            var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * offsetMultiplier;\n            var translateX = s.isHorizontal() ? s.params.coverflow.stretch * offsetMultiplier : 0;\n\n            //Fix for ultra small values\n            if (Math.abs(translateX) < 0.001) translateX = 0;\n            if (Math.abs(translateY) < 0.001) translateY = 0;\n            if (Math.abs(translateZ) < 0.001) translateZ = 0;\n            if (Math.abs(rotateY) < 0.001) rotateY = 0;\n            if (Math.abs(rotateX) < 0.001) rotateX = 0;\n            var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n            slide.transform(slideTransform);\n            slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n            if (s.params.coverflow.slideShadows) {\n              //Set shadows\n              var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n              var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n              if (shadowBefore.length === 0) {\n                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                slide.append(shadowBefore);\n              }\n              if (shadowAfter.length === 0) {\n                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                slide.append(shadowAfter);\n              }\n              if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n              if (shadowAfter.length) shadowAfter[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;\n            }\n          }\n\n          //Set correct perspective for IE10\n          if (s.browser.ie) {\n            var ws = s.wrapper[0].style;\n            ws.perspectiveOrigin = center + 'px 50%';\n          }\n        },\n        setTransition: function setTransition(duration) {\n          s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n        }\n      }\n    };\n\n    /*=========================\r\n      Images Lazy Loading\r\n      ===========================*/\n    s.lazy = {\n      initialImageLoaded: false,\n      loadImageInSlide: function loadImageInSlide(index, loadInDuplicate) {\n        if (typeof index === 'undefined') return;\n        if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n        if (s.slides.length === 0) return;\n        var slide = s.slides.eq(index);\n        var img = slide.find('.' + s.params.lazyLoadingClass + ':not(.' + s.params.lazyStatusLoadedClass + '):not(.' + s.params.lazyStatusLoadingClass + ')');\n        if (slide.hasClass(s.params.lazyLoadingClass) && !slide.hasClass(s.params.lazyStatusLoadedClass) && !slide.hasClass(s.params.lazyStatusLoadingClass)) {\n          img = img.add(slide[0]);\n        }\n        if (img.length === 0) return;\n        img.each(function () {\n          var _img = $(this);\n          _img.addClass(s.params.lazyStatusLoadingClass);\n          var background = _img.attr('data-background');\n          var src = _img.attr('data-src'),\n            srcset = _img.attr('data-srcset'),\n            sizes = _img.attr('data-sizes');\n          s.loadImage(_img[0], src || background, srcset, sizes, false, function () {\n            if (typeof s === 'undefined' || s === null || !s) return;\n            if (background) {\n              _img.css('background-image', 'url(\"' + background + '\")');\n              _img.removeAttr('data-background');\n            } else {\n              if (srcset) {\n                _img.attr('srcset', srcset);\n                _img.removeAttr('data-srcset');\n              }\n              if (sizes) {\n                _img.attr('sizes', sizes);\n                _img.removeAttr('data-sizes');\n              }\n              if (src) {\n                _img.attr('src', src);\n                _img.removeAttr('data-src');\n              }\n            }\n            _img.addClass(s.params.lazyStatusLoadedClass).removeClass(s.params.lazyStatusLoadingClass);\n            slide.find('.' + s.params.lazyPreloaderClass + ', .' + s.params.preloaderClass).remove();
1\n            if (s.params.loop && loadInDuplicate) {\n              var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n              if (slide.hasClass(s.params.slideDuplicateClass)) {\n                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                s.lazy.loadImageInSlide(originalSlide.index(), false);\n              } else {\n                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n              }\n            }\n            s.emit('onLazyImageReady', s, slide[0], _img[0]);\n          });\n          s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n        });\n      },\n      load: function load() {\n        var i;\n        var slidesPerView = s.params.slidesPerView;\n        if (slidesPerView === 'auto') {\n          slidesPerView = 0;\n        }\n        if (!s.lazy.initialImageLoaded) s.lazy.initialImageLoaded = true;\n        if (s.params.watchSlidesVisibility) {\n          s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n            s.lazy.loadImageInSlide($(this).index());\n          });\n        } else {\n          if (slidesPerView > 1) {\n            for (i = s.activeIndex; i < s.activeIndex + slidesPerView; i++) {\n              if (s.slides[i]) s.lazy.loadImageInSlide(i);\n            }\n          } else {\n            s.lazy.loadImageInSlide(s.activeIndex);\n          }\n        }\n        if (s.params.lazyLoadingInPrevNext) {\n          if (slidesPerView > 1 || s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1) {\n            var amount = s.params.lazyLoadingInPrevNextAmount;\n            var spv = slidesPerView;\n            var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n            var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n            // Next Slides\n            for (i = s.activeIndex + slidesPerView; i < maxIndex; i++) {\n              if (s.slides[i]) s.lazy.loadImageInSlide(i);\n            }\n            // Prev Slides\n            for (i = minIndex; i < s.activeIndex; i++) {\n              if (s.slides[i]) s.lazy.loadImageInSlide(i);\n            }\n          } else {\n            var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n            if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n            var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n            if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n          }\n        }\n      },\n      onTransitionStart: function onTransitionStart() {\n        if (s.params.lazyLoading) {\n          if (s.params.lazyLoadingOnTransitionStart || !s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded) {\n            s.lazy.load();\n          }\n        }\n      },\n      onTransitionEnd: function onTransitionEnd() {\n        if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n          s.lazy.load();\n        }\n      }\n    };\n\n    /*=========================\r\n      Scrollbar\r\n      ===========================*/\n    s.scrollbar = {\n      isTouched: false,\n      setDragPosition: function setDragPosition(e) {\n        var sb = s.scrollbar;\n        var x = 0,\n          y = 0;\n        var translate;\n        var pointerPosition = s.isHorizontal() ? s.getTouchEventX(e) : s.getTouchEventY(e);\n        var position = pointerPosition - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n        var positionMin = -s.minTranslate() * sb.moveDivider;\n        var positionMax = -s.maxTranslate() * sb.moveDivider;\n        if (position < positionMin) {\n          position = positionMin;\n        } else if (position > positionMax) {\n          position = positionMax;\n        }\n        position = -position / sb.moveDivider;\n        s.updateProgress(position);\n        s.setWrapperTranslate(position, true);\n      },\n      dragStart: function dragStart(e) {\n        var sb = s.scrollbar;\n        sb.isTouched = true;\n        e.preventDefault();\n        e.stopPropagation();\n        sb.setDragPosition(e);\n        clearTimeout(sb.dragTimeout);\n        sb.track.transition(0);\n        if (s.params.scrollbarHide) {\n          sb.track.css('opacity', 1);\n        }\n        s.wrapper.transition(100);\n        sb.drag.transition(100);\n        s.emit('onScrollbarDragStart', s);\n      },\n      dragMove: function dragMove(e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n        sb.setDragPosition(e);\n        s.wrapper.transition(0);\n        sb.track.transition(0);\n        sb.drag.transition(0);\n        s.emit('onScrollbarDragMove', s);\n      },\n      dragEnd: function dragEnd(e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        sb.isTouched = false;\n        if (s.params.scrollbarHide) {\n          clearTimeout(sb.dragTimeout);\n          sb.dragTimeout = setTimeout(function () {\n            sb.track.css('opacity', 0);\n            sb.track.transition(400);\n          }, 1000);\n        }\n        s.emit('onScrollbarDragEnd', s);\n        if (s.params.scrollbarSnapOnRelease) {\n          s.slideReset();\n        }\n      },\n      draggableEvents: function () {\n        if (s.params.simulateTouch === false && !s.support.touch) return s.touchEventsDesktop;else return s.touchEvents;\n      }(),\n      enableDraggable: function enableDraggable() {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).on(sb.draggableEvents.start, sb.dragStart);\n        $(target).on(sb.draggableEvents.move, sb.dragMove);\n        $(target).on(sb.draggableEvents.end, sb.dragEnd);\n      },\n      disableDraggable: function disableDraggable() {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).off(sb.draggableEvents.start, sb.dragStart);\n        $(target).off(sb.draggableEvents.move, sb.dragMove);\n        $(target).off(sb.draggableEvents.end, sb.dragEnd);\n      },\n      set: function set() {\n        if (!s.params.scrollbar) return;\n        var sb = s.scrollbar;\n        sb.track = $(s.params.scrollbar);\n        if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n          sb.track = s.container.find(s.params.scrollbar);\n        }\n        sb.drag = sb.track.find('.swiper-scrollbar-drag');\n        if (sb.drag.length === 0) {\n          sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n          sb.track.append(sb.drag);\n        }\n        sb.drag[0].style.width = '';\n        sb.drag[0].style.height = '';\n        sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        sb.divider = s.size / s.virtualSize;\n        sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n        sb.dragSize = sb.trackSize * sb.divider;\n        if (s.isHorizontal()) {\n          sb.drag[0].style.width = sb.dragSize + 'px';\n        } else {\n          sb.drag[0].style.height = sb.dragSize + 'px';\n        }\n        if (sb.divider >= 1) {\n          sb.track[0].style.display = 'none';\n        } else {\n          sb.track[0].style.display = '';\n        }\n        if (s.params.scrollbarHide) {\n          sb.track[0].style.opacity = 0;\n        }\n      },\n      setTranslate: function setTranslate() {\n        if (!s.params.scrollbar) return;\n        var diff;\n        var sb = s.scrollbar;\n        var translate = s.translate || 0;\n        var newPos;\n        var newSize = sb.dragSize;\n        newPos = (sb.trackSize - sb.dragSize) * s.progress;\n        if (s.rtl && s.isHorizontal()) {\n          newPos = -newPos;\n          if (newPos > 0) {\n            newSize = sb.dragSize - newPos;\n            newPos = 0;\n          } else if (-newPos + sb.dragSize > sb.trackSize) {\n            newSize = sb.trackSize + newPos;\n          }\n        } else {\n          if (newPos < 0) {\n            newSize = sb.dragSize + newPos;\n            newPos = 0;\n          } else if (newPos + sb.dragSize > sb.trackSize) {\n            newSize = sb.trackSize - newPos;\n          }\n        }\n        if (s.isHorizontal()) {\n          if (s.support.transforms3d) {\n            sb.drag.transform('translate3d(' + newPos + 'px, 0, 0)');\n          } else {\n            sb.drag.transform('translateX(' + newPos + 'px)');\n          }\n          sb.drag[0].style.width = newSize + 'px';\n        } else {\n          if (s.support.transforms3d) {\n            sb.drag.transform('translate3d(0px, ' + newPos + 'px, 0)');\n          } else {\n            sb.drag.transform('translateY(' + newPos + 'px)');\n          }\n          sb.drag[0].style.height = newSize + 'px';\n        }\n        if (s.params.scrollbarHide) {\n          clearTimeout(sb.timeout);\n          sb.track[0].style.opacity = 1;\n          sb.timeout = setTimeout(function () {\n            sb.track[0].style.opacity = 0;\n            sb.track.transition(400);\n          }, 1000);\n        }\n      },\n      setTransition: function setTransition(duration) {\n        if (!s.params.scrollbar) return;\n        s.scrollbar.drag.transition(duration);\n      }\n    };\n\n    /*=========================\r\n      Controller\r\n      ===========================*/\n    s.controller = {\n      LinearSpline: function LinearSpline(x, y) {\n        var binarySearch = function () {\n          var maxIndex, minIndex, guess;\n          return function (array, val) {\n            minIndex = -1;\n            maxIndex = array.length;\n            while (maxIndex - minIndex >
1 1) if (array[guess = maxIndex + minIndex >> 1] <= val) {\n              minIndex = guess;\n            } else {\n              maxIndex = guess;\n            }\n            return maxIndex;\n          };\n        }();\n        this.x = x;\n        this.y = y;\n        this.lastIndex = x.length - 1;\n        // Given an x value (x2), return the expected y2 value:\n        // (x1,y1) is the known point before given value,\n        // (x3,y3) is the known point after given value.\n        var i1, i3;\n        var l = this.x.length;\n        this.interpolate = function (x2) {\n          if (!x2) return 0;\n\n          // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n          i3 = binarySearch(this.x, x2);\n          i1 = i3 - 1;\n\n          // We have our indexes i1 & i3, so we can calculate already:\n          // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n          return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];\n        };\n      },\n      //xxx: for now i will just save one spline function to to\n      getInterpolateFunction: function getInterpolateFunction(c) {\n        if (!s.controller.spline) s.controller.spline = s.params.loop ? new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) : new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n      },\n      setTranslate: function setTranslate(translate, byController) {\n        var controlled = s.params.control;\n        var multiplier, controlledTranslate;\n        function setControlledTranslate(c) {\n          // this will create an Interpolate function based on the snapGrids\n          // x is the Grid of the scrolled scroller and y will be the controlled scroller\n          // it makes sense to create this only once and recall it for the interpolation\n          // the function does a lot of value caching for performance\n          translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n          if (s.params.controlBy === 'slide') {\n            s.controller.getInterpolateFunction(c);\n            // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n            // but it did not work out\n            controlledTranslate = -s.controller.spline.interpolate(-translate);\n          }\n          if (!controlledTranslate || s.params.controlBy === 'container') {\n            multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n            controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n          }\n          if (s.params.controlInverse) {\n            controlledTranslate = c.maxTranslate() - controlledTranslate;\n          }\n          c.updateProgress(controlledTranslate);\n          c.setWrapperTranslate(controlledTranslate, false, s);\n          c.updateActiveIndex();\n        }\n        if (Array.isArray(controlled)) {\n          for (var i = 0; i < controlled.length; i++) {\n            if (controlled[i] !== byController && controlled[i] instanceof _Swiper) {\n              setControlledTranslate(controlled[i]);\n            }\n          }\n        } else if (controlled instanceof _Swiper && byController !== controlled) {\n          setControlledTranslate(controlled);\n        }\n      },\n      setTransition: function setTransition(duration, byController) {\n        var controlled = s.params.control;\n        var i;\n        function setControlledTransition(c) {\n          c.setWrapperTransition(duration, s);\n          if (duration !== 0) {\n            c.onTransitionStart();\n            c.wrapper.transitionEnd(function () {\n              if (!controlled) return;\n              if (c.params.loop && s.params.controlBy === 'slide') {\n                c.fixLoop();\n              }\n              c.onTransitionEnd();\n            });\n          }\n        }\n        if (Array.isArray(controlled)) {\n          for (i = 0; i < controlled.length; i++) {\n            if (controlled[i] !== byController && controlled[i] instanceof _Swiper) {\n              setControlledTransition(controlled[i]);\n            }\n          }\n        } else if (controlled instanceof _Swiper && byController !== controlled) {\n          setControlledTransition(controlled);\n        }\n      }\n    };\n\n    /*=========================\r\n      Hash Navigation\r\n      ===========================*/\n    s.hashnav = {\
1n      onHashCange: function onHashCange(e, a) {\n        var newHash = document.location.hash.replace('#', '');\n        var activeSlideHash = s.slides.eq(s.activeIndex).attr('data-hash');\n        if (newHash !== activeSlideHash) {\n          s.slideTo(s.wrapper.children('.' + s.params.slideClass + '[data-hash=\"' + newHash + '\"]').index());\n        }\n      },\n      attachEvents: function attachEvents(detach) {\n        var action = detach ? 'off' : 'on';\n        $(window)[action]('hashchange', s.hashnav.onHashCange);\n      },\n      setHash: function setHash() {\n        if (!s.hashnav.initialized || !s.params.hashnav) return;\n        if (s.params.replaceState && window.history && window.history.replaceState) {\n          window.history.replaceState(null, null, '#' + s.slides.eq(s.activeIndex).attr('data-hash') || '');\n        } else {\n          var slide = s.slides.eq(s.activeIndex);\n          var hash = slide.attr('data-hash') || slide.attr('data-history');\n          document.location.hash = hash || '';\n        }\n      },\n      init: function init() {\n        if (!s.params.hashnav || s.params.history) return;\n        s.hashnav.initialized = true;\n        var hash = document.location.hash.replace('#', '');\n        if (hash) {\n          var speed = 0;\n          for (var i = 0, length = s.slides.length; i < length; i++) {\n            var slide = s.slides.eq(i);\n            var slideHash = slide.attr('data-hash') || slide.attr('data-history');\n            if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n              var index = slide.index();\n              s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n            }\n          }\n        }\n        if (s.params.hashnavWatchState) s.hashnav.attachEvents();\n      },\n      destroy: function destroy() {\n        if (s.params.hashnavWatchState) s.hashnav.attachEvents(true);\n      }\n    };\n\n    /*=========================\r\n      History Api with fallback to Hashnav\r\n      ===========================*/\n    s.history = {\n      init: function init() {\n        if (!s.params.history) return;\n        if (!window.history || !window.history.pushState) {\n          s.params.history = false;\n          s.params.hashnav = true;\n          return;\n        }\n        s.history.initialized = true;\n        this.paths = this.getPathValues();\n        if (!this.paths.key && !this.paths.value) return;\n        this.scrollToSlide(0, this.paths.value, s.params.runCallbacksOnInit);\n        if (!s.params.replaceState) {\n          window.addEventListener('popstate', this.setHistoryPopState);\n        }\n      },\n      setHistoryPopState: function setHistoryPopState() {\n        s.history.paths = s.history.getPathValues();\n        s.history.scrollToSlide(s.params.speed, s.history.paths.value, false);\n      },\n      getPathValues: function getPathValues() {\n        var pathArray = window.location.pathname.slice(1).split('/');\n        var total = pathArray.length;\n        var key = pathArray[total - 2];\n        var value = pathArray[total - 1];\n        return {\n          key: key,\n          value: value\n        };\n      },\n      setHistory: function setHistory(key, index) {\n        if (!s.history.initialized || !s.params.history) return;\n        var slide = s.slides.eq(index);\n        var value = this.slugify(slide.attr('data-history'));\n        if (!window.location.pathname.includes(key)) {\n          value = key + '/' + value;\n        }\n        if (s.params.replaceState) {\n          window.history.replaceState(null, null, value);\n        } else {\n          window.history.pushState(null, null, value);\n        }\n      },\n      slugify: function slugify(text) {\n        return text.toString().toLowerCase().replace(/\\s+/g, '-').replace(/[^\\w\\-]+/g, '').replace(/\\-\\-+/g, '-').replace(/^-+/, '').replace(/-+$/, '');\n      },\n      scrollToSlide: function scrollToSlide(speed, value, runCallbacks) {\n        if (value) {\n          for (var i = 0, length = s.slides.length; i < length; i++) {\n            var slide = s.slides.eq(i);\n            var slideHistory = this.slugify(slide.attr('data-history'));\n            if (slideHistory === value && !slide.hasClass(s.params.slideDuplicateClass)) {\n              var index = slide.index();\n              s.slideTo(index, speed, runCallbacks);\n            }\n          }\n        } else {\n          s.slideTo(0, speed, runCallbacks);\n        }\n      }\n    };\n\n    /*=========================\r\n      Keyboard Control\r\n      ===========================*/\n    function handleKeyboard(e) {\n      if (e.originalEvent) e = e.originalEvent; //jquery fix\n      var kc = e.keyCode || e.charCode;\n      // Directions locks\n      if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n        return false;\n      }\n      if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n        return false;\n      }\n      if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n        return;\n      }\n      if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n        return;\n      }\n      if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n        var inView = false;\n        //Check that swiper should be inside of visible area of window\n        if (s.container.parents('.' + s.params.slideClass).length > 0 && s.container.parents('.' + s.params.slideActiveClass).length === 0) {\n          return;\n        }\n        var windowScroll = {\n          left: window.pageXOffset,\n          top: window.pageYOffset\n        };\n        var windowWidth = window.innerWidth;\n        var windowHeight = window.innerHeight;\n        var swiperOffset = s.container.offset();\n        if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n        var swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + s.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + s.height], [swiperOffset.left + s.width, swiperOffset.top + s.height]];\n        for (var i = 0; i < swiperCoord.length;
1 i++) {\n          var point = swiperCoord[i];\n          if (point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth && point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight) {\n            inView = true;\n          }\n        }\n        if (!inView) return;\n      }\n      if (s.isHorizontal()) {\n        if (kc === 37 || kc === 39) {\n          if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n        }\n        if (kc === 39 && !s.rtl || kc === 37 && s.rtl) s.slideNext();\n        if (kc === 37 && !s.rtl || kc === 39 && s.rtl) s.slidePrev();\n      } else {\n        if (kc === 38 || kc === 40) {\n          if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n        }\n        if (kc === 40) s.slideNext();\n        if (kc === 38) s.slidePrev();\n      }\n      s.emit('onKeyPress', s, kc);\n    }\n    s.disableKeyboardControl = function () {\n      s.params.keyboardControl = false;\n      $(document).off('keydown', handleKeyboard);\n    };\n    s.enableKeyboardControl = function () {\n      s.params.keyboardControl = true;\n      $(document).on('keydown', handleKeyboard);\n    };\n\n    /*=========================\r\n      Mousewheel Control\r\n      ===========================*/\n    s.mousewheel = {\n      event: false,\n      lastScrollTime: new window.Date().getTime()\n    };\n    function isEventSupported() {\n      var eventName = 'onwheel';\n      var isSupported = eventName in document;\n      if (!isSupported) {\n        var element = document.createElement('div');\n        element.setAttribute(eventName, 'return;');\n        isSupported = typeof element[eventName] === 'function';\n      }\n      if (!isSupported && document.implementation && document.implementation.hasFeature &&\n      // always returns true in newer browsers as per the standard.\n      // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n      document.implementation.hasFeature('', '') !== true) {\n        // This is the only way to test support for the `wheel` event in IE9+.\n        isSupported = document.implementation.hasFeature('Events.wheel', '3.0');\n      }\n      return isSupported;\n    }\n    /**\r\n     * Mouse wheel (and 2-finger trackpad) support on the web sucks.  It is\r\n     * complicated, thus this doc is long and (hopefully) detailed enough to answer\r\n     * your questions.\r\n     *\r\n     * If you need to react to the mouse wheel in a predictable way, this code is\r\n     * like your bestest friend. * hugs *\r\n     *\r\n     * As of today, there are 4 DOM event types you can listen to:\r\n     *\r\n     *   'wheel'                -- Chrome(31+), FF(17+), IE(9+)\r\n     *   'mousewheel'           -- Chrome, IE(6+), Opera, Safari\r\n     *   'MozMousePixelScroll'  -- FF(3.5 only!) (2010-2013) -- don't bother!\r\n     *   'DOMMouseScroll'       -- FF(0.9.7+) since 2003\r\n     *\r\n     * So what to do?  The is the best:\r\n     *\r\n     *   normalizeWheel.getEventType();\r\n     *\r\n     * In your event callback, use this code to get sane interpretation of the\r\n     * deltas.  This code will return an object with properties:\r\n     *\r\n     *   spinX   -- normalized spin speed (use for zoom) - x plane\r\n     *   spinY   -- \" - y plane\r\n     *   pixelX  -- normalized distance (to pixels) - x plane\r\n     *   pixelY  -- \" - y plane\r\n     *\r\n     * Wheel values are provided by the browser assuming you are using the wheel to\r\n     * scroll a web page b
1y a number of lines or pixels (or pages).  Values can vary\r\n     * significantly on different platforms and browsers, forgetting that you can\r\n     * scroll at different speeds.  Some devices (like trackpads) emit more events\r\n     * at smaller increments with fine granularity, and some emit massive jumps with\r\n     * linear speed or acceleration.\r\n     *\r\n     * This code does its best to normalize the deltas for you:\r\n     *\r\n     *   - spin is trying to normalize how far the wheel was spun (or trackpad\r\n     *     dragged).  This is super useful for zoom support where you want to\r\n     *     throw away the chunky scroll steps on the PC and make those equal to\r\n     *     the slow and smooth tiny steps on the Mac. Key data: This code tries to\r\n     *     resolve a single slow step on a wheel to 1.\r\n     *\r\n     *   - pixel is normalizing the desired scroll delta in pixel units.  You'll\r\n     *     get the crazy differences between browsers, but at least it'll be in\r\n     *     pixels!\r\n     *\r\n     *   - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT.  This\r\n     *     should translate to positive value zooming IN, negative zooming OUT.\r\n     *     This matches the newer 'wheel' event.\r\n     *\r\n     * Why are there spinX, spinY (or pixels)?\r\n     *\r\n     *   - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn\r\n     *     with a mouse.  It results in side-scrolling in the browser by default.\r\n     *\r\n     *   - spinY is what you expect -- it's the classic axis of a mouse wheel.\r\n     *\r\n     *   - I dropped spinZ/pixelZ.  It is supported by the DOM 3 'wheel' event and\r\n     *     probably is by browsers in conjunction with fancy 3D controllers .. but\r\n     *     you know.\r\n     *\r\n     * Implementation info:\r\n     *\r\n     * Examples of 'wheel' event if you scroll slowly (down) by one step with an\r\n     * average mouse:\r\n     *\r\n     *   OS X + Chrome  (mouse)     -    4   pixel delta  (wheelDelta -120)\r\n     *   OS X + Safari  (mouse)     -  N/A   pixel delta  (wheelDelta  -12)\r\n     *   OS X + Firefox (mouse)     -    0.1 line  delta  (wheelDelta  N/A)\r\n     *   Win8 + Chrome  (mouse)     -  100   pixel delta  (wheelDelta -120)\r\n     *   Win8 + Firefox (mouse)     -    3   line  delta  (wheelDelta -120)\r\n     *\r\n     * On the trackpad:\r\n     *\r\n     *   OS X + Chrome  (trackpad)  -    2   pixel delta  (wheelDelta   -6)\r\n     *   OS X + Firefox (trackpad)  -    1   pixel delta  (wheelDelta  N/A)\r\n     *\r\n     * On other/older browsers.. it's more complicated as there can be multiple and\r\n     * also missing delta values.\r\n     *\r\n     * The 'wheel' event is more standard:\r\n     *\r\n     * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents\r\n     *\r\n     * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and\r\n     * deltaX, deltaY and deltaZ.  Some browsers provide other values to maintain\r\n     * backward compatibility with older events.  Those other values help us\r\n     * better normalize spin speed.  Example of what the browsers provide:\r\n     *\r\n     *                          | event.wheelDelta | event.detail\r\n     *        ------------------+------------------+--------------\r\n     *          Safari v5/OS X  |       -120       |       0\r\n     *          Safari v5/Win7  |       -120       |       0\r\n     *         Chrome v17/OS X  |       -120       |       0\r\n     *         Chrome v17/Win7  |       -120       |       0\r\n     *                IE9/Win7  |       -120       |   undefined\r\n     *         Firefox v4/OS X  |     undefined    |       1\r\n     *         Firefox v4/Win7  |     undefined    |       3\r\n     *\r\n     */\n    function normalizeWheel(/*object*/event) /*object*/{\n      // Reasonable defaults\n      var PIXEL_STEP = 10;\n      var LINE_HEIGHT = 40;\n      var PAGE_HEIGHT = 800;\n      var sX = 0,\n        sY = 0,\n        // spinX, spinY\n        pX = 0,\n        pY = 0; // pixelX, pixelY\n\n      // Legacy\n      if ('detail' in event) {\n        sY = event.detail;\n      }\n      if ('wheelDelta' in event) {\n        sY = -event.wheelDelta / 120;\n      }\n      if ('wheelDeltaY' in event) {\n        sY = -event.wheelDeltaY / 120;\n      }\n      if ('wheelDeltaX' in event) {\n        sX = -event.wheelDeltaX / 120;\n      }\n\n      // side scrolling on FF with DOMMouseScroll\n      if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {\n        sX = sY;\n        sY = 0;\n      }\n      pX = sX * PIXEL_STEP;\n      pY = sY * PIXEL_STEP;\n      if ('deltaY' in event) {\n        pY = event.deltaY;\n      }\n      if ('deltaX' in event) {\n        pX = event.deltaX;\n      }\n      if ((pX || pY) && event.deltaMode) {\n        if (event.deltaMode === 1) {\n          // delta in LINE units\n          pX *= LINE_HEIGHT;\n          pY *= LINE_HEIGHT;\n        } else {\n          // delta in PAGE units\n          pX *= PAGE_HEIGHT;\n          pY *= PAGE_HEIGHT;\n        }\n      }\n\n      // Fall-back if spin cannot be determined\n      if (pX && !sX) {\n        sX = pX < 1 ? -1 : 1;\n      }\n      if (pY && !sY) {\n        sY = pY < 1 ? -1 : 1;\n      }\n      return {\n        spinX: sX,\n        spinY: sY,\n        pixelX: pX,\n        pixelY: pY\n      };\n    }\n    if (s.params.mousewheelControl) {\n      /**\r\n       * The best combination if you prefer spinX + spinY normalization.  It favors\r\n       * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with\r\n       * 'wheel' event, making spin speed determination impossible.\r\n       */\n      s.mousewheel.event = navigator.userAgent.indexOf('firefox') > -1 ? 'DOMMouseScroll' : isEventSupported() ? 'wheel' : 'mousewheel';\n    }\n    function handleMousewheel(e) {\n      if (e.originalEvent) e = e.originalEvent; //jquery fix\n      var delta = 0;\n      var rtlFactor = s.rtl ? -1 : 1;\n      var data = normalizeWheel(e);\n      if (s.params.mousewheelForceToAxis) {\n        if (s.isHorizontal()) {\n          if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;else return;\n        } else {\n          if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;else return;\n        }\n      } else {\n        delta = Math.abs(data.pixelX) >
1 Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;\n      }\n      if (delta === 0) return;\n      if (s.params.mousewheelInvert) delta = -delta;\n      if (!s.params.freeMode) {\n        if (new window.Date().getTime() - s.mousewheel.lastScrollTime > 60) {\n          if (delta < 0) {\n            if ((!s.isEnd || s.params.loop) && !s.animating) {\n              s.slideNext();\n              s.emit('onScroll', s, e);\n            } else if (s.params.mousewheelReleaseOnEdges) return true;\n          } else {\n            if ((!s.isBeginning || s.params.loop) && !s.animating) {\n              s.slidePrev();\n              s.emit('onScroll', s, e);\n            } else if (s.params.mousewheelReleaseOnEdges) return true;\n          }\n        }\n        s.mousewheel.lastScrollTime = new window.Date().getTime();\n      } else {\n        //Freemode or scrollContainer:\n        var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n        var wasBeginning = s.isBeginning,\n          wasEnd = s.isEnd;\n        if (position >= s.minTranslate()) position = s.minTranslate();\n        if (position <= s.maxTranslate()) position = s.maxTranslate();\n        s.setWrapperTransition(0);\n        s.setWrapperTranslate(position);\n        s.updateProgress();\n        s.updateActiveIndex();\n        if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n          s.updateClasses();\n        }\n        if (s.params.freeModeSticky) {\n          clearTimeout(s.mousewheel.timeout);\n          s.mousewheel.timeout = setTimeout(function () {\n            s.slideReset();\n          }, 300);\n        } else {\n          if (s.params.lazyLoading && s.lazy) {\n            s.lazy.load();\n          }\n        }\n        // Emit event\n        s.emit('onScroll', s, e);\n\n        // Stop autoplay\n        if (s.params.autoplay && s.params.autoplayDisableOnInteraction) s.stopAutoplay();\n\n        // Return page scroll on edge positions\n        if (position === 0 || position === s.maxTranslate()) return;\n      }\n      if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n      return false;\n    }\n    s.disableMousewheelControl = function () {\n      if (!s.mousewheel.event) return false;\n      var target = s.container;\n      if (s.params.mousewheelEventsTarged !== 'container') {\n        target = $(s.params.mousewheelEventsTarged);\n      }\n      target.off(s.mousewheel.event, handleMousewheel);\n      s.params.mousewheelControl = false;\n      return true;\n    };\n    s.enableMousewheelControl = function () {\n      if (!s.mousewheel.event) return false;\n      var target = s.container;\n      if (s.params.mousewheelEventsTarged !== 'container') {\n        target = $(s.params.mousewheelEventsTarged);\n      }\n      target.on(s.mousewheel.event, handleMousewheel);\n      s.params.mousewheelControl = true;\n      return true;\n    };\n\n    /*=========================\r\n      Parallax\r\n      ===========================*/\n    function setParallaxTransform(el, progress) {\n      el = $(el);\n      var p, pX, pY;\n      var rtlFactor = s.rtl ? -1 : 1;\n      p = el.attr('data-swiper-parallax') || '0';\n      pX = el.attr('data-swiper-parallax-x');\n      pY = el.attr('data-swiper-parallax-y');\n      if (pX || pY) {\n        pX = pX || '0';\n        pY = pY || '0';\n      } else {\n        if (s.isHorizontal()) {\n          pX = p;\n          pY = '0';\n        } else {\n          pY = p;\n          pX = '0';\n        }\n      }\n      if (pX.indexOf('%') >= 0) {\n        pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n      } else {\n        pX = pX * progress * rtlFactor + 'px';\n      }\n      if (pY.indexOf('%') >= 0) {\n        pY = parseInt(pY, 10) * progress + '%';\n      } else {\n        pY = pY * progress + 'px';\n      }\n      el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n    }\n    s.parallax = {\n      setTranslate: function setTranslate() {\n        s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n          setParallaxTransform(this, s.progress);\n        });\n        s.slides.each(function () {\n          var slide = $(this);\n          slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n            var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n            setParallaxTransform(this, progress);\n          });\n        });\n      },\n      setTransition: function setTransition(duration) {\n        if (typeof duration === 'undefined') duration = s.params.speed;\n        s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n          var el = $(this);\n          var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n          if (duration === 0) parallaxDuration = 0;\n          el.transition(parallaxDuration);\n        });\n      }\n    };\n\n    /*=========================\r\n      Zoom\r\n      ===========================*/\n    s.zoom = {\n      // \"Global\" Props\n      scale: 1,\n      currentScale: 1,\n      isScaling: false,\n      gesture: {\n        slide: undefined,\n        slideWidth: undefined,\n        slideHeight: undefined,\n        image: undefined,\n        imageWrap: undefined,\n        zoomMax: s.params.zoomMax\n      },\n      image: {\n        isTouched: undefined,\n        isMoved: undefined,\n        currentX: undefined,\n        currentY: undefined,\n        minX: undefined,\n        minY: undefined,\n        maxX: undefined,\n        maxY: undefined,\n        width: undefined,\n        height: undefined,\n        startX: undefined,\n        startY: undefined,\n        touchesStart: {},\n        touchesCurrent: {}\n      },\n      velocity: {\n        x: undefined,\n        y: undefined,\n        prevPositionX: undefined,\n        prevPositionY: undefined,\n        prevTime: undefined\n      },\n      // Calc Scale From Multi-touches\n      getDistanceBetweenTouches: function getDistanceBetweenTouches(e) {\n        if (e.targetTouches.length < 2) return 1;\n        var x1 = e.targetTouches[0].pageX,\n          y1 = e.targetTouches[0].pageY,\n          x2 = e.targetTouches[1].pageX,\n          y2 = e.targetTouches[1].pageY;\n        var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));\n        return distance;\n      },\n      // Events\n      onGestureStart: function onGestureStart(e) {\n        var z = s.zoom;\n        if (!s.support.gestures) {\n          if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {\n            return;\n          }\n          z.gesture.scaleStart = z.getDistanceBetweenTouches(e);\n        }\n        if (!z.gesture.slide || !z.gesture.slide.length) {\n          z.gesture.slide = $(this);\n          if (z.gesture.slide.length === 0) z.gesture.slide = s.slides.eq(s.activeIndex);\n          z.gesture.image = z.gesture.slide.find('img, svg, canvas');\n          z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);\n          z.gesture.zoomMax = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax;\n          if (z.gesture.imageWrap.length === 0) {\n            z.gesture.image = undefined;\n            return;\n          }\n        }\n        z.gesture.image.transition(0);\n        z.isScaling = true;\n      },\n      onGestureChange: function onGestureChange(e) {\n        var z = s.zoom;\n        if (!s.support.gestures) {\n          if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {\n            return;\n          }\n          z.gesture.scaleMove = z.getDistanceBetweenTouches(e);\n        }\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        if (s.support.gestures) {\n          z.scale = e.scale * z.currentScale;\n        } else {\n          z.scale = z.gesture.scaleMove / z.gesture.scaleStart * z.currentScale;\n        }\n        if (z.scale > z.gesture.zoomMax) {\n          z.scale = z.gesture.zoomMax - 1 + Math.pow(z.scale - z.gesture.zoomMax + 1, 0.5);\n        }\n        if (z.scale < s.params.zoomMin) {\n          z.scale = s.params.zoomMin + 1 - Math.pow(s.params.zoomMin - z.scale + 1, 0.5);\n        }
1\n        z.gesture.image.transform('translate3d(0,0,0) scale(' + z.scale + ')');\n      },\n      onGestureEnd: function onGestureEnd(e) {\n        var z = s.zoom;\n        if (!s.support.gestures) {\n          if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2) {\n            return;\n          }\n        }\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.params.zoomMin);\n        z.gesture.image.transition(s.params.speed).transform('translate3d(0,0,0) scale(' + z.scale + ')');\n        z.currentScale = z.scale;\n        z.isScaling = false;\n        if (z.scale === 1) z.gesture.slide = undefined;\n      },\n      onTouchStart: function onTouchStart(s, e) {\n        var z = s.zoom;\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        if (z.image.isTouched) return;\n        if (s.device.os === 'android') e.preventDefault();\n        z.image.isTouched = true;\n        z.image.touchesStart.x = s.getTouchEventX(e);\n        z.image.touchesStart.y = s.getTouchEventY(e);\n      },\n      onTouchMove: function onTouchMove(e) {\n        var z = s.zoom;\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        s.allowClick = false;\n        if (!z.image.isTouched || !z.gesture.slide) return;\n        if (!z.image.isMoved) {\n          z.image.width = z.gesture.image[0].offsetWidth;\n          z.image.height = z.gesture.image[0].offsetHeight;\n          z.image.startX = s.getTranslate(z.gesture.imageWrap[0], 'x') || 0;\n          z.image.startY = s.getTranslate(z.gesture.imageWrap[0], 'y') || 0;\n          z.gesture.slideWidth = z.gesture.slide[0].offsetWidth;\n          z.gesture.slideHeight = z.gesture.slide[0].offsetHeight;\n          z.gesture.imageWrap.transition(0);\n          if (s.rtl) z.image.startX = -z.image.startX;\n          if (s.rtl) z.image.startY = -z.image.startY;\n        }\n        // Define if we need image drag\n        var scaledWidth = z.image.width * z.scale;\n        var scaledHeight = z.image.height * z.scale;\n        if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) return;\n        z.image.minX = Math.min(z.gesture.slideWidth / 2 - scaledWidth / 2, 0);\n        z.image.maxX = -z.image.minX;\n        z.image.minY = Math.min(z.gesture.slideHeight / 2 - scaledHeight / 2, 0);\n        z.image.maxY = -z.image.minY;\n        z.image.touchesCurrent.x = s.getTouchEventX(e);\n        z.image.touchesCurrent.y = s.getTouchEventY(e);\n        if (!z.image.isMoved && !z.isScaling) {\n          if (s.isHorizontal() && Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x || Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x) {\n            z.image.isTouched = false;\n            return;\n          } else if (!s.isHorizontal() && Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y || Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y) {\n            z.image.isTouched = false;\n            return;\n          }\n        }\n        e.preventDefault();\n        e.stopPropagation();\n        z.image.isMoved = true;\n        z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;\n        z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;\n        if (z.image.currentX < z.image.minX) {\n          z.image.currentX = z.image.minX + 1 - Math.pow(z.image.minX - z.image.currentX + 1, 0.8);\n        }\n        if (z.image.currentX > z.image.maxX) {\n          z.image.currentX = z.image.maxX - 1 + Math.pow(z.image.currentX - z.image.maxX + 1, 0.8);\n        }\n        if (z.image.currentY < z.image.minY) {\n          z.image.currentY = z.image.minY + 1 - Math.pow(z.image.minY - z.image.currentY + 1, 0.8);\n        }\n        if (z.image.currentY > z.image.maxY) {\n          z.image.currentY = z.image.maxY - 1 + Math.pow(z.image.currentY - z.image.maxY + 1, 0.8);\n        }\n\n        //Velocity\n        if (!z.velocity.prevPositionX) z.velocity.prevPositionX = z.image.touchesCurrent.x;\n        if (!z.velocity.prevPositionY) z.velocity.prevPositionY = z.image.touchesCurrent.y;\n        if (!z.velocity.prevTime) z.velocity.prevTime = Date.now();\n        z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;\n        z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;\n        if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2) z.velocity.x = 0;\n        if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2) z.velocity.y = 0;\n        z.velocity.prevPositionX = z.image.touchesCurrent.x;\n        z.velocity.prevPositionY = z.image.touchesCurrent.y;\n        z.velocity.prevTime = Date.now();\n        z.gesture.imageWrap.transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');\n      },\n      onTouchEnd: function onTouchEnd(s, e) {\n        var z = s.zoom;\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        if (!z.image.isTouched || !z.image.isMoved) {\n          z.image.isTouched = false;\n          z.image.isMoved = false;\n          return;\n        }\n        z.image.isTouched = false;\n        z.image.isMoved = false;\n        var momentumDurationX = 300;\n        var momentumDurationY = 300;\n        var momentumDistanceX = z.velocity.x * momentumDurationX;\n        var newPositionX = z.image.currentX + momentumDistanceX;\n        var momentumDistanceY = z.velocity.y * momentumDurationY;\n        var newPositionY = z.image.currentY + momentumDistanceY;\n\n        //Fix duration\n        if (z.velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);\n        if (z.velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);\n        var momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n        z.image.currentX = newPositionX;\n        z.image.currentY = newPositionY;\n\n        // Define if we need image drag\n        var scaledWidth = z.image.width * z.scale;\n        var scaledHeight = z.image.height * z.scale;\n        z.image.minX = Math.min(z.gesture.slideWidth / 2 - scaledWidth / 2, 0);\n        z.image.maxX = -z.image.minX;\n        z.image.minY = Math.min(z.gesture.slideHeight / 2 - scaledHeight / 2, 0);\n        z.image.maxY = -z.image.minY;\n        z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);\n        z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);\n        z.gesture.imageWrap.transition(momentumDuration).transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');\n      },\n      onTransitionEnd: function onTransitionEnd(s) {\n        var z = s.zoom;\n        if (z.gesture.slide && s.previousIndex !== s.activeIndex) {\n          z.gesture.image.transform('translate3d(0,
10,0) scale(1)');\n          z.gesture.imageWrap.transform('translate3d(0,0,0)');\n          z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;\n          z.scale = z.currentScale = 1;\n        }\n      },\n      // Toggle Zoom\n      toggleZoom: function toggleZoom(s, e) {\n        var z = s.zoom;\n        if (!z.gesture.slide) {\n          z.gesture.slide = s.clickedSlide ? $(s.clickedSlide) : s.slides.eq(s.activeIndex);\n          z.gesture.image = z.gesture.slide.find('img, svg, canvas');\n          z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);\n        }\n        if (!z.gesture.image || z.gesture.image.length === 0) return;\n        var touchX, touchY, offsetX, offsetY, diffX, diffY, translateX, translateY, imageWidth, imageHeight, scaledWidth, scaledHeight, translateMinX, translateMinY, translateMaxX, translateMaxY, slideWidth, slideHeight;\n        if (typeof z.image.touchesStart.x === 'undefined' && e) {\n          touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;\n          touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;\n        } else {\n          touchX = z.image.touchesStart.x;\n          touchY = z.image.touchesStart.y;\n        }\n        if (z.scale && z.scale !== 1) {\n          // Zoom Out\n          z.scale = z.currentScale = 1;\n          z.gesture.imageWrap.transition(300).transform('translate3d(0,0,0)');\n          z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(1)');\n          z.gesture.slide = undefined;\n        } else {\n          // Zoom In\n          z.scale = z.currentScale = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax;\n          if (e) {\n            slideWidth = z.gesture.slide[0].offsetWidth;\n            slideHeight = z.gesture.slide[0].offsetHeight;\n            offsetX = z.gesture.slide.offset().left;\n            offsetY = z.gesture.slide.offset().top;\n            diffX = offsetX + slideWidth / 2 - touchX;\n            diffY = offsetY + slideHeight / 2 - touchY;\n            imageWidth = z.gesture.image[0].offsetWidth;\n            imageHeight = z.gesture.image[0].offsetHeight;\n            scaledWidth = imageWidth * z.scale;\n            scaledHeight = imageHeight * z.scale;\n            translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);\n            translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);\n            translateMaxX = -translateMinX;\n            translateMaxY = -translateMinY;\n            translateX = diffX * z.scale;\n            translateY = diffY * z.scale;\n            if (translateX < translateMinX) {\n              translateX = translateMinX;\n            }\n            if (translateX > translateMaxX) {\n              translateX = translateMaxX;\n            }\n            if (translateY < translateMinY) {\n              translateY = translateMinY;\n            }\n            if (translateY > translateMaxY) {\n              translateY = translateMaxY;\n            }\n          } else {\n            translateX = 0;\n            translateY = 0;\n          }\n          z.gesture.imageWrap.transition(300).transform('translate3d(' + translateX + 'px, ' + translateY + 'px,0)');\n          z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(' + z.scale + ')');\n        }\n      },\n      // Attach/Detach Events\n      attachEvents: function attachEvents(detach) {\n        var action = detach ? 'off' : 'on';\n        if (s.params.zoom) {\n          var target = s.slides;\n          var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {\n            passive: true,\n            capture: false\n          } : false;\n          // Scale image\n          if (s.support.gestures) {\n            s.slides[action]('gesturestart', s.zoom.onGestureStart, passiveListener);\n            s.slides[action]('gesturechange', s.zoom.onGestureChange, passiveListener);\n            s.slides[action]('gestureend', s.zoom.onGestureEnd, passiveListener);\n          } else if (s.touchEvents.start === 'touchstart') {\n            s.slides[action](s.touchEvents.start, s.zoom.onGestureStart, passiveListener);\n            s.slides[action](s.touchEvents.move, s.zoom.onGestureChange, passiveListener);\n            s.slides[action](s.touchEvents.end, s.zoom.onGestureEnd, passiveListener);\n          }\n\n          // Move image\n          s[action]('touchStart', s.zoom.onTouchStart);\n          s.slides.each(function (index, slide) {\n            if ($(slide).find('.' + s.params.zoomContainerClass).length > 0) {\n              $(slide)[action](s.touchEvents.move, s.zoom.onTouchMove);\n            }\n          });\n          s[action]('touchEnd', s.zoom.onTouchEnd);\n\n          // Scale Out\n          s[action]('transitionEnd', s.zoom.onTransitionEnd);\n          if (s.params.zoomToggle) {\n            s.on('doubleTap', s.zoom.toggleZoom);\n          }\n        }\n      }
1,\n      init: function init() {\n        s.zoom.attachEvents();\n      },\n      destroy: function destroy() {\n        s.zoom.attachEvents(true);\n      }\n    };\n\n    /*=========================\r\n      Plugins API. Collect all and init all plugins\r\n      ===========================*/\n    s._plugins = [];\n    for (var plugin in s.plugins) {\n      var p = s.plugins[plugin](s, s.params[plugin]);\n      if (p) s._plugins.push(p);\n    }\n    // Method to call all plugins event/method\n    s.callPlugins = function (eventName) {\n      for (var i = 0; i < s._plugins.length; i++) {\n        if (eventName in s._plugins[i]) {\n          s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n      }\n    };\n\n    /*=========================\r\n      Events/Callbacks/Plugins Emitter\r\n      ===========================*/\n    function normalizeEventName(eventName) {\n      if (eventName.indexOf('on') !== 0) {\n        if (eventName[0] !== eventName[0].toUpperCase()) {\n          eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n        } else {\n          eventName = 'on' + eventName;\n        }\n      }\n      return eventName;\n    }\n    s.emitterEventListeners = {};\n    s.emit = function (eventName) {\n      // Trigger callbacks\n      if (s.params[eventName]) {\n        s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n      }\n      var i;\n      // Trigger events\n      if (s.emitterEventListeners[eventName]) {\n        for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n          s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n      }\n      // Trigger plugins\n      if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n    };\n    s.on = function (eventName, handler) {\n      eventName = normalizeEventName(eventName);\n      if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n      s.emitterEventListeners[eventName].push(handler);\n      return s;\n    };\n    s.off = function (eventName, handler) {\n      var i;\n      eventName = normalizeEventName(eventName);\n      if (typeof handler === 'undefined') {\n        // Remove all handlers for such event\n        s.emitterEventListeners[eventName] = [];\n        return s;\n      }\n      if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n      for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n        if (s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n      }\n      return s;\n    };\n    s.once = function (eventName, handler) {\n      eventName = normalizeEventName(eventName);\n      var _handler2 = function _handler() {\n        handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n        s.off(eventName, _handler2);\n      };\n      s.on(eventName, _handler2);\n      return s;\n    };\n\n    // Accessibility tools\n    s.a11y = {\n      makeFocusable: function makeFocusable($el) {\n        $el.attr('tabIndex', '0');\n        return $el;\n      },\n      addRole: function addRole($el, role) {\n        $el.attr('role', role);\n        return $el;\n      },\n      addLabel: function addLabel($el, label) {\n        $el.attr('aria-label', label);\n        return $el;\n      },\n      disable: function disable($el) {\n        $el.attr('aria-disabled', true);\n        return $el;\n      },\n      enable: function enable($el) {\n        $el.attr('aria-disabled', false);\n        return $el;\n      },\n      onEnterKey: function onEnterKey(event) {\n        if (event.keyCode !== 13) return;\n        if ($(event.target).is(s.params.nextButton)) {\n          s.onClickNext(event);\n          if (s.isEnd) {\n            s.a11y.notify(s.params.lastSlideMessage);\n          } else {\n            s.a11y.notify(s.params.nextSlideMessage);\n          }\n        } else if ($(event.target).is(s.params.prevButton)) {\n          s.onClickPrev(event);\n          if (s.isBeginning) {\n            s.a11y.notify(s.params.firstSlideMessage);\n          } else {\n            s.a11y.notify(s.params.prevSlideMessage);\n          }\n        }\n        if ($(event.target).is('.' + s.params.bulletClass)) {\n          $(event.target)[0].click();\n        }\n      },\n      liveRegion: $('<span class=\"' + s.params.notificationClass + '\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n      notify: function notify(message) {\n        var notification = s.a11y.liveRegion;\n        if (notification.length === 0) return;\n        notification.html('');\n        notification.html(message);\n      }
1,\n      init: function init() {\n        // Setup accessibility\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n          s.a11y.makeFocusable(s.nextButton);\n          s.a11y.addRole(s.nextButton, 'button');\n          s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n        }\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n          s.a11y.makeFocusable(s.prevButton);\n          s.a11y.addRole(s.prevButton, 'button');\n          s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n        }\n        $(s.container).append(s.a11y.liveRegion);\n      },\n      initPagination: function initPagination() {\n        if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n          s.bullets.each(function () {\n            var bullet = $(this);\n            s.a11y.makeFocusable(bullet);\n            s.a11y.addRole(bullet, 'button');\n            s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n          });\n        }\n      },\n      destroy: function destroy() {\n        if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n      }\n    };\n\n    /*=========================\r\n      Init/Destroy\r\n      ===========================*/\n    s.init = function () {\n      if (s.params.loop) s.createLoop();\n      s.updateContainerSize();\n      s.updateSlidesSize();\n      s.updatePagination();\n      if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n        if (s.params.scrollbarDraggable) {\n          s.scrollbar.enableDraggable();\n        }\n      }\n      if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        if (!s.params.loop) s.updateProgress();\n        s.effects[s.params.effect].setTranslate();\n      }\n      if (s.params.loop) {\n        s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n      } else {\n        s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n        if (s.params.initialSlide === 0) {\n          if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n          if (s.lazy && s.params.lazyLoading) {\n            s.lazy.load();\n            s.lazy.initialImageLoaded = true;\n          }\n        }\n      }\n      s.attachEvents();\n      if (s.params.observer && s.support.observer) {\n        s.initObservers();\n      }\n      if (s.params.preloadImages && !s.params.lazyLoading) {\n        s.preloadImages();\n      }\n      if (s.params.zoom && s.zoom) {\n        s.zoom.init();\n      }\n      if (s.params.autoplay) {\n        s.startAutoplay();\n      }\n      if (s.params.keyboardControl) {\n        if (s.enableKeyboardControl) s.enableKeyboardControl();\n      }\n      if (s.params.mousewheelControl) {\n        if (s.enableMousewheelControl) s.enableMousewheelControl();\n      }\n      // Deprecated hashnavReplaceState changed to replaceState for use in hashnav and history\n      if (s.params.hashnavReplaceState) {\n        s.params.replaceState = s.params.hashnavReplaceState;\n      }\n      if (s.params.history) {\n        if (s.history) s.history.init();\n      }\n      if (s.params.hashnav) {\n        if (s.hashnav) s.hashnav.init();\n      }\n      if (s.params.a11y && s.a11y) s.a11y.init();\n      s.emit('onInit', s);\n    };\n\n    // Cleanup dynamic styles\n    s.cleanupStyles = function () {\n      // Container\n      s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n\n      // Wrapper\n      s.wrapper.removeAttr('style');\n\n      // Slides\n      if (s.slides && s.slides.length) {\n        s.slides.removeClass([s.params.slideVisibleClass, s.params.slideActiveClass, s.params.slideNextClass, s.params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-column').removeAttr('data-swiper-row');\n      }\n\n      // Pagination/Bullets\n      if (s.paginationContainer && s.paginationContainer.length) {\n        s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n      }\n      if (s.bullets && s.bullets.length) {\n        s.bullets.removeClass(s.params.bulletActiveClass);\n      }\n\n      // Buttons\n      if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n      if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n\n      // Scrollbar\n      if (s.params.scrollbar && s.scrollbar) {\n        if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n        if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n      }\n    };\n\n    // Destroy\n    s.destroy = function (deleteInstance, cleanupStyles) {\n      // Detach evebt
1s\n      s.detachEvents();\n      // Stop autoplay\n      s.stopAutoplay();\n      // Disable draggable\n      if (s.params.scrollbar && s.scrollbar) {\n        if (s.params.scrollbarDraggable) {\n          s.scrollbar.disableDraggable();\n        }\n      }\n      // Destroy loop\n      if (s.params.loop) {\n        s.destroyLoop();\n      }\n      // Cleanup styles\n      if (cleanupStyles) {\n        s.cleanupStyles();\n      }\n      // Disconnect observer\n      s.disconnectObservers();\n\n      // Destroy zoom\n      if (s.params.zoom && s.zoom) {\n        s.zoom.destroy();\n      }\n      // Disable keyboard/mousewheel\n      if (s.params.keyboardControl) {\n        if (s.disableKeyboardControl) s.disableKeyboardControl();\n      }\n      if (s.params.mousewheelControl) {\n        if (s.disableMousewheelControl) s.disableMousewheelControl();\n      }\n      // Disable a11y\n      if (s.params.a11y && s.a11y) s.a11y.destroy();\n      // Delete history popstate\n      if (s.params.history && !s.params.replaceState) {\n        window.removeEventListener('popstate', s.history.setHistoryPopState);\n      }\n      if (s.params.hashnav && s.hashnav) {\n        s.hashnav.destroy();\n      }\n      // Destroy callback\n      s.emit('onDestroy');\n      // Delete instance\n      if (deleteInstance !== false) s = null;\n    };\n    s.init();\n\n    // Return swiper instance\n    return s;\n  };\n\n  /*==================================================\r\n      Prototype\r\n  ====================================================*/\n  _Swiper.prototype = {\n    isSafari: function () {\n      var ua = window.navigator.userAgent.toLowerCase();\n      return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;\n    }(),\n    isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent),\n    isArray: function isArray(arr) {\n      return Object.prototype.toString.apply(arr) === '[object Array]';\n    },\n    /*==================================================\r\n    Browser\r\n    ====================================================*/\n    browser: {\n      ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n      ieTouch: window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1 || window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1,\n      lteIE9: function () {\n        // create temporary DIV\n        var div = document.createElement('div');\n        // add content to tmp DIV which is wrapped into the IE HTML conditional statement\n        div.innerHTML = '\x3c!--[if lte IE 9]><i></i><![endif]--\x3e';\n        // return true / false value based on what will browser render\n        return div.getElementsByTagName('i').length === 1;\n      }()\n    },\n    /*==================================================\r\n    Devices\r\n    ====================================================*/\n    device: function () {\n      var ua = window.navigator.userAgent;\n      var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n      var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n      var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n      var iphone = !ipad && ua.match(/(iPhone\\sOS|iOS)\\s([\\d_]+)/);\n      return {\n        ios: ipad || iphone || ipod,\n        android: android\n      };\n    }(),\n    /*==================================================\r\n    Feature Detection\r\n    ====================================================*/\n    support: {\n      touch: window.Modernizr && Modernizr.touch === true || function () {\n        return !!('ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch);\n      }(),\n      transforms3d: window.Modernizr && Modernizr.csstransforms3d === true || function () {\n        var div = document.createElement('div').style;\n        return 'webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div;\n      }(),\n      flexbox: function () {\n        var div = document.createElement('div').style;\n        var styles = 'alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient'.split(' ');\n        for (var i = 0; i < styles.length;
1 i++) {\n          if (styles[i] in div) return true;\n        }\n      }(),\n      observer: function () {\n        return 'MutationObserver' in window || 'WebkitMutationObserver' in window;\n      }(),\n      passiveListener: function () {\n        var supportsPassive = false;\n        try {\n          var opts = Object.defineProperty({}, 'passive', {\n            get: function get() {\n              supportsPassive = true;\n            }\n          });\n          window.addEventListener('testPassiveListener', null, opts);\n        } catch (e) {}\n        return supportsPassive;\n      }(),\n      gestures: function () {\n        return 'ongesturestart' in window;\n      }()\n    },\n    /*==================================================\r\n    Plugins\r\n    ====================================================*/\n    plugins: {}\n  };\n\n  /*===========================\r\n   Get Dom libraries\r\n   ===========================*/\n  var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\n  for (var i = 0; i < swiperDomPlugins.length; i++) {\n    if (window[swiperDomPlugins[i]]) {\n      addLibraryPlugin(window[swiperDomPlugins[i]]);\n    }\n  }\n  // Required DOM Plugins\n  var domLib;\n  if (typeof Dom7 === 'undefined') {\n    domLib = window.Dom7 || window.Zepto || window.jQuery;\n  } else {\n    domLib = Dom7;\n  }\n\n  /*===========================\r\n  Add .swiper plugin from Dom libraries\r\n  ===========================*/\n  function addLibraryPlugin(lib) {\n    lib.fn.swiper = function (params) {\n      var firstInstance;\n      lib(this).each(function () {\n        var s = new _Swiper(this, params);\n        if (!firstInstance) firstInstance = s;\n      });\n      return firstInstance;\n    };\n  }\n  if (domLib) {\n    if (!('transitionEnd' in domLib.fn)) {\n      domLib.fn.transitionEnd = function (callback) {\n        var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n          i,\n          j,\n          dom = this;\n        function fireCallBack(e) {\n          /*jshint validthis:true */\n          if (e.target !== this) return;\n          callback.call(this, e);\n          for (i = 0; i < events.length; i++) {\n            dom.off(events[i], fireCallBack);\n          }\n        }\n        if (callback) {\n          for (i = 0; i < events.length; i++) {\n            dom.on(events[i], fireCallBack);\n          }\n        }\n        return this;\n      };\n    }\n    if (!('transform' in domLib.fn)) {\n      domLib.fn.transform = function (transform) {\n        for (var i = 0; i < this.length; i++) {\n          var elStyle = this[i].style;\n          elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n        }\n        return this;\n      };\n    }\n    if (!('transition' in domLib.fn)) {\n      domLib.fn.transition = function (duration) {\n        if (typeof duration !== 'string') {\n          duration = duration + 'ms';\n        }\n        for (var i = 0; i < this.length; i++) {\n          var elStyle = this[i].style;\n          elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n        }\n        return this;\n      };\n    }\n    if (!('outerWidth' in domLib.fn)) {\n      domLib.fn.outerWidth = function (includeMargins) {\n        if (this.length > 0) {\n          if (includeMargins) return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));else return this[0].offsetWidth;\n        } else return null;\n      };\n    }\n  }\n  window.Swiper = _Swiper;\n})();\n\n/*===========================\r\nSwiper AMD Export\r\n===========================*/\nif (typeof module !== 'undefined') {\n  module.exports = window.Swiper;\n} else if (typeof define === 'function' && define.amd) {\n  define([], function () {\n    'use strict';\n\n    return window.Swiper;\n  });\n}"},3995:function(e){e.exports="window.DD = window.DD || {};\nAM.Listpage = AM.Listpage || {};\n$(AM.Listpage._init);\n$(function () {\n  var $el = $('.magazine-swiper-homepage');\n  if (!$el.length) return;\n  AM.SwiperCarousel.prepForSwiper($el);\n  var isMobile = window.innerWidth < 767;\n  var slidesPerViewSetting = isMobile ? 'auto' : 4;\n  var swiper = new Swiper($el[0], $.extend({}, AM.SwiperCarousel.defaults, {\n    pagination: null,\n    slidesPerView: slidesPerViewSetting,\n    slidesPerGroup: 1,\n    // <- scrolls one at a time\n    spaceBetween: 0,\n    slidesOffsetBefore: isMobile ? 20 : 0,\n    //slidesOffsetAfter: isMobile ? 20 : 0,\n    roundLengths: true,\n    nextButton: '.mag-swiper-next',\n    prevButton: '.mag-swiper-prev'\n  }));\n  if (window.innerWidth < 767) {\n    // ms between nudge sequences\n    var resetToStart = function resetToStart() {\n      if (typeof swiper.minTranslate === 'function') {\n        setX(swiper.minTranslate());\n      } else {\n        setX(swiper.minTranslate);\n      }\n    };\n    var setTrans = function setTrans(d) {\n      // legacy first, then CSS fallback\n      if (typeof swiper.setWrapperTransition === 'function') {\n        swiper.setWrapperTransition(d);\n      } else {\n        $el.find('.article-list').css('transition', 'transform ' + d + 'ms ease');\n      }\n    };\n    var setX = function setX(x) {\n      if (typeof swiper.setWrapperTranslate === 'function') {\n        swiper.setWrapperTranslate(x);\n      } else {\n        $el.find('.article-list').css('transform', 'translate3d(' + x + 'px,0,0)');\n      }\n    };\n    var clearTrans = function clearTrans() {\n      if (typeof swiper.setWrapperTransition === 'function') {\n        swiper.setWrapperTransition(0);\n      } else {\n        $el.find('.article-list').css('transition', '');\n      }\n    };\n    var nudgeOnce = function nudgeOnce(cb) {\n      if (stopped) return;\n      setTrans(DUR);\n      setX(swiper.minTranslate() - A); // nudge left relative to Swiper’s baseline\n      setTimeout(function () {\n        resetToStart(); // <- return to true baseline\n        setTimeout(function () {\n          clearTrans();\n          cb && cb();\n        }, DUR);\n      }, GAP);\n    };\n    var _scheduleLoop = function scheduleLoop() {\n      if (stopped) return;\n      nudgeOnce(function () {\n        if (stopped) return;\n        loopTimer = setTimeout(_scheduleLoop, PAUSE);\n      });\n    };\n    var stopped = false;\n    var loopTimer = null;\n    var A = 20; // px\n    var DUR = 300; // ms per move\n    var GAP = 300; // ms between out/back\n    var PAUSE = 2000;\n    loopTimer = setTimeout(_scheduleLoop, 800);\n    swiper.on('transitionStart', function () {\n      if (swiper.activeIndex !== 0) {\n        stopped = true;\n        clearTimeout(loopTimer);\n        clearTrans();\n      }\n    });\n  }\n});"},4642:function(e){e.exports=function(e){function n(e){"undefined"!=typeof console&&(console.error||console.log)("[Script Loader]",e)}try{"undefined"!=typeof execScript&&"undefined"!=typeof attachEvent&&"undefined"==typeof addEventListener?execScript(e):"undefined"!=typeof eval?eval.call(null,e):n("EvalError: No eval function available")}catch(e){n(e)}}},6003:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;
1\n(function (DL) {\n  function expandableImages($images) {\n    $images.each(function (index, item) {\n      return new ExpandableImage($(item));\n    });\n    return $images;\n  }\n  DL.expandableImages = expandableImages;\n  var ExpandableImage = function () {\n    function ExpandableImage($image) {\n      this.$image = $image;\n      this.init();\n    }\n    ExpandableImage.prototype.init = function () {\n      var _this = this;\n      //\tBuild Template\n      var tmpl = $('#expandable-img-tmpl').html();\n      if (tmpl == null || tmpl.length === 0) {\n        return;\n      }\n      //\tStore variables for image data\n      var $img = this.$image.find('.img');\n      var id = this.$image.data('img');\n      var url = this.$image.data('src');\n      var $caption = this.$image.find('.img-caption').clone();\n      var tmplData = {\n        img_src: url,\n        img_id: id\n      };\n      //\tAppend expandable container to after image\n      var template = _.template(tmpl)(tmplData);\n      var $container = $(template);\n      DL.Utilities.getBodyElement().append($container);\n      //\tAttach data and preload images\n      var $expandedImageContainer = $container.find('.image');\n      //\tAttach data and preload images\n      $expandedImageContainer.append($caption);\n      //\tEvents\n      this.$image.find('.img').on('click', function () {\n        return _this.click();\n      }); //  Expand inline image\n      this.$image.find('.img').on('mouseenter', function () {\n        return _this.loadExpandedImg();\n      }); //  Load expanded image\n      //DL.Utilities.getDocumentElement().on('click', '.expanded-img .expanded-img-close-btn', () => this.close());\t\t\t//  Close on close button click\n      DL.Utilities.getDocumentElement().on('click', '.expanded-img', function () {\n        return _this.close();\n      }); //  Close on expanded image click\n    };\n    ExpandableImage.prototype.loadExpandedImg = function () {\n      var id = this.$image.closest('.inline-img').data('img');\n      //console.log('loadExpandedImg: ' + id);\n      var $expanded = $('.expanded-img[data-img=\"' + id + '\"]');\n      var $expandedImg = $expanded.find('.image > img');\n      var expandedImgDataSrc = $expandedImg.attr('data-src');\n      if (expandedImgDataSrc != null && expandedImgDataSrc.length > 0) {\n        $expandedImg.attr('src', expandedImgDataSrc);\n      }\n    };\n    ExpandableImage.prototype.click = function () {\n      var _this = this;\n      this.loadExpandedImg();\n      var id = this.$image.closest('.inline-img').data('img');\n      var $expanded = $('.expanded-img[data-img=\"' + id + '\"]');\n      $expanded.addClass('open');\n      DL.Utilities.getWindowElement().one('scroll.collapseExpandedImage', function () {\n        return _this.close();\n      });\n    };\n    ExpandableImage.prototype.close = function () {\n      var _this = this;\n      var $img = $('.expanded-img.open');\n      $img.removeClass('open');\n      DL.Utilities.getWindowElement().off('scroll.collapseExpandedImage', function () {\n        return _this.close();\n      });\n    };\n    return ExpandableImage;\n  }();\n})(DL || (DL = {}));"},6524:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  function getStringSize(str, styles) {\n    if (str == null || str.length === 0) {\n      return null;\n    }\n    var e = document.createElement('span');\n    e.style.whiteSpace = 'nowrap'; // needed to calculate width beyond the screen width\n    // Copy font rendering styles\n    e.style.font = styles.font;\n    e.style.letterSpacing = styles.letterSpacing;\n    e.style.boxSizing = styles.boxSizing;\n    e.style.padding = styles.padding;\n    e.style.margin = styles.margin;\n    e.style.border = styles.border;\n    // Set text\n    e.innerHTML = str;\n    document.body.appendChild(e);\n    var width = e.offsetWidth;\n    var height = e.offsetHeight;\n    document.body.removeChild(e);\n    return {\n      width: width + .5,\n      height: height + .5\n    }; // .5 to account for possible partial pixel rounding down\n  }\n  DL.getStringSize = getStringSize;\n  function balanceText(elements) {\n    for (var i = 0; i < elements.length;
1 i++) {\n      (function (el) {\n        var elStyles = window.getComputedStyle(el, null);\n        if (elStyles.display === 'block' && elStyles.textAlign === 'center') {\n          new FontFaceObserver(elStyles.fontFamily).load().then(function () {\n            DL.balanceTextRun(el);\n          });\n        }\n      })(elements[i]);\n    }\n  }\n  DL.balanceText = balanceText;\n  function balanceTextRun(el) {\n    el.style.width = '';\n    var elStyles = window.getComputedStyle(el, null);\n    var textContentSize = DL.getStringSize(el.textContent, elStyles);\n    var initialHeight = el.offsetHeight;\n    if (el.offsetWidth + 0.5 >= textContentSize.width) {\n      el.style.width = textContentSize.width + 'px';\n    } else if (el.offsetWidth * 2 + 0.5 >= textContentSize.width) {\n      var firstLineWidth = 0;\n      var secondLineWidth = 0;\n      var words = el.textContent.split(/\\s+/);\n      for (var k = 1; k < words.length; k++) {\n        firstLineWidth = DL.getStringSize(words.slice(0, k).join(' '), elStyles).width;\n        secondLineWidth = DL.getStringSize(words.slice(k).join(' '), elStyles).width;\n        if (firstLineWidth >= secondLineWidth) {\n          el.style.width = firstLineWidth + 'px';\n          break;\n        }\n      }\n    } else {\n      for (var i = 1; i <= 30 && initialHeight === el.offsetHeight; i++) {\n        el.style.width = el.offsetWidth - i * 20 + 'px';\n      }\n    }\n    for (var i = 1; i <= 12 && initialHeight < el.offsetHeight; i++) {\n      el.style.width = el.offsetWidth + i * 10 + 'px';\n    }\n    //var currentHeight = initialHeight;\n    //var currentWidth = initialWidth;\n    //var prevWidth = initialWidth;\n    //for (var i = 0; i < 100 && currentHeight == initialHeight; i++) {\n    //    prevWidth = currentWidth;\n    //    currentWidth -= 20;\n    //    el.style.width = currentWidth + 'px';\n    //    currentHeight = el.offsetHeight;\n    //}\n    //el.style.width = prevWidth + 'px';\n  }\n  DL.balanceTextRun = balanceTextRun;\n})(DL || (DL = {}));"},7041:function(e){e.exports="function _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\n//     Underscore.js 1.8.3\n//     http://underscorejs.org\n//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\n\n(function () {\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `exports` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype,\n    ObjProto = Object.prototype,\n    FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n    slice = ArrayProto.slice,\n    toString = ObjProto.toString,\n    hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n    nativeKeys = Object.keys,\n    nativeBind = FuncProto.bind,\n    nativeCreate = Object.create;\n\n  // Naked function reference for surrogate-prototype-swapping.\n  var Ctor = function Ctor() {};\n\n  // Create a safe reference to the Underscore object for use below.\n  var _2 = function _(obj) {\n    if (obj instanceof _2) return obj;\n    if (!(this instanceof _2)) return new _2(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _2;\n    }\n    exports._ = _2;\n  } else {\n    root._ = _2;\n  }\n\n  // Current version.\n  _2.VERSION = '1.8.3';
1\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  var optimizeCb = function optimizeCb(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1:\n        return function (value) {\n          return func.call(context, value);\n        };\n      case 2:\n        return function (value, other) {\n          return func.call(context, value, other);\n        };\n      case 3:\n        return function (value, index, collection) {\n          return func.call(context, value, index, collection);\n        };\n      case 4:\n        return function (accumulator, value, index, collection) {\n          return func.call(context, accumulator, value, index, collection);\n        };\n    }\n    return function () {\n      return func.apply(context, arguments);\n    };\n  };\n\n  // A mostly-internal function to generate callbacks that can be applied\n  // to each element in a collection, returning the desired result — either\n  // identity, an arbitrary callback, a property matcher, or a property accessor.\n  var cb = function cb(value, context, argCount) {\n    if (value == null) return _2.identity;\n    if (_2.isFunction(value)) return optimizeCb(value, context, argCount);\n    if (_2.isObject(value)) return _2.matcher(value);\n    return _2.property(value);\n  };\n  _2.iteratee = function (value, context) {\n    return cb(value, context, Infinity);\n  };\n\n  // An internal function for creating assigner functions.\n  var createAssigner = function createAssigner(keysFunc, undefinedOnly) {\n    return function (obj) {\n      var length = arguments.length;\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n          keys = keysFunc(source),\n          l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  };\n\n  // An internal function for creating a new object that inherits from another.\n  var baseCreate = function baseCreate(prototype) {\n    if (!_2.isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    Ctor.prototype = prototype;\n    var result = new Ctor();\n    Ctor.prototype = null;\n    return result;\n  };\n  var property = function property(key) {\n    return function (obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  };\n\n  // Helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object\n  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n  var getLength = property('length');\n  var isArrayLike = function isArrayLike(collection) {\n    var length = getLength(collection);\n    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;\n  };\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  _2.each = _2.forEach = function (obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var keys = _2.keys(obj);\n      for (i = 0, length = keys.length; i < length; i++) {\n        iteratee(obj[keys[i]], keys[i], obj);\n      }\n    }\n    return obj;\n  };\n\n  // Return the results of applying the iteratee to each element.\n  _2.map = _2.collect = function (obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = !isArrayLike(obj) && _2.keys(obj),\n      length = (keys || obj).length,\n      results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Create a reducing function iterating left or right.\n  function createReduce(dir) {\n    // Optimized iterator function as using arguments.length\n    // in the main function will deoptimize the, see #1991.\n    function iterator(obj, iteratee, memo, keys, index, length) {\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = keys ? keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    }\n    return function (obj, iteratee, memo, context) {\n      iteratee = optimizeCb(iteratee, context, 4);\n      var keys = !isArrayLike(obj) && _2.keys(obj),\n        length = (keys || obj).length,\n        index = dir > 0 ? 0 : length - 1;\n      // Determine the initial value if none is provided.\n      if (arguments.length < 3) {\n        memo = obj[keys ? keys[index] : index];\n        index += dir;\n      }\n      return iterator(obj, iteratee, memo, keys, index, length);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  _2.reduce = _2.foldl = _2.inject = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  _2.reduceRight = _2.foldr = createReduce(-1);\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _2.find = _2.detect = function (obj, predicate, context) {\n    var key;\n    if (isArrayLike(obj)) {\n      key = _2.findIndex(obj, predicate, context);\n    } else {\n      key = _2.findKey(obj, predicate, context);\n    }\n    if (key !== void 0 && key !== -1) return obj[key];\n  };\n\n  // Return all the elements that pass a truth test.\n  // Aliased as `select`.\n  _2.filter = _2.select = function (obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    _2.each(obj, function (value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _2.reject = function (obj, predicate, context) {\n    return _2.filter(obj, _2.negate(cb(predicate)), context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Aliased as `all`.\n  _2.every = _2.all = function (obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _2.keys(obj),\n      length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Aliased as `any`.\n  _2.some = _2.any = function (obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _2.keys(obj),\n      length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  };
1\n\n  // Determine if the array or object contains a given item (using `===`).\n  // Aliased as `includes` and `include`.\n  _2.contains = _2.includes = _2.include = function (obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = _2.values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return _2.indexOf(obj, item, fromIndex) >= 0;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _2.invoke = function (obj, method) {\n    var args = slice.call(arguments, 2);\n    var isFunc = _2.isFunction(method);\n    return _2.map(obj, function (value) {\n      var func = isFunc ? method : value[method];\n      return func == null ? func : func.apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _2.pluck = function (obj, key) {\n    return _2.map(obj, _2.property(key));\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // containing specific `key:value` pairs.\n  _2.where = function (obj, attrs) {\n    return _2.filter(obj, _2.matcher(attrs));\n  };\n\n  // Convenience version of a common use case of `find`: getting the first object\n  // containing specific `key:value` pairs.\n  _2.findWhere = function (obj, attrs) {\n    return _2.find(obj, _2.matcher(attrs));\n  };\n\n  // Return the maximum element (or element-based computation).\n  _2.max = function (obj, iteratee, context) {\n    var result = -Infinity,\n      lastComputed = -Infinity,\n      value,\n      computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _2.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _2.each(obj, function (value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _2.min = function (obj, iteratee, context) {\n    var result = Infinity,\n      lastComputed = Infinity,\n      value,\n      computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _2.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _2.each(obj, function (value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Shuffle a collection, using the modern version of the\n  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  _2.shuffle = function (obj) {\n    var set = isArrayLike(obj) ? obj : _2.values(obj);\n    var length = set.length;\n    var shuffled = Array(length);\n    for (var index = 0, rand; index < length; index++) {\n      rand = _2.random(0, index);\n      if (rand !== index) shuffled[index] = shuffled[rand];\n      shuffled[rand] = set[index];\n    }\n    return shuffled;\n  };\n\n  // Sample **n** random values from a collection.\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `map`.\n  _2.sample = function (obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = _2.values(obj);\n      return obj[_2.random(obj.length - 1)];\n    }\n    return _2.shuffle(obj).slice(0, Math.max(0, n));\n  };\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  _2.sortBy = function (obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    return _2.pluck(_2.map(obj, function (value, index, list) {\n      return {\n        value: value,\n        index: index,\n        criteria: iteratee(value, index, list)\n      };\n    }).sort(function (left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function group(behavior) {\n    return function (obj, iteratee, context) {\n      var result = {};\n      iteratee = cb(iteratee, context);\n      _2.each(obj, function (value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _2.groupBy = group(function (result, value, key) {\n    if (_2.has(result, key)) result[key].push(value);else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `groupBy`, but for\n  // when you know that your index values will be unique.\n  _2.indexBy = group(function (result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _2.countBy = group(function (result, value, key) {\n    if (_2.has(result, key)) result[key]++;else result[key] = 1;\n  });\n\n  // Safely create a real, live array from anything iterable.\n  _2.toArray = function (obj) {\n    if (!obj) return [];\n    if (_2.isArray(obj)) return slice.call(obj);\n    if (isArrayLike(obj)) return _2.map(obj, _2.identity);\n    return _2.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _2.size = function (obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : _2.keys(obj).length;\n  };\n\n  // Split a collection into two arrays: one whose elements all satisfy the given\n  // predicate, and one whose elements all do not satisfy the predicate.\n  _2.partition = function (obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var pass = [],\n      fail = [];\n    _2.each(obj, function (value, key, obj) {\n      (predicate(value, key, obj) ? pass : fail).push(value);\n    });\n    return [pass, fail];\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _2.first = _2.head = _2.take = function (array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[0];\n    return _2.initial(array, array.length - n);\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  _2.initial = function (array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  _2.last = function (array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[array.length - 1];\n    return _2.rest(array, Math.max(0, array.length - n));\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array.\n  _2.rest = _2.tail = _2.drop = function (array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  };
1\n\n  // Trim out all falsy values from an array.\n  _2.compact = function (array) {\n    return _2.filter(array, _2.identity);\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var _flatten = function flatten(input, shallow, strict, startIndex) {\n    var output = [],\n      idx = 0;\n    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (_2.isArray(value) || _2.isArguments(value))) {\n        //flatten current level of array or arguments object\n        if (!shallow) value = _flatten(value, shallow, strict);\n        var j = 0,\n          len = value.length;\n        output.length += len;\n        while (j < len) {\n          output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  };\n\n  // Flatten out an array, either recursively (by default), or just one level.\n  _2.flatten = function (array, shallow) {\n    return _flatten(array, shallow, false);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _2.without = function (array) {\n    return _2.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _2.uniq = _2.unique = function (array, isSorted, iteratee, context) {\n    if (!_2.isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n        computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!_2.contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!_2.contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _2.union = function () {\n    return _2.uniq(_flatten(arguments, true, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _2.intersection = function (array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (_2.contains(result, item)) continue;\n      for (var j = 1; j < argsLength; j++) {\n        if (!_2.contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _2.difference = function (array) {\n    var rest = _flatten(arguments, true, true, 1);\n    return _2.filter(array, function (value) {\n      return !_2.contains(rest, value);\n    });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _2.zip = function () {\n    return _2.unzip(arguments);\n  };\n\n  // Complement of _.zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices\n  _2.unzip = function (array) {\n    var length = array && _2.max(array, getLength).length || 0;\n    var result = Array(length);\n    for (var index = 0; index < length; index++) {\n      result[index] = _2.pluck(array, index);\n    }\n    return result;\n  };\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values.\n  _2.object = function (list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length;
1 i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // Generator function to create the findIndex and findLastIndex functions\n  function createPredicateIndexFinder(dir) {\n    return function (array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a predicate test\n  _2.findIndex = createPredicateIndexFinder(1);\n  _2.findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _2.sortedIndex = function (array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0,\n      high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1;else high = mid;\n    }\n    return low;\n  };\n\n  // Generator function to create the indexOf and lastIndexOf functions\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function (array, item, idx) {\n      var i = 0,\n        length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), _2.isNaN);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _2.indexOf = createIndexFinder(1, _2.findIndex, _2.sortedIndex);\n  _2.lastIndexOf = createIndexFinder(-1, _2.findLastIndex);\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _2.range = function (start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = step || 1;\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Determines whether to execute a function as a constructor\n  // or a normal function with the provided arguments\n  var executeBound = function executeBound(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (_2.isObject(result)) return result;\n    return self;\n  };\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n  // available.\n  _2.bind = function (func, context) {\n    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_2.isFunction(func)) throw new TypeError('Bind must be called on a function');\n    var args = slice.call(arguments, 2);\n    var _bound = function bound() {\n      return executeBound(func, _bound, context, this, args.concat(slice.call(arguments)));\n    };\n    return _bound;\n  };\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. _ acts\n  // as a placeholder, allowing any combination of arguments to be pre-filled.\n  _2.partial = function (func) {\n    var boundArgs = slice.call(arguments, 1);\n    var _bound2 = function bound() {\n      var position = 0,\n        length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length;
1 i++) {\n        args[i] = boundArgs[i] === _2 ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, _bound2, this, this, args);\n    };\n    return _bound2;\n  };\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  _2.bindAll = function (obj) {\n    var i,\n      length = arguments.length,\n      key;\n    if (length <= 1) throw new Error('bindAll must be passed function names');\n    for (i = 1; i < length; i++) {\n      key = arguments[i];\n      obj[key] = _2.bind(obj[key], obj);\n    }\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _2.memoize = function (func, hasher) {\n    var _memoize = function memoize(key) {\n      var cache = _memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!_2.has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    _memoize.cache = {};\n    return _memoize;\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _2.delay = function (func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function () {\n      return func.apply(null, args);\n    }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _2.defer = _2.partial(_2.delay, _2, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  _2.throttle = function (func, wait, options) {\n    var context, args, result;\n    var timeout = null;\n    var previous = 0;\n    if (!options) options = {};\n    var later = function later() {\n      previous = options.leading === false ? 0 : _2.now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n    return function () {\n      var now = _2.now();\n      if (!previous && options.leading === false) previous = now;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _2.debounce = function (func, wait, immediate) {\n    var timeout, args, context, timestamp, result;\n    var _later = function later() {\n      var last = _2.now() - timestamp;\n      if (last < wait && last >= 0) {\n        timeout = setTimeout(_later, wait - last);\n      } else {\n        timeout = null;\n        if (!immediate) {\n          result = func.apply(context, args);\n          if (!timeout) context = args = null;\n        }\n      }\n    };\n    return function () {\n      context = this;\n      args = arguments;\n      timestamp = _2.now();\n      var callNow = immediate && !timeout;\n      if (!timeout) timeout = setTimeout(_later, wait);\n      if (callNow) {\n        result = func.apply(context, args);\n        context = args = null;\n      }\n      return result;\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _2.wrap = function (func, wrapper) {\n    return _2.partial(wrapper, func);\n  };
1\n\n  // Returns a negated version of the passed-in predicate.\n  _2.negate = function (predicate) {\n    return function () {\n      return !predicate.apply(this, arguments);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _2.compose = function () {\n    var args = arguments;\n    var start = args.length - 1;\n    return function () {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  };\n\n  // Returns a function that will only be executed on and after the Nth call.\n  _2.after = function (times, func) {\n    return function () {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Returns a function that will only be executed up to (but not including) the Nth call.\n  _2.before = function (times, func) {\n    var memo;\n    return function () {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _2.once = _2.partial(_2.before, 2);\n\n  // Object Functions\n  // ----------------\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{\n    toString: null\n  }.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n  function collectNonEnumProps(obj, keys) {\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = _2.isFunction(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';
1\n    if (_2.has(obj, prop) && !_2.contains(keys, prop)) keys.push(prop);\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !_2.contains(keys, prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _2.keys = function (obj) {\n    if (!_2.isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (_2.has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve all the property names of an object.\n  _2.allKeys = function (obj) {\n    if (!_2.isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _2.values = function (obj) {\n    var keys = _2.keys(obj);\n    var length = keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[keys[i]];\n    }\n    return values;\n  };\n\n  // Returns the results of applying the iteratee to each element of the object\n  // In contrast to _.map it returns an object\n  _2.mapObject = function (obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = _2.keys(obj),\n      length = keys.length,\n      results = {},\n      currentKey;\n    for (var index = 0; index < length; index++) {\n      currentKey = keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  _2.pairs = function (obj) {\n    var keys = _2.keys(obj);\n    var length = keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [keys[i], obj[keys[i]]];\n    }\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _2.invert = function (obj) {\n    var result = {};\n    var keys = _2.keys(obj);\n    for (var i = 0, length = keys.length; i < length; i++) {\n      result[obj[keys[i]]] = keys[i];\n    }\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _2.functions = _2.methods = function (obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_2.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _2.extend = createAssigner(_2.allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in object(s)\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  _2.extendOwn = _2.assign = createAssigner(_2.keys);\n\n  // Returns the first key on an object that passes a predicate test\n  _2.findKey = function (obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = _2.keys(obj),\n      key;\n    for (var i = 0, length = keys.length; i < length; i++) {\n      key = keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  };\n\n  // Return a copy of the object only containing the whitelisted properties.\n  _2.pick = function (object, oiteratee, context) {\n    var result = {},\n      obj = object,\n      iteratee,\n      keys;\n    if (obj == null) return result;\n    if (_2.isFunction(oiteratee)) {\n      keys = _2.allKeys(obj);\n      iteratee = optimizeCb(oiteratee, context);\n    } else {\n      keys = _flatten(arguments, false, false, 1);\n      iteratee = function iteratee(value, key, obj) {\n        return key in obj;\n      };\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  };
1\n\n  // Return a copy of the object without the blacklisted properties.\n  _2.omit = function (obj, iteratee, context) {\n    if (_2.isFunction(iteratee)) {\n      iteratee = _2.negate(iteratee);\n    } else {\n      var keys = _2.map(_flatten(arguments, false, false, 1), String);\n      iteratee = function iteratee(value, key) {\n        return !_2.contains(keys, key);\n      };\n    }\n    return _2.pick(obj, iteratee, context);\n  };\n\n  // Fill in a given object with default properties.\n  _2.defaults = createAssigner(_2.allKeys, true);\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  _2.create = function (prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) _2.extendOwn(result, props);\n    return result;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _2.clone = function (obj) {\n    if (!_2.isObject(obj)) return obj;\n    return _2.isArray(obj) ? obj.slice() : _2.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _2.tap = function (obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  _2.isMatch = function (object, attrs) {\n    var keys = _2.keys(attrs),\n      length = keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  };\n\n  // Internal recursive comparison function for `isEqual`.\n  var _eq = function eq(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a instanceof _2) a = a._wrapped;\n    if (b instanceof _2) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, regular expressions, dates, and booleans are compared by value.\n      case '[object RegExp]':\n      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n    }\n    var areArrays = className === '[object Array]';\n    if (!areArrays) {\n      if (_typeof(a) != 'object' || _typeof(b) != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor,\n        bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_2.isFunction(aCtor) && aCtor instanceof aCtor && _2.isFunction(bCtor) && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!_eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var keys = _2.keys(a),\n        key;\n      length = keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (_2.ke
1ys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = keys[length];\n        if (!(_2.has(b, key) && _eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _2.isEqual = function (a, b) {\n    return _eq(a, b);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _2.isEmpty = function (obj) {\n    if (obj == null) return true;\n    if (isArrayLike(obj) && (_2.isArray(obj) || _2.isString(obj) || _2.isArguments(obj))) return obj.length === 0;\n    return _2.keys(obj).length === 0;\n  };\n\n  // Is a given value a DOM element?\n  _2.isElement = function (obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _2.isArray = nativeIsArray || function (obj) {\n    return toString.call(obj) === '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _2.isObject = function (obj) {\n    var type = _typeof(obj);\n    return type === 'function' || type === 'object' && !!obj;\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.\n  _2.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function (name) {\n    _2['is' + name] = function (obj) {\n      return toString.call(obj) === '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_2.isArguments(arguments)) {\n    _2.isArguments = function (obj) {\n      return _2.has(obj, 'callee');\n    };\n  }\n\n  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,\n  // IE 11 (#1621), and in Safari 8 (#1929).\n  if (typeof /./ != 'function' && (typeof Int8Array === \"undefined\" ? \"undefined\" : _typeof(Int8Array)) != 'object') {\n    _2.isFunction = function (obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  // Is a given object a finite number?\n  _2.isFinite = function (obj) {\n    return isFinite(obj) && !isNaN(parseFloat(obj));\n  };\n\n  // Is the given value `NaN`? (NaN is the only number which does not equal itself).\n  _2.isNaN = function (obj) {\n    return _2.isNumber(obj) && obj !== +obj;\n  };\n\n  // Is a given value a boolean?\n  _2.isBoolean = function (obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _2.isNull = function (obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _2.isUndefined = function (obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _2.has = function (obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _2.noConflict = function () {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iteratees.\n  _2.identity = function (value) {\n    return value;\n  };\n\n  // Predicate-generating functions. Often useful outside of Underscore.\n  _2.constant = function (value) {\n    return function () {\n      return value;\n    };\n  };\n  _2.noop = function () {};\n  _2.property = property;\n\n  // Generates a function for a given object that returns a given property.\n  _2.propertyOf = function (obj) {\n    return obj == null ? function () {} : function (key) {\n      return obj[key];\n    };\n  };\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  _2.matcher = _2.matches = function (attrs) {\n    attrs = _2.extendOwn({}, attrs);\n    return function (obj) {\n      return _2.isMatch(obj, attrs);\n    };\n  };\n\n  // Run a function **n** times.\n  _2.times = function (n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _2.random = function (min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  };\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  _2.now = Date.now || function () {\n    return new Date().getTime();\n  };\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  var unescapeMap = _2.invert(escapeMap);\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function createEscaper(map) {\n    var escaper = function escaper(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped\n    var source = '(?:' + _2.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');
1\n    return function (string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n  _2.escape = createEscaper(escapeMap);\n  _2.unescape = createEscaper(unescapeMap);\n\n  // If the value of the named `property` is a function then invoke it with the\n  // `object` as context; otherwise, return it.\n  _2.result = function (object, property, fallback) {\n    var value = object == null ? void 0 : object[property];\n    if (value === void 0) {\n      value = fallback;\n    }\n    return _2.isFunction(value) ? value.call(object) : value;\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _2.uniqueId = function (prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _2.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    \"\\u2028\": 'u2028',\n    \"\\u2029\": 'u2029'\n  };\n  var escaper = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n  var escapeChar = function escapeChar(match) {\n    return '\\\\' + escapes[match];\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  _2.template = function (text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = _2.defaults({}, settings, _2.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([(settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escaper, escapeChar);\n      index = offset + match.length;\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offest.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n    source = \"var __t,__p='',__j=Array.prototype.join,\" + \"print=function(){__p+=__j.call(arguments,'');};\\n\" + source + 'return __p;\\n';\n    try {\n      var render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n    var template = function template(data) {\n      return render.call(this, data, _2);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n    return template;\n  };\n\n  // Add a \"chain\" function. Start chaining a wrapped Underscore object.\n  _2.chain = function (obj) {\n    var instance = _2(obj);\n    instance._chain = true;\n    return instance;\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var result = function result(instance, obj) {\n    return instance._chain ? _2(obj).chain() : obj;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _2.mixin = function (obj) {\n    _2.each(_2.functions(obj), function (name) {\n      var func = _2[name] = obj[name];\n      _2.prototype[name] = function () {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return result(this, func.apply(_2, args));\n      };\n    });\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _2.mixin(_2);\n\n  // Add all mutator Array functions to the wrapper.\n  _2.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) {\n    var method = ArrayProto[name];\n    _2.prototype[name] = function () {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];\n      return result(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  _2.each(['concat', 'join', 'slice'], function (name) {\n    var method = ArrayProto[name];\n    _2.prototype[name] = function () {\n      return result(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  // Extracts the result from a wrapped and chained object.\n  _2.prototype.value = function () {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxy for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _2.prototype.valueOf = _2.prototype.toJSON = _2.prototype.value;\n  _2.prototype.toString = function () {\n    return '' + this._wrapped;\n  };\n\n  // AMD registration happens at the end for compatibility with AMD loaders\n  // that may not enforce next-turn semantics on modules. Even though general\n  // practice for AMD registration is to be anonymous, underscore registers\n  // as a named module because, like jQuery, it is a base library that is\n  // popular enough to be bundled in a third party lib, but not be part of\n  // an AMD load request. Those cases could generate an error when an\n  // anonymous define() is called outside of a loader request.\n  if (typeof define === 'function' && define.amd) {\n    define('underscore', [], function () {\n      return _2;\n    });\n  }\n}).call(this);"},7562:function(e){e.exports='function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }\n(function () {\n  \'use strict\';\n\n  var f,\n    g = [];\n  function l(a) {\n    g.push(a);\n    1 == g.length && f();\n  }\n  function m() {\n    for (; g.length;) g[0](), g.shift();\n  }\n  f = function f() {\n    setTimeout(m);\n  };\n  function n(a) {\n    this.a = p;\n    this.b = void 0;\n    this.f = [];\n    var b = this;\n    try {\n      a(function (a) {\n        q(b, a);\n      }, function (a) {\n        r(b, a);\n      });\n    } catch (c) {\n      r(b, c);\n    }\n  }\n  var p = 2;\n  function t(a) {\n    return new n(function (b, c) {\n      c(a);\n    });\n  }\n  function u(a) {\n    return new n(function (b) {\n      b(a);\n    });\n  }\n  function q(a, b) {\n    if (a.a == p) {\n      if (b == a) throw new TypeError();\n      var c = !1;
1\n      try {\n        var d = b && b.then;\n        if (null != b && "object" == _typeof(b) && "function" == typeof d) {\n          d.call(b, function (b) {\n            c || q(a, b);\n            c = !0;\n          }, function (b) {\n            c || r(a, b);\n            c = !0;\n          });\n          return;\n        }\n      } catch (e) {\n        c || r(a, e);\n        return;\n      }\n      a.a = 0;\n      a.b = b;\n      v(a);\n    }\n  }\n  function r(a, b) {\n    if (a.a == p) {\n      if (b == a) throw new TypeError();\n      a.a = 1;\n      a.b = b;\n      v(a);\n    }\n  }\n  function v(a) {\n    l(function () {\n      if (a.a != p) for (; a.f.length;) {\n        var b = a.f.shift(),\n          c = b[0],\n          d = b[1],\n          e = b[2],\n          b = b[3];\n        try {\n          0 == a.a ? "function" == typeof c ? e(c.call(void 0, a.b)) : e(a.b) : 1 == a.a && ("function" == typeof d ? e(d.call(void 0, a.b)) : b(a.b));\n        } catch (h) {\n          b(h);\n        }\n      }\n    });\n  }\n  n.prototype.g = function (a) {\n    return this.c(void 0, a);\n  };\n  n.prototype.c = function (a, b) {\n    var c = this;\n    return new n(function (d, e) {\n      c.f.push([a, b, d, e]);\n      v(c);\n    });\n  };\n  function w(a) {\n    return new n(function (b, c) {\n      function d(c) {\n        return function (d) {\n          h[c] = d;\n          e += 1;\n          e == a.length && b(h);\n        };\n      }\n      var e = 0,\n        h = [];\n      0 == a.length && b(h);\n      for (var k = 0; k < a.length; k += 1) u(a[k]).c(d(k), c);\n    });\n  }\n  function x(a) {\n    return new n(function (b, c) {\n      for (var d = 0; d < a.length; d += 1) u(a[d]).c(b, c);\n    });\n  }\n  ;\n  window.Promise || (window.Promise = n, window.Promise.resolve = u, window.Promise.reject = t, window.Promise.race = x, window.Promise.all = w, window.Promise.prototype.then = n.prototype.c, window.Promise.prototype["catch"] = n.prototype.g);\n})();\n(function () {\n  function l(a, b) {\n    document.addEventListener ? a.addEventListener("scroll", b, !1) : a.attachEvent("scroll", b);\n  }\n  function m(a) {\n    document.body ? a() : document.addEventListener ? document.addEventListener("DOMContentLoaded", function c() {\n      document.removeEventListener("DOMContentLoaded", c);\n      a();\n    }) : document.attachEvent("onreadystatechange", function k() {\n      if ("interactive" == document.readyState || "complete" == document.readyState) document.detachEvent("onreadystatechange", k), a();\n    });\n  }\n  ;\n  function q(a) {\n    this.a = document.createElement("div");\n    this.a.setAttribute("aria-hidden", "true");\n    this.a.appendChild(document.createTextNode(a));\n    this.b = document.createElement("span");\n    this.c = document.createElement("span");\n    this.h = document.createElement("span");\n    this.f = document.createElement("span");\n    this.g = -1;\n    this.b.style.cssText = "max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";\n    this.c.style.cssText = "max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";\n    this.f.style.cssText = "max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";\n    this.h.style.cssText = "display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";\n    this.b.appendChild(this.h);\n    this.c.appendChild(this.f);\n    this.a.appendChild(this.b);\n    this.a.appendChild(this.c);\n  }\n  function w(a, b) {\n    a.a.style.cssText = "max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;left:-999px;white-space:nowrap;font:" + b + ";";\n  }\n  function x(a) {\n    var b = a.a.offsetWidth,\n      c = b + 100;\n    a.f.style.width = c + "px";\n    a.c.scrollLeft = c;\n    a.b.scrollLeft = a.b.scrollWidth + 100;\n    return a.g !== b ? (a.g = b, !0) : !1;\n  }\n  function z(a, b) {\n    function c() {\n      var a = k;\n      x(a) && null !== a.a.parentNode && b(a.g);\n    }\n    var k = a;\n    l(a.b, c);\n    l(a.c, c);\n    x(a);\n  }\n  ;\n  function A(a, b) {\n    var c = b || {};\n    this.family = a;\n    this.style = c.style || "normal";\n    this.weight = c.weight || "normal";
1\n    this.stretch = c.stretch || "normal";\n  }\n  var B = null,\n    C = null,\n    D = null;\n  function H() {\n    if (null === C) {\n      var a = document.createElement("div");\n      try {\n        a.style.font = "condensed 100px sans-serif";\n      } catch (b) {}\n      C = "" !== a.style.font;\n    }\n    return C;\n  }\n  function I(a, b) {\n    return [a.style, a.weight, H() ? a.stretch : "", "100px", b].join(" ");\n  }\n  A.prototype.load = function (a, b) {\n    var c = this,\n      k = a || "BESbswy",\n      y = b || 3E3,\n      E = new Date().getTime();\n    return new Promise(function (a, b) {\n      null === D && (D = !!window.FontFace);\n      if (D) {\n        var J = new Promise(function (a, b) {\n            function e() {\n              new Date().getTime() - E >= y ? b() : document.fonts.load(I(c, c.family), k).then(function (c) {\n                1 <= c.length ? a() : setTimeout(e, 25);\n              }, function () {\n                b();\n              });\n            }\n            e();\n          }),\n          K = new Promise(function (a, c) {\n            setTimeout(c, y);\n          });\n        Promise.race([K, J]).then(function () {\n          a(c);\n        }, function () {\n          b(c);\n        });\n      } else m(function () {\n        function r() {\n          var b;\n          if (b = -1 != f && -1 != g || -1 != f && -1 != h || -1 != g && -1 != h) (b = f != g && f != h && g != h) || (null === B && (b = /AppleWebKit\\/([0-9]+)(?:\\.([0-9]+))/.exec(window.navigator.userAgent), B = !!b && (536 > parseInt(b[1], 10) || 536 === parseInt(b[1], 10) && 11 >= parseInt(b[2], 10))), b = B && (f == t && g == t && h == t || f == u && g == u && h == u || f == v && g == v && h == v)), b = !b;\n          b && (null !== d.parentNode && d.parentNode.removeChild(d), clearTimeout(G), a(c));\n        }\n        function F() {\n          if (new Date().getTime() - E >= y) null !== d.parentNode && d.parentNode.removeChild(d), b(c);else {\n            var a = document.hidden;\n            if (!0 === a || void 0 === a) f = e.a.offsetWidth, g = n.a.offsetWidth, h = p.a.offsetWidth, r();\n            G = setTimeout(F, 50);\n          }\n        }\n        var e = new q(k),\n          n = new q(k),\n          p = new q(k),\n          f = -1,\n          g = -1,\n          h = -1,\n          t = -1,\n          u = -1,\n          v = -1,\n          d = document.createElement("div"),\n          G = 0;\n        d.dir = "ltr";\n        w(e, I(c, "sans-serif"));\n        w(n, I(c, "serif"));\n        w(p, I(c, "monospace"));\n        d.appendChild(e.a);\n        d.appendChild(n.a);\n        d.appendChild(p.a);\n        document.body.appendChild(d);\n        t = e.a.offsetWidth;\n        u = n.a.offsetWidth;\n        v = p.a.offsetWidth;\n        F();\n        z(e, function (a) {\n          f = a;\n          r();\n        });\n        w(e, I(c, \'"\' + c.family + \'",sans-serif\'));\n        z(n, function (a) {\n          g = a;\n          r();\n        });\n        w(n, I(c, \'"\' + c.family + \'",serif\'));\n        z(p, function (a) {\n          h = a;\n          r();\n        });\n        w(p, I(c, \'"\' + c.family + \'",monospace\'));\n      });\n    });\n  };\n  "undefined" !== typeof module ? module.exports = A : (window.FontFaceObserver = A, window.FontFaceObserver.prototype.load = A.prototype.load);\n})();'},7731:function(e){e.exports="/**\r\n * Navbar Secondary (Dazed media sites menu)\r\n * Handles the opening/closing of the secondary navigation and scroll locking\r\n */\nwindow.AM = window.AM || {};\nAM.navbarSecondary = function () {\n  var $navbarSecondaryShowHideCheckbox;\n  var $navbarSecondaryShowHideLabel;\n  var $navbarSecondaryOverlay;\n  var $navbarSecondary;\n  var $body;\n  var windowScrollPos;\n  function scrollAtTop() {\n    DL.Utilities.getBodyElement().attr('data-scroll-at-top', DL.Utilities.WindowScrollTop() == 0 ? 'yes' : 'no');\n  }\n  function lockScroll(e) {\n    e.preventDefault();\n    e.stopPropagation();\n    $(window).scrollTop(windowScrollPos);\n  }\n  function unlockScroll() {\n    $navbarSecondaryOverlay.empty();\n    $body.off('mousewheel.stopScroll touchmove.stopScroll DOMMouseScroll.stopScroll');
1\n    $(window).off('scroll.stopScroll');\n\n    // Re-enable scroll tracking\n    if ($('body[data-scroll-at-top=\"yes\"]').length) {\n      $(document).on('scroll.scrollAtTop', _.throttle(scrollAtTop, 100));\n    }\n  }\n  function init() {\n    $navbarSecondaryShowHideCheckbox = $('#navbar-secondary-show-hide');\n    $navbarSecondaryShowHideLabel = $('.navbar-secondary-show-hide');\n    $navbarSecondaryOverlay = $('.navbar-secondary-overlay');\n    $navbarSecondary = $('.navbar-secondary');\n    $body = $('body');\n    if (!$navbarSecondaryShowHideCheckbox.length) {\n      return; // Exit if navbar secondary elements don't exist\n    }\n    if (!DL.Utilities.isMobile()) {\n      $navbarSecondaryShowHideLabel.on('click.navbarSecondaryIconMenu', function (e) {\n        windowScrollPos = $(window).scrollTop();\n        if ($navbarSecondaryOverlay.is(':empty')) {\n          $navbarSecondaryOverlay.append('<a style=\"width: 100%; height: 100%; display: block;\"></a>');\n        }\n\n        // Check if navbar is currently closed (checkbox unchecked) - it will open after this click\n        var isOpening = !$navbarSecondaryShowHideCheckbox.prop('checked');\n        if (isOpening) {\n          $body.on('mousewheel.stopScroll touchmove.stopScroll DOMMouseScroll.stopScroll', lockScroll);\n          $(window).on('scroll.stopScroll', lockScroll);\n\n          // Disable scroll tracking to prevent elements triggering changes\n          if ($('body[data-scroll-at-top=\"yes\"]').length) {\n            $(document).off('scroll.scrollAtTop');\n          }\n        } else {\n          unlockScroll();\n        }\n      });\n      $navbarSecondaryOverlay.on('click', function (e) {\n        $navbarSecondaryShowHideCheckbox.prop('checked', false);\n        unlockScroll();\n      });\n    } else {\n      // Mobile: disabled scrolling within the navbar for now\n      $navbarSecondary.on('touchmove scroll', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        return false;\n      });\n    }\n\n    // Show trigger button if loaded\n    $navbarSecondaryShowHideLabel.addClass('navbar-secondary-show');\n  }\n  return {\n    init: init\n  };\n}();"},8110:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  function tracking(e) {\n    var $this = $(e.currentTarget);\n    var key = $this.attr('data-title');\n    var val = $this.attr('data-value') || key;\n    var href = $this.attr('href');\n    if ($this.attr('target') === '_blank') {\n      analytics.trackEvent(key, val, href);\n    } else {\n      analytics.trackEventsOnNextPageLoad(key, val, href);\n    }\n  }\n  DL.tracking = tracking;\n  var analytics;\n  (function (analytics) {\n    function track() {\n      var args = [];\n      for (var _i = 0; _i < arguments.length;
1 _i++) {\n        args[_i - 0] = arguments[_i];\n      }\n      if (DL.TestMode) {\n        return;\n      }\n      //  var args = Array.prototype.slice.call(arguments);\n      //  window._gaq.push(args);\n      //     DL.Utilities.consoleLog('analytics', args);\n    }\n    analytics.track = track;\n    function trackEvent(event, action, label) {\n      if (event != null && event.length > 0) {\n        track('_trackEvent', event, action, label);\n      } else {}\n    }\n    analytics.trackEvent = trackEvent;\n    function trackNonInteractionEvent(event, action, label) {\n      if (event != null && event.length > 0) {\n        DL.analytics.track('_trackEvent', event, action, label, null, true);\n      } else {}\n    }\n    analytics.trackNonInteractionEvent = trackNonInteractionEvent;\n    function trackEventsOnNextPageLoad(event, action, label) {\n      if (!window.sessionStorage) {\n        DL.analytics.trackEvent(event, action, label);\n        return;\n      } else {\n        var trackEventsOnNextPageLoad = window.sessionStorage.getItem('trackEventsOnNextPageLoad');\n        if (trackEventsOnNextPageLoad != null && trackEventsOnNextPageLoad.length > 0) {\n          trackEventsOnNextPageLoad = JSON.parse(trackEventsOnNextPageLoad);\n        } else {\n          trackEventsOnNextPageLoad = [];\n        }\n        trackEventsOnNextPageLoad.push({\n          event: event,\n          action: action,\n          label: label\n        });\n        window.sessionStorage.setItem('trackEventsOnNextPageLoad', JSON.stringify(trackEventsOnNextPageLoad));\n      }\n    }\n    analytics.trackEventsOnNextPageLoad = trackEventsOnNextPageLoad;\n    function fireTrackEventsOnNextPageLoad() {\n      if (window.sessionStorage) {\n        var trackEventsOnNextPageLoad = window.sessionStorage.getItem('trackEventsOnNextPageLoad');\n        if (trackEventsOnNextPageLoad != null && trackEventsOnNextPageLoad.length > 0) {\n          JSON.parse(trackEventsOnNextPageLoad).forEach(function (trackObject) {\n            trackNonInteractionEvent(trackObject.event, trackObject.action, trackObject.label);\n          });\n          window.sessionStorage.setItem('trackEventsOnNextPageLoad', \"\");\n        }\n      }\n    }\n    analytics.fireTrackEventsOnNextPageLoad = fireTrackEventsOnNextPageLoad;\n    function trackPageview(url, title) {\n      //  Google Analytics\n      track('_trackPageview', url);\n      //  Chartbeat\n      if (!_.isUndefined(window.pSUPERFLY)) {\n        if (!_.isUndefined(window._sf_async_config)) {\n          window._sf_async_config.sponsorName = '';\n        }\n        window.pSUPERFLY.virtualPage(url, title);\n      }\n    }\n    analytics.trackPageview = trackPageview;\n  })(analytics = DL.analytics || (DL.analytics = {}));\n})(DL || (DL = {}));\n$(function () {\n  setTimeout(DL.analytics.fireTrackEventsOnNextPageLoad, 1500);\n});"},8291:function(e){e.exports="function _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\n/*!\r\n * modernizr v3.5.0\r\n * Build https://modernizr.com/download?-csspositionsticky-csstransforms-dataset-history-touchevents-addtest-mq-teststyles-dontmin\r\n *\r\n * Copyright (c)\r\n *  Faruk Ates\r\n *  Paul Irish\r\n *  Alex Sexton\r\n *  Ryan Seddon\r\n *  Patrick Kettner\r\n *  Stu Cox\r\n *  Richard Herrera\r\n\r\n * MIT License\r\n */\n\n/*\r\n * Modernizr tests which native CSS3 and HTML5 features are available in the\r\n * current UA and makes the results available to you in two ways: as properties on\r\n * a global `Modernizr` object, and as classes on the `<html>` element. This\r\n * information allows you to progressively enhance your pages with a granular level\r\n * of control over the experience.\r\n*/\n\n;\n(function (window, document, undefined) {\n  var tests = [];\n\n  /**\r\n   *\r\n   * ModernizrProto is the constructor for Modernizr\r\n   *\r\n   * @class\r\n   * @access public\r\n   */\n\n  var ModernizrProto = {\n    // The current version, dummy\n    _version: '3.5.0',\n    // Any settings that don't work as separate modules\n    // can go in here as configuration.\n    _config: {\
1n      'classPrefix': '',\n      'enableClasses': true,\n      'enableJSClass': true,\n      'usePrefixes': true\n    },\n    // Queue of tests\n    _q: [],\n    // Stub these for people who are listening\n    on: function on(test, cb) {\n      // I don't really think people should do this, but we can\n      // safe guard it a bit.\n      // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.\n      // This is in case people listen to synchronous tests. I would leave it out,\n      // but the code to *disallow* sync tests in the real version of this\n      // function is actually larger than this.\n      var self = this;\n      setTimeout(function () {\n        cb(self[test]);\n      }, 0);\n    },\n    addTest: function addTest(name, fn, options) {\n      tests.push({\n        name: name,\n        fn: fn,\n        options: options\n      });\n    },\n    addAsyncTest: function addAsyncTest(fn) {\n      tests.push({\n        name: null,\n        fn: fn\n      });\n    }\n  };\n\n  // Fake some of Object.create so we can force non test results to be non \"own\" properties.\n  var Modernizr = function Modernizr() {};\n  Modernizr.prototype = ModernizrProto;\n\n  // Leak modernizr globally when you `require` it rather than force it here.\n  // Overwrite name so constructor name is nicer :D\n  Modernizr = new Modernizr();\n\n  /*!\r\n  {\r\n    \"name\": \"History API\",\r\n    \"property\": \"history\",\r\n    \"caniuse\": \"history\",\r\n    \"tags\": [\"history\"],\r\n    \"authors\": [\"Hay Kranen\", \"Alexander Farkas\"],\r\n    \"notes\": [{\r\n      \"name\": \"W3C Spec\",\r\n      \"href\": \"https://www.w3.org/TR/html51/browsers.html#the-history-interface\"\r\n    }, {\r\n      \"name\": \"MDN documentation\",\r\n      \"href\": \"https://developer.mozilla.org/en-US/docs/Web/API/window.history\"\r\n    }],\r\n    \"polyfills\": [\"historyjs\", \"html5historyapi\"]\r\n  }\r\n  !*/\n  /* DOC\r\n  Detects support for the History API for manipulating the browser session history.\r\n  */\n\n  Modernizr.addTest('history', function () {\n    // Issue #733\n    // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on history support\n    // Unfortunately support is really buggy and there is no clean way to detect\n    // these bugs, so we fall back to a user agent sniff :(\n    var ua = navigator.userAgent;\n\n    // We only want Android 2 and 4.0, stock browser, and not Chrome which identifies\n    // itself as 'Mobile Safari' as well, nor Windows Phone (issue #1471).\n    if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1 &&\n    // Since all documents on file:// share an origin, the History apis are\n    // blocked there as well\n    location.protocol !== 'file:') {\n      return false;\n    }\n\n    // Return the regular check\n    return window.history && 'pushState' in window.history;\n  });\n  var classes = [];\n\n  /**\r\n   * is returns a boolean if the typeof an obj is exactly type.\r\n   *\r\n   * @access private\r\n   * @function is\r\n   * @param {*} obj - A thing we want to check the type of\r\n   * @param {string} type - A string to compare the typeof against\r\n   * @returns {boolean}\r\n   */\n\n  function is(obj, type) {\n    return _typeof(obj) === type;\n  }\n  ;\n\n  /**\r\n   * Run through all tests and detect their support in the current UA.\r\n   *\r\n   * @access private\r\n   */\n\n  function testRunner() {\n    var featureNames;\n    var feature;\n    var aliasIdx;\n    var result;\n    var nameIdx;\n    var featureName;\n    var featureNameSplit;\n    for (var featureIdx in tests) {\n      if (tests.hasOwnProperty(featureIdx)) {\n        featureNames = [];\n        feature = tests[featureIdx];\n        // run the test, throw the return value into the Modernizr,\n        // then based on that boolean, define an appropriate className\n        // and push it into an array of classes we'll join later.\n        //\n        // If there is no name, it's an 'async' test that is run,\n        // but not directly added to the object. That should\n        // be done with a post-run addTest call.\n        if (feature.name) {\n          featureNames.push(feature.name.toLowerCase());\n          if (feature.options && feature.options.aliases && feature.options.aliases.length) {\n            // Add all the aliases into the names list\n            for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {\n              featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());\n            }\n          }\n        }\n\n        // Run the test, or use the raw value if it's not a function\n        result = is(feature.fn, 'function') ? feature.fn() : feature.fn;\n\n        // Set each of the names on the Modernizr object\n        for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {\n          featureName = featureNames[nameIdx];
1\n          // Support dot properties as sub tests. We don't do checking to make sure\n          // that the implied parent tests have been added. You must call them in\n          // order (either in the test, or make the parent test a dependency).\n          //\n          // Cap it to TWO to make the logic simple and because who needs that kind of subtesting\n          // hashtag famous last words\n          featureNameSplit = featureName.split('.');\n          if (featureNameSplit.length === 1) {\n            Modernizr[featureNameSplit[0]] = result;\n          } else {\n            // cast to a Boolean, if not one already\n            if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {\n              Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);\n            }\n            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;\n          }\n          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));\n        }\n      }\n    }\n  }\n  ;\n\n  /**\r\n   * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support\r\n   *\r\n   * @author kangax\r\n   * @access private\r\n   * @function hasOwnProp\r\n   * @param {object} object - The object to check for a property\r\n   * @param {string} property - The property to check for\r\n   * @returns {boolean}\r\n   */\n\n  // hasOwnProperty shim by kangax needed for Safari 2.0 support\n  var hasOwnProp;\n  (function () {\n    var _hasOwnProperty = {}.hasOwnProperty;\n    /* istanbul ignore else */\n    /* we have no way of testing IE 5.5 or safari 2,\r\n     * so just assume the else gets hit */\n    if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {\n      hasOwnProp = function hasOwnProp(object, property) {\n        return _hasOwnProperty.call(object, property);\n      };\n    } else {\n      hasOwnProp = function hasOwnProp(object, property) {\n        /* yes, this can give false positives/negatives, but most of the time we don't care about those */\n        return property in object && is(object.constructor.prototype[property], 'undefined');\n      };\n    }\n  })();\n\n  /**\r\n   * List of property values to set for css tests. See ticket #21\r\n   * http://git.io/vUGl4\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr._prefixes\r\n   * @optionName Modernizr._prefixes\r\n   * @optionProp prefixes\r\n   * @access public\r\n   * @example\r\n   *\r\n   * Modernizr._prefixes is the internal list of prefixes that we test against\r\n   * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply\r\n   * an array of kebab-case vendor prefixes you can use within your code.\r\n   *\r\n   * Some common use cases include\r\n   *\r\n   * Generating all possible prefixed version of a CSS property\r\n   * ```js\r\n   * var rule = Modernizr._prefixes.join('transform: rotate(20deg); ');\r\n   *\r\n   * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);'\r\n   * ```\r\n   *\r\n   * Generating all possible prefixed version of a CSS value\r\n   * ```js\r\n   * rule = 'display:' +  Modernizr._prefixes.join('flex; display:') + 'flex';\r\n   *\r\n   * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex'\r\n   * ```\r\n   */\n\n  // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test\n  // values in feature detects to continue to work\n  var prefixes = ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['', ''];\n\n  // expose these for the plugin API. Look in the source for how to join() them against your input\n  ModernizrProto._prefixes = prefixes;\n\n  /**\r\n   * docElement is a convenience wrapper to grab the root element of the document\r\n   *\r\n   * @access private\r\n   * @returns {HTMLElement|SVGElement} The root element of the document\r\n   */\n\n  var docElement = document.documentElement;\n\n  /**\r\n   * A convenience helper to check if the document we are running in is an SVG document\r\n   *\r\n   * @access private\r\n   * @returns {boolean}\r\n   */\n\n  var isSVG = docElement.nodeName.toLowerCase() === 'svg';\n\n  /**\r\n   * setClasses takes an array of class names and adds them to the root element\r\n   *\r\n   * @access private\r\n   * @function setClasses\r\n   * @param {string[]} classes - Array of class names\r\n   */\n\n  // Pass in an and array of class names, e.g.:\n  //  ['no-webp', 'borderradiu
1s', ...]\n  function setClasses(classes) {\n    var className = docElement.className;\n    var classPrefix = Modernizr._config.classPrefix || '';\n    if (isSVG) {\n      className = className.baseVal;\n    }\n\n    // Change `no-js` to `js` (independently of the `enableClasses` option)\n    // Handle classPrefix on this too\n    if (Modernizr._config.enableJSClass) {\n      var reJS = new RegExp('(^|\\\\s)' + classPrefix + 'no-js(\\\\s|$)');\n      className = className.replace(reJS, '$1' + classPrefix + 'js$2');\n    }\n    if (Modernizr._config.enableClasses) {\n      // Add the new classes\n      className += ' ' + classPrefix + classes.join(' ' + classPrefix);\n      if (isSVG) {\n        docElement.className.baseVal = className;\n      } else {\n        docElement.className = className;\n      }\n    }\n  }\n  ;\n\n  // _l tracks listeners for async tests, as well as tests that execute after the initial run\n  ModernizrProto._l = {};\n\n  /**\r\n   * Modernizr.on is a way to listen for the completion of async tests. Being\r\n   * asynchronous, they may not finish before your scripts run. As a result you\r\n   * will get a possibly false negative `undefined` value.\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr.on\r\n   * @access public\r\n   * @function on\r\n   * @param {string} feature - String name of the feature detect\r\n   * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not\r\n   * @example\r\n   *\r\n   * ```js\r\n   * Modernizr.on('flash', function( result ) {\r\n   *   if (result) {\r\n   *    // the browser has flash\r\n   *   } else {\r\n   *     // the browser does not have flash\r\n   *   }\r\n   * });\r\n   * ```\r\n   */\n\n  ModernizrProto.on = function (feature, cb) {\n    // Create the list of listeners if it doesn't exist\n    if (!this._l[feature]) {\n      this._l[feature] = [];\n    }\n\n    // Push this test on to the listener list\n    this._l[feature].push(cb);\n\n    // If it's already been resolved, trigger it on next tick\n    if (Modernizr.hasOwnProperty(feature)) {\n      // Next Tick\n      setTimeout(function () {\n        Modernizr._trigger(feature, Modernizr[feature]);\n      }, 0);\n    }\n  };\n\n  /**\r\n   * _trigger is the private function used to signal test completion and run any\r\n   * callbacks registered through [Modernizr.on](#modernizr-on)\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr._trigger\r\n   * @access private\r\n   * @function _trigger\r\n   * @param {string} feature - string name of the feature detect\r\n   * @param {function|boolean} [res] - A feature detection function, or the boolean =\r\n   * result of a feature detection function\r\n   */\n\n  ModernizrProto._trigger = function (feature, res) {\n    if (!this._l[feature]) {\n      return;\n    }\n    var cbs = this._l[feature];\n\n    // Force async\n    setTimeout(function () {\n      var i, cb;\n      for (i = 0; i < cbs.length; i++) {\n        cb = cbs[i];\n        cb(res);\n      }\n    }, 0);\n\n    // Don't trigger these again\n    delete this._l[feature];\n  };\n\n  /**\r\n   * addTest allows you to define your own feature detects that are not currently\r\n   * included in Modernizr (under the covers it's the exact same code Modernizr\r\n   * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result\r\n   * will be added onto the Modernizr object, as well as an appropriate className set on\r\n   * the html element when configured to do so\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr.addTest\r\n   * @optionName Modernizr.addTest()\r\n   * @optionProp addTest\r\n   * @access public\r\n   * @function addTest\r\n   * @param {string|object} feature - The string name of the feature detect, or an\r\n   * object of feature detect names and test\r\n   * @param {function|boolean} test - Function returning true if feature is supported,\r\n   * false if not. Otherwise a boolean representing the results of a feature detection\r\n   * @example\r\n   *\r\n   * The most common way of creating your own feature detects is by calling\r\n   * `Modernizr.addTest` with a string (preferably just lowercase, without any\r\n   * punctuation), and a function you want executed that will return a boolean result\r\n   *\r\n   * ```js\r\n   * Modernizr.addTest('itsTuesday', function() {\r\n   *  var d = new Date();\r\n   *  return d.getDay() === 2;\r\n   * });\r\n   * ```\r\n   *\r\n   * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,\r\n   * and to `false` every other day of the week. One thing to notice is that the names of\r\n   * feature detect functions are always lowercased when added to the Modernizr object. That\r\n   * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.\r\n   *\r\n   *\r\n   *  Since we only look at the returned value from any feature detection function,\r\n   *  you do not need to actually use a function. For simple detections, just passing\r\n   *  in a statement that will return a boolean value works just fine.\r\n   *\r\n   * ```js\r\n   * Modernizr.addTest('hasJquery', 'jQuery' in window);\r\n   * ```\r\n   *\r\n   * Just like before, when the above runs `Modernizr.hasjquery` will be true if\r\n   * jQuery has been included on the page. Not using a function saves a small amount\r\n   * of overhead for the browser, as well as making your co
1de much more readable.\r\n   *\r\n   * Finally, you also have the ability to pass in an object of feature names and\r\n   * their tests. This is handy if you want to add multiple detections in one go.\r\n   * The keys should always be a string, and the value can be either a boolean or\r\n   * function that returns a boolean.\r\n   *\r\n   * ```js\r\n   * var detects = {\r\n   *  'hasjquery': 'jQuery' in window,\r\n   *  'itstuesday': function() {\r\n   *    var d = new Date();\r\n   *    return d.getDay() === 2;\r\n   *  }\r\n   * }\r\n   *\r\n   * Modernizr.addTest(detects);\r\n   * ```\r\n   *\r\n   * There is really no difference between the first methods and this one, it is\r\n   * just a convenience to let you write more readable code.\r\n   */\n\n  function addTest(feature, test) {\n    if (_typeof(feature) == 'object') {\n      for (var key in feature) {\n        if (hasOwnProp(feature, key)) {\n          addTest(key, feature[key]);\n        }\n      }\n    } else {\n      feature = feature.toLowerCase();\n      var featureNameSplit = feature.split('.');\n      var last = Modernizr[featureNameSplit[0]];\n\n      // Again, we don't check for parent test existence. Get that right, though.\n      if (featureNameSplit.length == 2) {\n        last = last[featureNameSplit[1]];\n      }\n      if (typeof last != 'undefined') {\n        // we're going to quit if you're trying to overwrite an existing test\n        // if we were to allow it, we'd do this:\n        //   var re = new RegExp(\"\\\\b(no-)?\" + feature + \"\\\\b\");\n        //   docElement.className = docElement.className.replace( re, '' );\n        // but, no rly, stuff 'em.\n        return Modernizr;\n      }\n      test = typeof test == 'function' ? test() : test;\n\n      // Set the value (this is the magic, right here).\n      if (featureNameSplit.length == 1) {\n        Modernizr[featureNameSplit[0]] = test;\n      } else {\n        // cast to a Boolean, if not one already\n        if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {\n          Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);\n        }\n        Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test;\n      }\n\n      // Set a single class (either `feature` or `no-feature`)\n      setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]);\n\n      // Trigger the event\n      Modernizr._trigger(feature, test);\n    }\n    return Modernizr; // allow chaining.\n  }\n\n  // After all the tests are run, add self to the Modernizr prototype\n  Modernizr._q.push(function () {\n    ModernizrProto.addTest = addTest;\n  });\n\n  /**\r\n   * createElement is a convenience wrapper around document.createElement. Since we\r\n   * use createElement all over the place, this allows for (slightly) smaller code\r\n   * as well as abstracting away issues with creating elements in contexts other than\r\n   * HTML documents (e.g. SVG documents).\r\n   *\r\n   * @access private\r\n   * @function createElement\r\n   * @returns {HTMLElement|SVGElement} An HTML or SVG element\r\n   */\n\n  function createElement() {\n    if (typeof document.createElement !== 'function') {\n      // This is the case in IE7, where the type of createElement is \"object\".\n      // For this reason, we cannot call apply() as Object is not a Function.\n      return document.createElement(arguments[0]);\n    } else if (isSVG) {\n      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);\n    } else {\n      return document.createElement.apply(document, arguments);\n    }\n  }\n  ;\n  /*!\r\n  {\r\n    \"name\": \"CSS position: sticky\",\r\n    \"property\": \"csspositionsticky\",\r\n    \"tags\": [\"css\"],\r\n    \"builderAliases\": [\"css_positionsticky\"],\r\n    \"notes\": [{\r\n      \"name\": \"Chrome bug report\",\r\n      \"href\":\"https://code.google.com/p/chromium/issues/detail?id=322972\"\r\n    }],\r\n    \"warnings\": [ \"using position:sticky on anything but top aligned elements is buggy in Chrome < 37 and iOS <=7+\" ]\r\n  }\r\n  !*/\n\n  // Sticky positioning - constrains an element to be positioned inside the\n  // intersection of its container box, and the viewport.\n  Modernizr.addTest('csspositionsticky', function () {\n    var prop = 'position:';\n    var value = 'sticky';\n    var el = createElement('a');\n    var mStyle = el.style;\n    mStyle.cssText = prop + prefixes.join(value + ';' + prop).slice(0, -prop.length);\n    return mStyle.position.indexOf(value) !== -1;\n  });\n\n  /*!\r\n  {\r\n    \"name\": \"dataset API\",\r\n    \"caniuse\": \"dataset\",\r\n    \"property\": \"dataset\",\r\n    \"tags\": [\"dom\"],\r\n    \"builderAliases\": [\"dom_dataset\"],\r\n    \"authors\": [\"@phiggins42\"]\r\n  }\r\n  !*/\n\n  // dataset API for data-* attributes\n  Modernizr.addTest('dataset', function () {\n    var n = createElement('div');\n    n.setAttribute('data-a-b', 'c');\n    return !!(n.dataset && n.dataset.aB === 'c');\n  });\n\n  /**\r\n   * getBody returns the body of a document, or an element that can stand in for\r\n   * the body if a real body does not exist\r\n   *\r\n   * @access private\r\n   * @function getBody\r\n   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an\r\n   * artificially created element that stands in for the body\r\n   */\n\n  function getBody() {\n    // After page load injecting a fake body doesn't work so check if body exists\n    var body = document.body;\n    if (!body) {\n      // Can't use the real body create a fake one.\n      body = createElement(isSVG ? 'svg' : 'body');\n      body.fake = true;\n    }\n    return body;\n  }\n  ;\n\n  /**\r\n   * injectElementWithStyles injects an element with style element and some CSS rules\r\n   *\r\n   * @access private\r\n   * @function injectElementWithStyles\r\n   * @param {string} rule - String representing a css rule\r\n   * @param {function} callback - A function that is used to test the injected element\r\n   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected\r\n   * @param {string[]}
1 [testnames] - An array of strings that are used as ids for the additional nodes\r\n   * @returns {boolean}\r\n   */\n\n  function injectElementWithStyles(rule, callback, nodes, testnames) {\n    var mod = 'modernizr';\n    var style;\n    var ret;\n    var node;\n    var docOverflow;\n    var div = createElement('div');\n    var body = getBody();\n    if (parseInt(nodes, 10)) {\n      // In order not to give false positives we create a node for each test\n      // This also allows the method to scale for unspecified uses\n      while (nodes--) {\n        node = createElement('div');\n        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);\n        div.appendChild(node);\n      }\n    }\n    style = createElement('style');\n    style.type = 'text/css';\n    style.id = 's' + mod;\n\n    // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.\n    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270\n    (!body.fake ? div : body).appendChild(style);\n    body.appendChild(div);\n    if (style.styleSheet) {\n      style.styleSheet.cssText = rule;\n    } else {\n      style.appendChild(document.createTextNode(rule));\n    }\n    div.id = mod;\n    if (body.fake) {\n      //avoid crashing IE8, if background image is used\n      body.style.background = '';\n      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible\n      body.style.overflow = 'hidden';\n      docOverflow = docElement.style.overflow;\n      docElement.style.overflow = 'hidden';\n      docElement.appendChild(body);\n    }\n    ret = callback(div, rule);\n    // If this is done after page load we don't want to remove the body so check if body exists\n    if (body.fake) {\n      body.parentNode.removeChild(body);\n      docElement.style.overflow = docOverflow;\n      // Trigger layout so kinetic scrolling isn't disabled in iOS6+\n      // eslint-disable-next-line\n      docElement.offsetHeight;\n    } else {\n      div.parentNode.removeChild(div);\n    }\n    return !!ret;\n  }\n  ;\n\n  /**\r\n   * Modernizr.mq tests a given media query, live against the current state of the window\r\n   * adapted from matchMedia polyfill by Scott Jehl and Paul Irish\r\n   * gist.github.com/786768\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr.mq\r\n   * @optionName Modernizr.mq()\r\n   * @optionProp mq\r\n   * @access public\r\n   * @function mq\r\n   * @param {string} mq - String of the media query we want to test\r\n   * @returns {boolean}\r\n   * @example\r\n   * Modernizr.mq allows for you to programmatically check if the current browser\r\n   * window state matches a media query.\r\n   *\r\n   * ```js\r\n   *  var query = Modernizr.mq('(min-width: 900px)');\r\n   *\r\n   *  if (query) {\r\n   *    // the browser window is larger than 900px\r\n   *  }\r\n   * ```\r\n   *\r\n   * Only valid media queries are supported, therefore you must always include values\r\n   * with your media query\r\n   *\r\n   * ```js\r\n   * // good\r\n   *  Modernizr.mq('(min-width: 900px)');\r\n   *\r\n   * // bad\r\n   *  Modernizr.mq('min-width');\r\n   * ```\r\n   *\r\n   * If you would just like to test that media queries are supported in general, use\r\n   *\r\n   * ```js\r\n   *  Modernizr.mq('only all'); // true if MQ are supported, false if not\r\n   * ```\r\n   *\r\n   *\r\n   * Note that if the browser does not support media queries (e.g. old IE) mq will\r\n   * always return false.\r\n   */\n\n  var mq = function () {\n    var matchMedia = window.matchMedia || window.msMatchMedia;\n    if (matchMedia) {\n      return function (mq) {\n        var mql = matchMedia(mq);\n        return mql && mql.matches || false;\n      };\n    }\n    return function (mq) {\n      var bool = false;\n      injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function (node) {\n        bool = (window.getComputedStyle ? window.getComputedStyle(node, null) : node.currentStyle).position == 'absolute';\n      });\n      return bool;\n    };\n  }();\n  ModernizrProto.mq = mq;\n\n  /**\r\n   * testStyles injects an element with style element and some CSS rules\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr.testStyles\r\n   * @optionName Modernizr.testStyles()\r\n   * @optionProp testStyles\r\n   * @access public\r\n   * @function testStyles\r\n   * @param {string} rule - String representing a css rule\r\n   * @param {function} callback - A function that is used to test the injected element\r\n   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected\r\n   * @param {string[]}
1 [testnames] - An array of strings that are used as ids for the additional nodes\r\n   * @returns {boolean}\r\n   * @example\r\n   *\r\n   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page\r\n   * along with (possibly multiple) DOM elements. This lets you check for features\r\n   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).\r\n   *\r\n   * ```js\r\n   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {\r\n   *   // elem is the first DOM node in the page (by default #modernizr)\r\n   *   // rule is the first argument you supplied - the CSS rule in string form\r\n   *\r\n   *   addTest('widthworks', elem.style.width === '9px')\r\n   * });\r\n   * ```\r\n   *\r\n   * If your test requires multiple nodes, you can include a third argument\r\n   * indicating how many additional div elements to include on the page. The\r\n   * additional nodes are injected as children of the `elem` that is returned as\r\n   * the first argument to the callback.\r\n   *\r\n   * ```js\r\n   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {\r\n   *   document.getElementById('modernizr').style.width === '1px'; // true\r\n   *   document.getElementById('modernizr2').style.width === '2px'; // true\r\n   *   elem.firstChild === document.getElementById('modernizr2'); // true\r\n   * }, 1);\r\n   * ```\r\n   *\r\n   * By default, all of the additional elements have an ID of `modernizr[n]`, where\r\n   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,\r\n   * the second additional is `#modernizr3`, etc.).\r\n   * If you want to have more meaningful IDs for your function, you can provide\r\n   * them as the fourth argument, as an array of strings\r\n   *\r\n   * ```js\r\n   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {\r\n   *   elem.firstChild === document.getElementById('foo'); // true\r\n   *   elem.lastChild === document.getElementById('bar'); // true\r\n   * }, 2, ['foo', 'bar']);\r\n   * ```\r\n   *\r\n   */\n\n  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;\n\n  /*!\r\n  {\r\n    \"name\": \"Touch Events\",\r\n    \"property\": \"touchevents\",\r\n    \"caniuse\" : \"touch\",\r\n    \"tags\": [\"media\", \"attribute\"],\r\n    \"notes\": [{\r\n      \"name\": \"Touch Events spec\",\r\n      \"href\": \"https://www.w3.org/TR/2013/WD-touch-events-20130124/\"\r\n    }],\r\n    \"warnings\": [\r\n      \"Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device\"\r\n    ],\r\n    \"knownBugs\": [\r\n      \"False-positive on some configurations of Nokia N900\",\r\n      \"False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695\"\r\n    ]\r\n  }\r\n  !*/\n  /* DOC\r\n  Indicates if the browser supports the W3C Touch Events API.\r\n  \r\n  This *does not* necessarily reflect a touchscreen device:\r\n  \r\n  * Older touchscreen devices only emulate mouse events\r\n  * Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that\r\n  * Some browsers & OS setups may enable touch APIs when no touchscreen is connected\r\n  * Future browsers may implement other event models for touch interactions\r\n  \r\n  See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).\r\n  \r\n  It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).\r\n  \r\n  This test will also return `true` for Firefox 4 Multitouch support.\r\n  */\n\n  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415\n  Modernizr.addTest('touchevents', function () {\n    var bool;\n    if ('ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch) {\n      bool = true;\n    } else {\n      // include the 'heartz' as a way to have a non matching MQ to help terminate the join\n      // https://git.io/vznFH\n      var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');\n      testStyles(query, function (node) {\n        bool = node.offsetTop === 9;\n      });\n    }\n    return bool;\n  });\n\n  /**\r\n   * If the browsers follow the spec, then they would expose vendor-specific styles as:\r\n   *   elem.style.WebkitBorderRadius\r\n   * instead of something like the following (which is technically incorrect):\r\n   *   elem.style.webkitBorderRadius\r\n     * WebKit ghosts their properties in lowercase but Opera & Moz do not.\r\n   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+\r\n   *   erik.eae.net/archives/2008/03/10/21.48.10/\r\n     * More here: github.com/Modernizr/Modernizr/issues/issue/21\r\n   *\r\n   * @access private\r\n   * @returns {string} The string representing the vendor-specific style properties\r\n   */\n\n  var omPrefixes = 'Moz O ms Webkit';\n  var cssomPrefixes = ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : [];\n  ModernizrProto._cssomPrefixes = cssomPrefixes;\n\n  /**\r\n   * List of JavaScript DOM values used for tests\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr._domPrefixes\r\n   * @optionName Modernizr._domPrefixes\r\n   * @optionProp domPrefixes\r\n   * @access public\r\n   * @example\r\n   *\r\n   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather\r\n   * than kebab-case properties, all properties are their Capitalized variant\r\n   *\r\n   * ```js\r\n   * Modernizr._domPrefixes === [ \"Moz\", \"O\", \"ms\", \"Webkit\" ];\r\n   * ```\r\n   */\n\n  var domPrefixes = ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : [];\n  ModernizrProto._domPrefixes = domPrefixes;\n\n  /**\r\n   * contains checks to see if a string contains another string\r\n   *\r\n   * @access private\r\n   * @function contains\r\n   * @param {string} str - The string we want to check for substrings\r\n   * @param {string} substr - The substring we want to search the first string for\r\n   * @returns {boolean}
1\r\n   */\n\n  function contains(str, substr) {\n    return !!~('' + str).indexOf(substr);\n  }\n  ;\n\n  /**\r\n   * cssToDOM takes a kebab-case string and converts it to camelCase\r\n   * e.g. box-sizing -> boxSizing\r\n   *\r\n   * @access private\r\n   * @function cssToDOM\r\n   * @param {string} name - String name of kebab-case prop we want to convert\r\n   * @returns {string} The camelCase version of the supplied name\r\n   */\n\n  function cssToDOM(name) {\n    return name.replace(/([a-z])-([a-z])/g, function (str, m1, m2) {\n      return m1 + m2.toUpperCase();\n    }).replace(/^-/, '');\n  }\n  ;\n\n  /**\r\n   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.\r\n   *\r\n   * @access private\r\n   * @function fnBind\r\n   * @param {function} fn - a function you want to change `this` reference to\r\n   * @param {object} that - the `this` you want to call the function with\r\n   * @returns {function} The wrapped version of the supplied function\r\n   */\n\n  function fnBind(fn, that) {\n    return function () {\n      return fn.apply(that, arguments);\n    };\n  }\n  ;\n\n  /**\r\n   * testDOMProps is a generic DOM property test; if a browser supports\r\n   *   a certain property, it won't return undefined for it.\r\n   *\r\n   * @access private\r\n   * @function testDOMProps\r\n   * @param {array.<string>} props - An array of properties to test for\r\n   * @param {object} obj - An object or Element you want to use to test the parameters again\r\n   * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check\r\n   * @returns {false|*} returns false if the prop is unsupported, otherwise the value that is supported\r\n   */\n  function testDOMProps(props, obj, elem) {\n    var item;\n    for (var i in props) {\n      if (props[i] in obj) {\n        // return the property name as a string\n        if (elem === false) {\n          return props[i];\n        }\n        item = obj[props[i]];\n\n        // let's bind a function\n        if (is(item, 'function')) {\n          // bind to obj unless overriden\n          return fnBind(item, elem || obj);\n        }\n\n        // return the unbound function or obj or value\n        return item;\n      }\n    }\n    return false;\n  }\n  ;\n\n  /**\r\n   * Create our \"modernizr\" element that we do most feature tests on.\r\n   *\r\n   * @access private\r\n   */\n\n  var modElem = {\n    elem: createElement('modernizr')\n  };\n\n  // Clean up this element\n  Modernizr._q.push(function () {\n    delete modElem.elem;\n  });\n  var mStyle = {\n    style: modElem.elem.style\n  };\n\n  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to\n  // the front of the queue.\n  Modernizr._q.unshift(function () {\n    delete mStyle.style;\n  });\n\n  /**\r\n   * domToCSS takes a camelCase string and converts it to kebab-case\r\n   * e.g. boxSizing -> box-sizing\r\n   *\r\n   * @access private\r\n   * @function domToCSS\r\n   * @param {string} name - String name of camelCase prop we want to convert\r\n   * @returns {string} The kebab-case version of the supplied name\r\n   */\n\n  function domToCSS(name) {\n    return name.replace(/([A-Z])/g, function (str, m1) {\n      return '-' + m1.toLowerCase();\n    }).replace(/^ms-/, '-ms-');\n  }\n  ;\n\n  /**\r\n   * wrapper around getComputedStyle, to fix issues with Firefox returning null when\r\n   * called inside of a hidden iframe\r\n   *\r\n   * @access private\r\n   * @function computedStyle\r\n   * @param {HTMLElement|SVGElement} - The element we want to find the computed styles of\r\n   * @param {string|null} [pseudoSelector]- An optional pseudo element selector (e.g. :before), of null if none\r\n   * @returns {CSSStyleDeclaration}\r\n   */\n\n  function computedStyle(elem, pseudo, prop) {\n    var result;\n    if ('getComputedStyle' in window) {\n      result = getComputedStyle.call(window, elem, pseudo);\n      var console = window.console;\n      if (result !== null) {\n        if (prop) {\n          result = result.getPropertyValue(prop);\n        }\n      } else {\n        if (console) {\n          var method = console.error ? 'error' : 'log';\n          console[method].call(console, 'getComputedStyle returning null, its possible modernizr test results are inaccurate');\n        }\n      }\n    } else {\n      result = !pseudo && elem.currentStyle && elem.currentStyle[prop];\n    }\n    return result;\n  }\n  ;\n\n  /**\r\n   * nativeTestProps allows for us to use native feature detection functionality if available.\r\n   * some prefixed form, or false, in the case of an unsupported rule\r\n   *\r\n   * @access private\r\n   * @function nativeTestProps\r\n   * @param {array} props - An array of property names\r\n   * @param {string} value - A string representing the value we want to check via @supports\r\n   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise\r\n   */\n\n  // Accepts a list of property names and a single value\n  // Returns `undefined` if native detection not available\n  function nativeTestProps(props, value) {\n    var i = props.length;\n    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface\n    if ('CSS' in window && 'supports' in window.CSS) {\n      // Try every prefixed variant of the property\n      while (i--) {\n        if (window.CSS.supports(domToCSS(props[i]), value)) {\n          return true;\n        }\n      }\n      return false;\n    }\n    // Otherwise fall back to at-rule (for Opera 12.x)\n    else if ('CSSSupportsRule' in window) {\
1n      // Build a condition string for every prefixed variant\n      var conditionText = [];\n      while (i--) {\n        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');\n      }\n      conditionText = conditionText.join(' or ');\n      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function (node) {\n        return computedStyle(node, null, 'position') == 'absolute';\n      });\n    }\n    return undefined;\n  }\n  ;\n\n  // testProps is a generic CSS / DOM property test.\n\n  // In testing support for a given CSS property, it's legit to test:\n  //    `elem.style[styleName] !== undefined`\n  // If the property is supported it will return an empty string,\n  // if unsupported it will return undefined.\n\n  // We'll take advantage of this quick test and skip setting a style\n  // on our modernizr element, but instead just testing undefined vs\n  // empty string.\n\n  // Property names can be provided in either camelCase or kebab-case.\n\n  function testProps(props, prefixed, value, skipValueTest) {\n    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;\n\n    // Try native detect first\n    if (!is(value, 'undefined')) {\n      var result = nativeTestProps(props, value);\n      if (!is(result, 'undefined')) {\n        return result;\n      }\n    }\n\n    // Otherwise do it properly\n    var afterInit, i, propsLength, prop, before;\n\n    // If we don't have a style element, that means we're running async or after\n    // the core tests, so we'll need to create our own elements to use\n\n    // inside of an SVG element, in certain browsers, the `style` element is only\n    // defined for valid tags. Therefore, if `modernizr` does not have one, we\n    // fall back to a less used element and hope for the best.\n    // for strict XHTML browsers the hardly used samp element is used\n    var elems = ['modernizr', 'tspan', 'samp'];\n    while (!mStyle.style && elems.length) {\n      afterInit = true;\n      mStyle.modElem = createElement(elems.shift());\n      mStyle.style = mStyle.modElem.style;\n    }\n\n    // Delete the objects if we created them.\n    function cleanElems() {\n      if (afterInit) {\n        delete mStyle.style;\n        delete mStyle.modElem;\n      }\n    }\n    propsLength = props.length;\n    for (i = 0; i < propsLength; i++) {\n      prop = props[i];\n      before = mStyle.style[prop];\n      if (contains(prop, '-')) {\n        prop = cssToDOM(prop);\n      }\n      if (mStyle.style[prop] !== undefined) {\n        // If value to test has been passed in, do a set-and-check test.\n        // 0 (integer) is a valid property value, so check that `value` isn't\n        // undefined, rather than just checking it's truthy.\n        if (!skipValueTest && !is(value, 'undefined')) {\n          // Needs a try catch block because of old IE. This is slow, but will\n          // be avoided in most cases because `skipValueTest` will be used.\n          try {\n            mStyle.style[prop] = value;\n          } catch (e) {}\n\n          // If the property value has changed, we assume the value used is\n          // supported. If `value` is empty string, it'll fail here (because\n          // it hasn't changed), which matches how browsers have implemented\n          // CSS.supports()\n          if (mStyle.style[prop] != before) {\n            cleanElems();\n            return prefixed == 'pfx' ? prop : true;\n          }\n        }\n        // Otherwise just return true, or the property name if this is a\n        // `prefixed()` call\n        else {\n          cleanElems();\n          return prefixed == 'pfx' ? prop : true;\n        }\n      }\n    }\n    cleanElems();\n    return false;\n  }\n  ;\n\n  /**\r\n   * testPropsAll tests a list of DOM properties we want to check against.\r\n   * We specify literally ALL possible (known and/or likely) properties on\r\n   * the element including the non-vendor prefixed one, for forward-\r\n   * compatibility.\r\n   *\r\n   * @access private\r\n   * @function testPropsAll\r\n   * @param {string} prop - A string of the property to test for\r\n   * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip\r\n   * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against\r\n   * @param {string} [value] - A string of a css value\r\n   * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set\r\n   * @returns {false|string} returns the string version of the property, or false if it is unsupported\r\n   */\n  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {\n    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),\n      props = (prop + ' ' + cssomPrefixes.join(ucPro
1p + ' ') + ucProp).split(' ');\n\n    // did they call .prefixed('boxSizing') or are we just testing a prop?\n    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {\n      return testProps(props, prefixed, value, skipValueTest);\n\n      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])\n    } else {\n      props = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' ');\n      return testDOMProps(props, prefixed, elem);\n    }\n  }\n\n  // Modernizr.testAllProps() investigates whether a given style property,\n  // or any of its vendor-prefixed variants, is recognized\n  //\n  // Note that the property names must be provided in the camelCase variant.\n  // Modernizr.testAllProps('boxSizing')\n  ModernizrProto.testAllProps = testPropsAll;\n\n  /**\r\n   * testAllProps determines whether a given CSS property is supported in the browser\r\n   *\r\n   * @memberof Modernizr\r\n   * @name Modernizr.testAllProps\r\n   * @optionName Modernizr.testAllProps()\r\n   * @optionProp testAllProps\r\n   * @access public\r\n   * @function testAllProps\r\n   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)\r\n   * @param {string} [value] - String of the value to test\r\n   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection\r\n   * @example\r\n   *\r\n   * testAllProps determines whether a given CSS property, in some prefixed form,\r\n   * is supported by the browser.\r\n   *\r\n   * ```js\r\n   * testAllProps('boxSizing')  // true\r\n   * ```\r\n   *\r\n   * It can optionally be given a CSS value in string form to test if a property\r\n   * value is valid\r\n   *\r\n   * ```js\r\n   * testAllProps('display', 'block') // true\r\n   * testAllProps('display', 'penguin') // false\r\n   * ```\r\n   *\r\n   * A boolean can be passed as a third parameter to skip the value check when\r\n   * native detection (@supports) isn't available.\r\n   *\r\n   * ```js\r\n   * testAllProps('shapeOutside', 'content-box', true);\r\n   * ```\r\n   */\n\n  function testAllProps(prop, value, skipValueTest) {\n    return testPropsAll(prop, undefined, undefined, value, skipValueTest);\n  }\n  ModernizrProto.testAllProps = testAllProps;\n\n  /*!\r\n  {\r\n    \"name\": \"CSS Transforms\",\r\n    \"property\": \"csstransforms\",\r\n    \"caniuse\": \"transforms2d\",\r\n    \"tags\": [\"css\"]\r\n  }\r\n  !*/\n\n  Modernizr.addTest('csstransforms', function () {\n    // Android < 3.0 is buggy, so we sniff and blacklist\n    // http://git.io/hHzL7w\n    return navigator.userAgent.indexOf('Android 2.') === -1 && testAllProps('transform', 'scale(1)', true);\n  });\n\n  // Run each test\n  testRunner();\n  delete ModernizrProto.addTest;\n  delete ModernizrProto.addAsyncTest;\n\n  // Run the things that are supposed to run after the tests\n  for (var i = 0; i < Modernizr._q.length; i++) {\n    Modernizr._q[i]();\n  }\n\n  // Leak Modernizr namespace\n  window.Modernizr = Modernizr;\n  ;
1\n})(window, document);"},8460:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  var deviceLoadOptimisation;\n  (function (deviceLoadOptimisation) {\n    deviceLoadOptimisation.devicePixelRatio = window.devicePixelRatio || 1;\n    var loadOnScrollItems = [];\n    var prefetchAssets = [];\n    function runWhenLoaded($el, callback) {\n      if ($el.attr('data-ajax-load') != null && $el.attr('data-ajax-load').length > 0 && $el.attr('data-delay-load-status') !== 'loaded') {\n        $el.one('loaded', function () {\n          callback();\n        });\n      } else {\n        callback();\n      }\n    }\n    deviceLoadOptimisation.runWhenLoaded = runWhenLoaded;\n    function ajaxLoadHtml($el) {\n      DL.Utilities.SilenceExceptionsOnLive(function () {\n        var ajaxUrl = $el.attr('data-ajax-load');\n        if (ajaxUrl === null || ajaxUrl.length === 0 || $el.attr('data-delay-load-status') != null) {\n          return;\n        }\n        $el.attr('data-delay-load-status', 'loading');\n        //$el.removeAttr('data-ajax-load'); // ensures it doesnt get called again\n        var ajaxSuccess = $el.attr('data-ajax-load-success'); // callback when ajax is successful\n        $.ajax({\n          url: ajaxUrl\n        }
1).done(function (data) {\n          $el.attr('data-delay-load-status', 'loaded');\n          var $data = data;\n          if (!data.jquery) {\n            $data = $(data);\n          }\n          $el.append($data);\n          DL.Utilities.executeFunctionByName(ajaxSuccess, window, $el, $data);\n          $el.trigger('loaded');\n          contentReady($data);\n        }).always(function () {\n          // if the container is empty after ajax load, then remove it (it be useless)\n          if ($el.children().length === 0) {\n            $el.remove();\n          }\n        });\n      });\n    }\n    deviceLoadOptimisation.ajaxLoadHtml = ajaxLoadHtml;\n    function ajaxLoadJson($el) {\n      DL.Utilities.SilenceExceptionsOnLive(function () {\n        var ajaxUrl = $el.attr('data-ajax-json');\n        if (ajaxUrl === null || ajaxUrl.length === 0 || $el.attr('data-delay-load-status') != null) {\n          return;\n        }\n        $el.attr('data-delay-load-status', 'loading');\n        //$el.removeAttr('data-ajax-load'); // ensures it doesnt get called again\n        var ajaxSuccess = $el.attr('data-ajax-json-success'); // callback when ajax is successful\n        function renderJson(data) {\n          $el.attr('data-delay-load-status', 'loaded');\n          var templateHtml = $el.html();\n          var renderedTemplate = _.template(templateHtml)(data);\n          var $content = $(renderedTemplate);\n          $el.replaceWith($content);\n          DL.Utilities.executeFunctionByName(ajaxSuccess, window, data, $content);\n          $content.trigger('loaded', data);\n          contentReady($content);\n        }\n        if (ajaxUrl.startsWith('#')) {\n          renderJson(JSON.parse($(ajaxUrl).html()));\n        }\n        var jqxhr = $.getJSON(ajaxUrl, renderJson);\n      });\n    }\n    deviceLoadOptimisation.ajaxLoadJson = ajaxLoadJson;\n    function removeDuplicatePrimaryArticle($el) {\n      // Remove page primary article from lists.\n      var pageArticleId = DL.Utilities.getBodyElement().find('article[data-primary-article=\"true\"]').attr('data-article-id');\n      if (pageArticleId != null && pageArticleId.length > 0) {\n        $el.filterFind('[data-article-id=\"' + pageArticleId + '\"]').remove();\n      }\n    }\n    deviceLoadOptimisation.removeDuplicatePrimaryArticle = removeDuplicatePrimaryArticle;\n    function removeDuplicatePrimaryArticleOrAnother($el) {\n      var $articles = $el.filterFind('[data-article-id]');\n      var articleCount = $articles.length;\n      removeDuplicatePrimaryArticle($el);\n      $articles = $el.filterFind('[data-article-id]');\n      if (articleCount === $articles.length) {\n        $articles.last().remove();\n      }\n    }\n    deviceLoadOptimisation.removeDuplicatePrimaryArticleOrAnother = removeDuplicatePrimaryArticleOrAnother;\n    function initInfiniteLoadArticles() {\n      DL.Utilities.getDocumentElement().on('click', '.article-list-load-more', function (e) {\n        e.preventDefault();\n        var $loadMoreLink = $(this);\n        var $container = $(this).closest('.article-list-container').find('.article-list');\n        var primaryArticleId;\n        $.ajax({\n          url: $loadMoreLink.attr('href')\n        }
1).done(function (data) {\n          var $data = $(data).filterFind('.article-list');\n          var $newLoadMoreLink = $(data).filterFind('.article-list-load-more');\n          if (primaryArticleId) {\n            $data.find('[data-article-id]').each(function () {\n              var $item = $(this);\n              if ($item.attr('data-article-id') === primaryArticleId) {\n                $item.remove();\n              }\n            });\n          }\n          var $childItems = $data.children(); // this is needed for deviceLoadOptimisation.contentReady\n          $container.append($childItems);\n          contentReady($childItems);\n          $container.attr('data-delay-load-status', 'loaded');\n          $container.trigger('items-loaded', [$childItems]);\n          $loadMoreLink.replaceWith($newLoadMoreLink);\n          queuePrefetchAssets($newLoadMoreLink.attr('href'));\n          setTimeout(loadPrefetchAssets, 500);\n          //TODO: create virtual pagination for analytics\n          //        DL.analytics.trackPageview(settings.url, document.title);\n          //        DL.Utilities.getWindowElement().trigger('infscr.complete', $container);\n        });\n        primaryArticleId = $(document.body).find('[data-primary-article=\"true\"]').attr('data-article-id');\n        $container.attr('data-delay-load-status', 'loading');\n      });\n    }\n    deviceLoadOptimisation.initInfiniteLoadArticles = initInfiniteLoadArticles;\n    function loadBestImageSizes($container) {\n      $container = $container || $(document.body);\n      // make images use best width for the rendered size\n      var $imgs = $container.filterFind('img');\n      $imgs.each(function (index, item) {\n        var img = item;\n        setTimeout(function () {\n          loadBestImageSize(img);\n        }, (index + 1) * 4);\n        // slight timeout to allow other processes to run and to ensure images near the top are more likely to be loaded first\n      });\n    }\n    deviceLoadOptimisation.loadBestImageSizes = loadBestImageSizes;\n    function loadBestImageSize(img, options) {\n      if (img == null) {\n        return;\n      }\n      //console.log('responsiveImage: ' + img.alt);\n      DL.Utilities.SilenceExceptionsOnLive(function () {\n        options = options || {};\n        var $img = $(img);\n        if (!img.hasAttribute('data-responsive-widths')) {\n          var imgSrc = $img.attr('src');\n          var imgDataSrc = $img.attr('data-src');\n          if (imgDataSrc != null && imgDataSrc.length > 0 && (imgSrc == null || imgSrc.length === 0 || imgSrc.startsWith('data:image/'))) {\n            $img.attr('src', $img.attr('data-src'));\n            $img.removeAttr('data-src');\n          }\n          return;\n        }\n        var maxDevicePixelRatio = parseFloat($img.attr('data-maxdevicepixelratio'));\n        maxDevicePixelRatio = Math.min(deviceLoadOptimisation.devicePixelRatio, isNaN(maxDevicePixelRatio) ? 1 : maxDevicePixelRatio);\n        var parentWidth = (options.parentWidth || Math.max(img.parentElement.clientWidth > 0 ? img.parentElement.clientWidth : $img.parent().innerWidth(), img.clientWidth)) * maxDevicePixelRatio;\n        if (options.parentHeight != null) {\n          var aspectRatio = parseFloat($img.attr('data-aspect-ratio'));\n          var heightRestrictionOnWidth = options.parentHeight * aspectRatio * maxDevicePixelRatio;\n          if (parentWidth > heightRestrictionOnWidth) {\n            parentWidth = heightRestrictionOnWidth;\n          }\n        }\n        // naturalWidth is only set when img has loaded. if not, dont wait for img to load, instead calculate\n        if (img.naturalWidth == null || parentWidth > img.naturalWidth || parentWidth === 0) {\n          var responsiveWidthsList = $img.attr('data-responsive-widths');\n          if (responsiveWidthsList == null || responsiveWidthsList.length === 0) {\n            return;\n          }\n          var responsiveWidths = responsiveWidthsList.split(',').map(Number);\n          if (responsiveWidths == null || responsiveWidths.length === 0) {\n            return;\n          }
1\n          //console.log('respsonsive img width: naturalWidth=' + (img.naturalWidth || 'null') + ', parentNode.clientWidth=' + img.parentNode.clientWidth)\n          var dataSrc = $img.attr('data-src');\n          $img.attr('data-src', '');\n          var src = dataSrc != null && dataSrc.length > 4 ? dataSrc : img.src;\n          var bestImgUrl = src;\n          if (parentWidth > 0) {\n            var bestFitWidth = responsiveWidths[0] || 200;\n            for (var i = 1; i < responsiveWidths.length; i++) {\n              if (maxDevicePixelRatio < 2) {\n                bestFitWidth = responsiveWidths[i];\n              }\n              if (responsiveWidths[i] > parentWidth) {\n                break;\n              }\n              if (maxDevicePixelRatio >= 2) {\n                bestFitWidth = responsiveWidths[i];\n              }\n            }\n            bestImgUrl = DL.Utilities.getImgUrlForWidth(src, bestFitWidth);\n          }\n          if (bestImgUrl !== img.src && bestImgUrl !== img.currentSrc) {\n            img.src = bestImgUrl;\n          }\n        }\n      });\n    }\n    deviceLoadOptimisation.loadBestImageSize = loadBestImageSize;\n    function sizeDependent() {\n      calculateLoadOnScrollItems();\n      delayLoadElements();\n    }\n    deviceLoadOptimisation.sizeDependent = sizeDependent;\n    function removeOnScreenWidth($content) {\n      $content = $content || $(document.body);\n      if (DL.Utilities.isMobile()) {\n        $content.filterFind('.hidden-phone').remove();\n      } else if (DL.Utilities.isDesktop()) {\n        $content.filterFind('.hidden-desktop').remove();\n      } else if (DL.Utilities.isTablet()) {\n        $content.filterFind('.hidden-tablet').remove();\n      }\n      // data-removeonscreenwidth must be in format \"#-#,##-##,###-###\"\n      $content.filterFind('[data-removeonscreenwidth]').each(function (index, item) {\n        try {\n          var $item = $(item);\n          var removeOnScreenWidthArray = $item.attr('data-removeonscreenwidth').split(',');\n          for (var i = 0; i < removeOnScreenWidthArray.length; i++) {\n            var widthRangeArray = removeOnScreenWidthArray[i].split('-');\n            if (DL.Utilities.getWindowActualWidth() >= parseInt(widthRangeArray[0], 10) && DL.Utilities.getWindowActualWidth() <= parseInt(widthRangeArray[1], 10)) {\n              $item.remove();\n              return;\n            }\n          }\n        } catch (exception) {\n          DL.Utilities.AlertError(exception);\n        }\n      });\n    }\n    deviceLoadOptimisation.removeOnScreenWidth = removeOnScreenWidth;\n    function loadNow($els) {\n      $els.filterFind('[data-delay-load]').each(function (i, item) {\n        var el = item;\n        var $el = $(el);\n        setTimeout(function () {\n          DL.Utilities.SilenceExceptionsOnLive(function () {\n            if (el instanceof HTMLImageElement) {\n              loadBestImageSize(el);\n            } else if (el instanceof HTMLIFrameElement) {\n              var iframeSrc = $el.attr('src');\n              if (iframeSrc == null || iframeSrc.length === 0) {\n                $el.attr('src', $el.attr('data-src'));\n              }\n            } else if (el.hasAttribute('data-ajax-load')) {\n              ajaxLoadHtml($el);\n            } else if (el.hasAttribute('data-ajax-json')) {\n              ajaxLoadJson($el);\n            }\n            $el.removeAttr('data-delay-load').removeAttr('data-delay-load-mobile');\n          });\n        }, (i + 1) * 4);\n      });\n    }\n    deviceLoadOptimisation.loadNow = loadNow;\n    function loadNextLoadOnScrollItem() {\n      if (loadOnScrollItems != null && loadOnScrollItems.shift) {\n        var delayLoadObject = loadOnScrollItems.shift();\n        if (delayLoadObject != null) {\n          //console.warn('loading on scroll: ' + delayLoadObject.item[0].tagName);\n          loadNow(delayLoadObject.item);\n        }\n      }\n    }\n    deviceLoadOptimisation.loadNextLoadOnScrollItem = loadNextLoadOnScrollItem;\n    function loadItemsNearViewport() {\n      if (loadOnScrollItems == null || loadOnScrollItems.length === 0) {\n        DL.Utilities.getWindowElement().off('scroll.delayLoad');\n        return;\n      }\n      var bottomOffPage = DL.Utilities.getWindowElement().scrollTop() + DL.Utilities.getWindowActualHeight() * 1.6; // 60% buffer\n      //console.log('scrollTop: ' + DL.Utilities.getWindowElement().scrollTop() + ', window height: ' + DL.Utilities.getWindowActualHeight());\n      while (loadOnScrollItems.length > 0) {\n        var delayLoadObject = loadOnScrollItems[0];\n        if (delayLoadObject.offset.top > bottomOffPage) {\n          return;\n        }\n        //console.log('delayLoadObject.offset.top: ' + delayLoadObject.offset.top);\n        loadNextLoadOnScrollItem();\n      }\n    }\n    deviceLoadOptimisation.loadItemsNearViewport = loadItemsNearViewport;
1\n    function prefetchItemsForLoadOnScroll() {\n      if (loadOnScrollItems === null || loadOnScrollItems.length === 0) {\n        DL.Utilities.getWindowElement().off('scroll.delayLoad');\n        return;\n      }\n      loadOnScrollItems.forEach(function (el, index) {\n        var ajaxUrl = el.item.attr('data-ajax-load');\n        if (ajaxUrl) {\n          //console.info('prefetch load: ' + ajaxUrl);\n          prefetchAssets.pushUnique(ajaxUrl);\n        }\n      });\n    }\n    deviceLoadOptimisation.prefetchItemsForLoadOnScroll = prefetchItemsForLoadOnScroll;\n    function delayLoadElements($content) {\n      $content = $content || $(document.body);\n      // transfer mobile specific delay load options\n      if (DL.Utilities.getWindowActualWidth() < 768) {\n        $content.filterFind('[data-delay-load-mobile]').each(function (index, item) {\n          item.setAttribute('data-delay-load', item.getAttribute('data-delay-load-mobile'));\n        });\n      }\n      var $delayLoadElements = $content.filterFind('[data-delay-load]');\n      loadNow($delayLoadElements.filter('[data-delay-load=\"immediate\"]'));\n      loadNow($delayLoadElements.filter('[data-delay-load=\"docready\"]'));\n      var $delayLoadUntilScroll = $delayLoadElements.filterFind('[data-delay-load=\"scroll\"]');\n      $delayLoadUntilScroll.each(function (index, item) {\n        loadOnScrollItems.push({\n          item: $(item)\n        });\n      });\n      calculateLoadOnScrollItems();
1\n      prefetchItemsForLoadOnScroll();\n      DL.Utilities.getWindowElement().off('scroll.delayLoad').on('scroll.delayLoad', _.throttle(loadItemsNearViewport, 32));\n    }\n    deviceLoadOptimisation.delayLoadElements = delayLoadElements;\n    function calculateLoadOnScrollItems() {\n      loadOnScrollItems.forEach(function (el, index) {\n        el.offset = el.item.offset();\n      });\n      loadOnScrollItems.sort(function (a, b) {\n        return a.offset.top - b.offset.top;\n      });\n      loadItemsNearViewport();\n    }\n    deviceLoadOptimisation.calculateLoadOnScrollItems = calculateLoadOnScrollItems;\n    removeOnScreenWidth();\n    function runTwitterWidgetScript($content) {\n      (function (d, s, id) {\n        var js;\n        var fjs = d.getElementsByTagName(s)[0];\n        var location = d.location.toString();\n        var p = /^http:/.test(location) ? 'http' : 'https';\n        if (!d.getElementById(id)) {\n          js = d.createElement(s);\n          js.id = id;\n          js.async = !0;\n          js.src = p + \"://platform.twitter.com/widgets.js\";\n          fjs.parentNode.insertBefore(js, fjs);\n          DL.social.twitter._init();\n        } else {\n          $content = $content || $(document.body);\n          DL.social.twitter.refresh($content);\n        }\n      })(document, \"script\", \"twitter-wjs\");\n    }\n    deviceLoadOptimisation.runTwitterWidgetScript = runTwitterWidgetScript;\n    function runFacebookSdkScript($content) {\n      (function (d, s, id) {\n        var js,\n          fjs = d.getElementsByTagName(s)[0];\n        if (!d.getElementById(id)) {\n          js = d.createElement(s);\n          js.id = id;\n          js.defer = \"defer\";\n          js.src = \"https://connect.facebook.net/en_UK/sdk.js#xfbml=1&version=v2.6\";\n          fjs.parentNode.insertBefore(js, fjs);\n          DL.social.facebook._init();\n        } else {\n          $content = $content || $(document.body);\n          DL.social.facebook.refresh($content);\n        }\n      })(document, 'script', 'facebook-jssdk');\n    }\n    deviceLoadOptimisation.runFacebookSdkScript = runFacebookSdkScript;\n    function runInstagramEmbedsScript() {\n      (function (d, s, id) {\n        var js,\n          fjs = d.getElementsByTagName(s)[0];\n        if (!d.getElementById(id)) {\n          js = d.createElement(s);\n          js.id = id;\n          js.async = !0;\n          js.src = '//platform.instagram.com/en_US/embeds.js';\n          fjs.parentNode.insertBefore(js, fjs);\n        } else {\n          setTimeout(function () {\n            if (window.instgrm != null && window.instgrm.Embeds != null) {\n              window.instgrm.Embeds.process();\n            } else {\n              DL.Utilities.AlertError('Instagram Embed cant execute process()');\n            }\n          }, 2000);\n        }\n      })(document, \"script\", \"instagram-embeds\");\n    }\n    deviceLoadOptimisation.runInstagramEmbedsScript = runInstagramEmbedsScript;\n    function runSkimResourcesScript() {\n      (function (d, s, id) {\n        var js,\n          fjs = d.getElementsByTagName(s)[0];\n        if (!d.getElementById(id)) {\n          js = d.createElement(s);\n          js.id = id;\n          js.defer = \"defer\";\n          js.src = \"//s.skimresources.com/js/54423X1306182.skimlinks.js\";\n          fjs.parentNode.insertBefore(js, fjs);\n        }\n      })(document, 'script', 'skimresources');\n    }\n    deviceLoadOptimisation.runSkimResourcesScript = runSkimResourcesScript;\n    function runScriptDependencies($content) {\n      $content = $content || $(document.body);\n      var scriptDependencies = [];\n      var $scriptDependencyElements = $content.filterFind('[data-script-depends]');\n      $scriptDependencyElements.each(function (index, item) {\n        $(item).attr('data-script-depends').split(',').forEach(function (val) {\n          scriptDependencies.push(val);\n        });\n      });\n      //scriptDependencies = $.unique(scriptDependencies);\n      if (scriptDependencies.indexOf('twitter-widgets') >= 0) {\n        deviceLoadOptimisation.runTwitterWidgetScript($content.filterFind('[data-script-depends=\"twitter-widgets\"]'));\n      }\n      if (scriptDependencies.indexOf('facebook-sdk') >= 0) {\n        runFacebookSdkScript($content.filterFind('[data-script-depends=\"facebook-sdk\"]'));\n      }\n      if (scriptDependencies.indexOf('instagram-embeds') >= 0) {\n        runInstagramEmbedsScript();\n      }\n      if (scriptDependencies.indexOf('skimresources') >= 0) {\n        runSkimResourcesScript();\n      }\n    }\n    deviceLoadOptimisation.runScriptDependencies = runScriptDependencies;\n    function contentReady($content, options) {\n      options = options || {};\n      //console.warn('DL.deviceLoadOptimisation.contentReady');\n      $content = $content || $(document.body);\n      removeOnScreenWidth($content);\n      // protection from nowrap being too big\n      function removeNoWrapWhenTooBig() {\n        $content.find('.nowrap').each(function (i, item) {\n          var $item = $(item);\n          if ($item.width() >= $item.parent().width()) {\n            $item.removeClass('nowrap');\n          }\n        });\n      }\n      removeNoWrapWhenTooBig();\n      setTimeout(removeNoWrapWhenTooBig, 1500); // just in case there's a race condition\n      $content.filterFind('[data-sponsored]:visible').each(function (i, item) {\n        var $item = $(item);\n        var pageType = 'unknown';\n        if (window.adTag != null && window.adTag.pageType != null) {\n          pageType = window.adTag.pageType;\n        }\n        var $sponsorLinks = $item.find('a[data-sponsor-link]');\n        DL.analytics.trackNonInteractionEvent('Sponsored article view', pageType, $sponsorLinks.first().attr('href'));\n        $sponsorLinks.on('click.trackEvent', function () {\n          DL.analytics.trackEventsOnNextPageLoad('Sponsored article click', pageType, $(this).attr('href'));\n        });\n      });\n      // after we have removed elements we dont need, we setup delay-load elements\n      if (options.loadNow) {\n        loadNow($content);\n      } else {\n        delayLoadElements($content);\n      }\n      // load / run 3rd party scripts\n      runScriptDependencies($content);\n    }\n    deviceLoadOptimisation.contentReady = contentReady;\n    function loadAssets(assets, relVal) {\n      relVal = relVal || 'prefetch';\n      if (assets != null) {\n        var assetArray = DL.Utilities.AsArray(assets);\n        var tags = '';\n        for (var i = 0; i < assetArray.length;
1 i++) {\n          tags += '<link rel=\"' + relVal + '\" href=\"' + assetArray[i] + '\" />';\n        }\n        if (tags.length > 0) {\n          $(document.head).append(tags);\n        }\n      }\n    }\n    deviceLoadOptimisation.loadAssets = loadAssets;\n    function queuePrefetchAssets(assets) {\n      // This currently only works if run before window on load and user has interacted with the page\n      // TODO: check if loadPrefetchAssets has already run, if yes then dont queue, execute immediately\n      $.merge(prefetchAssets, DL.Utilities.AsArray(assets));\n    }\n    deviceLoadOptimisation.queuePrefetchAssets = queuePrefetchAssets;\n    function loadPrefetchAssets() {\n      loadAssets(prefetchAssets, 'prefetch');\n      prefetchAssets = [];\n    }\n    deviceLoadOptimisation.loadPrefetchAssets = loadPrefetchAssets;\n    var delayLoadItemsInterval = null;\n    function windowOnLoad() {\n      // console.warn('DL.deviceLoadOptimisation.windowOnLoad');\n      calculateLoadOnScrollItems();\n      // Fire only when there is an active user on the page.\n      DL.Utilities.OnUserActiveOnPage(function () {\n        //console.warn('user interaction + window.load');\n        loadPrefetchAssets();\n        delayLoadItemsInterval = setInterval(function () {\n          loadNextLoadOnScrollItem();\n          if (loadOnScrollItems == null || loadOnScrollItems.length === 0) {\n            clearInterval(delayLoadItemsInterval);\n          }\n        }, 350);\n      });\n    }\n    deviceLoadOptimisation.windowOnLoad = windowOnLoad;\n    deviceLoadOptimisation.resizeDebounce = _.debounce(sizeDependent, 60);\n    if (window.performance && window.performance.timing && window.performance.timing.responseEnd - window.performance.timing.responseStart > 1000) {\n      deviceLoadOptimisation.devicePixelRatio = 1; // reduce DPR for slow connections\n    }\n    $(function () {\n      contentReady();\n      initInfiniteLoadArticles();\n    });\n    DL.Utilities.getWindowElement().on('load.deviceLoadOptimisation', windowOnLoad).on('resize.deviceLoadOptimisation', deviceLoadOptimisation.resizeDebounce);\n  })(deviceLoadOptimisation = DL.deviceLoadOptimisation || (DL.deviceLoadOptimisation = {}));\n})(DL || (DL = {}));\n//$('body').append('<div style=\"position:fixed;z-index:999999;bottom:20px;left:0;padding:10px;background:orangered;color:#000;\">'\n//    + 'request time: ' + (window.performance.timing.responseStart - window.performance.timing.requestStart)\n//    + '<br/>'\n//    + 'response time: ' + (window.performance.timing.responseEnd - window.performance.timing.responseStart)\n//    );"},8585:function(e){e.exports='function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }\n/*!\r\n * jQuery JavaScript Library v3.2.1\r\n * https://jquery.com/\r\n *\r\n * Includes Sizzle.js\r\n * https://sizzlejs.com/\r\n *\r\n * Copyright JS Foundation and other contributors\r\n * Released under the MIT license\r\n * https://jquery.org/license\r\n *\r\n * Date: 2017-03-20T18:59Z\r\n */\n(function (global, factory) {\n  "use strict";\n\n  if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") {\n    // For CommonJS and CommonJS-like environments where a proper `window`\n    // is present, execute the factory and get jQuery.\n    // For environments that do not have a `window` with a `document`\n    // (such as Node.js), expose a factory as module.exports.\n    // This accentuates the need for the creation of a real `window`.\n    // e.g. var jQuery = require("jquery")(window);\n    // See ticket #14549 for more info.\n    module.exports = global.document ? factory(global, true) : function (w) {\n      if (!w.document) {\n        throw new Error("jQuery requires a window with a document");\n      }\n      return factory(w);\n    };\n  } else {\n    factory(global);\n  }\n\n  // Pass this if window is not defined yet\n})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {\n  // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n  // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n  // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
1ict mode should be common\n  // enough that all such attempts are guarded in a try block.\n  "use strict";\n\n  var arr = [];\n  var document = window.document;\n  var getProto = Object.getPrototypeOf;\n  var _slice = arr.slice;\n  var concat = arr.concat;\n  var push = arr.push;\n  var indexOf = arr.indexOf;\n  var class2type = {};\n  var toString = class2type.toString;\n  var hasOwn = class2type.hasOwnProperty;\n  var fnToString = hasOwn.toString;\n  var ObjectFunctionString = fnToString.call(Object);\n  var support = {};\n  function DOMEval(code, doc) {\n    doc = doc || document;\n    var script = doc.createElement("script");\n    script.text = code;\n    doc.head.appendChild(script).parentNode.removeChild(script);\n  }\n  /* global Symbol */\n  // Defining this global in .eslintrc.json would create a danger of using the global\n  // unguarded in another place, it seems safer to define global only for this module\n\n  var version = "3.2.1",\n    // Define a local copy of jQuery\n    _jQuery2 = function jQuery(selector, context) {\n      // The jQuery object is actually just the init constructor \'enhanced\'\n      // Need init if jQuery is called (just allow error to be thrown if not included)\n      return new _jQuery2.fn.init(selector, context);\n    },\n    // Support: Android <=4.0 only\n    // Make sure we trim BOM and NBSP\n    rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n    // Matches dashed string for camelizing\n    rmsPrefix = /^-ms-/,\n    rdashAlpha = /-([a-z])/g,\n    // Used by jQuery.camelCase as callback to replace()\n    fcamelCase = function fcamelCase(all, letter) {\n      return letter.toUpperCase();\n    };\n  _jQuery2.fn = _jQuery2.prototype = {\n    // The current version of jQuery being used\n    jquery: version,\n    constructor: _jQuery2,\n    // The default length of a jQuery object is 0\n    length: 0,\n    toArray: function toArray() {\n      return _slice.call(this);\n    },\n    // Get the Nth element in the matched element set OR\n    // Get the whole matched element set as a clean array\n    get: function get(num) {\n      // Return all the elements in a clean array\n      if (num == null) {\n        return _slice.call(this);\n      }\n\n      // Return just the one element from the set\n      return num < 0 ? this[num + this.length] : this[num];\n    },\n    // Take an array of elements and push it onto the stack\n    // (returning the new matched element set)\n    pushStack: function pushStack(elems) {\n      // Build a new jQuery matched element set\n      var ret = _jQuery2.merge(this.constructor(), elems);\n\n      // Add the old object onto the stack (as a reference)\n      ret.prevObject = this;\n\n      // Return the newly-formed element set\n      return ret;\n    },\n    // Execute a callback for every element in the matched set.\n    each: function each(callback) {\n      return _jQuery2.each(this, callback);\n    },\n    map: function map(callback) {\n      return this.pushStack(_jQuery2.map(this, function (elem, i) {\n        return callback.call(elem, i, elem);\n      }));\n    },\n    slice: function slice() {\n      return this.pushStack(_slice.apply(this, arguments));\n    },\n    first: function first() {\n      return this.eq(0);\n    },\n    last: function last() {\n      return this.eq(-1);\n    },\n    eq: function eq(i) {\n      var len = this.length,\n        j = +i + (i < 0 ? len : 0);\n      return this.pushStack(j >= 0 && j < len ? [this[j]] : []);\n    },\n    end: function end() {\n      return this.prevObject || this.constructor();\n    },\n    // For internal use only.\n    // Behaves like an Array\'s method, not like a jQuery method.\n    push: push,\n    sort: arr.sort,\n    splice: arr.splice\n  };\n  _jQuery2.extend = _jQuery2.fn.extend = function () {\n    var options,\n      name,\n      src,\n      copy,\n      copyIsArray,\n      clone,\n      target = arguments[0] || {},\n      i = 1,\n      length = arguments.length,\n      deep = false;\n\n    // Handle a deep copy situation\n    if (typeof target === "boolean") {\n      deep = target;\n\n      // Skip the boolean and the target\n      target = arguments[i] || {};\n      i++;\n    }\n\n    // Handle case when target is a string or something (possible in deep copy)\n    if (_typeof(target) !== "object" && !_jQuery2.isFunction(target)) {\n      target = {};\n    }\n\n    // Extend jQuery itself if only one argument is passed\n    if (i === length) {\n      target = this;\n      i--;\n    }\n    for (; i < length;
1 i++) {\n      // Only deal with non-null/undefined values\n      if ((options = arguments[i]) != null) {\n        // Extend the base object\n        for (name in options) {\n          src = target[name];\n          copy = options[name];\n\n          // Prevent never-ending loop\n          if (target === copy) {\n            continue;\n          }\n\n          // Recurse if we\'re merging plain objects or arrays\n          if (deep && copy && (_jQuery2.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n            if (copyIsArray) {\n              copyIsArray = false;\n              clone = src && Array.isArray(src) ? src : [];\n            } else {\n              clone = src && _jQuery2.isPlainObject(src) ? src : {};\n            }\n\n            // Never move original objects, clone them\n            target[name] = _jQuery2.extend(deep, clone, copy);\n\n            // Don\'t bring in undefined values\n          } else if (copy !== undefined) {\n            target[name] = copy;\n          }\n        }\n      }\n    }\n\n    // Return the modified object\n    return target;\n  };\n  _jQuery2.extend({\n    // Unique for each copy of jQuery on the page\n    expando: "jQuery" + (version + Math.random()).replace(/\\D/g, ""),\n    // Assume jQuery is ready without the ready module\n    isReady: true,\n    error: function error(msg) {\n      throw new Error(msg);\n    },\n    noop: function noop() {},\n    isFunction: function isFunction(obj) {\n      return _jQuery2.type(obj) === "function";\n    },\n    isWindow: function isWindow(obj) {\n      return obj != null && obj === obj.window;\n    },\n    isNumeric: function isNumeric(obj) {\n      // As of jQuery 3.0, isNumeric is limited to\n      // strings and numbers (primitives or objects)\n      // that can be coerced to finite numbers (gh-2662)\n      var type = _jQuery2.type(obj);\n      return (type === "number" || type === "string") &&\n      // parseFloat NaNs numeric-cast false positives ("")\n      // ...but misinterprets leading-number strings, particularly hex literals ("0x...")\n      // subtraction forces infinities to NaN\n      !isNaN(obj - parseFloat(obj));\n    },\n    isPlainObject: function isPlainObject(obj) {\n      var proto, Ctor;\n\n      // Detect obvious negatives\n      // Use toString instead of jQuery.type to catch host objects\n      if (!obj || toString.call(obj) !== "[object Object]") {\n        return false;\n      }\n      proto = getProto(obj);\n\n      // Objects with no prototype (e.g., `Object.create( null )`) are plain\n      if (!proto) {\n        return true;\n      }\n\n      // Objects with prototype are plain iff they were constructed by a global Object function\n      Ctor = hasOwn.call(proto, "constructor") && proto.constructor;\n      return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;\n    },\n    isEmptyObject: function isEmptyObject(obj) {\n      /* eslint-disable no-unused-vars */\n      // See https://github.com/eslint/eslint/issues/6125\n      var name;\n      for (name in obj) {\n        return false;\n      }\n      return true;\n    },\n    type: function type(obj) {\n      if (obj == null) {\n        return obj + "";\n      }\n\n      // Support: Android <=2.3 only (functionish RegExp)\n      return _typeof(obj) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : _typeof(obj);\n    },\n    // Evaluates a script in a global context\n    globalEval: function globalEval(code) {\n      DOMEval(code);\n    },\n    // Convert dashed to camelCase; used by the css and data modules\n    // Support: IE <=9 - 11, Edge 12 - 13\n    // Microsoft forgot to hump their vendor prefix (#9572)\n    camelCase: function camelCase(string) {\n      return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);\n    },\n    each: function each(obj, callback) {\n      var length,\n        i = 0;\n      if (isArrayLike(obj)) {\n        length = obj.length;\n        for (; i < length; i++) {\n          if (callback.call(obj[i], i, obj[i]) === false) {\n            break;\n          }\n        }\n      } else {\n        for (i in obj) {\n          if (callback.call(obj[i], i, obj[i]) === false) {\n            break;\n          }\n        }\n      }\n      return obj;\n    }
1,\n    // Support: Android <=4.0 only\n    trim: function trim(text) {\n      return text == null ? "" : (text + "").replace(rtrim, "");\n    },\n    // results is for internal usage only\n    makeArray: function makeArray(arr, results) {\n      var ret = results || [];\n      if (arr != null) {\n        if (isArrayLike(Object(arr))) {\n          _jQuery2.merge(ret, typeof arr === "string" ? [arr] : arr);\n        } else {\n          push.call(ret, arr);\n        }\n      }\n      return ret;\n    },\n    inArray: function inArray(elem, arr, i) {\n      return arr == null ? -1 : indexOf.call(arr, elem, i);\n    },\n    // Support: Android <=4.0 only, PhantomJS 1 only\n    // push.apply(_, arraylike) throws on ancient WebKit\n    merge: function merge(first, second) {\n      var len = +second.length,\n        j = 0,\n        i = first.length;\n      for (; j < len; j++) {\n        first[i++] = second[j];\n      }\n      first.length = i;\n      return first;\n    },\n    grep: function grep(elems, callback, invert) {\n      var callbackInverse,\n        matches = [],\n        i = 0,\n        length = elems.length,\n        callbackExpect = !invert;\n\n      // Go through the array, only saving the items\n      // that pass the validator function\n      for (; i < length; i++) {\n        callbackInverse = !callback(elems[i], i);\n        if (callbackInverse !== callbackExpect) {\n          matches.push(elems[i]);\n        }\n      }\n      return matches;\n    },\n    // arg is for internal usage only\n    map: function map(elems, callback, arg) {\n      var length,\n        value,\n        i = 0,\n        ret = [];\n\n      // Go through the array, translating each of the items to their new values\n      if (isArrayLike(elems)) {\n        length = elems.length;\n        for (; i < length; i++) {\n          value = callback(elems[i], i, arg);\n          if (value != null) {\n            ret.push(value);\n          }\n        }\n\n        // Go through every key on the object,\n      } else {\n        for (i in elems) {\n          value = callback(elems[i], i, arg);\n          if (value != null) {\n            ret.push(value);\n          }\n        }\n      }\n\n      // Flatten any nested arrays\n      return concat.apply([], ret);\n    },\n    // A global GUID counter for objects\n    guid: 1,\n    // Bind a function to a context, optionally partially applying any\n    // arguments.\n    proxy: function proxy(fn, context) {\n      var tmp, args, proxy;\n      if (typeof context === "string") {\n        tmp = fn[context];\n        context = fn;\n        fn = tmp;\n      }\n\n      // Quick check to determine if target is callable, in the spec\n      // this throws a TypeError, but we will just return undefined.\n      if (!_jQuery2.isFunction(fn)) {\n        return undefined;\n      }\n\n      // Simulated bind\n      args = _slice.call(arguments, 2);\n      proxy = function proxy() {\n        return fn.apply(context || this, args.concat(_slice.call(arguments)));\n      };\n\n      // Set the guid of unique handler to the same of original handler, so it can be removed\n      proxy.guid = fn.guid = fn.guid || _jQuery2.guid++;\n      return proxy;\n    },\n    now: Date.now,\n    // jQuery.support is not used in Core but other projects attach their\n    // properties to it so it needs to exist.\n    support: support\n  });\n  if (typeof Symbol === "function") {\n    _jQuery2.fn[Symbol.iterator] = arr[Symbol.iterator];\n  }\n\n  // Populate the class2type map\n  _jQuery2.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) {\n    class2type["[object " + name + "]"] = name.toLowerCase();\n  });\n  function isArrayLike(obj) {\n    // Support: real iOS 8.2 only (not reproducible in simulator)\n    // `in` check used to prevent JIT error (gh-2145)\n    // hasOwn isn\'t used here due to false negatives\n    // regarding Nodelist length in IE\n    var length = !!obj && "length" in obj && obj.length,\n      type = _jQuery2.type(obj);\n    if (type === "function" || _jQuery2.isWindow(obj)) {\n      return false;\n    }\n    return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;\n  }\n  var Sizzle =\n  /*!\r\n   * Sizzle CSS Selector Engine v2.3.3\r\n   * https://sizzlejs.com/\r\n   *\r\n   * Copyright jQuery Foundation and other contributors\r\n   * Released under the MIT license\r\n   * http://jquery.org/license\r\n   *\r\n   * Date: 2016-08-08\r\n   */\n  function (window) {\
1n    var i,\n      support,\n      Expr,\n      getText,\n      isXML,\n      tokenize,\n      compile,\n      select,\n      outermostContext,\n      sortInput,\n      hasDuplicate,\n      // Local document vars\n      setDocument,\n      document,\n      docElem,\n      documentIsHTML,\n      rbuggyQSA,\n      rbuggyMatches,\n      matches,\n      contains,\n      // Instance-specific data\n      expando = "sizzle" + 1 * new Date(),\n      preferredDoc = window.document,\n      dirruns = 0,\n      done = 0,\n      classCache = createCache(),\n      tokenCache = createCache(),\n      compilerCache = createCache(),\n      sortOrder = function sortOrder(a, b) {\n        if (a === b) {\n          hasDuplicate = true;\n        }\n        return 0;\n      },\n      // Instance methods\n      hasOwn = {}.hasOwnProperty,\n      arr = [],\n      pop = arr.pop,\n      push_native = arr.push,\n      push = arr.push,\n      slice = arr.slice,\n      // Use a stripped-down indexOf as it\'s faster than native\n      // https://jsperf.com/thor-indexof-vs-for/5\n      indexOf = function indexOf(list, elem) {\n        var i = 0,\n          len = list.length;\n        for (; i < len; i++) {\n          if (list[i] === elem) {\n            return i;\n          }\n        }\n        return -1;\n      },\n      booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",\n      // Regular expressions\n\n      // http://www.w3.org/TR/css3-selectors/#whitespace\n      whitespace = "[\\\\x20\\\\t\\\\r\\\\n\\\\f]",\n      // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n      identifier = "(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+",\n      // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n      attributes = "\\\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +\n      // Operator (capture 2)\n      "*([*^$|!~]?=)" + whitespace +\n      // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"\n      "*(?:\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\"|(" + identifier + "))|)" + whitespace + "*\\\\]",\n      pseudos = ":(" + identifier + ")(?:\\\\((" +\n      // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n      // 1. quoted (capture 3; capture 4 or capture 5)\n      "(\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\")|" +\n      // 2. simple (capture 6)\n      "((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|" + attributes + ")*)|" +\n      // 3. anything else (capture 2)\n      ".*" + ")\\\\)|)",\n      // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n      rwhitespace = new RegExp(whitespace + "+", "g"),\n      rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)" + whitespace + "+$", "g"),\n      rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),\n      rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),\n      rattributeQuotes = new RegExp("=" + whitespace + "*([^\\\\]\'\\"]*?)" + whitespace + "*\\\\]", "g"),\n      rpseudo = new RegExp(pseudos),\n      ridentifier = new RegExp("^" + identifier + "$"),\n      matchExpr = {\n        "ID": new RegExp("^#(" + identifier + ")"),\n        "CLASS": new RegExp("^\\\\.(" + identifier + ")"),\n        "TAG": new RegExp("^(" + identifier + "|[*])"),\n        "ATTR": new RegExp("^" + attributes),\n        "PSEUDO": new RegExp("^" + pseudos),\n        "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(" + whitespace + "*(even|odd|(([+-]|)(\\\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\\\d+)|))" + whitespace + "*\\\\)|)", "i"),\n        "bool": new RegExp("^(?:" + booleans + ")$", "i"),\n        // For use in libraries implementing .is()\n        // We use this for POS matching in `select`\n        "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(" + whitespace + "*((?:-\\\\d)?\\\\d*)" + whitespace + "*\\\\)|)(?=[^-]|$)", "i")\n      },\n      rinputs = /^(?:input|select|textarea|button)$/i,\n      rheader = /^h\\d$/i,\n      rnative = /^[^{]+\\{\\s*\\[native \\w/,\n      // Easily-parseable/retrievable ID or TAG or CLASS selectors\n      rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n      rsibling = /[+~]/,\n      // CSS escapes\n      // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n      runescape = new RegExp("\\\\\\\\([\\\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),\n      funescape = function funescape(_, escaped, escapedWhitespace) {\n        var high = "0x" + escaped - 0x10000;
1\n        // NaN means non-codepoint\n        // Support: Firefox<24\n        // Workaround erroneous numeric interpretation of +"0x"\n        return high !== high || escapedWhitespace ? escaped : high < 0 ?\n        // BMP codepoint\n        String.fromCharCode(high + 0x10000) :\n        // Supplemental Plane codepoint (surrogate pair)\n        String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);\n      },\n      // CSS string/identifier serialization\n      // https://drafts.csswg.org/cssom/#common-serializing-idioms\n      rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n      fcssescape = function fcssescape(ch, asCodePoint) {\n        if (asCodePoint) {\n          // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n          if (ch === "\\0") {\n            return "\\uFFFD";\n          }\n\n          // Control characters and (dependent upon position) numbers get escaped as code points\n          return ch.slice(0, -1) + "\\\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";\n        }\n\n        // Other potentially-special ASCII characters get backslash-escaped\n        return "\\\\" + ch;\n      },\n      // Used for iframes\n      // See setDocument()\n      // Removing the function wrapper causes a "Permission Denied"\n      // error in IE\n      unloadHandler = function unloadHandler() {\n        setDocument();\n      },\n      disabledAncestor = addCombinator(function (elem) {\n        return elem.disabled === true && ("form" in elem || "label" in elem);\n      }, {\n        dir: "parentNode",\n        next: "legend"\n      });\n\n    // Optimize for push.apply( _, NodeList )\n    try {\n      push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);\n      // Support: Android<4.0\n      // Detect silently failing push.apply\n      arr[preferredDoc.childNodes.length].nodeType;\n    } catch (e) {\n      push = {\n        apply: arr.length ?\n        // Leverage slice if possible\n        function (target, els) {\n          push_native.apply(target, slice.call(els));\n        } :\n        // Support: IE<9\n        // Otherwise append directly\n        function (target, els) {\n          var j = target.length,\n            i = 0;\n          // Can\'t trust NodeList.length\n          while (target[j++] = els[i++]) {}\n          target.length = j - 1;\n        }\n      };\n    }\n    function Sizzle(selector, context, results, seed) {\n      var m,\n        i,\n        elem,\n        nid,\n        match,\n        groups,\n        newSelector,\n        newContext = context && context.ownerDocument,\n        // nodeType defaults to 9, since context defaults to document\n        nodeType = context ? context.nodeType : 9;\n      results = results || [];\n\n      // Return early from calls with invalid selector or context\n      if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {\n        return results;\n      }\n\n      // Try to shortcut find operations (as opposed to filters) in HTML documents\n      if (!seed) {\n        if ((context ? context.ownerDocument || context : preferredDoc) !== document) {\n          setDocument(context);\n        }\n        context = context || document;\n        if (documentIsHTML) {\n          // If the selector is sufficiently simple, try using a "get*By*" DOM method\n          // (excepting DocumentFragment context, where the methods don\'t exist)\n          if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {\n            // ID selector\n            if (m = match[1]) {\n              // Document context\n              if (nodeType === 9) {\n                if (elem = context.getElementById(m)) {\n                  // Support: IE, Opera, Webkit\n                  // TODO: identify versions\n                  // getElementById can match elements by name instead of ID\n                  if (elem.id === m) {\n                    results.push(elem);\n                    return results;\n                  }\n                } else {\n                  return results;\n                }\n\n                // Element context\n              }
1 else {\n                // Support: IE, Opera, Webkit\n                // TODO: identify versions\n                // getElementById can match elements by name instead of ID\n                if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {\n                  results.push(elem);\n                  return results;\n                }\n              }\n\n              // Type selector\n            } else if (match[2]) {\n              push.apply(results, context.getElementsByTagName(selector));\n              return results;\n\n              // Class selector\n            } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {\n              push.apply(results, context.getElementsByClassName(m));\n              return results;\n            }\n          }\n\n          // Take advantage of querySelectorAll\n          if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {\n            if (nodeType !== 1) {\n              newContext = context;\n              newSelector = selector;\n\n              // qSA looks outside Element context, which is not what we want\n              // Thanks to Andrew Dupont for this workaround technique\n              // Support: IE <=8\n              // Exclude object elements\n            } else if (context.nodeName.toLowerCase() !== "object") {\n              // Capture the context ID, setting it first if necessary\n              if (nid = context.getAttribute("id")) {\n                nid = nid.replace(rcssescape, fcssescape);\n              } else {\n                context.setAttribute("id", nid = expando);\n              }\n\n              // Prefix every selector in the list\n              groups = tokenize(selector);\n              i = groups.length;\n              while (i--) {\n                groups[i] = "#" + nid + " " + toSelector(groups[i]);\n              }\n              newSelector = groups.join(",");\n\n              // Expand context for sibling selectors\n              newContext = rsibling.test(selector) && testContext(context.parentNode) || context;\n            }\n            if (newSelector) {\n              try {\n                push.apply(results, newContext.querySelectorAll(newSelector));\n                return results;\n              } catch (qsaError) {} finally {\n                if (nid === expando) {\n                  context.removeAttribute("id");\n                }\n              }\n            }\n          }\n        }\n      }\n\n      // All others\n      return select(selector.replace(rtrim, "$1"), context, results, seed);\n    }\n\n    /**\r\n     * Create key-value caches of limited size\r\n     * @returns {function(string, object)} Returns the Object data after storing it on itself with\r\n     *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\r\n     *\tdeleting the oldest entry\r\n     */\n    function createCache() {\n      var keys = [];\n      function cache(key, value) {\n        // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)\n        if (keys.push(key + " ") > Expr.cacheLength) {\n          // Only keep the most recent entries\n          delete cache[keys.shift()];\n        }\n        return cache[key + " "] = value;\n      }\n      return cache;\n    }\n\n    /**\r\n     * Mark a function for special use by Sizzle\r\n     * @param {Function} fn The function to mark\r\n     */\n    function markFunction(fn) {\n      fn[expando] = true;\n      return fn;\n    }\n\n    /**\r\n     * Support testing using an element\r\n     * @param {Function} fn Passed the created element and returns a boolean result\r\n     */\n    function assert(fn) {\n      var el = document.createElement("fieldset");\n      try {\n        return !!fn(el);\n      } catch (e) {\n        return false;\n      } finally {\n        // Remove from its parent by default\n        if (el.parentNode) {\n          el.parentNode.removeChild(el);\n        }\n        // release memory in IE\n        el = null;\n      }\n    }\n\n    /**\r\n     * Adds the same handler for all of the specified attrs\r\n     * @param {String} attrs Pipe-separated list of attributes\r\n     * @param {Function} handler The method that will be applied\r\n     */\n    function addHandle(attrs, handler) {\n      var arr = attrs.split("|"),\n        i = arr.length;\n      while (i--) {\n        Expr.attrHandle[arr[i]] = handler;\n      }\n    }\n\n    /**\r\n     * Checks document order of two siblings\r\n     * @param {Element} a\r\n     * @param {Element} b\r\n     * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\r\n     */\n    function siblingCheck(a, b) {\n      var cur = b && a,\n        diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex;\n\n      // Use IE sourceIndex if available on both nodes\n      if (diff) {\n        return diff;\n      }\n\n      // Check if b follows a\n      if (cur) {\n        while (cur = cur.nextSibling) {\n          if (cur === b) {\n            return -1;\n          }\n        }\n      }\n      return a ? 1 : -1;\n    }\n\n    /**\r\n     * Returns a function to use in pseudos for input types\r\n     * @param {String} type\r\n     */\n    function createInputPseudo(type) {\n      return function (elem) {\n        var name = elem.nodeName.toLowerCase();\n        return name === "input" && elem.type === type;\n      };\n    }\n\n    /**\r\n     * Returns a function to use in pseudos for buttons\r\n     * @param {String} type\r\n     */\n    function createButtonPseudo(type) {\n      return function (elem) {\n        var name = elem.nodeName.toLowerCase();\n        return (name === "input" || name === "button") && elem.type === type;\n      };\n    }\n\n    /**\r\n     * Returns a function to use in pseudos for :enabled/:disabled\r\n     * @param {Boolean} disabled true for :disabled; false for :enabled\r\n     */\n    function createDisabledPseudo(disabled) {\n      // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n      return function (elem) {\n        // Only certain elements can match :enabled or :disabled\n        // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n        // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n        if ("form" in elem) {\n          // Check for inherited disabledness on relevant non-disabled elements:\n          // * listed form-associated elements in a disabled fieldset\n          //   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n          //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n          // * option elements in a disabled optgroup\n          //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n          // All such elements have a "form" property.\n          if (elem.parentNode && elem.disabled === false) {\n            // Option elements defer to a parent optgroup if present\n            if ("label" in elem) {\n              if ("label" in elem.parentNode) {\n                return elem.parentNode.disabled === disabled;\n              } else {\n                return elem.disabled === disabled;\n              }\n            }
1\n\n            // Support: IE 6 - 11\n            // Use the isDisabled shortcut property to check for disabled fieldset ancestors\n            return elem.isDisabled === disabled ||\n            // Where there is no isDisabled, check manually\n            /* jshint -W018 */\n            elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled;\n          }\n          return elem.disabled === disabled;\n\n          // Try to winnow out elements that can\'t be disabled before trusting the disabled property.\n          // Some victims get caught in our net (label, legend, menu, track), but it shouldn\'t\n          // even exist on them, let alone have a boolean value.\n        } else if ("label" in elem) {\n          return elem.disabled === disabled;\n        }\n\n        // Remaining elements are neither :enabled nor :disabled\n        return false;\n      };\n    }\n\n    /**\r\n     * Returns a function to use in pseudos for positionals\r\n     * @param {Function} fn\r\n     */\n    function createPositionalPseudo(fn) {\n      return markFunction(function (argument) {\n        argument = +argument;\n        return markFunction(function (seed, matches) {\n          var j,\n            matchIndexes = fn([], seed.length, argument),\n            i = matchIndexes.length;\n\n          // Match elements found at the specified indexes\n          while (i--) {\n            if (seed[j = matchIndexes[i]]) {\n              seed[j] = !(matches[j] = seed[j]);\n            }\n          }\n        });\n      });\n    }\n\n    /**\r\n     * Checks a node for validity as a Sizzle context\r\n     * @param {Element|Object=} context\r\n     * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\r\n     */\n    function testContext(context) {\n      return context && typeof context.getElementsByTagName !== "undefined" && context;\n    }\n\n    // Expose support vars for convenience\n    support = Sizzle.support = {};\n\n    /**\r\n     * Detects XML nodes\r\n     * @param {Element|Object} elem An element or a document\r\n     * @returns {Boolean} True iff elem is a non-HTML XML node\r\n     */\n    isXML = Sizzle.isXML = function (elem) {\n      // documentElement is verified for cases where it doesn\'t yet exist\n      // (such as loading iframes in IE - #4833)\n      var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n      return documentElement ? documentElement.nodeName !== "HTML" : false;\n    };\n\n    /**\r\n     * Sets document-related variables once based on the current document\r\n     * @param {Element|Object} [doc] An element or document object to use to set the document\r\n     * @returns {Object} Returns the current document\r\n     */\n    setDocument = Sizzle.setDocument = function (node) {\n      var hasCompare,\n        subWindow,\n        doc = node ? node.ownerDocument || node : preferredDoc;\n\n      // Return early if doc is invalid or already selected\n      if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {\n        return document;\n      }\n\n      // Update global variables\n      document = doc;\n      docElem = document.documentElement;\n      documentIsHTML = !isXML(document);\n\n      // Support: IE 9-11, Edge\n      // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)\n      if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {\n        // Support: IE 11, Edge\n        if (subWindow.addEventListener) {\n          subWindow.addEventListener("unload", unloadHandler, false);\n\n          // Support: IE 9 - 10 only\n        } else if (subWindow.attachEvent) {\n          subWindow.attachEvent("onunload", unloadHandler);\n        }\n      }\n\n      /* Attributes\r\n      ---------------------------------------------------------------------- */\n\n      // Support: IE<8\n      // Verify that getAttribute really returns attributes and not properties\n      // (excepting IE8 booleans)\n      support.attributes = assert(function (el) {\n        el.className = "i";\n        return !el.getAttribute("className");\n      });\n\n      /* getElement(s)By*\r\n      ---------------------------------------------------------------------- */\n\n      // Check if getElementsByTagName("*") returns only elements\n      support.getElementsByTagName = assert(function (el) {\n        el.appendChild(document.createComment(""));\n        return !el.getElementsByTagName("*").length;\n      });
1\n\n      // Support: IE<9\n      support.getElementsByClassName = rnative.test(document.getElementsByClassName);\n\n      // Support: IE<10\n      // Check if getElementById returns elements by name\n      // The broken getElementById methods don\'t pick up programmatically-set names,\n      // so use a roundabout getElementsByName test\n      support.getById = assert(function (el) {\n        docElem.appendChild(el).id = expando;\n        return !document.getElementsByName || !document.getElementsByName(expando).length;\n      });\n\n      // ID filter and find\n      if (support.getById) {\n        Expr.filter["ID"] = function (id) {\n          var attrId = id.replace(runescape, funescape);\n          return function (elem) {\n            return elem.getAttribute("id") === attrId;\n          };\n        };\n        Expr.find["ID"] = function (id, context) {\n          if (typeof context.getElementById !== "undefined" && documentIsHTML) {\n            var elem = context.getElementById(id);\n            return elem ? [elem] : [];\n          }\n        };\n      } else {\n        Expr.filter["ID"] = function (id) {\n          var attrId = id.replace(runescape, funescape);\n          return function (elem) {\n            var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");\n            return node && node.value === attrId;\n          };\n        };\n\n        // Support: IE 6 - 7 only\n        // getElementById is not reliable as a find shortcut\n        Expr.find["ID"] = function (id, context) {\n          if (typeof context.getElementById !== "undefined" && documentIsHTML) {\n            var node,\n              i,\n              elems,\n              elem = context.getElementById(id);\n            if (elem) {\n              // Verify the id attribute\n              node = elem.getAttributeNode("id");\n              if (node && node.value === id) {\n                return [elem];\n              }\n\n              // Fall back on getElementsByName\n              elems = context.getElementsByName(id);\n              i = 0;\n              while (elem = elems[i++]) {\n                node = elem.getAttributeNode("id");\n                if (node && node.value === id) {\n                  return [elem];\n                }\n              }\n            }\n            return [];\n          }\n        };\n      }\n\n      // Tag\n      Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {\n        if (typeof context.getElementsByTagName !== "undefined") {\n          return context.getElementsByTagName(tag);\n\n          // DocumentFragment nodes don\'t have gEBTN\n        } else if (support.qsa) {\n          return context.querySelectorAll(tag);\n        }\n      } : function (tag, context) {\n        var elem,\n          tmp = [],\n          i = 0,\n          // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n          results = context.getElementsByTagName(tag);\n\n        // Filter out possible comments\n        if (tag === "*") {\n          while (elem = results[i++]) {\n            if (elem.nodeType === 1) {\n              tmp.push(elem);\n            }\n          }\n          return tmp;\n        }\n        return results;\n      };\n\n      // Class\n      Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {\n        if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {\n          return context.getElementsByClassName(className);\n        }\n      };\n\n      /* QSA/matchesSelector\r\n      ---------------------------------------------------------------------- */\n\n      // QSA and matchesSelector support\n\n      // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n      rbuggyMatches = [];\n\n      // qSa(:focus) reports false when true (Chrome 21)\n      // We allow this because of a bug in IE8/9 that throws an error\n      // whenever `document.activeElement` is accessed on an iframe\n      // So, we allow :focus to pass through QSA all the time to avoid the IE error\n      // See https://bugs.jquery.com/ticket/13378\n      rbuggyQSA = [];\n      if (support.qsa = rnative.test(document.querySelectorAll)) {\n        // Build QSA regex\n        // Regex strategy adopted from Diego Perini\n        assert(function (el) {\n          // Select is set to empty string on purpose\n          // This is to test IE\'s treatment of not explicitly\n          // setting a boolean content attribute,\n          // since its presence should be enough\n          // https://bugs.jquery.com/ticket/12359\n          docElem.appendChild(el).innerHTML = "<a id=\'" + expando + "\'></a>" + "<select id=\'" + expando + "-\\r\\\\\' msallowcapture=\'\'>" + "<option selected=\'\'></option></select>";
1\n\n          // Support: IE8, Opera 11-12.16\n          // Nothing should be selected when empty strings follow ^= or $= or *=\n          // The test attribute must be unknown in Opera but "safe" for WinRT\n          // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n          if (el.querySelectorAll("[msallowcapture^=\'\']").length) {\n            rbuggyQSA.push("[*^$]=" + whitespace + "*(?:\'\'|\\"\\")");\n          }\n\n          // Support: IE8\n          // Boolean attributes and "value" are not treated correctly\n          if (!el.querySelectorAll("[selected]").length) {\n            rbuggyQSA.push("\\\\[" + whitespace + "*(?:value|" + booleans + ")");\n          }\n\n          // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n          if (!el.querySelectorAll("[id~=" + expando + "-]").length) {\n            rbuggyQSA.push("~=");\n          }\n\n          // Webkit/Opera - :checked should return selected option elements\n          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n          // IE8 throws error here and will not see later tests\n          if (!el.querySelectorAll(":checked").length) {\n            rbuggyQSA.push(":checked");\n          }\n\n          // Support: Safari 8+, iOS 8+\n          // https://bugs.webkit.org/show_bug.cgi?id=136851\n          // In-page `selector#id sibling-combinator selector` fails\n          if (!el.querySelectorAll("a#" + expando + "+*").length) {\n            rbuggyQSA.push(".#.+[+~]");\n          }\n        });\n        assert(function (el) {\n          el.innerHTML = "<a href=\'\' disabled=\'disabled\'></a>" + "<select disabled=\'disabled\'><option/></select>";\n\n          // Support: Windows 8 Native Apps\n          // The type and name attributes are restricted during .innerHTML assignment\n          var input = document.createElement("input");\n          input.setAttribute("type", "hidden");\n          el.appendChild(input).setAttribute("name", "D");\n\n          // Support: IE8\n          // Enforce case-sensitivity of name attribute\n          if (el.querySelectorAll("[name=d]").length) {\n            rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");\n          }\n\n          // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n          // IE8 throws error here and will not see later tests\n          if (el.querySelectorAll(":enabled").length !== 2) {\n            rbuggyQSA.push(":enabled", ":disabled");\n          }\n\n          // Support: IE9-11+\n          // IE\'s :disabled selector does not pick up the children of disabled fieldsets\n          docElem.appendChild(el).disabled = true;\n          if (el.querySelectorAll(":disabled").length !== 2) {\n            rbuggyQSA.push(":enabled", ":disabled");\n          }\n\n          // Opera 10-11 does not throw on post-comma invalid pseudos\n          el.querySelectorAll("*,:x");\n          rbuggyQSA.push(",.*:");\n        });\n      }\n      if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {\n        assert(function (el) {\n          // Check to see if it\'s possible to do matchesSelector\n          // on a disconnected node (IE 9)\n          support.disconnectedMatch = matches.call(el, "*");\n\n          // This should fail with an exception\n          // Gecko does not error, returns false instead\n          matches.call(el, "[s!=\'\']:x");\n          rbuggyMatches.push("!=", pseudos);\n        });\n      }\n      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));\n      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));\n\n      /* Contains\r\n      ---------------------------------------------------------------------- */\n      hasCompare = rnative.test(docElem.compareDocumentPosition);\n\n      // Element contains another\n      // Purposefully self-exclusive\n      // As in, an element does not contain itself\n      contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {\n        var adown = a.nodeType === 9 ? a.documentElement : a,\n          bup = b && b.parentNode;\n        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));\n      } : function (a, b) {\n        if (b) {\n          while (b = b.parentNode) {\n            if (b === a) {\n              return true;\n            }\n          }\n        }\n        return false;\n      };\n\n      /* Sorting\r\n      ---------------------------------------------------------------------- */\n\n      // Document order sorting\n      sortOrder = hasCompare ? function (a, b) {\n        // Flag for duplicate removal\n        if (a === b) {\n          hasDuplicate = true;\n          return 0;\n        }\n\n        // Sort on method existence if only one input has compareDocumentPosition\n        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n        if (compare) {\n          return compare;\n        }\n\n        // Calculate position if both inputs belong to the same document\n        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) :\n        // Otherwise we know they are disconnected\n        1;\n\n        // Disconnected nodes\n        if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {\n          // Choose the first element that is related to our preferred document\n          if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {\n            return -1;\n          }\n          if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {\n            return 1;\n          }\n\n          // Maintain original order\n          return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;\n        }\n        return compare & 4 ? -1 : 1;\n      } : function (a, b) {\n        // Exit early if the nodes are identical\n        if (a === b) {\n          hasDuplicate = true;\n          return 0;\n        }\n        var cur,\n          i = 0,\n          aup = a.parentNode,\n          bup = b.parentNode,\n          ap = [a],\n          bp = [b];\n\n        // Parentless nodes are either documents or disconnected\n        if (!aup || !bup) {\n          return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;\n\n          // If the nodes are siblings, we can do a quick check\n        } else if (aup === bup) {\n          return siblingCheck(a, b);\n        }\n\n        // Otherwise we need full lists of their ancestors for comparison\n        cur = a;\n        while (cur = cur.parentNode) {\n          ap.unshift(cur);\n        }\n        cur = b;\n        while (cur = cur.parentNode) {\n          bp.unshift(cur);\n        }\n\n        // Walk down the tree looking for a discrepancy\n        while (ap[i] === bp[i]) {\n          i++;\n        }\n        return i ?\n        // Do a sibling check if the nodes have a common ancestor\n        siblingCheck(ap[i], bp[i]) :\n        // Otherwise nodes in our document sort first\n        ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;\n      };\n      return document;\n    };\n    Sizzle.matches = function (expr, elements) {\n      return Sizzle(expr, null, null, elements);\n    };\n    Sizzle.matchesSelector = function (elem, expr) {\n      // Set document vars if needed\n      if ((elem.ownerDocument || elem) !== document) {\n        setDocument(elem);\n      }\n\n      // Make sure that attribute selectors are quoted\n      expr = expr.replace(rattributeQuotes, "=\'$1\']");\n      if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {\n        try {\n          var ret = matches.call(elem, expr);\n\n          // IE 9\'s matchesSelector returns false on disconnected nodes\n          if (ret || support.disconnectedMatch ||\n          // As well, disconnected nodes are said to be in a document\n          // fragment in IE 9\n          elem.document && elem.document.nodeType !== 11) {\n            return ret;\n          }\n        } catch (e) {}\n      }\n      return Sizzle(expr, document, null, [elem]).length > 0;\n    };\n    Sizzle.contains = function (context, elem) {\n      // Set document vars if needed\n      if ((context.ownerDocument || context) !== document) {\n        setDocument(context);\n      }\n      return contains(context, elem);\n    };\n    Sizzle.attr = function (elem, name) {\n      // Set document vars if needed\n      if ((elem.ownerDocument || elem) !== document) {\n        setDocument(elem);\n      }\n      var fn = Expr.attrHandle[name.toLowerCase()],\n        // Don\'t get fooled by Object.prototype properties (jQuery #13807)\n        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;\n      return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;\n    };\n    Sizzle.escape = function (sel) {\n      return (sel + "").replace(rcssescape, fcssescape);\n    };\n    Sizzle.error = function (msg) {\n      throw new Error("Syntax error, unrecognized expression: " + msg);\n    };\n\n    /**\r\n     * Document sorting and removing duplicates\r\n     * @param {ArrayLike} results\r\n     */\n    Sizzle.uniqueSort = function (results) {\n      var elem,\n        duplicates = [],\n        j = 0,\n        i = 0;\n\n      // Unless we *know* we can detect duplicates, assume their presence\n      hasDuplicate = !support.detectDuplicates;\n      sortInput = !support.sortStable && results.slice(0);\n      results.sort(sortOrder);
1\n      if (hasDuplicate) {\n        while (elem = results[i++]) {\n          if (elem === results[i]) {\n            j = duplicates.push(i);\n          }\n        }\n        while (j--) {\n          results.splice(duplicates[j], 1);\n        }\n      }\n\n      // Clear input after sorting to release objects\n      // See https://github.com/jquery/sizzle/pull/225\n      sortInput = null;\n      return results;\n    };\n\n    /**\r\n     * Utility function for retrieving the text value of an array of DOM nodes\r\n     * @param {Array|Element} elem\r\n     */\n    getText = Sizzle.getText = function (elem) {\n      var node,\n        ret = "",\n        i = 0,\n        nodeType = elem.nodeType;\n      if (!nodeType) {\n        // If no nodeType, this is expected to be an array\n        while (node = elem[i++]) {\n          // Do not traverse comment nodes\n          ret += getText(node);\n        }\n      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {\n        // Use textContent for elements\n        // innerText usage removed for consistency of new lines (jQuery #11153)\n        if (typeof elem.textContent === "string") {\n          return elem.textContent;\n        } else {\n          // Traverse its children\n          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n            ret += getText(elem);\n          }\n        }\n      } else if (nodeType === 3 || nodeType === 4) {\n        return elem.nodeValue;\n      }\n      // Do not include comment or processing instruction nodes\n\n      return ret;\n    };\n    Expr = Sizzle.selectors = {\n      // Can be adjusted by the user\n      cacheLength: 50,\n      createPseudo: markFunction,\n      match: matchExpr,\n      attrHandle: {},\n      find: {},\n      relative: {\n        ">": {\n          dir: "parentNode",\n          first: true\n        },\n        " ": {\n          dir: "parentNode"\n        },\n        "+": {\n          dir: "previousSibling",\n          first: true\n        },\n        "~": {\n          dir: "previousSibling"\n        }\n      },\n      preFilter: {\n        "ATTR": function ATTR(match) {\n          match[1] = match[1].replace(runescape, funescape);\n\n          // Move the given value to match[3] whether quoted or unquoted\n          match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);\n          if (match[2] === "~=") {\n            match[3] = " " + match[3] + " ";\n          }\n          return match.slice(0, 4);\n        },\n        "CHILD": function CHILD(match) {\n          /* matches from matchExpr["CHILD"]\r\n          \t1 type (only|nth|...)\r\n          \t2 what (child|of-type)\r\n          \t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\r\n          \t4 xn-component of xn+y argument ([+-]?\\d*n|)\r\n          \t5 sign of xn-component\r\n          \t6 x of xn-component\r\n          \t7 sign of y-component\r\n          \t8 y of y-component\r\n          */\n          match[1] = match[1].toLowerCase();\n          if (match[1].slice(0, 3) === "nth") {\n            // nth-* requires argument\n            if (!match[3]) {\n              Sizzle.error(match[0]);\n            }\n\n            // numeric x and y parameters for Expr.filter.CHILD\n            // remember that false/true cast respectively to 0/1\n            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));\n            match[5] = +(match[7] + match[8] || match[3] === "odd");\n\n            // other types prohibit arguments\n          } else if (match[3]) {\n            Sizzle.error(match[0]);\n          }\n          return match;\n        },\n        "PSEUDO": function PSEUDO(match) {\n          var excess,\n            unquoted = !match[6] && match[2];\n          if (matchExpr["CHILD"].test(match[0])) {\n            return null;\n          }\n\n          // Accept quoted arguments as-is\n          if (match[3]) {\n            match[2] = match[4] || match[5] || "";\n\n            // Strip excess characters from unquoted arguments\n          } else if (unquoted && rpseudo.test(unquoted) && (\n          // Get excess from tokenize (recursively)\n          excess = tokenize(unquoted, true)) && (\n          // advance to the next closing parenthesis\n          excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {\n            // excess is a negative index\n            match[0] = match[0].slice(0, excess);\n            match[2] = unquoted.slice(0, excess);\n          }\n\n          // Return only captures needed by the pseudo filter method (type and argument)\n          return match.slice(0, 3);\n        }\n      },\n      filter: {\n        "TAG": function TAG(nodeNameSelector) {\n          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();\n          return nodeNameSelector === "*" ? function () {\n            return true;\n          } : function (elem) {\n            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n          };\n        },\n        "CLASS": function CLASS(className) {\n          var pattern = classCache[className + " "];\n          return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {\n            return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");\n          });\n        },\n        "ATTR": function ATTR(name, operator, check) {\n          return function (elem) {\n            var result = Sizzle.attr(elem, name);\n            if (result == null) {\n              return operator === "!=";\n            }\n            if (!operator) {\n              return true;\n            }\n            result += "";\n            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;\n          };\n        },\n        "CHILD": function CHILD(type, what, argument, first, last) {\n          var simple = type.slice(0, 3) !== "nth",\n            forward = type.slice(-4) !== "last",\n            ofType = what === "of-type";\n          return first === 1 && last === 0 ?\n          // Shortcut for :nth-*(n)\n          function (elem) {\n            return !!elem.parentNode;\n          } : function (elem, context, xml) {\n            var cache,\n              uniqueCache,\n              outerCache,\n              node,\n              nodeIndex,\n              start,\n              dir = simple !== forward ? "nextSibling" : "previousSibling",\n              parent = elem.parentNode,\n              name = ofType && elem.nodeName.toLowerCase(),\n              useCache = !xml && !ofType,\n              diff = false;\n            if (parent) {\n              // :(first|last|only)-(child|of-type)\n              if (simple) {\n                while (dir) {\n                  node = elem;\n                  while (node = node[dir]) {\n                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {\n                      return false;\n                    }\n                  }\n                  // Reverse direction for :only-* (if we haven\'t yet done so)\n                  start = dir = type === "only" && !start && "nextSibling";\n                }\n                return true;\n              }\n              start = [forward ? parent.firstChild : parent.lastChild];\n\n              // non-xml :nth-child(...) stores cache data on `parent`\n              if (forward && useCache) {\n                // Seek `elem` from a previously-cached index\n\n                // ...in a gzip-friendly way\n                node = parent;\n                outerCache = node[expando] || (node[expando] = {});
1\n\n                // Support: IE <9 only\n                // Defend against cloned attroperties (jQuery gh-1709)\n                uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});\n                cache = uniqueCache[type] || [];\n                nodeIndex = cache[0] === dirruns && cache[1];\n                diff = nodeIndex && cache[2];\n                node = nodeIndex && parent.childNodes[nodeIndex];\n                while (node = ++nodeIndex && node && node[dir] || (\n                // Fallback to seeking `elem` from the start\n                diff = nodeIndex = 0) || start.pop()) {\n                  // When found, cache indexes on `parent` and break\n                  if (node.nodeType === 1 && ++diff && node === elem) {\n                    uniqueCache[type] = [dirruns, nodeIndex, diff];\n                    break;\n                  }\n                }\n              } else {\n                // Use previously-cached element index if available\n                if (useCache) {\n                  // ...in a gzip-friendly way\n                  node = elem;\n                  outerCache = node[expando] || (node[expando] = {});\n\n                  // Support: IE <9 only\n                  // Defend against cloned attroperties (jQuery gh-1709)\n                  uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});\n                  cache = uniqueCache[type] || [];\n                  nodeIndex = cache[0] === dirruns && cache[1];\n                  diff = nodeIndex;\n                }\n\n                // xml :nth-child(...)\n                // or :nth-last-child(...) or :nth(-last)?-of-type(...)\n                if (diff === false) {\n                  // Use the same loop as above to seek `elem` from the start\n                  while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {\n                    if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {\n                      // Cache the index of each encountered element\n                      if (useCache) {\n                        outerCache = node[expando] || (node[expando] = {});\n\n                        // Support: IE <9 only\n                        // Defend against cloned attroperties (jQuery gh-1709)\n                        uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});\n                        uniqueCache[type] = [dirruns, diff];\n                      }\n                      if (node === elem) {\n                        break;\n                      }\n                    }\n                  }\n                }\n              }\n\n              // Incorporate the offset, then check against cycle size\n              diff -= last;\n              return diff === first || diff % first === 0 && diff / first >= 0;\n            }\n          };\n        },\n        "PSEUDO": function PSEUDO(pseudo, argument) {\n          // pseudo-class names are case-insensitive\n          // http://www.w3.org/TR/selectors/#pseudo-classes\n          // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n          // Remember that setFilters inherits from pseudos\n          var args,\n            fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo);\n\n          // The user may use createPseudo to indicate that\n          // arguments are needed to create the filter function\n          // just as Sizzle does\n          if (fn[expando]) {\n            return fn(argument);\n          }\n\n          // But maintain support for old signatures\n          if (fn.length > 1) {\n            args = [pseudo, pseudo, "", argument];\n            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {\n              var idx,\n                matched = fn(seed, argument),\n                i = matched.length;\n              while (i--) {\n                idx = indexOf(seed, matched[i]);\n                seed[idx] = !(matches[idx] = matched[i]);\n              }\n            }) : function (elem) {\n              return fn(elem, 0, args);\n            };\n          }\n          return fn;\n        }\n      },\n      pseudos: {\n        // Potentially complex pseudos\n        "not": markFunction(function (selector) {\n          // Trim the selector passed to compile\n          // to avoid treating leading and trailing\n          // spaces as combinators\n          var input = [],\n            results = [],\n            matcher = compile(selector.replace(rtrim, "$1"));\n          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {\n            var elem,\n              unmatched = matcher(seed, null, xml, []),\n              i = seed.length;\n\n            // Match elements unmatched by `matcher`\n            while (i--) {\n              if (elem = unmatched[i]) {\n                seed[i] = !(matches[i] = elem);\n              }\n            }\n          }) : function (elem, context, xml) {\n            input[0] = elem;\n            matcher(input, null, xml, results);\n            // Don\'t keep the element (issue #299)\n            input[0] = null;\n            return !results.pop();\n          };\n        }),\n        "has": markFunction(function (selector) {\n          return function (elem) {\n            return Sizzle(selector, elem).length > 0;\n          };\n        }),\n        "contains": markFunction(function (text) {\n          text = text.replace(runescape, funescape);\n          return function (elem) {\n            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;\n          };\n        }),\n        // "Whether an element is represented by a :lang() selector\n        // is based solely on the element\'s language value\n        // being equal to the identifier C,\n        // or beginning with the identifier C immediately followed by "-".\n        // The matching of C against the element\'s language value is performed case-insensitively.\n        // The identifier C does not have to be a valid language name."\n        // http://www.w3.org/TR/selectors/#lang-pseudo\n        "lang": markFunction(function (lang) {\n          // lang value must be a valid identifier\n          if (!ridentifier.test(lang || "")) {\n            Sizzle.error("unsupported lang: " + lang);\n          }\n          lang = lang.replace(runescape, funescape).toLowerCase();\n          return function (elem) {\n            var elemLang;\n            do {\n              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {\n                elemLang = elemLang.toLowerCase();\n                return elemLang === lang || elemLang.indexOf(lang + "-") === 0;\n              }\n            } while ((elem = elem.parentNode) && elem.nodeType === 1);\n            return false;\n          };\n        }),\n        // Miscellaneous\n        "target": function target(elem) {\n          var hash = window.location && window.location.hash;\n          return hash && hash.slice(1) === elem.id;\n        },\n        "root": function root(elem) {\n          return elem === docElem;\n        },\n        "focus": function focus(elem) {\n          return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n        },\n        // Boolean properties\n        "enabled": createDisabledPseudo(false),\n        "disabled": createDisabledPseudo(true),\n        "checked": function checked(elem) {\n          // In CSS3, :checked should return both checked and selected elements\n          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#
1checked\n          var nodeName = elem.nodeName.toLowerCase();\n          return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;\n        },\n        "selected": function selected(elem) {\n          // Accessing this property makes selected-by-default\n          // options in Safari work properly\n          if (elem.parentNode) {\n            elem.parentNode.selectedIndex;\n          }\n          return elem.selected === true;\n        },\n        // Contents\n        "empty": function empty(elem) {\n          // http://www.w3.org/TR/selectors/#empty-pseudo\n          // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n          //   but not by others (comment: 8; processing instruction: 7; etc.)\n          // nodeType < 6 works because attributes (2) do not appear as children\n          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n            if (elem.nodeType < 6) {\n              return false;\n            }\n          }\n          return true;\n        },\n        "parent": function parent(elem) {\n          return !Expr.pseudos["empty"](elem);\n        },\n        // Element/input types\n        "header": function header(elem) {\n          return rheader.test(elem.nodeName);\n        },\n        "input": function input(elem) {\n          return rinputs.test(elem.nodeName);\n        },\n        "button": function button(elem) {\n          var name = elem.nodeName.toLowerCase();\n          return name === "input" && elem.type === "button" || name === "button";\n        },\n        "text": function text(elem) {\n          var attr;\n          return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && (\n          // Support: IE<8\n          // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"\n          (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");\n        },\n        // Position-in-collection\n        "first": createPositionalPseudo(function () {\n          return [0];\n        }),\n        "last": createPositionalPseudo(function (matchIndexes, length) {\n          return [length - 1];\n        }),\n        "eq": createPositionalPseudo(function (matchIndexes, length, argument) {\n          return [argument < 0 ? argument + length : argument];\n        }),\n        "even": createPositionalPseudo(function (matchIndexes, length) {\n          var i = 0;\n          for (; i < length; i += 2) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        "odd": createPositionalPseudo(function (matchIndexes, length) {\n          var i = 1;\n          for (; i < length; i += 2) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        "lt": createPositionalPseudo(function (matchIndexes, length, argument) {\n          var i = argument < 0 ? argument + length : argument;\n          for (; --i >= 0;) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        }),\n        "gt": createPositionalPseudo(function (matchIndexes, length, argument) {\n          var i = argument < 0 ? argument + length : argument;\n          for (; ++i < length;) {\n            matchIndexes.push(i);\n          }\n          return matchIndexes;\n        })\n      }\n    };\n    Expr.pseudos["nth"] = Expr.pseudos["eq"];\n\n    // Add button/input type pseudos\n    for (i in {\n      radio: true,\n      checkbox: true,\n      file: true,\n      password: true,\n      image: true\n    }) {\n      Expr.pseudos[i] = createInputPseudo(i);\n    }\n    for (i in {\n      submit: true,\n      reset: true\n    }) {\n      Expr.pseudos[i] = createButtonPseudo(i);\n    }\n\n    // Easy API for creating new setFilters\n    function setFilters() {}\n    setFilters.prototype = Expr.filters = Expr.pseudos;\n    Expr.setFilters = new setFilters();\n    tokenize = Sizzle.tokenize = function (selector, parseOnly) {\n      var matched,\n        match,\n        tokens,\n        type,\n        soFar,\n        groups,\n        preFilters,\n        cached = tokenCache[
1selector + " "];\n      if (cached) {\n        return parseOnly ? 0 : cached.slice(0);\n      }\n      soFar = selector;\n      groups = [];\n      preFilters = Expr.preFilter;\n      while (soFar) {\n        // Comma and first run\n        if (!matched || (match = rcomma.exec(soFar))) {\n          if (match) {\n            // Don\'t consume trailing commas as valid\n            soFar = soFar.slice(match[0].length) || soFar;\n          }\n          groups.push(tokens = []);\n        }\n        matched = false;\n\n        // Combinators\n        if (match = rcombinators.exec(soFar)) {\n          matched = match.shift();\n          tokens.push({\n            value: matched,\n            // Cast descendant combinators to space\n            type: match[0].replace(rtrim, " ")\n          });\n          soFar = soFar.slice(matched.length);\n        }\n\n        // Filters\n        for (type in Expr.filter) {\n          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {\n            matched = match.shift();\n            tokens.push({\n              value: matched,\n              type: type,\n              matches: match\n            });\n            soFar = soFar.slice(matched.length);\n          }\n        }\n        if (!matched) {\n          break;\n        }\n      }\n\n      // Return the length of the invalid excess\n      // if we\'re just parsing\n      // Otherwise, throw an error or return tokens\n      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :\n      // Cache the tokens\n      tokenCache(selector, groups).slice(0);\n    };\n    function toSelector(tokens) {\n      var i = 0,\n        len = tokens.length,\n        selector = "";\n      for (; i < len; i++) {\n        selector += tokens[i].value;\n      }\n      return selector;\n    }\n    function addCombinator(matcher, combinator, base) {\n      var dir = combinator.dir,\n        skip = combinator.next,\n        key = skip || dir,\n        checkNonElements = base && key === "parentNode",\n        doneName = done++;\n      return combinator.first ?\n      // Check against closest ancestor/preceding element\n      function (elem, context, xml) {\n        while (elem = elem[dir]) {\n          if (elem.nodeType === 1 || checkNonElements) {\n            return matcher(elem, context, xml);\n          }\n        }\n        return false;\n      } :\n      // Check against all ancestor/preceding elements\n      function (elem, context, xml) {\n        var oldCache,\n          uniqueCache,\n          outerCache,\n          newCache = [dirruns, doneName];\n\n        // We can\'t set arbitrary data on XML nodes, so they don\'t benefit from combinator caching\n        if (xml) {\n          while (elem = elem[dir]) {\n            if (elem.nodeType === 1 || checkNonElements) {\n              if (matcher(elem, context, xml)) {\n                return true;\n              }\n            }\n          }\n        } else {\n          while (elem = elem[dir]) {\n            if (elem.nodeType === 1 || checkNonElements) {\n              outerCache = elem[expando] || (elem[expando] = {});\n\n              // Support: IE <9 only\n              // Defend against cloned attroperties (jQuery gh-1709)\n              uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});\n              if (skip && skip === elem.nodeName.toLowerCase()) {\n                elem = elem[dir] || elem;\n              } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {\n                // Assign to newCache so results back-propagate to previous elements\n                return newCache[2] = oldCache[2];\n              } else {\n                // Reuse newcache so results back-propagate to previous elements\n                uniqueCache[key] = newCache;\n\n                // A match means we\'re done; a fail means we have to keep checking\n                if (newCache[2] = matcher(elem, context, xml)) {\n                  return true;\n                }\n              }\n            }\n          }\n        }\n        return false;\n      };\n    }\n    function elementMatcher(matchers) {\n      return matchers.length > 1 ? function (elem, context, xml) {\n        var i = matchers.length;\n        while (i--) {\n          if (!matchers[i](elem, context, xml)) {\n            return false;\n          }\n        }\n        return true;\n      } : matchers[0];\n    }\n    function multipleContexts(selector, contexts, results) {\n      var i = 0,\n        len = contexts.length;\n      for (; i < len;
1 i++) {\n        Sizzle(selector, contexts[i], results);\n      }\n      return results;\n    }\n    function condense(unmatched, map, filter, context, xml) {\n      var elem,\n        newUnmatched = [],\n        i = 0,\n        len = unmatched.length,\n        mapped = map != null;\n      for (; i < len; i++) {\n        if (elem = unmatched[i]) {\n          if (!filter || filter(elem, context, xml)) {\n            newUnmatched.push(elem);\n            if (mapped) {\n              map.push(i);\n            }\n          }\n        }\n      }\n      return newUnmatched;\n    }\n    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {\n      if (postFilter && !postFilter[expando]) {\n        postFilter = setMatcher(postFilter);\n      }\n      if (postFinder && !postFinder[expando]) {\n        postFinder = setMatcher(postFinder, postSelector);\n      }\n      return markFunction(function (seed, results, context, xml) {\n        var temp,\n          i,\n          elem,\n          preMap = [],\n          postMap = [],\n          preexisting = results.length,\n          // Get initial elements from seed or context\n          elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),\n          // Prefilter to get matcher input, preserving a map for seed-results synchronization\n          matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,\n          matcherOut = matcher ?\n          // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n          postFinder || (seed ? preFilter : preexisting || postFilter) ?\n          // ...intermediate processing is necessary\n          [] :\n          // ...otherwise use results directly\n          results : matcherIn;\n\n        // Find primary matches\n        if (matcher) {\n          matcher(matcherIn, matcherOut, context, xml);\n        }\n\n        // Apply postFilter\n        if (postFilter) {\n          temp = condense(matcherOut, postMap);\n          postFilter(temp, [], context, xml);\n\n          // Un-match failing elements by moving them back to matcherIn\n          i = temp.length;\n          while (i--) {\n            if (elem = temp[i]) {\n              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);\n            }\n          }\n        }\n        if (seed) {\n          if (postFinder || preFilter) {\n            if (postFinder) {\n              // Get the final matcherOut by condensing this intermediate into postFinder contexts\n              temp = [];\n              i = matcherOut.length;\n              while (i--) {\n                if (elem = matcherOut[i]) {\n                  // Restore matcherIn since elem is not yet a final match\n                  temp.push(matcherIn[i] = elem);\n                }\n              }\n              postFinder(null, matcherOut = [], temp, xml);\n            }\n\n            // Move matched elements from seed to results to keep them synchronized\n            i = matcherOut.length;\n            while (i--) {\n              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {\n                seed[temp] = !(results[temp] = elem);\n              }\n            }\n          }\n\n          // Add elements to results, through postFinder if defined\n        } else {\n          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);\n          if (postFinder) {\n            postFinder(null, results, matcherOut, xml);\n          } else {\n            push.apply(results, matcherOut);\n          }\n        }\n      });\n    }\n    function matcherFromTokens(tokens) {\n      var checkContext,\n        matcher,\n        j,\n        len = tokens.length,\n        leadingRelative = Expr.relative[tokens[0].type],\n        implicitRelative = leadingRelative || Expr.relative[" "],\n        i = leadingRelative ? 1 : 0,\n        // The foundational matcher ensures that elements are reachable from top-level context(s)\n        matchContext = addCombinator(function (elem) {\n          return elem === checkContext;\n        }, implicitRelative, true),\n        matchAnyContext = addCombinator(function (elem) {\n          return indexOf(checkContext, elem) > -1;\n        }, implicitRelative, true),\n        matchers = [function (elem, context, xml) {\n          var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));\n          // Avoid hanging onto element (issue #299)\n          checkContext = null;\n          return ret;\n        }];\n      for (; i < len;
1 i++) {\n        if (matcher = Expr.relative[tokens[i].type]) {\n          matchers = [addCombinator(elementMatcher(matchers), matcher)];\n        } else {\n          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);\n\n          // Return special upon seeing a positional matcher\n          if (matcher[expando]) {\n            // Find the next relative operator (if any) for proper handling\n            j = ++i;\n            for (; j < len; j++) {\n              if (Expr.relative[tokens[j].type]) {\n                break;\n              }\n            }\n            return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(\n            // If the preceding token was a descendant combinator, insert an implicit any-element `*`\n            tokens.slice(0, i - 1).concat({\n              value: tokens[i - 2].type === " " ? "*" : ""\n            })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));\n          }\n          matchers.push(matcher);\n        }\n      }\n      return elementMatcher(matchers);\n    }\n    function matcherFromGroupMatchers(elementMatchers, setMatchers) {\n      var bySet = setMatchers.length > 0,\n        byElement = elementMatchers.length > 0,\n        superMatcher = function superMatcher(seed, context, xml, results, outermost) {\n          var elem,\n            j,\n            matcher,\n            matchedCount = 0,\n            i = "0",\n            unmatched = seed && [],\n            setMatched = [],\n            contextBackup = outermostContext,\n            // We must always have either seed elements or outermost context\n            elems = seed || byElement && Expr.find["TAG"]("*", outermost),\n            // Use integer dirruns iff this is the outermost matcher\n            dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,\n            len = elems.length;\n          if (outermost) {\n            outermostContext = context === document || context || outermost;\n          }\n\n          // Add elements passing elementMatchers directly to results\n          // Support: IE<9, Safari\n          // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id\n          for (; i !== len && (elem = elems[i]) != null; i++) {\n            if (byElement && elem) {\n              j = 0;\n              if (!context && elem.ownerDocument !== document) {\n                setDocument(elem);\n                xml = !documentIsHTML;\n              }\n              while (matcher = elementMatchers[j++]) {\n                if (matcher(elem, context || document, xml)) {\n                  results.push(elem);\n                  break;\n                }\n              }\n              if (outermost) {\n                dirruns = dirrunsUnique;\n              }\n            }\n\n            // Track unmatched elements for set filters\n            if (bySet) {\n              // They will have gone through all possible matchers\n              if (elem = !matcher && elem) {\n                matchedCount--;\n              }\n\n              // Lengthen the array for every element, matched or not\n              if (seed) {\n                unmatched.push(elem);\n              }\n            }\n          }\n\n          // `i` is now the count of elements visited above, and adding it to `matchedCount`\n          // makes the latter nonnegative.\n          matchedCount += i;\n\n          // Apply set filters to unmatched elements\n          // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n          // equals `i`), unless we didn\'t visit _any_ elements in the above loop because we have\n          // no element matchers and no seed.\n          // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that\n          // case, which will result in a "00" `matchedCount` that differs from `i` but is also\n          // numerically zero.\n          if (bySet && i !== matchedCount) {\n            j = 0;\n            while (matcher = setMatchers[j++]) {\n              matcher(unmatched, setMatched, context, xml);\n            }
1\n            if (seed) {\n              // Reintegrate element matches to eliminate the need for sorting\n              if (matchedCount > 0) {\n                while (i--) {\n                  if (!(unmatched[i] || setMatched[i])) {\n                    setMatched[i] = pop.call(results);\n                  }\n                }\n              }\n\n              // Discard index placeholder values to get only actual matches\n              setMatched = condense(setMatched);\n            }\n\n            // Add matches to results\n            push.apply(results, setMatched);\n\n            // Seedless set matches succeeding multiple successful matchers stipulate sorting\n            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {\n              Sizzle.uniqueSort(results);\n            }\n          }\n\n          // Override manipulation of globals by nested matchers\n          if (outermost) {\n            dirruns = dirrunsUnique;\n            outermostContext = contextBackup;\n          }\n          return unmatched;\n        };\n      return bySet ? markFunction(superMatcher) : superMatcher;\n    }\n    compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {\n      var i,\n        setMatchers = [],\n        elementMatchers = [],\n        cached = compilerCache[selector + " "];\n      if (!cached) {\n        // Generate a function of recursive functions that can be used to check each element\n        if (!match) {\n          match = tokenize(selector);\n        }\n        i = match.length;\n        while (i--) {\n          cached = matcherFromTokens(match[i]);\n          if (cached[expando]) {\n            setMatchers.push(cached);\n          } else {\n            elementMatchers.push(cached);\n          }\n        }\n\n        // Cache the compiled function\n        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));\n\n        // Save selector and tokenization\n        cached.selector = selector;\n      }\n      return cached;\n    };\n\n    /**\r\n     * A low-level selection function that works with Sizzle\'s compiled\r\n     *  selector functions\r\n     * @param {String|Function} selector A selector or a pre-compiled\r\n     *  selector function built with Sizzle.compile\r\n     * @param {Element} context\r\n     * @param {Array} [results]\r\n     * @param {Array} [seed] A set of elements to match against\r\n     */\n    select = Sizzle.select = function (selector, context, results, seed) {\n      var i,\n        tokens,\n        token,\n        type,\n        find,\n        compiled = typeof selector === "function" && selector,\n        match = !seed && tokenize(selector = compiled.selector || selector);\n      results = results || [];\n\n      // Try to minimize operations if there is only one selector in the list and no seed\n      // (the latter of which guarantees us context)\n      if (match.length === 1) {\n        // Reduce context if the leading compound selector is an ID\n        tokens = match[0] = match[0].slice(0);\n        if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {\n          context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];\n          if (!context) {\n            return results;\n\n            // Precompiled matchers will still verify ancestry, so step up a level\n          } else if (compiled) {\n            context = context.parentNode;\n          }\n          selector = selector.slice(tokens.shift().value.length);\n        }\n\n        // Fetch a seed set for right-to-left matching\n        i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;\n        while (i--) {\n          token = tokens[i];\n\n          // Abort if we hit a combinator\n          if (Expr.relative[type = token.type]) {\n            break;\n          }\n          if (find = Expr.find[type]) {\n            // Search, expanding context for leading sibling combinators\n            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
1ontext(context.parentNode) || context)) {\n              // If seed is empty or no tokens remain, we can return early\n              tokens.splice(i, 1);\n              selector = seed.length && toSelector(tokens);\n              if (!selector) {\n                push.apply(results, seed);\n                return results;\n              }\n              break;\n            }\n          }\n        }\n      }\n\n      // Compile and execute a filtering function if one is not provided\n      // Provide `match` to avoid retokenization if we modified the selector above\n      (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);\n      return results;\n    };\n\n    // One-time assignments\n\n    // Sort stability\n    support.sortStable = expando.split("").sort(sortOrder).join("") === expando;\n\n    // Support: Chrome 14-35+\n    // Always assume duplicates if they aren\'t passed to the comparison function\n    support.detectDuplicates = !!hasDuplicate;\n\n    // Initialize against the default document\n    setDocument();\n\n    // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n    // Detached nodes confoundingly follow *each other*\n    support.sortDetached = assert(function (el) {\n      // Should return 1, but returns 4 (following)\n      return el.compareDocumentPosition(document.createElement("fieldset")) & 1;\n    });\n\n    // Support: IE<8\n    // Prevent attribute/property "interpolation"\n    // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\n    if (!assert(function (el) {\n      el.innerHTML = "<a href=\'#\'></a>";\n      return el.firstChild.getAttribute("href") === "#";\n    })) {\n      addHandle("type|href|height|width", function (elem, name, isXML) {\n        if (!isXML) {\n          return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);\n        }\n      });\n    }\n\n    // Support: IE<9\n    // Use defaultValue in place of getAttribute("value")\n    if (!support.attributes || !assert(function (el) {\n      el.innerHTML = "<input/>";\n      el.firstChild.setAttribute("value", "");\n      return el.firstChild.getAttribute("value") === "";\n    })) {\n      addHandle("value", function (elem, name, isXML) {\n        if (!isXML && elem.nodeName.toLowerCase() === "input") {\n          return elem.defaultValue;\n        }\n      });\n    }\n\n    // Support: IE<9\n    // Use getAttributeNode to fetch booleans when getAttribute lies\n    if (!assert(function (el) {\n      return el.getAttribute("disabled") == null;\n    })) {\n      addHandle(booleans, function (elem, name, isXML) {\n        var val;\n        if (!isXML) {\n          return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;\n        }\n      });\n    }\n    return Sizzle;\n  }(window);\n  _jQuery2.find = Sizzle;\n  _jQuery2.expr = Sizzle.selectors;\n\n  // Deprecated\n  _jQuery2.expr[":"] = _jQuery2.expr.pseudos;\n  _jQuery2.uniqueSort = _jQuery2.unique = Sizzle.uniqueSort;\n  _jQuery2.text = Sizzle.getText;\n  _jQuery2.isXMLDoc = Sizzle.isXML;\n  _jQuery2.contains = Sizzle.contains;\n  _jQuery2.escapeSelector = Sizzle.escape;\n  var dir = function dir(elem, _dir, until) {\n    var matched = [],\n      truncate = until !== undefined;\n    while ((elem = elem[_dir]) && elem.nodeType !== 9) {\n      if (elem.nodeType === 1) {\n        if (truncate && _jQuery2(elem).is(until)) {\n          break;\n        }\n        matched.push(elem);\n      }\n    }\n    return matched;\n  };\n  var _siblings = function siblings(n, elem) {\n    var matched = [];\n    for (; n; n = n.nextSibling) {\n      if (n.nodeType === 1 && n !== elem) {\n        matched.push(n);\n      }\n    }\n    return matched;\n  };\n  var rneedsContext = _jQuery2.expr.match.needsContext;\n  function nodeName(elem, name) {\n    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n  }\n  ;\n  var rsingleTag = /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;\n  var risSimple = /^.[^:#\\[\\.,]*$/;\n\n  // Implement the identical functionality for filter and not\n  function winnow(elements, qualifier, not) {\n    if (_jQuery2.isFunction(qualifier)) {\n      return _jQuery2.grep(elements, function (elem, i) {\n        return !!qualifier.call(elem, i, elem) !== not;
1\n      });\n    }\n\n    // Single element\n    if (qualifier.nodeType) {\n      return _jQuery2.grep(elements, function (elem) {\n        return elem === qualifier !== not;\n      });\n    }\n\n    // Arraylike of elements (jQuery, arguments, Array)\n    if (typeof qualifier !== "string") {\n      return _jQuery2.grep(elements, function (elem) {\n        return indexOf.call(qualifier, elem) > -1 !== not;\n      });\n    }\n\n    // Simple selector that can be filtered directly, removing non-Elements\n    if (risSimple.test(qualifier)) {\n      return _jQuery2.filter(qualifier, elements, not);\n    }\n\n    // Complex selector, compare the two sets, removing non-Elements\n    qualifier = _jQuery2.filter(qualifier, elements);\n    return _jQuery2.grep(elements, function (elem) {\n      return indexOf.call(qualifier, elem) > -1 !== not && elem.nodeType === 1;\n    });\n  }\n  _jQuery2.filter = function (expr, elems, not) {\n    var elem = elems[0];\n    if (not) {\n      expr = ":not(" + expr + ")";\n    }\n    if (elems.length === 1 && elem.nodeType === 1) {\n      return _jQuery2.find.matchesSelector(elem, expr) ? [elem] : [];\n    }\n    return _jQuery2.find.matches(expr, _jQuery2.grep(elems, function (elem) {\n      return elem.nodeType === 1;\n    }));\n  };\n  _jQuery2.fn.extend({\n    find: function find(selector) {\n      var i,\n        ret,\n        len = this.length,\n        self = this;\n      if (typeof selector !== "string") {\n        return this.pushStack(_jQuery2(selector).filter(function () {\n          for (i = 0; i < len; i++) {\n            if (_jQuery2.contains(self[i], this)) {\n              return true;\n            }\n          }\n        }));\n      }\n      ret = this.pushStack([]);\n      for (i = 0; i < len; i++) {\n        _jQuery2.find(selector, self[i], ret);\n      }\n      return len > 1 ? _jQuery2.uniqueSort(ret) : ret;\n    },\n    filter: function filter(selector) {\n      return this.pushStack(winnow(this, selector || [], false));\n    },\n    not: function not(selector) {\n      return this.pushStack(winnow(this, selector || [], true));\n    },\n    is: function is(selector) {\n      return !!winnow(this,\n      // If this is a positional/relative selector, check membership in the returned set\n      // so $("p:first").is("p:last") won\'t return true for a doc with two "p".\n      typeof selector === "string" && rneedsContext.test(selector) ? _jQuery2(selector) : selector || [], false).length;\n    }\n  });\n\n  // Initialize a jQuery object\n\n  // A central reference to the root jQuery(document)\n  var rootjQuery,\n    // A simple way to check for HTML strings\n    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n    // Strict HTML recognition (#11290: must start with <)\n    // Shortcut simple #id case for speed\n    rquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n    init = _jQuery2.fn.init = function (selector, context, root) {\n      var match, elem;\n\n      // HANDLE: $(""), $(null), $(undefined), $(false)\n      if (!selector) {\n        return this;\n      }\n\n      // Method init() accepts an alternate rootjQuery\n      // so migrate can support jQuery.sub (gh-2101)\n      root = root || rootjQuery;\n\n      // Handle HTML strings\n      if (typeof selector === "string") {\n        if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {\n          // Assume that strings that start and end with <> are HTML and skip the regex check\n          match = [null, selector, null];\n        } else {\n          match = rquickExpr.exec(selector);\n        }\n\n        // Match html or make sure no context is specified for #id\n        if (match && (match[1] || !context)) {\n          // HANDLE: $(html) -> $(array)\n          if (match[1]) {\n            context = context instanceof _jQuery2 ? context[0] : context;\n\n            // Option to run scripts is true for back-compat\n            // Intentionally let the error be thrown if parseHTML is not present\n            _jQuery2.merge(this, _jQuery2.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));\n\n            // HANDLE: $(html, props)\n            if (rsingleTag.test(match[1]) && _jQuery2.isPlainObject(context)) {\n              for (match in context) {\n                // Properties of context are called as methods if possible\n                if (_jQuery2.isFunction(this[match])) {\n                  this[match](context[match]);\n\n                  // ...and otherwise set as attributes\n                } else {\n                  this.attr(match, context[match]);\n                }\n              }\n            }\n            return this;\n\n            // HANDLE: $(#id)\n          } else {\n            elem = document.getElementById(match[2]);\n            if (elem) {\n              // Inject the element directly into the jQuery object\n              this[0] = elem;\n              this.length = 1;\n            }\n            return this;\n          }\n\n          // HANDLE: $(expr, $(...))\n        } else if (!context || context.jquery) {\n          return (context || root).find(selector);\n\n          // HANDLE: $(expr, context)\n          // (which is just equivalent to: $(context).find(expr)\n        } else {\n          return this.constructor(context).find(selector);\n        }\n\n        // HANDLE: $(DOMElement)\n      } else if (selector.nodeType) {\n        this[0] = selector;\n        this.length = 1;\n        return this;\n\n        // HANDLE: $(function)\n        // Shortcut for document ready\n      }
1 else if (_jQuery2.isFunction(selector)) {\n        return root.ready !== undefined ? root.ready(selector) :\n        // Execute immediately if ready is not present\n        selector(_jQuery2);\n      }\n      return _jQuery2.makeArray(selector, this);\n    };\n\n  // Give the init function the jQuery prototype for later instantiation\n  init.prototype = _jQuery2.fn;\n\n  // Initialize central reference\n  rootjQuery = _jQuery2(document);\n  var rparentsprev = /^(?:parents|prev(?:Until|All))/,\n    // Methods guaranteed to produce a unique set when starting from a unique set\n    guaranteedUnique = {\n      children: true,\n      contents: true,\n      next: true,\n      prev: true\n    };\n  _jQuery2.fn.extend({\n    has: function has(target) {\n      var targets = _jQuery2(target, this),\n        l = targets.length;\n      return this.filter(function () {\n        var i = 0;\n        for (; i < l; i++) {\n          if (_jQuery2.contains(this, targets[i])) {\n            return true;\n          }\n        }\n      });\n    },\n    closest: function closest(selectors, context) {\n      var cur,\n        i = 0,\n        l = this.length,\n        matched = [],\n        targets = typeof selectors !== "string" && _jQuery2(selectors);\n\n      // Positional selectors never match, since there\'s no _selection_ context\n      if (!rneedsContext.test(selectors)) {\n        for (; i < l; i++) {\n          for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {\n            // Always skip document fragments\n            if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 :\n            // Don\'t pass non-elements to Sizzle\n            cur.nodeType === 1 && _jQuery2.find.matchesSelector(cur, selectors))) {\n              matched.push(cur);\n              break;\n            }\n          }\n        }\n      }\n      return this.pushStack(matched.length > 1 ? _jQuery2.uniqueSort(matched) : matched);\n    },\n    // Determine the position of an element within the set\n    index: function index(elem) {\n      // No argument, return index in parent\n      if (!elem) {\n        return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;\n      }\n\n      // Index in selector\n      if (typeof elem === "string") {\n        return indexOf.call(_jQuery2(elem), this[0]);\n      }\n\n      // Locate the position of the desired element\n      return indexOf.call(this,\n      // If it receives a jQuery object, the first element is used\n      elem.jquery ? elem[0] : elem);\n    },\n    add: function add(selector, context) {\n      return this.pushStack(_jQuery2.uniqueSort(_jQuery2.merge(this.get(), _jQuery2(selector, context))));\n    },\n    addBack: function addBack(selector) {\n      return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));\n    }\n  });\n  function sibling(cur, dir) {\n    while ((cur = cur[dir]) && cur.nodeType !== 1) {}\n    return cur;\n  }\n  _jQuery2.each({\n    parent: function parent(elem) {\n      var parent = elem.parentNode;\n      return parent && parent.nodeType !== 11 ? parent : null;\n    },\n    parents: function parents(elem) {\n      return dir(elem, "parentNode");\n    },\n    parentsUntil: function parentsUntil(elem, i, until) {\n      return dir(elem, "parentNode", until);\n    },\n    next: function next(elem) {\n      return sibling(elem, "nextSibling");\n    },\n    prev: function prev(elem) {\n      return sibling(elem, "previousSibling");\n    },\n    nextAll: function nextAll(elem) {\n      return dir(elem, "nextSibling");\n    },\n    prevAll: function prevAll(elem) {\n      return dir(elem, "previousSibling");\n    },\n    nextUntil: function nextUntil(elem, i, until) {\n      return dir(elem, "nextSibling", until);\n    },\n    prevUntil: function prevUntil(elem, i, until) {\n      return dir(elem, "previousSibling", until);\n    },\n    siblings: function siblings(elem) {\n      return _siblings((elem.parentNode || {}).firstChild, elem);\n    },\n    children: function children(elem) {\n      return _siblings(elem.firstChild);\n    },\n    contents: function contents(elem) {\n      if (nodeName(elem, "iframe")) {\n        return elem.contentDocument;\n      }
1\n\n      // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n      // Treat the template element as a regular one in browsers that\n      // don\'t support it.\n      if (nodeName(elem, "template")) {\n        elem = elem.content || elem;\n      }\n      return _jQuery2.merge([], elem.childNodes);\n    }\n  }, function (name, fn) {\n    _jQuery2.fn[name] = function (until, selector) {\n      var matched = _jQuery2.map(this, fn, until);\n      if (name.slice(-5) !== "Until") {\n        selector = until;\n      }\n      if (selector && typeof selector === "string") {\n        matched = _jQuery2.filter(selector, matched);\n      }\n      if (this.length > 1) {\n        // Remove duplicates\n        if (!guaranteedUnique[name]) {\n          _jQuery2.uniqueSort(matched);\n        }\n\n        // Reverse order for parents* and prev-derivatives\n        if (rparentsprev.test(name)) {\n          matched.reverse();\n        }\n      }\n      return this.pushStack(matched);\n    };\n  });\n  var rnothtmlwhite = /[^\\x20\\t\\r\\n\\f]+/g;\n\n  // Convert String-formatted options into Object-formatted ones\n  function createOptions(options) {\n    var object = {};\n    _jQuery2.each(options.match(rnothtmlwhite) || [], function (_, flag) {\n      object[flag] = true;\n    });\n    return object;\n  }\n\n  /*\r\n   * Create a callback list using the following parameters:\r\n   *\r\n   *\toptions: an optional list of space-separated options that will change how\r\n   *\t\t\tthe callback list behaves or a more traditional option object\r\n   *\r\n   * By default a callback list will act like an event callback list and can be\r\n   * "fired" multiple times.\r\n   *\r\n   * Possible options:\r\n   *\r\n   *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\r\n   *\r\n   *\tmemory:\t\t\twill keep track of previous values and will call any callback added\r\n   *\t\t\t\t\tafter the list has been fired right away with the latest "memorized"\r\n   *\t\t\t\t\tvalues (like a Deferred)\r\n   *\r\n   *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\r\n   *\r\n   *\tstopOnFalse:\tinterrupt callings when a callback returns false\r\n   *\r\n   */\n  _jQuery2.Callbacks = function (options) {\n    // Convert options from String-formatted to Object-formatted if needed\n    // (we check in cache first)\n    options = typeof options === "string" ? createOptions(options) : _jQuery2.extend({}, options);\n    var\n      // Flag to know if list is currently firing\n      firing,\n      // Last fire value for non-forgettable lists\n      memory,\n      // Flag to know if list was already fired\n      _fired,\n      // Flag to prevent firing\n      _locked,\n      // Actual callback list\n      list = [],\n      // Queue of execution data for repeatable lists\n      queue = [],\n      // Index of currently firing callback (modified by add/remove as needed)\n      firingIndex = -1,\n      // Fire callbacks\n      fire = function fire() {\n        // Enforce single-firing\n        _locked = _locked || options.once;\n\n        // Execute callbacks for all pending executions,\n        // respecting firingIndex overrides and runtime changes\n        _fired = firing = true;\n        for (; queue.length; firingIndex = -1) {\n          memory = queue.shift();\n          while (++firingIndex < list.length) {\n            // Run callback and check for early termination\n            if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {\n              // Jump to end and forget the data so .add doesn\'t re-fire\n              firingIndex = list.length;\n              memory = false;\n            }\n          }\n        }\n\n        // Forget the data if we\'re done with it\n        if (!options.memory) {\n          memory = false;\n        }\n        firing = false;\n\n        // Clean up if we\'re done firing for good\n        if (_locked) {\n          // Keep an empty list if we have data for future add calls\n          if (memory) {\n            list = [];\n\n            // Otherwise, this object is spent\n          } else {\n            list = "";\n          }\n        }\n      },\n      // Actual Callbacks object\n      self = {\n        // Add a callback or a collection of callbacks to the list\n        add: function add() {\n          if (list) {\n            // If we have memory from a past run, we should fire after adding\n            if (memory && !firing) {\n              firingIndex = list.length - 1;\n              queue.push(memory);\n            }\n            (function add(args) {\n              _jQuery2.each(args, function (_, arg) {\n                if (_jQuery2.isFunction(arg)) {\n                  if (!options.unique || !self.has(arg)) {\n                    list.push(arg);\n                  }\n                } else if (arg && arg.length && _jQuery2.type(arg) !== "string") {\n                  // Inspect recursively\n                  add(arg);\n                }\n              });\n            })(arguments);\n            if (memory && !firing) {\n              fire();\n            }\n          }\n          return this;\n        },\n        // Remove a callback from the list\n        remove: function remove() {\n          _jQuery2.each(arguments, function (_, arg) {\n            var index;\n            while ((index = _jQuery2.inArray(arg, list, index)) > -1) {\n              list.splice(index, 1);\n\n              // Handle firing indexes\n              if (index <= firingIndex) {\n                firingIndex--;\n              }\n            }\n          });\n          return this;\n        },\n        // Check if a given callback is in the list.\n        // If no argument is given, return whether or not list has callbacks attached.\n        has: function has(fn) {\n          return fn ? _jQuery2.inArray(fn, list) > -1 : list.length > 0;\n        },\n        // Remove all callbacks from the list\n        empty: function empty() {\n          if (list) {\n            list = [];\n          }\n          return this;\n        },\n        // Disable .fire and .add\n        // Abort any current/pending executions\n        // Clear all callbacks and values\n        disable: function disable() {\n          _locked = queue = [];\n          list = memory = "";\n          return this;\n        },\n        disabled: function disabled() {\n          return !list;\n        },\n        // Disable .fire\n        // Also disable .add unless we have memory (since it would have no effect)\n        // Abort any pen
1ding executions\n        lock: function lock() {\n          _locked = queue = [];\n          if (!memory && !firing) {\n            list = memory = "";\n          }\n          return this;\n        },\n        locked: function locked() {\n          return !!_locked;\n        },\n        // Call all callbacks with the given context and arguments\n        fireWith: function fireWith(context, args) {\n          if (!_locked) {\n            args = args || [];\n            args = [context, args.slice ? args.slice() : args];\n            queue.push(args);\n            if (!firing) {\n              fire();\n            }\n          }\n          return this;\n        },\n        // Call all the callbacks with the given arguments\n        fire: function fire() {\n          self.fireWith(this, arguments);\n          return this;\n        },\n        // To know if the callbacks have already been called at least once\n        fired: function fired() {\n          return !!_fired;\n        }\n      };\n    return self;\n  };\n  function Identity(v) {\n    return v;\n  }\n  function Thrower(ex) {\n    throw ex;\n  }\n  function adoptValue(value, resolve, reject, noValue) {\n    var method;\n    try {\n      // Check for promise aspect first to privilege synchronous behavior\n      if (value && _jQuery2.isFunction(method = value.promise)) {\n        method.call(value).done(resolve).fail(reject);\n\n        // Other thenables\n      } else if (value && _jQuery2.isFunction(method = value.then)) {\n        method.call(value, resolve, reject);\n\n        // Other non-thenables\n      } else {\n        // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n        // * false: [ value ].slice( 0 ) => resolve( value )\n        // * true: [ value ].slice( 1 ) => resolve()\n        resolve.apply(undefined, [value].slice(noValue));\n      }\n\n      // For Promises/A+, convert exceptions into rejections\n      // Since jQuery.when doesn\'t unwrap thenables, we can skip the extra checks appearing in\n      // Deferred#then to conditionally suppress rejection.\n    } catch (value) {\n      // Support: Android 4.0 only\n      // Strict mode functions invoked without .call/.apply get global-object context\n      reject.apply(undefined, [value]);\n    }\n  }\n  _jQuery2.extend({\n    Deferred: function Deferred(func) {\n      var tuples = [\n        // action, add listener, callbacks,\n        // ... .then handlers, argument index, [final state]\n        ["notify", "progress", _jQuery2.Callbacks("memory"), _jQuery2.Callbacks("memory"), 2], ["resolve", "done", _jQuery2.Callbacks("once memory"), _jQuery2.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", _jQuery2.Callbacks("once memory"), _jQuery2.Callbacks("once memory"), 1, "rejected"]],\n        _state = "pending",\n        _promise = {\n          state: function state() {\n            return _state;\n          },\n          always: function always() {\n            deferred.done(arguments).fail(arguments);\n            return this;\n          },\n          "catch": function _catch(fn) {\n            return _promise.then(null, fn);\n          },\n          // Keep pipe for back-compat\n          pipe: function pipe(/* fnDone, fnFail, fnProgress */\n          ) {\n            var fns = arguments;\n            return _jQuery2.Deferred(function (newDefer) {\n              _jQuery2.each(tuples, function (i, tuple) {\n                // Map tuples (progress, done, fail) to arguments (done, fail, progress)\n                var fn = _jQuery2.isFunction(fns[tuple[4]]) && fns[tuple[4]];\n\n                // deferred.progress(function() { bind to newDefer or newDefer.notify })\n                // deferred.done(function() { bind to newDefer or newDefer.resolve })\n                // deferred.fail(function() { bind to newDefer or newDefer.reject })\n                deferred[tuple[1]](function () {\n                  var returned = fn && fn.apply(this, arguments);\n                  if (returned && _jQuery2.isFunction(returned.promise)) {\n                    returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);\n                  } else {\n                    newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments);\n                  }\n                });\n              });\n              fns = null;\n            }).promise();\n          },\n          then: function then(onFulfilled, onRejected, onProgress) {\n            var maxDepth = 0;\n            function resolve(depth, deferred, handler, special) {\n              return function () {\n                var that = this,\n                  args = arguments,\n                  mightThrow = function mightThrow() {\n                    var returned, then;
1\n\n                    // Support: Promises/A+ section 2.3.3.3.3\n                    // https://promisesaplus.com/#point-59\n                    // Ignore double-resolution attempts\n                    if (depth < maxDepth) {\n                      return;\n                    }\n                    returned = handler.apply(that, args);\n\n                    // Support: Promises/A+ section 2.3.1\n                    // https://promisesaplus.com/#point-48\n                    if (returned === deferred.promise()) {\n                      throw new TypeError("Thenable self-resolution");\n                    }\n\n                    // Support: Promises/A+ sections 2.3.3.1, 3.5\n                    // https://promisesaplus.com/#point-54\n                    // https://promisesaplus.com/#point-75\n                    // Retrieve `then` only once\n                    then = returned && (\n                    // Support: Promises/A+ section 2.3.4\n                    // https://promisesaplus.com/#point-64\n                    // Only check objects and functions for thenability\n                    _typeof(returned) === "object" || typeof returned === "function") && returned.then;\n\n                    // Handle a returned thenable\n                    if (_jQuery2.isFunction(then)) {\n                      // Special processors (notify) just wait for resolution\n                      if (special) {\n                        then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special));\n\n                        // Normal processors (resolve) also hook into progress\n                      } else {\n                        // ...and disregard older resolution values\n                        maxDepth++;\n                        then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith));\n                      }\n\n                      // Handle all other returned values\n                    } else {\n                      // Only substitute handlers pass on context\n                      // and multiple values (non-spec behavior)\n                      if (handler !== Identity) {\n                        that = undefined;\n                        args = [returned];\n                      }\n\n                      // Process the value(s)\n                      // Default process is resolve\n                      (special || deferred.resolveWith)(that, args);\n                    }\n                  },\n                  // Only normal processors (resolve) catch and reject exceptions\n                  process = special ? mightThrow : function () {\n                    try {\n                      mightThrow();\n                    } catch (e) {\n                      if (_jQuery2.Deferred.exceptionHook) {\n                        _jQuery2.Deferred.exceptionHook(e, process.stackTrace);\n                      }\n\n                      // Support: Promises/A+ section 2.3.3.3.4.1\n                      // https://promisesaplus.com/#point-61\n                      // Ignore post-resolution exceptions\n                      if (depth + 1 >= maxDepth) {\n                        // Only substitute handlers pass on context\n                        // and multiple values (non-spec behavior)\n                        if (handler !== Thrower) {\n                          that = undefined;\n                          args = [e];\n                        }\n                        deferred.rejectWith(that, args);\n                      }\n                    }\n                  };\n\n                // Support: Promises/A+ section 2.3.3.3.1\n                // https://promisesaplus.com/#point-57\n                // Re-resolve promises immediately to dodge false rejection from\n                // subsequent errors\n                if (depth) {\n                  process();\n                } else {\n                  // Call an optional hook to record the stack, in case of exception\n                  // since it\'s otherwise lost when execution goes async\n                  if (_jQuery2.Deferred.getStackHook) {\n                    process.stackTrace = _jQuery2.Deferred.getStackHook();\n                  }\n                  window.setTimeout(process);\n                }\n              };\n            }\n            return _jQuery2.Deferred(function (newDefer) {\n              // progress_handlers.add( ... )\n              tuples[0][3].add(resolve(0, newDefer, _jQuery2.isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith));\n\n              // fulfilled_handlers.add( ... )\n              tuples[1][3].add(resolve(0, newDefer, _jQuery2.isFunction(onFulfilled) ? onFulfilled : Identity));\n\n              // rejected_handlers.add( ... )\n              tuples[2][3].add(resolve(0, newDefer, _jQuery2.isFunction(onRejected) ? onRejected : Thrower));\n            }).promise();\n          },\n          // Get a promise for this deferred\n          // If obj is provided, the promise aspect is added to the object\n          promise: function promise(obj) {\n            return obj != null ? _jQuery2.extend(obj, _promise) : _promise;\n          }\n        },\n        deferred = {};\n\n      // Add list-specific methods\n      _jQuery2.each(tuples, function (i, tuple) {\n        var list = tuple[2],\n          stateString = tuple[5];\n\n        // promise.progress = list.add\n        // promise.done = list.add\n        // promise.fail = list.add\n        _promise[tuple[1]] = list.add;\n\n        // Handle state\n        if (stateString) {\n          list.add(function () {\n            // state = "resolved" (i.e., fulfilled)\n            // state = "rejected"\n            _state = stateString;\n          },\n          // rejected_callbacks.disable\n          // fulfilled_callbacks.disable\n          tuples[3 - i][2].disable,\n          // progress_callbacks.lock\n          tuples[0][2].lock);\n        }\n\n        // progress_handlers.fire\n        // fulfilled_handlers.fire\n        // rejected_handlers.fire\n        list.add(tuple[3].fire);\n\n        // deferred.notify = function() { deferred.notifyWith(...) }\n        // deferred.resolve = function() { deferred.resolveWith(...) }\n        // deferred.reject = function() { deferred.rejectWith(...) }\n        deferred[tuple[0]] = function () {\n          deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);\n          return this;\n        };\n\n        // deferred.notifyWith = list.fireWith\n        // deferred.resolveWith = list.fireWith\n        // deferred.rejectWith = list.fireWith\n        deferred[tuple[0] + "With"] = list.fireWith;\n      });\n\n      // Make the deferred a promise\n      _promise.promise(deferred);\n\n      // Call given func if any\n      if (func) {\n        func.call(deferred, deferred);\n      }\n\n      // All done!\n      return deferred;\n    },\n    // Deferred helper\n    when: function when(singleValue) {\n      var\n        // count of uncompleted subordinates\n        remaining = arguments.length,\n        // count of unprocessed arguments\n        i = remaining,\n        // subordinate fulfillment data\n        resolveContexts = Array(i),\n        resolveValues = _slice.call(arguments),\n        // the master Deferred\n        master = _jQuery2.Deferred(),\n        // subordinate callback factory\n        updateFunc = function updateFunc(i) {\n          return function (value) {\n            resolveContexts[i] = this;\n            resolveValues[i] = arguments.length > 1 ? _slice.call(arguments) : value;\n            if (! --remaining) {\n              master.resolveWith(resolveContexts, resolveValues);\n            }\n          };\n        };\n\n      // Single- and empty arguments are adopted like Promise.resolve\n      if (remaining <= 1) {\n        adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining);\n\n        // Use .then() to unwrap secondary thenables (cf. gh-3000)\n        if (master.state() === "pending" || _jQuery2.isFunction(resolveValues[i] && resolveValues[i].then)) {\n          return master.then();\n        }\n      }\n\n      // Multiple arguments are aggregated like Promise.all array elements\n      while (i--) {\n        adoptValue(resolveValues[i], updateFunc(i), master.reject);\n      }\n      return master.promise();\n    }\n  });\n\n  // These usually indicate a programmer mistake during development,\n  // warn about them ASAP rather than swallowing them by default.\n  var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n  _jQuery2.Deferred.exceptionHook = function (error, stack) {\n    // Supp
1ort: IE 8 - 9 only\n    // Console exists when dev tools are open, which can happen at any time\n    if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {\n      window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack);\n    }\n  };\n  _jQuery2.readyException = function (error) {\n    window.setTimeout(function () {\n      throw error;\n    });\n  };\n\n  // The deferred used on DOM ready\n  var readyList = _jQuery2.Deferred();\n  _jQuery2.fn.ready = function (fn) {\n    readyList.then(fn)\n\n    // Wrap jQuery.readyException in a function so that the lookup\n    // happens at the time of error handling instead of callback\n    // registration.\n    ["catch"](function (error) {\n      _jQuery2.readyException(error);\n    });\n    return this;\n  };\n  _jQuery2.extend({\n    // Is the DOM ready to be used? Set to true once it occurs.\n    isReady: false,\n    // A counter to track how many items to wait for before\n    // the ready event fires. See #6781\n    readyWait: 1,\n    // Handle when the DOM is ready\n    ready: function ready(wait) {\n      // Abort if there are pending holds or we\'re already ready\n      if (wait === true ? --_jQuery2.readyWait : _jQuery2.isReady) {\n        return;\n      }\n\n      // Remember that the DOM is ready\n      _jQuery2.isReady = true;\n\n      // If a normal DOM Ready event fired, decrement, and wait if need be\n      if (wait !== true && --_jQuery2.readyWait > 0) {\n        return;\n      }\n\n      // If there are functions bound, to execute\n      readyList.resolveWith(document, [_jQuery2]);\n    }\n  });\n  _jQuery2.ready.then = readyList.then;\n\n  // The ready event handler and self cleanup method\n  function completed() {\n    document.removeEventListener("DOMContentLoaded", completed);\n    window.removeEventListener("load", completed);\n    _jQuery2.ready();\n  }\n\n  // Catch cases where $(document).ready() is called\n  // after the browser event has already occurred.\n  // Support: IE <=9 - 10 only\n  // Older IE sometimes signals "interactive" too soon\n  if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {\n    // Handle it asynchronously to allow scripts the opportunity to delay ready\n    window.setTimeout(_jQuery2.ready);\n  } else {\n    // Use the handy event callback\n    document.addEventListener("DOMContentLoaded", completed);\n\n    // A fallback to window.onload, that will always work\n    window.addEventListener("load", completed);\n  }\n\n  // Multifunctional method to get and set values of a collection\n  // The value/s can optionally be executed if it\'s a function\n  var _access = function access(elems, fn, key, value, chainable, emptyGet, raw) {\n    var i = 0,\n      len = elems.length,\n      bulk = key == null;\n\n    // Sets many values\n    if (_jQuery2.type(key) === "object") {\n      chainable = true;\n      for (i in key) {\n        _access(elems, fn, i, key[i], true, emptyGet, raw);\n      }\n\n      // Sets one value\n    } else if (value !== undefined) {\n      chainable = true;\n      if (!_jQuery2.isFunction(value)) {\n        raw = true;\n      }\n      if (bulk) {\n        // Bulk operations run against the entire set\n        if (raw) {\n          fn.call(elems, value);\n          fn = null;\n\n          // ...except when executing function values\n        } else {\n          bulk = fn;\n          fn = function fn(elem, key, value) {\n            return bulk.call(_jQuery2(elem), value);\n          };\n        }\n      }\n      if (fn) {\n        for (; i < len; i++) {\n          fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));\n        }\n      }\n    }\n    if (chainable) {\n      return elems;\n    }\n\n    // Gets\n    if (bulk) {\n      return fn.call(elems);\n    }\n    return len ? fn(elems[0], key) : emptyGet;\n  };\n  var acceptData = function acceptData(owner) {\n    // Accepts only:\n    //  - Node\n    //    - Node.ELEMENT_NODE\n    //    - Node.DOCUMENT_NODE\n    //  - Object\n    //    - Any\n    return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;\n  };
1\n  function Data() {\n    this.expando = _jQuery2.expando + Data.uid++;\n  }\n  Data.uid = 1;\n  Data.prototype = {\n    cache: function cache(owner) {\n      // Check if the owner object already has a cache\n      var value = owner[this.expando];\n\n      // If not, create one\n      if (!value) {\n        value = {};\n\n        // We can accept data for non-element nodes in modern browsers,\n        // but we should not, see #8335.\n        // Always return an empty object.\n        if (acceptData(owner)) {\n          // If it is a node unlikely to be stringify-ed or looped over\n          // use plain assignment\n          if (owner.nodeType) {\n            owner[this.expando] = value;\n\n            // Otherwise secure it in a non-enumerable property\n            // configurable must be true to allow the property to be\n            // deleted when data is removed\n          } else {\n            Object.defineProperty(owner, this.expando, {\n              value: value,\n              configurable: true\n            });\n          }\n        }\n      }\n      return value;\n    },\n    set: function set(owner, data, value) {\n      var prop,\n        cache = this.cache(owner);\n\n      // Handle: [ owner, key, value ] args\n      // Always use camelCase key (gh-2257)\n      if (typeof data === "string") {\n        cache[_jQuery2.camelCase(data)] = value;\n\n        // Handle: [ owner, { properties } ] args\n      } else {\n        // Copy the properties one-by-one to the cache object\n        for (prop in data) {\n          cache[_jQuery2.camelCase(prop)] = data[prop];\n        }\n      }\n      return cache;\n    },\n    get: function get(owner, key) {\n      return key === undefined ? this.cache(owner) :\n      // Always use camelCase key (gh-2257)\n      owner[this.expando] && owner[this.expando][_jQuery2.camelCase(key)];\n    },\n    access: function access(owner, key, value) {\n      // In cases where either:\n      //\n      //   1. No key was specified\n      //   2. A string key was specified, but no value provided\n      //\n      // Take the "read" path and allow the get method to determine\n      // which value to return, respectively either:\n      //\n      //   1. The entire cache object\n      //   2. The data stored at the key\n      //\n      if (key === undefined || key && typeof key === "string" && value === undefined) {\n        return this.get(owner, key);\n      }\n\n      // When the key is not a string, or both a key and value\n      // are specified, set or extend (existing objects) with either:\n      //\n      //   1. An object of properties\n      //   2. A key and value\n      //\n      this.set(owner, key, value);\n\n      // Since the "set" path can have two possible entry points\n      // return the expected data based on which path was taken[*]\n      return value !== undefined ? value : key;\n    },\n    remove: function remove(owner, key) {\n      var i,\n        cache = owner[this.expando];\n      if (cache === undefined) {\n        return;\n      }\n      if (key !== undefined) {\n        // Support array or space separated string of keys\n        if (Array.isArray(key)) {\n          // If key is an array of keys...\n          // We always set camelCase keys, so remove that.\n          key = key.map(_jQuery2.camelCase);\n        } else {\n          key = _jQuery2.camelCase(key);\n\n          // If a key with the spaces exists, use it.\n          // Otherwise, create an array by matching non-whitespace\n          key = key in cache ? [key] : key.match(rnothtmlwhite) || [];\n        }\n        i = key.length;\n        while (i--) {\n          delete cache[key[i]];\n        }\n      }\n\n      // Remove the expando if there\'s no more data\n      if (key === undefined || _jQuery2.isEmptyObject(cache)) {\n        // Support: Chrome <=35 - 45\n        // Webkit & Blink performance suffers when deleting properties\n        // from DOM nodes, so set to undefined instead\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n        if (owner.nodeType) {\n          owner[this.expando] = undefined;\n        } else {\n          delete owner[this.expando];\n        }\n      }\n    },\n    hasData: function hasData(owner) {\n      var cache = owner[this.expando];\n      return cache !== undefined && !_jQuery2.isEmptyObject(cache);\n    }\n  };\n  var dataPriv = new Data();\n  var dataUser = new Data();\n\n  //\tImplementation Summary\n  //\n  //\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n  //\t2. Improve the module\'s maintainability by reducing the storage\n  //\t\tpaths to a single mechanism.\n  //\t3. Use the same single mechanism to supp
1ort "private" and "user" data.\n  //\t4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)\n  //\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n  //\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\n  var rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n    rmultiDash = /[A-Z]/g;\n  function getData(data) {\n    if (data === "true") {\n      return true;\n    }\n    if (data === "false") {\n      return false;\n    }\n    if (data === "null") {\n      return null;\n    }\n\n    // Only convert to a number if it doesn\'t change the string\n    if (data === +data + "") {\n      return +data;\n    }\n    if (rbrace.test(data)) {\n      return JSON.parse(data);\n    }\n    return data;\n  }\n  function dataAttr(elem, key, data) {\n    var name;\n\n    // If nothing was found internally, try to fetch any\n    // data from the HTML5 data-* attribute\n    if (data === undefined && elem.nodeType === 1) {\n      name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();\n      data = elem.getAttribute(name);\n      if (typeof data === "string") {\n        try {\n          data = getData(data);\n        } catch (e) {}\n\n        // Make sure we set the data so it isn\'t changed later\n        dataUser.set(elem, key, data);\n      } else {\n        data = undefined;\n      }\n    }\n    return data;\n  }\n  _jQuery2.extend({\n    hasData: function hasData(elem) {\n      return dataUser.hasData(elem) || dataPriv.hasData(elem);\n    },\n    data: function data(elem, name, _data) {\n      return dataUser.access(elem, name, _data);\n    },\n    removeData: function removeData(elem, name) {\n      dataUser.remove(elem, name);\n    },\n    // TODO: Now that all calls to _data and _removeData have been replaced\n    // with direct calls to dataPriv methods, these can be deprecated.\n    _data: function _data(elem, name, data) {\n      return dataPriv.access(elem, name, data);\n    },\n    _removeData: function _removeData(elem, name) {\n      dataPriv.remove(elem, name);\n    }\n  });\n  _jQuery2.fn.extend({\n    data: function data(key, value) {\n      var i,\n        name,\n        data,\n        elem = this[0],\n        attrs = elem && elem.attributes;\n\n      // Gets all values\n      if (key === undefined) {\n        if (this.length) {\n          data = dataUser.get(elem);\n          if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {\n            i = attrs.length;\n            while (i--) {\n              // Support: IE 11 only\n              // The attrs elements can be null (#14894)\n              if (attrs[i]) {\n                name = attrs[i].name;\n                if (name.indexOf("data-") === 0) {\n                  name = _jQuery2.camelCase(name.slice(5));\n                  dataAttr(elem, name, data[name]);\n                }\n              }\n            }\n            dataPriv.set(elem, "hasDataAttrs", true);\n          }\n        }\n        return data;\n      }\n\n      // Sets multiple values\n      if (_typeof(key) === "object") {\n        return this.each(function () {\n          dataUser.set(this, key);\n        });\n      }\n      return _access(this, function (value) {\n        var data;\n\n        // The calling jQuery object (element matches) is not empty\n        // (and therefore has an element appears at this[ 0 ]) and the\n        // `value` parameter was not undefined. An empty jQuery object\n        // will result in `undefined` for elem = this[ 0 ] which will\n        // throw an exception if an attempt to read a data cache is made.\n        if (elem && value === undefined) {\n          // Attempt to get data from the cache\n          // The key will always be camelCased in Data\n          data = dataUser.get(elem, key);\n          if (data !== undefined) {\n            return data;\n          }\n\n          // Attempt to "discover" the data in\n          // HTML5 custom data-* attrs\n          data = dataAttr(elem, key);\n          if (data !== undefined) {\n            return data;\n          }\n\n          // We tried really hard, but the data doesn\'t exist.\n          return;\n        }\n\n        // Set the data...\n        this.each(function () {\n          // We always store the camelCased key\n          dataUser.set(this, key, value);\n        });\n      }, null, value, arguments.length > 1, null, true);\n    },\n    removeData: function removeData(key) {\n      return this.each(function () {\n        dataUser.remove(this, key);\n      });\n    }\n  });\n  _jQuery2.extend({\n    queue: function queue(elem, type, data) {\n      var queue;\n      if (elem) {\n        type = (type || "fx") + "queue";\n        queue = dataPriv.get(elem, type);\n\n        // Speed up dequeue by getting out quickly if this is just a lookup\n        if (data) {\
1n          if (!queue || Array.isArray(data)) {\n            queue = dataPriv.access(elem, type, _jQuery2.makeArray(data));\n          } else {\n            queue.push(data);\n          }\n        }\n        return queue || [];\n      }\n    },\n    dequeue: function dequeue(elem, type) {\n      type = type || "fx";\n      var queue = _jQuery2.queue(elem, type),\n        startLength = queue.length,\n        fn = queue.shift(),\n        hooks = _jQuery2._queueHooks(elem, type),\n        next = function next() {\n          _jQuery2.dequeue(elem, type);\n        };\n\n      // If the fx queue is dequeued, always remove the progress sentinel\n      if (fn === "inprogress") {\n        fn = queue.shift();\n        startLength--;\n      }\n      if (fn) {\n        // Add a progress sentinel to prevent the fx queue from being\n        // automatically dequeued\n        if (type === "fx") {\n          queue.unshift("inprogress");\n        }\n\n        // Clear up the last queue stop function\n        delete hooks.stop;\n        fn.call(elem, next, hooks);\n      }\n      if (!startLength && hooks) {\n        hooks.empty.fire();\n      }\n    },\n    // Not public - generate a queueHooks object, or return the current one\n    _queueHooks: function _queueHooks(elem, type) {\n      var key = type + "queueHooks";\n      return dataPriv.get(elem, key) || dataPriv.access(elem, key, {\n        empty: _jQuery2.Callbacks("once memory").add(function () {\n          dataPriv.remove(elem, [type + "queue", key]);\n        })\n      });\n    }\n  });\n  _jQuery2.fn.extend({\n    queue: function queue(type, data) {\n      var setter = 2;\n      if (typeof type !== "string") {\n        data = type;\n        type = "fx";\n        setter--;\n      }\n      if (arguments.length < setter) {\n        return _jQuery2.queue(this[0], type);\n      }\n      return data === undefined ? this : this.each(function () {\n        var queue = _jQuery2.queue(this, type, data);\n\n        // Ensure a hooks for this queue\n        _jQuery2._queueHooks(this, type);\n        if (type === "fx" && queue[0] !== "inprogress") {\n          _jQuery2.dequeue(this, type);\n        }\n      });\n    },\n    dequeue: function dequeue(type) {\n      return this.each(function () {\n        _jQuery2.dequeue(this, type);\n      });\n    },\n    clearQueue: function clearQueue(type) {\n      return this.queue(type || "fx", []);\n    },\n    // Get a promise resolved when queues of a certain type\n    // are emptied (fx is the type by default)\n    promise: function promise(type, obj) {\n      var tmp,\n        count = 1,\n        defer = _jQuery2.Deferred(),\n        elements = this,\n        i = this.length,\n        resolve = function resolve() {\n          if (! --count) {\n            defer.resolveWith(elements, [elements]);\n          }\n        };\n      if (typeof type !== "string") {\n        obj = type;\n        type = undefined;\n      }\n      type = type || "fx";\n      while (i--) {\n        tmp = dataPriv.get(elements[i], type + "queueHooks");\n        if (tmp && tmp.empty) {\n          count++;\n          tmp.empty.add(resolve);\n        }\n      }\n      resolve();\n      return defer.promise(obj);\n    }\n  });\n  var pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source;\n  var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");\n  var cssExpand = ["Top", "Right", "Bottom", "Left"];\n  var isHiddenWithinTree = function isHiddenWithinTree(elem, el) {\n    // isHiddenWithinTree might be called from jQuery#filter function;\n    // in that case, element will be second argument\n    elem = el || elem;\n\n    // Inline style trumps all\n    return elem.style.display === "none" || elem.style.display === "" &&\n    // Otherwise, check computed style\n    // Support: Firefox <=43 - 45\n    // Disconnected elements can have computed display: none, so first confirm that elem is\n    // in the document.\n    _jQuery2.contains(elem.ownerDocument, elem) && _jQuery2.css(elem, "display") === "none";\n  };\n  var swap = function swap(elem, options, callback, args) {\n    var ret,\n      name,\n      old = {};\n\n    // Remember the old values, and insert the new ones\n    for (name in options) {\n      old[name] = elem.style[name];\n      elem.style[name] = options[name];\n    }\n    ret = callback.apply(elem, args || []);\n\n    // Revert the old values\n    for (name in options) {\n      elem.style[name] = old[name];\n    }\n    return ret;\n  };\n  function adjustCSS(elem, prop, valueParts, tween) {\n    var adjusted,\n      scale = 1,\n      maxIterations = 20,\n      currentValue = tween ? function () {\n        return tween.cur();\n      } : function () {\n        return _jQuery2.css(elem, prop, "");\n      },\n      initial = currentValue(),\n      unit = valueParts && valueParts[3] || (_jQuery2.cssNumber[prop] ? "" : "px"),\n      // Starting value computation is required for potential unit mismatches\n      initialInUnit = (_jQuery2.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(_jQuery2.css(elem, prop));\n    if (initialInUnit && initialInUnit[3] !== unit) {\n      // Trust units reported by jQuery.css\n      unit = unit || initialInUnit[3];\n\n      // Make sure we update the tween properties later on\n      valueParts = valueParts || [];\n\n      // Iteratively approximate from a nonzero starting point\n      initialInUnit = +initial || 1;\n      do {\n        // If previous iteration zeroed out, double until we get *something*.\n        // Use string for doubling so we don\'t accidentally see scale as unchanged below\n        scale = scale || ".5";\n\n        // Adjust and apply\n        initialInUnit = initialInUnit / scale;\n        _jQuery2.style(elem, prop, initialInUnit + unit);\n\n        // Update scale, tolerating zero or NaN from tween.cur()\n        // Break the loop if scale is unchanged or perfect, or if we\'ve just had enough.\n      } while (scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations);\n    }\n    if (valueParts) {\n      initialInUnit = +initialInUnit || +initial || 0;\n\n      // Apply relative offset (+=/-=) if specified\n      adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];\n      if (tween) {\n        tween.unit = unit;\n        tween.start = initialInUnit;\n        tween.end = adjusted;\n      }\n    }\n    return adjusted;\n  }\n  var defaultDisplayMap = {};\n  function getDefaultDisplay(elem) {\n    var temp,\n      doc = elem.ownerDocument,\n      nodeName = elem.nodeName,\n      display = defaultDisplayMap[nodeName];
1\n    if (display) {\n      return display;\n    }\n    temp = doc.body.appendChild(doc.createElement(nodeName));\n    display = _jQuery2.css(temp, "display");\n    temp.parentNode.removeChild(temp);\n    if (display === "none") {\n      display = "block";\n    }\n    defaultDisplayMap[nodeName] = display;\n    return display;\n  }\n  function showHide(elements, show) {\n    var display,\n      elem,\n      values = [],\n      index = 0,\n      length = elements.length;\n\n    // Determine new display value for elements that need to change\n    for (; index < length; index++) {\n      elem = elements[index];\n      if (!elem.style) {\n        continue;\n      }\n      display = elem.style.display;\n      if (show) {\n        // Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n        // check is required in this first loop unless we have a nonempty display value (either\n        // inline or about-to-be-restored)\n        if (display === "none") {\n          values[index] = dataPriv.get(elem, "display") || null;\n          if (!values[index]) {\n            elem.style.display = "";\n          }\n        }\n        if (elem.style.display === "" && isHiddenWithinTree(elem)) {\n          values[index] = getDefaultDisplay(elem);\n        }\n      } else {\n        if (display !== "none") {\n          values[index] = "none";\n\n          // Remember what we\'re overwriting\n          dataPriv.set(elem, "display", display);\n        }\n      }\n    }\n\n    // Set the display of the elements in a second loop to avoid constant reflow\n    for (index = 0; index < length; index++) {\n      if (values[index] != null) {\n        elements[index].style.display = values[index];\n      }\n    }\n    return elements;\n  }\n  _jQuery2.fn.extend({\n    show: function show() {\n      return showHide(this, true);\n    },\n    hide: function hide() {\n      return showHide(this);\n    },\n    toggle: function toggle(state) {\n      if (typeof state === "boolean") {\n        return state ? this.show() : this.hide();\n      }\n      return this.each(function () {\n        if (isHiddenWithinTree(this)) {\n          _jQuery2(this).show();\n        } else {\n          _jQuery2(this).hide();\n        }\n      });\n    }\n  });\n  var rcheckableType = /^(?:checkbox|radio)$/i;\n  var rtagName = /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i;\n  var rscriptType = /^$|\\/(?:java|ecma)script/i;\n\n  // We have to close these tags to support XHTML (#13200)\n  var wrapMap = {\n    // Support: IE <=9 only\n    option: [1, "<select multiple=\'multiple\'>", "</select>"],\n    // XHTML parsers do not magically insert elements in the\n    // same way that tag soup parsers do. So we cannot shorten\n    // this by omitting <tbody> or other required elements.\n    thead: [1, "<table>", "</table>"],\n    col: [2, "<table><colgroup>", "</colgroup></table>"],\n    tr: [2, "<table><tbody>", "</tbody></table>"],\n    td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],\n    _default: [0, "", ""]\n  };\n\n  // Support: IE <=9 only\n  wrapMap.optgroup = wrapMap.option;\n  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\n  wrapMap.th = wrapMap.td;\n  function getAll(context, tag) {\n    // Support: IE <=9 - 11 only\n    // Use typeof to avoid zero-argument method invocation on host objects (#15151)\n    var ret;\n    if (typeof context.getElementsByTagName !== "undefined") {\n      ret = context.getElementsByTagName(tag || "*");\n    } else if (typeof context.querySelectorAll !== "undefined") {\n      ret = context.querySelectorAll(tag || "*");\n    } else {\n      ret = [];\n    }\n    if (tag === undefined || tag && nodeName(context, tag)) {\n      return _jQuery2.merge([context], ret);\n    }\n    return ret;\n  }\n\n  // Mark scripts as having already been evaluated\n  function setGlobalEval(elems, refElements) {\n    var i = 0,\n      l = elems.length;\n    for (; i < l; i++) {\n      dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));\n    }\n  }\n  var rhtml = /<|&#?\\w+;/;\n  function buildFragment(elems, context, scripts, selection, ignored) {\n    var elem,\n      tmp,\n      tag,\n      wrap,\n      contains,\n      j,\n      fragment = context.createDocumentFragment(),\n      nodes = [],\n      i = 0,\n      l = elems.length;\n    for (; i < l;
1 i++) {\n      elem = elems[i];\n      if (elem || elem === 0) {\n        // Add nodes directly\n        if (_jQuery2.type(elem) === "object") {\n          // Support: Android <=4.0 only, PhantomJS 1 only\n          // push.apply(_, arraylike) throws on ancient WebKit\n          _jQuery2.merge(nodes, elem.nodeType ? [elem] : elem);\n\n          // Convert non-html into a text node\n        } else if (!rhtml.test(elem)) {\n          nodes.push(context.createTextNode(elem));\n\n          // Convert html into DOM nodes\n        } else {\n          tmp = tmp || fragment.appendChild(context.createElement("div"));\n\n          // Deserialize a standard representation\n          tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();\n          wrap = wrapMap[tag] || wrapMap._default;\n          tmp.innerHTML = wrap[1] + _jQuery2.htmlPrefilter(elem) + wrap[2];\n\n          // Descend through wrappers to the right content\n          j = wrap[0];\n          while (j--) {\n            tmp = tmp.lastChild;\n          }\n\n          // Support: Android <=4.0 only, PhantomJS 1 only\n          // push.apply(_, arraylike) throws on ancient WebKit\n          _jQuery2.merge(nodes, tmp.childNodes);\n\n          // Remember the top-level container\n          tmp = fragment.firstChild;\n\n          // Ensure the created nodes are orphaned (#12392)\n          tmp.textContent = "";\n        }\n      }\n    }\n\n    // Remove wrapper from fragment\n    fragment.textContent = "";\n    i = 0;\n    while (elem = nodes[i++]) {\n      // Skip elements already in the context collection (trac-4087)\n      if (selection && _jQuery2.inArray(elem, selection) > -1) {\n        if (ignored) {\n          ignored.push(elem);\n        }\n        continue;\n      }\n      contains = _jQuery2.contains(elem.ownerDocument, elem);\n\n      // Append to fragment\n      tmp = getAll(fragment.appendChild(elem), "script");\n\n      // Preserve script evaluation history\n      if (contains) {\n        setGlobalEval(tmp);\n      }\n\n      // Capture executables\n      if (scripts) {\n        j = 0;\n        while (elem = tmp[j++]) {\n          if (rscriptType.test(elem.type || "")) {\n            scripts.push(elem);\n          }\n        }\n      }\n    }\n    return fragment;\n  }\n  (function () {\n    var fragment = document.createDocumentFragment(),\n      div = fragment.appendChild(document.createElement("div")),\n      input = document.createElement("input");\n\n    // Support: Android 4.0 - 4.3 only\n    // Check state lost if the name is set (#11217)\n    // Support: Windows Web Apps (WWA)\n    // `name` and `type` must use .setAttribute for WWA (#14901)\n    input.setAttribute("type", "radio");\n    input.setAttribute("checked", "checked");\n    input.setAttribute("name", "t");\n    div.appendChild(input);
1\n\n    // Support: Android <=4.1 only\n    // Older WebKit doesn\'t clone checked state correctly in fragments\n    support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;\n\n    // Support: IE <=11 only\n    // Make sure textarea (and checkbox) defaultValue is properly cloned\n    div.innerHTML = "<textarea>x</textarea>";\n    support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;\n  })();\n  var documentElement = document.documentElement;\n  var rkeyEvent = /^key/,\n    rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n    rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n  function returnTrue() {\n    return true;\n  }\n  function returnFalse() {\n    return false;\n  }\n\n  // Support: IE <=9 only\n  // See #13393 for more info\n  function safeActiveElement() {\n    try {\n      return document.activeElement;\n    } catch (err) {}\n  }\n  function _on(elem, types, selector, data, fn, one) {\n    var origFn, type;\n\n    // Types can be a map of types/handlers\n    if (_typeof(types) === "object") {\n      // ( types-Object, selector, data )\n      if (typeof selector !== "string") {\n        // ( types-Object, data )\n        data = data || selector;\n        selector = undefined;\n      }\n      for (type in types) {\n        _on(elem, type, selector, data, types[type], one);\n      }\n      return elem;\n    }\n    if (data == null && fn == null) {\n      // ( types, fn )\n      fn = selector;\n      data = selector = undefined;\n    } else if (fn == null) {\n      if (typeof selector === "string") {\n        // ( types, selector, fn )\n        fn = data;\n        data = undefined;\n      } else {\n        // ( types, data, fn )\n        fn = data;\n        data = selector;\n        selector = undefined;\n      }\n    }\n    if (fn === false) {\n      fn = returnFalse;\n    } else if (!fn) {\n      return elem;\n    }\n    if (one === 1) {\n      origFn = fn;\n      fn = function fn(event) {\n        // Can use an empty set, since event contains the info\n        _jQuery2().off(event);\n        return origFn.apply(this, arguments);\n      };\n\n      // Use same guid so caller can remove using origFn\n      fn.guid = origFn.guid || (origFn.guid = _jQuery2.guid++);\n    }\n    return elem.each(function () {\n      _jQuery2.event.add(this, types, fn, data, selector);\n    });\n  }\n\n  /*\r\n   * Helper functions for managing events -- not part of the public interface.\r\n   * Props to Dean Edwards\' addEvent library for many of the ideas.\r\n   */\n  _jQuery2.event = {\n    global: {},\n    add: function add(elem, types, handler, data, selector) {\n      var handleObjIn,\n        eventHandle,\n        tmp,\n        events,\n        t,\n        handleObj,\n        special,\n        handlers,\n        type,\n        namespaces,\n        origType,\n        elemData = dataPriv.get(elem);\n\n      // Don\'t attach events to noData or text/comment nodes (but allow plain objects)\n      if (!elemData) {\n        return;\n      }\n\n      // Caller can pass in an object of custom data in lieu of the handler\n      if (handler.handler) {\n        handleObjIn = handler;\n        handler = handleObjIn.handler;\n        selector = handleObjIn.selector;\n      }\n\n      // Ensure that invalid selectors throw exceptions at attach time\n      // Evaluate against documentElement in case elem is a non-element node (e.g., document)\n      if (selector) {\n        _jQuery2.find.matchesSelector(documentElement, selector);\n      }\n\n      // Make sure that the handler has a unique ID, used to find/remove it later\n      if (!handler.guid) {\n        handler.guid = _jQuery2.guid++;\n      }\n\n      // Init the element\'s event structure and main handler, if this is the first\n      if (!(events = elemData.events)) {\n        events = elemData.events = {};\n      }\n      if (!(eventHandle = elemData.handle)) {\n        eventHandle = elemData.handle = function (e) {\n          // Discard the second event of a jQuery.event.trigger() and\n          // when an event is called after a page has unloaded\n          return typeof _jQuery2 !== "undefined" && _jQuery2.event.triggered !== e.type ? _jQuery2.event.dispatch.apply(elem, arguments) : undefined;\n        };\n      }\n\n      // Handle multiple events separated by a space\n      types = (types || "").match(rnothtmlwhite) || [""];\n      t = types.length;\n      while (t--) {\n        tmp = rtypenamespace.exec(types[t]) || [];\n        type = origType = tmp[1];\n        namespaces = (tmp[2] || "").split(".").sort();\n\n        // There *must* be a type, no attaching namespace-only handlers\n        if (!type) {\n          continue;\n        }\n\n        // If event changes its type, use the special event handlers for the changed type\n        special = _jQuery2.event.special[type] || {};\n\n        // If selector defined, determine special event api type, otherwise given type\n        type = (selector ? special.delegateType : special.bindType) || type;\n\n        // Update special based on newly reset type\n        special = _jQuery2.event.special[type] || {};\n\n        // handleObj is passed to all event handlers\n        handleObj = _jQuery2.extend({\n          type: type,\n          origType: origType,\n          data: data,\n          handler: handler,\n          guid: handler.guid,\n          selector: selector,\n          needsContext: selector && _jQuery2.expr.match.needsContext.test(selector),\n          namespace: namespaces.join(".")\n        }, handleObjIn);\n\n        // Init the event handler queue if we\'re the first\n        if (!(handlers = events[type])) {\n          handlers = events[type] = [];\n          handlers.delegateCount = 0;\n\n          // Only use addEventListener if the special events handler returns false\n          if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {\n            if (elem.addEventListener) {\n              elem.addEventListener(type, eventHandle);\n            }\n          }\n        }\n        if (special.add) {\n          special.add.call(elem, handleObj);\n          if (!handleObj.handler.guid) {\n            handleObj.handler.guid = handler.guid;\n          }\n        }\n\n        // Add to the element\'s handler list, delegates in front\n        if (selector) {\n          handlers.splice(handlers.delegateCount++, 0, handleObj);\n        } else {\n          handlers.push(handleObj);\n        }\n\n        // Keep track of which events have ever been used, for event optimization\n        _jQuery2.event.global[type] = true;\n      }\n    },\n    // Detach an event or set of events from an element\n    remove: function remove(elem, types, handler, selector, mappedTypes) {\n      var j,\n        origCount,\n        tmp,\n        events,\n        t,\n        handleObj,\n        special,\n        handlers,\n        type,\n        namespaces,\
1n        origType,\n        elemData = dataPriv.hasData(elem) && dataPriv.get(elem);\n      if (!elemData || !(events = elemData.events)) {\n        return;\n      }\n\n      // Once for each type.namespace in types; type may be omitted\n      types = (types || "").match(rnothtmlwhite) || [""];\n      t = types.length;\n      while (t--) {\n        tmp = rtypenamespace.exec(types[t]) || [];\n        type = origType = tmp[1];\n        namespaces = (tmp[2] || "").split(".").sort();\n\n        // Unbind all events (on this namespace, if provided) for the element\n        if (!type) {\n          for (type in events) {\n            _jQuery2.event.remove(elem, type + types[t], handler, selector, true);\n          }\n          continue;\n        }\n        special = _jQuery2.event.special[type] || {};\n        type = (selector ? special.delegateType : special.bindType) || type;\n        handlers = events[type] || [];\n        tmp = tmp[2] && new RegExp("(^|\\\\.)" + namespaces.join("\\\\.(?:.*\\\\.|)") + "(\\\\.|$)");\n\n        // Remove matching events\n        origCount = j = handlers.length;\n        while (j--) {\n          handleObj = handlers[j];\n          if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {\n            handlers.splice(j, 1);\n            if (handleObj.selector) {\n              handlers.delegateCount--;\n            }\n            if (special.remove) {\n              special.remove.call(elem, handleObj);\n            }\n          }\n        }\n\n        // Remove generic event handler if we removed something and no more handlers exist\n        // (avoids potential for endless recursion during removal of special event handlers)\n        if (origCount && !handlers.length) {\n          if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {\n            _jQuery2.removeEvent(elem, type, elemData.handle);\n          }\n          delete events[type];\n        }\n      }\n\n      // Remove data and the expando if it\'s no longer used\n      if (_jQuery2.isEmptyObject(events)) {\n        dataPriv.remove(elem, "handle events");\n      }\n    },\n    dispatch: function dispatch(nativeEvent) {\n      // Make a writable jQuery.Event from the native event object\n      var event = _jQuery2.event.fix(nativeEvent);\n      var i,\n        j,\n        ret,\n        matched,\n        handleObj,\n        handlerQueue,\n        args = new Array(arguments.length),\n        handlers = (dataPriv.get(this, "events") || {})[event.type] || [],\n        special = _jQuery2.event.special[event.type] || {};\n\n      // Use the fix-ed jQuery.Event rather than the (read-only) native event\n      args[0] = event;\n      for (i = 1; i < arguments.length; i++) {\n        args[i] = arguments[i];\n      }\n      event.delegateTarget = this;\n\n      // Call the preDispatch hook for the mapped type, and let it bail if desired\n      if (special.preDispatch && special.preDispatch.call(this, event) === false) {\n        return;\n      }\n\n      // Determine handlers\n      handlerQueue = _jQuery2.event.handlers.call(this, event, handlers);\n\n      // Run delegates first; they may want to stop propagation beneath us\n      i = 0;\n      while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {\n        event.currentTarget = matched.elem;\n        j = 0;\n        while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {\n          // Triggered event must either 1) have no namespace, or 2) have namespace(s)\n          // a subset or equal to those in the bound event (both can have no namespace).\n          if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {\n            event.handleObj = handleObj;\n            event.data = handleObj.data;\n            ret = ((_jQuery2.event.special[handleObj.origType] || {}
1).handle || handleObj.handler).apply(matched.elem, args);\n            if (ret !== undefined) {\n              if ((event.result = ret) === false) {\n                event.preventDefault();\n                event.stopPropagation();\n              }\n            }\n          }\n        }\n      }\n\n      // Call the postDispatch hook for the mapped type\n      if (special.postDispatch) {\n        special.postDispatch.call(this, event);\n      }\n      return event.result;\n    },\n    handlers: function handlers(event, _handlers) {\n      var i,\n        handleObj,\n        sel,\n        matchedHandlers,\n        matchedSelectors,\n        handlerQueue = [],\n        delegateCount = _handlers.delegateCount,\n        cur = event.target;\n\n      // Find delegate handlers\n      if (delegateCount &&\n      // Support: IE <=9\n      // Black-hole SVG <use> instance trees (trac-13180)\n      cur.nodeType &&\n      // Support: Firefox <=42\n      // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n      // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n      // Support: IE 11 only\n      // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)\n      !(event.type === "click" && event.button >= 1)) {\n        for (; cur !== this; cur = cur.parentNode || this) {\n          // Don\'t check non-elements (#13208)\n          // Don\'t process clicks on disabled elements (#6911, #8165, #11382, #11764)\n          if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {\n            matchedHandlers = [];\n            matchedSelectors = {};\n            for (i = 0; i < delegateCount; i++) {\n              handleObj = _handlers[i];\n\n              // Don\'t conflict with Object.prototype properties (#13203)\n              sel = handleObj.selector + " ";\n              if (matchedSelectors[sel] === undefined) {\n                matchedSelectors[sel] = handleObj.needsContext ? _jQuery2(sel, this).index(cur) > -1 : _jQuery2.find(sel, this, null, [cur]).length;\n              }\n              if (matchedSelectors[sel]) {\n                matchedHandlers.push(handleObj);\n              }\n            }\n            if (matchedHandlers.length) {\n              handlerQueue.push({\n                elem: cur,\n                handlers: matchedHandlers\n              });\n            }\n          }\n        }\n      }\n\n      // Add the remaining (directly-bound) handlers\n      cur = this;\n      if (delegateCount < _handlers.length) {\n        handlerQueue.push({\n          elem: cur,\n          handlers: _handlers.slice(delegateCount)\n        });\n      }\n      return handlerQueue;\n    },\n    addProp: function addProp(name, hook) {\n      Object.defineProperty(_jQuery2.Event.prototype, name, {\n        enumerable: true,\n        configurable: true,\n        get: _jQuery2.isFunction(hook) ? function () {\n          if (this.originalEvent) {\n            return hook(this.originalEvent);\n          }\n        } : function () {\n          if (this.originalEvent) {\n            return this.originalEvent[name];\n          }\n        },\n        set: function set(value) {\n          Object.defineProperty(this, name, {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: value\n          });\n        }\n      });\n    },\n    fix: function fix(originalEvent) {\n      return originalEvent[_jQuery2.expando] ? originalEvent : new _jQuery2.Event(originalEvent);\n    },\n    special: {\n      load: {\n        // Prevent triggered image.load events from bubbling to window.load\n        noBubble: true\n      },\n      focus: {\n        // Fire native event if possible so blur/focus sequence is correct\n        trigger: function trigger() {\n          if (this !== safeActiveElement() && this.focus) {\n            this.focus();\n            return false;\n          }\n        },\n        delegateType: "focusin"\n      },\n      blur: {\n        trigger: function trigger() {\n          if (this === safeActiveElement() && this.blur) {\n            this.blur();\n            return false;\n          }\n        },\n        delegateType: "focusout"\n      },\n      click: {\n        // For checkbox, fire native event so checked state will be right\n        trigger: function trigger() {\n          if (this.t
1ype === "checkbox" && this.click && nodeName(this, "input")) {\n            this.click();\n            return false;\n          }\n        },\n        // For cross-browser consistency, don\'t fire native .click() on links\n        _default: function _default(event) {\n          return nodeName(event.target, "a");\n        }\n      },\n      beforeunload: {\n        postDispatch: function postDispatch(event) {\n          // Support: Firefox 20+\n          // Firefox doesn\'t alert if the returnValue field is not set.\n          if (event.result !== undefined && event.originalEvent) {\n            event.originalEvent.returnValue = event.result;\n          }\n        }\n      }\n    }\n  };\n  _jQuery2.removeEvent = function (elem, type, handle) {\n    // This "if" is needed for plain objects\n    if (elem.removeEventListener) {\n      elem.removeEventListener(type, handle);\n    }\n  };\n  _jQuery2.Event = function (src, props) {\n    // Allow instantiation without the \'new\' keyword\n    if (!(this instanceof _jQuery2.Event)) {\n      return new _jQuery2.Event(src, props);\n    }\n\n    // Event object\n    if (src && src.type) {\n      this.originalEvent = src;\n      this.type = src.type;\n\n      // Events bubbling up the document may have been marked as prevented\n      // by a handler lower down the tree; reflect the correct value.\n      this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined &&\n      // Support: Android <=2.3 only\n      src.returnValue === false ? returnTrue : returnFalse;\n\n      // Create target properties\n      // Support: Safari <=6 - 7 only\n      // Target should not be a text node (#504, #13143)\n      this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target;\n      this.currentTarget = src.currentTarget;\n      this.relatedTarget = src.relatedTarget;\n\n      // Event type\n    } else {\n      this.type = src;\n    }\n\n    // Put explicitly provided properties onto the event object\n    if (props) {\n      _jQuery2.extend(this, props);\n    }\n\n    // Create a timestamp if incoming event doesn\'t have one\n    this.timeStamp = src && src.timeStamp || _jQuery2.now();\n\n    // Mark it as fixed\n    this[_jQuery2.expando] = true;\n  };\n\n  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n  // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\n  _jQuery2.Event.prototype = {\n    constructor: _jQuery2.Event,\n    isDefaultPrevented: returnFalse,\n    isPropagationStopped: returnFalse,\n    isImmediatePropagationStopped: returnFalse,\n    isSimulated: false,\n    preventDefault: function preventDefault() {\n      var e = this.originalEvent;\n      this.isDefaultPrevented = returnTrue;\n      if (e && !this.isSimulated) {\n        e.preventDefault();\n      }\n    },\n    stopPropagation: function stopPropagation() {\n      var e = this.originalEvent;\n      this.isPropagationStopped = returnTrue;\n      if (e && !this.isSimulated) {\n        e.stopPropagation();\n      }\n    },\n    stopImmediatePropagation: function stopImmediatePropagation() {\n      var e = this.originalEvent;\n      this.isImmediatePropagationStopped = returnTrue;\n      if (e && !this.isSimulated) {\n        e.stopImmediatePropagation();\n      }\n      this.stopPropagation();\n    }\n  };\n\n  // Includes all common event props including KeyEvent and MouseEvent specific props\n  _jQuery2.each({\n    altKey: true,\n    bubbles: true,\n    cancelable: true,\n    changedTouches: true,\n    ctrlKey: true,\n    detail: true,\n    eventPhase: true,\n    metaKey: true,\n    pageX: true,\n    pageY: true,\n    shift
1Key: true,\n    view: true,\n    "char": true,\n    charCode: true,\n    key: true,\n    keyCode: true,\n    button: true,\n    buttons: true,\n    clientX: true,\n    clientY: true,\n    offsetX: true,\n    offsetY: true,\n    pointerId: true,\n    pointerType: true,\n    screenX: true,\n    screenY: true,\n    targetTouches: true,\n    toElement: true,\n    touches: true,\n    which: function which(event) {\n      var button = event.button;\n\n      // Add which for key events\n      if (event.which == null && rkeyEvent.test(event.type)) {\n        return event.charCode != null ? event.charCode : event.keyCode;\n      }\n\n      // Add which for click: 1 === left; 2 === middle; 3 === right\n      if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {\n        if (button & 1) {\n          return 1;\n        }\n        if (button & 2) {\n          return 3;\n        }\n        if (button & 4) {\n          return 2;\n        }\n        return 0;\n      }\n      return event.which;\n    }\n  }, _jQuery2.event.addProp);\n\n  // Create mouseenter/leave events using mouseover/out and event-time checks\n  // so that event delegation works in jQuery.\n  // Do the same for pointerenter/pointerleave and pointerover/pointerout\n  //\n  // Support: Safari 7 only\n  // Safari sends mouseenter too often; see:\n  // https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n  // for the description of the bug (it existed in older Chrome versions as well).\n  _jQuery2.each({\n    mouseenter: "mouseover",\n    mouseleave: "mouseout",\n    pointerenter: "pointerover",\n    pointerleave: "pointerout"\n  }, function (orig, fix) {\n    _jQuery2.event.special[orig] = {\n      delegateType: fix,\n      bindType: fix,\n      handle: function handle(event) {\n        var ret,\n          target = this,\n          related = event.relatedTarget,\n          handleObj = event.handleObj;\n\n        // For mouseenter/leave call the handler if related is outside the target.\n        // NB: No relatedTarget if the mouse left/entered the browser window\n        if (!related || related !== target && !_jQuery2.contains(target, related)) {\n          event.type = handleObj.origType;\n          ret = handleObj.handler.apply(this, arguments);\n          event.type = fix;\n        }\n        return ret;\n      }\n    };\n  });\n  _jQuery2.fn.extend({\n    on: function on(types, selector, data, fn) {\n      return _on(this, types, selector, data, fn);\n    },\n    one: function one(types, selector, data, fn) {\n      return _on(this, types, selector, data, fn, 1);\n    },\n    off: function off(types, selector, fn) {\n      var handleObj, type;\n      if (types && types.preventDefault && types.handleObj) {\n        // ( event )  dispatched jQuery.Event\n        handleObj = types.handleObj;\n        _jQuery2(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);\n        return this;\n      }\n      if (_typeof(types) === "object") {\n        // ( types-object [, selector] )\n        for (type in types) {\n          this.off(type, selector, types[type]);\n        }\n        return this;\n      }\n      if (selector === false || typeof selector === "function") {\n        // ( types [, fn] )\n        fn = selector;\n        selector = undefined;\n      }\n      if (fn === false) {\n        fn = returnFalse;\n      }\n      return this.each(function () {\n        _jQuery2.event.remove(this, types, fn, selector);\n      });\n    }\n  });\n  var /* eslint-disable max-len */\n\n    // See https://github.com/eslint/eslint/issues/3229\n    rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n    /* eslint-enable */\n\n    // Support: IE <=10 - 11, Edge 12 - 13\n    // In IE/Edge using regex groups here causes severe slowdowns.\n    // See https://connect.microsoft.com/IE/feedback/details/1736512/\n    rnoInnerhtml = /<script|<style|<link/i,\n    // checked="checked" or checked\n    rchecked = /checked\\s*(?:[^=]|=\\
1s*.checked.)/i,\n    rscriptTypeMasked = /^true\\/(.*)/,\n    rcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n  // Prefer a tbody over its parent table for containing new rows\n  function manipulationTarget(elem, content) {\n    if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {\n      return _jQuery2(">tbody", elem)[0] || elem;\n    }\n    return elem;\n  }\n\n  // Replace/restore the type attribute of script elements for safe DOM manipulation\n  function disableScript(elem) {\n    elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;\n    return elem;\n  }\n  function restoreScript(elem) {\n    var match = rscriptTypeMasked.exec(elem.type);\n    if (match) {\n      elem.type = match[1];\n    } else {\n      elem.removeAttribute("type");\n    }\n    return elem;\n  }\n  function cloneCopyEvent(src, dest) {\n    var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n    if (dest.nodeType !== 1) {\n      return;\n    }\n\n    // 1. Copy private data: events, handlers, etc.\n    if (dataPriv.hasData(src)) {\n      pdataOld = dataPriv.access(src);\n      pdataCur = dataPriv.set(dest, pdataOld);\n      events = pdataOld.events;\n      if (events) {\n        delete pdataCur.handle;\n        pdataCur.events = {};\n        for (type in events) {\n          for (i = 0, l = events[type].length; i < l; i++) {\n            _jQuery2.event.add(dest, type, events[type][i]);\n          }\n        }\n      }\n    }\n\n    // 2. Copy user data\n    if (dataUser.hasData(src)) {\n      udataOld = dataUser.access(src);\n      udataCur = _jQuery2.extend({}, udataOld);\n      dataUser.set(dest, udataCur);\n    }\n  }\n\n  // Fix IE bugs, see support tests\n  function fixInput(src, dest) {\n    var nodeName = dest.nodeName.toLowerCase();\n\n    // Fails to persist the checked state of a cloned checkbox or radio button.\n    if (nodeName === "input" && rcheckableType.test(src.type)) {\n      dest.checked = src.checked;\n\n      // Fails to return the selected option to the default selected state when cloning options\n    } else if (nodeName === "input" || nodeName === "textarea") {\n      dest.defaultValue = src.defaultValue;\n    }\n  }\n  function domManip(collection, args, callback, ignored) {\n    // Flatten any nested arrays\n    args = concat.apply([], args);\n    var fragment,\n      first,\n      scripts,\n      hasScripts,\n      node,\n      doc,\n      i = 0,\n      l = collection.length,\n      iNoClone = l - 1,\n      value = args[0],\n      isFunction = _jQuery2.isFunction(value);\n\n    // We can\'t cloneNode fragments that contain checked, in WebKit\n    if (isFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {\n      return collection.each(function (index) {\n        var self = collection.eq(index);\n        if (isFunction) {\n          args[0] = value.call(this, index, self.html());\n        }\n        domManip(self, args, callback, ignored);\n      });\n    }\n    if (l) {\n      fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);\n      first = fragment.firstChild;\n      if (fragment.childNodes.length === 1) {\n        fragment = first;\n      }\n\n      // Require either new content or an interest in ignored elements to invoke the callback\n      if (first || ignored) {\n        scripts = _jQuery2.map(getAll(fragment, "script"), disableScript);\n        hasScripts = scripts.length;\n\n        // Use the original fragment for the last item\n        // instead of the first because it can end up\n        // being emptied incorrectly in certain situations (#8070).\n        for (; i < l; i++) {\n          node = fragment;\n          if (i !== iNoClone) {\n            node = _jQuery2.clone(node, true, true);\n\n            // Keep references to cloned scripts for later restoration\n            if (hasScripts) {\n              // Support: Android <=4.0 only, PhantomJS 1 only\n              // push.apply(_, arraylike) throws on ancient WebKit\n              _jQuery2.merge(scripts, getAll(node, "script"));\n            }\n          }\n          callback.call(collection[i], node, i);\n        }\n        if (hasScripts) {\n          doc = scripts[scripts.length - 1].ownerDocument;\n\n          // Reenable scripts\n          _jQuery2.map(scripts, restoreScript);\n\n          // Evaluate executable scripts on first document insertion\n          for (i = 0; i < hasScripts;
1 i++) {\n            node = scripts[i];\n            if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && _jQuery2.contains(doc, node)) {\n              if (node.src) {\n                // Optional AJAX dependency, but won\'t run scripts if not present\n                if (_jQuery2._evalUrl) {\n                  _jQuery2._evalUrl(node.src);\n                }\n              } else {\n                DOMEval(node.textContent.replace(rcleanScript, ""), doc);\n              }\n            }\n          }\n        }\n      }\n    }\n    return collection;\n  }\n  function _remove(elem, selector, keepData) {\n    var node,\n      nodes = selector ? _jQuery2.filter(selector, elem) : elem,\n      i = 0;\n    for (; (node = nodes[i]) != null; i++) {\n      if (!keepData && node.nodeType === 1) {\n        _jQuery2.cleanData(getAll(node));\n      }\n      if (node.parentNode) {\n        if (keepData && _jQuery2.contains(node.ownerDocument, node)) {\n          setGlobalEval(getAll(node, "script"));\n        }\n        node.parentNode.removeChild(node);\n      }\n    }\n    return elem;\n  }\n  _jQuery2.extend({\n    htmlPrefilter: function htmlPrefilter(html) {\n      return html.replace(rxhtmlTag, "<$1></$2>");\n    },\n    clone: function clone(elem, dataAndEvents, deepDataAndEvents) {\n      var i,\n        l,\n        srcElements,\n        destElements,\n        clone = elem.cloneNode(true),\n        inPage = _jQuery2.contains(elem.ownerDocument, elem);\n\n      // Fix IE cloning issues\n      if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !_jQuery2.isXMLDoc(elem)) {\n        // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n        destElements = getAll(clone);\n        srcElements = getAll(elem);\n        for (i = 0, l = srcElements.length; i < l; i++) {\n          fixInput(srcElements[i], destElements[i]);\n        }\n      }\n\n      // Copy the events from the original to the clone\n      if (dataAndEvents) {\n        if (deepDataAndEvents) {\n          srcElements = srcElements || getAll(elem);\n          destElements = destElements || getAll(clone);\n          for (i = 0, l = srcElements.length; i < l; i++) {\n            cloneCopyEvent(srcElements[i], destElements[i]);\n          }\n        } else {\n          cloneCopyEvent(elem, clone);\n        }\n      }\n\n      // Preserve script evaluation history\n      destElements = getAll(clone, "script");\n      if (destElements.length > 0) {\n        setGlobalEval(destElements, !inPage && getAll(elem, "script"));\n      }\n\n      // Return the cloned set\n      return clone;\n    },\n    cleanData: function cleanData(elems) {\n      var data,\n        elem,\n        type,\n        special = _jQuery2.event.special,\n        i = 0;\n      for (; (elem = elems[i]) !== undefined; i++) {\n        if (acceptData(elem)) {\n          if (data = elem[dataPriv.expando]) {\n            if (data.events) {\n              for (type in data.events) {\n                if (special[type]) {\n                  _jQuery2.event.remove(elem, type);\n\n                  // This is a shortcut to avoid jQuery.event.remove\'s overhead\n                } else {\n                  _jQuery2.removeEvent(elem, type, data.handle);\n                }\n              }\n            }\n\n            // Support: Chrome <=35 - 45+\n            // Assign undefined instead of using delete, see Data#remove\n            elem[dataPriv.expando] = undefined;\n          }\n          if (elem[dataUser.expando]) {\n            // Support: Chrome <=35 - 45+\n            // Assign undefined instead of using delete, see Data#remove\n            elem[dataUser.expando] = undefined;\n          }\n        }\n      }\n    }\n  });\n  _jQuery2.fn.extend({\n    detach: function detach(selector) {\n      return _remove(this, selector, true);\n    },\n    remove: function remove(selector) {\n      return _remove(this, selector);\n    },\n    text: function text(value) {\n      return _access(this, function (value) {\n        return value === undefined ? _jQuery2.text(this) : this.empty().each(function () {\n          if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n            this.textContent = value;\n          }\n        });\n      }, null, value, arguments.length);\n    },\n    append: function append() {\n      return domManip(this, arguments, function (elem) {\n        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n          var target = manipulationTarget(this, elem);\n          target.appendChild(elem);\n        }\n      });\n    },\n    prepend: function prepend() {\n      return domManip(this, arguments, function (elem) {\n        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n          var target = manipulationTarget(this, elem);\n          target.insertBefore(elem, target.firstChild);\n        }\n      });\n    },\n    before: function before() {\n      return domManip(this, arguments, function (elem) {\n        if (this.parentNode) {\n          this.parentNode.insertBefore(elem, this);\n        }\n      });\n    },\n    after: function after() {\n      return domManip(this, arguments, function (elem) {\n        if (this.parentNode) {\n          this.parentNode.insertBefore(elem, this.nextSibling);\n        }\n      });\n    },\n    empty: function empty() {\n      var elem,\n        i = 0;\n      for (; (elem = this[i]) != null;
1 i++) {\n        if (elem.nodeType === 1) {\n          // Prevent memory leaks\n          _jQuery2.cleanData(getAll(elem, false));\n\n          // Remove any remaining nodes\n          elem.textContent = "";\n        }\n      }\n      return this;\n    },\n    clone: function clone(dataAndEvents, deepDataAndEvents) {\n      dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n      deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n      return this.map(function () {\n        return _jQuery2.clone(this, dataAndEvents, deepDataAndEvents);\n      });\n    },\n    html: function html(value) {\n      return _access(this, function (value) {\n        var elem = this[0] || {},\n          i = 0,\n          l = this.length;\n        if (value === undefined && elem.nodeType === 1) {\n          return elem.innerHTML;\n        }\n\n        // See if we can take a shortcut and just use innerHTML\n        if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {\n          value = _jQuery2.htmlPrefilter(value);\n          try {\n            for (; i < l; i++) {\n              elem = this[i] || {};\n\n              // Remove element nodes and prevent memory leaks\n              if (elem.nodeType === 1) {\n                _jQuery2.cleanData(getAll(elem, false));\n                elem.innerHTML = value;\n              }\n            }\n            elem = 0;\n\n            // If using innerHTML throws an exception, use the fallback method\n          } catch (e) {}\n        }\n        if (elem) {\n          this.empty().append(value);\n        }\n      }, null, value, arguments.length);\n    },\n    replaceWith: function replaceWith() {\n      var ignored = [];\n\n      // Make the changes, replacing each non-ignored context element with the new content\n      return domManip(this, arguments, function (elem) {\n        var parent = this.parentNode;\n        if (_jQuery2.inArray(this, ignored) < 0) {\n          _jQuery2.cleanData(getAll(this));\n          if (parent) {\n            parent.replaceChild(elem, this);\n          }\n        }\n\n        // Force callback invocation\n      }, ignored);\n    }\n  });\n  _jQuery2.each({\n    appendTo: "append",\n    prependTo: "prepend",\n    insertBefore: "before",\n    insertAfter: "after",\n    replaceAll: "replaceWith"\n  }, function (name, original) {\n    _jQuery2.fn[name] = function (selector) {\n      var elems,\n        ret = [],\n        insert = _jQuery2(selector),\n        last = insert.length - 1,\n        i = 0;\n      for (; i <= last; i++) {\n        elems = i === last ? this : this.clone(true);\n        _jQuery2(insert[i])[original](elems);\n\n        // Support: Android <=4.0 only, PhantomJS 1 only\n        // .get() because push.apply(_, arraylike) throws on ancient WebKit\n        push.apply(ret, elems.get());\n      }\n      return this.pushStack(ret);\n    };\n  });\n  var rmargin = /^margin/;\n  var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");\n  var getStyles = function getStyles(elem) {\n    // Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n    // IE throws on elements created in popups\n    // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"\n    var view = elem.ownerDocument.defaultView;\n    if (!view || !view.opener) {\n      view = window;\n    }\n    return view.getComputedStyle(elem);\n  };\n  (function () {\n    // Executing both pixelPosition & boxSizingReliable tests require only one layout\n    // so they\'re executed at the same time to save the second computation.\n    function computeStyleTests() {\n      // This is a singleton, we need to execute it only once\n      if (!div) {\n        return;\n      }\n      div.style.cssText = "box-sizing:border-box;" + "position:relative;display:block;" + "margin:auto;border:1px;padding:1px;" + "top:1%;width:50%";\n      div.innerHTML = "";\n      documentElement.appendChild(container);\n      var divStyle = window.getComputedStyle(div);\n      pixelPositionVal = divStyle.top !== "1%";
1\n\n      // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n      reliableMarginLeftVal = divStyle.marginLeft === "2px";\n      boxSizingReliableVal = divStyle.width === "4px";\n\n      // Support: Android 4.0 - 4.3 only\n      // Some styles come back with percentage values, even though they shouldn\'t\n      div.style.marginRight = "50%";\n      pixelMarginRightVal = divStyle.marginRight === "4px";\n      documentElement.removeChild(container);\n\n      // Nullify the div so it wouldn\'t be stored in the memory and\n      // it will also be a sign that checks already performed\n      div = null;\n    }\n    var pixelPositionVal,\n      boxSizingReliableVal,\n      pixelMarginRightVal,\n      reliableMarginLeftVal,\n      container = document.createElement("div"),\n      div = document.createElement("div");\n\n    // Finish early in limited (non-browser) environments\n    if (!div.style) {\n      return;\n    }\n\n    // Support: IE <=9 - 11 only\n    // Style of cloned element affects source element cloned (#8908)\n    div.style.backgroundClip = "content-box";\n    div.cloneNode(true).style.backgroundClip = "";\n    support.clearCloneStyle = div.style.backgroundClip === "content-box";\n    container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + "padding:0;margin-top:1px;position:absolute";\n    container.appendChild(div);\n    _jQuery2.extend(support, {\n      pixelPosition: function pixelPosition() {\n        computeStyleTests();\n        return pixelPositionVal;\n      },\n      boxSizingReliable: function boxSizingReliable() {\n        computeStyleTests();\n        return boxSizingReliableVal;\n      },\n      pixelMarginRight: function pixelMarginRight() {\n        computeStyleTests();\n        return pixelMarginRightVal;\n      },\n      reliableMarginLeft: function reliableMarginLeft() {\n        computeStyleTests();\n        return reliableMarginLeftVal;\n      }\n    });\n  })();\n  function curCSS(elem, name, computed) {\n    var width,\n      minWidth,\n      maxWidth,\n      ret,\n      // Support: Firefox 51+\n      // Retrieving style before computed somehow\n      // fixes an issue with getting wrong values\n      // on detached elements\n      style = elem.style;\n    computed = computed || getStyles(elem);\n\n    // getPropertyValue is needed for:\n    //   .css(\'filter\') (IE 9 only, #12537)\n    //   .css(\'--customProperty) (#3144)\n    if (computed) {\n      ret = computed.getPropertyValue(name) || computed[name];\n      if (ret === "" && !_jQuery2.contains(elem.ownerDocument, elem)) {\n        ret = _jQuery2.style(elem, name);\n      }\n\n      // A tribute to the "awesome hack by Dean Edwards"\n      // Android Browser returns percentage for some values,\n      // but width seems to be reliably pixels.\n      // This is against the CSSOM draft spec:\n      // https://drafts.csswg.org/cssom/#resolved-values\n      if (!support.pixelMarginRight() && rnumnonpx.test(ret) && rmargin.test(name)) {\
1n        // Remember the original values\n        width = style.width;\n        minWidth = style.minWidth;\n        maxWidth = style.maxWidth;\n\n        // Put in the new values to get a computed value out\n        style.minWidth = style.maxWidth = style.width = ret;\n        ret = computed.width;\n\n        // Revert the changed values\n        style.width = width;\n        style.minWidth = minWidth;\n        style.maxWidth = maxWidth;\n      }\n    }\n    return ret !== undefined ?\n    // Support: IE <=9 - 11 only\n    // IE returns zIndex value as an integer.\n    ret + "" : ret;\n  }\n  function addGetHookIf(conditionFn, hookFn) {\n    // Define the hook, we\'ll check on the first run if it\'s really needed.\n    return {\n      get: function get() {\n        if (conditionFn()) {\n          // Hook not needed (or it\'s not possible to use it due\n          // to missing dependency), remove it.\n          delete this.get;\n          return;\n        }\n\n        // Hook needed; redefine it so that the support test is not executed again.\n        return (this.get = hookFn).apply(this, arguments);\n      }\n    };\n  }\n  var\n    // Swappable if display is none or starts with table\n    // except "table", "table-cell", or "table-caption"\n    // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n    rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n    rcustomProp = /^--/,\n    cssShow = {\n      position: "absolute",\n      visibility: "hidden",\n      display: "block"\n    },\n    cssNormalTransform = {\n      letterSpacing: "0",\n      fontWeight: "400"\n    },\n    cssPrefixes = ["Webkit", "Moz", "ms"],\n    emptyStyle = document.createElement("div").style;\n\n  // Return a css property mapped to a potentially vendor prefixed property\n  function vendorPropName(name) {\n    // Shortcut for names that are not vendor prefixed\n    if (name in emptyStyle) {\n      return name;\n    }\n\n    // Check for vendor prefixed names\n    var capName = name[0].toUpperCase() + name.slice(1),\n      i = cssPrefixes.length;\n    while (i--) {\n      name = cssPrefixes[i] + capName;\n      if (name in emptyStyle) {\n        return name;\n      }\n    }\n  }\n\n  // Return a property mapped along what jQuery.cssProps suggests or to\n  // a vendor prefixed property.\n  function finalPropName(name) {\n    var ret = _jQuery2.cssProps[name];\n    if (!ret) {\n      ret = _jQuery2.cssProps[name] = vendorPropName(name) || name;\n    }\n    return ret;\n  }\n  function setPositiveNumber(elem, value, subtract) {\n    // Any relative (+/-) values have already been\n    // normalized at this point\n    var matches = rcssNum.exec(value);\n    return matches ?\n    // Guard against undefined "subtract", e.g., when used as in cssHooks\n    Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value;\n  }\n  function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {\n    var i,\n      val = 0;\n\n    // If we already have the right measurement, avoid augmentation\n    if (extra === (isBorderBox ? "border" : "content")) {\n      i = 4;\n\n      // Otherwise initialize for horizontal or vertical properties\n    } else {\n      i = name === "width" ? 1 : 0;\n    }\n    for (; i < 4; i += 2) {\n      // Both box models exclude margin, so add it if we want it\n      if (extra === "margin") {\n        val += _jQuery2.css(elem, extra + cssExpand[i], true, styles);\n      }\n      if (isBorderBox) {\n        // border-box includes padding, so remove it if we want content\n        if (extra === "content") {\n          val -= _jQuery2.css(elem, "padding" + cssExpand[i], true, styles);\n        }\n\n        // At this point, extra isn\'t border nor margin, so remove border\n        if (extra !== "margin") {\n          val -= _jQuery2.css(elem, "border" + cssExpand[i] + "Width", true, styles);\n        }\n      } else {\n        // At this point, extra isn\'t content, so add padding\n        val += _jQuery2.css(elem, "padding" + cssExpand[i], true, styles);\n\n        // At this point, extra isn\'t content nor padding, so add border\n        if (extra !== "padding") {\n          val += _jQuery2.css(elem, "border" + cssExpand[i] + "Width", true, styles);\n        }\n      }\n    }\n    return val;\n  }\n  function getWidthOrHeight(elem, name, extra) {\n    // Start with computed style\n    var valueIsBorderBox,\n      styles = getStyles(elem),\n      val = curCSS(elem, name, styles),\n      isBorderBox = _jQuery2.css(elem, "boxSizing", false, styles) === "border-box";\n\n    // Computed unit is not pixels. Stop here and return.\n    if (rnumnonpx.test(val)) {\n      return val;\n    }\n\n    // Check for style in case a browser which returns unreliable values\n    // for getComputedStyle silently falls back to the reliable elem.style\n    valueIsBorderBox = isBorderBox && (support.boxSizingReliable() || val === elem.style[name]);\n\n    // Fall back to offsetWidth/Height when value is "auto"\n    // This happens for inline elements with no explicit setting (gh-3571)\n    if (val === "auto") {\n      val = elem["offset" + name[0].toUpperCase() + name.slice(1)];\n    }\n\n    // Normalize "", auto, and prepare for extra\n    val = parseFloat(val) || 0;\n\n    // Use the active box-sizing model to add/subtract irrelevant styles\n    return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles) + "px";\n  }\n  _jQuery2.extend({\n    // Add in style property hooks for overriding the default\n    // behavior of getting and setting a style property\n    cssHooks: {\n      opacity: {\n        get: function get(elem, computed) {\
1n          if (computed) {\n            // We should always get a number back from opacity\n            var ret = curCSS(elem, "opacity");\n            return ret === "" ? "1" : ret;\n          }\n        }\n      }\n    },\n    // Don\'t automatically add "px" to these possibly-unitless properties\n    cssNumber: {\n      "animationIterationCount": true,\n      "columnCount": true,\n      "fillOpacity": true,\n      "flexGrow": true,\n      "flexShrink": true,\n      "fontWeight": true,\n      "lineHeight": true,\n      "opacity": true,\n      "order": true,\n      "orphans": true,\n      "widows": true,\n      "zIndex": true,\n      "zoom": true\n    },\n    // Add in properties whose names you wish to fix before\n    // setting or getting the value\n    cssProps: {\n      "float": "cssFloat"\n    },\n    // Get and set the style property on a DOM Node\n    style: function style(elem, name, value, extra) {\n      // Don\'t set styles on text and comment nodes\n      if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {\n        return;\n      }\n\n      // Make sure that we\'re working with the right name\n      var ret,\n        type,\n        hooks,\n        origName = _jQuery2.camelCase(name),\n        isCustomProp = rcustomProp.test(name),\n        style = elem.style;\n\n      // Make sure that we\'re working with the right name. We don\'t\n      // want to query the value if it is a CSS custom property\n      // since they are user-defined.\n      if (!isCustomProp) {\n        name = finalPropName(origName);\n      }\n\n      // Gets hook for the prefixed version, then unprefixed version\n      hooks = _jQuery2.cssHooks[name] || _jQuery2.cssHooks[origName];\n\n      // Check if we\'re setting a value\n      if (value !== undefined) {\n        type = _typeof(value);\n\n        // Convert "+=" or "-=" to relative numbers (#7345)\n        if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {\n          value = adjustCSS(elem, name, ret);\n\n          // Fixes bug #9237\n          type = "number";\n        }\n\n        // Make sure that null and NaN values aren\'t set (#7116)\n        if (value == null || value !== value) {\n          return;\n        }\n\n        // If a number was passed in, add the unit (except for certain CSS properties)\n        if (type === "number") {\n          value += ret && ret[3] || (_jQuery2.cssNumber[origName] ? "" : "px");\n        }\n\n        // background-* props affect original clone\'s values\n        if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {\n          style[name] = "inherit";\n        }\n\n        // If a hook was provided, use that value, otherwise just set the specified value\n        if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {\n          if (isCustomProp) {\n            style.setProperty(name, value);\n          } else {\n            style[name] = value;\n          }\n        }\n      } else {\n        // If a hook was provided get the non-computed value from there\n        if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {\n          return ret;\n        }\n\n        // Otherwise just get the value from the style object\n        return style[name];\n      }\n    },\n    css: function css(elem, name, extra, styles) {\n      var val,\n        num,\n        hooks,\n        origName = _jQuery2.camelCase(name),\n        isCustomProp = rcustomProp.test(name);\n\n      // Make sure that we\'re working with the right name. We don\'t\n      // want to modify the value if it is a CSS custom property\n      // since they are user-defined.\n      if (!isCustomProp) {\n        name = finalPropName(origName);\n      }\n\n      // Try prefixed name followed by the unprefixed name\n      hooks = _jQuery2.cssHooks[name] || _jQuery2.cssHooks[origName];\n\n      // If a hook was provided get the computed value from there\n      if (hooks && "get" in hooks) {\n        val = hooks.get(elem, true, extra);\n      }\n\n      // Otherwise, if a way to get the computed value exists, use that\n      if (val === undefined) {\n        val = curCSS(elem, name, styles);\n      }
1\n\n      // Convert "normal" to computed value\n      if (val === "normal" && name in cssNormalTransform) {\n        val = cssNormalTransform[name];\n      }\n\n      // Make numeric if forced or a qualifier was provided and val looks numeric\n      if (extra === "" || extra) {\n        num = parseFloat(val);\n        return extra === true || isFinite(num) ? num || 0 : val;\n      }\n      return val;\n    }\n  });\n  _jQuery2.each(["height", "width"], function (i, name) {\n    _jQuery2.cssHooks[name] = {\n      get: function get(elem, computed, extra) {\n        if (computed) {\n          // Certain elements can have dimension info if we invisibly show them\n          // but it must have a current display style that would benefit\n          return rdisplayswap.test(_jQuery2.css(elem, "display")) && (\n          // Support: Safari 8+\n          // Table columns in Safari have non-zero offsetWidth & zero\n          // getBoundingClientRect().width unless display is changed.\n          // Support: IE <=11 only\n          // Running getBoundingClientRect on a disconnected node\n          // in IE throws an error.\n          !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () {\n            return getWidthOrHeight(elem, name, extra);\n          }) : getWidthOrHeight(elem, name, extra);\n        }\n      },\n      set: function set(elem, value, extra) {\n        var matches,\n          styles = extra && getStyles(elem),\n          subtract = extra && augmentWidthOrHeight(elem, name, extra, _jQuery2.css(elem, "boxSizing", false, styles) === "border-box", styles);\n\n        // Convert to pixels if value adjustment is needed\n        if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") {\n          elem.style[name] = value;\n          value = _jQuery2.css(elem, name);\n        }\n        return setPositiveNumber(elem, value, subtract);\n      }\n    };\n  });\n  _jQuery2.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {\n    if (computed) {\n      return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, {\n        marginLeft: 0\n      }, function () {\n        return elem.getBoundingClientRect().left;\n      })) + "px";\n    }\n  });\n\n  // These hooks are used by animate to expand properties\n  _jQuery2.each({\n    margin: "",\n    padding: "",\n    border: "Width"\n  }, function (prefix, suffix) {\n    _jQuery2.cssHooks[prefix + suffix] = {\n      expand: function expand(value) {\n        var i = 0,\n          expanded = {},\n          // Assumes a single number if not a string\n          parts = typeof value === "string" ? value.split(" ") : [value];\n        for (; i < 4; i++) {\n          expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];\n        }\n        return expanded;\n      }\n    };\n    if (!rmargin.test(prefix)) {\n      _jQuery2.cssHooks[prefix + suffix].set = setPositiveNumber;\n    }\n  });\n  _jQuery2.fn.extend({\n    css: function css(name, value) {\n      return _access(this, function (elem, name, value) {\n        var styles,\n          len,\n          map = {},\n          i = 0;\n        if (Array.isArray(name)) {\n          styles = getStyles(elem);\n          len = name.length;\n          for (; i < len; i++) {\n            map[name[i]] = _jQuery2.css(elem, name[i], false, styles);\n          }\n          return map;\n        }\n        return value !== undefined ? _jQuery2.style(elem, name, value) : _jQuery2.css(elem, name);\n      }, name, value, arguments.length > 1);\n    }\n  });\n  function Tween(elem, options, prop, end, easing) {\n    return new Tween.prototype.init(elem, options, prop, end, easing);\n  }\n  _jQuery2.Tween = Tween;\n  Tween.prototype = {\n    constructor: Tween,\n    init: function init(elem, options, prop, end, easing, unit) {\n      this.elem = elem;\n      this.prop = prop;\n      this.easing = easing || _jQuery2.easing._default;\n      this.options = options;\n      this.start = this.now = this.cur();\n      this.end = end;\n      this.unit = unit || (_jQuery2.cssNumber[prop] ? "" : "px");\n    },\n    cur: function cur() {\n      var hooks = Tween.propHooks[this.prop];\n      return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);\n    },\n    run: function run(percent) {\n      var eased,\n        hooks = Tween.propHooks[this.prop];\n      if (this.options.duration) {\n        this.pos = eased = _jQuery2.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);\n      } else {\n        this.pos = eased = percent;\n      }
1\n      this.now = (this.end - this.start) * eased + this.start;\n      if (this.options.step) {\n        this.options.step.call(this.elem, this.now, this);\n      }\n      if (hooks && hooks.set) {\n        hooks.set(this);\n      } else {\n        Tween.propHooks._default.set(this);\n      }\n      return this;\n    }\n  };\n  Tween.prototype.init.prototype = Tween.prototype;\n  Tween.propHooks = {\n    _default: {\n      get: function get(tween) {\n        var result;\n\n        // Use a property on the element directly when it is not a DOM element,\n        // or when there is no matching style property that exists.\n        if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {\n          return tween.elem[tween.prop];\n        }\n\n        // Passing an empty string as a 3rd parameter to .css will automatically\n        // attempt a parseFloat and fallback to a string if the parse fails.\n        // Simple values such as "10px" are parsed to Float;\n        // complex values such as "rotate(1rad)" are returned as-is.\n        result = _jQuery2.css(tween.elem, tween.prop, "");\n\n        // Empty strings, null, undefined and "auto" are converted to 0.\n        return !result || result === "auto" ? 0 : result;\n      },\n      set: function set(tween) {\n        // Use step hook for back compat.\n        // Use cssHook if its there.\n        // Use .style if available and use plain properties where available.\n        if (_jQuery2.fx.step[tween.prop]) {\n          _jQuery2.fx.step[tween.prop](tween);\n        } else if (tween.elem.nodeType === 1 && (tween.elem.style[_jQuery2.cssProps[tween.prop]] != null || _jQuery2.cssHooks[tween.prop])) {\n          _jQuery2.style(tween.elem, tween.prop, tween.now + tween.unit);\n        } else {\n          tween.elem[tween.prop] = tween.now;\n        }\n      }\n    }\n  };\n\n  // Support: IE <=9 only\n  // Panic based approach to setting things on disconnected nodes\n  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n    set: function set(tween) {\n      if (tween.elem.nodeType && tween.elem.parentNode) {\n        tween.elem[tween.prop] = tween.now;\n      }\n    }\n  };\n  _jQuery2.easing = {\n    linear: function linear(p) {\n      return p;\n    },\n    swing: function swing(p) {\n      return 0.5 - Math.cos(p * Math.PI) / 2;\n    },\n    _default: "swing"\n  };\n  _jQuery2.fx = Tween.prototype.init;\n\n  // Back compat <1.8 extension point\n  _jQuery2.fx.step = {};\n  var fxNow,\n    inProgress,\n    rfxtypes = /^(?:toggle|show|hide)$/,\n    rrun = /queueHooks$/;\n  function schedule() {\n    if (inProgress) {\n      if (document.hidden === false && window.requestAnimationFrame) {\n        window.requestAnimationFrame(schedule);\n      } else {\n        window.setTimeout(schedule, _jQuery2.fx.interval);\n      }\n      _jQuery2.fx.tick();\n    }\n  }\n\n  // Animations created synchronously will run synchronously\n  function createFxNow() {\n    window.setTimeout(function () {\n      fxNow = undefined;\n    });\n    return fxNow = _jQuery2.now();\n  }\n\n  // Generate parameters to create a standard animation\n  function genFx(type, includeWidth) {\n    var which,\n      i = 0,\n      attrs = {\n        height: type\n      };\n\n    // If we include width, step value is 1 to do all cssExpand values,\n    // otherwise step value is 2 to skip over Left and Right\n    includeWidth = includeWidth ? 1 : 0;\n    for (; i < 4; i += 2 - includeWidth) {\n      which = cssExpand[i];\n      attrs["margin" + which] = attrs["padding" + which] = type;\n    }\n    if (includeWidth) {\n      attrs.opacity = attrs.width = type;\n    }\n    return attrs;\n  }\n  function createTween(value, prop, animation) {\n    var tween,\n      collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),\n      index = 0,\n      length = collection.length;\n    for (; index < length; index++) {\n      if (tween = collection[index].call(animation, prop, value)) {\n        // We\'re done with this property\n        return tween;\n      }\n    }\n  }\n  function defaultPrefilter(elem, props, opts) {\n    var prop,\n      value,\n      toggle,\n      hooks,\n      oldfire,\n      propTween,\n      restoreDisplay,\n      display,\n      isBox = "width" in props || "height" in props,\n      anim = this,\n      orig = {},\n      style = elem.style,\n      hidden = elem.nodeType && isHiddenWithinTree(elem),\n      dataShow = dataPriv.get(elem, "fxshow");\n\n    // Queue-skipping animations hijack the fx hooks\n    if (!opts.queue) {\n      hooks = _jQuery2._queueHooks(elem, "fx");\n      if (hooks.unqueued == null) {\n        hooks.unqueued = 0;\n        oldfire = hooks.empty.fire;\n        hooks.empty.fire = function () {\n          if (!hooks.unqueued) {\n            oldfire();\n          }\n        };\n      }\n      hooks.unqueued++;\n      anim.always(function () {\n        // Ensure the complete handler is called before this completes\n        anim.always(function () {\n          hooks.unqueued--;\n          if (!_jQuery2.queue(elem, "fx").length) {\n            hooks.empty.fire();\n          }\n        });\n      });\n    }\n\n    // Detect show/hide animations\n    for (prop in props) {\n      value = props[prop];\n      if (rfxtypes.test(value)) {\n        delete props[prop];\n        toggle = toggle || value === "toggle";\n        if (value === (hidden ? "hide" : "show")) {\n          // Pretend to be hidden if this is a "show" and\n          // there is still data from a stopped show/hide\n          if (value === "show" && dataShow && dataShow[prop] !== undefined) {\n            hidden = true;\n\n            // Ignore all other no-op show/hide data\n          } else {\n            continue;\n          }\n        }\n        orig[prop] = dataShow && dataShow[prop] || _jQuery2.style(elem, prop);\n      }\n    }\n\n    // Bail out if this is a no-op like .hide().hide()\n    propTween = !_jQuery2.isEmptyObject(props);
1\n    if (!propTween && _jQuery2.isEmptyObject(orig)) {\n      return;\n    }\n\n    // Restrict "overflow" and "display" styles during box animations\n    if (isBox && elem.nodeType === 1) {\n      // Support: IE <=9 - 11, Edge 12 - 13\n      // Record all 3 overflow attributes because IE does not infer the shorthand\n      // from identically-valued overflowX and overflowY\n      opts.overflow = [style.overflow, style.overflowX, style.overflowY];\n\n      // Identify a display type, preferring old show/hide data over the CSS cascade\n      restoreDisplay = dataShow && dataShow.display;\n      if (restoreDisplay == null) {\n        restoreDisplay = dataPriv.get(elem, "display");\n      }\n      display = _jQuery2.css(elem, "display");\n      if (display === "none") {\n        if (restoreDisplay) {\n          display = restoreDisplay;\n        } else {\n          // Get nonempty value(s) by temporarily forcing visibility\n          showHide([elem], true);\n          restoreDisplay = elem.style.display || restoreDisplay;\n          display = _jQuery2.css(elem, "display");\n          showHide([elem]);\n        }\n      }\n\n      // Animate inline elements as inline-block\n      if (display === "inline" || display === "inline-block" && restoreDisplay != null) {\n        if (_jQuery2.css(elem, "float") === "none") {\n          // Restore the original display value at the end of pure show/hide animations\n          if (!propTween) {\n            anim.done(function () {\n              style.display = restoreDisplay;\n            });\n            if (restoreDisplay == null) {\n              display = style.display;\n              restoreDisplay = display === "none" ? "" : display;\n            }\n          }\n          style.display = "inline-block";\n        }\n      }\n    }\n    if (opts.overflow) {\n      style.overflow = "hidden";\n      anim.always(function () {\n        style.overflow = opts.overflow[0];\n        style.overflowX = opts.overflow[1];\n        style.overflowY = opts.overflow[2];\n      });\n    }\n\n    // Implement show/hide animations\n    propTween = false;\n    for (prop in orig) {\n      // General show/hide setup for this element animation\n      if (!propTween) {\n        if (dataShow) {\n          if ("hidden" in dataShow) {\n            hidden = dataShow.hidden;\n          }\n        } else {\n          dataShow = dataPriv.access(elem, "fxshow", {\n            display: restoreDisplay\n          });\n        }\n\n        // Store hidden/visible for toggle so `.stop().toggle()` "reverses"\n        if (toggle) {\n          dataShow.hidden = !hidden;\n        }\n\n        // Show elements before animating them\n        if (hidden) {\n          showHide([elem], true);\n        }\n\n        /* eslint-disable no-loop-func */\n\n        anim.done(function () {\n          /* eslint-enable no-loop-func */\n\n          // The final step of a "hide" animation is actually hiding the element\n          if (!hidden) {\n            showHide([elem]);\n          }\n          dataPriv.remove(elem, "fxshow");\n          for (prop in orig) {\n            _jQuery2.style(elem, prop, orig[prop]);\n          }\n        });\n      }\n\n      // Per-property setup\n      propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);\n      if (!(prop in dataShow)) {\n        dataShow[prop] = propTween.start;\n        if (hidden) {\n          propTween.end = propTween.start;\n          propTween.start = 0;\n        }\n      }\n    }\n  }\n  function propFilter(props, specialEasing) {\n    var index, name, easing, value, hooks;\n\n    // camelCase, specialEasing and expand cssHook pass\n    for (index in props) {\n      name = _jQuery2.camelCase(index);
1\n      easing = specialEasing[name];\n      value = props[index];\n      if (Array.isArray(value)) {\n        easing = value[1];\n        value = props[index] = value[0];\n      }\n      if (index !== name) {\n        props[name] = value;\n        delete props[index];\n      }\n      hooks = _jQuery2.cssHooks[name];\n      if (hooks && "expand" in hooks) {\n        value = hooks.expand(value);\n        delete props[name];\n\n        // Not quite $.extend, this won\'t overwrite existing keys.\n        // Reusing \'index\' because we have the correct "name"\n        for (index in value) {\n          if (!(index in props)) {\n            props[index] = value[index];\n            specialEasing[index] = easing;\n          }\n        }\n      } else {\n        specialEasing[name] = easing;\n      }\n    }\n  }\n  function Animation(elem, properties, options) {\n    var result,\n      stopped,\n      index = 0,\n      length = Animation.prefilters.length,\n      deferred = _jQuery2.Deferred().always(function () {\n        // Don\'t match elem in the :animated selector\n        delete tick.elem;\n      }),\n      tick = function tick() {\n        if (stopped) {\n          return false;\n        }\n        var currentTime = fxNow || createFxNow(),\n          remaining = Math.max(0, animation.startTime + animation.duration - currentTime),\n          // Support: Android 2.3 only\n          // Archaic crash bug won\'t allow us to use `1 - ( 0.5 || 0 )` (#12497)\n          temp = remaining / animation.duration || 0,\n          percent = 1 - temp,\n          index = 0,\n          length = animation.tweens.length;\n        for (; index < length; index++) {\n          animation.tweens[index].run(percent);\n        }\n        deferred.notifyWith(elem, [animation, percent, remaining]);\n\n        // If there\'s more to do, yield\n        if (percent < 1 && length) {\n          return remaining;\n        }\n\n        // If this was an empty animation, synthesize a final progress notification\n        if (!length) {\n          deferred.notifyWith(elem, [animation, 1, 0]);\n        }\n\n        // Resolve the animation and report its conclusion\n        deferred.resolveWith(elem, [animation]);\n        return false;\n      },\n      animation = deferred.promise({\n        elem: elem,\n        props: _jQuery2.extend({}, properties),\n        opts: _jQuery2.extend(true, {\n          specialEasing: {},\n          easing: _jQuery2.easing._default\n        }, options),\n        originalProperties: properties,\n        originalOptions: options,\n        startTime: fxNow || createFxNow(),\n        duration: options.duration,\n        tweens: [],\n        createTween: function createTween(prop, end) {\n          var tween = _jQuery2.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);\n          animation.tweens.push(tween);\n          return tween;\n        },\n        stop: function stop(gotoEnd) {\n          var index = 0,\n            // If we are going to the end, we want to run all the tweens\n            // otherwise we skip this part\n            length = gotoEnd ? animation.tweens.length : 0;\n          if (stopped) {\n            return this;\n          }\n          stopped = true;\n          for (; index < length; index++) {\n            animation.tweens[index].run(1);\n          }\n\n          // Resolve when we played the last frame; otherwise, reject\n          if (gotoEnd) {\n            deferred.notifyWith(elem, [animation, 1, 0]);\n            deferred.resolveWith(elem, [animation, gotoEnd]);\n          } else {\n            deferred.rejectWith(elem, [animation, gotoEnd]);\n          }\n          return this;\n        }\n      }),\n      props = animation.props;\n    propFilter(props, animation.opts.specialEasing);\n    for (; index < length; index++) {\n      result = Animation.prefilters[index].call(animation, elem, props, animation.opts);\n      if (result) {\n        if (_jQuery2.isFunction(result.stop)) {\n          _jQuery2._queueHooks(animation.elem, animation.opts.queue).stop = _jQuery2.proxy(result.stop, result);\n        }\n        return result;\n      }\n    }\n    _jQuery2.map(props, createTween, animation);\n    if (_jQuery2.isFunction(animation.opts.start)) {\n      animation.opts.start.call(elem, animation);\n    }\n\n    // Attach callbacks from options\n    animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);\n    _jQuery2.fx.timer(_jQuery2.extend(tick, {\n      elem: elem,\n      anim: animation,\n      queue: animation.opts.queue\n    }));\n    return animation;\n  }\n  _jQuery2.Animation = _jQuery2.extend(Animation, {\n    tweeners: {\n      "*": [function (prop, value) {\n        var tween = this.createTween(prop, value);\n        adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);\n        return tween;\n      }]\n    },\n    tweener: function tweener(props, callback) {\n      if (_jQuery2.isFunction(props)) {\n        callback = props;\n        props = ["*"];\n      } else {\n        props = props.match(rnothtmlwhite);\n      }\n      var prop,\n        index = 0,\n        length = props.length;\n      for (; index < length; index++) {\n        prop = props[index];\n        Animation.tweeners[prop] = Animation.tweeners[prop] || [];\n        Animation.tweeners[prop].unshift(callback);\n      }\n    },\n    prefilters: [defaultPrefilter],\n    prefilter: function prefilter(callback, prepend) {\n      if (prepend) {\n        Animation.prefilters.unshift(callback);\n      } else {\n        Animation.prefilters.push(callback);\n      }\n    }\n  });\n  _jQuery2.speed = function (speed, easing, fn) {\n    var opt = speed && _typeof(speed) === "object" ? _jQuery2.extend({}, speed) : {\n      complete: fn || !fn && easing || _jQuery2.isFunction(speed) && speed,\n      duration: speed,\n      easing: fn && easing || easing && !_jQuery2.isFunction(easing) && easing\n    };\n\n    // Go to the end state if fx are off\n    if (_jQuery2.fx.off) {\n      opt.duration = 0;\n    } else {\n      if (typeof opt.duration !== "number") {\n        if (opt.duration in _jQuery2.fx.speeds) {\n          opt.duration = _jQuery2.fx.speeds[opt.duration];\n        } else {\n          opt.duration = _jQuery2.fx.speeds._default;\n        }\n      }\n    }\n\n    // Normalize opt.queue - true/undefined/null -> "fx"\n    if (opt.queue == null || opt.queue === true) {\n      opt.queue = "fx";\n    }
1\n\n    // Queueing\n    opt.old = opt.complete;\n    opt.complete = function () {\n      if (_jQuery2.isFunction(opt.old)) {\n        opt.old.call(this);\n      }\n      if (opt.queue) {\n        _jQuery2.dequeue(this, opt.queue);\n      }\n    };\n    return opt;\n  };\n  _jQuery2.fn.extend({\n    fadeTo: function fadeTo(speed, to, easing, callback) {\n      // Show any hidden elements after setting opacity to 0\n      return this.filter(isHiddenWithinTree).css("opacity", 0).show()\n\n      // Animate to the value specified\n      .end().animate({\n        opacity: to\n      }, speed, easing, callback);\n    },\n    animate: function animate(prop, speed, easing, callback) {\n      var empty = _jQuery2.isEmptyObject(prop),\n        optall = _jQuery2.speed(speed, easing, callback),\n        doAnimation = function doAnimation() {\n          // Operate on a copy of prop so per-property easing won\'t be lost\n          var anim = Animation(this, _jQuery2.extend({}, prop), optall);\n\n          // Empty animations, or finishing resolves immediately\n          if (empty || dataPriv.get(this, "finish")) {\n            anim.stop(true);\n          }\n        };\n      doAnimation.finish = doAnimation;\n      return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);\n    },\n    stop: function stop(type, clearQueue, gotoEnd) {\n      var stopQueue = function stopQueue(hooks) {\n        var stop = hooks.stop;\n        delete hooks.stop;\n        stop(gotoEnd);\n      };\n      if (typeof type !== "string") {\n        gotoEnd = clearQueue;\n        clearQueue = type;\n        type = undefined;\n      }\n      if (clearQueue && type !== false) {\n        this.queue(type || "fx", []);\n      }\n      return this.each(function () {\n        var dequeue = true,\n          index = type != null && type + "queueHooks",\n          timers = _jQuery2.timers,\n          data = dataPriv.get(this);\n        if (index) {\n          if (data[index] && data[index].stop) {\n            stopQueue(data[index]);\n          }\n        } else {\n          for (index in data) {\n            if (data[index] && data[index].stop && rrun.test(index)) {\n              stopQueue(data[index]);\n            }\n          }\n        }\n        for (index = timers.length; index--;) {\n          if (timers[index].elem === this && (type == null || timers[index].queue === type)) {\n            timers[index].anim.stop(gotoEnd);\n            dequeue = false;\n            timers.splice(index, 1);\n          }\n        }\n\n        // Start the next in the queue if the last step wasn\'t forced.\n        // Timers currently will call their complete callbacks, which\n        // will dequeue but only if they were gotoEnd.\n        if (dequeue || !gotoEnd) {\n          _jQuery2.dequeue(this, type);\n        }\n      });\n    },\n    finish: function finish(type) {\n      if (type !== false) {\n        type = type || "fx";\n      }\n      return this.each(function () {\n        var index,\n          data = dataPriv.get(this),\n          queue = data[type + "queue"],\n          hooks = data[type + "queueHooks"],\n          timers = _jQuery2.timers,\n          length = queue ? queue.length : 0;\n\n        // Enable finishing flag on private data\n        data.finish = true;\n\n        // Empty the queue first\n        _jQuery2.queue(this, type, []);\n        if (hooks && hooks.stop) {\n          hooks.stop.call(this, true);\n        }\n\n        // Look for any active animations, and finish them\n        for (index = timers.length; index--;) {\n          if (timers[index].elem === this && timers[index].queue === type) {\n            timers[index].anim.stop(true);\n            timers.splice(index, 1);\n          }\n        }\n\n        // Look for any animations in the old queue and finish them\n        for (index = 0; index < length; index++) {\n          if (queue[index] && queue[index].finish) {\n            queue[index].finish.call(this);\n          }\n        }\n\n        // Turn off finishing flag\n        delete data.finish;\n      });\n    }\n  });\n  _jQuery2.each(["toggle", "show", "hide"], function (i, name) {\n    var cssFn = _jQuery2.fn[name];\n    _jQuery2.fn[name] = function (speed, easing, callback) {\n      return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);\n    };\n  });\n\n  // Generate shortcuts for custom animations\n  _jQuery2.each({\n    slideDown: genFx("show"),\n    slideUp: genFx("hide"),\n    slideToggle: genFx("toggle"),\n    fadeIn: {\n      opacity: "show"\n    },\n    fadeOut: {\n      opacity: "hide"\n    },\n    fadeToggle: {\n      opacity: "toggle"\n    }\n  }, function (name, props) {\n    _jQuery2.fn[name] = function (speed, easing, callback) {\n      return this.animate(props, speed, easing, callback);\n    };\n  });\n  _jQuery2.timers = [];\n  _jQuery2.fx.tick = function () {\n    var timer,\n      i = 0,\n      timers = _jQuery2.timers;\n    fxNow = _jQuery2.now();\n    for (; i < timers.length;
1 i++) {\n      timer = timers[i];\n\n      // Run the timer and safely remove it when done (allowing for external removal)\n      if (!timer() && timers[i] === timer) {\n        timers.splice(i--, 1);\n      }\n    }\n    if (!timers.length) {\n      _jQuery2.fx.stop();\n    }\n    fxNow = undefined;\n  };\n  _jQuery2.fx.timer = function (timer) {\n    _jQuery2.timers.push(timer);\n    _jQuery2.fx.start();\n  };\n  _jQuery2.fx.interval = 13;\n  _jQuery2.fx.start = function () {\n    if (inProgress) {\n      return;\n    }\n    inProgress = true;\n    schedule();\n  };\n  _jQuery2.fx.stop = function () {\n    inProgress = null;\n  };\n  _jQuery2.fx.speeds = {\n    slow: 600,\n    fast: 200,\n    // Default speed\n    _default: 400\n  };\n\n  // Based off of the plugin by Clint Helfers, with permission.\n  // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\n  _jQuery2.fn.delay = function (time, type) {\n    time = _jQuery2.fx ? _jQuery2.fx.speeds[time] || time : time;\n    type = type || "fx";\n    return this.queue(type, function (next, hooks) {\n      var timeout = window.setTimeout(next, time);\n      hooks.stop = function () {\n        window.clearTimeout(timeout);\n      };\n    });\n  };\n  (function () {\n    var input = document.createElement("input"),\n      select = document.createElement("select"),\n      opt = select.appendChild(document.createElement("option"));\n    input.type = "checkbox";\n\n    // Support: Android <=4.3 only\n    // Default value for a checkbox should be "on"\n    support.checkOn = input.value !== "";\n\n    // Support: IE <=11 only\n    // Must access selectedIndex to make default options select\n    support.optSelected = opt.selected;\n\n    // Support: IE <=11 only\n    // An input loses its value after becoming a radio\n    input = document.createElement("input");\n    input.value = "t";\n    input.type = "radio";\n    support.radioValue = input.value === "t";\n  })();\n  var boolHook,\n    attrHandle = _jQuery2.expr.attrHandle;\n  _jQuery2.fn.extend({\n    attr: function attr(name, value) {\n      return _access(this, _jQuery2.attr, name, value, arguments.length > 1);\n    },\n    removeAttr: function removeAttr(name) {\n      return this.each(function () {\n        _jQuery2.removeAttr(this, name);\n      });\n    }\n  });\n  _jQuery2.extend({\n    attr: function attr(elem, name, value) {\n      var ret,\n        hooks,\n        nType = elem.nodeType;\n\n      // Don\'t get/set attributes on text, comment and attribute nodes\n      if (nType === 3 || nType === 8 || nType === 2) {\n        return;\n      }\n\n      // Fallback to prop when attributes are not supported\n      if (typeof elem.getAttribute === "undefined") {\n        return _jQuery2.prop(elem, name, value);\n      }\n\n      // Attribute hooks are determined by the lowercase version\n      // Grab necessary hook if one is defined\n      if (nType !== 1 || !_jQuery2.isXMLDoc(elem)) {\n        hooks = _jQuery2.attrHooks[name.toLowerCase()] || (_jQuery2.expr.match.bool.test(name) ? boolHook : undefined);\n      }\n      if (value !== undefined) {\n        if (value === null) {\n          _jQuery2.removeAttr(elem, name);\n          return;\n        }\n        if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {\n          return ret;\n        }\n        elem.setAttribute(name, value + "");\n        return value;\n      }\n      if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {\n        return ret;\n      }\n      ret = _jQuery2.find.attr(elem, name);\n\n      // Non-existent attributes return null, we normalize to undefined\n      return ret == null ? undefined : ret;\n    },\n    attrHooks: {\n      type: {\n        set: function set(elem, value) {\n          if (!support.radioValue && value === "radio" && nodeName(elem, "input")) {\n            var val = elem.value;\n            elem.setAttribute("type", value);\n            if (val) {\n              elem.value = val;\n            }\n            return value;\n          }\n        }\n      }\n    },\n    removeAttr: function removeAttr(elem, value) {\n      var name,\n        i = 0,\n        // Attribute names can contain non-HTML whitespace characters\n        // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n        attrNames = value && value.match(rnothtmlwhite);\n      if (attrNames && elem.nodeType === 1) {\n        while (name = attrNames[i++]) {\n          elem.removeAttribute(name);\n        }\n      }\n    }\n  });\n\n  // Hooks for boolean attributes\n  boolHook = {\n    set: function set(elem, value, name) {\n      if (value === false) {\n        // Remove boolean attributes when set to false\n        _jQuery2.removeAttr(elem, name);\n      } else {\n        elem.setAttribute(name, name);\n      }\n      return name;\n    }\n  };\n  _jQuery2.each(_jQuery2.expr.match.bool.source.match(/\\w+/g), function (i, name) {\n    var getter = attrHandle[name] || _jQuery2.find.attr;\n    attrHandle[name] = function (elem, name, isXML) {\n      var ret,\n        handle,\n        lowercaseName = name.toLowerCase();\n      if (!isXML) {\n        // Avoid an infinite loop by temporarily removing this function from the getter\n        handle = attrHandle[lowercaseName];\n        attrHandle[lowercaseName] = ret;\n        ret = getter(elem, name, isXML) != null ? lowercaseName : null;\n        attrHandle[lowercaseName] = handle;\n      }\n      return ret;\n    };\n  });\n  var rfocusable = /^(?:input|select|textarea|button)$/i,\n    rclickable = /^(?:a|area)$/i;\n  _jQuery2.fn.extend({\n    prop: function prop(name, value) {\n      return _access(this, _jQuery2.prop, name, value, arguments.length > 1);\n    },\n    removeProp: function removeProp(name) {\n      return this.each(function () {\n        delete this[_jQuery2.propFix[name] || name];\n      });\n    }\n  });\n  _jQuery2.extend({\n    prop: function prop(elem, name, value) {\n      var ret,\n        hooks,\n        nType = elem.nodeType;\n\n      // Don\'t get/set properties on text, comment and attribute nodes\n      if (nType === 3 || nType === 8 || nType === 2) {\n        return;\n      }\n      if (nType !== 1 || !_jQuery2.isXMLDoc(elem)) {\n        // Fix name and attach hooks\n        name = _jQuery2.propFix[name] || name;\n        hooks = _jQuery2.propHooks[name];\n      }\n      if (value !== undefined) {\n        if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {\n          return ret;\n        }\n        return elem[name] = value;\n      }\n      if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {\n        return ret;\n      }\n      return elem[name];\n    },\n    propHooks: {\n      tabIndex: {\n        get: function get(elem) {\n          // Supp
1ort: IE <=9 - 11 only\n          // elem.tabIndex doesn\'t always return the\n          // correct value when it hasn\'t been explicitly set\n          // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n          // Use proper attribute retrieval(#12072)\n          var tabindex = _jQuery2.find.attr(elem, "tabindex");\n          if (tabindex) {\n            return parseInt(tabindex, 10);\n          }\n          if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) {\n            return 0;\n          }\n          return -1;\n        }\n      }\n    },\n    propFix: {\n      "for": "htmlFor",\n      "class": "className"\n    }\n  });\n\n  // Support: IE <=11 only\n  // Accessing the selectedIndex property\n  // forces the browser to respect setting selected\n  // on the option\n  // The getter ensures a default option is selected\n  // when in an optgroup\n  // eslint rule "no-unused-expressions" is disabled for this code\n  // since it considers such accessions noop\n  if (!support.optSelected) {\n    _jQuery2.propHooks.selected = {\n      get: function get(elem) {\n        /* eslint no-unused-expressions: "off" */\n\n        var parent = elem.parentNode;\n        if (parent && parent.parentNode) {\n          parent.parentNode.selectedIndex;\n        }\n        return null;\n      },\n      set: function set(elem) {\n        /* eslint no-unused-expressions: "off" */\n\n        var parent = elem.parentNode;\n        if (parent) {\n          parent.selectedIndex;\n          if (parent.parentNode) {\n            parent.parentNode.selectedIndex;\n          }\n        }\n      }\n    };\n  }\n  _jQuery2.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {\n    _jQuery2.propFix[this.toLowerCase()] = this;\n  });\n\n  // Strip and collapse whitespace according to HTML spec\n  // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace\n  function stripAndCollapse(value) {\n    var tokens = value.match(rnothtmlwhite) || [];\n    return tokens.join(" ");\n  }\n  function getClass(elem) {\n    return elem.getAttribute && elem.getAttribute("class") || "";\n  }\n  _jQuery2.fn.extend({\n    addClass: function addClass(value) {\n      var classes,\n        elem,\n        cur,\n        curValue,\n        clazz,\n        j,\n        finalValue,\n        i = 0;\n      if (_jQuery2.isFunction(value)) {\n        return this.each(function (j) {\n          _jQuery2(this).addClass(value.call(this, j, getClass(this)));\n        });\n      }\n      if (typeof value === "string" && value) {\n        classes = value.match(rnothtmlwhite) || [];\n        while (elem = this[i++]) {\n          curValue = getClass(elem);\n          cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";\n          if (cur) {\n            j = 0;\n            while (clazz = classes[j++]) {\n              if (cur.indexOf(" " + clazz + " ") < 0) {\n                cur += clazz + " ";\n              }\n            }\n\n            // Only assign if different to avoid unneeded rendering.\n            finalValue = stripAndCollapse(cur);\n            if (curValue !== finalValue) {\n              elem.setAttribute("class", finalValue);\n            }\n          }\n        }\n      }\n      return this;\n    },\n    removeClass: function removeClass(value) {\n      var classes,\n        elem,\n        cur,\n        curValue,\n        clazz,\n        j,\n        finalValue,\n        i = 0;\n      if (_jQuery2.isFunction(value)) {\n        return this.each(function (j) {\n          _jQuery2(this).removeClass(value.call(this, j, getClass(this)));\n        });\n      }\n      if (!arguments.length) {\n        return this.attr("class", "");\n      }\n      if (typeof value === "string" && value) {\n        classes = value.match(rnothtmlwhite) || [];\n        while (elem = this[i++]) {\n          curValue = getClass(elem);\n\n          // This expression is here for better compressibility (see addClass)\n          cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";\n          if (cur) {\n            j = 0;\n            while (clazz = classes[j++]) {\n              // Remove *all* 
1instances\n              while (cur.indexOf(" " + clazz + " ") > -1) {\n                cur = cur.replace(" " + clazz + " ", " ");\n              }\n            }\n\n            // Only assign if different to avoid unneeded rendering.\n            finalValue = stripAndCollapse(cur);\n            if (curValue !== finalValue) {\n              elem.setAttribute("class", finalValue);\n            }\n          }\n        }\n      }\n      return this;\n    },\n    toggleClass: function toggleClass(value, stateVal) {\n      var type = _typeof(value);\n      if (typeof stateVal === "boolean" && type === "string") {\n        return stateVal ? this.addClass(value) : this.removeClass(value);\n      }\n      if (_jQuery2.isFunction(value)) {\n        return this.each(function (i) {\n          _jQuery2(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);\n        });\n      }\n      return this.each(function () {\n        var className, i, self, classNames;\n        if (type === "string") {\n          // Toggle individual class names\n          i = 0;\n          self = _jQuery2(this);\n          classNames = value.match(rnothtmlwhite) || [];\n          while (className = classNames[i++]) {\n            // Check each className given, space separated list\n            if (self.hasClass(className)) {\n              self.removeClass(className);\n            } else {\n              self.addClass(className);\n            }\n          }\n\n          // Toggle whole class name\n        } else if (value === undefined || type === "boolean") {\n          className = getClass(this);\n          if (className) {\n            // Store className if set\n            dataPriv.set(this, "__className__", className);\n          }\n\n          // If the element has a class name or if we\'re passed `false`,\n          // then remove the whole classname (if there was one, the above saved it).\n          // Otherwise bring back whatever was previously saved (if anything),\n          // falling back to the empty string if nothing was stored.\n          if (this.setAttribute) {\n            this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || "");\n          }\n        }\n      });\n    },\n    hasClass: function hasClass(selector) {\n      var className,\n        elem,\n        i = 0;\n      className = " " + selector + " ";\n      while (elem = this[i++]) {\n        if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {\n          return true;\n        }\n      }\n      return false;\n    }\n  });\n  var rreturn = /\\r/g;\n  _jQuery2.fn.extend({\n    val: function val(value) {\n      var hooks,\n        ret,\n        isFunction,\n        elem = this[0];\n      if (!arguments.length) {\n        if (elem) {\n          hooks = _jQuery2.valHooks[elem.type] || _jQuery2.valHooks[elem.nodeName.toLowerCase()];\n          if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {\n            return ret;\n          }\n          ret = elem.value;\n\n          // Handle most common string cases\n          if (typeof ret === "string") {\n            return ret.replace(rreturn, "");\n          }\n\n          // Handle cases where value is null/undef or number\n          return ret == null ? "" : ret;\n        }\n        return;\n      }\n      isFunction = _jQuery2.isFunction(value);\n      return this.each(function (i) {\n        var val;\n        if (this.nodeType !== 1) {\n          return;\n        }\n        if (isFunction) {\n          val = value.call(this, i, _jQuery2(this).val());\n        } else {\n          val = value;\n        }\n\n        // Treat null/undefined as ""; convert numbers to string\n        if (val == null) {\n          val = "";\n        } else if (typeof val === "number") {\n          val += "";\n        } else if (Array.isArray(val)) {\n          val = _jQuery2.map(val, function (value) {\n            return value == null ? "" : value + "";\n          });\n        }\n        hooks = _jQuery2.valHooks[this.type] || _jQuery2.valHooks[this.nodeName.toLowerCase()];\n\n        // If set returns undefined, fall back to normal setting\n        if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {\n          this.value = val;\n        }\n      });\n    }\n  });\n  _jQuery2.extend({\n    valHooks: {\n      option: {\n        get: function get(elem) {\n          var val = _jQuery2.find.attr(elem, "value");
1\n          return val != null ? val :\n          // Support: IE <=10 - 11 only\n          // option.text throws exceptions (#14686, #14858)\n          // Strip and collapse whitespace\n          // https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n          stripAndCollapse(_jQuery2.text(elem));\n        }\n      },\n      select: {\n        get: function get(elem) {\n          var value,\n            option,\n            i,\n            options = elem.options,\n            index = elem.selectedIndex,\n            one = elem.type === "select-one",\n            values = one ? null : [],\n            max = one ? index + 1 : options.length;\n          if (index < 0) {\n            i = max;\n          } else {\n            i = one ? index : 0;\n          }\n\n          // Loop through all the selected options\n          for (; i < max; i++) {\n            option = options[i];\n\n            // Support: IE <=9 only\n            // IE8-9 doesn\'t update selected after form reset (#2551)\n            if ((option.selected || i === index) &&\n            // Don\'t return options that are disabled or in a disabled optgroup\n            !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) {\n              // Get the specific value for the option\n              value = _jQuery2(option).val();\n\n              // We don\'t need an array for one selects\n              if (one) {\n                return value;\n              }\n\n              // Multi-Selects return an array\n              values.push(value);\n            }\n          }\n          return values;\n        },\n        set: function set(elem, value) {\n          var optionSet,\n            option,\n            options = elem.options,\n            values = _jQuery2.makeArray(value),\n            i = options.length;\n          while (i--) {\n            option = options[i];\n\n            /* eslint-disable no-cond-assign */\n\n            if (option.selected = _jQuery2.inArray(_jQuery2.valHooks.option.get(option), values) > -1) {\n              optionSet = true;\n            }\n\n            /* eslint-enable no-cond-assign */\n          }\n\n          // Force browsers to behave consistently when non-matching value is set\n          if (!optionSet) {\n            elem.selectedIndex = -1;\n          }\n          return values;\n        }\n      }\n    }\n  });\n\n  // Radios and checkboxes getter/setter\n  _jQuery2.each(["radio", "checkbox"], function () {\n    _jQuery2.valHooks[this] = {\n      set: function set(elem, value) {\n        if (Array.isArray(value)) {\n          return elem.checked = _jQuery2.inArray(_jQuery2(elem).val(), value) > -1;\n        }\n      }\n    };\n    if (!support.checkOn) {\n      _jQuery2.valHooks[this].get = function (elem) {\n        return elem.getAttribute("value") === null ? "on" : elem.value;\n      };\n    }\n  });\n\n  // Return jQuery for attributes-only inclusion\n\n  var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n  _jQuery2.extend(_jQuery2.event, {\n    trigger: function trigger(event, data, elem, onlyHandlers) {\n      var i,\n        cur,\n        tmp,\n        bubbleType,\n        ontype,\n        handle,\n        special,\n        eventPath = [elem || document],\n        type = hasOwn.call(event, "type") ? event.type : event,\n        namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];\n      cur = tmp = elem = elem || document;\n\n      // Don\'t do events on text and comment nodes\n      if (elem.nodeType === 3 || elem.nodeType === 8) {\n        return;\n      }\n\n      // focus/blur morphs to focusin/out; ensure we\'re not firing them right now\n      if (rfocusMorph.test(type + _jQuery2.event.triggered)) {\n        return;\n      }\n      if (type.indexOf(".") > -1) {\n        // Namespaced trigger; create a regexp to match event type in handle()\n        namespaces = type.split(".");\n        type = namespaces.shift();\n        namespaces.sort();\n      }\n      ontype = type.indexOf(":") < 0 && "on" + type;\n\n      // Caller can pass in a jQuery.Event object, Object, or just an event type string\n      event = event[_jQuery2.expando] ? event : new _jQuery2.Event(type, _typeof(event) === "object" && event);\n\n      // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n      event.isTrigger = onlyHandlers ? 2 : 3;\n      event.namespace = namespaces.join(".");
1\n      event.rnamespace = event.namespace ? new RegExp("(^|\\\\.)" + namespaces.join("\\\\.(?:.*\\\\.|)") + "(\\\\.|$)") : null;\n\n      // Clean up the event in case it is being reused\n      event.result = undefined;\n      if (!event.target) {\n        event.target = elem;\n      }\n\n      // Clone any incoming data and prepend the event, creating the handler arg list\n      data = data == null ? [event] : _jQuery2.makeArray(data, [event]);\n\n      // Allow special events to draw outside the lines\n      special = _jQuery2.event.special[type] || {};\n      if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {\n        return;\n      }\n\n      // Determine event propagation path in advance, per W3C events spec (#9951)\n      // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n      if (!onlyHandlers && !special.noBubble && !_jQuery2.isWindow(elem)) {\n        bubbleType = special.delegateType || type;\n        if (!rfocusMorph.test(bubbleType + type)) {\n          cur = cur.parentNode;\n        }\n        for (; cur; cur = cur.parentNode) {\n          eventPath.push(cur);\n          tmp = cur;\n        }\n\n        // Only add window if we got to document (e.g., not plain obj or detached DOM)\n        if (tmp === (elem.ownerDocument || document)) {\n          eventPath.push(tmp.defaultView || tmp.parentWindow || window);\n        }\n      }\n\n      // Fire handlers on the event path\n      i = 0;\n      while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {\n        event.type = i > 1 ? bubbleType : special.bindType || type;\n\n        // jQuery handler\n        handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle");\n        if (handle) {\n          handle.apply(cur, data);\n        }\n\n        // Native handler\n        handle = ontype && cur[ontype];\n        if (handle && handle.apply && acceptData(cur)) {\n          event.result = handle.apply(cur, data);\n          if (event.result === false) {\n            event.preventDefault();\n          }\n        }\n      }\n      event.type = type;\n\n      // If nobody prevented the default action, do it now\n      if (!onlyHandlers && !event.isDefaultPrevented()) {\n        if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {\n          // Call a native DOM method on the target with the same name as the event.\n          // Don\'t do default actions on window, that\'s where global variables be (#6170)\n          if (ontype && _jQuery2.isFunction(elem[type]) && !_jQuery2.isWindow(elem)) {\n            // Don\'t re-trigger an onFOO event when we call its FOO() method\n            tmp = elem[ontype];\n            if (tmp) {\n              elem[ontype] = null;\n            }\n\n            // Prevent re-triggering of the same event, since we already bubbled it above\n            _jQuery2.event.triggered = type;\n            elem[type]();\n            _jQuery2.event.triggered = undefined;\n            if (tmp) {\n              elem[ontype] = tmp;\n            }\n          }\n        }\n      }\n      return event.result;\n    },\n    // Piggyback on a donor event to simulate a different one\n    // Used only for `focus(in | out)` events\n    simulate: function simulate(type, elem, event) {\n      var e = _jQuery2.extend(new _jQuery2.Event(), event, {\n        type: type,\n        isSimulated: true\n      });\n      _jQuery2.event.trigger(e, null, elem);\n    }\n  });\n  _jQuery2.fn.extend({\n    trigger: function trigger(type, data) {\n      return this.each(function () {\n        _jQuery2.event.trigger(type, data, this);\n      });\n    },\n    triggerHandler: function triggerHandler(type, data) {\n      var elem = this[0];\n      if (elem) {\n        return _jQuery2.event.trigger(type, data, elem, true);\n      }\n    }\n  });\n  _jQuery2.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) {\n    // Handle event binding\n    _jQuery2.fn[name] = function (data, fn) {\n      return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);\n    };\n  });\n  _jQuery2.fn.extend({\n    hover: function hover(fnOver, fnOut) {\n      return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);\n    }\n  });\n  support.focusin = "onfocusin" in window;
1\n\n  // Support: Firefox <=44\n  // Firefox doesn\'t have focus(in | out) events\n  // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n  //\n  // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n  // focus(in | out) events fire after focus & blur events,\n  // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n  // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\n  if (!support.focusin) {\n    _jQuery2.each({\n      focus: "focusin",\n      blur: "focusout"\n    }, function (orig, fix) {\n      // Attach a single capturing handler on the document while someone wants focusin/focusout\n      var handler = function handler(event) {\n        _jQuery2.event.simulate(fix, event.target, _jQuery2.event.fix(event));\n      };\n      _jQuery2.event.special[fix] = {\n        setup: function setup() {\n          var doc = this.ownerDocument || this,\n            attaches = dataPriv.access(doc, fix);\n          if (!attaches) {\n            doc.addEventListener(orig, handler, true);\n          }\n          dataPriv.access(doc, fix, (attaches || 0) + 1);\n        },\n        teardown: function teardown() {\n          var doc = this.ownerDocument || this,\n            attaches = dataPriv.access(doc, fix) - 1;\n          if (!attaches) {\n            doc.removeEventListener(orig, handler, true);\n            dataPriv.remove(doc, fix);\n          }
1 else {\n            dataPriv.access(doc, fix, attaches);\n          }\n        }\n      };\n    });\n  }\n  var location = window.location;\n  var nonce = _jQuery2.now();\n  var rquery = /\\?/;\n\n  // Cross-browser xml parsing\n  _jQuery2.parseXML = function (data) {\n    var xml;\n    if (!data || typeof data !== "string") {\n      return null;\n    }\n\n    // Support: IE 9 - 11 only\n    // IE throws on parseFromString with invalid input.\n    try {\n      xml = new window.DOMParser().parseFromString(data, "text/xml");\n    } catch (e) {\n      xml = undefined;\n    }\n    if (!xml || xml.getElementsByTagName("parsererror").length) {\n      _jQuery2.error("Invalid XML: " + data);\n    }\n    return xml;\n  };\n  var rbracket = /\\[\\]$/,\n    rCRLF = /\\r?\\n/g,\n    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n    rsubmittable = /^(?:input|select|textarea|keygen)/i;\n  function buildParams(prefix, obj, traditional, add) {\n    var name;\n    if (Array.isArray(obj)) {\n      // Serialize array item.\n      _jQuery2.each(obj, function (i, v) {\n        if (traditional || rbracket.test(prefix)) {\n          // Treat each array item as a scalar.\n          add(prefix, v);\n        } else {\n          // Item is non-scalar (array or object), encode its numeric index.\n          buildParams(prefix + "[" + (_typeof(v) === "object" && v != null ? i : "") + "]", v, traditional, add);\n        }\n      });\n    } else if (!traditional && _jQuery2.type(obj) === "object") {\n      // Serialize object item.\n      for (name in obj) {\n        buildParams(prefix + "[" + name + "]", obj[name], traditional, add);\n      }\n    } else {\n      // Serialize scalar item.\n      add(prefix, obj);\n    }\n  }\n\n  // Serialize an array of form elements or a set of\n  // key/values into a query string\n  _jQuery2.param = function (a, traditional) {\n    var prefix,\n      s = [],\n      add = function add(key, valueOrFunction) {\n        // If value is a function, invoke it and use its return value\n        var value = _jQuery2.isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;\n        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);\n      };\n\n    // If an array was passed in, assume that it is an array of form elements.\n    if (Array.isArray(a) || a.jquery && !_jQuery2.isPlainObject(a)) {\n      // Serialize the form elements\n      _jQuery2.each(a, function () {\n        add(this.name, this.value);\n      });\n    } else {\n      // If traditional, encode the "old" way (the way 1.3.2 or older\n      // did it), otherwise encode params recursively.\n      for (prefix in a) {\n        buildParams(prefix, a[prefix], traditional, add);\n      }\n    }\n\n    // Return the resulting serialization\n    return s.join("&");\n  };\n  _jQuery2.fn.extend({\n    serialize: function serialize() {\n      return _jQuery2.param(this.serializeArray());\n    },\n    serializeArray: function serializeArray() {\n      return this.map(function () {\n        // Can add propHook for "elements" to filter or add form elements\n        var elements = _jQuery2.prop(this, "elements");\n        return elements ? _jQuery2.makeArray(elements) : this;\n      }).filter(function () {\n        var type = this.type;\n\n        // Use .is( ":disabled" ) so that fieldset[disabled] works\n        return this.name && !_jQuery2(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));\n      }).map(function (i, elem) {\n        var val = _jQuery2(this).val();\n        if (val == null) {\n          return null;\n        }\n        if (Array.isArray(val)) {\n          return _jQuery2.map(val, function (val) {\n            return {\n              name: elem.name,\n              value: val.replace(rCRLF, "\\r\\n")\n            };\n          });\n        }\n        return {\n          name: elem.name,\n          value: val.replace(rCRLF, "\\r\\n")\n        };\n      }).get();\n    }\n  });\n  var r20 = /%20/g,\n    rhash = /#.*$/,\n    rantiCache = /([?&])_=[^&]*/,\n    rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n    // #7653, #8
1125, #8152: local protocol detection\n    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n    rnoContent = /^(?:GET|HEAD)$/,\n    rprotocol = /^\\/\\//,\n    /* Prefilters\r\n     * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\r\n     * 2) These are called:\r\n     *    - BEFORE asking for a transport\r\n     *    - AFTER param serialization (s.data is a string if s.processData is true)\r\n     * 3) key is the dataType\r\n     * 4) the catchall symbol "*" can be used\r\n     * 5) execution will start with transport dataType and THEN continue down to "*" if needed\r\n     */\n    prefilters = {},\n    /* Transports bindings\r\n     * 1) key is the dataType\r\n     * 2) the catchall symbol "*" can be used\r\n     * 3) selection will start with transport dataType and THEN go to "*" if needed\r\n     */\n    transports = {},\n    // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n    allTypes = "*/".concat("*"),\n    // Anchor tag for parsing the document origin\n    originAnchor = document.createElement("a");\n  originAnchor.href = location.href;\n\n  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\n  function addToPrefiltersOrTransports(structure) {\n    // dataTypeExpression is optional and defaults to "*"\n    return function (dataTypeExpression, func) {\n      if (typeof dataTypeExpression !== "string") {\n        func = dataTypeExpression;\n        dataTypeExpression = "*";\n      }\n      var dataType,\n        i = 0,\n        dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];\n      if (_jQuery2.isFunction(func)) {\n        // For each dataType in the dataTypeExpression\n        while (dataType = dataTypes[i++]) {\n          // Prepend if requested\n          if (dataType[0] === "+") {\n            dataType = dataType.slice(1) || "*";\n            (structure[dataType] = structure[dataType] || []).unshift(func);\n\n            // Otherwise append\n          } else {\n            (structure[dataType] = structure[dataType] || []).push(func);\n          }\n        }\n      }\n    };\n  }\n\n  // Base inspection function for prefilters and transports\n  function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {\n    var inspected = {},\n      seekingTransport = structure === transports;\n    function inspect(dataType) {\n      var selected;\n      inspected[dataType] = true;\n      _jQuery2.each(structure[dataType] || [], function (_, prefilterOrFactory) {\n        var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);\n        if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {\n          options.dataTypes.unshift(dataTypeOrTransport);\n          inspect(dataTypeOrTransport);\n          return false;\n        } else if (seekingTransport) {\n          return !(selected = dataTypeOrTransport);\n        }\n      });\n      return selected;\n    }\n    return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");\n  }\n\n  // A special extend for ajax options\n  // that takes "flat" options (not to be deep extended)\n  // Fixes #9887\n  function ajaxExtend(target, src) {\n    var key,\n      deep,\n      flatOptions = _jQuery2.ajaxSettings.flatOptions || {};\n    for (key in src) {\n      if (src[key] !== undefined) {\n        (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];\n      }\n    }\n    if (deep) {\n      _jQuery2.extend(true, target, deep);\n    }\n    return target;\n  }\n\n  /* Handles responses to an ajax request:\r\n   * - finds the right dataType (mediates between content-type and expected dataType)\r\n   * - returns the corresponding response\r\n   */\n  function ajaxHandleResponses(s, jqXHR, responses) {\n    var ct,\n      type,\n      finalDataType,\n      firstDataType,\n      contents = s.contents,\n      dataTypes = s.dataTypes;\n\n    // Remove auto dataType and get content-type in the process\n    while (dataTypes[0] === "*") {\n      dataTypes.shift();\n      if (ct === undefined) {\n        ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");\n      }\n    }\n\n    // Check if we\'re dealing with a known content-type\n    if (ct) {\n      for (type in contents) {\n        if (contents[type] && contents[type].test(ct)) {\n          dataTypes.unshift(type);\n          break;\n        }\n      }\n    }\n\n    // Check to see if we have a response for the expected dataType\n    if (dataTypes[0] in responses) {\n      finalDataType = dataTypes[0];\n    }
1 else {\n      // Try convertible dataTypes\n      for (type in responses) {\n        if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {\n          finalDataType = type;\n          break;\n        }\n        if (!firstDataType) {\n          firstDataType = type;\n        }\n      }\n\n      // Or just use first one\n      finalDataType = finalDataType || firstDataType;\n    }\n\n    // If we found a dataType\n    // We add the dataType to the list if needed\n    // and return the corresponding response\n    if (finalDataType) {\n      if (finalDataType !== dataTypes[0]) {\n        dataTypes.unshift(finalDataType);\n      }\n      return responses[finalDataType];\n    }\n  }\n\n  /* Chain conversions given the request and the original response\r\n   * Also sets the responseXXX fields on the jqXHR instance\r\n   */\n  function ajaxConvert(s, response, jqXHR, isSuccess) {\n    var conv2,\n      current,\n      conv,\n      tmp,\n      prev,\n      converters = {},\n      // Work with a copy of dataTypes in case we need to modify it for conversion\n      dataTypes = s.dataTypes.slice();\n\n    // Create converters map with lowercased keys\n    if (dataTypes[1]) {\n      for (conv in s.converters) {\n        converters[conv.toLowerCase()] = s.converters[conv];\n      }\n    }\n    current = dataTypes.shift();\n\n    // Convert to each sequential dataType\n    while (current) {\n      if (s.responseFields[current]) {\n        jqXHR[s.responseFields[current]] = response;\n      }\n\n      // Apply the dataFilter if provided\n      if (!prev && isSuccess && s.dataFilter) {\n        response = s.dataFilter(response, s.dataType);\n      }\n      prev = current;\n      current = dataTypes.shift();\n      if (current) {\n        // There\'s only work to do if current dataType is non-auto\n        if (current === "*") {\n          current = prev;\n\n          // Convert response if prev dataType is non-auto and differs from current\n        } else if (prev !== "*" && prev !== current) {\n          // Seek a direct converter\n          conv = converters[prev + " " + current] || converters["* " + current];\n\n          // If none found, seek a pair\n          if (!conv) {\n            for (conv2 in converters) {\n              // If conv2 outputs current\n              tmp = conv2.split(" ");\n              if (tmp[1] === current) {\n                // If prev can be converted to accepted input\n                conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];\n                if (conv) {\n                  // Condense equivalence converters\n                  if (conv === true) {\n                    conv = converters[conv2];\n\n                    // Otherwise, insert the intermediate dataType\n                  } else if (converters[conv2] !== true) {\n                    current = tmp[0];\n                    dataTypes.unshift(tmp[1]);\n                  }\n                  break;\n                }\n              }\n            }\n          }\n\n          // Apply converter (if not an equivalence)\n          if (conv !== true) {\n            // Unless errors are allowed to bubble, catch and return them\n            if (conv && s["throws"]) {\n              response = conv(response);\n            } else {\n              try {\n                response = conv(response);\n              } catch (e) {\n                return {\n                  state: "parsererror",\n                  error: conv ? e : "No conversion from " + prev + " to " + current\n                };\n              }\n            }\n          }\n        }\n      }\n    }\n    return {\n      state: "success",\n      data: response\n    };\n  }\n  _jQuery2.extend({\n    // Counter for holding the number of active queries\n    active: 0,\n    // Last-Modified header cache for next request\n    lastModified: {},\n    etag: {},\n    ajaxSettings: {\n      url: location.href,\n      type: "GET",\n      isLocal: rlocalProtocol.test(location.protocol),\n      global: true,\n      processData: true,\n      async: true,\n      contentType: "application/x-www-form-urlencoded; charset=UTF-8",\n      /*\r\n      timeout: 0,\r\n      data: null,\r\n      dataType: null,\r\n      username: null,\r\n      password: null,\r\n      cache: null,\r\n      throws: fal
1se,\r\n      traditional: false,\r\n      headers: {},\r\n      */\n\n      accepts: {\n        "*": allTypes,\n        text: "text/plain",\n        html: "text/html",\n        xml: "application/xml, text/xml",\n        json: "application/json, text/javascript"\n      },\n      contents: {\n        xml: /\\bxml\\b/,\n        html: /\\bhtml/,\n        json: /\\bjson\\b/\n      },\n      responseFields: {\n        xml: "responseXML",\n        text: "responseText",\n        json: "responseJSON"\n      },\n      // Data converters\n      // Keys separate source (or catchall "*") and destination types with a single space\n      converters: {\n        // Convert anything to text\n        "* text": String,\n        // Text to html (true = no transformation)\n        "text html": true,\n        // Evaluate text as a json expression\n        "text json": JSON.parse,\n        // Parse text as xml\n        "text xml": _jQuery2.parseXML\n      },\n      // For options that shouldn\'t be deep extended:\n      // you can add your own custom options here if\n      // and when you create one that shouldn\'t be\n      // deep extended (see ajaxExtend)\n      flatOptions: {\n        url: true,\n        context: true\n      }\n    },\n    // Creates a full fledged settings object into target\n    // with both ajaxSettings and settings fields.\n    // If target is omitted, writes into ajaxSettings.\n    ajaxSetup: function ajaxSetup(target, settings) {\n      return settings ?\n      // Building a settings object\n      ajaxExtend(ajaxExtend(target, _jQuery2.ajaxSettings), settings) :\n      // Extending ajaxSettings\n      ajaxExtend(_jQuery2.ajaxSettings, target);\n    },\n    ajaxPrefilter: addToPrefiltersOrTransports(prefilters),\n    ajaxTransport: addToPrefiltersOrTransports(transports),\n    // Main method\n    ajax: function ajax(url, options) {\n      // If url is an object, simulate pre-1.5 signature\n      if (_typeof(url) === "object") {\n        options = url;\n        url = undefined;\n      }\n\n      // Force options to be an object\n      options = options || {};\n      var transport,\n        // URL without anti-cache param\n        cacheURL,\n        // Response headers\n        responseHeadersString,\n        responseHeaders,\n        // timeout handle\n        timeoutTimer,\n        // Url cleanup var\n        urlAnchor,\n        // Request state (becomes false upon send and true upon completion)\n        completed,\n        // To know if global events are to be dispatched\n        fireGlobals,\n        // Loop variable\n        i,\n        // uncached part of the url\n        uncached,\n        // Create the final options object\n        s = _jQuery2.ajaxSetup({}, options),\n        // Callbacks context\n        callbackContext = s.context || s,\n        // Context for global events is callbackContext if it is a DOM node or jQuery collection\n        globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? _jQuery2(callbackContext) : _jQuery2.event,\n        // Deferreds\n        deferred = _jQuery2.Deferred(),\n        completeDeferred = _jQuery2.Callbacks("once memory"),\n        // Status-dependent callbacks\n        _statusCode = s.statusCode || {},\n        // Headers (they are sent all at once)\n        requestHeaders = {},\n        requestHeadersNames = {},\n        // Default abort message\n        strAbort = "canceled",\n        // Fake xhr\n        jqXHR = {\n          readyState: 0,\n          // Builds headers hashtable if needed\n          getResponseHeader: function getResponseHeader(key) {\n            var match;\n            if (completed) {\n              if (!responseHeaders) {\n                responseHeaders = {};\n                while (match = rheaders.exec(responseHeadersString)) {\n                  responseHeaders[match[1].toLowerCase()] = match[2];\n                }\n              }\n              match = responseHeaders[key.toLowerCase()];\n            }\n            return match == null ? null : match;\n          },\n          // Raw string\n          getAllResponseHeaders: function getAllResponseHeaders() {\n            return completed ? responseHeadersString : null;\n          },\n          // Caches the header\n          setRequestHeader: function setRequestHeader(name, value) {\n            if (completed == null) {\n              name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name;\n              requestHeaders[name] = value;\n            }\n            return this;\n          },\n          // Overrides response content-type header\n          overrideMimeType: function overrideMimeType(type) {\n            if (completed == null) {\n              s.mimeType = type;\n            }\n            return this;\n          },\n          // Status-dependent callbacks\n          statusCode: function statusCode(map) {\n            var code;\n            if (map) {\n              if (completed) {\n                // Execute the appropriate callbacks\n                jqXHR.always(map[jqXHR.status]);\n              } else {\n                // Lazy-add the new callbacks in a way that preserves old ones\n                for (code in map) {\n                  _statusCode[code] = [_statusCode[code], map[code]];\n                }\n              }\n            }\n            return this;\n          },\n          // Cancel the request\n          abort: function abort(statusText) {\n            var finalText = statusText || strAbort;\n            if (transport) {\n              transport.abort(finalText);\n            }\n            done(0, finalText);\n            return this;\n          }\n        };\n\n      // Attach deferreds\n      deferred.promise(jqXHR);\n\n      // Add protocol if not provided (prefilters might expect it)\n      // Handle falsy url in the settings object (#10093: consistency with old signature)\n      // We also use the url parameter if available\n      s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//");\n\n      // Alias method option to type as per ticket #12004\n      s.type = options.method || options.type || s.method || s.type;\n\n      // Extract dataTypes list\n      s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""];\n\n      // A cross-domain request is in order when the origin doesn\'t match the current origin.\n      if (s.crossDomain == null) {\n        urlAnchor = document.createElement("a");
1\n\n        // Support: IE <=8 - 11, Edge 12 - 13\n        // IE throws exception on accessing the href property if url is malformed,\n        // e.g. http://example.com:80x/\n        try {\n          urlAnchor.href = s.url;\n\n          // Support: IE <=8 - 11 only\n          // Anchor\'s host property isn\'t correctly set when s.url is relative\n          urlAnchor.href = urlAnchor.href;\n          s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host;\n        } catch (e) {\n          // If there is an error parsing the URL, assume it is crossDomain,\n          // it can be rejected by the transport if it is invalid\n          s.crossDomain = true;\n        }\n      }\n\n      // Convert data if not already a string\n      if (s.data && s.processData && typeof s.data !== "string") {\n        s.data = _jQuery2.param(s.data, s.traditional);\n      }\n\n      // Apply prefilters\n      inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);\n\n      // If request was aborted inside a prefilter, stop there\n      if (completed) {\n        return jqXHR;\n      }\n\n      // We can fire global events as of now if asked to\n      // Don\'t fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n      fireGlobals = _jQuery2.event && s.global;\n\n      // Watch for a new set of requests\n      if (fireGlobals && _jQuery2.active++ === 0) {\n        _jQuery2.event.trigger("ajaxStart");\n      }\n\n      // Uppercase the type\n      s.type = s.type.toUpperCase();\n\n      // Determine if request has content\n      s.hasContent = !rnoContent.test(s.type);\n\n      // Save the URL in case we\'re toying with the If-Modified-Since\n      // and/or If-None-Match header later on\n      // Remove hash to simplify url manipulation\n      cacheURL = s.url.replace(rhash, "");\n\n      // More options handling for requests with no content\n      if (!s.hasContent) {\n        // Remember the hash so we can put it back\n        uncached = s.url.slice(cacheURL.length);\n\n        // If data is available, append data to url\n        if (s.data) {\n          cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data;\n\n          // #9682: remove data so that it\'s not used in an eventual retry\n          delete s.data;\n        }\n\n        // Add or update anti-cache param if needed\n        if (s.cache === false) {\n          cacheURL = cacheURL.replace(rantiCache, "$1");\n          uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++ + uncached;\n        }\n\n        // Put hash and anti-cache on the URL that will be requested (gh-1732)\n        s.url = cacheURL + uncached;\n\n        // Change \'%20\' to \'+\' if this is encoded form body content (gh-2658)\n      } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {\n        s.data = s.data.replace(r20, "+");\n      }\n\n      // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n      if (s.ifModified) {\n        if (_jQuery2.lastModified[cacheURL]) {\n          jqXHR.setRequestHeader("If-Modified-Since", _jQuery2.lastModified[cacheURL]);\n        }\n        if (_jQuery2.etag[cacheURL]) {\n          jqXHR.setRequestHeader("If-None-Match", _jQuery2.etag[cacheURL]);\n        }\n      }\n\n      // Set the correct header, if data is being sent\n      if (s.data && s.hasContent && s.contentType !== false || options.contentType) {\n        jqXHR.setRequestHeader("Content-Type", s.contentType);\n      }\n\n      // Set the Accepts header for the server, depending on the dataType\n      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["*"]);\n\n      // Check for headers option\n      for (i in s.headers) {\n        jqXHR.setRequestHeader(i, s.headers[i]);\n      }\n\n      // Allow custom headers/mimetypes and early abort\n      if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {\n        // Abort if not done already and return\n        return jqXHR.abort();\n      }\n\n      // Aborting is no longer a cancellation\n      strAbort = "abort";\n\n      // Install callbacks on deferreds\n      completeDeferred.add(s.complete);\n      jqXHR.done(s.success);\n      jqXHR.fail(s.error);\n\n      // Get transport\n      transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);\n\n      // If no transport, we auto-abort\n      if (!transport) {\n        done(-1, "No Transport");\n      } else {\n        jqXHR.readyState = 1;\n\n        // Send global event\n        if (fireGlobals) {\n          globalEventContext.trigger("ajaxSend", [jqXHR, s]);\n        }\n\n        // If request was aborted inside ajaxSend, stop there\n        if (completed) {\n          return jqXHR;\n        }\n\n        // Timeout\n        if (s.async && s.timeout > 0) {\n          timeoutTimer = window.setTimeout(function () {\n            jqXHR.abort("timeout");\n          }, s.timeout);\n        }\n        try {\n          completed = false;\n          transport.send(requestHeaders, done);\n        } catch (e) {\n          // Rethrow post-completion exceptions\n          if (completed) {\n            throw e;\n          }\n\n          // Propagate others as results\n          done(-1, e);\n        }\n      }\n\n      // Callback for when everything is done\n      function done(status, nativeStatusText, responses, headers) {\n        var isSuccess,\n          success,\n          error,\n          response,\n          modified,\n          statusText = nativeStatusText;\n\n        // Ignore repeat invocations\n        if (completed) {\n          return;\n        }\n        completed = true;\n\n        // Clear timeout if it exists\n        if (timeoutTimer) {\n          window.clearTimeout(timeoutTimer);\n        }\n\n        // Dereference transport for early garbage collection\n        // (no matter how long the jqXHR object will be used)\n        transport = undefined;\n\n        // Cache response headers\n        responseHeadersString = headers || "";\n\n        // Set readyState\n        jqXHR.readyState = status > 0 ? 4 : 0;\n\n        // Determine if successful\n        isSuccess = status >= 200 && status < 300 || status === 304;\n\n        // Get response data\n        if (responses) {\n          response = ajaxHandleResponses(s, jqXHR, responses);\n        }\n\n        // Convert no matter what (that way responseXXX fields are always set)\n        response = ajaxConvert(s, response, jqXHR, isSuccess);\n\n        // If successful, handle type chaining\n        if (isSuccess) {\
1n          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n          if (s.ifModified) {\n            modified = jqXHR.getResponseHeader("Last-Modified");\n            if (modified) {\n              _jQuery2.lastModified[cacheURL] = modified;\n            }\n            modified = jqXHR.getResponseHeader("etag");\n            if (modified) {\n              _jQuery2.etag[cacheURL] = modified;\n            }\n          }\n\n          // if no content\n          if (status === 204 || s.type === "HEAD") {\n            statusText = "nocontent";\n\n            // if not modified\n          } else if (status === 304) {\n            statusText = "notmodified";\n\n            // If we have data, let\'s convert it\n          } else {\n            statusText = response.state;\n            success = response.data;\n            error = response.error;\n            isSuccess = !error;\n          }\n        } else {\n          // Extract error from statusText and normalize for non-aborts\n          error = statusText;\n          if (status || !statusText) {\n            statusText = "error";\n            if (status < 0) {\n              status = 0;\n            }\n          }\n        }\n\n        // Set data for the fake xhr object\n        jqXHR.status = status;\n        jqXHR.statusText = (nativeStatusText || statusText) + "";\n\n        // Success/Error\n        if (isSuccess) {\n          deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);\n        } else {\n          deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);\n        }\n\n        // Status-dependent callbacks\n        jqXHR.statusCode(_statusCode);\n        _statusCode = undefined;\n        if (fireGlobals) {\n          globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);\n        }\n\n        // Complete\n        completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);\n        if (fireGlobals) {\n          globalEventContext.trigger("ajaxComplete", [jqXHR, s]);\n\n          // Handle the global AJAX counter\n          if (! --_jQuery2.active) {\n            _jQuery2.event.trigger("ajaxStop");\n          }\n        }\n      }\n      return jqXHR;\n    },\n    getJSON: function getJSON(url, data, callback) {\n      return _jQuery2.get(url, data, callback, "json");\n    },\n    getScript: function getScript(url, callback) {\n      return _jQuery2.get(url, undefined, callback, "script");\n    }\n  });\n  _jQuery2.each(["get", "post"], function (i, method) {\n    _jQuery2[method] = function (url, data, callback, type) {\n      // Shift arguments if data argument was omitted\n      if (_jQuery2.isFunction(data)) {\n        type = type || callback;\n        callback = data;\n        data = undefined;\n      }\n\n      // The url can be an options object (which then must have .url)\n      return _jQuery2.ajax(_jQuery2.extend({\n        url: url,\n        type: method,\n        dataType: type,\n        data: data,\n        success: callback\n      }, _jQuery2.isPlainObject(url) && url));\n    };\n  });\n  _jQuery2._evalUrl = function (url) {\n    return _jQuery2.ajax({\n      url: url,\n      // Make this explicit, since user can override this through ajaxSetup (#11264)\n      type: "GET",\n      dataType: "script",\n      cache: true,\n      async: false,\n      global: false,\n      "throws": true\n    });\n  };\n  _jQuery2.fn.extend({\n    wrapAll: function wrapAll(html) {\n      var wrap;\n      if (this[0]) {\n        if (_jQuery2.isFunction(html)) {\n          html = html.call(this[0]);\n        }\n\n        // The elements to wrap the target around\n        wrap = _jQuery2(html, this[0].ownerDocument).eq(0).clone(true);\n        if (this[0].parentNode) {\n          wrap.insertBefore(this[0]);\n        }\n        wrap.map(function () {\n          var elem = this;\n          while (elem.firstElementChild) {\n            elem = elem.firstElementChild;\n          }\n          return elem;\n        }).append(this);\n      }\n      return this;\n    },\n    wrapInner: function wrapInner(html) {\n      if (_jQuery2.isFunction(html)) {\n        return this.each(function (i) {\n          _jQuery2(this).wrapInner(html.call(this, i));\n        });\n      }\n      return this.each(function () {\n        var self = _jQuery2(this),\n          contents = self.contents();\n        if (contents.length) {\n          contents.wrapAll(html);\n        } else {\n          self.append(html);\n        }\n      });\n    },\n    wrap: function wrap(html) {\n      var isFunction = _jQuery2.isFunction(html);\n      return this.each(function (i) {\n        _jQuery2(this).wrapAll(isFunction ? html.call(this, i) : html);\n      });\n    },\n    unwrap: function unwrap(selector) {\n      this.parent(selector).not("body").each(function () {\n        _jQuery2(this).replaceWith(this.childNodes);\n      });\n      return this;\n    }\n  });\n  _jQuery2.expr.pseudos.hidden = function (elem) {\n    return !_jQuery2.expr.pseudos.visible(elem);\n  };\n  _jQuery2.expr.pseudos.visible = function (elem) {\n    return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);\n  };\n  _jQuery2.ajaxSettings.xhr = function () {\n    try {\n      return new window.XMLHttpRequest();\n    } catch (e) {}\n  };\n  var xhrSuccessStatus = {\n      // File protocol always yields status code 0, assume 200\n      0: 200,\n      // Supp
1ort: IE <=9 only\n      // #1450: sometimes IE returns 1223 when it should be 204\n      1223: 204\n    },\n    xhrSupported = _jQuery2.ajaxSettings.xhr();\n  support.cors = !!xhrSupported && "withCredentials" in xhrSupported;\n  support.ajax = xhrSupported = !!xhrSupported;\n  _jQuery2.ajaxTransport(function (options) {\n    var _callback, errorCallback;\n\n    // Cross domain only allowed if supported through XMLHttpRequest\n    if (support.cors || xhrSupported && !options.crossDomain) {\n      return {\n        send: function send(headers, complete) {\n          var i,\n            xhr = options.xhr();\n          xhr.open(options.type, options.url, options.async, options.username, options.password);\n\n          // Apply custom fields if provided\n          if (options.xhrFields) {\n            for (i in options.xhrFields) {\n              xhr[i] = options.xhrFields[i];\n            }\n          }\n\n          // Override mime type if needed\n          if (options.mimeType && xhr.overrideMimeType) {\n            xhr.overrideMimeType(options.mimeType);\n          }\n\n          // X-Requested-With header\n          // For cross-domain requests, seeing as conditions for a preflight are\n          // akin to a jigsaw puzzle, we simply never set it to be sure.\n          // (it can always be set on a per-request basis or even using ajaxSetup)\n          // For same-domain requests, won\'t change header if already provided.\n          if (!options.crossDomain && !headers["X-Requested-With"]) {\n            headers["X-Requested-With"] = "XMLHttpRequest";\n          }\n\n          // Set headers\n          for (i in headers) {\n            xhr.setRequestHeader(i, headers[i]);\n          }\n\n          // Callback\n          _callback = function callback(type) {\n            return function () {\n              if (_callback) {\n                _callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n                if (type === "abort") {\n                  xhr.abort();\n                } else if (type === "error") {\n                  // Support: IE <=9 only\n                  // On a manual native abort, IE9 throws\n                  // errors on any property access that is not readyState\n                  if (typeof xhr.status !== "number") {\n                    complete(0, "error");\n                  } else {\n                    complete(\n                    // File: protocol always yields status 0; see #8605, #14207\n                    xhr.status, xhr.statusText);\n                  }\n                } else {\n                  complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText,\n                  // Support: IE <=9 only\n                  // IE9 has no XHR2 but throws on binary (trac-11426)\n                  // For XHR2 non-text, let the caller handle it (gh-2498)\n                  (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? {\n                    binary: xhr.response\n                  } : {\n                    text: xhr.responseText\n                  }, xhr.getAllResponseHeaders());\n                }\n              }\n            };\n          };\n\n          // Listen to events\n          xhr.onload = _callback();\n          errorCallback = xhr.onerror = _callback("error");\n\n          // Support: IE 9 only\n          // Use onreadystatechange to replace onabort\n          // to handle uncaught aborts\n          if (xhr.onabort !== undefined) {\n            xhr.onabort = errorCallback;\n          } else {\n            xhr.onreadystatechange = function () {\n              // Check readyState before timeout as it changes\n              if (xhr.readyState === 4) {\n                // Allow onerror to be called first,\n                // but that will not handle a native abort\n                // Also, save errorCallback to a variable\n                // as xhr.onerror cannot be accessed\n                window.setTimeout(function () {\n                  if (_callback) {\n                    errorCallback();\n                  }\n                });\n              }\n            };\n          }\n\n          // Create the abort callback\n          _callback = _callback("abort");\n          try {\n            // Do send the request (this may raise an exception)\n            xhr.send(options.hasContent && options.data || null);\n          } catch (e) {\n            // #14683: Only rethrow if this hasn\'t been n
1otified as an error yet\n            if (_callback) {\n              throw e;\n            }\n          }\n        },\n        abort: function abort() {\n          if (_callback) {\n            _callback();\n          }\n        }\n      };\n    }\n  });\n\n  // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\n  _jQuery2.ajaxPrefilter(function (s) {\n    if (s.crossDomain) {\n      s.contents.script = false;\n    }\n  });\n\n  // Install script dataType\n  _jQuery2.ajaxSetup({\n    accepts: {\n      script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript"\n    },\n    contents: {\n      script: /\\b(?:java|ecma)script\\b/\n    },\n    converters: {\n      "text script": function text_script(text) {\n        _jQuery2.globalEval(text);\n        return text;\n      }\n    }\n  });\n\n  // Handle cache\'s special case and crossDomain\n  _jQuery2.ajaxPrefilter("script", function (s) {\n    if (s.cache === undefined) {\n      s.cache = false;\n    }\n    if (s.crossDomain) {\n      s.type = "GET";\n    }\n  });\n\n  // Bind script tag hack transport\n  _jQuery2.ajaxTransport("script", function (s) {\n    // This transport only deals with cross domain requests\n    if (s.crossDomain) {\n      var script, _callback2;\n      return {\n        send: function send(_, complete) {\n          script = _jQuery2("<script>").prop({\n            charset: s.scriptCharset,\n            src: s.url\n          }).on("load error", _callback2 = function callback(evt) {\n            script.remove();\n            _callback2 = null;\n            if (evt) {\n              complete(evt.type === "error" ? 404 : 200, evt.type);\n            }\n          });\n\n          // Use native DOM manipulation to avoid our domManip AJAX trickery\n          document.head.appendChild(script[0]);\n        },\n        abort: function abort() {\n          if (_callback2) {\n            _callback2();\n          }\n        }\n      };\n    }\n  });\n  var oldCallbacks = [],\n    rjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n  // Default jsonp settings\n  _jQuery2.ajaxSetup({\n    jsonp: "callback",\n    jsonpCallback: function jsonpCallback() {\n      var callback = oldCallbacks.pop() || _jQuery2.expando + "_" + nonce++;\n      this[callback] = true;\n      return callback;\n    }\n  });\n\n  // Detect, normalize options and install callbacks for jsonp requests\n  _jQuery2.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {\n    var callbackName,\n      overwritten,\n      responseContainer,\n      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");\n\n    // Handle iff the expected data type is "jsonp" or we have a parameter to set\n    if (jsonProp || s.dataTypes[0] === "jsonp") {\n      // Get callback name, remembering preexisting value associated with it\n      callbackName = s.jsonpCallback = _jQuery2.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;\n\n      // Insert callback into url or form data\n      if (jsonProp) {\n        s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);\n      } else if (s.jsonp !== false) {\n        s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;\n      }\n\n      // Use data converter to retrieve json after script execution\n      s.converters["script json"] = function () {\n        if (!responseContainer) {\n          _jQuery2.error(callbackName + " was not called");\n        }\n        return responseContainer[0];\n      };\n\n      // Force json dataType\n      s.dataTypes[0] = "json";\n\n      // Install callback\n      overwritten = window[callbackName];\n      window[callbackName] = function () {\n        responseContainer = arguments;\n      };\n\n      // Clean-up function (fires after converters)\n      jqXHR.always(function () {\n        // If previous value didn\'t exist - remove it\n        if (overwritten === undefined) {\n          _jQuery2(window).removeProp(callbackName);\n\n          // Otherwise restore preexisting value\n        } else {\n          window[callbackName] = overwritten;\n        }\n\n        // Save back as free\n        if (s[callbackName]) {\n          // Make sure that re-using the options doesn\'t screw things around\n          s.jsonpCallback = originalSettings.jsonpCallback;\n\n          // Save the callback name for future use\n          oldCallbacks.push(callbackName);\n        }\n\n        // Call if it was a function and we have a response\n        if (responseContainer && _jQuery2.isFunction(overwritten)) {\n          overwritten(responseContainer[0]);\n        }\n        responseContainer = overwritten = undefined;\n      });\n\n      // Delegate to script\n      return "script";\n    }\n  });
1\n\n  // Support: Safari 8 only\n  // In Safari 8 documents created via document.implementation.createHTMLDocument\n  // collapse sibling forms: the second one becomes a child of the first one.\n  // Because of that, this security measure has to be disabled in Safari 8.\n  // https://bugs.webkit.org/show_bug.cgi?id=137337\n  support.createHTMLDocument = function () {\n    var body = document.implementation.createHTMLDocument("").body;\n    body.innerHTML = "<form></form><form></form>";\n    return body.childNodes.length === 2;\n  }();\n\n  // Argument "data" should be string of html\n  // context (optional): If specified, the fragment will be created in this context,\n  // defaults to document\n  // keepScripts (optional): If true, will include scripts passed in the html string\n  _jQuery2.parseHTML = function (data, context, keepScripts) {\n    if (typeof data !== "string") {\n      return [];\n    }\n    if (typeof context === "boolean") {\n      keepScripts = context;\n      context = false;\n    }\n    var base, parsed, scripts;\n    if (!context) {\n      // Stop scripts or inline event handlers from being executed immediately\n      // by using document.implementation\n      if (support.createHTMLDocument) {\n        context = document.implementation.createHTMLDocument("");\n\n        // Set the base href for the created document\n        // so any parsed elements with URLs\n        // are based on the document\'s URL (gh-2965)\n        base = context.createElement("base");\n        base.href = document.location.href;\n        context.head.appendChild(base);\n      } else {\n        context = document;\n      }\n    }\n    parsed = rsingleTag.exec(data);\n    scripts = !keepScripts && [];\n\n    // Single tag\n    if (parsed) {\n      return [context.createElement(parsed[1])];\n    }\n    parsed = buildFragment([data], context, scripts);\n    if (scripts && scripts.length) {\n      _jQuery2(scripts).remove();\n    }\n    return _jQuery2.merge([], parsed.childNodes);\n  };\n\n  /**\r\n   * Load a url into a page\r\n   */\n  _jQuery2.fn.load = function (url, params, callback) {\n    var selector,\n      type,\n      response,\n      self = this,\n      off = url.indexOf(" ");\n    if (off > -1) {\n      selector = stripAndCollapse(url.slice(off));\n      url = url.slice(0, off);\n    }\n\n    // If it\'s a function\n    if (_jQuery2.isFunction(params)) {\n      // We assume that it\'s the callback\n      callback = params;\n      params = undefined;\n\n      // Otherwise, build a param string\n    } else if (params && _typeof(params) === "object") {\n      type = "POST";\n    }\n\n    // If we have elements to modify, make the request\n    if (self.length > 0) {\n      _jQuery2.ajax({\n        url: url,\n        // If "type" variable is undefined, then "GET" method will be used.\n        // Make value of this field explicit since\n        // user can override it through ajaxSetup method\n        type: type || "GET",\n        dataType: "html",\n        data: params\n      }).done(function (responseText) {\n        // Save response for use in complete callback\n        response = arguments;\n        self.html(selector ?\n        // If a selector was specified, locate the right elements in a dummy div\n        // Exclude scripts to avoid IE \'Permission Denied\' errors\n        _jQuery2("<div>").append(_jQuery2.parseHTML(responseText)).find(selector) :\n        // Otherwise use the full result\n        responseText);\n\n        // If the request succeeds, this function gets "data", "status", "jqXHR"\n        // but they are ignored because response was set above.\n        // If it fails, this function gets "jqXHR", "status", "error"\n      }).always(callback && function (jqXHR, status) {\n        self.each(function () {\n          callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);\n        });\n      });\n    }\n    return this;\n  };\n\n  // Attach a bunch of functions for handling common AJAX events\n  _jQuery2.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {\n    _jQuery2.fn[type] = function (fn) {\n      return this.on(type, fn
1);\n    };\n  });\n  _jQuery2.expr.pseudos.animated = function (elem) {\n    return _jQuery2.grep(_jQuery2.timers, function (fn) {\n      return elem === fn.elem;\n    }).length;\n  };\n  _jQuery2.offset = {\n    setOffset: function setOffset(elem, options, i) {\n      var curPosition,\n        curLeft,\n        curCSSTop,\n        curTop,\n        curOffset,\n        curCSSLeft,\n        calculatePosition,\n        position = _jQuery2.css(elem, "position"),\n        curElem = _jQuery2(elem),\n        props = {};\n\n      // Set position first, in-case top/left are set even on static elem\n      if (position === "static") {\n        elem.style.position = "relative";\n      }\n      curOffset = curElem.offset();\n      curCSSTop = _jQuery2.css(elem, "top");\n      curCSSLeft = _jQuery2.css(elem, "left");\n      calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1;\n\n      // Need to be able to calculate position if either\n      // top or left is auto and position is either absolute or fixed\n      if (calculatePosition) {\n        curPosition = curElem.position();\n        curTop = curPosition.top;\n        curLeft = curPosition.left;\n      } else {\n        curTop = parseFloat(curCSSTop) || 0;\n        curLeft = parseFloat(curCSSLeft) || 0;\n      }\n      if (_jQuery2.isFunction(options)) {\n        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n        options = options.call(elem, i, _jQuery2.extend({}, curOffset));\n      }\n      if (options.top != null) {\n        props.top = options.top - curOffset.top + curTop;\n      }\n      if (options.left != null) {\n        props.left = options.left - curOffset.left + curLeft;\n      }\n      if ("using" in options) {\n        options.using.call(elem, props);\n      } else {\n        curElem.css(props);\n      }\n    }\n  };\n  _jQuery2.fn.extend({\n    offset: function offset(options) {\n      // Preserve chaining for setter\n      if (arguments.length) {\n        return options === undefined ? this : this.each(function (i) {\n          _jQuery2.offset.setOffset(this, options, i);\n        });\n      }\n      var doc,\n        docElem,\n        rect,\n        win,\n        elem = this[0];\n      if (!elem) {\n        return;\n      }\n\n      // Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n      // Support: IE <=11 only\n      // Running getBoundingClientRect on a\n      // disconnected node in IE throws an error\n      if (!elem.getClientRects().length) {\n        return {\n          top: 0,\n          left: 0\n        };\n      }\n      rect = elem.getBoundingClientRect();\n      doc = elem.ownerDocument;\n      docElem = doc.documentElement;\n      win = doc.defaultView;\n      return {\n        top: rect.top + win.pageYOffset - docElem.clientTop,\n        left: rect.left + win.pageXOffset - docElem.clientLeft\n      };\n    },\n    position: function position() {\n      if (!this[0]) {\n        return;\n      }\n      var offsetParent,\n        offset,\n        elem = this[0],\n        parentOffset = {\n          top: 0,\n          left: 0\n        };\n\n      // Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n      // because it is its only offset parent\n      if (_jQuery2.css(elem, "position") === "fixed") {\n        // Assume getBoundingClientRect is there when computed position is fixed\n        offset = elem.getBoundingClientRect();\n      } else {\n        // Get *real* offsetParent\n        offsetParent = this.offsetParent();\n\n        // Get correct offsets\n        offset = this.offset();\n        if (!nodeName(offsetParent[0], "html")) {\n          parentOffset = offsetParent.offset();\n        }\n\n        // Add offsetParent borders\n        parentOffset = {\n          top: parentOffset.top + _jQuery2.css(offsetParent[0], "borderTopWidth", true),\n          left: parentOffset.left + _jQuery2.css(offsetParent[0], "borderLeftWidth", true)\n        };\n      }\n\n      // Subtract parent offsets and element margins\n      return {\n        top: offset.top - parentOffset.top - _jQuery2.css(elem, "marginTop", true),\n        left: offset.left - parentOffset.left - _jQuery2.css(elem, "marginLeft", true)\n      };\n    },\n    // This method will return documentElement in the following cases:\n    // 1) For the element inside the iframe without offsetParent, this method will return\n    //    documentElement of the parent window\n    // 2) For the hidden or detached element\n    // 3) For body or html element, i.e. in case of the html node - it will return itself\n    //\n    // but those exceptions were never presented as a real life use-cases\n    // and might be considered as more preferable results.\n    //\n    // This logic, however, is not guaranteed and can change at any point in the future\n    offsetParent: function offsetParent() {\n      return this.map(function () {\n        var offsetParent = this.offsetParent;\n        while (offsetParent && _jQuery2.css(offsetParent, "position") === "static") {\n          offsetParent = offsetParent.offsetParent;\n        }\n        return offsetParent || documentElement;\n      });\n    }\n  });\n\n  // Create scrollLeft and scrollTop methods\n  _jQuery2.each({\n    scrollLeft: "pageXOffset",\n    scrollTop: "pageYOffset"\n  }, function (method, prop) {\n    var top = "pageYOffset" === prop;\n    _jQuery2.fn[method] = function (val) {\n      return _access(this, function (elem, method, val) {\n        // Coalesce documents and windows\n        var win;\n        if (_jQuery2.isWindow(elem)) {\n          win = elem;\n        } else if (elem.nodeType === 9) {\n          win = elem.defaultView;\n        }\n        if (val === undefined) {\n          return win ? win[prop] : elem[method];\n        }\n        if (win) {\n          win.scrollTo(!top ? val : win.pageXOffset, top ? val : win.pageYOffset);\n        } else {\n          elem[method] = val;\n        }\n      }, method, val, arguments.length);\n    };\n  });
1\n\n  // Support: Safari <=7 - 9.1, Chrome <=37 - 49\n  // Add the top/left cssHooks using jQuery.fn.position\n  // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n  // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n  // getComputedStyle returns percent when specified for top/left/bottom/right;\n  // rather than make the css module depend on the offset module, just check for it here\n  _jQuery2.each(["top", "left"], function (i, prop) {\n    _jQuery2.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {\n      if (computed) {\n        computed = curCSS(elem, prop);\n\n        // If curCSS returns percentage, fallback to offset\n        return rnumnonpx.test(computed) ? _jQuery2(elem).position()[prop] + "px" : computed;\n      }\n    });\n  });\n\n  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\n  _jQuery2.each({\n    Height: "height",\n    Width: "width"\n  }, function (name, type) {\n    _jQuery2.each({\n      padding: "inner" + name,\n      content: type,\n      "": "outer" + name\n    }, function (defaultExtra, funcName) {\n      // Margin is only for outerHeight, outerWidth\n      _jQuery2.fn[funcName] = function (margin, value) {\n        var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),\n          extra = defaultExtra || (margin === true || value === true ? "margin" : "border");\n        return _access(this, function (elem, type, value) {\n          var doc;\n          if (_jQuery2.isWindow(elem)) {\n            // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n            return funcName.indexOf("outer") === 0 ? elem["inner" + name] : elem.document.documentElement["client" + name];\n          }\n\n          // Get document width or height\n          if (elem.nodeType === 9) {\n            doc = elem.documentElement;\n\n            // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n            // whichever is greatest\n            return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);\n          }\n          return value === undefined ?\n          // Get width or height on the element, requesting but not forcing parseFloat\n          _jQuery2.css(elem, type, extra) :\n          // Set width or height on the element\n          _jQuery2.style(elem, type, value, extra);\n        }, type, chainable ? margin : undefined, chainable);\n      };\n    });\n  });\n  _jQuery2.fn.extend({\n    bind: function bind(types, data, fn) {\n      return this.on(types, null, data, fn);\n    },\n    unbind: function unbind(types, fn) {\n      return this.off(types, null, fn);\n    },\n    delegate: function delegate(selector, types, data, fn) {\n      return this.on(types, selector, data, fn);\n    },\n    undelegate: function undelegate(selector, types, fn) {\n      // ( namespace ) or ( selector, types [, fn] )\n      return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);\n    }\n  });\n  _jQuery2.holdReady = function (hold) {\n    if (hold) {\n      _jQuery2.readyWait++;\n    } else {\n      _jQuery2.ready(true);\n    }\n  };\n  _jQuery2.isArray = Array.isArray;\n  _jQuery2.parseJSON = JSON.parse;\n  _jQuery2.nodeName = nodeName;\n\n  // Register as a named AMD module, since jQuery can be concatenated with other\n  // f
1iles that may use define, but not via a proper concatenation script that\n  // understands anonymous AMD modules. A named AMD is safest and most robust\n  // way to register. Lowercase jquery is used because AMD module names are\n  // derived from file names, and jQuery is normally delivered in a lowercase\n  // file name. Do this after creating the global so that if an AMD module wants\n  // to call noConflict to hide this version of jQuery, it will work.\n\n  // Note that for maximum portability, libraries that are not jQuery should\n  // declare themselves as anonymous modules, and avoid setting a global if an\n  // AMD loader is present. jQuery is a special case. For more information, see\n  // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\n  if (typeof define === "function" && define.amd) {\n    define("jquery", [], function () {\n      return _jQuery2;\n    });\n  }\n  var\n    // Map over jQuery in case of overwrite\n    _jQuery = window.jQuery,\n    // Map over the $ in case of overwrite\n    _$ = window.$;\n  _jQuery2.noConflict = function (deep) {\n    if (window.$ === _jQuery2) {\n      window.$ = _$;\n    }\n    if (deep && window.jQuery === _jQuery2) {\n      window.jQuery = _jQuery;\n    }\n    return _jQuery2;\n  };\n\n  // Expose jQuery and $ identifiers, even in AMD\n  // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n  // and CommonJS for browser emulators (#13566)\n  if (!noGlobal) {\n    window.jQuery = window.$ = _jQuery2;\n  }\n  return _jQuery2;\n});'},9269:function(e){e.exports="function _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\n(function (global, factory) {\n  (typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('window')) : typeof define === 'function' && define.amd ? define('isInViewport', ['jquery', 'window'], factory) : factory(global.$, global.window);\n})(this, function ($, window) {\n  'use strict';\n\n  $ = 'default' in $ ? $['default'] : $;\n  window = 'default' in window ? window['default'] : window;\n\n  /**\r\n   * @author  Mudit Ameta\r\n   * @license https://github.com/zeusdeux/isInViewport/blob/master/license.md MIT\r\n   */\n\n  // expose isInViewport as a custom pseudo-selector\n  $.extend($.expr[':'], {\n    // if $.expr.createPseudo is available, use it\n    'in-viewport': $.expr.createPseudo ? $.expr.createPseudo(function (argsString) {\n      return function (currElement) {\n        return isInViewport(currElement, getSelectorArgs(argsString));\n      };\n    }) : function (currObj, index, meta) {\n      return isInViewport(currObj, getSelectorArgs(meta[3]));\n    }\n  });\n\n  // expose isInViewport as a function too\n  // this lets folks pass around actual objects as options (like custom viewport)\n  // and doesn't tie 'em down to strings. It also prevents isInViewport from\n  // having to look up and wrap the dom element corresponding to the viewport selector\n  $.fn.isInViewport = function (options) {\n    return this.filter(function (i, el) {\n      return isInViewport(el, options);\n    });\n  };\n  $.fn.run = run;\n\n  // lets you chain any arbitrary function or an array of functions and returns a jquery object\n  function run(args) {\n    var this$1 = this;\n    if (arguments.length === 1 && typeof args === 'function') {\n      args = [args];\n    }\n    if (!(args instanceof Array)) {\n      throw new SyntaxError('isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions');\n    }\n    args.forEach(function (arg) {\n      if (typeof arg !== 'function') {\n        console.warn('isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions');\n        console.warn('isInViewport: Ignoring non-function values in array and moving on');\n      }
1 else {\n        [].slice.call(this$1).forEach(function (t) {\n          return arg.call($(t));\n        });\n      }\n    });\n    return this;\n  }\n\n  // gets the width of the scrollbar\n  function getScrollbarWidth(viewport) {\n    // append a div that has 100% width to get true width of viewport\n    var el = $('<div></div>').css({\n      width: '100%'\n    });\n    viewport.append(el);\n\n    // subtract true width from the viewport width which is inclusive\n    // of scrollbar by default\n    var scrollBarWidth = viewport.width() - el.width();\n\n    // remove our element from DOM\n    el.remove();\n    return scrollBarWidth;\n  }\n\n  // Returns true if DOM element `element` is in viewport\n  function isInViewport(element, options) {\n    var ref = element.getBoundingClientRect();\n    var top = ref.top;\n    var bottom = ref.bottom;\n    var left = ref.left;\n    var right = ref.right;\n    var settings = $.extend({\n      tolerance: 0,\n      viewport: window\n    }, options);\n    var isVisibleFlag = false;\n    var $viewport = settings.viewport.jquery ? settings.viewport : $(settings.viewport);\n    if (!$viewport.length) {\n      console.warn('isInViewport: The viewport selector you have provided matches no element on page.');\n      console.warn('isInViewport: Defaulting to viewport as window');\n      $viewport = $(window);\n    }\n    var $viewportHeight = $viewport.height();\n    var $viewportWidth = $viewport.width();\n    var typeofViewport = $viewport[0].toString();\n\n    // if the viewport is other than window recalculate the top,\n    // bottom,left and right wrt the new viewport\n    // the [object DOMWindow] check is for window object type in PhantomJS\n    if ($viewport[0] !== window && typeofViewport !== '[object Window]' && typeofViewport !== '[object DOMWindow]') {\n      // use getBoundingClientRect() instead of $.Offset()\n      // since the original top/bottom positions are calculated relative to browser viewport and not document\n      var viewportRect = $viewport[0].getBoundingClientRect();\n\n      // recalculate these relative to viewport\n      top = top - viewportRect.top;\n      bottom = bottom - viewportRect.top;\n      left = left - viewportRect.left;\n      right = right - viewportRect.left;\n\n      // get the scrollbar width from cache or calculate it\n      isInViewport.scrollBarWidth = isInViewport.scrollBarWidth || getScrollbarWidth($viewport);\n\n      // remove the width of the scrollbar from the viewport width\n      $viewportWidth -= isInViewport.scrollBarWidth;\n    }\n\n    // handle falsy, non-number and non-integer tolerance value\n    // same as checking using isNaN and then setting to 0\n    // bitwise operators deserve some love too you know\n    settings.tolerance = ~~Math.round(parseFloat(settings.tolerance));\n    if (settings.tolerance < 0) {\n      settings.tolerance = $viewportHeight + settings.tolerance; // viewport height - tol\n    }\n\n    // the element is NOT in viewport iff it is completely out of\n    // viewport laterally or if it is completely out of the tolerance\n    // region. Therefore, if it is partially in view then it is considered\n    // to be in the viewport and hence true is returned. Because we have adjusted\n    // the left/right positions relative to the viewport, we should check the\n    // element's right against the viewport's 0 (left side), and the element's\n    // left against the viewport's width to see if it is outside of the viewport.\n\n    if (right <= 0 || left >= $viewportWidth) {\n      return isVisibleFlag;\n    }\n\n    // if the element is bound to some tolerance\n    isVisibleFlag = settings.tolerance ? top <= settings.tolerance && bottom >= settings.tolerance : bottom > 0 && top <= $viewportHeight;\n    return isVisibleFlag;\n  }\n\n  // get the selector args from the args string proved by Sizzle\n  function getSelectorArgs(argsString) {\n    if (argsString) {\n      var args = argsString.split(',');\n\n      // when user only gives viewport and no tolerance\n      if (args.length === 1 && isNaN(args[0])) {\n        args[1] = args[0];\n        args[0] = void 0;\n      }\n      return {\n        tolerance: args[0] ? args[0].trim() : void 0,\n        viewport: args[1] ? $(args[1].trim()) : void 0\n      };\n    }\n    return {};\n  }\n});"},9368:function(e){e.exports='/*!\r\n * jQuery imagesLoaded plugin v2.1.1\r\n * http://github.com/desandro/imagesloaded\r\n *\r\n * MIT License. by Paul Irish et al.\r\n */\n(function (c, q) {\n  var m = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";\n  c.fn.imagesLoaded = function (f) {\n    function n() {\n      var b = c(j),\n        a = c(h);\n      d && (h.length ? d.reject(e, b, a) : d.resolve(e));\n      c.isFunction(f) && f.call(g, e, b, a);\n    }\n    function p(b) {\n      k(b.target, "error" === b.type);\n    }\n    function k(b, a) {\n      b.src === m || -1 !== c.inArray(b, l) || (l.push(b), a ? h.push(b) : j.push(b), c.data(b, "imagesLoaded", {\n        isBroken: a,\n        src: b.src\n      }), r && d.notifyWith(c(b), [a, e, c(j), c(h)]), e.length === l.length && (setTimeout(n), e.unbind(".imagesLoaded", p)));\n    }\n    var g = this,\n      d = c.isFunction(c.Deferred) ? c.Deferred() : 0,\n      r = c.isFunction(d.notify),\n      e = g.find("img").add(g.filter("img")),\n      l = [],\n      j = [],\n      h = [];\n    c.isPlainObject(f) && c.each(f, function (b, a) {\n      if ("callback" === b) f = a;else if (d) d[b](a);\n    });\n    e.length ? e.bind("load.imagesLoaded error.imagesLoaded", p).each(function (b, a) {\n      var d = a.src,\n        e = c.data(a, "imagesLoaded");\n      if (e && e.src === d) k(a, e.isBroken);
1else if (a.complete && a.naturalWidth !== q) k(a, 0 === a.naturalWidth || 0 === a.naturalHeight);else if (a.readyState || a.complete) a.src = m, a.src = d;\n    }) : n();\n    return d ? d.promise(g) : g;\n  };\n})(jQuery);'},9885:function(e){e.exports="/* === To be edited in Revolution only === */\nvar DL;\n(function (DL) {\n  var BaseSitePage = function () {\n    function BaseSitePage() {\n      $(document).on('keydown', window.DL.keydown) //\tKeyboard Integration\n      .on('click', '[data-track=\"event\"]', _.debounce(window.DL.tracking, 250, true)) //\tEvent Tracking\n      .on('ready', window.DL.social._init); //\tSocial Tracking\n    }\n    return BaseSitePage;\n  }();\n  DL.BaseSitePage = BaseSitePage;\n})(DL || (DL = {}));"}},n={};function t(r){var a=n[r];if(void 0!==a)return a.exports;var i=n[r]={exports:{}};return e[r](i,i.exports,t),i.exports}t(4642)(t(8291)),t(4642)(t(8585)),t(4642)(t(7041)),t(4642)(t(1735)),t(4642)(t(1962)),t(4642)(t(8110)),t(4642)(t(9368)),t(4642)(t(1021)),t(4642)(t(970)),t(4642)(t(9269)),t(4642)(t(2023)),t(4642)(t(8460)),t(4642)(t(6003)),t(4642)(t(1073)),t(4642)(t(7562)),t(4642)(t(6524)),t(4642)(t(1213)),t(4642)(t(9885)),t(4642)(t(7731)),t(4642)(t(1207)),t(4642)(t(2448)),t(4642)(t(3995))}();

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