Iwara Download Tool

Download videos from iwara.tv

// ==UserScript==
// @name              Iwara Download Tool
// @description       Download videos from iwara.tv
// @name:ja           Iwara バッチダウンローダー
// @description:ja    Iwara 動画バッチをダウンロード
// @name:zh-CN        Iwara 批量下载工具
// @description:zh-CN 批量下载 Iwara 视频
// @icon              https://www.google.com/s2/favicons?sz=64&domain=iwara.tv
// @namespace         https://github.com/dawn-lc/
// @author            dawn-lc
// @license           Apache-2.0
// @copyright         2025, Dawnlc (https://dawnlc.me/)
// @source            https://github.com/dawn-lc/IwaraDownloadTool
// @supportURL        https://github.com/dawn-lc/IwaraDownloadTool/issues
// @connect           iwara.tv
// @connect           *.iwara.*
// @connect           mmdfans.net
// @connect           *.mmdfans.net
// @connect           localhost
// @connect           127.0.0.1
// @connect           *
// @include           *://*.iwara.*/*
// @grant             GM_getValue
// @grant             GM_setValue
// @grant             GM_listValues
// @grant             GM_deleteValue
// @grant             GM_addValueChangeListener
// @grant             GM_addStyle
// @grant             GM_setClipboard
// @grant             GM_download
// @grant             GM_xmlhttpRequest
// @grant             GM_openInTab
// @grant             GM_getTab
// @grant             GM_saveTab
// @grant             GM_getTabs
// @grant             GM_info
// @grant             unsafeWindow
// @grant             window.close
// @run-at            document-start
// @version           3.3.49
// ==/UserScript==
"use strict";
(() => {
  var __create = Object.create;
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __getProtoOf = Object.getPrototypeOf;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __require =  ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
    get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
  }) : x)(function(x) {
    if (typeof require !== "undefined") return require.apply(this, arguments);
    throw Error('Dynamic require of "' + x + '" is not supported');
  });
  var __commonJS = (cb, mod) => function __require2() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
    isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
    mod
  ));
  var require_moment = __commonJS({
    "node_modules/moment/moment.js"(exports, module) {
      "use strict";
      ;
      (function(global2, factory) {
        typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global2.moment = factory();
      })(exports, function() {
        "use strict";
        var hookCallback;
        function hooks() {
          return hookCallback.apply(null, arguments);
        }
        function setHookCallback(callback) {
          hookCallback = callback;
        }
        function isArray3(input) {
          return input instanceof Array || Object.prototype.toString.call(input) === "[object Array]";
        }
        function isObject2(input) {
          return input != null && Object.prototype.toString.call(input) === "[object Object]";
        }
        function hasOwnProp(a, b) {
          return Object.prototype.hasOwnProperty.call(a, b);
        }
        function isObjectEmpty(obj) {
          if (Object.getOwnPropertyNames) {
            return Object.getOwnPropertyNames(obj).length === 0;
          } else {
            var k;
            for (k in obj) {
              if (hasOwnProp(obj, k)) {
                return false;
              }
            }
            return true;
          }
        }
        function isUndefined2(input) {
          return input === void 0;
        }
        function isNumber2(input) {
          return typeof input === "number" || Object.prototype.toString.call(input) === "[object Number]";
        }
        function isDate(input) {
          return input instanceof Date || Object.prototype.toString.call(input) === "[object Date]";
        }
        function map(arr, fn) {
          var res = [], i, arrLen = arr.length;
          for (i = 0; i < arrLen; ++i) {
            res.push(fn(arr[i], i));
          }
          return res;
        }
        function extend2(a, b) {
          for (var i in b) {
            if (hasOwnProp(b, i)) {
              a[i] = b[i];
            }
          }
          if (hasOwnProp(b, "toString")) {
            a.toString = b.toString;
          }
          if (hasOwnProp(b, "valueOf")) {
            a.valueOf = b.valueOf;
          }
          return a;
        }
        function createUTC(input, format2, locale2, strict) {
          return createLocalOrUTC(input, format2, locale2, strict, true).utc();
        }
        function defaultParsingFlags() {
          return {
            empty: false,
            unusedTokens: [],
            unusedInput: [],
            overflow: -2,
            charsLeftOver: 0,
            nullInput: false,
            invalidEra: null,
            invalidMonth: null,
            invalidFormat: false,
            userInvalidated: false,
            iso: false,
            parsedDateParts: [],
            era: null,
            meridiem: null,
            rfc2822: false,
            weekdayMismatch: false
          };
        }
        function getParsingFlags(m) {
          if (m._pf == null) {
            m._pf = defaultParsingFlags();
          }
          return m._pf;
        }
        var some;
        if (Array.prototype.some) {
          some = Array.prototype.some;
        } else {
          some = function(fun) {
            var t = Object(this), len = t.length >>> 0, i;
            for (i = 0; i < len; i++) {
              if (i in t && fun.call(this, t[i], i, t)) {
                return true;
              }
            }
            return false;
          };
        }
        function isValid(m) {
          var flags = null, parsedParts = false, isNowValid = m._d && !isNaN(m._d.getTime());
          if (isNowValid) {
            flags = getParsingFlags(m);
            parsedParts = some.call(flags.parsedDateParts, function(i) {
              return i != null;
            });
            isNowValid = flags.overflow < 0 && !flags.empty && !flags.invalidEra && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || flags.meridiem && parsedParts);
            if (m._strict) {
              isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === void 0;
            }
          }
          if (Object.isFrozen == null || !Object.isFrozen(m)) {
            m._isValid = isNowValid;
          } else {
            return isNowValid;
          }
          return m._isValid;
        }
        function createInvalid(flags) {
          var m = createUTC(NaN);
          if (flags != null) {
            extend2(getParsingFlags(m), flags);
          } else {
            getParsingFlags(m).userInvalidated = true;
          }
          return m;
        }
        var momentProperties = hooks.momentProperties = [], updateInProgress = false;
        function copyConfig(to2, from2) {
          var i, prop, val, momentPropertiesLen = momentProperties.length;
          if (!isUndefined2(from2._isAMomentObject)) {
            to2._isAMomentObject = from2._isAMomentObject;
          }
          if (!isUndefined2(from2._i)) {
            to2._i = from2._i;
          }
          if (!isUndefined2(from2._f)) {
            to2._f = from2._f;
          }
          if (!isUndefined2(from2._l)) {
            to2._l = from2._l;
          }
          if (!isUndefined2(from2._strict)) {
            to2._strict = from2._strict;
          }
          if (!isUndefined2(from2._tzm)) {
            to2._tzm = from2._tzm;
          }
          if (!isUndefined2(from2._isUTC)) {
            to2._isUTC = from2._isUTC;
          }
          if (!isUndefined2(from2._offset)) {
            to2._offset = from2._offset;
          }
          if (!isUndefined2(from2._pf)) {
            to2._pf = getParsingFlags(from2);
          }
          if (!isUndefined2(from2._locale)) {
            to2._locale = from2._locale;
          }
          if (momentPropertiesLen > 0) {
            for (i = 0; i < momentPropertiesLen; i++) {
              prop = momentProperties[i];
              val = from2[prop];
              if (!isUndefined2(val)) {
                to2[prop] = val;
              }
            }
          }
          return to2;
        }
        function Moment2(config2) {
          copyConfig(this, config2);
          this._d = new Date(config2._d != null ? config2._d.getTime() : NaN);
          if (!this.isValid()) {
            this._d =  new Date(NaN);
          }
          if (updateInProgress === false) {
            updateInProgress = true;
            hooks.updateOffset(this);
            updateInProgress = false;
          }
        }
        function isMoment(obj) {
          return obj instanceof Moment2 || obj != null && obj._isAMomentObject != null;
        }
        function warn(msg) {
          if (hooks.suppressDeprecationWarnings === false && typeof console !== "undefined" && console.warn) {
            console.warn("Deprecation warning: " + msg);
          }
        }
        function deprecate(msg, fn) {
          var firstTime = true;
          return extend2(function() {
            if (hooks.deprecationHandler != null) {
              hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
              var args = [], arg, i, key, argLen = arguments.length;
              for (i = 0; i < argLen; i++) {
                arg = "";
                if (typeof arguments[i] === "object") {
                  arg += "\n[" + i + "] ";
                  for (key in arguments[0]) {
                    if (hasOwnProp(arguments[0], key)) {
                      arg += key + ": " + arguments[0][key] + ", ";
                    }
                  }
                  arg = arg.slice(0, -2);
                } else {
                  arg = arguments[i];
                }
                args.push(arg);
              }
              warn(msg + "\nArguments: " + Array.prototype.slice.call(args).join("") + "\n" + new Error().stack);
              firstTime = false;
            }
            return fn.apply(this, arguments);
          }, fn);
        }
        var deprecations = {};
        function deprecateSimple(name, msg) {
          if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(name, msg);
          }
          if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
          }
        }
        hooks.suppressDeprecationWarnings = false;
        hooks.deprecationHandler = null;
        function isFunction(input) {
          return typeof Function !== "undefined" && input instanceof Function || Object.prototype.toString.call(input) === "[object Function]";
        }
        function set(config2) {
          var prop, i;
          for (i in config2) {
            if (hasOwnProp(config2, i)) {
              prop = config2[i];
              if (isFunction(prop)) {
                this[i] = prop;
              } else {
                this["_" + i] = prop;
              }
            }
          }
          this._config = config2;
          this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + "|" + /\d{1,2}/.source);
        }
        function mergeConfigs(parentConfig, childConfig) {
          var res = extend2({}, parentConfig), prop;
          for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
              if (isObject2(parentConfig[prop]) && isObject2(childConfig[prop])) {
                res[prop] = {};
                extend2(res[prop], parentConfig[prop]);
                extend2(res[prop], childConfig[prop]);
              } else if (childConfig[prop] != null) {
                res[prop] = childConfig[prop];
              } else {
                delete res[prop];
              }
            }
          }
          for (prop in parentConfig) {
            if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject2(parentConfig[prop])) {
              res[prop] = extend2({}, res[prop]);
            }
          }
          return res;
        }
        function Locale(config2) {
          if (config2 != null) {
            this.set(config2);
          }
        }
        var keys2;
        if (Object.keys) {
          keys2 = Object.keys;
        } else {
          keys2 = function(obj) {
            var i, res = [];
            for (i in obj) {
              if (hasOwnProp(obj, i)) {
                res.push(i);
              }
            }
            return res;
          };
        }
        var defaultCalendar = {
          sameDay: "[Today at] LT",
          nextDay: "[Tomorrow at] LT",
          nextWeek: "dddd [at] LT",
          lastDay: "[Yesterday at] LT",
          lastWeek: "[Last] dddd [at] LT",
          sameElse: "L"
        };
        function calendar(key, mom, now2) {
          var output = this._calendar[key] || this._calendar["sameElse"];
          return isFunction(output) ? output.call(mom, now2) : output;
        }
        function zeroFill(number, targetLength, forceSign) {
          var absNumber = "" + Math.abs(number), zerosToFill = targetLength - absNumber.length, sign2 = number >= 0;
          return (sign2 ? forceSign ? "+" : "" : "-") + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
        }
        var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, formatFunctions = {}, formatTokenFunctions = {};
        function addFormatToken(token2, padded, ordinal2, callback) {
          var func = callback;
          if (typeof callback === "string") {
            func = function() {
              return this[callback]();
            };
          }
          if (token2) {
            formatTokenFunctions[token2] = func;
          }
          if (padded) {
            formatTokenFunctions[padded[0]] = function() {
              return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
          }
          if (ordinal2) {
            formatTokenFunctions[ordinal2] = function() {
              return this.localeData().ordinal(func.apply(this, arguments), token2);
            };
          }
        }
        function removeFormattingTokens(input) {
          if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, "");
          }
          return input.replace(/\\/g, "");
        }
        function makeFormatFunction(format2) {
          var array = format2.match(formattingTokens), i, length;
          for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
              array[i] = formatTokenFunctions[array[i]];
            } else {
              array[i] = removeFormattingTokens(array[i]);
            }
          }
          return function(mom) {
            var output = "", i2;
            for (i2 = 0; i2 < length; i2++) {
              output += isFunction(array[i2]) ? array[i2].call(mom, format2) : array[i2];
            }
            return output;
          };
        }
        function formatMoment(m, format2) {
          if (!m.isValid()) {
            return m.localeData().invalidDate();
          }
          format2 = expandFormat(format2, m.localeData());
          formatFunctions[format2] = formatFunctions[format2] || makeFormatFunction(format2);
          return formatFunctions[format2](m);
        }
        function expandFormat(format2, locale2) {
          var i = 5;
          function replaceLongDateFormatTokens(input) {
            return locale2.longDateFormat(input) || input;
          }
          localFormattingTokens.lastIndex = 0;
          while (i >= 0 && localFormattingTokens.test(format2)) {
            format2 = format2.replace(localFormattingTokens, replaceLongDateFormatTokens);
            localFormattingTokens.lastIndex = 0;
            i -= 1;
          }
          return format2;
        }
        var defaultLongDateFormat = {
          LTS: "h:mm:ss A",
          LT: "h:mm A",
          L: "MM/DD/YYYY",
          LL: "MMMM D, YYYY",
          LLL: "MMMM D, YYYY h:mm A",
          LLLL: "dddd, MMMM D, YYYY h:mm A"
        };
        function longDateFormat(key) {
          var format2 = this._longDateFormat[key], formatUpper = this._longDateFormat[key.toUpperCase()];
          if (format2 || !formatUpper) {
            return format2;
          }
          this._longDateFormat[key] = formatUpper.match(formattingTokens).map(function(tok) {
            if (tok === "MMMM" || tok === "MM" || tok === "DD" || tok === "dddd") {
              return tok.slice(1);
            }
            return tok;
          }).join("");
          return this._longDateFormat[key];
        }
        var defaultInvalidDate = "Invalid date";
        function invalidDate() {
          return this._invalidDate;
        }
        var defaultOrdinal = "%d", defaultDayOfMonthOrdinalParse = /\d{1,2}/;
        function ordinal(number) {
          return this._ordinal.replace("%d", number);
        }
        var defaultRelativeTime = {
          future: "in %s",
          past: "%s ago",
          s: "a few seconds",
          ss: "%d seconds",
          m: "a minute",
          mm: "%d minutes",
          h: "an hour",
          hh: "%d hours",
          d: "a day",
          dd: "%d days",
          w: "a week",
          ww: "%d weeks",
          M: "a month",
          MM: "%d months",
          y: "a year",
          yy: "%d years"
        };
        function relativeTime(number, withoutSuffix, string, isFuture) {
          var output = this._relativeTime[string];
          return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
        }
        function pastFuture(diff2, output) {
          var format2 = this._relativeTime[diff2 > 0 ? "future" : "past"];
          return isFunction(format2) ? format2(output) : format2.replace(/%s/i, output);
        }
        var aliases = {
          D: "date",
          dates: "date",
          date: "date",
          d: "day",
          days: "day",
          day: "day",
          e: "weekday",
          weekdays: "weekday",
          weekday: "weekday",
          E: "isoWeekday",
          isoweekdays: "isoWeekday",
          isoweekday: "isoWeekday",
          DDD: "dayOfYear",
          dayofyears: "dayOfYear",
          dayofyear: "dayOfYear",
          h: "hour",
          hours: "hour",
          hour: "hour",
          ms: "millisecond",
          milliseconds: "millisecond",
          millisecond: "millisecond",
          m: "minute",
          minutes: "minute",
          minute: "minute",
          M: "month",
          months: "month",
          month: "month",
          Q: "quarter",
          quarters: "quarter",
          quarter: "quarter",
          s: "second",
          seconds: "second",
          second: "second",
          gg: "weekYear",
          weekyears: "weekYear",
          weekyear: "weekYear",
          GG: "isoWeekYear",
          isoweekyears: "isoWeekYear",
          isoweekyear: "isoWeekYear",
          w: "week",
          weeks: "week",
          week: "week",
          W: "isoWeek",
          isoweeks: "isoWeek",
          isoweek: "isoWeek",
          y: "year",
          years: "year",
          year: "year"
        };
        function normalizeUnits(units) {
          return typeof units === "string" ? aliases[units] || aliases[units.toLowerCase()] : void 0;
        }
        function normalizeObjectUnits(inputObject) {
          var normalizedInput = {}, normalizedProp, prop;
          for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
              normalizedProp = normalizeUnits(prop);
              if (normalizedProp) {
                normalizedInput[normalizedProp] = inputObject[prop];
              }
            }
          }
          return normalizedInput;
        }
        var priorities = {
          date: 9,
          day: 11,
          weekday: 11,
          isoWeekday: 11,
          dayOfYear: 4,
          hour: 13,
          millisecond: 16,
          minute: 14,
          month: 8,
          quarter: 7,
          second: 15,
          weekYear: 1,
          isoWeekYear: 1,
          week: 5,
          isoWeek: 5,
          year: 1
        };
        function getPrioritizedUnits(unitsObj) {
          var units = [], u;
          for (u in unitsObj) {
            if (hasOwnProp(unitsObj, u)) {
              units.push({
                unit: u,
                priority: priorities[u]
              });
            }
          }
          units.sort(function(a, b) {
            return a.priority - b.priority;
          });
          return units;
        }
        var match1 = /\d/, match2 = /\d\d/, match3 = /\d{3}/, match4 = /\d{4}/, match6 = /[+-]?\d{6}/, match1to2 = /\d\d?/, match3to4 = /\d\d\d\d?/, match5to6 = /\d\d\d\d\d\d?/, match1to3 = /\d{1,3}/, match1to4 = /\d{1,4}/, match1to6 = /[+-]?\d{1,6}/, matchUnsigned = /\d+/, matchSigned = /[+-]?\d+/, matchOffset = /Z|[+-]\d\d:?\d\d/gi, matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, match1to2NoLeadingZero = /^[1-9]\d?/, match1to2HasZero = /^([1-9]\d|\d)/, regexes;
        regexes = {};
        function addRegexToken(token2, regex, strictRegex) {
          regexes[token2] = isFunction(regex) ? regex : function(isStrict, localeData2) {
            return isStrict && strictRegex ? strictRegex : regex;
          };
        }
        function getParseRegexForToken(token2, config2) {
          if (!hasOwnProp(regexes, token2)) {
            return new RegExp(unescapeFormat(token2));
          }
          return regexes[token2](config2._strict, config2._locale);
        }
        function unescapeFormat(s) {
          return regexEscape(s.replace("\\", "").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(matched, p1, p2, p3, p4) {
            return p1 || p2 || p3 || p4;
          }));
        }
        function regexEscape(s) {
          return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
        }
        function absFloor(number) {
          if (number < 0) {
            return Math.ceil(number) || 0;
          } else {
            return Math.floor(number);
          }
        }
        function toInt(argumentForCoercion) {
          var coercedNumber = +argumentForCoercion, value = 0;
          if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
          }
          return value;
        }
        var tokens = {};
        function addParseToken(token2, callback) {
          var i, func = callback, tokenLen;
          if (typeof token2 === "string") {
            token2 = [token2];
          }
          if (isNumber2(callback)) {
            func = function(input, array) {
              array[callback] = toInt(input);
            };
          }
          tokenLen = token2.length;
          for (i = 0; i < tokenLen; i++) {
            tokens[token2[i]] = func;
          }
        }
        function addWeekParseToken(token2, callback) {
          addParseToken(token2, function(input, array, config2, token3) {
            config2._w = config2._w || {};
            callback(input, config2._w, config2, token3);
          });
        }
        function addTimeToArrayFromToken(token2, input, config2) {
          if (input != null && hasOwnProp(tokens, token2)) {
            tokens[token2](input, config2._a, config2, token2);
          }
        }
        function isLeapYear(year) {
          return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
        }
        var YEAR = 0, MONTH = 1, DATE = 2, HOUR = 3, MINUTE = 4, SECOND = 5, MILLISECOND = 6, WEEK = 7, WEEKDAY = 8;
        addFormatToken("Y", 0, 0, function() {
          var y = this.year();
          return y <= 9999 ? zeroFill(y, 4) : "+" + y;
        });
        addFormatToken(0, ["YY", 2], 0, function() {
          return this.year() % 100;
        });
        addFormatToken(0, ["YYYY", 4], 0, "year");
        addFormatToken(0, ["YYYYY", 5], 0, "year");
        addFormatToken(0, ["YYYYYY", 6, true], 0, "year");
        addRegexToken("Y", matchSigned);
        addRegexToken("YY", match1to2, match2);
        addRegexToken("YYYY", match1to4, match4);
        addRegexToken("YYYYY", match1to6, match6);
        addRegexToken("YYYYYY", match1to6, match6);
        addParseToken(["YYYYY", "YYYYYY"], YEAR);
        addParseToken("YYYY", function(input, array) {
          array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
        });
        addParseToken("YY", function(input, array) {
          array[YEAR] = hooks.parseTwoDigitYear(input);
        });
        addParseToken("Y", function(input, array) {
          array[YEAR] = parseInt(input, 10);
        });
        function daysInYear(year) {
          return isLeapYear(year) ? 366 : 365;
        }
        hooks.parseTwoDigitYear = function(input) {
          return toInt(input) + (toInt(input) > 68 ? 1900 : 2e3);
        };
        var getSetYear = makeGetSet("FullYear", true);
        function getIsLeapYear() {
          return isLeapYear(this.year());
        }
        function makeGetSet(unit, keepTime) {
          return function(value) {
            if (value != null) {
              set$1(this, unit, value);
              hooks.updateOffset(this, keepTime);
              return this;
            } else {
              return get(this, unit);
            }
          };
        }
        function get(mom, unit) {
          if (!mom.isValid()) {
            return NaN;
          }
          var d = mom._d, isUTC = mom._isUTC;
          switch (unit) {
            case "Milliseconds":
              return isUTC ? d.getUTCMilliseconds() : d.getMilliseconds();
            case "Seconds":
              return isUTC ? d.getUTCSeconds() : d.getSeconds();
            case "Minutes":
              return isUTC ? d.getUTCMinutes() : d.getMinutes();
            case "Hours":
              return isUTC ? d.getUTCHours() : d.getHours();
            case "Date":
              return isUTC ? d.getUTCDate() : d.getDate();
            case "Day":
              return isUTC ? d.getUTCDay() : d.getDay();
            case "Month":
              return isUTC ? d.getUTCMonth() : d.getMonth();
            case "FullYear":
              return isUTC ? d.getUTCFullYear() : d.getFullYear();
            default:
              return NaN;
          }
        }
        function set$1(mom, unit, value) {
          var d, isUTC, year, month, date;
          if (!mom.isValid() || isNaN(value)) {
            return;
          }
          d = mom._d;
          isUTC = mom._isUTC;
          switch (unit) {
            case "Milliseconds":
              return void (isUTC ? d.setUTCMilliseconds(value) : d.setMilliseconds(value));
            case "Seconds":
              return void (isUTC ? d.setUTCSeconds(value) : d.setSeconds(value));
            case "Minutes":
              return void (isUTC ? d.setUTCMinutes(value) : d.setMinutes(value));
            case "Hours":
              return void (isUTC ? d.setUTCHours(value) : d.setHours(value));
            case "Date":
              return void (isUTC ? d.setUTCDate(value) : d.setDate(value));
            case "FullYear":
              break;
            default:
              return;
          }
          year = value;
          month = mom.month();
          date = mom.date();
          date = date === 29 && month === 1 && !isLeapYear(year) ? 28 : date;
          void (isUTC ? d.setUTCFullYear(year, month, date) : d.setFullYear(year, month, date));
        }
        function stringGet(units) {
          units = normalizeUnits(units);
          if (isFunction(this[units])) {
            return this[units]();
          }
          return this;
        }
        function stringSet(units, value) {
          if (typeof units === "object") {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units), i, prioritizedLen = prioritized.length;
            for (i = 0; i < prioritizedLen; i++) {
              this[prioritized[i].unit](units[prioritized[i].unit]);
            }
          } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
              return this[units](value);
            }
          }
          return this;
        }
        function mod(n, x) {
          return (n % x + x) % x;
        }
        var indexOf;
        if (Array.prototype.indexOf) {
          indexOf = Array.prototype.indexOf;
        } else {
          indexOf = function(o) {
            var i;
            for (i = 0; i < this.length; ++i) {
              if (this[i] === o) {
                return i;
              }
            }
            return -1;
          };
        }
        function daysInMonth(year, month) {
          if (isNaN(year) || isNaN(month)) {
            return NaN;
          }
          var modMonth = mod(month, 12);
          year += (month - modMonth) / 12;
          return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
        }
        addFormatToken("M", ["MM", 2], "Mo", function() {
          return this.month() + 1;
        });
        addFormatToken("MMM", 0, 0, function(format2) {
          return this.localeData().monthsShort(this, format2);
        });
        addFormatToken("MMMM", 0, 0, function(format2) {
          return this.localeData().months(this, format2);
        });
        addRegexToken("M", match1to2, match1to2NoLeadingZero);
        addRegexToken("MM", match1to2, match2);
        addRegexToken("MMM", function(isStrict, locale2) {
          return locale2.monthsShortRegex(isStrict);
        });
        addRegexToken("MMMM", function(isStrict, locale2) {
          return locale2.monthsRegex(isStrict);
        });
        addParseToken(["M", "MM"], function(input, array) {
          array[MONTH] = toInt(input) - 1;
        });
        addParseToken(["MMM", "MMMM"], function(input, array, config2, token2) {
          var month = config2._locale.monthsParse(input, token2, config2._strict);
          if (month != null) {
            array[MONTH] = month;
          } else {
            getParsingFlags(config2).invalidMonth = input;
          }
        });
        var defaultLocaleMonths = "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), defaultLocaleMonthsShort = "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, defaultMonthsShortRegex = matchWord, defaultMonthsRegex = matchWord;
        function localeMonths(m, format2) {
          if (!m) {
            return isArray3(this._months) ? this._months : this._months["standalone"];
          }
          return isArray3(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format2) ? "format" : "standalone"][m.month()];
        }
        function localeMonthsShort(m, format2) {
          if (!m) {
            return isArray3(this._monthsShort) ? this._monthsShort : this._monthsShort["standalone"];
          }
          return isArray3(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format2) ? "format" : "standalone"][m.month()];
        }
        function handleStrictParse(monthName, format2, strict) {
          var i, ii, mom, llc = monthName.toLocaleLowerCase();
          if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
              mom = createUTC([2e3, i]);
              this._shortMonthsParse[i] = this.monthsShort(mom, "").toLocaleLowerCase();
              this._longMonthsParse[i] = this.months(mom, "").toLocaleLowerCase();
            }
          }
          if (strict) {
            if (format2 === "MMM") {
              ii = indexOf.call(this._shortMonthsParse, llc);
              return ii !== -1 ? ii : null;
            } else {
              ii = indexOf.call(this._longMonthsParse, llc);
              return ii !== -1 ? ii : null;
            }
          } else {
            if (format2 === "MMM") {
              ii = indexOf.call(this._shortMonthsParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._longMonthsParse, llc);
              return ii !== -1 ? ii : null;
            } else {
              ii = indexOf.call(this._longMonthsParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._shortMonthsParse, llc);
              return ii !== -1 ? ii : null;
            }
          }
        }
        function localeMonthsParse(monthName, format2, strict) {
          var i, mom, regex;
          if (this._monthsParseExact) {
            return handleStrictParse.call(this, monthName, format2, strict);
          }
          if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
          }
          for (i = 0; i < 12; i++) {
            mom = createUTC([2e3, i]);
            if (strict && !this._longMonthsParse[i]) {
              this._longMonthsParse[i] = new RegExp("^" + this.months(mom, "").replace(".", "") + "$", "i");
              this._shortMonthsParse[i] = new RegExp("^" + this.monthsShort(mom, "").replace(".", "") + "$", "i");
            }
            if (!strict && !this._monthsParse[i]) {
              regex = "^" + this.months(mom, "") + "|^" + this.monthsShort(mom, "");
              this._monthsParse[i] = new RegExp(regex.replace(".", ""), "i");
            }
            if (strict && format2 === "MMMM" && this._longMonthsParse[i].test(monthName)) {
              return i;
            } else if (strict && format2 === "MMM" && this._shortMonthsParse[i].test(monthName)) {
              return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
              return i;
            }
          }
        }
        function setMonth(mom, value) {
          if (!mom.isValid()) {
            return mom;
          }
          if (typeof value === "string") {
            if (/^\d+$/.test(value)) {
              value = toInt(value);
            } else {
              value = mom.localeData().monthsParse(value);
              if (!isNumber2(value)) {
                return mom;
              }
            }
          }
          var month = value, date = mom.date();
          date = date < 29 ? date : Math.min(date, daysInMonth(mom.year(), month));
          void (mom._isUTC ? mom._d.setUTCMonth(month, date) : mom._d.setMonth(month, date));
          return mom;
        }
        function getSetMonth(value) {
          if (value != null) {
            setMonth(this, value);
            hooks.updateOffset(this, true);
            return this;
          } else {
            return get(this, "Month");
          }
        }
        function getDaysInMonth() {
          return daysInMonth(this.year(), this.month());
        }
        function monthsShortRegex(isStrict) {
          if (this._monthsParseExact) {
            if (!hasOwnProp(this, "_monthsRegex")) {
              computeMonthsParse.call(this);
            }
            if (isStrict) {
              return this._monthsShortStrictRegex;
            } else {
              return this._monthsShortRegex;
            }
          } else {
            if (!hasOwnProp(this, "_monthsShortRegex")) {
              this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
          }
        }
        function monthsRegex(isStrict) {
          if (this._monthsParseExact) {
            if (!hasOwnProp(this, "_monthsRegex")) {
              computeMonthsParse.call(this);
            }
            if (isStrict) {
              return this._monthsStrictRegex;
            } else {
              return this._monthsRegex;
            }
          } else {
            if (!hasOwnProp(this, "_monthsRegex")) {
              this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
          }
        }
        function computeMonthsParse() {
          function cmpLenRev(a, b) {
            return b.length - a.length;
          }
          var shortPieces = [], longPieces = [], mixedPieces = [], i, mom, shortP, longP;
          for (i = 0; i < 12; i++) {
            mom = createUTC([2e3, i]);
            shortP = regexEscape(this.monthsShort(mom, ""));
            longP = regexEscape(this.months(mom, ""));
            shortPieces.push(shortP);
            longPieces.push(longP);
            mixedPieces.push(longP);
            mixedPieces.push(shortP);
          }
          shortPieces.sort(cmpLenRev);
          longPieces.sort(cmpLenRev);
          mixedPieces.sort(cmpLenRev);
          this._monthsRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i");
          this._monthsShortRegex = this._monthsRegex;
          this._monthsStrictRegex = new RegExp("^(" + longPieces.join("|") + ")", "i");
          this._monthsShortStrictRegex = new RegExp("^(" + shortPieces.join("|") + ")", "i");
        }
        function createDate(y, m, d, h, M, s, ms) {
          var date;
          if (y < 100 && y >= 0) {
            date = new Date(y + 400, m, d, h, M, s, ms);
            if (isFinite(date.getFullYear())) {
              date.setFullYear(y);
            }
          } else {
            date = new Date(y, m, d, h, M, s, ms);
          }
          return date;
        }
        function createUTCDate(y) {
          var date, args;
          if (y < 100 && y >= 0) {
            args = Array.prototype.slice.call(arguments);
            args[0] = y + 400;
            date = new Date(Date.UTC.apply(null, args));
            if (isFinite(date.getUTCFullYear())) {
              date.setUTCFullYear(y);
            }
          } else {
            date = new Date(Date.UTC.apply(null, arguments));
          }
          return date;
        }
        function firstWeekOffset(year, dow, doy) {
          var fwd = 7 + dow - doy, fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
          return -fwdlw + fwd - 1;
        }
        function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
          var localWeekday = (7 + weekday - dow) % 7, weekOffset = firstWeekOffset(year, dow, doy), dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, resYear, resDayOfYear;
          if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
          } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
          } else {
            resYear = year;
            resDayOfYear = dayOfYear;
          }
          return {
            year: resYear,
            dayOfYear: resDayOfYear
          };
        }
        function weekOfYear(mom, dow, doy) {
          var weekOffset = firstWeekOffset(mom.year(), dow, doy), week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, resWeek, resYear;
          if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
          } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
          } else {
            resYear = mom.year();
            resWeek = week;
          }
          return {
            week: resWeek,
            year: resYear
          };
        }
        function weeksInYear(year, dow, doy) {
          var weekOffset = firstWeekOffset(year, dow, doy), weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
          return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
        }
        addFormatToken("w", ["ww", 2], "wo", "week");
        addFormatToken("W", ["WW", 2], "Wo", "isoWeek");
        addRegexToken("w", match1to2, match1to2NoLeadingZero);
        addRegexToken("ww", match1to2, match2);
        addRegexToken("W", match1to2, match1to2NoLeadingZero);
        addRegexToken("WW", match1to2, match2);
        addWeekParseToken(["w", "ww", "W", "WW"], function(input, week, config2, token2) {
          week[token2.substr(0, 1)] = toInt(input);
        });
        function localeWeek(mom) {
          return weekOfYear(mom, this._week.dow, this._week.doy).week;
        }
        var defaultLocaleWeek = {
          dow: 0,
          doy: 6
        };
        function localeFirstDayOfWeek() {
          return this._week.dow;
        }
        function localeFirstDayOfYear() {
          return this._week.doy;
        }
        function getSetWeek(input) {
          var week = this.localeData().week(this);
          return input == null ? week : this.add((input - week) * 7, "d");
        }
        function getSetISOWeek(input) {
          var week = weekOfYear(this, 1, 4).week;
          return input == null ? week : this.add((input - week) * 7, "d");
        }
        addFormatToken("d", 0, "do", "day");
        addFormatToken("dd", 0, 0, function(format2) {
          return this.localeData().weekdaysMin(this, format2);
        });
        addFormatToken("ddd", 0, 0, function(format2) {
          return this.localeData().weekdaysShort(this, format2);
        });
        addFormatToken("dddd", 0, 0, function(format2) {
          return this.localeData().weekdays(this, format2);
        });
        addFormatToken("e", 0, 0, "weekday");
        addFormatToken("E", 0, 0, "isoWeekday");
        addRegexToken("d", match1to2);
        addRegexToken("e", match1to2);
        addRegexToken("E", match1to2);
        addRegexToken("dd", function(isStrict, locale2) {
          return locale2.weekdaysMinRegex(isStrict);
        });
        addRegexToken("ddd", function(isStrict, locale2) {
          return locale2.weekdaysShortRegex(isStrict);
        });
        addRegexToken("dddd", function(isStrict, locale2) {
          return locale2.weekdaysRegex(isStrict);
        });
        addWeekParseToken(["dd", "ddd", "dddd"], function(input, week, config2, token2) {
          var weekday = config2._locale.weekdaysParse(input, token2, config2._strict);
          if (weekday != null) {
            week.d = weekday;
          } else {
            getParsingFlags(config2).invalidWeekday = input;
          }
        });
        addWeekParseToken(["d", "e", "E"], function(input, week, config2, token2) {
          week[token2] = toInt(input);
        });
        function parseWeekday(input, locale2) {
          if (typeof input !== "string") {
            return input;
          }
          if (!isNaN(input)) {
            return parseInt(input, 10);
          }
          input = locale2.weekdaysParse(input);
          if (typeof input === "number") {
            return input;
          }
          return null;
        }
        function parseIsoWeekday(input, locale2) {
          if (typeof input === "string") {
            return locale2.weekdaysParse(input) % 7 || 7;
          }
          return isNaN(input) ? null : input;
        }
        function shiftWeekdays(ws, n) {
          return ws.slice(n, 7).concat(ws.slice(0, n));
        }
        var defaultLocaleWeekdays = "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), defaultLocaleWeekdaysShort = "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), defaultLocaleWeekdaysMin = "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), defaultWeekdaysRegex = matchWord, defaultWeekdaysShortRegex = matchWord, defaultWeekdaysMinRegex = matchWord;
        function localeWeekdays(m, format2) {
          var weekdays = isArray3(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format2) ? "format" : "standalone"];
          return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
        }
        function localeWeekdaysShort(m) {
          return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
        }
        function localeWeekdaysMin(m) {
          return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
        }
        function handleStrictParse$1(weekdayName, format2, strict) {
          var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
          if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];
            for (i = 0; i < 7; ++i) {
              mom = createUTC([2e3, 1]).day(i);
              this._minWeekdaysParse[i] = this.weekdaysMin(mom, "").toLocaleLowerCase();
              this._shortWeekdaysParse[i] = this.weekdaysShort(mom, "").toLocaleLowerCase();
              this._weekdaysParse[i] = this.weekdays(mom, "").toLocaleLowerCase();
            }
          }
          if (strict) {
            if (format2 === "dddd") {
              ii = indexOf.call(this._weekdaysParse, llc);
              return ii !== -1 ? ii : null;
            } else if (format2 === "ddd") {
              ii = indexOf.call(this._shortWeekdaysParse, llc);
              return ii !== -1 ? ii : null;
            } else {
              ii = indexOf.call(this._minWeekdaysParse, llc);
              return ii !== -1 ? ii : null;
            }
          } else {
            if (format2 === "dddd") {
              ii = indexOf.call(this._weekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._shortWeekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._minWeekdaysParse, llc);
              return ii !== -1 ? ii : null;
            } else if (format2 === "ddd") {
              ii = indexOf.call(this._shortWeekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._weekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._minWeekdaysParse, llc);
              return ii !== -1 ? ii : null;
            } else {
              ii = indexOf.call(this._minWeekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._weekdaysParse, llc);
              if (ii !== -1) {
                return ii;
              }
              ii = indexOf.call(this._shortWeekdaysParse, llc);
              return ii !== -1 ? ii : null;
            }
          }
        }
        function localeWeekdaysParse(weekdayName, format2, strict) {
          var i, mom, regex;
          if (this._weekdaysParseExact) {
            return handleStrictParse$1.call(this, weekdayName, format2, strict);
          }
          if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
          }
          for (i = 0; i < 7; i++) {
            mom = createUTC([2e3, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
              this._fullWeekdaysParse[i] = new RegExp("^" + this.weekdays(mom, "").replace(".", "\\.?") + "$", "i");
              this._shortWeekdaysParse[i] = new RegExp("^" + this.weekdaysShort(mom, "").replace(".", "\\.?") + "$", "i");
              this._minWeekdaysParse[i] = new RegExp("^" + this.weekdaysMin(mom, "").replace(".", "\\.?") + "$", "i");
            }
            if (!this._weekdaysParse[i]) {
              regex = "^" + this.weekdays(mom, "") + "|^" + this.weekdaysShort(mom, "") + "|^" + this.weekdaysMin(mom, "");
              this._weekdaysParse[i] = new RegExp(regex.replace(".", ""), "i");
            }
            if (strict && format2 === "dddd" && this._fullWeekdaysParse[i].test(weekdayName)) {
              return i;
            } else if (strict && format2 === "ddd" && this._shortWeekdaysParse[i].test(weekdayName)) {
              return i;
            } else if (strict && format2 === "dd" && this._minWeekdaysParse[i].test(weekdayName)) {
              return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
              return i;
            }
          }
        }
        function getSetDayOfWeek(input) {
          if (!this.isValid()) {
            return input != null ? this : NaN;
          }
          var day = get(this, "Day");
          if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, "d");
          } else {
            return day;
          }
        }
        function getSetLocaleDayOfWeek(input) {
          if (!this.isValid()) {
            return input != null ? this : NaN;
          }
          var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
          return input == null ? weekday : this.add(input - weekday, "d");
        }
        function getSetISODayOfWeek(input) {
          if (!this.isValid()) {
            return input != null ? this : NaN;
          }
          if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
          } else {
            return this.day() || 7;
          }
        }
        function weekdaysRegex(isStrict) {
          if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, "_weekdaysRegex")) {
              computeWeekdaysParse.call(this);
            }
            if (isStrict) {
              return this._weekdaysStrictRegex;
            } else {
              return this._weekdaysRegex;
            }
          } else {
            if (!hasOwnProp(this, "_weekdaysRegex")) {
              this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
          }
        }
        function weekdaysShortRegex(isStrict) {
          if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, "_weekdaysRegex")) {
              computeWeekdaysParse.call(this);
            }
            if (isStrict) {
              return this._weekdaysShortStrictRegex;
            } else {
              return this._weekdaysShortRegex;
            }
          } else {
            if (!hasOwnProp(this, "_weekdaysShortRegex")) {
              this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
          }
        }
        function weekdaysMinRegex(isStrict) {
          if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, "_weekdaysRegex")) {
              computeWeekdaysParse.call(this);
            }
            if (isStrict) {
              return this._weekdaysMinStrictRegex;
            } else {
              return this._weekdaysMinRegex;
            }
          } else {
            if (!hasOwnProp(this, "_weekdaysMinRegex")) {
              this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
          }
        }
        function computeWeekdaysParse() {
          function cmpLenRev(a, b) {
            return b.length - a.length;
          }
          var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], i, mom, minp, shortp, longp;
          for (i = 0; i < 7; i++) {
            mom = createUTC([2e3, 1]).day(i);
            minp = regexEscape(this.weekdaysMin(mom, ""));
            shortp = regexEscape(this.weekdaysShort(mom, ""));
            longp = regexEscape(this.weekdays(mom, ""));
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
          }
          minPieces.sort(cmpLenRev);
          shortPieces.sort(cmpLenRev);
          longPieces.sort(cmpLenRev);
          mixedPieces.sort(cmpLenRev);
          this._weekdaysRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i");
          this._weekdaysShortRegex = this._weekdaysRegex;
          this._weekdaysMinRegex = this._weekdaysRegex;
          this._weekdaysStrictRegex = new RegExp("^(" + longPieces.join("|") + ")", "i");
          this._weekdaysShortStrictRegex = new RegExp("^(" + shortPieces.join("|") + ")", "i");
          this._weekdaysMinStrictRegex = new RegExp("^(" + minPieces.join("|") + ")", "i");
        }
        function hFormat() {
          return this.hours() % 12 || 12;
        }
        function kFormat() {
          return this.hours() || 24;
        }
        addFormatToken("H", ["HH", 2], 0, "hour");
        addFormatToken("h", ["hh", 2], 0, hFormat);
        addFormatToken("k", ["kk", 2], 0, kFormat);
        addFormatToken("hmm", 0, 0, function() {
          return "" + hFormat.apply(this) + zeroFill(this.minutes(), 2);
        });
        addFormatToken("hmmss", 0, 0, function() {
          return "" + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
        });
        addFormatToken("Hmm", 0, 0, function() {
          return "" + this.hours() + zeroFill(this.minutes(), 2);
        });
        addFormatToken("Hmmss", 0, 0, function() {
          return "" + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
        });
        function meridiem(token2, lowercase) {
          addFormatToken(token2, 0, 0, function() {
            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
          });
        }
        meridiem("a", true);
        meridiem("A", false);
        function matchMeridiem(isStrict, locale2) {
          return locale2._meridiemParse;
        }
        addRegexToken("a", matchMeridiem);
        addRegexToken("A", matchMeridiem);
        addRegexToken("H", match1to2, match1to2HasZero);
        addRegexToken("h", match1to2, match1to2NoLeadingZero);
        addRegexToken("k", match1to2, match1to2NoLeadingZero);
        addRegexToken("HH", match1to2, match2);
        addRegexToken("hh", match1to2, match2);
        addRegexToken("kk", match1to2, match2);
        addRegexToken("hmm", match3to4);
        addRegexToken("hmmss", match5to6);
        addRegexToken("Hmm", match3to4);
        addRegexToken("Hmmss", match5to6);
        addParseToken(["H", "HH"], HOUR);
        addParseToken(["k", "kk"], function(input, array, config2) {
          var kInput = toInt(input);
          array[HOUR] = kInput === 24 ? 0 : kInput;
        });
        addParseToken(["a", "A"], function(input, array, config2) {
          config2._isPm = config2._locale.isPM(input);
          config2._meridiem = input;
        });
        addParseToken(["h", "hh"], function(input, array, config2) {
          array[HOUR] = toInt(input);
          getParsingFlags(config2).bigHour = true;
        });
        addParseToken("hmm", function(input, array, config2) {
          var pos = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos));
          array[MINUTE] = toInt(input.substr(pos));
          getParsingFlags(config2).bigHour = true;
        });
        addParseToken("hmmss", function(input, array, config2) {
          var pos1 = input.length - 4, pos2 = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos1));
          array[MINUTE] = toInt(input.substr(pos1, 2));
          array[SECOND] = toInt(input.substr(pos2));
          getParsingFlags(config2).bigHour = true;
        });
        addParseToken("Hmm", function(input, array, config2) {
          var pos = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos));
          array[MINUTE] = toInt(input.substr(pos));
        });
        addParseToken("Hmmss", function(input, array, config2) {
          var pos1 = input.length - 4, pos2 = input.length - 2;
          array[HOUR] = toInt(input.substr(0, pos1));
          array[MINUTE] = toInt(input.substr(pos1, 2));
          array[SECOND] = toInt(input.substr(pos2));
        });
        function localeIsPM(input) {
          return (input + "").toLowerCase().charAt(0) === "p";
        }
        var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i, getSetHour = makeGetSet("Hours", true);
        function localeMeridiem(hours2, minutes2, isLower) {
          if (hours2 > 11) {
            return isLower ? "pm" : "PM";
          } else {
            return isLower ? "am" : "AM";
          }
        }
        var baseConfig = {
          calendar: defaultCalendar,
          longDateFormat: defaultLongDateFormat,
          invalidDate: defaultInvalidDate,
          ordinal: defaultOrdinal,
          dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
          relativeTime: defaultRelativeTime,
          months: defaultLocaleMonths,
          monthsShort: defaultLocaleMonthsShort,
          week: defaultLocaleWeek,
          weekdays: defaultLocaleWeekdays,
          weekdaysMin: defaultLocaleWeekdaysMin,
          weekdaysShort: defaultLocaleWeekdaysShort,
          meridiemParse: defaultLocaleMeridiemParse
        };
        var locales = {}, localeFamilies = {}, globalLocale;
        function commonPrefix(arr1, arr2) {
          var i, minl = Math.min(arr1.length, arr2.length);
          for (i = 0; i < minl; i += 1) {
            if (arr1[i] !== arr2[i]) {
              return i;
            }
          }
          return minl;
        }
        function normalizeLocale(key) {
          return key ? key.toLowerCase().replace("_", "-") : key;
        }
        function chooseLocale(names) {
          var i = 0, j, next, locale2, split;
          while (i < names.length) {
            split = normalizeLocale(names[i]).split("-");
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split("-") : null;
            while (j > 0) {
              locale2 = loadLocale(split.slice(0, j).join("-"));
              if (locale2) {
                return locale2;
              }
              if (next && next.length >= j && commonPrefix(split, next) >= j - 1) {
                break;
              }
              j--;
            }
            i++;
          }
          return globalLocale;
        }
        function isLocaleNameSane(name) {
          return !!(name && name.match("^[^/\\\\]*$"));
        }
        function loadLocale(name) {
          var oldLocale = null, aliasedRequire;
          if (locales[name] === void 0 && typeof module !== "undefined" && module && module.exports && isLocaleNameSane(name)) {
            try {
              oldLocale = globalLocale._abbr;
              aliasedRequire = __require;
              aliasedRequire("./locale/" + name);
              getSetGlobalLocale(oldLocale);
            } catch (e) {
              locales[name] = null;
            }
          }
          return locales[name];
        }
        function getSetGlobalLocale(key, values) {
          var data;
          if (key) {
            if (isUndefined2(values)) {
              data = getLocale(key);
            } else {
              data = defineLocale(key, values);
            }
            if (data) {
              globalLocale = data;
            } else {
              if (typeof console !== "undefined" && console.warn) {
                console.warn("Locale " + key + " not found. Did you forget to load it?");
              }
            }
          }
          return globalLocale._abbr;
        }
        function defineLocale(name, config2) {
          if (config2 !== null) {
            var locale2, parentConfig = baseConfig;
            config2.abbr = name;
            if (locales[name] != null) {
              deprecateSimple("defineLocaleOverride", "use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info.");
              parentConfig = locales[name]._config;
            } else if (config2.parentLocale != null) {
              if (locales[config2.parentLocale] != null) {
                parentConfig = locales[config2.parentLocale]._config;
              } else {
                locale2 = loadLocale(config2.parentLocale);
                if (locale2 != null) {
                  parentConfig = locale2._config;
                } else {
                  if (!localeFamilies[config2.parentLocale]) {
                    localeFamilies[config2.parentLocale] = [];
                  }
                  localeFamilies[config2.parentLocale].push({
                    name,
                    config: config2
                  });
                  return null;
                }
              }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config2));
            if (localeFamilies[name]) {
              localeFamilies[name].forEach(function(x) {
                defineLocale(x.name, x.config);
              });
            }
            getSetGlobalLocale(name);
            return locales[name];
          } else {
            delete locales[name];
            return null;
          }
        }
        function updateLocale(name, config2) {
          if (config2 != null) {
            var locale2, tmpLocale, parentConfig = baseConfig;
            if (locales[name] != null && locales[name].parentLocale != null) {
              locales[name].set(mergeConfigs(locales[name]._config, config2));
            } else {
              tmpLocale = loadLocale(name);
              if (tmpLocale != null) {
                parentConfig = tmpLocale._config;
              }
              config2 = mergeConfigs(parentConfig, config2);
              if (tmpLocale == null) {
                config2.abbr = name;
              }
              locale2 = new Locale(config2);
              locale2.parentLocale = locales[name];
              locales[name] = locale2;
            }
            getSetGlobalLocale(name);
          } else {
            if (locales[name] != null) {
              if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
                if (name === getSetGlobalLocale()) {
                  getSetGlobalLocale(name);
                }
              } else if (locales[name] != null) {
                delete locales[name];
              }
            }
          }
          return locales[name];
        }
        function getLocale(key) {
          var locale2;
          if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
          }
          if (!key) {
            return globalLocale;
          }
          if (!isArray3(key)) {
            locale2 = loadLocale(key);
            if (locale2) {
              return locale2;
            }
            key = [key];
          }
          return chooseLocale(key);
        }
        function listLocales() {
          return keys2(locales);
        }
        function checkOverflow(m) {
          var overflow, a = m._a;
          if (a && getParsingFlags(m).overflow === -2) {
            overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1;
            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
              overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
              overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
              overflow = WEEKDAY;
            }
            getParsingFlags(m).overflow = overflow;
          }
          return m;
        }
        var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, isoDates = [["YYYYYY-MM-DD", /[+-]\d{6}-\d\d-\d\d/], ["YYYY-MM-DD", /\d{4}-\d\d-\d\d/], ["GGGG-[W]WW-E", /\d{4}-W\d\d-\d/], ["GGGG-[W]WW", /\d{4}-W\d\d/, false], ["YYYY-DDD", /\d{4}-\d{3}/], ["YYYY-MM", /\d{4}-\d\d/, false], ["YYYYYYMMDD", /[+-]\d{10}/], ["YYYYMMDD", /\d{8}/], ["GGGG[W]WWE", /\d{4}W\d{3}/], ["GGGG[W]WW", /\d{4}W\d{2}/, false], ["YYYYDDD", /\d{7}/], ["YYYYMM", /\d{6}/, false], ["YYYY", /\d{4}/, false]], isoTimes = [["HH:mm:ss.SSSS", /\d\d:\d\d:\d\d\.\d+/], ["HH:mm:ss,SSSS", /\d\d:\d\d:\d\d,\d+/], ["HH:mm:ss", /\d\d:\d\d:\d\d/], ["HH:mm", /\d\d:\d\d/], ["HHmmss.SSSS", /\d\d\d\d\d\d\.\d+/], ["HHmmss,SSSS", /\d\d\d\d\d\d,\d+/], ["HHmmss", /\d\d\d\d\d\d/], ["HHmm", /\d\d\d\d/], ["HH", /\d\d/]], aspNetJsonRegex = /^\/?Date\((-?\d+)/i, rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, obsOffsets = {
          UT: 0,
          GMT: 0,
          EDT: -4 * 60,
          EST: -5 * 60,
          CDT: -5 * 60,
          CST: -6 * 60,
          MDT: -6 * 60,
          MST: -7 * 60,
          PDT: -7 * 60,
          PST: -8 * 60
        };
        function configFromISO(config2) {
          var i, l, string = config2._i, match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), allowTime, dateFormat, timeFormat, tzFormat, isoDatesLen = isoDates.length, isoTimesLen = isoTimes.length;
          if (match) {
            getParsingFlags(config2).iso = true;
            for (i = 0, l = isoDatesLen; i < l; i++) {
              if (isoDates[i][1].exec(match[1])) {
                dateFormat = isoDates[i][0];
                allowTime = isoDates[i][2] !== false;
                break;
              }
            }
            if (dateFormat == null) {
              config2._isValid = false;
              return;
            }
            if (match[3]) {
              for (i = 0, l = isoTimesLen; i < l; i++) {
                if (isoTimes[i][1].exec(match[3])) {
                  timeFormat = (match[2] || " ") + isoTimes[i][0];
                  break;
                }
              }
              if (timeFormat == null) {
                config2._isValid = false;
                return;
              }
            }
            if (!allowTime && timeFormat != null) {
              config2._isValid = false;
              return;
            }
            if (match[4]) {
              if (tzRegex.exec(match[4])) {
                tzFormat = "Z";
              } else {
                config2._isValid = false;
                return;
              }
            }
            config2._f = dateFormat + (timeFormat || "") + (tzFormat || "");
            configFromStringAndFormat(config2);
          } else {
            config2._isValid = false;
          }
        }
        function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
          var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
          if (secondStr) {
            result.push(parseInt(secondStr, 10));
          }
          return result;
        }
        function untruncateYear(yearStr) {
          var year = parseInt(yearStr, 10);
          if (year <= 49) {
            return 2e3 + year;
          } else if (year <= 999) {
            return 1900 + year;
          }
          return year;
        }
        function preprocessRFC2822(s) {
          return s.replace(/\([^()]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").replace(/^\s\s*/, "").replace(/\s\s*$/, "");
        }
        function checkWeekday(weekdayStr, parsedInput, config2) {
          if (weekdayStr) {
            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
            if (weekdayProvided !== weekdayActual) {
              getParsingFlags(config2).weekdayMismatch = true;
              config2._isValid = false;
              return false;
            }
          }
          return true;
        }
        function calculateOffset(obsOffset, militaryOffset, numOffset) {
          if (obsOffset) {
            return obsOffsets[obsOffset];
          } else if (militaryOffset) {
            return 0;
          } else {
            var hm = parseInt(numOffset, 10), m = hm % 100, h = (hm - m) / 100;
            return h * 60 + m;
          }
        }
        function configFromRFC2822(config2) {
          var match = rfc2822.exec(preprocessRFC2822(config2._i)), parsedArray;
          if (match) {
            parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
            if (!checkWeekday(match[1], parsedArray, config2)) {
              return;
            }
            config2._a = parsedArray;
            config2._tzm = calculateOffset(match[8], match[9], match[10]);
            config2._d = createUTCDate.apply(null, config2._a);
            config2._d.setUTCMinutes(config2._d.getUTCMinutes() - config2._tzm);
            getParsingFlags(config2).rfc2822 = true;
          } else {
            config2._isValid = false;
          }
        }
        function configFromString(config2) {
          var matched = aspNetJsonRegex.exec(config2._i);
          if (matched !== null) {
            config2._d =  new Date(+matched[1]);
            return;
          }
          configFromISO(config2);
          if (config2._isValid === false) {
            delete config2._isValid;
          } else {
            return;
          }
          configFromRFC2822(config2);
          if (config2._isValid === false) {
            delete config2._isValid;
          } else {
            return;
          }
          if (config2._strict) {
            config2._isValid = false;
          } else {
            hooks.createFromInputFallback(config2);
          }
        }
        hooks.createFromInputFallback = deprecate("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.", function(config2) {
          config2._d =  new Date(config2._i + (config2._useUTC ? " UTC" : ""));
        });
        function defaults(a, b, c) {
          if (a != null) {
            return a;
          }
          if (b != null) {
            return b;
          }
          return c;
        }
        function currentDateArray(config2) {
          var nowValue = new Date(hooks.now());
          if (config2._useUTC) {
            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
          }
          return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
        }
        function configFromArray(config2) {
          var i, date, input = [], currentDate, expectedWeekday, yearToUse;
          if (config2._d) {
            return;
          }
          currentDate = currentDateArray(config2);
          if (config2._w && config2._a[DATE] == null && config2._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config2);
          }
          if (config2._dayOfYear != null) {
            yearToUse = defaults(config2._a[YEAR], currentDate[YEAR]);
            if (config2._dayOfYear > daysInYear(yearToUse) || config2._dayOfYear === 0) {
              getParsingFlags(config2)._overflowDayOfYear = true;
            }
            date = createUTCDate(yearToUse, 0, config2._dayOfYear);
            config2._a[MONTH] = date.getUTCMonth();
            config2._a[DATE] = date.getUTCDate();
          }
          for (i = 0; i < 3 && config2._a[i] == null; ++i) {
            config2._a[i] = input[i] = currentDate[i];
          }
          for (; i < 7; i++) {
            config2._a[i] = input[i] = config2._a[i] == null ? i === 2 ? 1 : 0 : config2._a[i];
          }
          if (config2._a[HOUR] === 24 && config2._a[MINUTE] === 0 && config2._a[SECOND] === 0 && config2._a[MILLISECOND] === 0) {
            config2._nextDay = true;
            config2._a[HOUR] = 0;
          }
          config2._d = (config2._useUTC ? createUTCDate : createDate).apply(null, input);
          expectedWeekday = config2._useUTC ? config2._d.getUTCDay() : config2._d.getDay();
          if (config2._tzm != null) {
            config2._d.setUTCMinutes(config2._d.getUTCMinutes() - config2._tzm);
          }
          if (config2._nextDay) {
            config2._a[HOUR] = 24;
          }
          if (config2._w && typeof config2._w.d !== "undefined" && config2._w.d !== expectedWeekday) {
            getParsingFlags(config2).weekdayMismatch = true;
          }
        }
        function dayOfYearFromWeekInfo(config2) {
          var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
          w = config2._w;
          if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;
            weekYear = defaults(w.GG, config2._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
              weekdayOverflow = true;
            }
          } else {
            dow = config2._locale._week.dow;
            doy = config2._locale._week.doy;
            curWeek = weekOfYear(createLocal(), dow, doy);
            weekYear = defaults(w.gg, config2._a[YEAR], curWeek.year);
            week = defaults(w.w, curWeek.week);
            if (w.d != null) {
              weekday = w.d;
              if (weekday < 0 || weekday > 6) {
                weekdayOverflow = true;
              }
            } else if (w.e != null) {
              weekday = w.e + dow;
              if (w.e < 0 || w.e > 6) {
                weekdayOverflow = true;
              }
            } else {
              weekday = dow;
            }
          }
          if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config2)._overflowWeeks = true;
          } else if (weekdayOverflow != null) {
            getParsingFlags(config2)._overflowWeekday = true;
          } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config2._a[YEAR] = temp.year;
            config2._dayOfYear = temp.dayOfYear;
          }
        }
        hooks.ISO_8601 = function() {
        };
        hooks.RFC_2822 = function() {
        };
        function configFromStringAndFormat(config2) {
          if (config2._f === hooks.ISO_8601) {
            configFromISO(config2);
            return;
          }
          if (config2._f === hooks.RFC_2822) {
            configFromRFC2822(config2);
            return;
          }
          config2._a = [];
          getParsingFlags(config2).empty = true;
          var string = "" + config2._i, i, parsedInput, tokens2, token2, skipped, stringLength = string.length, totalParsedInputLength = 0, era, tokenLen;
          tokens2 = expandFormat(config2._f, config2._locale).match(formattingTokens) || [];
          tokenLen = tokens2.length;
          for (i = 0; i < tokenLen; i++) {
            token2 = tokens2[i];
            parsedInput = (string.match(getParseRegexForToken(token2, config2)) || [])[0];
            if (parsedInput) {
              skipped = string.substr(0, string.indexOf(parsedInput));
              if (skipped.length > 0) {
                getParsingFlags(config2).unusedInput.push(skipped);
              }
              string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
              totalParsedInputLength += parsedInput.length;
            }
            if (formatTokenFunctions[token2]) {
              if (parsedInput) {
                getParsingFlags(config2).empty = false;
              } else {
                getParsingFlags(config2).unusedTokens.push(token2);
              }
              addTimeToArrayFromToken(token2, parsedInput, config2);
            } else if (config2._strict && !parsedInput) {
              getParsingFlags(config2).unusedTokens.push(token2);
            }
          }
          getParsingFlags(config2).charsLeftOver = stringLength - totalParsedInputLength;
          if (string.length > 0) {
            getParsingFlags(config2).unusedInput.push(string);
          }
          if (config2._a[HOUR] <= 12 && getParsingFlags(config2).bigHour === true && config2._a[HOUR] > 0) {
            getParsingFlags(config2).bigHour = void 0;
          }
          getParsingFlags(config2).parsedDateParts = config2._a.slice(0);
          getParsingFlags(config2).meridiem = config2._meridiem;
          config2._a[HOUR] = meridiemFixWrap(config2._locale, config2._a[HOUR], config2._meridiem);
          era = getParsingFlags(config2).era;
          if (era !== null) {
            config2._a[YEAR] = config2._locale.erasConvertYear(era, config2._a[YEAR]);
          }
          configFromArray(config2);
          checkOverflow(config2);
        }
        function meridiemFixWrap(locale2, hour, meridiem2) {
          var isPm;
          if (meridiem2 == null) {
            return hour;
          }
          if (locale2.meridiemHour != null) {
            return locale2.meridiemHour(hour, meridiem2);
          } else if (locale2.isPM != null) {
            isPm = locale2.isPM(meridiem2);
            if (isPm && hour < 12) {
              hour += 12;
            }
            if (!isPm && hour === 12) {
              hour = 0;
            }
            return hour;
          } else {
            return hour;
          }
        }
        function configFromStringAndArray(config2) {
          var tempConfig, bestMoment, scoreToBeat, i, currentScore, validFormatFound, bestFormatIsValid = false, configfLen = config2._f.length;
          if (configfLen === 0) {
            getParsingFlags(config2).invalidFormat = true;
            config2._d =  new Date(NaN);
            return;
          }
          for (i = 0; i < configfLen; i++) {
            currentScore = 0;
            validFormatFound = false;
            tempConfig = copyConfig({}, config2);
            if (config2._useUTC != null) {
              tempConfig._useUTC = config2._useUTC;
            }
            tempConfig._f = config2._f[i];
            configFromStringAndFormat(tempConfig);
            if (isValid(tempConfig)) {
              validFormatFound = true;
            }
            currentScore += getParsingFlags(tempConfig).charsLeftOver;
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
            getParsingFlags(tempConfig).score = currentScore;
            if (!bestFormatIsValid) {
              if (scoreToBeat == null || currentScore < scoreToBeat || validFormatFound) {
                scoreToBeat = currentScore;
                bestMoment = tempConfig;
                if (validFormatFound) {
                  bestFormatIsValid = true;
                }
              }
            } else {
              if (currentScore < scoreToBeat) {
                scoreToBeat = currentScore;
                bestMoment = tempConfig;
              }
            }
          }
          extend2(config2, bestMoment || tempConfig);
        }
        function configFromObject(config2) {
          if (config2._d) {
            return;
          }
          var i = normalizeObjectUnits(config2._i), dayOrDate = i.day === void 0 ? i.date : i.day;
          config2._a = map([i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond], function(obj) {
            return obj && parseInt(obj, 10);
          });
          configFromArray(config2);
        }
        function createFromConfig(config2) {
          var res = new Moment2(checkOverflow(prepareConfig(config2)));
          if (res._nextDay) {
            res.add(1, "d");
            res._nextDay = void 0;
          }
          return res;
        }
        function prepareConfig(config2) {
          var input = config2._i, format2 = config2._f;
          config2._locale = config2._locale || getLocale(config2._l);
          if (input === null || format2 === void 0 && input === "") {
            return createInvalid({
              nullInput: true
            });
          }
          if (typeof input === "string") {
            config2._i = input = config2._locale.preparse(input);
          }
          if (isMoment(input)) {
            return new Moment2(checkOverflow(input));
          } else if (isDate(input)) {
            config2._d = input;
          } else if (isArray3(format2)) {
            configFromStringAndArray(config2);
          } else if (format2) {
            configFromStringAndFormat(config2);
          } else {
            configFromInput(config2);
          }
          if (!isValid(config2)) {
            config2._d = null;
          }
          return config2;
        }
        function configFromInput(config2) {
          var input = config2._i;
          if (isUndefined2(input)) {
            config2._d = new Date(hooks.now());
          } else if (isDate(input)) {
            config2._d = new Date(input.valueOf());
          } else if (typeof input === "string") {
            configFromString(config2);
          } else if (isArray3(input)) {
            config2._a = map(input.slice(0), function(obj) {
              return parseInt(obj, 10);
            });
            configFromArray(config2);
          } else if (isObject2(input)) {
            configFromObject(config2);
          } else if (isNumber2(input)) {
            config2._d = new Date(input);
          } else {
            hooks.createFromInputFallback(config2);
          }
        }
        function createLocalOrUTC(input, format2, locale2, strict, isUTC) {
          var c = {};
          if (format2 === true || format2 === false) {
            strict = format2;
            format2 = void 0;
          }
          if (locale2 === true || locale2 === false) {
            strict = locale2;
            locale2 = void 0;
          }
          if (isObject2(input) && isObjectEmpty(input) || isArray3(input) && input.length === 0) {
            input = void 0;
          }
          c._isAMomentObject = true;
          c._useUTC = c._isUTC = isUTC;
          c._l = locale2;
          c._i = input;
          c._f = format2;
          c._strict = strict;
          return createFromConfig(c);
        }
        function createLocal(input, format2, locale2, strict) {
          return createLocalOrUTC(input, format2, locale2, strict, false);
        }
        var prototypeMin = deprecate("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/", function() {
          var other = createLocal.apply(null, arguments);
          if (this.isValid() && other.isValid()) {
            return other < this ? this : other;
          } else {
            return createInvalid();
          }
        }), prototypeMax = deprecate("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/", function() {
          var other = createLocal.apply(null, arguments);
          if (this.isValid() && other.isValid()) {
            return other > this ? this : other;
          } else {
            return createInvalid();
          }
        });
        function pickBy(fn, moments) {
          var res, i;
          if (moments.length === 1 && isArray3(moments[0])) {
            moments = moments[0];
          }
          if (!moments.length) {
            return createLocal();
          }
          res = moments[0];
          for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
              res = moments[i];
            }
          }
          return res;
        }
        function min() {
          var args = [].slice.call(arguments, 0);
          return pickBy("isBefore", args);
        }
        function max() {
          var args = [].slice.call(arguments, 0);
          return pickBy("isAfter", args);
        }
        var now = function() {
          return Date.now ? Date.now() : + new Date();
        };
        var ordering = ["year", "quarter", "month", "week", "day", "hour", "minute", "second", "millisecond"];
        function isDurationValid(m) {
          var key, unitHasDecimal = false, i, orderLen = ordering.length;
          for (key in m) {
            if (hasOwnProp(m, key) && !(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
              return false;
            }
          }
          for (i = 0; i < orderLen; ++i) {
            if (m[ordering[i]]) {
              if (unitHasDecimal) {
                return false;
              }
              if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                unitHasDecimal = true;
              }
            }
          }
          return true;
        }
        function isValid$1() {
          return this._isValid;
        }
        function createInvalid$1() {
          return createDuration(NaN);
        }
        function Duration(duration) {
          var normalizedInput = normalizeObjectUnits(duration), years2 = normalizedInput.year || 0, quarters = normalizedInput.quarter || 0, months2 = normalizedInput.month || 0, weeks2 = normalizedInput.week || normalizedInput.isoWeek || 0, days2 = normalizedInput.day || 0, hours2 = normalizedInput.hour || 0, minutes2 = normalizedInput.minute || 0, seconds2 = normalizedInput.second || 0, milliseconds2 = normalizedInput.millisecond || 0;
          this._isValid = isDurationValid(normalizedInput);
          this._milliseconds = +milliseconds2 + seconds2 * 1e3 + minutes2 * 6e4 + hours2 * 1e3 * 60 * 60;
          this._days = +days2 + weeks2 * 7;
          this._months = +months2 + quarters * 3 + years2 * 12;
          this._data = {};
          this._locale = getLocale();
          this._bubble();
        }
        function isDuration(obj) {
          return obj instanceof Duration;
        }
        function absRound(number) {
          if (number < 0) {
            return Math.round(-1 * number) * -1;
          } else {
            return Math.round(number);
          }
        }
        function compareArrays2(array1, array2, dontConvert) {
          var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), diffs = 0, i;
          for (i = 0; i < len; i++) {
            if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
              diffs++;
            }
          }
          return diffs + lengthDiff;
        }
        function offset(token2, separator) {
          addFormatToken(token2, 0, 0, function() {
            var offset2 = this.utcOffset(), sign2 = "+";
            if (offset2 < 0) {
              offset2 = -offset2;
              sign2 = "-";
            }
            return sign2 + zeroFill(~~(offset2 / 60), 2) + separator + zeroFill(~~offset2 % 60, 2);
          });
        }
        offset("Z", ":");
        offset("ZZ", "");
        addRegexToken("Z", matchShortOffset);
        addRegexToken("ZZ", matchShortOffset);
        addParseToken(["Z", "ZZ"], function(input, array, config2) {
          config2._useUTC = true;
          config2._tzm = offsetFromString(matchShortOffset, input);
        });
        var chunkOffset = /([\+\-]|\d\d)/gi;
        function offsetFromString(matcher, string) {
          var matches = (string || "").match(matcher), chunk, parts, minutes2;
          if (matches === null) {
            return null;
          }
          chunk = matches[matches.length - 1] || [];
          parts = (chunk + "").match(chunkOffset) || ["-", 0, 0];
          minutes2 = +(parts[1] * 60) + toInt(parts[2]);
          return minutes2 === 0 ? 0 : parts[0] === "+" ? minutes2 : -minutes2;
        }
        function cloneWithOffset(input, model) {
          var res, diff2;
          if (model._isUTC) {
            res = model.clone();
            diff2 = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
            res._d.setTime(res._d.valueOf() + diff2);
            hooks.updateOffset(res, false);
            return res;
          } else {
            return createLocal(input).local();
          }
        }
        function getDateOffset(m) {
          return -Math.round(m._d.getTimezoneOffset());
        }
        hooks.updateOffset = function() {
        };
        function getSetOffset(input, keepLocalTime, keepMinutes) {
          var offset2 = this._offset || 0, localAdjust;
          if (!this.isValid()) {
            return input != null ? this : NaN;
          }
          if (input != null) {
            if (typeof input === "string") {
              input = offsetFromString(matchShortOffset, input);
              if (input === null) {
                return this;
              }
            } else if (Math.abs(input) < 16 && !keepMinutes) {
              input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
              localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
              this.add(localAdjust, "m");
            }
            if (offset2 !== input) {
              if (!keepLocalTime || this._changeInProgress) {
                addSubtract(this, createDuration(input - offset2, "m"), 1, false);
              } else if (!this._changeInProgress) {
                this._changeInProgress = true;
                hooks.updateOffset(this, true);
                this._changeInProgress = null;
              }
            }
            return this;
          } else {
            return this._isUTC ? offset2 : getDateOffset(this);
          }
        }
        function getSetZone(input, keepLocalTime) {
          if (input != null) {
            if (typeof input !== "string") {
              input = -input;
            }
            this.utcOffset(input, keepLocalTime);
            return this;
          } else {
            return -this.utcOffset();
          }
        }
        function setOffsetToUTC(keepLocalTime) {
          return this.utcOffset(0, keepLocalTime);
        }
        function setOffsetToLocal(keepLocalTime) {
          if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;
            if (keepLocalTime) {
              this.subtract(getDateOffset(this), "m");
            }
          }
          return this;
        }
        function setOffsetToParsedOffset() {
          if (this._tzm != null) {
            this.utcOffset(this._tzm, false, true);
          } else if (typeof this._i === "string") {
            var tZone = offsetFromString(matchOffset, this._i);
            if (tZone != null) {
              this.utcOffset(tZone);
            } else {
              this.utcOffset(0, true);
            }
          }
          return this;
        }
        function hasAlignedHourOffset(input) {
          if (!this.isValid()) {
            return false;
          }
          input = input ? createLocal(input).utcOffset() : 0;
          return (this.utcOffset() - input) % 60 === 0;
        }
        function isDaylightSavingTime() {
          return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
        }
        function isDaylightSavingTimeShifted() {
          if (!isUndefined2(this._isDSTShifted)) {
            return this._isDSTShifted;
          }
          var c = {}, other;
          copyConfig(c, this);
          c = prepareConfig(c);
          if (c._a) {
            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
            this._isDSTShifted = this.isValid() && compareArrays2(c._a, other.toArray()) > 0;
          } else {
            this._isDSTShifted = false;
          }
          return this._isDSTShifted;
        }
        function isLocal() {
          return this.isValid() ? !this._isUTC : false;
        }
        function isUtcOffset() {
          return this.isValid() ? this._isUTC : false;
        }
        function isUtc() {
          return this.isValid() ? this._isUTC && this._offset === 0 : false;
        }
        var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/, isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
        function createDuration(input, key) {
          var duration = input, match = null, sign2, ret, diffRes;
          if (isDuration(input)) {
            duration = {
              ms: input._milliseconds,
              d: input._days,
              M: input._months
            };
          } else if (isNumber2(input) || !isNaN(+input)) {
            duration = {};
            if (key) {
              duration[key] = +input;
            } else {
              duration.milliseconds = +input;
            }
          } else if (match = aspNetRegex.exec(input)) {
            sign2 = match[1] === "-" ? -1 : 1;
            duration = {
              y: 0,
              d: toInt(match[DATE]) * sign2,
              h: toInt(match[HOUR]) * sign2,
              m: toInt(match[MINUTE]) * sign2,
              s: toInt(match[SECOND]) * sign2,
              ms: toInt(absRound(match[MILLISECOND] * 1e3)) * sign2
            };
          } else if (match = isoRegex.exec(input)) {
            sign2 = match[1] === "-" ? -1 : 1;
            duration = {
              y: parseIso(match[2], sign2),
              M: parseIso(match[3], sign2),
              w: parseIso(match[4], sign2),
              d: parseIso(match[5], sign2),
              h: parseIso(match[6], sign2),
              m: parseIso(match[7], sign2),
              s: parseIso(match[8], sign2)
            };
          } else if (duration == null) {
            duration = {};
          } else if (typeof duration === "object" && ("from" in duration || "to" in duration)) {
            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
          }
          ret = new Duration(duration);
          if (isDuration(input) && hasOwnProp(input, "_locale")) {
            ret._locale = input._locale;
          }
          if (isDuration(input) && hasOwnProp(input, "_isValid")) {
            ret._isValid = input._isValid;
          }
          return ret;
        }
        createDuration.fn = Duration.prototype;
        createDuration.invalid = createInvalid$1;
        function parseIso(inp, sign2) {
          var res = inp && parseFloat(inp.replace(",", "."));
          return (isNaN(res) ? 0 : res) * sign2;
        }
        function positiveMomentsDifference(base, other) {
          var res = {};
          res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
          if (base.clone().add(res.months, "M").isAfter(other)) {
            --res.months;
          }
          res.milliseconds = +other - +base.clone().add(res.months, "M");
          return res;
        }
        function momentsDifference(base, other) {
          var res;
          if (!(base.isValid() && other.isValid())) {
            return {
              milliseconds: 0,
              months: 0
            };
          }
          other = cloneWithOffset(other, base);
          if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
          } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
          }
          return res;
        }
        function createAdder(direction, name) {
          return function(val, period) {
            var dur, tmp;
            if (period !== null && !isNaN(+period)) {
              deprecateSimple(name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.");
              tmp = val;
              val = period;
              period = tmp;
            }
            dur = createDuration(val, period);
            addSubtract(this, dur, direction);
            return this;
          };
        }
        function addSubtract(mom, duration, isAdding, updateOffset) {
          var milliseconds2 = duration._milliseconds, days2 = absRound(duration._days), months2 = absRound(duration._months);
          if (!mom.isValid()) {
            return;
          }
          updateOffset = updateOffset == null ? true : updateOffset;
          if (months2) {
            setMonth(mom, get(mom, "Month") + months2 * isAdding);
          }
          if (days2) {
            set$1(mom, "Date", get(mom, "Date") + days2 * isAdding);
          }
          if (milliseconds2) {
            mom._d.setTime(mom._d.valueOf() + milliseconds2 * isAdding);
          }
          if (updateOffset) {
            hooks.updateOffset(mom, days2 || months2);
          }
        }
        var add = createAdder(1, "add"), subtract = createAdder(-1, "subtract");
        function isString2(input) {
          return typeof input === "string" || input instanceof String;
        }
        function isMomentInput(input) {
          return isMoment(input) || isDate(input) || isString2(input) || isNumber2(input) || isNumberOrStringArray(input) || isMomentInputObject(input) || input === null || input === void 0;
        }
        function isMomentInputObject(input) {
          var objectTest = isObject2(input) && !isObjectEmpty(input), propertyTest = false, properties = ["years", "year", "y", "months", "month", "M", "days", "day", "d", "dates", "date", "D", "hours", "hour", "h", "minutes", "minute", "m", "seconds", "second", "s", "milliseconds", "millisecond", "ms"], i, property, propertyLen = properties.length;
          for (i = 0; i < propertyLen; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
          }
          return objectTest && propertyTest;
        }
        function isNumberOrStringArray(input) {
          var arrayTest = isArray3(input), dataTypeTest = false;
          if (arrayTest) {
            dataTypeTest = input.filter(function(item) {
              return !isNumber2(item) && isString2(input);
            }).length === 0;
          }
          return arrayTest && dataTypeTest;
        }
        function isCalendarSpec(input) {
          var objectTest = isObject2(input) && !isObjectEmpty(input), propertyTest = false, properties = ["sameDay", "nextDay", "lastDay", "nextWeek", "lastWeek", "sameElse"], i, property;
          for (i = 0; i < properties.length; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
          }
          return objectTest && propertyTest;
        }
        function getCalendarFormat(myMoment, now2) {
          var diff2 = myMoment.diff(now2, "days", true);
          return diff2 < -6 ? "sameElse" : diff2 < -1 ? "lastWeek" : diff2 < 0 ? "lastDay" : diff2 < 1 ? "sameDay" : diff2 < 2 ? "nextDay" : diff2 < 7 ? "nextWeek" : "sameElse";
        }
        function calendar$1(time, formats) {
          if (arguments.length === 1) {
            if (!arguments[0]) {
              time = void 0;
              formats = void 0;
            } else if (isMomentInput(arguments[0])) {
              time = arguments[0];
              formats = void 0;
            } else if (isCalendarSpec(arguments[0])) {
              formats = arguments[0];
              time = void 0;
            }
          }
          var now2 = time || createLocal(), sod = cloneWithOffset(now2, this).startOf("day"), format2 = hooks.calendarFormat(this, sod) || "sameElse", output = formats && (isFunction(formats[format2]) ? formats[format2].call(this, now2) : formats[format2]);
          return this.format(output || this.localeData().calendar(format2, this, createLocal(now2)));
        }
        function clone() {
          return new Moment2(this);
        }
        function isAfter(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input);
          if (!(this.isValid() && localInput.isValid())) {
            return false;
          }
          units = normalizeUnits(units) || "millisecond";
          if (units === "millisecond") {
            return this.valueOf() > localInput.valueOf();
          } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
          }
        }
        function isBefore(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input);
          if (!(this.isValid() && localInput.isValid())) {
            return false;
          }
          units = normalizeUnits(units) || "millisecond";
          if (units === "millisecond") {
            return this.valueOf() < localInput.valueOf();
          } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
          }
        }
        function isBetween(from2, to2, units, inclusivity) {
          var localFrom = isMoment(from2) ? from2 : createLocal(from2), localTo = isMoment(to2) ? to2 : createLocal(to2);
          if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
            return false;
          }
          inclusivity = inclusivity || "()";
          return (inclusivity[0] === "(" ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ")" ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
        }
        function isSame(input, units) {
          var localInput = isMoment(input) ? input : createLocal(input), inputMs;
          if (!(this.isValid() && localInput.isValid())) {
            return false;
          }
          units = normalizeUnits(units) || "millisecond";
          if (units === "millisecond") {
            return this.valueOf() === localInput.valueOf();
          } else {
            inputMs = localInput.valueOf();
            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
          }
        }
        function isSameOrAfter(input, units) {
          return this.isSame(input, units) || this.isAfter(input, units);
        }
        function isSameOrBefore(input, units) {
          return this.isSame(input, units) || this.isBefore(input, units);
        }
        function diff(input, units, asFloat) {
          var that, zoneDelta, output;
          if (!this.isValid()) {
            return NaN;
          }
          that = cloneWithOffset(input, this);
          if (!that.isValid()) {
            return NaN;
          }
          zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
          units = normalizeUnits(units);
          switch (units) {
            case "year":
              output = monthDiff(this, that) / 12;
              break;
            case "month":
              output = monthDiff(this, that);
              break;
            case "quarter":
              output = monthDiff(this, that) / 3;
              break;
            case "second":
              output = (this - that) / 1e3;
              break;
            case "minute":
              output = (this - that) / 6e4;
              break;
            case "hour":
              output = (this - that) / 36e5;
              break;
            case "day":
              output = (this - that - zoneDelta) / 864e5;
              break;
            case "week":
              output = (this - that - zoneDelta) / 6048e5;
              break;
            default:
              output = this - that;
          }
          return asFloat ? output : absFloor(output);
        }
        function monthDiff(a, b) {
          if (a.date() < b.date()) {
            return -monthDiff(b, a);
          }
          var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()), anchor = a.clone().add(wholeMonthDiff, "months"), anchor2, adjust;
          if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, "months");
            adjust = (b - anchor) / (anchor - anchor2);
          } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, "months");
            adjust = (b - anchor) / (anchor2 - anchor);
          }
          return -(wholeMonthDiff + adjust) || 0;
        }
        hooks.defaultFormat = "YYYY-MM-DDTHH:mm:ssZ";
        hooks.defaultFormatUtc = "YYYY-MM-DDTHH:mm:ss[Z]";
        function toString2() {
          return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
        }
        function toISOString(keepOffset) {
          if (!this.isValid()) {
            return null;
          }
          var utc = keepOffset !== true, m = utc ? this.clone().utc() : this;
          if (m.year() < 0 || m.year() > 9999) {
            return formatMoment(m, utc ? "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYYYY-MM-DD[T]HH:mm:ss.SSSZ");
          }
          if (isFunction(Date.prototype.toISOString)) {
            if (utc) {
              return this.toDate().toISOString();
            } else {
              return new Date(this.valueOf() + this.utcOffset() * 60 * 1e3).toISOString().replace("Z", formatMoment(m, "Z"));
            }
          }
          return formatMoment(m, utc ? "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYY-MM-DD[T]HH:mm:ss.SSSZ");
        }
        function inspect() {
          if (!this.isValid()) {
            return "moment.invalid(/* " + this._i + " */)";
          }
          var func = "moment", zone = "", prefix, year, datetime, suffix;
          if (!this.isLocal()) {
            func = this.utcOffset() === 0 ? "moment.utc" : "moment.parseZone";
            zone = "Z";
          }
          prefix = "[" + func + '("]';
          year = 0 <= this.year() && this.year() <= 9999 ? "YYYY" : "YYYYYY";
          datetime = "-MM-DD[T]HH:mm:ss.SSS";
          suffix = zone + '[")]';
          return this.format(prefix + year + datetime + suffix);
        }
        function format(inputString) {
          if (!inputString) {
            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
          }
          var output = formatMoment(this, inputString);
          return this.localeData().postformat(output);
        }
        function from(time, withoutSuffix) {
          if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
            return createDuration({
              to: this,
              from: time
            }).locale(this.locale()).humanize(!withoutSuffix);
          } else {
            return this.localeData().invalidDate();
          }
        }
        function fromNow(withoutSuffix) {
          return this.from(createLocal(), withoutSuffix);
        }
        function to(time, withoutSuffix) {
          if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
            return createDuration({
              from: this,
              to: time
            }).locale(this.locale()).humanize(!withoutSuffix);
          } else {
            return this.localeData().invalidDate();
          }
        }
        function toNow(withoutSuffix) {
          return this.to(createLocal(), withoutSuffix);
        }
        function locale(key) {
          var newLocaleData;
          if (key === void 0) {
            return this._locale._abbr;
          } else {
            newLocaleData = getLocale(key);
            if (newLocaleData != null) {
              this._locale = newLocaleData;
            }
            return this;
          }
        }
        var lang = deprecate("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.", function(key) {
          if (key === void 0) {
            return this.localeData();
          } else {
            return this.locale(key);
          }
        });
        function localeData() {
          return this._locale;
        }
        var MS_PER_SECOND = 1e3, MS_PER_MINUTE = 60 * MS_PER_SECOND, MS_PER_HOUR = 60 * MS_PER_MINUTE, MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
        function mod$1(dividend, divisor) {
          return (dividend % divisor + divisor) % divisor;
        }
        function localStartOfDate(y, m, d) {
          if (y < 100 && y >= 0) {
            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
          } else {
            return new Date(y, m, d).valueOf();
          }
        }
        function utcStartOfDate(y, m, d) {
          if (y < 100 && y >= 0) {
            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
          } else {
            return Date.UTC(y, m, d);
          }
        }
        function startOf(units) {
          var time, startOfDate;
          units = normalizeUnits(units);
          if (units === void 0 || units === "millisecond" || !this.isValid()) {
            return this;
          }
          startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
          switch (units) {
            case "year":
              time = startOfDate(this.year(), 0, 1);
              break;
            case "quarter":
              time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
              break;
            case "month":
              time = startOfDate(this.year(), this.month(), 1);
              break;
            case "week":
              time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
              break;
            case "isoWeek":
              time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
              break;
            case "day":
            case "date":
              time = startOfDate(this.year(), this.month(), this.date());
              break;
            case "hour":
              time = this._d.valueOf();
              time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
              break;
            case "minute":
              time = this._d.valueOf();
              time -= mod$1(time, MS_PER_MINUTE);
              break;
            case "second":
              time = this._d.valueOf();
              time -= mod$1(time, MS_PER_SECOND);
              break;
          }
          this._d.setTime(time);
          hooks.updateOffset(this, true);
          return this;
        }
        function endOf(units) {
          var time, startOfDate;
          units = normalizeUnits(units);
          if (units === void 0 || units === "millisecond" || !this.isValid()) {
            return this;
          }
          startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
          switch (units) {
            case "year":
              time = startOfDate(this.year() + 1, 0, 1) - 1;
              break;
            case "quarter":
              time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
              break;
            case "month":
              time = startOfDate(this.year(), this.month() + 1, 1) - 1;
              break;
            case "week":
              time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
              break;
            case "isoWeek":
              time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
              break;
            case "day":
            case "date":
              time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
              break;
            case "hour":
              time = this._d.valueOf();
              time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
              break;
            case "minute":
              time = this._d.valueOf();
              time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
              break;
            case "second":
              time = this._d.valueOf();
              time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
              break;
          }
          this._d.setTime(time);
          hooks.updateOffset(this, true);
          return this;
        }
        function valueOf() {
          return this._d.valueOf() - (this._offset || 0) * 6e4;
        }
        function unix() {
          return Math.floor(this.valueOf() / 1e3);
        }
        function toDate() {
          return new Date(this.valueOf());
        }
        function toArray() {
          var m = this;
          return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
        }
        function toObject() {
          var m = this;
          return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds()
          };
        }
        function toJSON() {
          return this.isValid() ? this.toISOString() : null;
        }
        function isValid$2() {
          return isValid(this);
        }
        function parsingFlags() {
          return extend2({}, getParsingFlags(this));
        }
        function invalidAt() {
          return getParsingFlags(this).overflow;
        }
        function creationData() {
          return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict
          };
        }
        addFormatToken("N", 0, 0, "eraAbbr");
        addFormatToken("NN", 0, 0, "eraAbbr");
        addFormatToken("NNN", 0, 0, "eraAbbr");
        addFormatToken("NNNN", 0, 0, "eraName");
        addFormatToken("NNNNN", 0, 0, "eraNarrow");
        addFormatToken("y", ["y", 1], "yo", "eraYear");
        addFormatToken("y", ["yy", 2], 0, "eraYear");
        addFormatToken("y", ["yyy", 3], 0, "eraYear");
        addFormatToken("y", ["yyyy", 4], 0, "eraYear");
        addRegexToken("N", matchEraAbbr);
        addRegexToken("NN", matchEraAbbr);
        addRegexToken("NNN", matchEraAbbr);
        addRegexToken("NNNN", matchEraName);
        addRegexToken("NNNNN", matchEraNarrow);
        addParseToken(["N", "NN", "NNN", "NNNN", "NNNNN"], function(input, array, config2, token2) {
          var era = config2._locale.erasParse(input, token2, config2._strict);
          if (era) {
            getParsingFlags(config2).era = era;
          } else {
            getParsingFlags(config2).invalidEra = input;
          }
        });
        addRegexToken("y", matchUnsigned);
        addRegexToken("yy", matchUnsigned);
        addRegexToken("yyy", matchUnsigned);
        addRegexToken("yyyy", matchUnsigned);
        addRegexToken("yo", matchEraYearOrdinal);
        addParseToken(["y", "yy", "yyy", "yyyy"], YEAR);
        addParseToken(["yo"], function(input, array, config2, token2) {
          var match;
          if (config2._locale._eraYearOrdinalRegex) {
            match = input.match(config2._locale._eraYearOrdinalRegex);
          }
          if (config2._locale.eraYearOrdinalParse) {
            array[YEAR] = config2._locale.eraYearOrdinalParse(input, match);
          } else {
            array[YEAR] = parseInt(input, 10);
          }
        });
        function localeEras(m, format2) {
          var i, l, date, eras = this._eras || getLocale("en")._eras;
          for (i = 0, l = eras.length; i < l; ++i) {
            switch (typeof eras[i].since) {
              case "string":
                date = hooks(eras[i].since).startOf("day");
                eras[i].since = date.valueOf();
                break;
            }
            switch (typeof eras[i].until) {
              case "undefined":
                eras[i].until = Infinity;
                break;
              case "string":
                date = hooks(eras[i].until).startOf("day").valueOf();
                eras[i].until = date.valueOf();
                break;
            }
          }
          return eras;
        }
        function localeErasParse(eraName, format2, strict) {
          var i, l, eras = this.eras(), name, abbr, narrow;
          eraName = eraName.toUpperCase();
          for (i = 0, l = eras.length; i < l; ++i) {
            name = eras[i].name.toUpperCase();
            abbr = eras[i].abbr.toUpperCase();
            narrow = eras[i].narrow.toUpperCase();
            if (strict) {
              switch (format2) {
                case "N":
                case "NN":
                case "NNN":
                  if (abbr === eraName) {
                    return eras[i];
                  }
                  break;
                case "NNNN":
                  if (name === eraName) {
                    return eras[i];
                  }
                  break;
                case "NNNNN":
                  if (narrow === eraName) {
                    return eras[i];
                  }
                  break;
              }
            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
              return eras[i];
            }
          }
        }
        function localeErasConvertYear(era, year) {
          var dir = era.since <= era.until ? 1 : -1;
          if (year === void 0) {
            return hooks(era.since).year();
          } else {
            return hooks(era.since).year() + (year - era.offset) * dir;
          }
        }
        function getEraName() {
          var i, l, val, eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
            val = this.clone().startOf("day").valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
              return eras[i].name;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
              return eras[i].name;
            }
          }
          return "";
        }
        function getEraNarrow() {
          var i, l, val, eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
            val = this.clone().startOf("day").valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
              return eras[i].narrow;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
              return eras[i].narrow;
            }
          }
          return "";
        }
        function getEraAbbr() {
          var i, l, val, eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
            val = this.clone().startOf("day").valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
              return eras[i].abbr;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
              return eras[i].abbr;
            }
          }
          return "";
        }
        function getEraYear() {
          var i, l, dir, val, eras = this.localeData().eras();
          for (i = 0, l = eras.length; i < l; ++i) {
            dir = eras[i].since <= eras[i].until ? 1 : -1;
            val = this.clone().startOf("day").valueOf();
            if (eras[i].since <= val && val <= eras[i].until || eras[i].until <= val && val <= eras[i].since) {
              return (this.year() - hooks(eras[i].since).year()) * dir + eras[i].offset;
            }
          }
          return this.year();
        }
        function erasNameRegex(isStrict) {
          if (!hasOwnProp(this, "_erasNameRegex")) {
            computeErasParse.call(this);
          }
          return isStrict ? this._erasNameRegex : this._erasRegex;
        }
        function erasAbbrRegex(isStrict) {
          if (!hasOwnProp(this, "_erasAbbrRegex")) {
            computeErasParse.call(this);
          }
          return isStrict ? this._erasAbbrRegex : this._erasRegex;
        }
        function erasNarrowRegex(isStrict) {
          if (!hasOwnProp(this, "_erasNarrowRegex")) {
            computeErasParse.call(this);
          }
          return isStrict ? this._erasNarrowRegex : this._erasRegex;
        }
        function matchEraAbbr(isStrict, locale2) {
          return locale2.erasAbbrRegex(isStrict);
        }
        function matchEraName(isStrict, locale2) {
          return locale2.erasNameRegex(isStrict);
        }
        function matchEraNarrow(isStrict, locale2) {
          return locale2.erasNarrowRegex(isStrict);
        }
        function matchEraYearOrdinal(isStrict, locale2) {
          return locale2._eraYearOrdinalRegex || matchUnsigned;
        }
        function computeErasParse() {
          var abbrPieces = [], namePieces = [], narrowPieces = [], mixedPieces = [], i, l, erasName, erasAbbr, erasNarrow, eras = this.eras();
          for (i = 0, l = eras.length; i < l; ++i) {
            erasName = regexEscape(eras[i].name);
            erasAbbr = regexEscape(eras[i].abbr);
            erasNarrow = regexEscape(eras[i].narrow);
            namePieces.push(erasName);
            abbrPieces.push(erasAbbr);
            narrowPieces.push(erasNarrow);
            mixedPieces.push(erasName);
            mixedPieces.push(erasAbbr);
            mixedPieces.push(erasNarrow);
          }
          this._erasRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i");
          this._erasNameRegex = new RegExp("^(" + namePieces.join("|") + ")", "i");
          this._erasAbbrRegex = new RegExp("^(" + abbrPieces.join("|") + ")", "i");
          this._erasNarrowRegex = new RegExp("^(" + narrowPieces.join("|") + ")", "i");
        }
        addFormatToken(0, ["gg", 2], 0, function() {
          return this.weekYear() % 100;
        });
        addFormatToken(0, ["GG", 2], 0, function() {
          return this.isoWeekYear() % 100;
        });
        function addWeekYearFormatToken(token2, getter) {
          addFormatToken(0, [token2, token2.length], 0, getter);
        }
        addWeekYearFormatToken("gggg", "weekYear");
        addWeekYearFormatToken("ggggg", "weekYear");
        addWeekYearFormatToken("GGGG", "isoWeekYear");
        addWeekYearFormatToken("GGGGG", "isoWeekYear");
        addRegexToken("G", matchSigned);
        addRegexToken("g", matchSigned);
        addRegexToken("GG", match1to2, match2);
        addRegexToken("gg", match1to2, match2);
        addRegexToken("GGGG", match1to4, match4);
        addRegexToken("gggg", match1to4, match4);
        addRegexToken("GGGGG", match1to6, match6);
        addRegexToken("ggggg", match1to6, match6);
        addWeekParseToken(["gggg", "ggggg", "GGGG", "GGGGG"], function(input, week, config2, token2) {
          week[token2.substr(0, 2)] = toInt(input);
        });
        addWeekParseToken(["gg", "GG"], function(input, week, config2, token2) {
          week[token2] = hooks.parseTwoDigitYear(input);
        });
        function getSetWeekYear(input) {
          return getSetWeekYearHelper.call(this, input, this.week(), this.weekday() + this.localeData()._week.dow, this.localeData()._week.dow, this.localeData()._week.doy);
        }
        function getSetISOWeekYear(input) {
          return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
        }
        function getISOWeeksInYear() {
          return weeksInYear(this.year(), 1, 4);
        }
        function getISOWeeksInISOWeekYear() {
          return weeksInYear(this.isoWeekYear(), 1, 4);
        }
        function getWeeksInYear() {
          var weekInfo = this.localeData()._week;
          return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
        }
        function getWeeksInWeekYear() {
          var weekInfo = this.localeData()._week;
          return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
        }
        function getSetWeekYearHelper(input, week, weekday, dow, doy) {
          var weeksTarget;
          if (input == null) {
            return weekOfYear(this, dow, doy).year;
          } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
              week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
          }
        }
        function setWeekAll(weekYear, week, weekday, dow, doy) {
          var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
          this.year(date.getUTCFullYear());
          this.month(date.getUTCMonth());
          this.date(date.getUTCDate());
          return this;
        }
        addFormatToken("Q", 0, "Qo", "quarter");
        addRegexToken("Q", match1);
        addParseToken("Q", function(input, array) {
          array[MONTH] = (toInt(input) - 1) * 3;
        });
        function getSetQuarter(input) {
          return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
        }
        addFormatToken("D", ["DD", 2], "Do", "date");
        addRegexToken("D", match1to2, match1to2NoLeadingZero);
        addRegexToken("DD", match1to2, match2);
        addRegexToken("Do", function(isStrict, locale2) {
          return isStrict ? locale2._dayOfMonthOrdinalParse || locale2._ordinalParse : locale2._dayOfMonthOrdinalParseLenient;
        });
        addParseToken(["D", "DD"], DATE);
        addParseToken("Do", function(input, array) {
          array[DATE] = toInt(input.match(match1to2)[0]);
        });
        var getSetDayOfMonth = makeGetSet("Date", true);
        addFormatToken("DDD", ["DDDD", 3], "DDDo", "dayOfYear");
        addRegexToken("DDD", match1to3);
        addRegexToken("DDDD", match3);
        addParseToken(["DDD", "DDDD"], function(input, array, config2) {
          config2._dayOfYear = toInt(input);
        });
        function getSetDayOfYear(input) {
          var dayOfYear = Math.round((this.clone().startOf("day") - this.clone().startOf("year")) / 864e5) + 1;
          return input == null ? dayOfYear : this.add(input - dayOfYear, "d");
        }
        addFormatToken("m", ["mm", 2], 0, "minute");
        addRegexToken("m", match1to2, match1to2HasZero);
        addRegexToken("mm", match1to2, match2);
        addParseToken(["m", "mm"], MINUTE);
        var getSetMinute = makeGetSet("Minutes", false);
        addFormatToken("s", ["ss", 2], 0, "second");
        addRegexToken("s", match1to2, match1to2HasZero);
        addRegexToken("ss", match1to2, match2);
        addParseToken(["s", "ss"], SECOND);
        var getSetSecond = makeGetSet("Seconds", false);
        addFormatToken("S", 0, 0, function() {
          return ~~(this.millisecond() / 100);
        });
        addFormatToken(0, ["SS", 2], 0, function() {
          return ~~(this.millisecond() / 10);
        });
        addFormatToken(0, ["SSS", 3], 0, "millisecond");
        addFormatToken(0, ["SSSS", 4], 0, function() {
          return this.millisecond() * 10;
        });
        addFormatToken(0, ["SSSSS", 5], 0, function() {
          return this.millisecond() * 100;
        });
        addFormatToken(0, ["SSSSSS", 6], 0, function() {
          return this.millisecond() * 1e3;
        });
        addFormatToken(0, ["SSSSSSS", 7], 0, function() {
          return this.millisecond() * 1e4;
        });
        addFormatToken(0, ["SSSSSSSS", 8], 0, function() {
          return this.millisecond() * 1e5;
        });
        addFormatToken(0, ["SSSSSSSSS", 9], 0, function() {
          return this.millisecond() * 1e6;
        });
        addRegexToken("S", match1to3, match1);
        addRegexToken("SS", match1to3, match2);
        addRegexToken("SSS", match1to3, match3);
        var token, getSetMillisecond;
        for (token = "SSSS"; token.length <= 9; token += "S") {
          addRegexToken(token, matchUnsigned);
        }
        function parseMs(input, array) {
          array[MILLISECOND] = toInt(("0." + input) * 1e3);
        }
        for (token = "S"; token.length <= 9; token += "S") {
          addParseToken(token, parseMs);
        }
        getSetMillisecond = makeGetSet("Milliseconds", false);
        addFormatToken("z", 0, 0, "zoneAbbr");
        addFormatToken("zz", 0, 0, "zoneName");
        function getZoneAbbr() {
          return this._isUTC ? "UTC" : "";
        }
        function getZoneName() {
          return this._isUTC ? "Coordinated Universal Time" : "";
        }
        var proto = Moment2.prototype;
        proto.add = add;
        proto.calendar = calendar$1;
        proto.clone = clone;
        proto.diff = diff;
        proto.endOf = endOf;
        proto.format = format;
        proto.from = from;
        proto.fromNow = fromNow;
        proto.to = to;
        proto.toNow = toNow;
        proto.get = stringGet;
        proto.invalidAt = invalidAt;
        proto.isAfter = isAfter;
        proto.isBefore = isBefore;
        proto.isBetween = isBetween;
        proto.isSame = isSame;
        proto.isSameOrAfter = isSameOrAfter;
        proto.isSameOrBefore = isSameOrBefore;
        proto.isValid = isValid$2;
        proto.lang = lang;
        proto.locale = locale;
        proto.localeData = localeData;
        proto.max = prototypeMax;
        proto.min = prototypeMin;
        proto.parsingFlags = parsingFlags;
        proto.set = stringSet;
        proto.startOf = startOf;
        proto.subtract = subtract;
        proto.toArray = toArray;
        proto.toObject = toObject;
        proto.toDate = toDate;
        proto.toISOString = toISOString;
        proto.inspect = inspect;
        if (typeof Symbol !== "undefined" && Symbol.for != null) {
          proto[Symbol.for("nodejs.util.inspect.custom")] = function() {
            return "Moment<" + this.format() + ">";
          };
        }
        proto.toJSON = toJSON;
        proto.toString = toString2;
        proto.unix = unix;
        proto.valueOf = valueOf;
        proto.creationData = creationData;
        proto.eraName = getEraName;
        proto.eraNarrow = getEraNarrow;
        proto.eraAbbr = getEraAbbr;
        proto.eraYear = getEraYear;
        proto.year = getSetYear;
        proto.isLeapYear = getIsLeapYear;
        proto.weekYear = getSetWeekYear;
        proto.isoWeekYear = getSetISOWeekYear;
        proto.quarter = proto.quarters = getSetQuarter;
        proto.month = getSetMonth;
        proto.daysInMonth = getDaysInMonth;
        proto.week = proto.weeks = getSetWeek;
        proto.isoWeek = proto.isoWeeks = getSetISOWeek;
        proto.weeksInYear = getWeeksInYear;
        proto.weeksInWeekYear = getWeeksInWeekYear;
        proto.isoWeeksInYear = getISOWeeksInYear;
        proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
        proto.date = getSetDayOfMonth;
        proto.day = proto.days = getSetDayOfWeek;
        proto.weekday = getSetLocaleDayOfWeek;
        proto.isoWeekday = getSetISODayOfWeek;
        proto.dayOfYear = getSetDayOfYear;
        proto.hour = proto.hours = getSetHour;
        proto.minute = proto.minutes = getSetMinute;
        proto.second = proto.seconds = getSetSecond;
        proto.millisecond = proto.milliseconds = getSetMillisecond;
        proto.utcOffset = getSetOffset;
        proto.utc = setOffsetToUTC;
        proto.local = setOffsetToLocal;
        proto.parseZone = setOffsetToParsedOffset;
        proto.hasAlignedHourOffset = hasAlignedHourOffset;
        proto.isDST = isDaylightSavingTime;
        proto.isLocal = isLocal;
        proto.isUtcOffset = isUtcOffset;
        proto.isUtc = isUtc;
        proto.isUTC = isUtc;
        proto.zoneAbbr = getZoneAbbr;
        proto.zoneName = getZoneName;
        proto.dates = deprecate("dates accessor is deprecated. Use date instead.", getSetDayOfMonth);
        proto.months = deprecate("months accessor is deprecated. Use month instead", getSetMonth);
        proto.years = deprecate("years accessor is deprecated. Use year instead", getSetYear);
        proto.zone = deprecate("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/", getSetZone);
        proto.isDSTShifted = deprecate("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information", isDaylightSavingTimeShifted);
        function createUnix(input) {
          return createLocal(input * 1e3);
        }
        function createInZone() {
          return createLocal.apply(null, arguments).parseZone();
        }
        function preParsePostFormat(string) {
          return string;
        }
        var proto$1 = Locale.prototype;
        proto$1.calendar = calendar;
        proto$1.longDateFormat = longDateFormat;
        proto$1.invalidDate = invalidDate;
        proto$1.ordinal = ordinal;
        proto$1.preparse = preParsePostFormat;
        proto$1.postformat = preParsePostFormat;
        proto$1.relativeTime = relativeTime;
        proto$1.pastFuture = pastFuture;
        proto$1.set = set;
        proto$1.eras = localeEras;
        proto$1.erasParse = localeErasParse;
        proto$1.erasConvertYear = localeErasConvertYear;
        proto$1.erasAbbrRegex = erasAbbrRegex;
        proto$1.erasNameRegex = erasNameRegex;
        proto$1.erasNarrowRegex = erasNarrowRegex;
        proto$1.months = localeMonths;
        proto$1.monthsShort = localeMonthsShort;
        proto$1.monthsParse = localeMonthsParse;
        proto$1.monthsRegex = monthsRegex;
        proto$1.monthsShortRegex = monthsShortRegex;
        proto$1.week = localeWeek;
        proto$1.firstDayOfYear = localeFirstDayOfYear;
        proto$1.firstDayOfWeek = localeFirstDayOfWeek;
        proto$1.weekdays = localeWeekdays;
        proto$1.weekdaysMin = localeWeekdaysMin;
        proto$1.weekdaysShort = localeWeekdaysShort;
        proto$1.weekdaysParse = localeWeekdaysParse;
        proto$1.weekdaysRegex = weekdaysRegex;
        proto$1.weekdaysShortRegex = weekdaysShortRegex;
        proto$1.weekdaysMinRegex = weekdaysMinRegex;
        proto$1.isPM = localeIsPM;
        proto$1.meridiem = localeMeridiem;
        function get$1(format2, index, field, setter) {
          var locale2 = getLocale(), utc = createUTC().set(setter, index);
          return locale2[field](utc, format2);
        }
        function listMonthsImpl(format2, index, field) {
          if (isNumber2(format2)) {
            index = format2;
            format2 = void 0;
          }
          format2 = format2 || "";
          if (index != null) {
            return get$1(format2, index, field, "month");
          }
          var i, out = [];
          for (i = 0; i < 12; i++) {
            out[i] = get$1(format2, i, field, "month");
          }
          return out;
        }
        function listWeekdaysImpl(localeSorted, format2, index, field) {
          if (typeof localeSorted === "boolean") {
            if (isNumber2(format2)) {
              index = format2;
              format2 = void 0;
            }
            format2 = format2 || "";
          } else {
            format2 = localeSorted;
            index = format2;
            localeSorted = false;
            if (isNumber2(format2)) {
              index = format2;
              format2 = void 0;
            }
            format2 = format2 || "";
          }
          var locale2 = getLocale(), shift = localeSorted ? locale2._week.dow : 0, i, out = [];
          if (index != null) {
            return get$1(format2, (index + shift) % 7, field, "day");
          }
          for (i = 0; i < 7; i++) {
            out[i] = get$1(format2, (i + shift) % 7, field, "day");
          }
          return out;
        }
        function listMonths(format2, index) {
          return listMonthsImpl(format2, index, "months");
        }
        function listMonthsShort(format2, index) {
          return listMonthsImpl(format2, index, "monthsShort");
        }
        function listWeekdays(localeSorted, format2, index) {
          return listWeekdaysImpl(localeSorted, format2, index, "weekdays");
        }
        function listWeekdaysShort(localeSorted, format2, index) {
          return listWeekdaysImpl(localeSorted, format2, index, "weekdaysShort");
        }
        function listWeekdaysMin(localeSorted, format2, index) {
          return listWeekdaysImpl(localeSorted, format2, index, "weekdaysMin");
        }
        getSetGlobalLocale("en", {
          eras: [{
            since: "0001-01-01",
            until: Infinity,
            offset: 1,
            name: "Anno Domini",
            narrow: "AD",
            abbr: "AD"
          }, {
            since: "0000-12-31",
            until: -Infinity,
            offset: 1,
            name: "Before Christ",
            narrow: "BC",
            abbr: "BC"
          }],
          dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
          ordinal: function(number) {
            var b = number % 10, output = toInt(number % 100 / 10) === 1 ? "th" : b === 1 ? "st" : b === 2 ? "nd" : b === 3 ? "rd" : "th";
            return number + output;
          }
        });
        hooks.lang = deprecate("moment.lang is deprecated. Use moment.locale instead.", getSetGlobalLocale);
        hooks.langData = deprecate("moment.langData is deprecated. Use moment.localeData instead.", getLocale);
        var mathAbs = Math.abs;
        function abs() {
          var data = this._data;
          this._milliseconds = mathAbs(this._milliseconds);
          this._days = mathAbs(this._days);
          this._months = mathAbs(this._months);
          data.milliseconds = mathAbs(data.milliseconds);
          data.seconds = mathAbs(data.seconds);
          data.minutes = mathAbs(data.minutes);
          data.hours = mathAbs(data.hours);
          data.months = mathAbs(data.months);
          data.years = mathAbs(data.years);
          return this;
        }
        function addSubtract$1(duration, input, value, direction) {
          var other = createDuration(input, value);
          duration._milliseconds += direction * other._milliseconds;
          duration._days += direction * other._days;
          duration._months += direction * other._months;
          return duration._bubble();
        }
        function add$1(input, value) {
          return addSubtract$1(this, input, value, 1);
        }
        function subtract$1(input, value) {
          return addSubtract$1(this, input, value, -1);
        }
        function absCeil(number) {
          if (number < 0) {
            return Math.floor(number);
          } else {
            return Math.ceil(number);
          }
        }
        function bubble() {
          var milliseconds2 = this._milliseconds, days2 = this._days, months2 = this._months, data = this._data, seconds2, minutes2, hours2, years2, monthsFromDays;
          if (!(milliseconds2 >= 0 && days2 >= 0 && months2 >= 0 || milliseconds2 <= 0 && days2 <= 0 && months2 <= 0)) {
            milliseconds2 += absCeil(monthsToDays(months2) + days2) * 864e5;
            days2 = 0;
            months2 = 0;
          }
          data.milliseconds = milliseconds2 % 1e3;
          seconds2 = absFloor(milliseconds2 / 1e3);
          data.seconds = seconds2 % 60;
          minutes2 = absFloor(seconds2 / 60);
          data.minutes = minutes2 % 60;
          hours2 = absFloor(minutes2 / 60);
          data.hours = hours2 % 24;
          days2 += absFloor(hours2 / 24);
          monthsFromDays = absFloor(daysToMonths(days2));
          months2 += monthsFromDays;
          days2 -= absCeil(monthsToDays(monthsFromDays));
          years2 = absFloor(months2 / 12);
          months2 %= 12;
          data.days = days2;
          data.months = months2;
          data.years = years2;
          return this;
        }
        function daysToMonths(days2) {
          return days2 * 4800 / 146097;
        }
        function monthsToDays(months2) {
          return months2 * 146097 / 4800;
        }
        function as(units) {
          if (!this.isValid()) {
            return NaN;
          }
          var days2, months2, milliseconds2 = this._milliseconds;
          units = normalizeUnits(units);
          if (units === "month" || units === "quarter" || units === "year") {
            days2 = this._days + milliseconds2 / 864e5;
            months2 = this._months + daysToMonths(days2);
            switch (units) {
              case "month":
                return months2;
              case "quarter":
                return months2 / 3;
              case "year":
                return months2 / 12;
            }
          } else {
            days2 = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
              case "week":
                return days2 / 7 + milliseconds2 / 6048e5;
              case "day":
                return days2 + milliseconds2 / 864e5;
              case "hour":
                return days2 * 24 + milliseconds2 / 36e5;
              case "minute":
                return days2 * 1440 + milliseconds2 / 6e4;
              case "second":
                return days2 * 86400 + milliseconds2 / 1e3;
              case "millisecond":
                return Math.floor(days2 * 864e5) + milliseconds2;
              default:
                throw new Error("Unknown unit " + units);
            }
          }
        }
        function makeAs(alias) {
          return function() {
            return this.as(alias);
          };
        }
        var asMilliseconds = makeAs("ms"), asSeconds = makeAs("s"), asMinutes = makeAs("m"), asHours = makeAs("h"), asDays = makeAs("d"), asWeeks = makeAs("w"), asMonths = makeAs("M"), asQuarters = makeAs("Q"), asYears = makeAs("y"), valueOf$1 = asMilliseconds;
        function clone$1() {
          return createDuration(this);
        }
        function get$2(units) {
          units = normalizeUnits(units);
          return this.isValid() ? this[units + "s"]() : NaN;
        }
        function makeGetter(name) {
          return function() {
            return this.isValid() ? this._data[name] : NaN;
          };
        }
        var milliseconds = makeGetter("milliseconds"), seconds = makeGetter("seconds"), minutes = makeGetter("minutes"), hours = makeGetter("hours"), days = makeGetter("days"), months = makeGetter("months"), years = makeGetter("years");
        function weeks() {
          return absFloor(this.days() / 7);
        }
        var round = Math.round, thresholds = {
          ss: 44,
          s: 45,
          m: 45,
          h: 22,
          d: 26,
          w: null,
          M: 11
        };
        function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale2) {
          return locale2.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
        }
        function relativeTime$1(posNegDuration, withoutSuffix, thresholds2, locale2) {
          var duration = createDuration(posNegDuration).abs(), seconds2 = round(duration.as("s")), minutes2 = round(duration.as("m")), hours2 = round(duration.as("h")), days2 = round(duration.as("d")), months2 = round(duration.as("M")), weeks2 = round(duration.as("w")), years2 = round(duration.as("y")), a = seconds2 <= thresholds2.ss && ["s", seconds2] || seconds2 < thresholds2.s && ["ss", seconds2] || minutes2 <= 1 && ["m"] || minutes2 < thresholds2.m && ["mm", minutes2] || hours2 <= 1 && ["h"] || hours2 < thresholds2.h && ["hh", hours2] || days2 <= 1 && ["d"] || days2 < thresholds2.d && ["dd", days2];
          if (thresholds2.w != null) {
            a = a || weeks2 <= 1 && ["w"] || weeks2 < thresholds2.w && ["ww", weeks2];
          }
          a = a || months2 <= 1 && ["M"] || months2 < thresholds2.M && ["MM", months2] || years2 <= 1 && ["y"] || ["yy", years2];
          a[2] = withoutSuffix;
          a[3] = +posNegDuration > 0;
          a[4] = locale2;
          return substituteTimeAgo.apply(null, a);
        }
        function getSetRelativeTimeRounding(roundingFunction) {
          if (roundingFunction === void 0) {
            return round;
          }
          if (typeof roundingFunction === "function") {
            round = roundingFunction;
            return true;
          }
          return false;
        }
        function getSetRelativeTimeThreshold(threshold, limit) {
          if (thresholds[threshold] === void 0) {
            return false;
          }
          if (limit === void 0) {
            return thresholds[threshold];
          }
          thresholds[threshold] = limit;
          if (threshold === "s") {
            thresholds.ss = limit - 1;
          }
          return true;
        }
        function humanize(argWithSuffix, argThresholds) {
          if (!this.isValid()) {
            return this.localeData().invalidDate();
          }
          var withSuffix = false, th = thresholds, locale2, output;
          if (typeof argWithSuffix === "object") {
            argThresholds = argWithSuffix;
            argWithSuffix = false;
          }
          if (typeof argWithSuffix === "boolean") {
            withSuffix = argWithSuffix;
          }
          if (typeof argThresholds === "object") {
            th = Object.assign({}, thresholds, argThresholds);
            if (argThresholds.s != null && argThresholds.ss == null) {
              th.ss = argThresholds.s - 1;
            }
          }
          locale2 = this.localeData();
          output = relativeTime$1(this, !withSuffix, th, locale2);
          if (withSuffix) {
            output = locale2.pastFuture(+this, output);
          }
          return locale2.postformat(output);
        }
        var abs$1 = Math.abs;
        function sign(x) {
          return (x > 0) - (x < 0) || +x;
        }
        function toISOString$1() {
          if (!this.isValid()) {
            return this.localeData().invalidDate();
          }
          var seconds2 = abs$1(this._milliseconds) / 1e3, days2 = abs$1(this._days), months2 = abs$1(this._months), minutes2, hours2, years2, s, total = this.asSeconds(), totalSign, ymSign, daysSign, hmsSign;
          if (!total) {
            return "P0D";
          }
          minutes2 = absFloor(seconds2 / 60);
          hours2 = absFloor(minutes2 / 60);
          seconds2 %= 60;
          minutes2 %= 60;
          years2 = absFloor(months2 / 12);
          months2 %= 12;
          s = seconds2 ? seconds2.toFixed(3).replace(/\.?0+$/, "") : "";
          totalSign = total < 0 ? "-" : "";
          ymSign = sign(this._months) !== sign(total) ? "-" : "";
          daysSign = sign(this._days) !== sign(total) ? "-" : "";
          hmsSign = sign(this._milliseconds) !== sign(total) ? "-" : "";
          return totalSign + "P" + (years2 ? ymSign + years2 + "Y" : "") + (months2 ? ymSign + months2 + "M" : "") + (days2 ? daysSign + days2 + "D" : "") + (hours2 || minutes2 || seconds2 ? "T" : "") + (hours2 ? hmsSign + hours2 + "H" : "") + (minutes2 ? hmsSign + minutes2 + "M" : "") + (seconds2 ? hmsSign + s + "S" : "");
        }
        var proto$2 = Duration.prototype;
        proto$2.isValid = isValid$1;
        proto$2.abs = abs;
        proto$2.add = add$1;
        proto$2.subtract = subtract$1;
        proto$2.as = as;
        proto$2.asMilliseconds = asMilliseconds;
        proto$2.asSeconds = asSeconds;
        proto$2.asMinutes = asMinutes;
        proto$2.asHours = asHours;
        proto$2.asDays = asDays;
        proto$2.asWeeks = asWeeks;
        proto$2.asMonths = asMonths;
        proto$2.asQuarters = asQuarters;
        proto$2.asYears = asYears;
        proto$2.valueOf = valueOf$1;
        proto$2._bubble = bubble;
        proto$2.clone = clone$1;
        proto$2.get = get$2;
        proto$2.milliseconds = milliseconds;
        proto$2.seconds = seconds;
        proto$2.minutes = minutes;
        proto$2.hours = hours;
        proto$2.days = days;
        proto$2.weeks = weeks;
        proto$2.months = months;
        proto$2.years = years;
        proto$2.humanize = humanize;
        proto$2.toISOString = toISOString$1;
        proto$2.toString = toISOString$1;
        proto$2.toJSON = toISOString$1;
        proto$2.locale = locale;
        proto$2.localeData = localeData;
        proto$2.toIsoString = deprecate("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)", toISOString$1);
        proto$2.lang = lang;
        addFormatToken("X", 0, 0, "unix");
        addFormatToken("x", 0, 0, "valueOf");
        addRegexToken("x", matchSigned);
        addRegexToken("X", matchTimestamp);
        addParseToken("X", function(input, array, config2) {
          config2._d = new Date(parseFloat(input) * 1e3);
        });
        addParseToken("x", function(input, array, config2) {
          config2._d = new Date(toInt(input));
        });
        hooks.version = "2.30.1";
        setHookCallback(createLocal);
        hooks.fn = proto;
        hooks.min = min;
        hooks.max = max;
        hooks.now = now;
        hooks.utc = createUTC;
        hooks.unix = createUnix;
        hooks.months = listMonths;
        hooks.isDate = isDate;
        hooks.locale = getSetGlobalLocale;
        hooks.invalid = createInvalid;
        hooks.duration = createDuration;
        hooks.isMoment = isMoment;
        hooks.weekdays = listWeekdays;
        hooks.parseZone = createInZone;
        hooks.localeData = getLocale;
        hooks.isDuration = isDuration;
        hooks.monthsShort = listMonthsShort;
        hooks.weekdaysMin = listWeekdaysMin;
        hooks.defineLocale = defineLocale;
        hooks.updateLocale = updateLocale;
        hooks.locales = listLocales;
        hooks.weekdaysShort = listWeekdaysShort;
        hooks.normalizeUnits = normalizeUnits;
        hooks.relativeTimeRounding = getSetRelativeTimeRounding;
        hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
        hooks.calendarFormat = getCalendarFormat;
        hooks.prototype = proto;
        hooks.HTML5_FMT = {
          DATETIME_LOCAL: "YYYY-MM-DDTHH:mm",
          DATETIME_LOCAL_SECONDS: "YYYY-MM-DDTHH:mm:ss",
          DATETIME_LOCAL_MS: "YYYY-MM-DDTHH:mm:ss.SSS",
          DATE: "YYYY-MM-DD",
          TIME: "HH:mm",
          TIME_SECONDS: "HH:mm:ss",
          TIME_MS: "HH:mm:ss.SSS",
          WEEK: "GGGG-[W]WW",
          MONTH: "YYYY-MM"
        };
        return hooks;
      });
    }
  });
  var ConvertibleNumber = Symbol("ConvertibleNumber");
  var PositiveInteger = Symbol("PositiveInteger");
  var NegativeInteger = Symbol("NegativeInteger");
  var PositiveFloat = Symbol("PositiveFloat");
  var NegativeFloat = Symbol("NegativeFloat");
  var emojiSeq = String.raw`(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})`;
  var emojiSTags = String.raw`\u{E0061}-\u{E007A}`;
  var emojiRegex = new RegExp(String.raw`[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[${emojiSTags}]{2}[\u{E0030}-\u{E0039}${emojiSTags}]{1,3}\u{E007F}|${emojiSeq}(?:\u200D${emojiSeq})*`, "gu");
  var isNull = (obj) => obj === null;
  var isUndefined = (obj) => typeof obj === "undefined";
  var isNullOrUndefined = (obj) => isUndefined(obj) || isNull(obj);
  var isObject = (obj) => !isNullOrUndefined(obj) && typeof obj === "object" && !Array.isArray(obj);
  var isString = (obj) => !isNullOrUndefined(obj) && typeof obj === "string";
  var isNumber = (obj) => !isNullOrUndefined(obj) && typeof obj === "number";
  var isArray = (obj) => Array.isArray(obj);
  var isElement = (obj) => !isNullOrUndefined(obj) && obj instanceof Element;
  var isNode = (obj) => !isNullOrUndefined(obj) && obj instanceof Node;
  var isNotEmpty = (obj) => {
    if (isNullOrUndefined(obj)) {
      return false;
    }
    if (Array.isArray(obj)) {
      return obj.some(isNotEmpty);
    }
    if (isString(obj)) {
      return !obj.isEmpty();
    }
    if (isNumber(obj)) {
      return !Number.isNaN(obj);
    }
    if (isElement(obj) || isNode(obj)) {
      return true;
    }
    if (isObject(obj)) {
      return Object.values(obj).some(isNotEmpty);
    }
    return true;
  };
  var isVideoInfo = (obj) => {
    if (obj === null || typeof obj !== "object") return false;
    const info = obj;
    return isInitVideoInfo(info) || isFullVideoInfo(info) || isPartialVideoInfo(info) || isCacheVideoInfo(info) || isFailVideoInfo(info);
  };
  var hasValidID = (info) => isString(info.ID) && isNotEmpty(info.ID);
  var isInitVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "init" && hasValidID(info);
  var isFullVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "full" && hasValidID(info) && isNumber(info.UploadTime) && isString(info.Title) && isNotEmpty(info.Title) && isString(info.FileName) && isNotEmpty(info.FileName) && isNumber(info.Size) && isArray(info.Tags) && typeof info.Liked === "boolean" && typeof info.Following === "boolean" && typeof info.Friend === "boolean" && isString(info.Author) && isNotEmpty(info.Author) && isString(info.AuthorID) && isNotEmpty(info.AuthorID) && typeof info.Private === "boolean" && typeof info.Unlisted === "boolean" && isString(info.DownloadQuality) && typeof info.External === "boolean" && isString(info.DownloadUrl) && isNotEmpty(info.DownloadUrl) && isObject(info.RAW);
  var isPartialVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "partial" && hasValidID(info) && isNumber(info.UploadTime) && isString(info.Title) && isNotEmpty(info.Title) && isArray(info.Tags) && typeof info.Liked === "boolean" && isString(info.Author) && isNotEmpty(info.Author) && isString(info.AuthorID) && isNotEmpty(info.AuthorID) && typeof info.Private === "boolean" && typeof info.Unlisted === "boolean" && typeof info.External === "boolean" && isObject(info.RAW);
  var isCacheVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "cache" && hasValidID(info) && isObject(info.RAW);
  var isFailVideoInfo = (info) => !isNullOrUndefined(info) && info.Type === "fail" && hasValidID(info);
  var assertVideoInfoType = (info) => {
    switch (info.Type) {
      case "init":
        return info;
      case "full":
        return info;
      case "partial":
        return info;
      case "cache":
        return info;
      case "fail":
        return info;
      default:
        throw new Error(`未知的 VideoInfo 类型: ${info.Type}`);
    }
  };
  function isConvertibleToNumber(obj, includeInfinity = false) {
    if (isNullOrUndefined(obj)) {
      return false;
    }
    if (isString(obj)) {
      return obj.isConvertibleToNumber(includeInfinity);
    }
    if (isNumber(obj)) {
      return isNaN(obj) ? false : includeInfinity ? true : isFinite(obj);
    }
    return false;
  }
  Number.isConvertibleNumber = (value, includeInfinity = false) => {
    if (isNullOrUndefined(value)) {
      return false;
    }
    if (isString(value)) {
      return value.isConvertibleToNumber(includeInfinity);
    }
    if (isNumber(value)) {
      return isNaN(value) ? false : includeInfinity ? true : isFinite(value);
    }
    return false;
  };
  Number.isPositiveInteger = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
  Number.isNegativeInteger = (value) => typeof value === "number" && Number.isInteger(value) && value < 0;
  Number.isPositiveFloat = (value) => typeof value === "number" && !Number.isInteger(value) && value > 0;
  Number.isNegativeFloat = (value) => typeof value === "number" && !Number.isInteger(value) && value < 0;
  Number.toPositiveInteger = (value) => {
    if (!Number.isPositiveInteger(value)) {
      throw new Error("值必须为正整数");
    }
    return value;
  };
  Number.toNegativeInteger = (value) => {
    if (!Number.isNegativeInteger(value)) {
      throw new Error("值必须为负整数");
    }
    return value;
  };
  Number.toPositiveFloat = (value) => {
    if (!Number.isPositiveFloat(value)) {
      throw new Error("值必须为正浮点数");
    }
    return value;
  };
  Number.toNegativeFloat = (value) => {
    if (!Number.isNegativeFloat(value)) {
      throw new Error("值必须为负浮点数");
    }
    return value;
  };
  Array.prototype.any = function() {
    return this.filter((i) => !isNullOrUndefined(i)).length > 0;
  };
  Array.prototype.unique = function(prop) {
    if (isNullOrUndefined(prop)) {
      const seen =  new Set();
      return this.filter((item) => {
        if (seen.has(item)) return false;
        seen.add(item);
        return true;
      });
    } else {
      const seen =  new Map();
      const nanSymbol = Symbol();
      return this.filter((item) => {
        const rawKey = item[prop];
        const key = isNumber(rawKey) && Number.isNaN(rawKey) ? nanSymbol : rawKey;
        if (seen.has(key)) return false;
        seen.set(key, true);
        return true;
      });
    }
  };
  Array.prototype.union = function(that, prop) {
    return [...this, ...that].unique(prop);
  };
  Array.prototype.intersect = function(that, prop) {
    return this.filter((item) => that.some((t) => isNullOrUndefined(prop) ? t === item : t[prop] === item[prop])).unique(prop);
  };
  Array.prototype.difference = function(that, prop) {
    return this.filter((item) => !that.some((t) => isNullOrUndefined(prop) ? t === item : t[prop] === item[prop])).unique(prop);
  };
  Array.prototype.complement = function(that, prop) {
    return this.union(that, prop).difference(this.intersect(that, prop), prop);
  };
  String.prototype.isEmpty = function() {
    return !isNullOrUndefined(this) && this.length === 0;
  };
  String.prototype.isConvertibleToNumber = function(includeInfinity = false) {
    const trimmed = this.trim();
    if (trimmed === "") return false;
    return Number.isConvertibleNumber(Number(trimmed), includeInfinity);
  };
  String.prototype.reversed = function() {
    const segmenter = new Intl.Segmenter(navigator.language, {
      granularity: "grapheme"
    });
    return [...segmenter.segment(this.toString())].reverse().join("");
  };
  String.prototype.among = function(start, end, greedy = false, reverse = false) {
    if (this.isEmpty() || start.isEmpty() || end.isEmpty()) return "";
    if (!reverse) {
      const startIndex = this.indexOf(start);
      if (startIndex === -1) return "";
      const adjustedStartIndex = startIndex + start.length;
      const endIndex = greedy ? this.lastIndexOf(end) : this.indexOf(end, adjustedStartIndex);
      if (endIndex === -1 || endIndex < adjustedStartIndex) return "";
      return this.slice(adjustedStartIndex, endIndex);
    } else {
      const endIndex = this.lastIndexOf(end);
      if (endIndex === -1) return "";
      const adjustedEndIndex = endIndex - end.length;
      const startIndex = greedy ? this.indexOf(start) : this.lastIndexOf(start, adjustedEndIndex);
      if (startIndex === -1 || startIndex + start.length > adjustedEndIndex) return "";
      return this.slice(startIndex + start.length, endIndex);
    }
  };
  String.prototype.splitLimit = function(separator, limit) {
    if (this.isEmpty() || isNullOrUndefined(separator)) {
      throw new Error("Empty");
    }
    let body = this.split(separator);
    return limit ? body.slice(0, limit).concat(body.slice(limit).join(separator)) : body;
  };
  String.prototype.truncate = function(maxLength) {
    return this.length > maxLength ? this.substring(0, maxLength) : this.toString();
  };
  String.prototype.trimHead = function(prefix) {
    return this.startsWith(prefix) ? this.slice(prefix.length) : this.toString();
  };
  String.prototype.trimTail = function(suffix) {
    return this.endsWith(suffix) ? this.slice(0, -suffix.length) : this.toString();
  };
  String.prototype.replaceEmojis = function(replace) {
    return this.replaceAll(emojiRegex, replace ?? "");
  };
  String.prototype.toURL = function() {
    let URLString = this;
    if (URLString.split("//")[0].isEmpty()) {
      URLString = `${unsafeWindow.location.protocol}${URLString}`;
    }
    return new URL(URLString.toString());
  };
  Date.prototype.add = function({
    years = 0,
    months = 0,
    days = 0,
    hours = 0,
    minutes = 0,
    seconds = 0,
    ms = 0
  } = {}) {
    const newDate = new Date(this.getTime());
    if (years) newDate.setFullYear(newDate.getFullYear() + years);
    if (months) newDate.setMonth(newDate.getMonth() + months);
    if (days) newDate.setDate(newDate.getDate() + days);
    if (hours) newDate.setHours(newDate.getHours() + hours);
    if (minutes) newDate.setMinutes(newDate.getMinutes() + minutes);
    if (seconds) newDate.setSeconds(newDate.getSeconds() + seconds);
    if (ms) newDate.setMilliseconds(newDate.getMilliseconds() + ms);
    return newDate;
  };
  Date.prototype.sub = function({
    years = 0,
    months = 0,
    days = 0,
    hours = 0,
    minutes = 0,
    seconds = 0,
    ms = 0
  } = {}) {
    const newDate = new Date(this.getTime());
    if (years) newDate.setFullYear(newDate.getFullYear() - years);
    if (months) newDate.setMonth(newDate.getMonth() - months);
    if (days) newDate.setDate(newDate.getDate() - days);
    if (hours) newDate.setHours(newDate.getHours() - hours);
    if (minutes) newDate.setMinutes(newDate.getMinutes() - minutes);
    if (seconds) newDate.setSeconds(newDate.getSeconds() - seconds);
    if (ms) newDate.setMilliseconds(newDate.getMilliseconds() - ms);
    return newDate;
  };
  function throttle(fn, delay2, {
    leading = true,
    trailing = true
  } = {}) {
    let lastCall = 0;
    let timer = null;
    const throttled = function(...args) {
      const now = Date.now();
      if (!lastCall && !leading) {
        lastCall = now;
      }
      const remaining = delay2 - (now - lastCall);
      if (remaining <= 0) {
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }
        lastCall = now;
        fn.apply(this, args);
      } else if (trailing && !timer) {
        timer = setTimeout(() => {
          lastCall = leading ? Date.now() : 0;
          timer = null;
          fn.apply(this, args);
        }, remaining);
      }
    };
    throttled.cancel = () => {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      lastCall = 0;
    };
    return throttled;
  }
  function debounce(fn, delay2, {
    immediate = false
  } = {}) {
    let timer = null;
    const debounced = function(...args) {
      const callNow = immediate && !timer;
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        timer = null;
        if (!immediate) {
          fn.apply(this, args);
        }
      }, delay2);
      if (callNow) {
        fn.apply(this, args);
      }
    };
    debounced.cancel = () => {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
    };
    return debounced;
  }
  function delay(time) {
    return new Promise((resolve) => setTimeout(resolve, time));
  }
  function hasFunction(obj, method) {
    return isObject(obj) && method in obj && typeof obj[method] === "function";
  }
  ;
  function UUID() {
    return isNullOrUndefined(crypto) ? Array.from({
      length: 8
    }, () => ((1 + Math.random()) * 65536 | 0).toString(16).substring(1)).join("") : crypto.randomUUID().replaceAll("-", "");
  }
  function stringify(data) {
    switch (typeof data) {
      case "undefined":
        return "undefined";
      case "boolean":
        return data ? "true" : "false";
      case "number":
        return String(data);
      case "string":
        return data;
      case "symbol":
        return data.toString();
      case "function":
        return data.toString();
      case "object":
        if (isNull(data)) {
          return "null";
        }
        if (data instanceof Error) {
          return data.toString();
        }
        if (data instanceof Date) {
          return data.toISOString();
        }
        return JSON.stringify(data, null, 2);
      default:
        return "unknown";
    }
  }
  function prune(data) {
    if (isElement(data) || isNode(data)) {
      return data;
    }
    if (Array.isArray(data)) {
      return data.map((item) => prune(item)).filter(isNotEmpty);
    }
    if (isObject(data)) {
      const result = Object.fromEntries(Object.entries(data).filter(([, v]) => isNotEmpty(v)).map(([k, v]) => [k, prune(v)]).filter(([, v]) => isNotEmpty(v)));
      return result;
    }
    return data;
  }
  function compareVC(vc1, vc2) {
    vc1 = vc1 || {};
    vc2 = vc2 || {};
    let less = false, greater = false;
    const keys2 =  new Set([...Object.keys(vc1), ...Object.keys(vc2)]);
    for (const k of keys2) {
      const a = vc1[k] ?? 0;
      const b = vc2[k] ?? 0;
      if (a < b) less = true;
      if (a > b) greater = true;
    }
    if (less && !greater) return "before";
    if (!less && greater) return "after";
    if (!less && !greater) return "equal";
    return "concurrent";
  }
  function mergeVC(vc1, vc2) {
    const result = {
      ...vc1
    };
    for (const k in vc2) {
      result[k] = Math.max(result[k] ?? 0, vc2[k]);
    }
    return result;
  }
  String.prototype.replaceVariable = function(replacements, prefix = "%#", suffix = "#%") {
    function escapeRegex(str) {
      return str.replace(/[\.\*\+\?\^\$\{\}\(\)\|\[\]\\]/g, "\\$&");
    }
    let current = this.toString();
    prefix = escapeRegex(prefix);
    suffix = escapeRegex(suffix);
    const seen =  new Set();
    const patterns = Object.keys(replacements).map((key) => {
      const escKey = escapeRegex(key);
      return {
        value: replacements[key],
        placeholderRegex: new RegExp(`${prefix}${escKey}(?=(?::.*?${suffix}|${suffix}))(?::.*?)?${suffix}`, "gs"),
        placeholderFormatRegex: new RegExp(`(?<=${prefix}${escKey}(?=(?::.*?${suffix}|${suffix})):).*?(?=${suffix})`, "gs")
      };
    });
    while (true) {
      if (seen.has(current)) {
        console.warn("检测到循环替换!", `终止于: ${current}`);
        break;
      }
      seen.add(current);
      let next = current;
      for (const {
        value,
        placeholderRegex,
        placeholderFormatRegex
      } of patterns) {
        if (placeholderRegex.test(next)) {
          let format = next.match(placeholderFormatRegex);
          if (!isNullOrUndefined(format) && format.any() && !format[0].isEmpty() && hasFunction(value, "format")) {
            next = next.replace(placeholderRegex, stringify(value.format(escapeRegex(format[0]))));
          } else {
            next = next.replace(placeholderRegex, stringify(value instanceof Date ? value.format("YYYY-MM-DD") : value));
          }
        }
      }
      if (current === next) break;
      current = next;
    }
    return current;
  };
  var zh_cn_default = {
    appName: "Iwara 批量下载工具",
    language: "语言: ",
    downloadPriority: "下载画质: ",
    downloadPath: "下载到: ",
    downloadProxy: "下载代理: ",
    downloadProxyUsername: "下载代理用户名: ",
    downloadProxyPassword: "下载代理密码: ",
    aria2Path: "Aria2 RPC: ",
    aria2Token: "Aria2 密钥: ",
    iwaraDownloaderPath: "IwaraDownloader RPC: ",
    iwaraDownloaderToken: "IwaraDownloader 密钥: ",
    experimentalFeatures: "实验性功能",
    enableUnsafeMode: "激进模式(风险自行承担)",
    rename: "重命名",
    save: "保存",
    reset: "重置",
    ok: "确定",
    on: "开启",
    off: "关闭",
    delete: "删除",
    deleteSucceed: "删除成功!",
    isDebug: "调试模式",
    downloadType: "下载方式",
    browserDownload: "浏览器下载",
    iwaraDownloaderDownload: "IwaraDownloader下载",
    autoFollow: "自动关注选中的视频作者",
    autoLike: "自动点赞选中的视频",
    addUnlistedAndPrivate: "不公开和私有视频强制显示(需关注作者)",
    checkDownloadLink: "第三方网盘下载地址检查",
    checkPriority: "下载画质检查",
    autoDownloadMetadata: "自动下载视频元数据",
    videoMetadata: "视频元数据",
    autoInjectCheckbox: "自动注入选择框",
    notOfficialWarning: "警告,此网站不是Iwara官方网站,请勿填写任何敏感信息!\n继续浏览该网站?",
    autoCopySaveFileName: "自动复制根据规则生成的文件名",
    configurationIncompatible: "初始化或配置文件不兼容,请重新配置!",
    browserDownloadNotEnabled: "未启用下载功能!",
    browserDownloadNotWhitelisted: "请求的文件扩展名未列入白名单!",
    browserDownloadNotPermitted: "下载功能已启用,但未授予下载权限!",
    browserDownloadNotSupported: "目前浏览器/版本不支持下载功能!",
    browserDownloadNotSucceeded: "下载未开始或失败!",
    browserDownloadUnknownError: "未知错误,有可能是下载时提供的参数存在问题,请检查文件名是否合法!",
    browserDownloadTimeout: "下载超时,请检查网络环境是否正常!",
    variable: "→ 查看可用变量 ←",
    downloadTime: "下载时间 ",
    uploadTime: "发布时间 ",
    example: "示例: ",
    result: "结果: ",
    loadingCompleted: "加载完成",
    settings: "打开设置",
    downloadThis: "下载当前视频",
    manualDownload: "手动下载指定",
    aria2TaskCheck: "Aria2任务重启",
    reverseSelect: "本页反向选中",
    deselectThis: "取消本页选中",
    deselectAll: "取消所有选中",
    selectThis: "本页全部选中",
    parseUnlistedAndPrivate: "解析近期隐藏或私有的视频",
    downloadSelected: "下载所选",
    selected: "已选中",
    downloadingSelected: "正在下载所选,请稍后...",
    injectCheckbox: "开关选择框",
    configError: "脚本配置中存在错误,请修改。",
    alreadyKnowHowToUse: "我已知晓如何使用!!!(此页面仅显示一次)",
    notice: [
      "加载完成",
      {
        nodeType: "br"
      },
      "公告: ",
      {
        nodeType: "br"
      },
      "解决了批量选中或取消选择时多标签页不同步的问题。",
      {
        nodeType: "br"
      },
      "添加安全检查,本脚本将拒绝在风险网站上加载功能模块。"
    ],
    useHelpForBase: [
      "请认真阅读使用指南!",
      {
        nodeType: "br"
      },
      "点击网页侧边的灰色侧栏展开脚本菜单,根据需求点击菜单中的功能。"
    ],
    useHelpForInjectCheckbox: "打开任意存在视频卡片的页面,脚本会在视频卡片上注入复选框,点击复选框或鼠标悬浮在视频卡片上按空格将会勾选此视频。",
    useHelpForCheckDownloadLink: "开启“%#checkDownloadLink#%”功能会在下载视频前会检查视频简介以及评论,如果在其中发现疑似第三方网盘下载链接,将会弹出提示,您可以点击提示打开视频页面。",
    useHelpForManualDownload: [
      "使用手动下载功能需要提供视频ID,如需批量手动下载请提供使用“|”分割的视频ID。",
      {
        nodeType: "br"
      },
      "例如: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L",
      {
        nodeType: "br"
      },
      "或提供符合以下格式对象的数组json字符串",
      {
        nodeType: "br"
      },
      "[ ID: string, { Title?: string, Alias?: string, Author?: string } ] ",
      {
        nodeType: "br"
      },
      "例如: ",
      {
        nodeType: "br"
      },
      '[["AeGUIRO2D5vQ6F", { Title: "237知更鸟", Alias: "骑着牛儿追织女", Author: "user1528210" }],["qQsUMJa19LcK3L", { Title: "Mika Automotive Extradimensional", Alias: "Temptation’s_Symphony", Author: "temptations_symphony" }]]'
    ],
    useHelpForBugreport: [
      "反馈遇到的BUG、使用问题等请前往: ",
      {
        nodeType: "a",
        childs: "Github",
        attributes: {
          href: "https://github.com/dawn-lc/IwaraDownloadTool/"
        }
      }
    ],
    tryRestartingDownload: "→ 点击此处重新下载 ←",
    tryReparseDownload: "→ 点击此处重新解析 ←",
    cdnCacheFinded: "→ 进入 MMD Fans 缓存页面 ←",
    openVideoLink: "→ 进入视频页面 ←",
    copySucceed: "复制成功!",
    pushTaskSucceed: "推送下载任务成功!",
    exportConfig: "导出配置",
    exportConfigSucceed: "配置已导出至剪切板!",
    connectionTest: "连接测试",
    settingsCheck: "配置检查",
    createTask: "创建任务",
    downloadPathError: "下载路径错误!",
    browserDownloadModeError: "请启用脚本管理器的浏览器API下载模式!",
    downloadQualityError: "未找到指定的画质下载地址!",
    findedDownloadLink: "发现疑似第三方网盘下载地址!",
    allCompleted: "全部解析完成!",
    parsing: "预解析中...",
    following: "已关注",
    parsingProgress: "解析进度: ",
    manualDownloadTips: '单独下载请直接在此处输入视频ID, 批量下载请提供使用“|”分割的视频ID, 例如: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L\r\n或提供符合以下格式对象的数组json字符串\r\n{ key: string, value: { Title?: string, Alias?: string, Author?: string } }\r\n例如: \r\n[{ key: "AeGUIRO2D5vQ6F", value: { Title: "237知更鸟", Alias: "骑着牛儿追织女", Author: "user1528210" } },{ key: "qQsUMJa19LcK3L", value: { Title: "Mika Automotive Extradimensional", Alias: "Temptation’s_Symphony", Author: "temptations_symphony" } }]',
    externalVideo: "非本站视频",
    noAvailableVideoSource: "没有可供下载的视频源",
    videoSourceNotAvailable: "视频源地址不可用",
    getVideoSourceFailed: "获取视频源失败",
    downloadFailed: "下载失败!",
    downloadThisFailed: "未找到可供下载的视频!",
    pushTaskFailed: "推送下载任务失败!",
    parsingFailed: "视频信息解析失败!",
    autoFollowFailed: "自动关注视频作者失败!",
    autoLikeFailed: "自动点赞视频失败!"
  };
  var en_default = {
    appName: "Iwara Download Tool",
    language: "Language: ",
    downloadPriority: "Download Quality: ",
    downloadPath: "Download Path: ",
    downloadProxy: "Download Proxy: ",
    downloadProxyUsername: "Download Proxy Username: ",
    downloadProxyPassword: "Download Proxy Password: ",
    aria2Path: "Aria2 RPC: ",
    aria2Token: "Aria2 Token: ",
    iwaraDownloaderPath: "IwaraDownloader RPC: ",
    iwaraDownloaderToken: "IwaraDownloader Token: ",
    experimentalFeatures: "Experimental Features",
    enableUnsafeMode: "Unsafe Mode (Use at your own risk)",
    rename: "Rename",
    save: "Save",
    reset: "Reset",
    ok: "OK",
    on: "On",
    off: "Off",
    delete: "Delete",
    deleteSucceed: "Deletion successful!",
    isDebug: "Debug Mode",
    downloadType: "Download Type",
    browserDownload: "Browser Download",
    iwaraDownloaderDownload: "IwaraDownloader Download",
    autoFollow: "Automatically follow the selected video author",
    autoLike: "Automatically like the selected videos",
    addUnlistedAndPrivate: "Force display unlisted and private videos (requires following the author)",
    parseUnlistedAndPrivate: "Parse recent unlisted and private videos",
    checkDownloadLink: "Check third-party cloud storage download links",
    checkPriority: "Check download quality",
    autoDownloadMetadata: "Auto-download metadata",
    videoMetadata: "Video Metadata",
    autoInjectCheckbox: "Automatically inject selection box",
    autoCopySaveFileName: "Automatically copy the filename generated by rules",
    configurationIncompatible: "Initialization or configuration file incompatible, please reconfigure!",
    browserDownloadNotEnabled: "Download feature not enabled!",
    browserDownloadNotWhitelisted: "Requested file extension not whitelisted!",
    browserDownloadNotPermitted: "Download feature enabled, but permission not granted!",
    browserDownloadNotSupported: "Current browser/version does not support download functionality!",
    browserDownloadNotSucceeded: "Download did not start or failed!",
    browserDownloadUnknownError: "Unknown error, possibly due to invalid download parameters. Please check if the filename is valid!",
    browserDownloadTimeout: "Download timed out. Please check your network connection!",
    variable: "View available variables",
    downloadTime: "Download Time ",
    uploadTime: "Upload Time ",
    example: "Example: ",
    result: "Result: ",
    loadingCompleted: "Loading completed",
    settings: "Open Settings",
    downloadThis: "Download current video",
    manualDownload: "Manually specify download",
    aria2TaskCheck: "Aria2 Task Restart",
    reverseSelect: "Reverse selection on this page",
    deselectThis: "Deselect on this page",
    deselectAll: "Deselect all",
    selectThis: "Select all on this page",
    selected: "Selected",
    downloadSelected: "Download selected",
    downloadingSelected: "Downloading selected, please wait...",
    injectCheckbox: "Toggle selection box",
    configError: "There is an error in the script configuration. Please modify.",
    alreadyKnowHowToUse: "I already know how to use it!!!",
    notice: [
      "Loading Complete",
      {
        nodeType: "br"
      },
      "Notice: ",
      {
        nodeType: "br"
      },
      "Optimized notification display module, smoother animations (rewrote Toastify JS)"
    ],
    useHelpForBase: "Please read the usage guide carefully!",
    useHelpForInjectCheckbox: 'Enable "%#autoInjectCheckbox#%" for a better experience! Or wait for video cards to load, then click [%#injectCheckbox#%] in the sidebar to enable the selection box.',
    useHelpForCheckDownloadLink: 'Enabling "%#checkDownloadLink#%" will check the video description and comments before downloading. If third-party cloud storage links are found, a prompt will appear allowing you to visit the video page.',
    useHelpForManualDownload: [
      'To use manual download, provide the video ID. For batch manual download, use "|" to separate video IDs.',
      {
        nodeType: "br"
      },
      "Example: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L",
      {
        nodeType: "br"
      },
      "Or provide an array of objects in JSON format matching the following structure:",
      {
        nodeType: "br"
      },
      "[ ID: string, { Title?: string, Alias?: string, Author?: string } ]",
      {
        nodeType: "br"
      },
      "Example: ",
      {
        nodeType: "br"
      },
      `[["AeGUIRO2D5vQ6F", { Title: "237 Robin", Alias: "Riding Cow Chasing Weaving Maiden", Author: "user1528210" }],["qQsUMJa19LcK3L", { Title: "Mika Automotive Extradimensional", Alias: "Temptation's Symphony", Author: "temptations_symphony" }]]`
    ],
    useHelpForBugreport: [
      "To report bugs or usage issues, please visit: ",
      {
        nodeType: "a",
        childs: "Github",
        attributes: {
          href: "https://github.com/dawn-lc/IwaraDownloadTool/"
        }
      }
    ],
    tryRestartingDownload: "→ Click here to restart download ←",
    tryReparseDownload: "→ Click here to reparse ←",
    cdnCacheFinded: "→ Visit MMD Fans Cache Page ←",
    openVideoLink: "→ Visit Video Page ←",
    copySucceed: "Copy succeeded!",
    pushTaskSucceed: "Task pushed successfully!",
    connectionTest: "Connection Test",
    settingsCheck: "Settings Check",
    createTask: "Create Task",
    downloadPathError: "Download path error!",
    browserDownloadModeError: "Please enable the browser API download mode in the script manager!",
    downloadQualityError: "Specified quality download URL not found!",
    findedDownloadLink: "Possible third-party cloud storage link found!",
    allCompleted: "All parsing completed!",
    parsing: "Parsing...",
    following: "Following",
    parsingProgress: "Parsing Progress: ",
    manualDownloadTips: `For individual downloads, input the video ID here. For batch downloads, separate video IDs with "|". Example: AeGUIRO2D5vQ6F|qQsUMJa19LcK3L\r
Or provide an array of objects in JSON format matching the following structure:\r
{ key: string, value: { Title?: string, Alias?: string, Author?: string } }\r
Example: \r
[{ key: "AeGUIRO2D5vQ6F", value: { Title: "237 Robin", Alias: "Riding Cow Chasing Weaving Maiden", Author: "user1528210" } },{ key: "qQsUMJa19LcK3L", value: { Title: "Mika Automotive Extradimensional", Alias: "Temptation's Symphony", Author: "temptations_symphony" } }]`,
    externalVideo: "External Video",
    noAvailableVideoSource: "No available video sources",
    videoSourceNotAvailable: "Video source URL unavailable",
    getVideoSourceFailed: "Failed to get video source",
    downloadFailed: "Download failed!",
    downloadThisFailed: "No downloadable video found!",
    pushTaskFailed: "Failed to push download task!",
    parsingFailed: "Failed to parse video information!",
    autoFollowFailed: "Failed to auto-follow the video author!",
    autoLikeFailed: "Failed to auto-like the video!"
  };
  var i18nList = {
    zh: zh_cn_default,
    en: en_default
  };
  var DownloadType = (function(DownloadType2) {
    DownloadType2[DownloadType2["Aria2"] = 0] = "Aria2";
    DownloadType2[DownloadType2["IwaraDownloader"] = 1] = "IwaraDownloader";
    DownloadType2[DownloadType2["Browser"] = 2] = "Browser";
    DownloadType2[DownloadType2["Others"] = 3] = "Others";
    return DownloadType2;
  })({});
  var PageType = (function(PageType2) {
    PageType2["Video"] = "video";
    PageType2["Image"] = "image";
    PageType2["VideoList"] = "videoList";
    PageType2["ImageList"] = "imageList";
    PageType2["Forum"] = "forum";
    PageType2["ForumSection"] = "forumSection";
    PageType2["ForumThread"] = "forumThread";
    PageType2["Page"] = "page";
    PageType2["Home"] = "home";
    PageType2["Profile"] = "profile";
    PageType2["Subscriptions"] = "subscriptions";
    PageType2["Playlist"] = "playlist";
    PageType2["Favorites"] = "favorites";
    PageType2["Search"] = "search";
    PageType2["Account"] = "account";
    return PageType2;
  })({});
  var ToastType = (function(ToastType2) {
    ToastType2[ToastType2["Log"] = 0] = "Log";
    ToastType2[ToastType2["Info"] = 1] = "Info";
    ToastType2[ToastType2["Warn"] = 2] = "Warn";
    ToastType2[ToastType2["Error"] = 3] = "Error";
    return ToastType2;
  })({});
  var MessageType = (function(MessageType2) {
    MessageType2[MessageType2["Close"] = 0] = "Close";
    MessageType2[MessageType2["Request"] = 1] = "Request";
    MessageType2[MessageType2["Receive"] = 2] = "Receive";
    MessageType2[MessageType2["Set"] = 3] = "Set";
    MessageType2[MessageType2["Del"] = 4] = "Del";
    return MessageType2;
  })({});
  var VersionState = (function(VersionState2) {
    VersionState2[VersionState2["Low"] = 0] = "Low";
    VersionState2[VersionState2["Equal"] = 1] = "Equal";
    VersionState2[VersionState2["High"] = 2] = "High";
    return VersionState2;
  })({});
  var originalFetch = unsafeWindow.fetch;
  var originalHistoryPushState = unsafeWindow.history.pushState;
  var originalHistoryReplaceState = unsafeWindow.history.replaceState;
  var originalNodeAppendChild = unsafeWindow.Node.prototype.appendChild;
  var originalNodeRemoveChild = unsafeWindow.Node.prototype.removeChild;
  var originalElementRemove = unsafeWindow.Element.prototype.remove;
  var originalAddEventListener = unsafeWindow.EventTarget.prototype.addEventListener;
  var originalRemoveEventListener = unsafeWindow.EventTarget.prototype.removeEventListener;
  var originalStorageSetItem = unsafeWindow.Storage.prototype.setItem;
  var originalStorageRemoveItem = unsafeWindow.Storage.prototype.removeItem;
  var originalStorageClear = unsafeWindow.Storage.prototype.clear;
  var originalConsole = {
    log: unsafeWindow.console.log.bind(unsafeWindow.console),
    info: unsafeWindow.console.info.bind(unsafeWindow.console),
    warn: unsafeWindow.console.warn.bind(unsafeWindow.console),
    error: unsafeWindow.console.error.bind(unsafeWindow.console),
    debug: unsafeWindow.console.debug.bind(unsafeWindow.console),
    trace: unsafeWindow.console.trace.bind(unsafeWindow.console),
    dir: unsafeWindow.console.dir.bind(unsafeWindow.console),
    table: unsafeWindow.console.table?.bind(unsafeWindow.console)
  };
  var DEFAULT_CONFIG = {
    language: "zh_cn",
    autoFollow: false,
    autoLike: false,
    autoCopySaveFileName: false,
    autoDownloadMetadata: false,
    enableUnsafeMode: false,
    experimentalFeatures: false,
    autoInjectCheckbox: true,
    checkDownloadLink: false,
    checkPriority: true,
    addUnlistedAndPrivate: false,
    downloadPriority: "Source",
    downloadType: DownloadType.Others,
    downloadPath: "/Iwara/%#AUTHOR#%/%#TITLE#%[%#ID#%].mp4",
    downloadProxy: "",
    downloadProxyUsername: "",
    downloadProxyPassword: "",
    aria2Path: "http://127.0.0.1:6800/jsonrpc",
    aria2Token: "",
    iwaraDownloaderPath: "http://127.0.0.1:6800/jsonrpc",
    iwaraDownloaderToken: "",
    priority: {
      "Source": 100,
      "540": 99,
      "360": 98,
      "preview": 1
    }
  };
  var Config = class _Config {
    constructor() {
      this.language = DEFAULT_CONFIG.language;
      this.autoFollow = DEFAULT_CONFIG.autoFollow;
      this.autoLike = DEFAULT_CONFIG.autoLike;
      this.autoCopySaveFileName = DEFAULT_CONFIG.autoCopySaveFileName;
      this.experimentalFeatures = DEFAULT_CONFIG.experimentalFeatures;
      this.enableUnsafeMode = DEFAULT_CONFIG.enableUnsafeMode;
      this.autoInjectCheckbox = DEFAULT_CONFIG.autoInjectCheckbox;
      this.checkDownloadLink = DEFAULT_CONFIG.checkDownloadLink;
      this.checkPriority = DEFAULT_CONFIG.checkPriority;
      this.addUnlistedAndPrivate = DEFAULT_CONFIG.addUnlistedAndPrivate;
      this.downloadPriority = DEFAULT_CONFIG.downloadPriority;
      this.downloadType = DEFAULT_CONFIG.downloadType;
      this.downloadPath = DEFAULT_CONFIG.downloadPath;
      this.downloadProxy = DEFAULT_CONFIG.downloadProxy;
      this.downloadProxyUsername = DEFAULT_CONFIG.downloadProxyUsername;
      this.downloadProxyPassword = DEFAULT_CONFIG.downloadProxyPassword;
      this.aria2Path = DEFAULT_CONFIG.aria2Path;
      this.aria2Token = DEFAULT_CONFIG.aria2Token;
      this.iwaraDownloaderPath = DEFAULT_CONFIG.iwaraDownloaderPath;
      this.iwaraDownloaderToken = DEFAULT_CONFIG.iwaraDownloaderToken;
      this.priority = DEFAULT_CONFIG.priority;
      this.autoDownloadMetadata = DEFAULT_CONFIG.autoDownloadMetadata;
      let body = new Proxy(this, {
        get: function(target, property) {
          if (property === "configChange") {
            return target.configChange;
          }
          let value = GM_getValue(property, target[property]);
          if (property === "language") {
            return _Config.getLanguage(value);
          }
          GM_getValue("isDebug") && originalConsole.debug(`[Debug] get: ${property} ${/password/i.test(property) || /token/i.test(property) || /authorization/i.test(property) ? "凭证已隐藏" : stringify(value)}`);
          return value;
        },
        set: function(target, property, value) {
          if (property === "configChange") {
            target.configChange = value;
            return true;
          }
          GM_setValue(property, value);
          GM_getValue("isDebug") && originalConsole.debug(`[Debug] set: ${property} ${/password/i.test(property) || /token/i.test(property) || /authorization/i.test(property) ? "凭证已隐藏" : stringify(value)}`);
          if (!isNullOrUndefined(target.configChange)) target.configChange(property);
          return true;
        }
      });
      GM_listValues().forEach((value) => {
        GM_addValueChangeListener(value, (name, old_value, new_value, remote) => {
          GM_getValue("isDebug") && originalConsole.debug(`[Debug] Config Change Is Remote: ${remote} Change Value: ${name}`);
          if (remote && !isNullOrUndefined(body.configChange)) body.configChange(name);
        });
      });
      return body;
    }
    static getLanguage(value) {
      function formatLanguage(value2) {
        return value2.replace("-", "_").toLowerCase();
      }
      function getMainLanguage(value2) {
        return value2.split("_").shift();
      }
      let custom = formatLanguage(value ?? DEFAULT_CONFIG.language);
      if (!isNullOrUndefined(custom)) {
        if (!isNullOrUndefined(i18nList[custom])) {
          return custom;
        } else {
          let customMain = getMainLanguage(custom);
          if (!isNullOrUndefined(i18nList[customMain])) {
            return customMain;
          }
        }
      }
      let env = formatLanguage(navigator.language ?? navigator.languages[0] ?? DEFAULT_CONFIG.language);
      if (!isNullOrUndefined(i18nList[env])) {
        return env;
      } else {
        let main2 = getMainLanguage(env);
        if (!isNullOrUndefined(i18nList[main2])) {
          return main2;
        }
      }
      return DEFAULT_CONFIG.language;
    }
    static getInstance() {
      if (isNullOrUndefined(_Config.instance)) _Config.instance = new _Config();
      return _Config.instance;
    }
    static destroyInstance() {
      _Config.instance = void 0;
    }
  };
  var config = Config.getInstance();
  var Path = class {
    constructor(inputPath) {
      if (inputPath === "") {
        throw new Error("路径不能为空");
      }
      if (this.isUNC(inputPath)) {
        throw new Error("不接受UNC路径");
      }
      const detectedType = this.detectPathType(inputPath);
      this.validatePath(inputPath, detectedType);
      const normalized = this.normalizePath(inputPath, detectedType);
      const directory = this.extractDirectory(normalized, detectedType);
      const fileName = this.extractFileName(normalized, detectedType);
      const {
        baseName,
        extension
      } = this.extractBaseAndExtension(fileName);
      this.type = detectedType;
      this.fullPath = normalized;
      this.directory = directory;
      this.fullName = fileName;
      this.baseName = baseName;
      this.extension = extension;
    }
    isUNC(path) {
      return path.startsWith("\\\\");
    }
    detectPathType(path) {
      if (/^[A-Za-z]:[\\/]/.test(path)) {
        return "Windows";
      }
      if (path.startsWith("/")) {
        return "Unix";
      }
      return "Relative";
    }
    validatePath(path, type2) {
      const invalidChars = /[<>:"|?*]/;
      if (type2 === "Windows") {
        if (!/^[A-Za-z]:[\\/]/.test(path)) {
          throw new Error("无效的Windows路径格式");
        }
        const segments = path.split(/[\\/]/);
        for (let i = 1; i < segments.length; i++) {
          let segment = segments[i];
          let variables = [...segment.matchAll(/%#(.*?)#%/g)].map((match) => {
            let variable = match[1].split(":");
            if (variable.length > 1) {
              if (invalidChars.test(variable[1])) {
                throw new Error(`路径变量格式化参数 "${variable[1]}" 含有非法字符`);
              }
            }
            return match[1];
          });
          for (let index = 0; index < variables.length; index++) {
            const variable = variables[index];
            segment = segment.replaceAll(variable, "");
          }
          if (invalidChars.test(segment)) {
            throw new Error(`路径段 "${segments[i]}" 含有非法字符`);
          }
        }
      } else if (type2 === "Unix") {
        if (path.indexOf("\0") !== -1) {
          throw new Error("路径中包含非法空字符");
        }
      } else if (type2 === "Relative") {
        if (path.indexOf("\0") !== -1) {
          throw new Error("路径中包含非法空字符");
        }
        if (invalidChars.test(path)) {
          throw new Error("路径含有非法字符");
        }
      }
    }
    normalizePath(path, type2) {
      const sep = type2 === "Windows" ? "\\" : "/";
      if (type2 === "Windows") {
        path = path.replace(/\//g, "\\");
        path = path.replace(/\\+/g, "\\");
      } else {
        path = path.replace(/\\/g, "/");
        path = path.replace(/\/+/g, "/");
      }
      let segments;
      if (type2 === "Windows") {
        segments = path.split("\\");
      } else {
        segments = path.split("/");
      }
      let isAbsolute = false;
      let prefix = "";
      if (type2 === "Windows") {
        if (/^[A-Za-z]:$/.test(segments[0])) {
          isAbsolute = true;
          prefix = segments[0];
          segments = segments.slice(1);
        }
      } else if (type2 === "Unix") {
        if (path.startsWith("/")) {
          isAbsolute = true;
          if (segments[0] === "") {
            segments = segments.slice(1);
          }
        }
      } else {
        isAbsolute = false;
      }
      const resolvedSegments = this.resolveSegments(segments, isAbsolute);
      let normalized = "";
      if (type2 === "Windows") {
        normalized = prefix ? prefix + sep + resolvedSegments.join(sep) : resolvedSegments.join(sep);
        if (prefix && normalized === prefix) {
          normalized += sep;
        }
      } else if (type2 === "Unix") {
        normalized = (isAbsolute ? sep : "") + resolvedSegments.join(sep);
        if (isAbsolute && normalized === "") {
          normalized = sep;
        }
      } else {
        normalized = resolvedSegments.join(sep);
      }
      return normalized;
    }
    resolveSegments(segments, isAbsolute) {
      const stack = [];
      for (const segment of segments) {
        if (segment === "" || segment === ".") continue;
        if (segment === "..") {
          if (stack.length > 0 && stack[stack.length - 1] !== "..") {
            stack.pop();
          } else {
            if (isAbsolute) {
              throw new Error("绝对路径不能越界");
            } else {
              stack.push("..");
            }
          }
        } else {
          stack.push(segment);
        }
      }
      return stack;
    }
    extractDirectory(path, type2) {
      const sep = type2 === "Windows" ? "\\" : "/";
      if (type2 === "Windows" && /^[A-Za-z]:\\$/.test(path)) {
        return path;
      }
      if (type2 === "Unix" && path === "/") {
        return path;
      }
      const lastIndex = path.lastIndexOf(sep);
      return lastIndex === -1 ? "" : path.substring(0, lastIndex);
    }
    extractFileName(path, type2) {
      const sep = type2 === "Windows" ? "\\" : "/";
      const lastIndex = path.lastIndexOf(sep);
      return lastIndex === -1 ? path : path.substring(lastIndex + 1);
    }
    extractBaseAndExtension(fileName) {
      const lastDot = fileName.lastIndexOf(".");
      if (lastDot <= 0) {
        return {
          baseName: fileName,
          extension: ""
        };
      }
      const baseName = fileName.substring(0, lastDot);
      const extension = fileName.substring(lastDot + 1);
      return {
        baseName,
        extension
      };
    }
  };
  var Version = class _Version {
    constructor(versionString) {
      if (!versionString || typeof versionString !== "string") {
        throw new Error("Invalid version string");
      }
      const [version, preRelease, buildMetadata] = versionString.split(/[-+]/);
      const versionParts = version.split(".").map(Number);
      if (versionParts.some(isNaN)) {
        throw new Error("Version string contains invalid numbers");
      }
      this.major = versionParts[0] || 0;
      this.minor = versionParts.length > 1 ? versionParts[1] : 0;
      this.patch = versionParts.length > 2 ? versionParts[2] : 0;
      this.preRelease = preRelease ? preRelease.split(".") : [];
      this.buildMetadata = buildMetadata || "";
    }
    static compareValues(a, b) {
      if (a < b) return VersionState.Low;
      if (a > b) return VersionState.High;
      return VersionState.Equal;
    }
    compare(other) {
      let state = _Version.compareValues(this.major, other.major);
      if (state !== VersionState.Equal) return state;
      state = _Version.compareValues(this.minor, other.minor);
      if (state !== VersionState.Equal) return state;
      state = _Version.compareValues(this.patch, other.patch);
      if (state !== VersionState.Equal) return state;
      for (let i = 0; i < Math.max(this.preRelease.length, other.preRelease.length); i++) {
        const pre1 = this.preRelease[i] ?? "";
        const pre2 = other.preRelease[i] ?? "";
        state = _Version.compareValues(isNaN(+pre1) ? pre1 : +pre1, isNaN(+pre2) ? pre2 : +pre2);
        if (state !== VersionState.Equal) return state;
      }
      return VersionState.Equal;
    }
    toString() {
      const version = `${this.major}.${this.minor}.${this.patch}`;
      const preRelease = this.preRelease.length ? `-${this.preRelease.join(".")}` : "";
      const buildMetadata = this.buildMetadata ? `+${this.buildMetadata}` : "";
      return `${version}${preRelease}${buildMetadata}`;
    }
  };
  var Dictionary = class extends Map {
    constructor(data = []) {
      super(data);
    }
    toArray() {
      return Array.from(this);
    }
    keysArray() {
      return Array.from(this.keys());
    }
    valuesArray() {
      return Array.from(this.values());
    }
  };
  var VCSyncDictionary = class _VCSyncDictionary extends Dictionary {
    constructor(channelName, initial = []) {
      super(initial.length ? initial : void 0);
      this.channelName = channelName;
      this.id = UUID();
      this.vectorClock = {
        [this.id]: 0
      };
      this.keyWallClock =  new Map();
      const now = Date.now();
      for (const [k] of initial) {
        this.keyWallClock.set(k, now);
      }
      this.channel = new BroadcastChannel(channelName);
      this.channel.onmessage = ({
        data: msg
      }) => this.handleMessage(msg);
      this.channel.postMessage({
        type: "sync",
        id: this.id,
        vectorClock: this.vectorClock,
        wallClock: Date.now()
      });
    }
    incrementVC() {
      this.vectorClock[this.id] = (this.vectorClock[this.id] ?? 0) + 1;
    }
    set(key, value) {
      this.incrementVC();
      const wallClock = Date.now();
      super.set(key, value);
      this.keyWallClock.set(key, wallClock);
      this.channel.postMessage({
        type: "set",
        key,
        value,
        id: this.id,
        vectorClock: {
          ...this.vectorClock
        },
        wallClock
      });
      this.onSet?.(key, value);
      return this;
    }
    delete(key) {
      this.incrementVC();
      const wallClock = Date.now();
      const existed = super.delete(key);
      if (existed) {
        this.keyWallClock.set(key, wallClock);
        this.channel.postMessage({
          type: "delete",
          key,
          id: this.id,
          vectorClock: {
            ...this.vectorClock
          },
          wallClock
        });
        this.onDel?.(key);
      }
      return existed;
    }
    clear() {
      this.incrementVC();
      const wallClock = Date.now();
      super.clear();
      this.keyWallClock.clear();
      this.channel.postMessage({
        type: "state",
        state: super.toArray(),
        id: this.id,
        vectorClock: {
          ...this.vectorClock
        },
        wallClock
      });
      this.onSync?.();
    }
    handleMessage(msg) {
      if (msg.id === this.id) return;
      const cmp2 = compareVC(msg.vectorClock, this.vectorClock);
      if (cmp2 === "before") {
        if (msg.type === "sync") {
          this.channel.postMessage({
            type: "state",
            state: super.toArray(),
            id: this.id,
            vectorClock: {
              ...this.vectorClock
            },
            wallClock: Date.now()
          });
        }
        return;
      }
      this.vectorClock = mergeVC(this.vectorClock, msg.vectorClock);
      switch (msg.type) {
        case "state":
          super.clear();
          this.keyWallClock.clear();
          const now = Date.now();
          for (const [key, value] of msg.state) {
            super.set(key, value);
            this.keyWallClock.set(key, now);
          }
          this.onSync?.();
          break;
        case "set": {
          const {
            key,
            value,
            wallClock
          } = msg;
          const localWallClock = this.keyWallClock.get(key) ?? 0;
          if (cmp2 === "after" || cmp2 === "concurrent" && wallClock > localWallClock) {
            super.set(key, value);
            this.keyWallClock.set(key, wallClock);
            this.onSet?.(key, value);
          }
          break;
        }
        case "delete": {
          const {
            key,
            wallClock
          } = msg;
          const localWallClock = this.keyWallClock.get(key) ?? 0;
          if (cmp2 === "after" || cmp2 === "concurrent" && wallClock > localWallClock) {
            if (super.delete(key)) {
              this.keyWallClock.set(key, wallClock);
              this.onDel?.(key);
            }
          }
          break;
        }
      }
    }
    save() {
      const obj = {
        data: super.toArray(),
        vectorClock: this.vectorClock,
        keyWallClock: Array.from(this.keyWallClock.entries()),
        id: this.id
      };
      GM_setValue(this.channelName, obj);
    }
    static load(channelName) {
      const obj = GM_getValue(channelName, void 0);
      if (!obj) return void 0;
      const dict = new _VCSyncDictionary(channelName, obj.data);
      dict.vectorClock = obj.vectorClock || {};
      dict.keyWallClock = new Map(obj.keyWallClock || []);
      dict.id = obj.id || UUID();
      return dict;
    }
  };
  var SyncDictionary = class extends Dictionary {
    constructor(channelName, initial = []) {
      const hasInitial = prune(initial).any();
      super(hasInitial ? initial : void 0);
      this.timestamp = hasInitial ? Date.now() : 0;
      this.lifetime = hasInitial ? performance.now() : 0;
      this.id = UUID();
      this.channel = new BroadcastChannel(channelName);
      this.channel.onmessage = ({
        data: msg
      }) => this.handleMessage(msg);
      this.channel.postMessage({
        type: "sync",
        id: this.id,
        timestamp: this.timestamp,
        lifetime: this.lifetime
      });
    }
    setTimestamp(timestamp) {
      this.timestamp = timestamp ?? Date.now();
      this.lifetime = performance.now();
    }
    set(key, value) {
      this.setTimestamp();
      super.set(key, value);
      this.channel.postMessage({
        type: "set",
        key,
        value,
        timestamp: this.timestamp,
        lifetime: this.lifetime,
        id: this.id
      });
      this.onSet?.(key, value);
      return this;
    }
    delete(key) {
      this.setTimestamp();
      const existed = super.delete(key);
      if (existed) {
        this.onDel?.(key);
        this.channel.postMessage({
          type: "delete",
          key,
          timestamp: this.timestamp,
          lifetime: this.lifetime,
          id: this.id
        });
      }
      return existed;
    }
    clear() {
      this.setTimestamp();
      super.clear();
      this.channel.postMessage({
        timestamp: this.timestamp,
        lifetime: this.lifetime,
        id: this.id,
        type: "state",
        state: super.toArray()
      });
      this.onSync?.();
    }
    handleMessage(msg) {
      if (msg.id === this.id) return;
      if (msg.type === "sync") {
        this.channel.postMessage({
          timestamp: this.timestamp,
          lifetime: this.lifetime,
          id: this.id,
          type: "state",
          state: super.toArray()
        });
        return;
      }
      if (msg.timestamp === this.timestamp && msg.lifetime === this.lifetime) return;
      if (msg.timestamp < this.timestamp || msg.lifetime < this.lifetime) return;
      switch (msg.type) {
        case "state": {
          super.clear();
          for (let index = 0; index < msg.state.length; index++) {
            const [key, value] = msg.state[index];
            super.set(key, value);
          }
          this.setTimestamp(msg.timestamp);
          this.onSync?.();
          break;
        }
        case "set": {
          const {
            key,
            value
          } = msg;
          super.set(key, value);
          this.setTimestamp(msg.timestamp);
          this.onSet?.(key, value);
          break;
        }
        case "delete": {
          const {
            key
          } = msg;
          if (super.delete(key)) {
            this.setTimestamp(msg.timestamp);
            this.onDel?.(key);
          }
          break;
        }
      }
    }
  };
  var MultiPage = class {
    constructor() {
      this.pageId = UUID();
      GM_saveTab({
        id: this.pageId
      });
      this.channel = new BroadcastChannel("page-status-channel");
      this.channel.onmessage = (event) => this.handleMessage(event.data);
      this.channel.postMessage({
        type: "join",
        id: this.pageId
      });
      this.beforeUnloadHandler = () => {
        this.channel.postMessage({
          type: "leave",
          id: this.pageId
        });
        originalRemoveEventListener.call(unsafeWindow.document, "beforeunload", this.beforeUnloadHandler);
      };
      originalAddEventListener.call(unsafeWindow.document, "beforeunload", this.beforeUnloadHandler);
    }
    suicide() {
      this.channel.postMessage({
        type: "suicide",
        id: this.pageId
      });
    }
    handleMessage(message) {
      switch (message.type) {
        case "suicide":
          if (this.pageId !== message.id) unsafeWindow.close();
          break;
        case "join":
          this.onPageJoin?.(message.id);
          break;
        case "leave":
          this.onPageLeave?.(message.id);
          GM_getTabs((tabs) => {
            if (Object.keys(tabs).length > 1) return;
            this.onLastPage?.();
          });
          break;
      }
    }
  };
  var _global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : global;
  var keys = Object.keys;
  var isArray2 = Array.isArray;
  if (typeof Promise !== "undefined" && !_global.Promise) {
    _global.Promise = Promise;
  }
  function extend(obj, extension) {
    if (typeof extension !== "object")
      return obj;
    keys(extension).forEach(function(key) {
      obj[key] = extension[key];
    });
    return obj;
  }
  var getProto = Object.getPrototypeOf;
  var _hasOwn = {}.hasOwnProperty;
  function hasOwn(obj, prop) {
    return _hasOwn.call(obj, prop);
  }
  function props(proto, extension) {
    if (typeof extension === "function")
      extension = extension(getProto(proto));
    (typeof Reflect === "undefined" ? keys : Reflect.ownKeys)(extension).forEach((key) => {
      setProp(proto, key, extension[key]);
    });
  }
  var defineProperty = Object.defineProperty;
  function setProp(obj, prop, functionOrGetSet, options) {
    defineProperty(obj, prop, extend(functionOrGetSet && hasOwn(functionOrGetSet, "get") && typeof functionOrGetSet.get === "function" ? { get: functionOrGetSet.get, set: functionOrGetSet.set, configurable: true } : { value: functionOrGetSet, configurable: true, writable: true }, options));
  }
  function derive(Child) {
    return {
      from: function(Parent) {
        Child.prototype = Object.create(Parent.prototype);
        setProp(Child.prototype, "constructor", Child);
        return {
          extend: props.bind(null, Child.prototype)
        };
      }
    };
  }
  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  function getPropertyDescriptor(obj, prop) {
    const pd = getOwnPropertyDescriptor(obj, prop);
    let proto;
    return pd || (proto = getProto(obj)) && getPropertyDescriptor(proto, prop);
  }
  var _slice = [].slice;
  function slice(args, start, end) {
    return _slice.call(args, start, end);
  }
  function override(origFunc, overridedFactory) {
    return overridedFactory(origFunc);
  }
  function assert(b) {
    if (!b)
      throw new Error("Assertion Failed");
  }
  function asap$1(fn) {
    if (_global.setImmediate)
      setImmediate(fn);
    else
      setTimeout(fn, 0);
  }
  function arrayToObject(array, extractor) {
    return array.reduce((result, item, i) => {
      var nameAndValue = extractor(item, i);
      if (nameAndValue)
        result[nameAndValue[0]] = nameAndValue[1];
      return result;
    }, {});
  }
  function tryCatch(fn, onerror, args) {
    try {
      fn.apply(null, args);
    } catch (ex) {
      onerror && onerror(ex);
    }
  }
  function getByKeyPath(obj, keyPath) {
    if (typeof keyPath === "string" && hasOwn(obj, keyPath))
      return obj[keyPath];
    if (!keyPath)
      return obj;
    if (typeof keyPath !== "string") {
      var rv = [];
      for (var i = 0, l = keyPath.length; i < l; ++i) {
        var val = getByKeyPath(obj, keyPath[i]);
        rv.push(val);
      }
      return rv;
    }
    var period = keyPath.indexOf(".");
    if (period !== -1) {
      var innerObj = obj[keyPath.substr(0, period)];
      return innerObj == null ? void 0 : getByKeyPath(innerObj, keyPath.substr(period + 1));
    }
    return void 0;
  }
  function setByKeyPath(obj, keyPath, value) {
    if (!obj || keyPath === void 0)
      return;
    if ("isFrozen" in Object && Object.isFrozen(obj))
      return;
    if (typeof keyPath !== "string" && "length" in keyPath) {
      assert(typeof value !== "string" && "length" in value);
      for (var i = 0, l = keyPath.length; i < l; ++i) {
        setByKeyPath(obj, keyPath[i], value[i]);
      }
    } else {
      var period = keyPath.indexOf(".");
      if (period !== -1) {
        var currentKeyPath = keyPath.substr(0, period);
        var remainingKeyPath = keyPath.substr(period + 1);
        if (remainingKeyPath === "")
          if (value === void 0) {
            if (isArray2(obj) && !isNaN(parseInt(currentKeyPath)))
              obj.splice(currentKeyPath, 1);
            else
              delete obj[currentKeyPath];
          } else
            obj[currentKeyPath] = value;
        else {
          var innerObj = obj[currentKeyPath];
          if (!innerObj || !hasOwn(obj, currentKeyPath))
            innerObj = obj[currentKeyPath] = {};
          setByKeyPath(innerObj, remainingKeyPath, value);
        }
      } else {
        if (value === void 0) {
          if (isArray2(obj) && !isNaN(parseInt(keyPath)))
            obj.splice(keyPath, 1);
          else
            delete obj[keyPath];
        } else
          obj[keyPath] = value;
      }
    }
  }
  function delByKeyPath(obj, keyPath) {
    if (typeof keyPath === "string")
      setByKeyPath(obj, keyPath, void 0);
    else if ("length" in keyPath)
      [].map.call(keyPath, function(kp) {
        setByKeyPath(obj, kp, void 0);
      });
  }
  function shallowClone(obj) {
    var rv = {};
    for (var m in obj) {
      if (hasOwn(obj, m))
        rv[m] = obj[m];
    }
    return rv;
  }
  var concat = [].concat;
  function flatten(a) {
    return concat.apply([], a);
  }
  var intrinsicTypeNames = "BigUint64Array,BigInt64Array,Array,Boolean,String,Date,RegExp,Blob,File,FileList,FileSystemFileHandle,FileSystemDirectoryHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey".split(",").concat(flatten([8, 16, 32, 64].map((num) => ["Int", "Uint", "Float"].map((t) => t + num + "Array")))).filter((t) => _global[t]);
  var intrinsicTypes = intrinsicTypeNames.map((t) => _global[t]);
  arrayToObject(intrinsicTypeNames, (x) => [x, true]);
  var circularRefs = null;
  function deepClone(any) {
    circularRefs = typeof WeakMap !== "undefined" &&  new WeakMap();
    const rv = innerDeepClone(any);
    circularRefs = null;
    return rv;
  }
  function innerDeepClone(any) {
    if (!any || typeof any !== "object")
      return any;
    let rv = circularRefs && circularRefs.get(any);
    if (rv)
      return rv;
    if (isArray2(any)) {
      rv = [];
      circularRefs && circularRefs.set(any, rv);
      for (var i = 0, l = any.length; i < l; ++i) {
        rv.push(innerDeepClone(any[i]));
      }
    } else if (intrinsicTypes.indexOf(any.constructor) >= 0) {
      rv = any;
    } else {
      const proto = getProto(any);
      rv = proto === Object.prototype ? {} : Object.create(proto);
      circularRefs && circularRefs.set(any, rv);
      for (var prop in any) {
        if (hasOwn(any, prop)) {
          rv[prop] = innerDeepClone(any[prop]);
        }
      }
    }
    return rv;
  }
  var { toString } = {};
  function toStringTag(o) {
    return toString.call(o).slice(8, -1);
  }
  var iteratorSymbol = typeof Symbol !== "undefined" ? Symbol.iterator : "@@iterator";
  var getIteratorOf = typeof iteratorSymbol === "symbol" ? function(x) {
    var i;
    return x != null && (i = x[iteratorSymbol]) && i.apply(x);
  } : function() {
    return null;
  };
  var NO_CHAR_ARRAY = {};
  function getArrayOf(arrayLike) {
    var i, a, x, it;
    if (arguments.length === 1) {
      if (isArray2(arrayLike))
        return arrayLike.slice();
      if (this === NO_CHAR_ARRAY && typeof arrayLike === "string")
        return [arrayLike];
      if (it = getIteratorOf(arrayLike)) {
        a = [];
        while (x = it.next(), !x.done)
          a.push(x.value);
        return a;
      }
      if (arrayLike == null)
        return [arrayLike];
      i = arrayLike.length;
      if (typeof i === "number") {
        a = new Array(i);
        while (i--)
          a[i] = arrayLike[i];
        return a;
      }
      return [arrayLike];
    }
    i = arguments.length;
    a = new Array(i);
    while (i--)
      a[i] = arguments[i];
    return a;
  }
  var isAsyncFunction = typeof Symbol !== "undefined" ? (fn) => fn[Symbol.toStringTag] === "AsyncFunction" : () => false;
  var debug = typeof location !== "undefined" && /^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href);
  function setDebug(value, filter) {
    debug = value;
    libraryFilter = filter;
  }
  var libraryFilter = () => true;
  var NEEDS_THROW_FOR_STACK = !new Error("").stack;
  function getErrorWithStack() {
    if (NEEDS_THROW_FOR_STACK)
      try {
        getErrorWithStack.arguments;
        throw new Error();
      } catch (e) {
        return e;
      }
    return new Error();
  }
  function prettyStack(exception, numIgnoredFrames) {
    var stack = exception.stack;
    if (!stack)
      return "";
    numIgnoredFrames = numIgnoredFrames || 0;
    if (stack.indexOf(exception.name) === 0)
      numIgnoredFrames += (exception.name + exception.message).split("\n").length;
    return stack.split("\n").slice(numIgnoredFrames).filter(libraryFilter).map((frame) => "\n" + frame).join("");
  }
  var dexieErrorNames = [
    "Modify",
    "Bulk",
    "OpenFailed",
    "VersionChange",
    "Schema",
    "Upgrade",
    "InvalidTable",
    "MissingAPI",
    "NoSuchDatabase",
    "InvalidArgument",
    "SubTransaction",
    "Unsupported",
    "Internal",
    "DatabaseClosed",
    "PrematureCommit",
    "ForeignAwait"
  ];
  var idbDomErrorNames = [
    "Unknown",
    "Constraint",
    "Data",
    "TransactionInactive",
    "ReadOnly",
    "Version",
    "NotFound",
    "InvalidState",
    "InvalidAccess",
    "Abort",
    "Timeout",
    "QuotaExceeded",
    "Syntax",
    "DataClone"
  ];
  var errorList = dexieErrorNames.concat(idbDomErrorNames);
  var defaultTexts = {
    VersionChanged: "Database version changed by other database connection",
    DatabaseClosed: "Database has been closed",
    Abort: "Transaction aborted",
    TransactionInactive: "Transaction has already completed or failed",
    MissingAPI: "IndexedDB API missing. Please visit https://tinyurl.com/y2uuvskb"
  };
  function DexieError(name, msg) {
    this._e = getErrorWithStack();
    this.name = name;
    this.message = msg;
  }
  derive(DexieError).from(Error).extend({
    stack: {
      get: function() {
        return this._stack || (this._stack = this.name + ": " + this.message + prettyStack(this._e, 2));
      }
    },
    toString: function() {
      return this.name + ": " + this.message;
    }
  });
  function getMultiErrorMessage(msg, failures) {
    return msg + ". Errors: " + Object.keys(failures).map((key) => failures[key].toString()).filter((v, i, s) => s.indexOf(v) === i).join("\n");
  }
  function ModifyError(msg, failures, successCount, failedKeys) {
    this._e = getErrorWithStack();
    this.failures = failures;
    this.failedKeys = failedKeys;
    this.successCount = successCount;
    this.message = getMultiErrorMessage(msg, failures);
  }
  derive(ModifyError).from(DexieError);
  function BulkError(msg, failures) {
    this._e = getErrorWithStack();
    this.name = "BulkError";
    this.failures = Object.keys(failures).map((pos) => failures[pos]);
    this.failuresByPos = failures;
    this.message = getMultiErrorMessage(msg, failures);
  }
  derive(BulkError).from(DexieError);
  var errnames = errorList.reduce((obj, name) => (obj[name] = name + "Error", obj), {});
  var BaseException = DexieError;
  var exceptions = errorList.reduce((obj, name) => {
    var fullName = name + "Error";
    function DexieError2(msgOrInner, inner) {
      this._e = getErrorWithStack();
      this.name = fullName;
      if (!msgOrInner) {
        this.message = defaultTexts[name] || fullName;
        this.inner = null;
      } else if (typeof msgOrInner === "string") {
        this.message = `${msgOrInner}${!inner ? "" : "\n " + inner}`;
        this.inner = inner || null;
      } else if (typeof msgOrInner === "object") {
        this.message = `${msgOrInner.name} ${msgOrInner.message}`;
        this.inner = msgOrInner;
      }
    }
    derive(DexieError2).from(BaseException);
    obj[name] = DexieError2;
    return obj;
  }, {});
  exceptions.Syntax = SyntaxError;
  exceptions.Type = TypeError;
  exceptions.Range = RangeError;
  var exceptionMap = idbDomErrorNames.reduce((obj, name) => {
    obj[name + "Error"] = exceptions[name];
    return obj;
  }, {});
  function mapError(domError, message) {
    if (!domError || domError instanceof DexieError || domError instanceof TypeError || domError instanceof SyntaxError || !domError.name || !exceptionMap[domError.name])
      return domError;
    var rv = new exceptionMap[domError.name](message || domError.message, domError);
    if ("stack" in domError) {
      setProp(rv, "stack", { get: function() {
        return this.inner.stack;
      } });
    }
    return rv;
  }
  var fullNameExceptions = errorList.reduce((obj, name) => {
    if (["Syntax", "Type", "Range"].indexOf(name) === -1)
      obj[name + "Error"] = exceptions[name];
    return obj;
  }, {});
  fullNameExceptions.ModifyError = ModifyError;
  fullNameExceptions.DexieError = DexieError;
  fullNameExceptions.BulkError = BulkError;
  function nop() {
  }
  function mirror(val) {
    return val;
  }
  function pureFunctionChain(f1, f2) {
    if (f1 == null || f1 === mirror)
      return f2;
    return function(val) {
      return f2(f1(val));
    };
  }
  function callBoth(on1, on2) {
    return function() {
      on1.apply(this, arguments);
      on2.apply(this, arguments);
    };
  }
  function hookCreatingChain(f1, f2) {
    if (f1 === nop)
      return f2;
    return function() {
      var res = f1.apply(this, arguments);
      if (res !== void 0)
        arguments[0] = res;
      var onsuccess = this.onsuccess, onerror = this.onerror;
      this.onsuccess = null;
      this.onerror = null;
      var res2 = f2.apply(this, arguments);
      if (onsuccess)
        this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess;
      if (onerror)
        this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror;
      return res2 !== void 0 ? res2 : res;
    };
  }
  function hookDeletingChain(f1, f2) {
    if (f1 === nop)
      return f2;
    return function() {
      f1.apply(this, arguments);
      var onsuccess = this.onsuccess, onerror = this.onerror;
      this.onsuccess = this.onerror = null;
      f2.apply(this, arguments);
      if (onsuccess)
        this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess;
      if (onerror)
        this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror;
    };
  }
  function hookUpdatingChain(f1, f2) {
    if (f1 === nop)
      return f2;
    return function(modifications) {
      var res = f1.apply(this, arguments);
      extend(modifications, res);
      var onsuccess = this.onsuccess, onerror = this.onerror;
      this.onsuccess = null;
      this.onerror = null;
      var res2 = f2.apply(this, arguments);
      if (onsuccess)
        this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess;
      if (onerror)
        this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror;
      return res === void 0 ? res2 === void 0 ? void 0 : res2 : extend(res, res2);
    };
  }
  function reverseStoppableEventChain(f1, f2) {
    if (f1 === nop)
      return f2;
    return function() {
      if (f2.apply(this, arguments) === false)
        return false;
      return f1.apply(this, arguments);
    };
  }
  function promisableChain(f1, f2) {
    if (f1 === nop)
      return f2;
    return function() {
      var res = f1.apply(this, arguments);
      if (res && typeof res.then === "function") {
        var thiz = this, i = arguments.length, args = new Array(i);
        while (i--)
          args[i] = arguments[i];
        return res.then(function() {
          return f2.apply(thiz, args);
        });
      }
      return f2.apply(this, arguments);
    };
  }
  var INTERNAL = {};
  var LONG_STACKS_CLIP_LIMIT = 100, MAX_LONG_STACKS = 20, ZONE_ECHO_LIMIT = 100, [resolvedNativePromise, nativePromiseProto, resolvedGlobalPromise] = typeof Promise === "undefined" ? [] : (() => {
    let globalP = Promise.resolve();
    if (typeof crypto === "undefined" || !crypto.subtle)
      return [globalP, getProto(globalP), globalP];
    const nativeP = crypto.subtle.digest("SHA-512", new Uint8Array([0]));
    return [
      nativeP,
      getProto(nativeP),
      globalP
    ];
  })(), nativePromiseThen = nativePromiseProto && nativePromiseProto.then;
  var NativePromise = resolvedNativePromise && resolvedNativePromise.constructor;
  var patchGlobalPromise = !!resolvedGlobalPromise;
  var stack_being_generated = false;
  var schedulePhysicalTick = resolvedGlobalPromise ? () => {
    resolvedGlobalPromise.then(physicalTick);
  } : _global.setImmediate ? setImmediate.bind(null, physicalTick) : _global.MutationObserver ? () => {
    var hiddenDiv = document.createElement("div");
    new MutationObserver(() => {
      physicalTick();
      hiddenDiv = null;
    }).observe(hiddenDiv, { attributes: true });
    hiddenDiv.setAttribute("i", "1");
  } : () => {
    setTimeout(physicalTick, 0);
  };
  var asap = function(callback, args) {
    microtickQueue.push([callback, args]);
    if (needsNewPhysicalTick) {
      schedulePhysicalTick();
      needsNewPhysicalTick = false;
    }
  };
  var isOutsideMicroTick = true, needsNewPhysicalTick = true, unhandledErrors = [], rejectingErrors = [], currentFulfiller = null, rejectionMapper = mirror;
  var globalPSD = {
    id: "global",
    global: true,
    ref: 0,
    unhandleds: [],
    onunhandled: globalError,
    pgp: false,
    env: {},
    finalize: function() {
      this.unhandleds.forEach((uh) => {
        try {
          globalError(uh[0], uh[1]);
        } catch (e) {
        }
      });
    }
  };
  var PSD = globalPSD;
  var microtickQueue = [];
  var numScheduledCalls = 0;
  var tickFinalizers = [];
  function DexiePromise(fn) {
    if (typeof this !== "object")
      throw new TypeError("Promises must be constructed via new");
    this._listeners = [];
    this.onuncatched = nop;
    this._lib = false;
    var psd = this._PSD = PSD;
    if (debug) {
      this._stackHolder = getErrorWithStack();
      this._prev = null;
      this._numPrev = 0;
    }
    if (typeof fn !== "function") {
      if (fn !== INTERNAL)
        throw new TypeError("Not a function");
      this._state = arguments[1];
      this._value = arguments[2];
      if (this._state === false)
        handleRejection(this, this._value);
      return;
    }
    this._state = null;
    this._value = null;
    ++psd.ref;
    executePromiseTask(this, fn);
  }
  var thenProp = {
    get: function() {
      var psd = PSD, microTaskId = totalEchoes;
      function then(onFulfilled, onRejected) {
        var possibleAwait = !psd.global && (psd !== PSD || microTaskId !== totalEchoes);
        const cleanup = possibleAwait && !decrementExpectedAwaits();
        var rv = new DexiePromise((resolve, reject) => {
          propagateToListener(this, new Listener(nativeAwaitCompatibleWrap(onFulfilled, psd, possibleAwait, cleanup), nativeAwaitCompatibleWrap(onRejected, psd, possibleAwait, cleanup), resolve, reject, psd));
        });
        debug && linkToPreviousPromise(rv, this);
        return rv;
      }
      then.prototype = INTERNAL;
      return then;
    },
    set: function(value) {
      setProp(this, "then", value && value.prototype === INTERNAL ? thenProp : {
        get: function() {
          return value;
        },
        set: thenProp.set
      });
    }
  };
  props(DexiePromise.prototype, {
    then: thenProp,
    _then: function(onFulfilled, onRejected) {
      propagateToListener(this, new Listener(null, null, onFulfilled, onRejected, PSD));
    },
    catch: function(onRejected) {
      if (arguments.length === 1)
        return this.then(null, onRejected);
      var type2 = arguments[0], handler = arguments[1];
      return typeof type2 === "function" ? this.then(null, (err) => err instanceof type2 ? handler(err) : PromiseReject(err)) : this.then(null, (err) => err && err.name === type2 ? handler(err) : PromiseReject(err));
    },
    finally: function(onFinally) {
      return this.then((value) => {
        onFinally();
        return value;
      }, (err) => {
        onFinally();
        return PromiseReject(err);
      });
    },
    stack: {
      get: function() {
        if (this._stack)
          return this._stack;
        try {
          stack_being_generated = true;
          var stacks = getStack(this, [], MAX_LONG_STACKS);
          var stack = stacks.join("\nFrom previous: ");
          if (this._state !== null)
            this._stack = stack;
          return stack;
        } finally {
          stack_being_generated = false;
        }
      }
    },
    timeout: function(ms, msg) {
      return ms < Infinity ? new DexiePromise((resolve, reject) => {
        var handle = setTimeout(() => reject(new exceptions.Timeout(msg)), ms);
        this.then(resolve, reject).finally(clearTimeout.bind(null, handle));
      }) : this;
    }
  });
  if (typeof Symbol !== "undefined" && Symbol.toStringTag)
    setProp(DexiePromise.prototype, Symbol.toStringTag, "Dexie.Promise");
  globalPSD.env = snapShot();
  function Listener(onFulfilled, onRejected, resolve, reject, zone) {
    this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null;
    this.onRejected = typeof onRejected === "function" ? onRejected : null;
    this.resolve = resolve;
    this.reject = reject;
    this.psd = zone;
  }
  props(DexiePromise, {
    all: function() {
      var values = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync);
      return new DexiePromise(function(resolve, reject) {
        if (values.length === 0)
          resolve([]);
        var remaining = values.length;
        values.forEach((a, i) => DexiePromise.resolve(a).then((x) => {
          values[i] = x;
          if (!--remaining)
            resolve(values);
        }, reject));
      });
    },
    resolve: (value) => {
      if (value instanceof DexiePromise)
        return value;
      if (value && typeof value.then === "function")
        return new DexiePromise((resolve, reject) => {
          value.then(resolve, reject);
        });
      var rv = new DexiePromise(INTERNAL, true, value);
      linkToPreviousPromise(rv, currentFulfiller);
      return rv;
    },
    reject: PromiseReject,
    race: function() {
      var values = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync);
      return new DexiePromise((resolve, reject) => {
        values.map((value) => DexiePromise.resolve(value).then(resolve, reject));
      });
    },
    PSD: {
      get: () => PSD,
      set: (value) => PSD = value
    },
    totalEchoes: { get: () => totalEchoes },
    newPSD: newScope,
    usePSD,
    scheduler: {
      get: () => asap,
      set: (value) => {
        asap = value;
      }
    },
    rejectionMapper: {
      get: () => rejectionMapper,
      set: (value) => {
        rejectionMapper = value;
      }
    },
    follow: (fn, zoneProps) => {
      return new DexiePromise((resolve, reject) => {
        return newScope((resolve2, reject2) => {
          var psd = PSD;
          psd.unhandleds = [];
          psd.onunhandled = reject2;
          psd.finalize = callBoth(function() {
            run_at_end_of_this_or_next_physical_tick(() => {
              this.unhandleds.length === 0 ? resolve2() : reject2(this.unhandleds[0]);
            });
          }, psd.finalize);
          fn();
        }, zoneProps, resolve, reject);
      });
    }
  });
  if (NativePromise) {
    if (NativePromise.allSettled)
      setProp(DexiePromise, "allSettled", function() {
        const possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync);
        return new DexiePromise((resolve) => {
          if (possiblePromises.length === 0)
            resolve([]);
          let remaining = possiblePromises.length;
          const results = new Array(remaining);
          possiblePromises.forEach((p, i) => DexiePromise.resolve(p).then((value) => results[i] = { status: "fulfilled", value }, (reason) => results[i] = { status: "rejected", reason }).then(() => --remaining || resolve(results)));
        });
      });
    if (NativePromise.any && typeof AggregateError !== "undefined")
      setProp(DexiePromise, "any", function() {
        const possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync);
        return new DexiePromise((resolve, reject) => {
          if (possiblePromises.length === 0)
            reject(new AggregateError([]));
          let remaining = possiblePromises.length;
          const failures = new Array(remaining);
          possiblePromises.forEach((p, i) => DexiePromise.resolve(p).then((value) => resolve(value), (failure) => {
            failures[i] = failure;
            if (!--remaining)
              reject(new AggregateError(failures));
          }));
        });
      });
  }
  function executePromiseTask(promise, fn) {
    try {
      fn((value) => {
        if (promise._state !== null)
          return;
        if (value === promise)
          throw new TypeError("A promise cannot be resolved with itself.");
        var shouldExecuteTick = promise._lib && beginMicroTickScope();
        if (value && typeof value.then === "function") {
          executePromiseTask(promise, (resolve, reject) => {
            value instanceof DexiePromise ? value._then(resolve, reject) : value.then(resolve, reject);
          });
        } else {
          promise._state = true;
          promise._value = value;
          propagateAllListeners(promise);
        }
        if (shouldExecuteTick)
          endMicroTickScope();
      }, handleRejection.bind(null, promise));
    } catch (ex) {
      handleRejection(promise, ex);
    }
  }
  function handleRejection(promise, reason) {
    rejectingErrors.push(reason);
    if (promise._state !== null)
      return;
    var shouldExecuteTick = promise._lib && beginMicroTickScope();
    reason = rejectionMapper(reason);
    promise._state = false;
    promise._value = reason;
    debug && reason !== null && typeof reason === "object" && !reason._promise && tryCatch(() => {
      var origProp = getPropertyDescriptor(reason, "stack");
      reason._promise = promise;
      setProp(reason, "stack", {
        get: () => stack_being_generated ? origProp && (origProp.get ? origProp.get.apply(reason) : origProp.value) : promise.stack
      });
    });
    addPossiblyUnhandledError(promise);
    propagateAllListeners(promise);
    if (shouldExecuteTick)
      endMicroTickScope();
  }
  function propagateAllListeners(promise) {
    var listeners = promise._listeners;
    promise._listeners = [];
    for (var i = 0, len = listeners.length; i < len; ++i) {
      propagateToListener(promise, listeners[i]);
    }
    var psd = promise._PSD;
    --psd.ref || psd.finalize();
    if (numScheduledCalls === 0) {
      ++numScheduledCalls;
      asap(() => {
        if (--numScheduledCalls === 0)
          finalizePhysicalTick();
      }, []);
    }
  }
  function propagateToListener(promise, listener) {
    if (promise._state === null) {
      promise._listeners.push(listener);
      return;
    }
    var cb = promise._state ? listener.onFulfilled : listener.onRejected;
    if (cb === null) {
      return (promise._state ? listener.resolve : listener.reject)(promise._value);
    }
    ++listener.psd.ref;
    ++numScheduledCalls;
    asap(callListener, [cb, promise, listener]);
  }
  function callListener(cb, promise, listener) {
    try {
      currentFulfiller = promise;
      var ret, value = promise._value;
      if (promise._state) {
        ret = cb(value);
      } else {
        if (rejectingErrors.length)
          rejectingErrors = [];
        ret = cb(value);
        if (rejectingErrors.indexOf(value) === -1)
          markErrorAsHandled(promise);
      }
      listener.resolve(ret);
    } catch (e) {
      listener.reject(e);
    } finally {
      currentFulfiller = null;
      if (--numScheduledCalls === 0)
        finalizePhysicalTick();
      --listener.psd.ref || listener.psd.finalize();
    }
  }
  function getStack(promise, stacks, limit) {
    if (stacks.length === limit)
      return stacks;
    var stack = "";
    if (promise._state === false) {
      var failure = promise._value, errorName, message;
      if (failure != null) {
        errorName = failure.name || "Error";
        message = failure.message || failure;
        stack = prettyStack(failure, 0);
      } else {
        errorName = failure;
        message = "";
      }
      stacks.push(errorName + (message ? ": " + message : "") + stack);
    }
    if (debug) {
      stack = prettyStack(promise._stackHolder, 2);
      if (stack && stacks.indexOf(stack) === -1)
        stacks.push(stack);
      if (promise._prev)
        getStack(promise._prev, stacks, limit);
    }
    return stacks;
  }
  function linkToPreviousPromise(promise, prev) {
    var numPrev = prev ? prev._numPrev + 1 : 0;
    if (numPrev < LONG_STACKS_CLIP_LIMIT) {
      promise._prev = prev;
      promise._numPrev = numPrev;
    }
  }
  function physicalTick() {
    beginMicroTickScope() && endMicroTickScope();
  }
  function beginMicroTickScope() {
    var wasRootExec = isOutsideMicroTick;
    isOutsideMicroTick = false;
    needsNewPhysicalTick = false;
    return wasRootExec;
  }
  function endMicroTickScope() {
    var callbacks, i, l;
    do {
      while (microtickQueue.length > 0) {
        callbacks = microtickQueue;
        microtickQueue = [];
        l = callbacks.length;
        for (i = 0; i < l; ++i) {
          var item = callbacks[i];
          item[0].apply(null, item[1]);
        }
      }
    } while (microtickQueue.length > 0);
    isOutsideMicroTick = true;
    needsNewPhysicalTick = true;
  }
  function finalizePhysicalTick() {
    var unhandledErrs = unhandledErrors;
    unhandledErrors = [];
    unhandledErrs.forEach((p) => {
      p._PSD.onunhandled.call(null, p._value, p);
    });
    var finalizers = tickFinalizers.slice(0);
    var i = finalizers.length;
    while (i)
      finalizers[--i]();
  }
  function run_at_end_of_this_or_next_physical_tick(fn) {
    function finalizer() {
      fn();
      tickFinalizers.splice(tickFinalizers.indexOf(finalizer), 1);
    }
    tickFinalizers.push(finalizer);
    ++numScheduledCalls;
    asap(() => {
      if (--numScheduledCalls === 0)
        finalizePhysicalTick();
    }, []);
  }
  function addPossiblyUnhandledError(promise) {
    if (!unhandledErrors.some((p) => p._value === promise._value))
      unhandledErrors.push(promise);
  }
  function markErrorAsHandled(promise) {
    var i = unhandledErrors.length;
    while (i)
      if (unhandledErrors[--i]._value === promise._value) {
        unhandledErrors.splice(i, 1);
        return;
      }
  }
  function PromiseReject(reason) {
    return new DexiePromise(INTERNAL, false, reason);
  }
  function wrap(fn, errorCatcher) {
    var psd = PSD;
    return function() {
      var wasRootExec = beginMicroTickScope(), outerScope = PSD;
      try {
        switchToZone(psd, true);
        return fn.apply(this, arguments);
      } catch (e) {
        errorCatcher && errorCatcher(e);
      } finally {
        switchToZone(outerScope, false);
        if (wasRootExec)
          endMicroTickScope();
      }
    };
  }
  var task = { awaits: 0, echoes: 0, id: 0 };
  var taskCounter = 0;
  var zoneStack = [];
  var zoneEchoes = 0;
  var totalEchoes = 0;
  var zone_id_counter = 0;
  function newScope(fn, props2, a1, a2) {
    var parent = PSD, psd = Object.create(parent);
    psd.parent = parent;
    psd.ref = 0;
    psd.global = false;
    psd.id = ++zone_id_counter;
    var globalEnv = globalPSD.env;
    psd.env = patchGlobalPromise ? {
      Promise: DexiePromise,
      PromiseProp: { value: DexiePromise, configurable: true, writable: true },
      all: DexiePromise.all,
      race: DexiePromise.race,
      allSettled: DexiePromise.allSettled,
      any: DexiePromise.any,
      resolve: DexiePromise.resolve,
      reject: DexiePromise.reject,
      nthen: getPatchedPromiseThen(globalEnv.nthen, psd),
      gthen: getPatchedPromiseThen(globalEnv.gthen, psd)
    } : {};
    if (props2)
      extend(psd, props2);
    ++parent.ref;
    psd.finalize = function() {
      --this.parent.ref || this.parent.finalize();
    };
    var rv = usePSD(psd, fn, a1, a2);
    if (psd.ref === 0)
      psd.finalize();
    return rv;
  }
  function incrementExpectedAwaits() {
    if (!task.id)
      task.id = ++taskCounter;
    ++task.awaits;
    task.echoes += ZONE_ECHO_LIMIT;
    return task.id;
  }
  function decrementExpectedAwaits() {
    if (!task.awaits)
      return false;
    if (--task.awaits === 0)
      task.id = 0;
    task.echoes = task.awaits * ZONE_ECHO_LIMIT;
    return true;
  }
  if (("" + nativePromiseThen).indexOf("[native code]") === -1) {
    incrementExpectedAwaits = decrementExpectedAwaits = nop;
  }
  function onPossibleParallellAsync(possiblePromise) {
    if (task.echoes && possiblePromise && possiblePromise.constructor === NativePromise) {
      incrementExpectedAwaits();
      return possiblePromise.then((x) => {
        decrementExpectedAwaits();
        return x;
      }, (e) => {
        decrementExpectedAwaits();
        return rejection(e);
      });
    }
    return possiblePromise;
  }
  function zoneEnterEcho(targetZone) {
    ++totalEchoes;
    if (!task.echoes || --task.echoes === 0) {
      task.echoes = task.id = 0;
    }
    zoneStack.push(PSD);
    switchToZone(targetZone, true);
  }
  function zoneLeaveEcho() {
    var zone = zoneStack[zoneStack.length - 1];
    zoneStack.pop();
    switchToZone(zone, false);
  }
  function switchToZone(targetZone, bEnteringZone) {
    var currentZone = PSD;
    if (bEnteringZone ? task.echoes && (!zoneEchoes++ || targetZone !== PSD) : zoneEchoes && (!--zoneEchoes || targetZone !== PSD)) {
      enqueueNativeMicroTask(bEnteringZone ? zoneEnterEcho.bind(null, targetZone) : zoneLeaveEcho);
    }
    if (targetZone === PSD)
      return;
    PSD = targetZone;
    if (currentZone === globalPSD)
      globalPSD.env = snapShot();
    if (patchGlobalPromise) {
      var GlobalPromise = globalPSD.env.Promise;
      var targetEnv = targetZone.env;
      nativePromiseProto.then = targetEnv.nthen;
      GlobalPromise.prototype.then = targetEnv.gthen;
      if (currentZone.global || targetZone.global) {
        Object.defineProperty(_global, "Promise", targetEnv.PromiseProp);
        GlobalPromise.all = targetEnv.all;
        GlobalPromise.race = targetEnv.race;
        GlobalPromise.resolve = targetEnv.resolve;
        GlobalPromise.reject = targetEnv.reject;
        if (targetEnv.allSettled)
          GlobalPromise.allSettled = targetEnv.allSettled;
        if (targetEnv.any)
          GlobalPromise.any = targetEnv.any;
      }
    }
  }
  function snapShot() {
    var GlobalPromise = _global.Promise;
    return patchGlobalPromise ? {
      Promise: GlobalPromise,
      PromiseProp: Object.getOwnPropertyDescriptor(_global, "Promise"),
      all: GlobalPromise.all,
      race: GlobalPromise.race,
      allSettled: GlobalPromise.allSettled,
      any: GlobalPromise.any,
      resolve: GlobalPromise.resolve,
      reject: GlobalPromise.reject,
      nthen: nativePromiseProto.then,
      gthen: GlobalPromise.prototype.then
    } : {};
  }
  function usePSD(psd, fn, a1, a2, a3) {
    var outerScope = PSD;
    try {
      switchToZone(psd, true);
      return fn(a1, a2, a3);
    } finally {
      switchToZone(outerScope, false);
    }
  }
  function enqueueNativeMicroTask(job) {
    nativePromiseThen.call(resolvedNativePromise, job);
  }
  function nativeAwaitCompatibleWrap(fn, zone, possibleAwait, cleanup) {
    return typeof fn !== "function" ? fn : function() {
      var outerZone = PSD;
      if (possibleAwait)
        incrementExpectedAwaits();
      switchToZone(zone, true);
      try {
        return fn.apply(this, arguments);
      } finally {
        switchToZone(outerZone, false);
        if (cleanup)
          enqueueNativeMicroTask(decrementExpectedAwaits);
      }
    };
  }
  function getPatchedPromiseThen(origThen, zone) {
    return function(onResolved, onRejected) {
      return origThen.call(this, nativeAwaitCompatibleWrap(onResolved, zone), nativeAwaitCompatibleWrap(onRejected, zone));
    };
  }
  var UNHANDLEDREJECTION = "unhandledrejection";
  function globalError(err, promise) {
    var rv;
    try {
      rv = promise.onuncatched(err);
    } catch (e) {
    }
    if (rv !== false)
      try {
        var event, eventData = { promise, reason: err };
        if (_global.document && document.createEvent) {
          event = document.createEvent("Event");
          event.initEvent(UNHANDLEDREJECTION, true, true);
          extend(event, eventData);
        } else if (_global.CustomEvent) {
          event = new CustomEvent(UNHANDLEDREJECTION, { detail: eventData });
          extend(event, eventData);
        }
        if (event && _global.dispatchEvent) {
          dispatchEvent(event);
          if (!_global.PromiseRejectionEvent && _global.onunhandledrejection)
            try {
              _global.onunhandledrejection(event);
            } catch (_) {
            }
        }
        if (debug && event && !event.defaultPrevented) {
          console.warn(`Unhandled rejection: ${err.stack || err}`);
        }
      } catch (e) {
      }
  }
  var rejection = DexiePromise.reject;
  function tempTransaction(db2, mode, storeNames, fn) {
    if (!db2.idbdb || !db2._state.openComplete && (!PSD.letThrough && !db2._vip)) {
      if (db2._state.openComplete) {
        return rejection(new exceptions.DatabaseClosed(db2._state.dbOpenError));
      }
      if (!db2._state.isBeingOpened) {
        if (!db2._options.autoOpen)
          return rejection(new exceptions.DatabaseClosed());
        db2.open().catch(nop);
      }
      return db2._state.dbReadyPromise.then(() => tempTransaction(db2, mode, storeNames, fn));
    } else {
      var trans = db2._createTransaction(mode, storeNames, db2._dbSchema);
      try {
        trans.create();
        db2._state.PR1398_maxLoop = 3;
      } catch (ex) {
        if (ex.name === errnames.InvalidState && db2.isOpen() && --db2._state.PR1398_maxLoop > 0) {
          console.warn("Dexie: Need to reopen db");
          db2._close();
          return db2.open().then(() => tempTransaction(db2, mode, storeNames, fn));
        }
        return rejection(ex);
      }
      return trans._promise(mode, (resolve, reject) => {
        return newScope(() => {
          PSD.trans = trans;
          return fn(resolve, reject, trans);
        });
      }).then((result) => {
        return trans._completion.then(() => result);
      });
    }
  }
  var DEXIE_VERSION = "3.2.7";
  var maxString = String.fromCharCode(65535);
  var minKey = -Infinity;
  var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
  var STRING_EXPECTED = "String expected.";
  var connections = [];
  var isIEOrEdge = typeof navigator !== "undefined" && /(MSIE|Trident|Edge)/.test(navigator.userAgent);
  var hasIEDeleteObjectStoreBug = isIEOrEdge;
  var hangsOnDeleteLargeKeyRange = isIEOrEdge;
  var dexieStackFrameFilter = (frame) => !/(dexie\.js|dexie\.min\.js)/.test(frame);
  var DBNAMES_DB = "__dbnames";
  var READONLY = "readonly";
  var READWRITE = "readwrite";
  function combine(filter1, filter2) {
    return filter1 ? filter2 ? function() {
      return filter1.apply(this, arguments) && filter2.apply(this, arguments);
    } : filter1 : filter2;
  }
  var AnyRange = {
    type: 3,
    lower: -Infinity,
    lowerOpen: false,
    upper: [[]],
    upperOpen: false
  };
  function workaroundForUndefinedPrimKey(keyPath) {
    return typeof keyPath === "string" && !/\./.test(keyPath) ? (obj) => {
      if (obj[keyPath] === void 0 && keyPath in obj) {
        obj = deepClone(obj);
        delete obj[keyPath];
      }
      return obj;
    } : (obj) => obj;
  }
  var Table = class {
    _trans(mode, fn, writeLocked) {
      const trans = this._tx || PSD.trans;
      const tableName = this.name;
      function checkTableInTransaction(resolve, reject, trans2) {
        if (!trans2.schema[tableName])
          throw new exceptions.NotFound("Table " + tableName + " not part of transaction");
        return fn(trans2.idbtrans, trans2);
      }
      const wasRootExec = beginMicroTickScope();
      try {
        return trans && trans.db === this.db ? trans === PSD.trans ? trans._promise(mode, checkTableInTransaction, writeLocked) : newScope(() => trans._promise(mode, checkTableInTransaction, writeLocked), { trans, transless: PSD.transless || PSD }) : tempTransaction(this.db, mode, [this.name], checkTableInTransaction);
      } finally {
        if (wasRootExec)
          endMicroTickScope();
      }
    }
    get(keyOrCrit, cb) {
      if (keyOrCrit && keyOrCrit.constructor === Object)
        return this.where(keyOrCrit).first(cb);
      return this._trans("readonly", (trans) => {
        return this.core.get({ trans, key: keyOrCrit }).then((res) => this.hook.reading.fire(res));
      }).then(cb);
    }
    where(indexOrCrit) {
      if (typeof indexOrCrit === "string")
        return new this.db.WhereClause(this, indexOrCrit);
      if (isArray2(indexOrCrit))
        return new this.db.WhereClause(this, `[${indexOrCrit.join("+")}]`);
      const keyPaths = keys(indexOrCrit);
      if (keyPaths.length === 1)
        return this.where(keyPaths[0]).equals(indexOrCrit[keyPaths[0]]);
      const compoundIndex = this.schema.indexes.concat(this.schema.primKey).filter((ix) => {
        if (ix.compound && keyPaths.every((keyPath) => ix.keyPath.indexOf(keyPath) >= 0)) {
          for (let i = 0; i < keyPaths.length; ++i) {
            if (keyPaths.indexOf(ix.keyPath[i]) === -1)
              return false;
          }
          return true;
        }
        return false;
      }).sort((a, b) => a.keyPath.length - b.keyPath.length)[0];
      if (compoundIndex && this.db._maxKey !== maxString) {
        const keyPathsInValidOrder = compoundIndex.keyPath.slice(0, keyPaths.length);
        return this.where(keyPathsInValidOrder).equals(keyPathsInValidOrder.map((kp) => indexOrCrit[kp]));
      }
      if (!compoundIndex && debug)
        console.warn(`The query ${JSON.stringify(indexOrCrit)} on ${this.name} would benefit of a compound index [${keyPaths.join("+")}]`);
      const { idxByName } = this.schema;
      const idb = this.db._deps.indexedDB;
      function equals(a, b) {
        try {
          return idb.cmp(a, b) === 0;
        } catch (e) {
          return false;
        }
      }
      const [idx, filterFunction] = keyPaths.reduce(([prevIndex, prevFilterFn], keyPath) => {
        const index = idxByName[keyPath];
        const value = indexOrCrit[keyPath];
        return [
          prevIndex || index,
          prevIndex || !index ? combine(prevFilterFn, index && index.multi ? (x) => {
            const prop = getByKeyPath(x, keyPath);
            return isArray2(prop) && prop.some((item) => equals(value, item));
          } : (x) => equals(value, getByKeyPath(x, keyPath))) : prevFilterFn
        ];
      }, [null, null]);
      return idx ? this.where(idx.name).equals(indexOrCrit[idx.keyPath]).filter(filterFunction) : compoundIndex ? this.filter(filterFunction) : this.where(keyPaths).equals("");
    }
    filter(filterFunction) {
      return this.toCollection().and(filterFunction);
    }
    count(thenShortcut) {
      return this.toCollection().count(thenShortcut);
    }
    offset(offset) {
      return this.toCollection().offset(offset);
    }
    limit(numRows) {
      return this.toCollection().limit(numRows);
    }
    each(callback) {
      return this.toCollection().each(callback);
    }
    toArray(thenShortcut) {
      return this.toCollection().toArray(thenShortcut);
    }
    toCollection() {
      return new this.db.Collection(new this.db.WhereClause(this));
    }
    orderBy(index) {
      return new this.db.Collection(new this.db.WhereClause(this, isArray2(index) ? `[${index.join("+")}]` : index));
    }
    reverse() {
      return this.toCollection().reverse();
    }
    mapToClass(constructor) {
      this.schema.mappedClass = constructor;
      const readHook = (obj) => {
        if (!obj)
          return obj;
        const res = Object.create(constructor.prototype);
        for (var m in obj)
          if (hasOwn(obj, m))
            try {
              res[m] = obj[m];
            } catch (_) {
            }
        return res;
      };
      if (this.schema.readHook) {
        this.hook.reading.unsubscribe(this.schema.readHook);
      }
      this.schema.readHook = readHook;
      this.hook("reading", readHook);
      return constructor;
    }
    defineClass() {
      function Class(content) {
        extend(this, content);
      }
      return this.mapToClass(Class);
    }
    add(obj, key) {
      const { auto, keyPath } = this.schema.primKey;
      let objToAdd = obj;
      if (keyPath && auto) {
        objToAdd = workaroundForUndefinedPrimKey(keyPath)(obj);
      }
      return this._trans("readwrite", (trans) => {
        return this.core.mutate({ trans, type: "add", keys: key != null ? [key] : null, values: [objToAdd] });
      }).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult).then((lastResult) => {
        if (keyPath) {
          try {
            setByKeyPath(obj, keyPath, lastResult);
          } catch (_) {
          }
        }
        return lastResult;
      });
    }
    update(keyOrObject, modifications) {
      if (typeof keyOrObject === "object" && !isArray2(keyOrObject)) {
        const key = getByKeyPath(keyOrObject, this.schema.primKey.keyPath);
        if (key === void 0)
          return rejection(new exceptions.InvalidArgument("Given object does not contain its primary key"));
        try {
          if (typeof modifications !== "function") {
            keys(modifications).forEach((keyPath) => {
              setByKeyPath(keyOrObject, keyPath, modifications[keyPath]);
            });
          } else {
            modifications(keyOrObject, { value: keyOrObject, primKey: key });
          }
        } catch (_a) {
        }
        return this.where(":id").equals(key).modify(modifications);
      } else {
        return this.where(":id").equals(keyOrObject).modify(modifications);
      }
    }
    put(obj, key) {
      const { auto, keyPath } = this.schema.primKey;
      let objToAdd = obj;
      if (keyPath && auto) {
        objToAdd = workaroundForUndefinedPrimKey(keyPath)(obj);
      }
      return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "put", values: [objToAdd], keys: key != null ? [key] : null })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult).then((lastResult) => {
        if (keyPath) {
          try {
            setByKeyPath(obj, keyPath, lastResult);
          } catch (_) {
          }
        }
        return lastResult;
      });
    }
    delete(key) {
      return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "delete", keys: [key] })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : void 0);
    }
    clear() {
      return this._trans("readwrite", (trans) => this.core.mutate({ trans, type: "deleteRange", range: AnyRange })).then((res) => res.numFailures ? DexiePromise.reject(res.failures[0]) : void 0);
    }
    bulkGet(keys2) {
      return this._trans("readonly", (trans) => {
        return this.core.getMany({
          keys: keys2,
          trans
        }).then((result) => result.map((res) => this.hook.reading.fire(res)));
      });
    }
    bulkAdd(objects, keysOrOptions, options) {
      const keys2 = Array.isArray(keysOrOptions) ? keysOrOptions : void 0;
      options = options || (keys2 ? void 0 : keysOrOptions);
      const wantResults = options ? options.allKeys : void 0;
      return this._trans("readwrite", (trans) => {
        const { auto, keyPath } = this.schema.primKey;
        if (keyPath && keys2)
          throw new exceptions.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");
        if (keys2 && keys2.length !== objects.length)
          throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length");
        const numObjects = objects.length;
        let objectsToAdd = keyPath && auto ? objects.map(workaroundForUndefinedPrimKey(keyPath)) : objects;
        return this.core.mutate({ trans, type: "add", keys: keys2, values: objectsToAdd, wantResults }).then(({ numFailures, results, lastResult, failures }) => {
          const result = wantResults ? results : lastResult;
          if (numFailures === 0)
            return result;
          throw new BulkError(`${this.name}.bulkAdd(): ${numFailures} of ${numObjects} operations failed`, failures);
        });
      });
    }
    bulkPut(objects, keysOrOptions, options) {
      const keys2 = Array.isArray(keysOrOptions) ? keysOrOptions : void 0;
      options = options || (keys2 ? void 0 : keysOrOptions);
      const wantResults = options ? options.allKeys : void 0;
      return this._trans("readwrite", (trans) => {
        const { auto, keyPath } = this.schema.primKey;
        if (keyPath && keys2)
          throw new exceptions.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");
        if (keys2 && keys2.length !== objects.length)
          throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length");
        const numObjects = objects.length;
        let objectsToPut = keyPath && auto ? objects.map(workaroundForUndefinedPrimKey(keyPath)) : objects;
        return this.core.mutate({ trans, type: "put", keys: keys2, values: objectsToPut, wantResults }).then(({ numFailures, results, lastResult, failures }) => {
          const result = wantResults ? results : lastResult;
          if (numFailures === 0)
            return result;
          throw new BulkError(`${this.name}.bulkPut(): ${numFailures} of ${numObjects} operations failed`, failures);
        });
      });
    }
    bulkDelete(keys2) {
      const numKeys = keys2.length;
      return this._trans("readwrite", (trans) => {
        return this.core.mutate({ trans, type: "delete", keys: keys2 });
      }).then(({ numFailures, lastResult, failures }) => {
        if (numFailures === 0)
          return lastResult;
        throw new BulkError(`${this.name}.bulkDelete(): ${numFailures} of ${numKeys} operations failed`, failures);
      });
    }
  };
  function Events(ctx) {
    var evs = {};
    var rv = function(eventName, subscriber) {
      if (subscriber) {
        var i2 = arguments.length, args = new Array(i2 - 1);
        while (--i2)
          args[i2 - 1] = arguments[i2];
        evs[eventName].subscribe.apply(null, args);
        return ctx;
      } else if (typeof eventName === "string") {
        return evs[eventName];
      }
    };
    rv.addEventType = add;
    for (var i = 1, l = arguments.length; i < l; ++i) {
      add(arguments[i]);
    }
    return rv;
    function add(eventName, chainFunction, defaultFunction) {
      if (typeof eventName === "object")
        return addConfiguredEvents(eventName);
      if (!chainFunction)
        chainFunction = reverseStoppableEventChain;
      if (!defaultFunction)
        defaultFunction = nop;
      var context = {
        subscribers: [],
        fire: defaultFunction,
        subscribe: function(cb) {
          if (context.subscribers.indexOf(cb) === -1) {
            context.subscribers.push(cb);
            context.fire = chainFunction(context.fire, cb);
          }
        },
        unsubscribe: function(cb) {
          context.subscribers = context.subscribers.filter(function(fn) {
            return fn !== cb;
          });
          context.fire = context.subscribers.reduce(chainFunction, defaultFunction);
        }
      };
      evs[eventName] = rv[eventName] = context;
      return context;
    }
    function addConfiguredEvents(cfg) {
      keys(cfg).forEach(function(eventName) {
        var args = cfg[eventName];
        if (isArray2(args)) {
          add(eventName, cfg[eventName][0], cfg[eventName][1]);
        } else if (args === "asap") {
          var context = add(eventName, mirror, function fire() {
            var i2 = arguments.length, args2 = new Array(i2);
            while (i2--)
              args2[i2] = arguments[i2];
            context.subscribers.forEach(function(fn) {
              asap$1(function fireEvent() {
                fn.apply(null, args2);
              });
            });
          });
        } else
          throw new exceptions.InvalidArgument("Invalid event config");
      });
    }
  }
  function makeClassConstructor(prototype, constructor) {
    derive(constructor).from({ prototype });
    return constructor;
  }
  function createTableConstructor(db2) {
    return makeClassConstructor(Table.prototype, function Table2(name, tableSchema, trans) {
      this.db = db2;
      this._tx = trans;
      this.name = name;
      this.schema = tableSchema;
      this.hook = db2._allTables[name] ? db2._allTables[name].hook : Events(null, {
        "creating": [hookCreatingChain, nop],
        "reading": [pureFunctionChain, mirror],
        "updating": [hookUpdatingChain, nop],
        "deleting": [hookDeletingChain, nop]
      });
    });
  }
  function isPlainKeyRange(ctx, ignoreLimitFilter) {
    return !(ctx.filter || ctx.algorithm || ctx.or) && (ignoreLimitFilter ? ctx.justLimit : !ctx.replayFilter);
  }
  function addFilter(ctx, fn) {
    ctx.filter = combine(ctx.filter, fn);
  }
  function addReplayFilter(ctx, factory, isLimitFilter) {
    var curr = ctx.replayFilter;
    ctx.replayFilter = curr ? () => combine(curr(), factory()) : factory;
    ctx.justLimit = isLimitFilter && !curr;
  }
  function addMatchFilter(ctx, fn) {
    ctx.isMatch = combine(ctx.isMatch, fn);
  }
  function getIndexOrStore(ctx, coreSchema) {
    if (ctx.isPrimKey)
      return coreSchema.primaryKey;
    const index = coreSchema.getIndexByKeyPath(ctx.index);
    if (!index)
      throw new exceptions.Schema("KeyPath " + ctx.index + " on object store " + coreSchema.name + " is not indexed");
    return index;
  }
  function openCursor(ctx, coreTable, trans) {
    const index = getIndexOrStore(ctx, coreTable.schema);
    return coreTable.openCursor({
      trans,
      values: !ctx.keysOnly,
      reverse: ctx.dir === "prev",
      unique: !!ctx.unique,
      query: {
        index,
        range: ctx.range
      }
    });
  }
  function iter(ctx, fn, coreTrans, coreTable) {
    const filter = ctx.replayFilter ? combine(ctx.filter, ctx.replayFilter()) : ctx.filter;
    if (!ctx.or) {
      return iterate(openCursor(ctx, coreTable, coreTrans), combine(ctx.algorithm, filter), fn, !ctx.keysOnly && ctx.valueMapper);
    } else {
      const set = {};
      const union = (item, cursor, advance) => {
        if (!filter || filter(cursor, advance, (result) => cursor.stop(result), (err) => cursor.fail(err))) {
          var primaryKey = cursor.primaryKey;
          var key = "" + primaryKey;
          if (key === "[object ArrayBuffer]")
            key = "" + new Uint8Array(primaryKey);
          if (!hasOwn(set, key)) {
            set[key] = true;
            fn(item, cursor, advance);
          }
        }
      };
      return Promise.all([
        ctx.or._iterate(union, coreTrans),
        iterate(openCursor(ctx, coreTable, coreTrans), ctx.algorithm, union, !ctx.keysOnly && ctx.valueMapper)
      ]);
    }
  }
  function iterate(cursorPromise, filter, fn, valueMapper) {
    var mappedFn = valueMapper ? (x, c, a) => fn(valueMapper(x), c, a) : fn;
    var wrappedFn = wrap(mappedFn);
    return cursorPromise.then((cursor) => {
      if (cursor) {
        return cursor.start(() => {
          var c = () => cursor.continue();
          if (!filter || filter(cursor, (advancer) => c = advancer, (val) => {
            cursor.stop(val);
            c = nop;
          }, (e) => {
            cursor.fail(e);
            c = nop;
          }))
            wrappedFn(cursor.value, cursor, (advancer) => c = advancer);
          c();
        });
      }
    });
  }
  function cmp(a, b) {
    try {
      const ta = type(a);
      const tb = type(b);
      if (ta !== tb) {
        if (ta === "Array")
          return 1;
        if (tb === "Array")
          return -1;
        if (ta === "binary")
          return 1;
        if (tb === "binary")
          return -1;
        if (ta === "string")
          return 1;
        if (tb === "string")
          return -1;
        if (ta === "Date")
          return 1;
        if (tb !== "Date")
          return NaN;
        return -1;
      }
      switch (ta) {
        case "number":
        case "Date":
        case "string":
          return a > b ? 1 : a < b ? -1 : 0;
        case "binary": {
          return compareUint8Arrays(getUint8Array(a), getUint8Array(b));
        }
        case "Array":
          return compareArrays(a, b);
      }
    } catch (_a) {
    }
    return NaN;
  }
  function compareArrays(a, b) {
    const al = a.length;
    const bl = b.length;
    const l = al < bl ? al : bl;
    for (let i = 0; i < l; ++i) {
      const res = cmp(a[i], b[i]);
      if (res !== 0)
        return res;
    }
    return al === bl ? 0 : al < bl ? -1 : 1;
  }
  function compareUint8Arrays(a, b) {
    const al = a.length;
    const bl = b.length;
    const l = al < bl ? al : bl;
    for (let i = 0; i < l; ++i) {
      if (a[i] !== b[i])
        return a[i] < b[i] ? -1 : 1;
    }
    return al === bl ? 0 : al < bl ? -1 : 1;
  }
  function type(x) {
    const t = typeof x;
    if (t !== "object")
      return t;
    if (ArrayBuffer.isView(x))
      return "binary";
    const tsTag = toStringTag(x);
    return tsTag === "ArrayBuffer" ? "binary" : tsTag;
  }
  function getUint8Array(a) {
    if (a instanceof Uint8Array)
      return a;
    if (ArrayBuffer.isView(a))
      return new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
    return new Uint8Array(a);
  }
  var Collection = class {
    _read(fn, cb) {
      var ctx = this._ctx;
      return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans("readonly", fn).then(cb);
    }
    _write(fn) {
      var ctx = this._ctx;
      return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans("readwrite", fn, "locked");
    }
    _addAlgorithm(fn) {
      var ctx = this._ctx;
      ctx.algorithm = combine(ctx.algorithm, fn);
    }
    _iterate(fn, coreTrans) {
      return iter(this._ctx, fn, coreTrans, this._ctx.table.core);
    }
    clone(props2) {
      var rv = Object.create(this.constructor.prototype), ctx = Object.create(this._ctx);
      if (props2)
        extend(ctx, props2);
      rv._ctx = ctx;
      return rv;
    }
    raw() {
      this._ctx.valueMapper = null;
      return this;
    }
    each(fn) {
      var ctx = this._ctx;
      return this._read((trans) => iter(ctx, fn, trans, ctx.table.core));
    }
    count(cb) {
      return this._read((trans) => {
        const ctx = this._ctx;
        const coreTable = ctx.table.core;
        if (isPlainKeyRange(ctx, true)) {
          return coreTable.count({
            trans,
            query: {
              index: getIndexOrStore(ctx, coreTable.schema),
              range: ctx.range
            }
          }).then((count2) => Math.min(count2, ctx.limit));
        } else {
          var count = 0;
          return iter(ctx, () => {
            ++count;
            return false;
          }, trans, coreTable).then(() => count);
        }
      }).then(cb);
    }
    sortBy(keyPath, cb) {
      const parts = keyPath.split(".").reverse(), lastPart = parts[0], lastIndex = parts.length - 1;
      function getval(obj, i) {
        if (i)
          return getval(obj[parts[i]], i - 1);
        return obj[lastPart];
      }
      var order = this._ctx.dir === "next" ? 1 : -1;
      function sorter(a, b) {
        var aVal = getval(a, lastIndex), bVal = getval(b, lastIndex);
        return aVal < bVal ? -order : aVal > bVal ? order : 0;
      }
      return this.toArray(function(a) {
        return a.sort(sorter);
      }).then(cb);
    }
    toArray(cb) {
      return this._read((trans) => {
        var ctx = this._ctx;
        if (ctx.dir === "next" && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
          const { valueMapper } = ctx;
          const index = getIndexOrStore(ctx, ctx.table.core.schema);
          return ctx.table.core.query({
            trans,
            limit: ctx.limit,
            values: true,
            query: {
              index,
              range: ctx.range
            }
          }).then(({ result }) => valueMapper ? result.map(valueMapper) : result);
        } else {
          const a = [];
          return iter(ctx, (item) => a.push(item), trans, ctx.table.core).then(() => a);
        }
      }, cb);
    }
    offset(offset) {
      var ctx = this._ctx;
      if (offset <= 0)
        return this;
      ctx.offset += offset;
      if (isPlainKeyRange(ctx)) {
        addReplayFilter(ctx, () => {
          var offsetLeft = offset;
          return (cursor, advance) => {
            if (offsetLeft === 0)
              return true;
            if (offsetLeft === 1) {
              --offsetLeft;
              return false;
            }
            advance(() => {
              cursor.advance(offsetLeft);
              offsetLeft = 0;
            });
            return false;
          };
        });
      } else {
        addReplayFilter(ctx, () => {
          var offsetLeft = offset;
          return () => --offsetLeft < 0;
        });
      }
      return this;
    }
    limit(numRows) {
      this._ctx.limit = Math.min(this._ctx.limit, numRows);
      addReplayFilter(this._ctx, () => {
        var rowsLeft = numRows;
        return function(cursor, advance, resolve) {
          if (--rowsLeft <= 0)
            advance(resolve);
          return rowsLeft >= 0;
        };
      }, true);
      return this;
    }
    until(filterFunction, bIncludeStopEntry) {
      addFilter(this._ctx, function(cursor, advance, resolve) {
        if (filterFunction(cursor.value)) {
          advance(resolve);
          return bIncludeStopEntry;
        } else {
          return true;
        }
      });
      return this;
    }
    first(cb) {
      return this.limit(1).toArray(function(a) {
        return a[0];
      }).then(cb);
    }
    last(cb) {
      return this.reverse().first(cb);
    }
    filter(filterFunction) {
      addFilter(this._ctx, function(cursor) {
        return filterFunction(cursor.value);
      });
      addMatchFilter(this._ctx, filterFunction);
      return this;
    }
    and(filter) {
      return this.filter(filter);
    }
    or(indexName) {
      return new this.db.WhereClause(this._ctx.table, indexName, this);
    }
    reverse() {
      this._ctx.dir = this._ctx.dir === "prev" ? "next" : "prev";
      if (this._ondirectionchange)
        this._ondirectionchange(this._ctx.dir);
      return this;
    }
    desc() {
      return this.reverse();
    }
    eachKey(cb) {
      var ctx = this._ctx;
      ctx.keysOnly = !ctx.isMatch;
      return this.each(function(val, cursor) {
        cb(cursor.key, cursor);
      });
    }
    eachUniqueKey(cb) {
      this._ctx.unique = "unique";
      return this.eachKey(cb);
    }
    eachPrimaryKey(cb) {
      var ctx = this._ctx;
      ctx.keysOnly = !ctx.isMatch;
      return this.each(function(val, cursor) {
        cb(cursor.primaryKey, cursor);
      });
    }
    keys(cb) {
      var ctx = this._ctx;
      ctx.keysOnly = !ctx.isMatch;
      var a = [];
      return this.each(function(item, cursor) {
        a.push(cursor.key);
      }).then(function() {
        return a;
      }).then(cb);
    }
    primaryKeys(cb) {
      var ctx = this._ctx;
      if (ctx.dir === "next" && isPlainKeyRange(ctx, true) && ctx.limit > 0) {
        return this._read((trans) => {
          var index = getIndexOrStore(ctx, ctx.table.core.schema);
          return ctx.table.core.query({
            trans,
            values: false,
            limit: ctx.limit,
            query: {
              index,
              range: ctx.range
            }
          });
        }).then(({ result }) => result).then(cb);
      }
      ctx.keysOnly = !ctx.isMatch;
      var a = [];
      return this.each(function(item, cursor) {
        a.push(cursor.primaryKey);
      }).then(function() {
        return a;
      }).then(cb);
    }
    uniqueKeys(cb) {
      this._ctx.unique = "unique";
      return this.keys(cb);
    }
    firstKey(cb) {
      return this.limit(1).keys(function(a) {
        return a[0];
      }).then(cb);
    }
    lastKey(cb) {
      return this.reverse().firstKey(cb);
    }
    distinct() {
      var ctx = this._ctx, idx = ctx.index && ctx.table.schema.idxByName[ctx.index];
      if (!idx || !idx.multi)
        return this;
      var set = {};
      addFilter(this._ctx, function(cursor) {
        var strKey = cursor.primaryKey.toString();
        var found = hasOwn(set, strKey);
        set[strKey] = true;
        return !found;
      });
      return this;
    }
    modify(changes) {
      var ctx = this._ctx;
      return this._write((trans) => {
        var modifyer;
        if (typeof changes === "function") {
          modifyer = changes;
        } else {
          var keyPaths = keys(changes);
          var numKeys = keyPaths.length;
          modifyer = function(item) {
            var anythingModified = false;
            for (var i = 0; i < numKeys; ++i) {
              var keyPath = keyPaths[i], val = changes[keyPath];
              if (getByKeyPath(item, keyPath) !== val) {
                setByKeyPath(item, keyPath, val);
                anythingModified = true;
              }
            }
            return anythingModified;
          };
        }
        const coreTable = ctx.table.core;
        const { outbound, extractKey } = coreTable.schema.primaryKey;
        const limit = this.db._options.modifyChunkSize || 200;
        const totalFailures = [];
        let successCount = 0;
        const failedKeys = [];
        const applyMutateResult = (expectedCount, res) => {
          const { failures, numFailures } = res;
          successCount += expectedCount - numFailures;
          for (let pos of keys(failures)) {
            totalFailures.push(failures[pos]);
          }
        };
        return this.clone().primaryKeys().then((keys2) => {
          const nextChunk = (offset) => {
            const count = Math.min(limit, keys2.length - offset);
            return coreTable.getMany({
              trans,
              keys: keys2.slice(offset, offset + count),
              cache: "immutable"
            }).then((values) => {
              const addValues = [];
              const putValues = [];
              const putKeys = outbound ? [] : null;
              const deleteKeys = [];
              for (let i = 0; i < count; ++i) {
                const origValue = values[i];
                const ctx2 = {
                  value: deepClone(origValue),
                  primKey: keys2[offset + i]
                };
                if (modifyer.call(ctx2, ctx2.value, ctx2) !== false) {
                  if (ctx2.value == null) {
                    deleteKeys.push(keys2[offset + i]);
                  } else if (!outbound && cmp(extractKey(origValue), extractKey(ctx2.value)) !== 0) {
                    deleteKeys.push(keys2[offset + i]);
                    addValues.push(ctx2.value);
                  } else {
                    putValues.push(ctx2.value);
                    if (outbound)
                      putKeys.push(keys2[offset + i]);
                  }
                }
              }
              const criteria = isPlainKeyRange(ctx) && ctx.limit === Infinity && (typeof changes !== "function" || changes === deleteCallback) && {
                index: ctx.index,
                range: ctx.range
              };
              return Promise.resolve(addValues.length > 0 && coreTable.mutate({ trans, type: "add", values: addValues }).then((res) => {
                for (let pos in res.failures) {
                  deleteKeys.splice(parseInt(pos), 1);
                }
                applyMutateResult(addValues.length, res);
              })).then(() => (putValues.length > 0 || criteria && typeof changes === "object") && coreTable.mutate({
                trans,
                type: "put",
                keys: putKeys,
                values: putValues,
                criteria,
                changeSpec: typeof changes !== "function" && changes
              }).then((res) => applyMutateResult(putValues.length, res))).then(() => (deleteKeys.length > 0 || criteria && changes === deleteCallback) && coreTable.mutate({
                trans,
                type: "delete",
                keys: deleteKeys,
                criteria
              }).then((res) => applyMutateResult(deleteKeys.length, res))).then(() => {
                return keys2.length > offset + count && nextChunk(offset + limit);
              });
            });
          };
          return nextChunk(0).then(() => {
            if (totalFailures.length > 0)
              throw new ModifyError("Error modifying one or more objects", totalFailures, successCount, failedKeys);
            return keys2.length;
          });
        });
      });
    }
    delete() {
      var ctx = this._ctx, range = ctx.range;
      if (isPlainKeyRange(ctx) && (ctx.isPrimKey && !hangsOnDeleteLargeKeyRange || range.type === 3)) {
        return this._write((trans) => {
          const { primaryKey } = ctx.table.core.schema;
          const coreRange = range;
          return ctx.table.core.count({ trans, query: { index: primaryKey, range: coreRange } }).then((count) => {
            return ctx.table.core.mutate({ trans, type: "deleteRange", range: coreRange }).then(({ failures, lastResult, results, numFailures }) => {
              if (numFailures)
                throw new ModifyError("Could not delete some values", Object.keys(failures).map((pos) => failures[pos]), count - numFailures);
              return count - numFailures;
            });
          });
        });
      }
      return this.modify(deleteCallback);
    }
  };
  var deleteCallback = (value, ctx) => ctx.value = null;
  function createCollectionConstructor(db2) {
    return makeClassConstructor(Collection.prototype, function Collection2(whereClause, keyRangeGenerator) {
      this.db = db2;
      let keyRange = AnyRange, error = null;
      if (keyRangeGenerator)
        try {
          keyRange = keyRangeGenerator();
        } catch (ex) {
          error = ex;
        }
      const whereCtx = whereClause._ctx;
      const table = whereCtx.table;
      const readingHook = table.hook.reading.fire;
      this._ctx = {
        table,
        index: whereCtx.index,
        isPrimKey: !whereCtx.index || table.schema.primKey.keyPath && whereCtx.index === table.schema.primKey.name,
        range: keyRange,
        keysOnly: false,
        dir: "next",
        unique: "",
        algorithm: null,
        filter: null,
        replayFilter: null,
        justLimit: true,
        isMatch: null,
        offset: 0,
        limit: Infinity,
        error,
        or: whereCtx.or,
        valueMapper: readingHook !== mirror ? readingHook : null
      };
    });
  }
  function simpleCompare(a, b) {
    return a < b ? -1 : a === b ? 0 : 1;
  }
  function simpleCompareReverse(a, b) {
    return a > b ? -1 : a === b ? 0 : 1;
  }
  function fail(collectionOrWhereClause, err, T) {
    var collection = collectionOrWhereClause instanceof WhereClause ? new collectionOrWhereClause.Collection(collectionOrWhereClause) : collectionOrWhereClause;
    collection._ctx.error = T ? new T(err) : new TypeError(err);
    return collection;
  }
  function emptyCollection(whereClause) {
    return new whereClause.Collection(whereClause, () => rangeEqual("")).limit(0);
  }
  function upperFactory(dir) {
    return dir === "next" ? (s) => s.toUpperCase() : (s) => s.toLowerCase();
  }
  function lowerFactory(dir) {
    return dir === "next" ? (s) => s.toLowerCase() : (s) => s.toUpperCase();
  }
  function nextCasing(key, lowerKey, upperNeedle, lowerNeedle, cmp2, dir) {
    var length = Math.min(key.length, lowerNeedle.length);
    var llp = -1;
    for (var i = 0; i < length; ++i) {
      var lwrKeyChar = lowerKey[i];
      if (lwrKeyChar !== lowerNeedle[i]) {
        if (cmp2(key[i], upperNeedle[i]) < 0)
          return key.substr(0, i) + upperNeedle[i] + upperNeedle.substr(i + 1);
        if (cmp2(key[i], lowerNeedle[i]) < 0)
          return key.substr(0, i) + lowerNeedle[i] + upperNeedle.substr(i + 1);
        if (llp >= 0)
          return key.substr(0, llp) + lowerKey[llp] + upperNeedle.substr(llp + 1);
        return null;
      }
      if (cmp2(key[i], lwrKeyChar) < 0)
        llp = i;
    }
    if (length < lowerNeedle.length && dir === "next")
      return key + upperNeedle.substr(key.length);
    if (length < key.length && dir === "prev")
      return key.substr(0, upperNeedle.length);
    return llp < 0 ? null : key.substr(0, llp) + lowerNeedle[llp] + upperNeedle.substr(llp + 1);
  }
  function addIgnoreCaseAlgorithm(whereClause, match, needles, suffix) {
    var upper, lower, compare, upperNeedles, lowerNeedles, direction, nextKeySuffix, needlesLen = needles.length;
    if (!needles.every((s) => typeof s === "string")) {
      return fail(whereClause, STRING_EXPECTED);
    }
    function initDirection(dir) {
      upper = upperFactory(dir);
      lower = lowerFactory(dir);
      compare = dir === "next" ? simpleCompare : simpleCompareReverse;
      var needleBounds = needles.map(function(needle) {
        return { lower: lower(needle), upper: upper(needle) };
      }).sort(function(a, b) {
        return compare(a.lower, b.lower);
      });
      upperNeedles = needleBounds.map(function(nb) {
        return nb.upper;
      });
      lowerNeedles = needleBounds.map(function(nb) {
        return nb.lower;
      });
      direction = dir;
      nextKeySuffix = dir === "next" ? "" : suffix;
    }
    initDirection("next");
    var c = new whereClause.Collection(whereClause, () => createRange(upperNeedles[0], lowerNeedles[needlesLen - 1] + suffix));
    c._ondirectionchange = function(direction2) {
      initDirection(direction2);
    };
    var firstPossibleNeedle = 0;
    c._addAlgorithm(function(cursor, advance, resolve) {
      var key = cursor.key;
      if (typeof key !== "string")
        return false;
      var lowerKey = lower(key);
      if (match(lowerKey, lowerNeedles, firstPossibleNeedle)) {
        return true;
      } else {
        var lowestPossibleCasing = null;
        for (var i = firstPossibleNeedle; i < needlesLen; ++i) {
          var casing = nextCasing(key, lowerKey, upperNeedles[i], lowerNeedles[i], compare, direction);
          if (casing === null && lowestPossibleCasing === null)
            firstPossibleNeedle = i + 1;
          else if (lowestPossibleCasing === null || compare(lowestPossibleCasing, casing) > 0) {
            lowestPossibleCasing = casing;
          }
        }
        if (lowestPossibleCasing !== null) {
          advance(function() {
            cursor.continue(lowestPossibleCasing + nextKeySuffix);
          });
        } else {
          advance(resolve);
        }
        return false;
      }
    });
    return c;
  }
  function createRange(lower, upper, lowerOpen, upperOpen) {
    return {
      type: 2,
      lower,
      upper,
      lowerOpen,
      upperOpen
    };
  }
  function rangeEqual(value) {
    return {
      type: 1,
      lower: value,
      upper: value
    };
  }
  var WhereClause = class {
    get Collection() {
      return this._ctx.table.db.Collection;
    }
    between(lower, upper, includeLower, includeUpper) {
      includeLower = includeLower !== false;
      includeUpper = includeUpper === true;
      try {
        if (this._cmp(lower, upper) > 0 || this._cmp(lower, upper) === 0 && (includeLower || includeUpper) && !(includeLower && includeUpper))
          return emptyCollection(this);
        return new this.Collection(this, () => createRange(lower, upper, !includeLower, !includeUpper));
      } catch (e) {
        return fail(this, INVALID_KEY_ARGUMENT);
      }
    }
    equals(value) {
      if (value == null)
        return fail(this, INVALID_KEY_ARGUMENT);
      return new this.Collection(this, () => rangeEqual(value));
    }
    above(value) {
      if (value == null)
        return fail(this, INVALID_KEY_ARGUMENT);
      return new this.Collection(this, () => createRange(value, void 0, true));
    }
    aboveOrEqual(value) {
      if (value == null)
        return fail(this, INVALID_KEY_ARGUMENT);
      return new this.Collection(this, () => createRange(value, void 0, false));
    }
    below(value) {
      if (value == null)
        return fail(this, INVALID_KEY_ARGUMENT);
      return new this.Collection(this, () => createRange(void 0, value, false, true));
    }
    belowOrEqual(value) {
      if (value == null)
        return fail(this, INVALID_KEY_ARGUMENT);
      return new this.Collection(this, () => createRange(void 0, value));
    }
    startsWith(str) {
      if (typeof str !== "string")
        return fail(this, STRING_EXPECTED);
      return this.between(str, str + maxString, true, true);
    }
    startsWithIgnoreCase(str) {
      if (str === "")
        return this.startsWith(str);
      return addIgnoreCaseAlgorithm(this, (x, a) => x.indexOf(a[0]) === 0, [str], maxString);
    }
    equalsIgnoreCase(str) {
      return addIgnoreCaseAlgorithm(this, (x, a) => x === a[0], [str], "");
    }
    anyOfIgnoreCase() {
      var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments);
      if (set.length === 0)
        return emptyCollection(this);
      return addIgnoreCaseAlgorithm(this, (x, a) => a.indexOf(x) !== -1, set, "");
    }
    startsWithAnyOfIgnoreCase() {
      var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments);
      if (set.length === 0)
        return emptyCollection(this);
      return addIgnoreCaseAlgorithm(this, (x, a) => a.some((n) => x.indexOf(n) === 0), set, maxString);
    }
    anyOf() {
      const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments);
      let compare = this._cmp;
      try {
        set.sort(compare);
      } catch (e) {
        return fail(this, INVALID_KEY_ARGUMENT);
      }
      if (set.length === 0)
        return emptyCollection(this);
      const c = new this.Collection(this, () => createRange(set[0], set[set.length - 1]));
      c._ondirectionchange = (direction) => {
        compare = direction === "next" ? this._ascending : this._descending;
        set.sort(compare);
      };
      let i = 0;
      c._addAlgorithm((cursor, advance, resolve) => {
        const key = cursor.key;
        while (compare(key, set[i]) > 0) {
          ++i;
          if (i === set.length) {
            advance(resolve);
            return false;
          }
        }
        if (compare(key, set[i]) === 0) {
          return true;
        } else {
          advance(() => {
            cursor.continue(set[i]);
          });
          return false;
        }
      });
      return c;
    }
    notEqual(value) {
      return this.inAnyRange([[minKey, value], [value, this.db._maxKey]], { includeLowers: false, includeUppers: false });
    }
    noneOf() {
      const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments);
      if (set.length === 0)
        return new this.Collection(this);
      try {
        set.sort(this._ascending);
      } catch (e) {
        return fail(this, INVALID_KEY_ARGUMENT);
      }
      const ranges = set.reduce((res, val) => res ? res.concat([[res[res.length - 1][1], val]]) : [[minKey, val]], null);
      ranges.push([set[set.length - 1], this.db._maxKey]);
      return this.inAnyRange(ranges, { includeLowers: false, includeUppers: false });
    }
    inAnyRange(ranges, options) {
      const cmp2 = this._cmp, ascending = this._ascending, descending = this._descending, min = this._min, max = this._max;
      if (ranges.length === 0)
        return emptyCollection(this);
      if (!ranges.every((range) => range[0] !== void 0 && range[1] !== void 0 && ascending(range[0], range[1]) <= 0)) {
        return fail(this, "First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower", exceptions.InvalidArgument);
      }
      const includeLowers = !options || options.includeLowers !== false;
      const includeUppers = options && options.includeUppers === true;
      function addRange2(ranges2, newRange) {
        let i = 0, l = ranges2.length;
        for (; i < l; ++i) {
          const range = ranges2[i];
          if (cmp2(newRange[0], range[1]) < 0 && cmp2(newRange[1], range[0]) > 0) {
            range[0] = min(range[0], newRange[0]);
            range[1] = max(range[1], newRange[1]);
            break;
          }
        }
        if (i === l)
          ranges2.push(newRange);
        return ranges2;
      }
      let sortDirection = ascending;
      function rangeSorter(a, b) {
        return sortDirection(a[0], b[0]);
      }
      let set;
      try {
        set = ranges.reduce(addRange2, []);
        set.sort(rangeSorter);
      } catch (ex) {
        return fail(this, INVALID_KEY_ARGUMENT);
      }
      let rangePos = 0;
      const keyIsBeyondCurrentEntry = includeUppers ? (key) => ascending(key, set[rangePos][1]) > 0 : (key) => ascending(key, set[rangePos][1]) >= 0;
      const keyIsBeforeCurrentEntry = includeLowers ? (key) => descending(key, set[rangePos][0]) > 0 : (key) => descending(key, set[rangePos][0]) >= 0;
      function keyWithinCurrentRange(key) {
        return !keyIsBeyondCurrentEntry(key) && !keyIsBeforeCurrentEntry(key);
      }
      let checkKey = keyIsBeyondCurrentEntry;
      const c = new this.Collection(this, () => createRange(set[0][0], set[set.length - 1][1], !includeLowers, !includeUppers));
      c._ondirectionchange = (direction) => {
        if (direction === "next") {
          checkKey = keyIsBeyondCurrentEntry;
          sortDirection = ascending;
        } else {
          checkKey = keyIsBeforeCurrentEntry;
          sortDirection = descending;
        }
        set.sort(rangeSorter);
      };
      c._addAlgorithm((cursor, advance, resolve) => {
        var key = cursor.key;
        while (checkKey(key)) {
          ++rangePos;
          if (rangePos === set.length) {
            advance(resolve);
            return false;
          }
        }
        if (keyWithinCurrentRange(key)) {
          return true;
        } else if (this._cmp(key, set[rangePos][1]) === 0 || this._cmp(key, set[rangePos][0]) === 0) {
          return false;
        } else {
          advance(() => {
            if (sortDirection === ascending)
              cursor.continue(set[rangePos][0]);
            else
              cursor.continue(set[rangePos][1]);
          });
          return false;
        }
      });
      return c;
    }
    startsWithAnyOf() {
      const set = getArrayOf.apply(NO_CHAR_ARRAY, arguments);
      if (!set.every((s) => typeof s === "string")) {
        return fail(this, "startsWithAnyOf() only works with strings");
      }
      if (set.length === 0)
        return emptyCollection(this);
      return this.inAnyRange(set.map((str) => [str, str + maxString]));
    }
  };
  function createWhereClauseConstructor(db2) {
    return makeClassConstructor(WhereClause.prototype, function WhereClause2(table, index, orCollection) {
      this.db = db2;
      this._ctx = {
        table,
        index: index === ":id" ? null : index,
        or: orCollection
      };
      const indexedDB2 = db2._deps.indexedDB;
      if (!indexedDB2)
        throw new exceptions.MissingAPI();
      this._cmp = this._ascending = indexedDB2.cmp.bind(indexedDB2);
      this._descending = (a, b) => indexedDB2.cmp(b, a);
      this._max = (a, b) => indexedDB2.cmp(a, b) > 0 ? a : b;
      this._min = (a, b) => indexedDB2.cmp(a, b) < 0 ? a : b;
      this._IDBKeyRange = db2._deps.IDBKeyRange;
    });
  }
  function eventRejectHandler(reject) {
    return wrap(function(event) {
      preventDefault(event);
      reject(event.target.error);
      return false;
    });
  }
  function preventDefault(event) {
    if (event.stopPropagation)
      event.stopPropagation();
    if (event.preventDefault)
      event.preventDefault();
  }
  var DEXIE_STORAGE_MUTATED_EVENT_NAME = "storagemutated";
  var STORAGE_MUTATED_DOM_EVENT_NAME = "x-storagemutated-1";
  var globalEvents = Events(null, DEXIE_STORAGE_MUTATED_EVENT_NAME);
  var Transaction = class {
    _lock() {
      assert(!PSD.global);
      ++this._reculock;
      if (this._reculock === 1 && !PSD.global)
        PSD.lockOwnerFor = this;
      return this;
    }
    _unlock() {
      assert(!PSD.global);
      if (--this._reculock === 0) {
        if (!PSD.global)
          PSD.lockOwnerFor = null;
        while (this._blockedFuncs.length > 0 && !this._locked()) {
          var fnAndPSD = this._blockedFuncs.shift();
          try {
            usePSD(fnAndPSD[1], fnAndPSD[0]);
          } catch (e) {
          }
        }
      }
      return this;
    }
    _locked() {
      return this._reculock && PSD.lockOwnerFor !== this;
    }
    create(idbtrans) {
      if (!this.mode)
        return this;
      const idbdb = this.db.idbdb;
      const dbOpenError = this.db._state.dbOpenError;
      assert(!this.idbtrans);
      if (!idbtrans && !idbdb) {
        switch (dbOpenError && dbOpenError.name) {
          case "DatabaseClosedError":
            throw new exceptions.DatabaseClosed(dbOpenError);
          case "MissingAPIError":
            throw new exceptions.MissingAPI(dbOpenError.message, dbOpenError);
          default:
            throw new exceptions.OpenFailed(dbOpenError);
        }
      }
      if (!this.active)
        throw new exceptions.TransactionInactive();
      assert(this._completion._state === null);
      idbtrans = this.idbtrans = idbtrans || (this.db.core ? this.db.core.transaction(this.storeNames, this.mode, { durability: this.chromeTransactionDurability }) : idbdb.transaction(this.storeNames, this.mode, { durability: this.chromeTransactionDurability }));
      idbtrans.onerror = wrap((ev) => {
        preventDefault(ev);
        this._reject(idbtrans.error);
      });
      idbtrans.onabort = wrap((ev) => {
        preventDefault(ev);
        this.active && this._reject(new exceptions.Abort(idbtrans.error));
        this.active = false;
        this.on("abort").fire(ev);
      });
      idbtrans.oncomplete = wrap(() => {
        this.active = false;
        this._resolve();
        if ("mutatedParts" in idbtrans) {
          globalEvents.storagemutated.fire(idbtrans["mutatedParts"]);
        }
      });
      return this;
    }
    _promise(mode, fn, bWriteLock) {
      if (mode === "readwrite" && this.mode !== "readwrite")
        return rejection(new exceptions.ReadOnly("Transaction is readonly"));
      if (!this.active)
        return rejection(new exceptions.TransactionInactive());
      if (this._locked()) {
        return new DexiePromise((resolve, reject) => {
          this._blockedFuncs.push([() => {
            this._promise(mode, fn, bWriteLock).then(resolve, reject);
          }, PSD]);
        });
      } else if (bWriteLock) {
        return newScope(() => {
          var p2 = new DexiePromise((resolve, reject) => {
            this._lock();
            const rv = fn(resolve, reject, this);
            if (rv && rv.then)
              rv.then(resolve, reject);
          });
          p2.finally(() => this._unlock());
          p2._lib = true;
          return p2;
        });
      } else {
        var p = new DexiePromise((resolve, reject) => {
          var rv = fn(resolve, reject, this);
          if (rv && rv.then)
            rv.then(resolve, reject);
        });
        p._lib = true;
        return p;
      }
    }
    _root() {
      return this.parent ? this.parent._root() : this;
    }
    waitFor(promiseLike) {
      var root = this._root();
      const promise = DexiePromise.resolve(promiseLike);
      if (root._waitingFor) {
        root._waitingFor = root._waitingFor.then(() => promise);
      } else {
        root._waitingFor = promise;
        root._waitingQueue = [];
        var store = root.idbtrans.objectStore(root.storeNames[0]);
        (function spin() {
          ++root._spinCount;
          while (root._waitingQueue.length)
            root._waitingQueue.shift()();
          if (root._waitingFor)
            store.get(-Infinity).onsuccess = spin;
        })();
      }
      var currentWaitPromise = root._waitingFor;
      return new DexiePromise((resolve, reject) => {
        promise.then((res) => root._waitingQueue.push(wrap(resolve.bind(null, res))), (err) => root._waitingQueue.push(wrap(reject.bind(null, err)))).finally(() => {
          if (root._waitingFor === currentWaitPromise) {
            root._waitingFor = null;
          }
        });
      });
    }
    abort() {
      if (this.active) {
        this.active = false;
        if (this.idbtrans)
          this.idbtrans.abort();
        this._reject(new exceptions.Abort());
      }
    }
    table(tableName) {
      const memoizedTables = this._memoizedTables || (this._memoizedTables = {});
      if (hasOwn(memoizedTables, tableName))
        return memoizedTables[tableName];
      const tableSchema = this.schema[tableName];
      if (!tableSchema) {
        throw new exceptions.NotFound("Table " + tableName + " not part of transaction");
      }
      const transactionBoundTable = new this.db.Table(tableName, tableSchema, this);
      transactionBoundTable.core = this.db.core.table(tableName);
      memoizedTables[tableName] = transactionBoundTable;
      return transactionBoundTable;
    }
  };
  function createTransactionConstructor(db2) {
    return makeClassConstructor(Transaction.prototype, function Transaction2(mode, storeNames, dbschema, chromeTransactionDurability, parent) {
      this.db = db2;
      this.mode = mode;
      this.storeNames = storeNames;
      this.schema = dbschema;
      this.chromeTransactionDurability = chromeTransactionDurability;
      this.idbtrans = null;
      this.on = Events(this, "complete", "error", "abort");
      this.parent = parent || null;
      this.active = true;
      this._reculock = 0;
      this._blockedFuncs = [];
      this._resolve = null;
      this._reject = null;
      this._waitingFor = null;
      this._waitingQueue = null;
      this._spinCount = 0;
      this._completion = new DexiePromise((resolve, reject) => {
        this._resolve = resolve;
        this._reject = reject;
      });
      this._completion.then(() => {
        this.active = false;
        this.on.complete.fire();
      }, (e) => {
        var wasActive = this.active;
        this.active = false;
        this.on.error.fire(e);
        this.parent ? this.parent._reject(e) : wasActive && this.idbtrans && this.idbtrans.abort();
        return rejection(e);
      });
    });
  }
  function createIndexSpec(name, keyPath, unique, multi, auto, compound, isPrimKey) {
    return {
      name,
      keyPath,
      unique,
      multi,
      auto,
      compound,
      src: (unique && !isPrimKey ? "&" : "") + (multi ? "*" : "") + (auto ? "++" : "") + nameFromKeyPath(keyPath)
    };
  }
  function nameFromKeyPath(keyPath) {
    return typeof keyPath === "string" ? keyPath : keyPath ? "[" + [].join.call(keyPath, "+") + "]" : "";
  }
  function createTableSchema(name, primKey, indexes) {
    return {
      name,
      primKey,
      indexes,
      mappedClass: null,
      idxByName: arrayToObject(indexes, (index) => [index.name, index])
    };
  }
  function safariMultiStoreFix(storeNames) {
    return storeNames.length === 1 ? storeNames[0] : storeNames;
  }
  var getMaxKey = (IdbKeyRange) => {
    try {
      IdbKeyRange.only([[]]);
      getMaxKey = () => [[]];
      return [[]];
    } catch (e) {
      getMaxKey = () => maxString;
      return maxString;
    }
  };
  function getKeyExtractor(keyPath) {
    if (keyPath == null) {
      return () => void 0;
    } else if (typeof keyPath === "string") {
      return getSinglePathKeyExtractor(keyPath);
    } else {
      return (obj) => getByKeyPath(obj, keyPath);
    }
  }
  function getSinglePathKeyExtractor(keyPath) {
    const split = keyPath.split(".");
    if (split.length === 1) {
      return (obj) => obj[keyPath];
    } else {
      return (obj) => getByKeyPath(obj, keyPath);
    }
  }
  function arrayify(arrayLike) {
    return [].slice.call(arrayLike);
  }
  var _id_counter = 0;
  function getKeyPathAlias(keyPath) {
    return keyPath == null ? ":id" : typeof keyPath === "string" ? keyPath : `[${keyPath.join("+")}]`;
  }
  function createDBCore(db2, IdbKeyRange, tmpTrans) {
    function extractSchema(db3, trans) {
      const tables2 = arrayify(db3.objectStoreNames);
      return {
        schema: {
          name: db3.name,
          tables: tables2.map((table) => trans.objectStore(table)).map((store) => {
            const { keyPath, autoIncrement } = store;
            const compound = isArray2(keyPath);
            const outbound = keyPath == null;
            const indexByKeyPath = {};
            const result = {
              name: store.name,
              primaryKey: {
                name: null,
                isPrimaryKey: true,
                outbound,
                compound,
                keyPath,
                autoIncrement,
                unique: true,
                extractKey: getKeyExtractor(keyPath)
              },
              indexes: arrayify(store.indexNames).map((indexName) => store.index(indexName)).map((index) => {
                const { name, unique, multiEntry, keyPath: keyPath2 } = index;
                const compound2 = isArray2(keyPath2);
                const result2 = {
                  name,
                  compound: compound2,
                  keyPath: keyPath2,
                  unique,
                  multiEntry,
                  extractKey: getKeyExtractor(keyPath2)
                };
                indexByKeyPath[getKeyPathAlias(keyPath2)] = result2;
                return result2;
              }),
              getIndexByKeyPath: (keyPath2) => indexByKeyPath[getKeyPathAlias(keyPath2)]
            };
            indexByKeyPath[":id"] = result.primaryKey;
            if (keyPath != null) {
              indexByKeyPath[getKeyPathAlias(keyPath)] = result.primaryKey;
            }
            return result;
          })
        },
        hasGetAll: tables2.length > 0 && "getAll" in trans.objectStore(tables2[0]) && !(typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
      };
    }
    function makeIDBKeyRange(range) {
      if (range.type === 3)
        return null;
      if (range.type === 4)
        throw new Error("Cannot convert never type to IDBKeyRange");
      const { lower, upper, lowerOpen, upperOpen } = range;
      const idbRange = lower === void 0 ? upper === void 0 ? null : IdbKeyRange.upperBound(upper, !!upperOpen) : upper === void 0 ? IdbKeyRange.lowerBound(lower, !!lowerOpen) : IdbKeyRange.bound(lower, upper, !!lowerOpen, !!upperOpen);
      return idbRange;
    }
    function createDbCoreTable(tableSchema) {
      const tableName = tableSchema.name;
      function mutate({ trans, type: type2, keys: keys2, values, range }) {
        return new Promise((resolve, reject) => {
          resolve = wrap(resolve);
          const store = trans.objectStore(tableName);
          const outbound = store.keyPath == null;
          const isAddOrPut = type2 === "put" || type2 === "add";
          if (!isAddOrPut && type2 !== "delete" && type2 !== "deleteRange")
            throw new Error("Invalid operation type: " + type2);
          const { length } = keys2 || values || { length: 1 };
          if (keys2 && values && keys2.length !== values.length) {
            throw new Error("Given keys array must have same length as given values array.");
          }
          if (length === 0)
            return resolve({ numFailures: 0, failures: {}, results: [], lastResult: void 0 });
          let req;
          const reqs = [];
          const failures = [];
          let numFailures = 0;
          const errorHandler = (event) => {
            ++numFailures;
            preventDefault(event);
          };
          if (type2 === "deleteRange") {
            if (range.type === 4)
              return resolve({ numFailures, failures, results: [], lastResult: void 0 });
            if (range.type === 3)
              reqs.push(req = store.clear());
            else
              reqs.push(req = store.delete(makeIDBKeyRange(range)));
          } else {
            const [args1, args2] = isAddOrPut ? outbound ? [values, keys2] : [values, null] : [keys2, null];
            if (isAddOrPut) {
              for (let i = 0; i < length; ++i) {
                reqs.push(req = args2 && args2[i] !== void 0 ? store[type2](args1[i], args2[i]) : store[type2](args1[i]));
                req.onerror = errorHandler;
              }
            } else {
              for (let i = 0; i < length; ++i) {
                reqs.push(req = store[type2](args1[i]));
                req.onerror = errorHandler;
              }
            }
          }
          const done = (event) => {
            const lastResult = event.target.result;
            reqs.forEach((req2, i) => req2.error != null && (failures[i] = req2.error));
            resolve({
              numFailures,
              failures,
              results: type2 === "delete" ? keys2 : reqs.map((req2) => req2.result),
              lastResult
            });
          };
          req.onerror = (event) => {
            errorHandler(event);
            done(event);
          };
          req.onsuccess = done;
        });
      }
      function openCursor2({ trans, values, query: query2, reverse, unique }) {
        return new Promise((resolve, reject) => {
          resolve = wrap(resolve);
          const { index, range } = query2;
          const store = trans.objectStore(tableName);
          const source = index.isPrimaryKey ? store : store.index(index.name);
          const direction = reverse ? unique ? "prevunique" : "prev" : unique ? "nextunique" : "next";
          const req = values || !("openKeyCursor" in source) ? source.openCursor(makeIDBKeyRange(range), direction) : source.openKeyCursor(makeIDBKeyRange(range), direction);
          req.onerror = eventRejectHandler(reject);
          req.onsuccess = wrap((ev) => {
            const cursor = req.result;
            if (!cursor) {
              resolve(null);
              return;
            }
            cursor.___id = ++_id_counter;
            cursor.done = false;
            const _cursorContinue = cursor.continue.bind(cursor);
            let _cursorContinuePrimaryKey = cursor.continuePrimaryKey;
            if (_cursorContinuePrimaryKey)
              _cursorContinuePrimaryKey = _cursorContinuePrimaryKey.bind(cursor);
            const _cursorAdvance = cursor.advance.bind(cursor);
            const doThrowCursorIsNotStarted = () => {
              throw new Error("Cursor not started");
            };
            const doThrowCursorIsStopped = () => {
              throw new Error("Cursor not stopped");
            };
            cursor.trans = trans;
            cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsNotStarted;
            cursor.fail = wrap(reject);
            cursor.next = function() {
              let gotOne = 1;
              return this.start(() => gotOne-- ? this.continue() : this.stop()).then(() => this);
            };
            cursor.start = (callback) => {
              const iterationPromise = new Promise((resolveIteration, rejectIteration) => {
                resolveIteration = wrap(resolveIteration);
                req.onerror = eventRejectHandler(rejectIteration);
                cursor.fail = rejectIteration;
                cursor.stop = (value) => {
                  cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsStopped;
                  resolveIteration(value);
                };
              });
              const guardedCallback = () => {
                if (req.result) {
                  try {
                    callback();
                  } catch (err) {
                    cursor.fail(err);
                  }
                } else {
                  cursor.done = true;
                  cursor.start = () => {
                    throw new Error("Cursor behind last entry");
                  };
                  cursor.stop();
                }
              };
              req.onsuccess = wrap((ev2) => {
                req.onsuccess = guardedCallback;
                guardedCallback();
              });
              cursor.continue = _cursorContinue;
              cursor.continuePrimaryKey = _cursorContinuePrimaryKey;
              cursor.advance = _cursorAdvance;
              guardedCallback();
              return iterationPromise;
            };
            resolve(cursor);
          }, reject);
        });
      }
      function query(hasGetAll2) {
        return (request) => {
          return new Promise((resolve, reject) => {
            resolve = wrap(resolve);
            const { trans, values, limit, query: query2 } = request;
            const nonInfinitLimit = limit === Infinity ? void 0 : limit;
            const { index, range } = query2;
            const store = trans.objectStore(tableName);
            const source = index.isPrimaryKey ? store : store.index(index.name);
            const idbKeyRange = makeIDBKeyRange(range);
            if (limit === 0)
              return resolve({ result: [] });
            if (hasGetAll2) {
              const req = values ? source.getAll(idbKeyRange, nonInfinitLimit) : source.getAllKeys(idbKeyRange, nonInfinitLimit);
              req.onsuccess = (event) => resolve({ result: event.target.result });
              req.onerror = eventRejectHandler(reject);
            } else {
              let count = 0;
              const req = values || !("openKeyCursor" in source) ? source.openCursor(idbKeyRange) : source.openKeyCursor(idbKeyRange);
              const result = [];
              req.onsuccess = (event) => {
                const cursor = req.result;
                if (!cursor)
                  return resolve({ result });
                result.push(values ? cursor.value : cursor.primaryKey);
                if (++count === limit)
                  return resolve({ result });
                cursor.continue();
              };
              req.onerror = eventRejectHandler(reject);
            }
          });
        };
      }
      return {
        name: tableName,
        schema: tableSchema,
        mutate,
        getMany({ trans, keys: keys2 }) {
          return new Promise((resolve, reject) => {
            resolve = wrap(resolve);
            const store = trans.objectStore(tableName);
            const length = keys2.length;
            const result = new Array(length);
            let keyCount = 0;
            let callbackCount = 0;
            let req;
            const successHandler = (event) => {
              const req2 = event.target;
              if ((result[req2._pos] = req2.result) != null)
                ;
              if (++callbackCount === keyCount)
                resolve(result);
            };
            const errorHandler = eventRejectHandler(reject);
            for (let i = 0; i < length; ++i) {
              const key = keys2[i];
              if (key != null) {
                req = store.get(keys2[i]);
                req._pos = i;
                req.onsuccess = successHandler;
                req.onerror = errorHandler;
                ++keyCount;
              }
            }
            if (keyCount === 0)
              resolve(result);
          });
        },
        get({ trans, key }) {
          return new Promise((resolve, reject) => {
            resolve = wrap(resolve);
            const store = trans.objectStore(tableName);
            const req = store.get(key);
            req.onsuccess = (event) => resolve(event.target.result);
            req.onerror = eventRejectHandler(reject);
          });
        },
        query: query(hasGetAll),
        openCursor: openCursor2,
        count({ query: query2, trans }) {
          const { index, range } = query2;
          return new Promise((resolve, reject) => {
            const store = trans.objectStore(tableName);
            const source = index.isPrimaryKey ? store : store.index(index.name);
            const idbKeyRange = makeIDBKeyRange(range);
            const req = idbKeyRange ? source.count(idbKeyRange) : source.count();
            req.onsuccess = wrap((ev) => resolve(ev.target.result));
            req.onerror = eventRejectHandler(reject);
          });
        }
      };
    }
    const { schema, hasGetAll } = extractSchema(db2, tmpTrans);
    const tables = schema.tables.map((tableSchema) => createDbCoreTable(tableSchema));
    const tableMap = {};
    tables.forEach((table) => tableMap[table.name] = table);
    return {
      stack: "dbcore",
      transaction: db2.transaction.bind(db2),
      table(name) {
        const result = tableMap[name];
        if (!result)
          throw new Error(`Table '${name}' not found`);
        return tableMap[name];
      },
      MIN_KEY: -Infinity,
      MAX_KEY: getMaxKey(IdbKeyRange),
      schema
    };
  }
  function createMiddlewareStack(stackImpl, middlewares) {
    return middlewares.reduce((down, { create }) => ({ ...down, ...create(down) }), stackImpl);
  }
  function createMiddlewareStacks(middlewares, idbdb, { IDBKeyRange, indexedDB: indexedDB2 }, tmpTrans) {
    const dbcore = createMiddlewareStack(createDBCore(idbdb, IDBKeyRange, tmpTrans), middlewares.dbcore);
    return {
      dbcore
    };
  }
  function generateMiddlewareStacks({ _novip: db2 }, tmpTrans) {
    const idbdb = tmpTrans.db;
    const stacks = createMiddlewareStacks(db2._middlewares, idbdb, db2._deps, tmpTrans);
    db2.core = stacks.dbcore;
    db2.tables.forEach((table) => {
      const tableName = table.name;
      if (db2.core.schema.tables.some((tbl) => tbl.name === tableName)) {
        table.core = db2.core.table(tableName);
        if (db2[tableName] instanceof db2.Table) {
          db2[tableName].core = table.core;
        }
      }
    });
  }
  function setApiOnPlace({ _novip: db2 }, objs, tableNames, dbschema) {
    tableNames.forEach((tableName) => {
      const schema = dbschema[tableName];
      objs.forEach((obj) => {
        const propDesc = getPropertyDescriptor(obj, tableName);
        if (!propDesc || "value" in propDesc && propDesc.value === void 0) {
          if (obj === db2.Transaction.prototype || obj instanceof db2.Transaction) {
            setProp(obj, tableName, {
              get() {
                return this.table(tableName);
              },
              set(value) {
                defineProperty(this, tableName, { value, writable: true, configurable: true, enumerable: true });
              }
            });
          } else {
            obj[tableName] = new db2.Table(tableName, schema);
          }
        }
      });
    });
  }
  function removeTablesApi({ _novip: db2 }, objs) {
    objs.forEach((obj) => {
      for (let key in obj) {
        if (obj[key] instanceof db2.Table)
          delete obj[key];
      }
    });
  }
  function lowerVersionFirst(a, b) {
    return a._cfg.version - b._cfg.version;
  }
  function runUpgraders(db2, oldVersion, idbUpgradeTrans, reject) {
    const globalSchema = db2._dbSchema;
    const trans = db2._createTransaction("readwrite", db2._storeNames, globalSchema);
    trans.create(idbUpgradeTrans);
    trans._completion.catch(reject);
    const rejectTransaction = trans._reject.bind(trans);
    const transless = PSD.transless || PSD;
    newScope(() => {
      PSD.trans = trans;
      PSD.transless = transless;
      if (oldVersion === 0) {
        keys(globalSchema).forEach((tableName) => {
          createTable(idbUpgradeTrans, tableName, globalSchema[tableName].primKey, globalSchema[tableName].indexes);
        });
        generateMiddlewareStacks(db2, idbUpgradeTrans);
        DexiePromise.follow(() => db2.on.populate.fire(trans)).catch(rejectTransaction);
      } else
        updateTablesAndIndexes(db2, oldVersion, trans, idbUpgradeTrans).catch(rejectTransaction);
    });
  }
  function updateTablesAndIndexes({ _novip: db2 }, oldVersion, trans, idbUpgradeTrans) {
    const queue = [];
    const versions = db2._versions;
    let globalSchema = db2._dbSchema = buildGlobalSchema(db2, db2.idbdb, idbUpgradeTrans);
    let anyContentUpgraderHasRun = false;
    const versToRun = versions.filter((v) => v._cfg.version >= oldVersion);
    versToRun.forEach((version) => {
      queue.push(() => {
        const oldSchema = globalSchema;
        const newSchema = version._cfg.dbschema;
        adjustToExistingIndexNames(db2, oldSchema, idbUpgradeTrans);
        adjustToExistingIndexNames(db2, newSchema, idbUpgradeTrans);
        globalSchema = db2._dbSchema = newSchema;
        const diff = getSchemaDiff(oldSchema, newSchema);
        diff.add.forEach((tuple) => {
          createTable(idbUpgradeTrans, tuple[0], tuple[1].primKey, tuple[1].indexes);
        });
        diff.change.forEach((change) => {
          if (change.recreate) {
            throw new exceptions.Upgrade("Not yet support for changing primary key");
          } else {
            const store = idbUpgradeTrans.objectStore(change.name);
            change.add.forEach((idx) => addIndex(store, idx));
            change.change.forEach((idx) => {
              store.deleteIndex(idx.name);
              addIndex(store, idx);
            });
            change.del.forEach((idxName) => store.deleteIndex(idxName));
          }
        });
        const contentUpgrade = version._cfg.contentUpgrade;
        if (contentUpgrade && version._cfg.version > oldVersion) {
          generateMiddlewareStacks(db2, idbUpgradeTrans);
          trans._memoizedTables = {};
          anyContentUpgraderHasRun = true;
          let upgradeSchema = shallowClone(newSchema);
          diff.del.forEach((table) => {
            upgradeSchema[table] = oldSchema[table];
          });
          removeTablesApi(db2, [db2.Transaction.prototype]);
          setApiOnPlace(db2, [db2.Transaction.prototype], keys(upgradeSchema), upgradeSchema);
          trans.schema = upgradeSchema;
          const contentUpgradeIsAsync = isAsyncFunction(contentUpgrade);
          if (contentUpgradeIsAsync) {
            incrementExpectedAwaits();
          }
          let returnValue;
          const promiseFollowed = DexiePromise.follow(() => {
            returnValue = contentUpgrade(trans);
            if (returnValue) {
              if (contentUpgradeIsAsync) {
                var decrementor = decrementExpectedAwaits.bind(null, null);
                returnValue.then(decrementor, decrementor);
              }
            }
          });
          return returnValue && typeof returnValue.then === "function" ? DexiePromise.resolve(returnValue) : promiseFollowed.then(() => returnValue);
        }
      });
      queue.push((idbtrans) => {
        if (!anyContentUpgraderHasRun || !hasIEDeleteObjectStoreBug) {
          const newSchema = version._cfg.dbschema;
          deleteRemovedTables(newSchema, idbtrans);
        }
        removeTablesApi(db2, [db2.Transaction.prototype]);
        setApiOnPlace(db2, [db2.Transaction.prototype], db2._storeNames, db2._dbSchema);
        trans.schema = db2._dbSchema;
      });
    });
    function runQueue() {
      return queue.length ? DexiePromise.resolve(queue.shift()(trans.idbtrans)).then(runQueue) : DexiePromise.resolve();
    }
    return runQueue().then(() => {
      createMissingTables(globalSchema, idbUpgradeTrans);
    });
  }
  function getSchemaDiff(oldSchema, newSchema) {
    const diff = {
      del: [],
      add: [],
      change: []
    };
    let table;
    for (table in oldSchema) {
      if (!newSchema[table])
        diff.del.push(table);
    }
    for (table in newSchema) {
      const oldDef = oldSchema[table], newDef = newSchema[table];
      if (!oldDef) {
        diff.add.push([table, newDef]);
      } else {
        const change = {
          name: table,
          def: newDef,
          recreate: false,
          del: [],
          add: [],
          change: []
        };
        if ("" + (oldDef.primKey.keyPath || "") !== "" + (newDef.primKey.keyPath || "") || oldDef.primKey.auto !== newDef.primKey.auto && !isIEOrEdge) {
          change.recreate = true;
          diff.change.push(change);
        } else {
          const oldIndexes = oldDef.idxByName;
          const newIndexes = newDef.idxByName;
          let idxName;
          for (idxName in oldIndexes) {
            if (!newIndexes[idxName])
              change.del.push(idxName);
          }
          for (idxName in newIndexes) {
            const oldIdx = oldIndexes[idxName], newIdx = newIndexes[idxName];
            if (!oldIdx)
              change.add.push(newIdx);
            else if (oldIdx.src !== newIdx.src)
              change.change.push(newIdx);
          }
          if (change.del.length > 0 || change.add.length > 0 || change.change.length > 0) {
            diff.change.push(change);
          }
        }
      }
    }
    return diff;
  }
  function createTable(idbtrans, tableName, primKey, indexes) {
    const store = idbtrans.db.createObjectStore(tableName, primKey.keyPath ? { keyPath: primKey.keyPath, autoIncrement: primKey.auto } : { autoIncrement: primKey.auto });
    indexes.forEach((idx) => addIndex(store, idx));
    return store;
  }
  function createMissingTables(newSchema, idbtrans) {
    keys(newSchema).forEach((tableName) => {
      if (!idbtrans.db.objectStoreNames.contains(tableName)) {
        createTable(idbtrans, tableName, newSchema[tableName].primKey, newSchema[tableName].indexes);
      }
    });
  }
  function deleteRemovedTables(newSchema, idbtrans) {
    [].slice.call(idbtrans.db.objectStoreNames).forEach((storeName) => newSchema[storeName] == null && idbtrans.db.deleteObjectStore(storeName));
  }
  function addIndex(store, idx) {
    store.createIndex(idx.name, idx.keyPath, { unique: idx.unique, multiEntry: idx.multi });
  }
  function buildGlobalSchema(db2, idbdb, tmpTrans) {
    const globalSchema = {};
    const dbStoreNames = slice(idbdb.objectStoreNames, 0);
    dbStoreNames.forEach((storeName) => {
      const store = tmpTrans.objectStore(storeName);
      let keyPath = store.keyPath;
      const primKey = createIndexSpec(nameFromKeyPath(keyPath), keyPath || "", false, false, !!store.autoIncrement, keyPath && typeof keyPath !== "string", true);
      const indexes = [];
      for (let j = 0; j < store.indexNames.length; ++j) {
        const idbindex = store.index(store.indexNames[j]);
        keyPath = idbindex.keyPath;
        var index = createIndexSpec(idbindex.name, keyPath, !!idbindex.unique, !!idbindex.multiEntry, false, keyPath && typeof keyPath !== "string", false);
        indexes.push(index);
      }
      globalSchema[storeName] = createTableSchema(storeName, primKey, indexes);
    });
    return globalSchema;
  }
  function readGlobalSchema({ _novip: db2 }, idbdb, tmpTrans) {
    db2.verno = idbdb.version / 10;
    const globalSchema = db2._dbSchema = buildGlobalSchema(db2, idbdb, tmpTrans);
    db2._storeNames = slice(idbdb.objectStoreNames, 0);
    setApiOnPlace(db2, [db2._allTables], keys(globalSchema), globalSchema);
  }
  function verifyInstalledSchema(db2, tmpTrans) {
    const installedSchema = buildGlobalSchema(db2, db2.idbdb, tmpTrans);
    const diff = getSchemaDiff(installedSchema, db2._dbSchema);
    return !(diff.add.length || diff.change.some((ch) => ch.add.length || ch.change.length));
  }
  function adjustToExistingIndexNames({ _novip: db2 }, schema, idbtrans) {
    const storeNames = idbtrans.db.objectStoreNames;
    for (let i = 0; i < storeNames.length; ++i) {
      const storeName = storeNames[i];
      const store = idbtrans.objectStore(storeName);
      db2._hasGetAll = "getAll" in store;
      for (let j = 0; j < store.indexNames.length; ++j) {
        const indexName = store.indexNames[j];
        const keyPath = store.index(indexName).keyPath;
        const dexieName = typeof keyPath === "string" ? keyPath : "[" + slice(keyPath).join("+") + "]";
        if (schema[storeName]) {
          const indexSpec = schema[storeName].idxByName[dexieName];
          if (indexSpec) {
            indexSpec.name = indexName;
            delete schema[storeName].idxByName[dexieName];
            schema[storeName].idxByName[indexName] = indexSpec;
          }
        }
      }
    }
    if (typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && _global.WorkerGlobalScope && _global instanceof _global.WorkerGlobalScope && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604) {
      db2._hasGetAll = false;
    }
  }
  function parseIndexSyntax(primKeyAndIndexes) {
    return primKeyAndIndexes.split(",").map((index, indexNum) => {
      index = index.trim();
      const name = index.replace(/([&*]|\+\+)/g, "");
      const keyPath = /^\[/.test(name) ? name.match(/^\[(.*)\]$/)[1].split("+") : name;
      return createIndexSpec(name, keyPath || null, /\&/.test(index), /\*/.test(index), /\+\+/.test(index), isArray2(keyPath), indexNum === 0);
    });
  }
  var Version2 = class {
    _parseStoresSpec(stores, outSchema) {
      keys(stores).forEach((tableName) => {
        if (stores[tableName] !== null) {
          var indexes = parseIndexSyntax(stores[tableName]);
          var primKey = indexes.shift();
          if (primKey.multi)
            throw new exceptions.Schema("Primary key cannot be multi-valued");
          indexes.forEach((idx) => {
            if (idx.auto)
              throw new exceptions.Schema("Only primary key can be marked as autoIncrement (++)");
            if (!idx.keyPath)
              throw new exceptions.Schema("Index must have a name and cannot be an empty string");
          });
          outSchema[tableName] = createTableSchema(tableName, primKey, indexes);
        }
      });
    }
    stores(stores) {
      const db2 = this.db;
      this._cfg.storesSource = this._cfg.storesSource ? extend(this._cfg.storesSource, stores) : stores;
      const versions = db2._versions;
      const storesSpec = {};
      let dbschema = {};
      versions.forEach((version) => {
        extend(storesSpec, version._cfg.storesSource);
        dbschema = version._cfg.dbschema = {};
        version._parseStoresSpec(storesSpec, dbschema);
      });
      db2._dbSchema = dbschema;
      removeTablesApi(db2, [db2._allTables, db2, db2.Transaction.prototype]);
      setApiOnPlace(db2, [db2._allTables, db2, db2.Transaction.prototype, this._cfg.tables], keys(dbschema), dbschema);
      db2._storeNames = keys(dbschema);
      return this;
    }
    upgrade(upgradeFunction) {
      this._cfg.contentUpgrade = promisableChain(this._cfg.contentUpgrade || nop, upgradeFunction);
      return this;
    }
  };
  function createVersionConstructor(db2) {
    return makeClassConstructor(Version2.prototype, function Version3(versionNumber) {
      this.db = db2;
      this._cfg = {
        version: versionNumber,
        storesSource: null,
        dbschema: {},
        tables: {},
        contentUpgrade: null
      };
    });
  }
  function getDbNamesTable(indexedDB2, IDBKeyRange) {
    let dbNamesDB = indexedDB2["_dbNamesDB"];
    if (!dbNamesDB) {
      dbNamesDB = indexedDB2["_dbNamesDB"] = new Dexie$1(DBNAMES_DB, {
        addons: [],
        indexedDB: indexedDB2,
        IDBKeyRange
      });
      dbNamesDB.version(1).stores({ dbnames: "name" });
    }
    return dbNamesDB.table("dbnames");
  }
  function hasDatabasesNative(indexedDB2) {
    return indexedDB2 && typeof indexedDB2.databases === "function";
  }
  function getDatabaseNames({ indexedDB: indexedDB2, IDBKeyRange }) {
    return hasDatabasesNative(indexedDB2) ? Promise.resolve(indexedDB2.databases()).then((infos) => infos.map((info) => info.name).filter((name) => name !== DBNAMES_DB)) : getDbNamesTable(indexedDB2, IDBKeyRange).toCollection().primaryKeys();
  }
  function _onDatabaseCreated({ indexedDB: indexedDB2, IDBKeyRange }, name) {
    !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).put({ name }).catch(nop);
  }
  function _onDatabaseDeleted({ indexedDB: indexedDB2, IDBKeyRange }, name) {
    !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).delete(name).catch(nop);
  }
  function vip(fn) {
    return newScope(function() {
      PSD.letThrough = true;
      return fn();
    });
  }
  function idbReady() {
    var isSafari = !navigator.userAgentData && /Safari\//.test(navigator.userAgent) && !/Chrom(e|ium)\//.test(navigator.userAgent);
    if (!isSafari || !indexedDB.databases)
      return Promise.resolve();
    var intervalId;
    return new Promise(function(resolve) {
      var tryIdb = function() {
        return indexedDB.databases().finally(resolve);
      };
      intervalId = setInterval(tryIdb, 100);
      tryIdb();
    }).finally(function() {
      return clearInterval(intervalId);
    });
  }
  function dexieOpen(db2) {
    const state = db2._state;
    const { indexedDB: indexedDB2 } = db2._deps;
    if (state.isBeingOpened || db2.idbdb)
      return state.dbReadyPromise.then(() => state.dbOpenError ? rejection(state.dbOpenError) : db2);
    debug && (state.openCanceller._stackHolder = getErrorWithStack());
    state.isBeingOpened = true;
    state.dbOpenError = null;
    state.openComplete = false;
    const openCanceller = state.openCanceller;
    function throwIfCancelled() {
      if (state.openCanceller !== openCanceller)
        throw new exceptions.DatabaseClosed("db.open() was cancelled");
    }
    let resolveDbReady = state.dbReadyResolve, upgradeTransaction = null, wasCreated = false;
    const tryOpenDB = () => new DexiePromise((resolve, reject) => {
      throwIfCancelled();
      if (!indexedDB2)
        throw new exceptions.MissingAPI();
      const dbName = db2.name;
      const req = state.autoSchema ? indexedDB2.open(dbName) : indexedDB2.open(dbName, Math.round(db2.verno * 10));
      if (!req)
        throw new exceptions.MissingAPI();
      req.onerror = eventRejectHandler(reject);
      req.onblocked = wrap(db2._fireOnBlocked);
      req.onupgradeneeded = wrap((e) => {
        upgradeTransaction = req.transaction;
        if (state.autoSchema && !db2._options.allowEmptyDB) {
          req.onerror = preventDefault;
          upgradeTransaction.abort();
          req.result.close();
          const delreq = indexedDB2.deleteDatabase(dbName);
          delreq.onsuccess = delreq.onerror = wrap(() => {
            reject(new exceptions.NoSuchDatabase(`Database ${dbName} doesnt exist`));
          });
        } else {
          upgradeTransaction.onerror = eventRejectHandler(reject);
          var oldVer = e.oldVersion > Math.pow(2, 62) ? 0 : e.oldVersion;
          wasCreated = oldVer < 1;
          db2._novip.idbdb = req.result;
          runUpgraders(db2, oldVer / 10, upgradeTransaction, reject);
        }
      }, reject);
      req.onsuccess = wrap(() => {
        upgradeTransaction = null;
        const idbdb = db2._novip.idbdb = req.result;
        const objectStoreNames = slice(idbdb.objectStoreNames);
        if (objectStoreNames.length > 0)
          try {
            const tmpTrans = idbdb.transaction(safariMultiStoreFix(objectStoreNames), "readonly");
            if (state.autoSchema)
              readGlobalSchema(db2, idbdb, tmpTrans);
            else {
              adjustToExistingIndexNames(db2, db2._dbSchema, tmpTrans);
              if (!verifyInstalledSchema(db2, tmpTrans)) {
                console.warn(`Dexie SchemaDiff: Schema was extended without increasing the number passed to db.version(). Some queries may fail.`);
              }
            }
            generateMiddlewareStacks(db2, tmpTrans);
          } catch (e) {
          }
        connections.push(db2);
        idbdb.onversionchange = wrap((ev) => {
          state.vcFired = true;
          db2.on("versionchange").fire(ev);
        });
        idbdb.onclose = wrap((ev) => {
          db2.on("close").fire(ev);
        });
        if (wasCreated)
          _onDatabaseCreated(db2._deps, dbName);
        resolve();
      }, reject);
    }).catch((err) => {
      if (err && err.name === "UnknownError" && state.PR1398_maxLoop > 0) {
        state.PR1398_maxLoop--;
        console.warn("Dexie: Workaround for Chrome UnknownError on open()");
        return tryOpenDB();
      } else {
        return DexiePromise.reject(err);
      }
    });
    return DexiePromise.race([
      openCanceller,
      (typeof navigator === "undefined" ? DexiePromise.resolve() : idbReady()).then(tryOpenDB)
    ]).then(() => {
      throwIfCancelled();
      state.onReadyBeingFired = [];
      return DexiePromise.resolve(vip(() => db2.on.ready.fire(db2.vip))).then(function fireRemainders() {
        if (state.onReadyBeingFired.length > 0) {
          let remainders = state.onReadyBeingFired.reduce(promisableChain, nop);
          state.onReadyBeingFired = [];
          return DexiePromise.resolve(vip(() => remainders(db2.vip))).then(fireRemainders);
        }
      });
    }).finally(() => {
      state.onReadyBeingFired = null;
      state.isBeingOpened = false;
    }).then(() => {
      return db2;
    }).catch((err) => {
      state.dbOpenError = err;
      try {
        upgradeTransaction && upgradeTransaction.abort();
      } catch (_a) {
      }
      if (openCanceller === state.openCanceller) {
        db2._close();
      }
      return rejection(err);
    }).finally(() => {
      state.openComplete = true;
      resolveDbReady();
    });
  }
  function awaitIterator(iterator) {
    var callNext = (result) => iterator.next(result), doThrow = (error) => iterator.throw(error), onSuccess = step(callNext), onError = step(doThrow);
    function step(getNext) {
      return (val) => {
        var next = getNext(val), value = next.value;
        return next.done ? value : !value || typeof value.then !== "function" ? isArray2(value) ? Promise.all(value).then(onSuccess, onError) : onSuccess(value) : value.then(onSuccess, onError);
      };
    }
    return step(callNext)();
  }
  function extractTransactionArgs(mode, _tableArgs_, scopeFunc) {
    var i = arguments.length;
    if (i < 2)
      throw new exceptions.InvalidArgument("Too few arguments");
    var args = new Array(i - 1);
    while (--i)
      args[i - 1] = arguments[i];
    scopeFunc = args.pop();
    var tables = flatten(args);
    return [mode, tables, scopeFunc];
  }
  function enterTransactionScope(db2, mode, storeNames, parentTransaction, scopeFunc) {
    return DexiePromise.resolve().then(() => {
      const transless = PSD.transless || PSD;
      const trans = db2._createTransaction(mode, storeNames, db2._dbSchema, parentTransaction);
      const zoneProps = {
        trans,
        transless
      };
      if (parentTransaction) {
        trans.idbtrans = parentTransaction.idbtrans;
      } else {
        try {
          trans.create();
          db2._state.PR1398_maxLoop = 3;
        } catch (ex) {
          if (ex.name === errnames.InvalidState && db2.isOpen() && --db2._state.PR1398_maxLoop > 0) {
            console.warn("Dexie: Need to reopen db");
            db2._close();
            return db2.open().then(() => enterTransactionScope(db2, mode, storeNames, null, scopeFunc));
          }
          return rejection(ex);
        }
      }
      const scopeFuncIsAsync = isAsyncFunction(scopeFunc);
      if (scopeFuncIsAsync) {
        incrementExpectedAwaits();
      }
      let returnValue;
      const promiseFollowed = DexiePromise.follow(() => {
        returnValue = scopeFunc.call(trans, trans);
        if (returnValue) {
          if (scopeFuncIsAsync) {
            var decrementor = decrementExpectedAwaits.bind(null, null);
            returnValue.then(decrementor, decrementor);
          } else if (typeof returnValue.next === "function" && typeof returnValue.throw === "function") {
            returnValue = awaitIterator(returnValue);
          }
        }
      }, zoneProps);
      return (returnValue && typeof returnValue.then === "function" ? DexiePromise.resolve(returnValue).then((x) => trans.active ? x : rejection(new exceptions.PrematureCommit("Transaction committed too early. See http://bit.ly/2kdckMn"))) : promiseFollowed.then(() => returnValue)).then((x) => {
        if (parentTransaction)
          trans._resolve();
        return trans._completion.then(() => x);
      }).catch((e) => {
        trans._reject(e);
        return rejection(e);
      });
    });
  }
  function pad(a, value, count) {
    const result = isArray2(a) ? a.slice() : [a];
    for (let i = 0; i < count; ++i)
      result.push(value);
    return result;
  }
  function createVirtualIndexMiddleware(down) {
    return {
      ...down,
      table(tableName) {
        const table = down.table(tableName);
        const { schema } = table;
        const indexLookup = {};
        const allVirtualIndexes = [];
        function addVirtualIndexes(keyPath, keyTail, lowLevelIndex) {
          const keyPathAlias = getKeyPathAlias(keyPath);
          const indexList = indexLookup[keyPathAlias] = indexLookup[keyPathAlias] || [];
          const keyLength = keyPath == null ? 0 : typeof keyPath === "string" ? 1 : keyPath.length;
          const isVirtual = keyTail > 0;
          const virtualIndex = {
            ...lowLevelIndex,
            isVirtual,
            keyTail,
            keyLength,
            extractKey: getKeyExtractor(keyPath),
            unique: !isVirtual && lowLevelIndex.unique
          };
          indexList.push(virtualIndex);
          if (!virtualIndex.isPrimaryKey) {
            allVirtualIndexes.push(virtualIndex);
          }
          if (keyLength > 1) {
            const virtualKeyPath = keyLength === 2 ? keyPath[0] : keyPath.slice(0, keyLength - 1);
            addVirtualIndexes(virtualKeyPath, keyTail + 1, lowLevelIndex);
          }
          indexList.sort((a, b) => a.keyTail - b.keyTail);
          return virtualIndex;
        }
        const primaryKey = addVirtualIndexes(schema.primaryKey.keyPath, 0, schema.primaryKey);
        indexLookup[":id"] = [primaryKey];
        for (const index of schema.indexes) {
          addVirtualIndexes(index.keyPath, 0, index);
        }
        function findBestIndex(keyPath) {
          const result2 = indexLookup[getKeyPathAlias(keyPath)];
          return result2 && result2[0];
        }
        function translateRange(range, keyTail) {
          return {
            type: range.type === 1 ? 2 : range.type,
            lower: pad(range.lower, range.lowerOpen ? down.MAX_KEY : down.MIN_KEY, keyTail),
            lowerOpen: true,
            upper: pad(range.upper, range.upperOpen ? down.MIN_KEY : down.MAX_KEY, keyTail),
            upperOpen: true
          };
        }
        function translateRequest(req) {
          const index = req.query.index;
          return index.isVirtual ? {
            ...req,
            query: {
              index,
              range: translateRange(req.query.range, index.keyTail)
            }
          } : req;
        }
        const result = {
          ...table,
          schema: {
            ...schema,
            primaryKey,
            indexes: allVirtualIndexes,
            getIndexByKeyPath: findBestIndex
          },
          count(req) {
            return table.count(translateRequest(req));
          },
          query(req) {
            return table.query(translateRequest(req));
          },
          openCursor(req) {
            const { keyTail, isVirtual, keyLength } = req.query.index;
            if (!isVirtual)
              return table.openCursor(req);
            function createVirtualCursor(cursor) {
              function _continue(key) {
                key != null ? cursor.continue(pad(key, req.reverse ? down.MAX_KEY : down.MIN_KEY, keyTail)) : req.unique ? cursor.continue(cursor.key.slice(0, keyLength).concat(req.reverse ? down.MIN_KEY : down.MAX_KEY, keyTail)) : cursor.continue();
              }
              const virtualCursor = Object.create(cursor, {
                continue: { value: _continue },
                continuePrimaryKey: {
                  value(key, primaryKey2) {
                    cursor.continuePrimaryKey(pad(key, down.MAX_KEY, keyTail), primaryKey2);
                  }
                },
                primaryKey: {
                  get() {
                    return cursor.primaryKey;
                  }
                },
                key: {
                  get() {
                    const key = cursor.key;
                    return keyLength === 1 ? key[0] : key.slice(0, keyLength);
                  }
                },
                value: {
                  get() {
                    return cursor.value;
                  }
                }
              });
              return virtualCursor;
            }
            return table.openCursor(translateRequest(req)).then((cursor) => cursor && createVirtualCursor(cursor));
          }
        };
        return result;
      }
    };
  }
  var virtualIndexMiddleware = {
    stack: "dbcore",
    name: "VirtualIndexMiddleware",
    level: 1,
    create: createVirtualIndexMiddleware
  };
  function getObjectDiff(a, b, rv, prfx) {
    rv = rv || {};
    prfx = prfx || "";
    keys(a).forEach((prop) => {
      if (!hasOwn(b, prop)) {
        rv[prfx + prop] = void 0;
      } else {
        var ap = a[prop], bp = b[prop];
        if (typeof ap === "object" && typeof bp === "object" && ap && bp) {
          const apTypeName = toStringTag(ap);
          const bpTypeName = toStringTag(bp);
          if (apTypeName !== bpTypeName) {
            rv[prfx + prop] = b[prop];
          } else if (apTypeName === "Object") {
            getObjectDiff(ap, bp, rv, prfx + prop + ".");
          } else if (ap !== bp) {
            rv[prfx + prop] = b[prop];
          }
        } else if (ap !== bp)
          rv[prfx + prop] = b[prop];
      }
    });
    keys(b).forEach((prop) => {
      if (!hasOwn(a, prop)) {
        rv[prfx + prop] = b[prop];
      }
    });
    return rv;
  }
  function getEffectiveKeys(primaryKey, req) {
    if (req.type === "delete")
      return req.keys;
    return req.keys || req.values.map(primaryKey.extractKey);
  }
  var hooksMiddleware = {
    stack: "dbcore",
    name: "HooksMiddleware",
    level: 2,
    create: (downCore) => ({
      ...downCore,
      table(tableName) {
        const downTable = downCore.table(tableName);
        const { primaryKey } = downTable.schema;
        const tableMiddleware = {
          ...downTable,
          mutate(req) {
            const dxTrans = PSD.trans;
            const { deleting, creating, updating } = dxTrans.table(tableName).hook;
            switch (req.type) {
              case "add":
                if (creating.fire === nop)
                  break;
                return dxTrans._promise("readwrite", () => addPutOrDelete(req), true);
              case "put":
                if (creating.fire === nop && updating.fire === nop)
                  break;
                return dxTrans._promise("readwrite", () => addPutOrDelete(req), true);
              case "delete":
                if (deleting.fire === nop)
                  break;
                return dxTrans._promise("readwrite", () => addPutOrDelete(req), true);
              case "deleteRange":
                if (deleting.fire === nop)
                  break;
                return dxTrans._promise("readwrite", () => deleteRange(req), true);
            }
            return downTable.mutate(req);
            function addPutOrDelete(req2) {
              const dxTrans2 = PSD.trans;
              const keys2 = req2.keys || getEffectiveKeys(primaryKey, req2);
              if (!keys2)
                throw new Error("Keys missing");
              req2 = req2.type === "add" || req2.type === "put" ? { ...req2, keys: keys2 } : { ...req2 };
              if (req2.type !== "delete")
                req2.values = [...req2.values];
              if (req2.keys)
                req2.keys = [...req2.keys];
              return getExistingValues(downTable, req2, keys2).then((existingValues) => {
                const contexts = keys2.map((key, i) => {
                  const existingValue = existingValues[i];
                  const ctx = { onerror: null, onsuccess: null };
                  if (req2.type === "delete") {
                    deleting.fire.call(ctx, key, existingValue, dxTrans2);
                  } else if (req2.type === "add" || existingValue === void 0) {
                    const generatedPrimaryKey = creating.fire.call(ctx, key, req2.values[i], dxTrans2);
                    if (key == null && generatedPrimaryKey != null) {
                      key = generatedPrimaryKey;
                      req2.keys[i] = key;
                      if (!primaryKey.outbound) {
                        setByKeyPath(req2.values[i], primaryKey.keyPath, key);
                      }
                    }
                  } else {
                    const objectDiff = getObjectDiff(existingValue, req2.values[i]);
                    const additionalChanges = updating.fire.call(ctx, objectDiff, key, existingValue, dxTrans2);
                    if (additionalChanges) {
                      const requestedValue = req2.values[i];
                      Object.keys(additionalChanges).forEach((keyPath) => {
                        if (hasOwn(requestedValue, keyPath)) {
                          requestedValue[keyPath] = additionalChanges[keyPath];
                        } else {
                          setByKeyPath(requestedValue, keyPath, additionalChanges[keyPath]);
                        }
                      });
                    }
                  }
                  return ctx;
                });
                return downTable.mutate(req2).then(({ failures, results, numFailures, lastResult }) => {
                  for (let i = 0; i < keys2.length; ++i) {
                    const primKey = results ? results[i] : keys2[i];
                    const ctx = contexts[i];
                    if (primKey == null) {
                      ctx.onerror && ctx.onerror(failures[i]);
                    } else {
                      ctx.onsuccess && ctx.onsuccess(
                        req2.type === "put" && existingValues[i] ? req2.values[i] : primKey
                      );
                    }
                  }
                  return { failures, results, numFailures, lastResult };
                }).catch((error) => {
                  contexts.forEach((ctx) => ctx.onerror && ctx.onerror(error));
                  return Promise.reject(error);
                });
              });
            }
            function deleteRange(req2) {
              return deleteNextChunk(req2.trans, req2.range, 1e4);
            }
            function deleteNextChunk(trans, range, limit) {
              return downTable.query({ trans, values: false, query: { index: primaryKey, range }, limit }).then(({ result }) => {
                return addPutOrDelete({ type: "delete", keys: result, trans }).then((res) => {
                  if (res.numFailures > 0)
                    return Promise.reject(res.failures[0]);
                  if (result.length < limit) {
                    return { failures: [], numFailures: 0, lastResult: void 0 };
                  } else {
                    return deleteNextChunk(trans, { ...range, lower: result[result.length - 1], lowerOpen: true }, limit);
                  }
                });
              });
            }
          }
        };
        return tableMiddleware;
      }
    })
  };
  function getExistingValues(table, req, effectiveKeys) {
    return req.type === "add" ? Promise.resolve([]) : table.getMany({ trans: req.trans, keys: effectiveKeys, cache: "immutable" });
  }
  function getFromTransactionCache(keys2, cache, clone) {
    try {
      if (!cache)
        return null;
      if (cache.keys.length < keys2.length)
        return null;
      const result = [];
      for (let i = 0, j = 0; i < cache.keys.length && j < keys2.length; ++i) {
        if (cmp(cache.keys[i], keys2[j]) !== 0)
          continue;
        result.push(clone ? deepClone(cache.values[i]) : cache.values[i]);
        ++j;
      }
      return result.length === keys2.length ? result : null;
    } catch (_a) {
      return null;
    }
  }
  var cacheExistingValuesMiddleware = {
    stack: "dbcore",
    level: -1,
    create: (core) => {
      return {
        table: (tableName) => {
          const table = core.table(tableName);
          return {
            ...table,
            getMany: (req) => {
              if (!req.cache) {
                return table.getMany(req);
              }
              const cachedResult = getFromTransactionCache(req.keys, req.trans["_cache"], req.cache === "clone");
              if (cachedResult) {
                return DexiePromise.resolve(cachedResult);
              }
              return table.getMany(req).then((res) => {
                req.trans["_cache"] = {
                  keys: req.keys,
                  values: req.cache === "clone" ? deepClone(res) : res
                };
                return res;
              });
            },
            mutate: (req) => {
              if (req.type !== "add")
                req.trans["_cache"] = null;
              return table.mutate(req);
            }
          };
        }
      };
    }
  };
  function isEmptyRange(node) {
    return !("from" in node);
  }
  var RangeSet = function(fromOrTree, to) {
    if (this) {
      extend(this, arguments.length ? { d: 1, from: fromOrTree, to: arguments.length > 1 ? to : fromOrTree } : { d: 0 });
    } else {
      const rv = new RangeSet();
      if (fromOrTree && "d" in fromOrTree) {
        extend(rv, fromOrTree);
      }
      return rv;
    }
  };
  props(RangeSet.prototype, {
    add(rangeSet) {
      mergeRanges(this, rangeSet);
      return this;
    },
    addKey(key) {
      addRange(this, key, key);
      return this;
    },
    addKeys(keys2) {
      keys2.forEach((key) => addRange(this, key, key));
      return this;
    },
    [iteratorSymbol]() {
      return getRangeSetIterator(this);
    }
  });
  function addRange(target, from, to) {
    const diff = cmp(from, to);
    if (isNaN(diff))
      return;
    if (diff > 0)
      throw RangeError();
    if (isEmptyRange(target))
      return extend(target, { from, to, d: 1 });
    const left = target.l;
    const right = target.r;
    if (cmp(to, target.from) < 0) {
      left ? addRange(left, from, to) : target.l = { from, to, d: 1, l: null, r: null };
      return rebalance(target);
    }
    if (cmp(from, target.to) > 0) {
      right ? addRange(right, from, to) : target.r = { from, to, d: 1, l: null, r: null };
      return rebalance(target);
    }
    if (cmp(from, target.from) < 0) {
      target.from = from;
      target.l = null;
      target.d = right ? right.d + 1 : 1;
    }
    if (cmp(to, target.to) > 0) {
      target.to = to;
      target.r = null;
      target.d = target.l ? target.l.d + 1 : 1;
    }
    const rightWasCutOff = !target.r;
    if (left && !target.l) {
      mergeRanges(target, left);
    }
    if (right && rightWasCutOff) {
      mergeRanges(target, right);
    }
  }
  function mergeRanges(target, newSet) {
    function _addRangeSet(target2, { from, to, l, r }) {
      addRange(target2, from, to);
      if (l)
        _addRangeSet(target2, l);
      if (r)
        _addRangeSet(target2, r);
    }
    if (!isEmptyRange(newSet))
      _addRangeSet(target, newSet);
  }
  function rangesOverlap(rangeSet1, rangeSet2) {
    const i1 = getRangeSetIterator(rangeSet2);
    let nextResult1 = i1.next();
    if (nextResult1.done)
      return false;
    let a = nextResult1.value;
    const i2 = getRangeSetIterator(rangeSet1);
    let nextResult2 = i2.next(a.from);
    let b = nextResult2.value;
    while (!nextResult1.done && !nextResult2.done) {
      if (cmp(b.from, a.to) <= 0 && cmp(b.to, a.from) >= 0)
        return true;
      cmp(a.from, b.from) < 0 ? a = (nextResult1 = i1.next(b.from)).value : b = (nextResult2 = i2.next(a.from)).value;
    }
    return false;
  }
  function getRangeSetIterator(node) {
    let state = isEmptyRange(node) ? null : { s: 0, n: node };
    return {
      next(key) {
        const keyProvided = arguments.length > 0;
        while (state) {
          switch (state.s) {
            case 0:
              state.s = 1;
              if (keyProvided) {
                while (state.n.l && cmp(key, state.n.from) < 0)
                  state = { up: state, n: state.n.l, s: 1 };
              } else {
                while (state.n.l)
                  state = { up: state, n: state.n.l, s: 1 };
              }
            case 1:
              state.s = 2;
              if (!keyProvided || cmp(key, state.n.to) <= 0)
                return { value: state.n, done: false };
            case 2:
              if (state.n.r) {
                state.s = 3;
                state = { up: state, n: state.n.r, s: 0 };
                continue;
              }
            case 3:
              state = state.up;
          }
        }
        return { done: true };
      }
    };
  }
  function rebalance(target) {
    var _a, _b;
    const diff = (((_a = target.r) === null || _a === void 0 ? void 0 : _a.d) || 0) - (((_b = target.l) === null || _b === void 0 ? void 0 : _b.d) || 0);
    const r = diff > 1 ? "r" : diff < -1 ? "l" : "";
    if (r) {
      const l = r === "r" ? "l" : "r";
      const rootClone = { ...target };
      const oldRootRight = target[r];
      target.from = oldRootRight.from;
      target.to = oldRootRight.to;
      target[r] = oldRootRight[r];
      rootClone[r] = oldRootRight[l];
      target[l] = rootClone;
      rootClone.d = computeDepth(rootClone);
    }
    target.d = computeDepth(target);
  }
  function computeDepth({ r, l }) {
    return (r ? l ? Math.max(r.d, l.d) : r.d : l ? l.d : 0) + 1;
  }
  var observabilityMiddleware = {
    stack: "dbcore",
    level: 0,
    create: (core) => {
      const dbName = core.schema.name;
      const FULL_RANGE = new RangeSet(core.MIN_KEY, core.MAX_KEY);
      return {
        ...core,
        table: (tableName) => {
          const table = core.table(tableName);
          const { schema } = table;
          const { primaryKey } = schema;
          const { extractKey, outbound } = primaryKey;
          const tableClone = {
            ...table,
            mutate: (req) => {
              const trans = req.trans;
              const mutatedParts = trans.mutatedParts || (trans.mutatedParts = {});
              const getRangeSet = (indexName) => {
                const part = `idb://${dbName}/${tableName}/${indexName}`;
                return mutatedParts[part] || (mutatedParts[part] = new RangeSet());
              };
              const pkRangeSet = getRangeSet("");
              const delsRangeSet = getRangeSet(":dels");
              const { type: type2 } = req;
              let [keys2, newObjs] = req.type === "deleteRange" ? [req.range] : req.type === "delete" ? [req.keys] : req.values.length < 50 ? [[], req.values] : [];
              const oldCache = req.trans["_cache"];
              return table.mutate(req).then((res) => {
                if (isArray2(keys2)) {
                  if (type2 !== "delete")
                    keys2 = res.results;
                  pkRangeSet.addKeys(keys2);
                  const oldObjs = getFromTransactionCache(keys2, oldCache);
                  if (!oldObjs && type2 !== "add") {
                    delsRangeSet.addKeys(keys2);
                  }
                  if (oldObjs || newObjs) {
                    trackAffectedIndexes(getRangeSet, schema, oldObjs, newObjs);
                  }
                } else if (keys2) {
                  const range = { from: keys2.lower, to: keys2.upper };
                  delsRangeSet.add(range);
                  pkRangeSet.add(range);
                } else {
                  pkRangeSet.add(FULL_RANGE);
                  delsRangeSet.add(FULL_RANGE);
                  schema.indexes.forEach((idx) => getRangeSet(idx.name).add(FULL_RANGE));
                }
                return res;
              });
            }
          };
          const getRange = ({ query: { index, range } }) => {
            var _a, _b;
            return [
              index,
              new RangeSet((_a = range.lower) !== null && _a !== void 0 ? _a : core.MIN_KEY, (_b = range.upper) !== null && _b !== void 0 ? _b : core.MAX_KEY)
            ];
          };
          const readSubscribers = {
            get: (req) => [primaryKey, new RangeSet(req.key)],
            getMany: (req) => [primaryKey, new RangeSet().addKeys(req.keys)],
            count: getRange,
            query: getRange,
            openCursor: getRange
          };
          keys(readSubscribers).forEach((method) => {
            tableClone[method] = function(req) {
              const { subscr } = PSD;
              if (subscr) {
                const getRangeSet = (indexName) => {
                  const part = `idb://${dbName}/${tableName}/${indexName}`;
                  return subscr[part] || (subscr[part] = new RangeSet());
                };
                const pkRangeSet = getRangeSet("");
                const delsRangeSet = getRangeSet(":dels");
                const [queriedIndex, queriedRanges] = readSubscribers[method](req);
                getRangeSet(queriedIndex.name || "").add(queriedRanges);
                if (!queriedIndex.isPrimaryKey) {
                  if (method === "count") {
                    delsRangeSet.add(FULL_RANGE);
                  } else {
                    const keysPromise = method === "query" && outbound && req.values && table.query({
                      ...req,
                      values: false
                    });
                    return table[method].apply(this, arguments).then((res) => {
                      if (method === "query") {
                        if (outbound && req.values) {
                          return keysPromise.then(({ result: resultingKeys }) => {
                            pkRangeSet.addKeys(resultingKeys);
                            return res;
                          });
                        }
                        const pKeys = req.values ? res.result.map(extractKey) : res.result;
                        if (req.values) {
                          pkRangeSet.addKeys(pKeys);
                        } else {
                          delsRangeSet.addKeys(pKeys);
                        }
                      } else if (method === "openCursor") {
                        const cursor = res;
                        const wantValues = req.values;
                        return cursor && Object.create(cursor, {
                          key: {
                            get() {
                              delsRangeSet.addKey(cursor.primaryKey);
                              return cursor.key;
                            }
                          },
                          primaryKey: {
                            get() {
                              const pkey = cursor.primaryKey;
                              delsRangeSet.addKey(pkey);
                              return pkey;
                            }
                          },
                          value: {
                            get() {
                              wantValues && pkRangeSet.addKey(cursor.primaryKey);
                              return cursor.value;
                            }
                          }
                        });
                      }
                      return res;
                    });
                  }
                }
              }
              return table[method].apply(this, arguments);
            };
          });
          return tableClone;
        }
      };
    }
  };
  function trackAffectedIndexes(getRangeSet, schema, oldObjs, newObjs) {
    function addAffectedIndex(ix) {
      const rangeSet = getRangeSet(ix.name || "");
      function extractKey(obj) {
        return obj != null ? ix.extractKey(obj) : null;
      }
      const addKeyOrKeys = (key) => ix.multiEntry && isArray2(key) ? key.forEach((key2) => rangeSet.addKey(key2)) : rangeSet.addKey(key);
      (oldObjs || newObjs).forEach((_, i) => {
        const oldKey = oldObjs && extractKey(oldObjs[i]);
        const newKey = newObjs && extractKey(newObjs[i]);
        if (cmp(oldKey, newKey) !== 0) {
          if (oldKey != null)
            addKeyOrKeys(oldKey);
          if (newKey != null)
            addKeyOrKeys(newKey);
        }
      });
    }
    schema.indexes.forEach(addAffectedIndex);
  }
  var Dexie$1 = class _Dexie$1 {
    constructor(name, options) {
      this._middlewares = {};
      this.verno = 0;
      const deps = _Dexie$1.dependencies;
      this._options = options = {
        addons: _Dexie$1.addons,
        autoOpen: true,
        indexedDB: deps.indexedDB,
        IDBKeyRange: deps.IDBKeyRange,
        ...options
      };
      this._deps = {
        indexedDB: options.indexedDB,
        IDBKeyRange: options.IDBKeyRange
      };
      const { addons } = options;
      this._dbSchema = {};
      this._versions = [];
      this._storeNames = [];
      this._allTables = {};
      this.idbdb = null;
      this._novip = this;
      const state = {
        dbOpenError: null,
        isBeingOpened: false,
        onReadyBeingFired: null,
        openComplete: false,
        dbReadyResolve: nop,
        dbReadyPromise: null,
        cancelOpen: nop,
        openCanceller: null,
        autoSchema: true,
        PR1398_maxLoop: 3
      };
      state.dbReadyPromise = new DexiePromise((resolve) => {
        state.dbReadyResolve = resolve;
      });
      state.openCanceller = new DexiePromise((_, reject) => {
        state.cancelOpen = reject;
      });
      this._state = state;
      this.name = name;
      this.on = Events(this, "populate", "blocked", "versionchange", "close", { ready: [promisableChain, nop] });
      this.on.ready.subscribe = override(this.on.ready.subscribe, (subscribe) => {
        return (subscriber, bSticky) => {
          _Dexie$1.vip(() => {
            const state2 = this._state;
            if (state2.openComplete) {
              if (!state2.dbOpenError)
                DexiePromise.resolve().then(subscriber);
              if (bSticky)
                subscribe(subscriber);
            } else if (state2.onReadyBeingFired) {
              state2.onReadyBeingFired.push(subscriber);
              if (bSticky)
                subscribe(subscriber);
            } else {
              subscribe(subscriber);
              const db2 = this;
              if (!bSticky)
                subscribe(function unsubscribe() {
                  db2.on.ready.unsubscribe(subscriber);
                  db2.on.ready.unsubscribe(unsubscribe);
                });
            }
          });
        };
      });
      this.Collection = createCollectionConstructor(this);
      this.Table = createTableConstructor(this);
      this.Transaction = createTransactionConstructor(this);
      this.Version = createVersionConstructor(this);
      this.WhereClause = createWhereClauseConstructor(this);
      this.on("versionchange", (ev) => {
        if (ev.newVersion > 0)
          console.warn(`Another connection wants to upgrade database '${this.name}'. Closing db now to resume the upgrade.`);
        else
          console.warn(`Another connection wants to delete database '${this.name}'. Closing db now to resume the delete request.`);
        this.close();
      });
      this.on("blocked", (ev) => {
        if (!ev.newVersion || ev.newVersion < ev.oldVersion)
          console.warn(`Dexie.delete('${this.name}') was blocked`);
        else
          console.warn(`Upgrade '${this.name}' blocked by other connection holding version ${ev.oldVersion / 10}`);
      });
      this._maxKey = getMaxKey(options.IDBKeyRange);
      this._createTransaction = (mode, storeNames, dbschema, parentTransaction) => new this.Transaction(mode, storeNames, dbschema, this._options.chromeTransactionDurability, parentTransaction);
      this._fireOnBlocked = (ev) => {
        this.on("blocked").fire(ev);
        connections.filter((c) => c.name === this.name && c !== this && !c._state.vcFired).map((c) => c.on("versionchange").fire(ev));
      };
      this.use(virtualIndexMiddleware);
      this.use(hooksMiddleware);
      this.use(observabilityMiddleware);
      this.use(cacheExistingValuesMiddleware);
      this.vip = Object.create(this, { _vip: { value: true } });
      addons.forEach((addon) => addon(this));
    }
    version(versionNumber) {
      if (isNaN(versionNumber) || versionNumber < 0.1)
        throw new exceptions.Type(`Given version is not a positive number`);
      versionNumber = Math.round(versionNumber * 10) / 10;
      if (this.idbdb || this._state.isBeingOpened)
        throw new exceptions.Schema("Cannot add version when database is open");
      this.verno = Math.max(this.verno, versionNumber);
      const versions = this._versions;
      var versionInstance = versions.filter((v) => v._cfg.version === versionNumber)[0];
      if (versionInstance)
        return versionInstance;
      versionInstance = new this.Version(versionNumber);
      versions.push(versionInstance);
      versions.sort(lowerVersionFirst);
      versionInstance.stores({});
      this._state.autoSchema = false;
      return versionInstance;
    }
    _whenReady(fn) {
      return this.idbdb && (this._state.openComplete || PSD.letThrough || this._vip) ? fn() : new DexiePromise((resolve, reject) => {
        if (this._state.openComplete) {
          return reject(new exceptions.DatabaseClosed(this._state.dbOpenError));
        }
        if (!this._state.isBeingOpened) {
          if (!this._options.autoOpen) {
            reject(new exceptions.DatabaseClosed());
            return;
          }
          this.open().catch(nop);
        }
        this._state.dbReadyPromise.then(resolve, reject);
      }).then(fn);
    }
    use({ stack, create, level, name }) {
      if (name)
        this.unuse({ stack, name });
      const middlewares = this._middlewares[stack] || (this._middlewares[stack] = []);
      middlewares.push({ stack, create, level: level == null ? 10 : level, name });
      middlewares.sort((a, b) => a.level - b.level);
      return this;
    }
    unuse({ stack, name, create }) {
      if (stack && this._middlewares[stack]) {
        this._middlewares[stack] = this._middlewares[stack].filter((mw) => create ? mw.create !== create : name ? mw.name !== name : false);
      }
      return this;
    }
    open() {
      return dexieOpen(this);
    }
    _close() {
      const state = this._state;
      const idx = connections.indexOf(this);
      if (idx >= 0)
        connections.splice(idx, 1);
      if (this.idbdb) {
        try {
          this.idbdb.close();
        } catch (e) {
        }
        this._novip.idbdb = null;
      }
      state.dbReadyPromise = new DexiePromise((resolve) => {
        state.dbReadyResolve = resolve;
      });
      state.openCanceller = new DexiePromise((_, reject) => {
        state.cancelOpen = reject;
      });
    }
    close() {
      this._close();
      const state = this._state;
      this._options.autoOpen = false;
      state.dbOpenError = new exceptions.DatabaseClosed();
      if (state.isBeingOpened)
        state.cancelOpen(state.dbOpenError);
    }
    delete() {
      const hasArguments = arguments.length > 0;
      const state = this._state;
      return new DexiePromise((resolve, reject) => {
        const doDelete = () => {
          this.close();
          var req = this._deps.indexedDB.deleteDatabase(this.name);
          req.onsuccess = wrap(() => {
            _onDatabaseDeleted(this._deps, this.name);
            resolve();
          });
          req.onerror = eventRejectHandler(reject);
          req.onblocked = this._fireOnBlocked;
        };
        if (hasArguments)
          throw new exceptions.InvalidArgument("Arguments not allowed in db.delete()");
        if (state.isBeingOpened) {
          state.dbReadyPromise.then(doDelete);
        } else {
          doDelete();
        }
      });
    }
    backendDB() {
      return this.idbdb;
    }
    isOpen() {
      return this.idbdb !== null;
    }
    hasBeenClosed() {
      const dbOpenError = this._state.dbOpenError;
      return dbOpenError && dbOpenError.name === "DatabaseClosed";
    }
    hasFailed() {
      return this._state.dbOpenError !== null;
    }
    dynamicallyOpened() {
      return this._state.autoSchema;
    }
    get tables() {
      return keys(this._allTables).map((name) => this._allTables[name]);
    }
    transaction() {
      const args = extractTransactionArgs.apply(this, arguments);
      return this._transaction.apply(this, args);
    }
    _transaction(mode, tables, scopeFunc) {
      let parentTransaction = PSD.trans;
      if (!parentTransaction || parentTransaction.db !== this || mode.indexOf("!") !== -1)
        parentTransaction = null;
      const onlyIfCompatible = mode.indexOf("?") !== -1;
      mode = mode.replace("!", "").replace("?", "");
      let idbMode, storeNames;
      try {
        storeNames = tables.map((table) => {
          var storeName = table instanceof this.Table ? table.name : table;
          if (typeof storeName !== "string")
            throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed");
          return storeName;
        });
        if (mode == "r" || mode === READONLY)
          idbMode = READONLY;
        else if (mode == "rw" || mode == READWRITE)
          idbMode = READWRITE;
        else
          throw new exceptions.InvalidArgument("Invalid transaction mode: " + mode);
        if (parentTransaction) {
          if (parentTransaction.mode === READONLY && idbMode === READWRITE) {
            if (onlyIfCompatible) {
              parentTransaction = null;
            } else
              throw new exceptions.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY");
          }
          if (parentTransaction) {
            storeNames.forEach((storeName) => {
              if (parentTransaction && parentTransaction.storeNames.indexOf(storeName) === -1) {
                if (onlyIfCompatible) {
                  parentTransaction = null;
                } else
                  throw new exceptions.SubTransaction("Table " + storeName + " not included in parent transaction.");
              }
            });
          }
          if (onlyIfCompatible && parentTransaction && !parentTransaction.active) {
            parentTransaction = null;
          }
        }
      } catch (e) {
        return parentTransaction ? parentTransaction._promise(null, (_, reject) => {
          reject(e);
        }) : rejection(e);
      }
      const enterTransaction = enterTransactionScope.bind(null, this, idbMode, storeNames, parentTransaction, scopeFunc);
      return parentTransaction ? parentTransaction._promise(idbMode, enterTransaction, "lock") : PSD.trans ? usePSD(PSD.transless, () => this._whenReady(enterTransaction)) : this._whenReady(enterTransaction);
    }
    table(tableName) {
      if (!hasOwn(this._allTables, tableName)) {
        throw new exceptions.InvalidTable(`Table ${tableName} does not exist`);
      }
      return this._allTables[tableName];
    }
  };
  var symbolObservable = typeof Symbol !== "undefined" && "observable" in Symbol ? Symbol.observable : "@@observable";
  var Observable = class {
    constructor(subscribe) {
      this._subscribe = subscribe;
    }
    subscribe(x, error, complete) {
      return this._subscribe(!x || typeof x === "function" ? { next: x, error, complete } : x);
    }
    [symbolObservable]() {
      return this;
    }
  };
  function extendObservabilitySet(target, newSet) {
    keys(newSet).forEach((part) => {
      const rangeSet = target[part] || (target[part] = new RangeSet());
      mergeRanges(rangeSet, newSet[part]);
    });
    return target;
  }
  function liveQuery(querier) {
    let hasValue = false;
    let currentValue = void 0;
    const observable = new Observable((observer) => {
      const scopeFuncIsAsync = isAsyncFunction(querier);
      function execute(subscr) {
        if (scopeFuncIsAsync) {
          incrementExpectedAwaits();
        }
        const exec = () => newScope(querier, { subscr, trans: null });
        const rv = PSD.trans ? usePSD(PSD.transless, exec) : exec();
        if (scopeFuncIsAsync) {
          rv.then(decrementExpectedAwaits, decrementExpectedAwaits);
        }
        return rv;
      }
      let closed = false;
      let accumMuts = {};
      let currentObs = {};
      const subscription = {
        get closed() {
          return closed;
        },
        unsubscribe: () => {
          closed = true;
          globalEvents.storagemutated.unsubscribe(mutationListener);
        }
      };
      observer.start && observer.start(subscription);
      let querying = false, startedListening = false;
      function shouldNotify() {
        return keys(currentObs).some((key) => accumMuts[key] && rangesOverlap(accumMuts[key], currentObs[key]));
      }
      const mutationListener = (parts) => {
        extendObservabilitySet(accumMuts, parts);
        if (shouldNotify()) {
          doQuery();
        }
      };
      const doQuery = () => {
        if (querying || closed)
          return;
        accumMuts = {};
        const subscr = {};
        const ret = execute(subscr);
        if (!startedListening) {
          globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, mutationListener);
          startedListening = true;
        }
        querying = true;
        Promise.resolve(ret).then((result) => {
          hasValue = true;
          currentValue = result;
          querying = false;
          if (closed)
            return;
          if (shouldNotify()) {
            doQuery();
          } else {
            accumMuts = {};
            currentObs = subscr;
            observer.next && observer.next(result);
          }
        }, (err) => {
          querying = false;
          hasValue = false;
          observer.error && observer.error(err);
          subscription.unsubscribe();
        });
      };
      doQuery();
      return subscription;
    });
    observable.hasValue = () => hasValue;
    observable.getValue = () => currentValue;
    return observable;
  }
  var domDeps;
  try {
    domDeps = {
      indexedDB: _global.indexedDB || _global.mozIndexedDB || _global.webkitIndexedDB || _global.msIndexedDB,
      IDBKeyRange: _global.IDBKeyRange || _global.webkitIDBKeyRange
    };
  } catch (e) {
    domDeps = { indexedDB: null, IDBKeyRange: null };
  }
  var Dexie = Dexie$1;
  props(Dexie, {
    ...fullNameExceptions,
    delete(databaseName) {
      const db2 = new Dexie(databaseName, { addons: [] });
      return db2.delete();
    },
    exists(name) {
      return new Dexie(name, { addons: [] }).open().then((db2) => {
        db2.close();
        return true;
      }).catch("NoSuchDatabaseError", () => false);
    },
    getDatabaseNames(cb) {
      try {
        return getDatabaseNames(Dexie.dependencies).then(cb);
      } catch (_a) {
        return rejection(new exceptions.MissingAPI());
      }
    },
    defineClass() {
      function Class(content) {
        extend(this, content);
      }
      return Class;
    },
    ignoreTransaction(scopeFunc) {
      return PSD.trans ? usePSD(PSD.transless, scopeFunc) : scopeFunc();
    },
    vip,
    async: function(generatorFn) {
      return function() {
        try {
          var rv = awaitIterator(generatorFn.apply(this, arguments));
          if (!rv || typeof rv.then !== "function")
            return DexiePromise.resolve(rv);
          return rv;
        } catch (e) {
          return rejection(e);
        }
      };
    },
    spawn: function(generatorFn, args, thiz) {
      try {
        var rv = awaitIterator(generatorFn.apply(thiz, args || []));
        if (!rv || typeof rv.then !== "function")
          return DexiePromise.resolve(rv);
        return rv;
      } catch (e) {
        return rejection(e);
      }
    },
    currentTransaction: {
      get: () => PSD.trans || null
    },
    waitFor: function(promiseOrFunction, optionalTimeout) {
      const promise = DexiePromise.resolve(typeof promiseOrFunction === "function" ? Dexie.ignoreTransaction(promiseOrFunction) : promiseOrFunction).timeout(optionalTimeout || 6e4);
      return PSD.trans ? PSD.trans.waitFor(promise) : promise;
    },
    Promise: DexiePromise,
    debug: {
      get: () => debug,
      set: (value) => {
        setDebug(value, value === "dexie" ? () => true : dexieStackFrameFilter);
      }
    },
    derive,
    extend,
    props,
    override,
    Events,
    on: globalEvents,
    liveQuery,
    extendObservabilitySet,
    getByKeyPath,
    setByKeyPath,
    delByKeyPath,
    shallowClone,
    deepClone,
    getObjectDiff,
    cmp,
    asap: asap$1,
    minKey,
    addons: [],
    connections,
    errnames,
    dependencies: domDeps,
    semVer: DEXIE_VERSION,
    version: DEXIE_VERSION.split(".").map((n) => parseInt(n)).reduce((p, c, i) => p + c / Math.pow(10, i * 2))
  });
  Dexie.maxKey = getMaxKey(Dexie.dependencies.IDBKeyRange);
  if (typeof dispatchEvent !== "undefined" && typeof addEventListener !== "undefined") {
    globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (updatedParts) => {
      if (!propagatingLocally) {
        let event;
        if (isIEOrEdge) {
          event = document.createEvent("CustomEvent");
          event.initCustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, true, true, updatedParts);
        } else {
          event = new CustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, {
            detail: updatedParts
          });
        }
        propagatingLocally = true;
        dispatchEvent(event);
        propagatingLocally = false;
      }
    });
    addEventListener(STORAGE_MUTATED_DOM_EVENT_NAME, ({ detail }) => {
      if (!propagatingLocally) {
        propagateLocally(detail);
      }
    });
  }
  function propagateLocally(updateParts) {
    let wasMe = propagatingLocally;
    try {
      propagatingLocally = true;
      globalEvents.storagemutated.fire(updateParts);
    } finally {
      propagatingLocally = wasMe;
    }
  }
  var propagatingLocally = false;
  if (typeof BroadcastChannel !== "undefined") {
    const bc = new BroadcastChannel(STORAGE_MUTATED_DOM_EVENT_NAME);
    if (typeof bc.unref === "function") {
      bc.unref();
    }
    globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (changedParts) => {
      if (!propagatingLocally) {
        bc.postMessage(changedParts);
      }
    });
    bc.onmessage = (ev) => {
      if (ev.data)
        propagateLocally(ev.data);
    };
  } else if (typeof self !== "undefined" && typeof navigator !== "undefined") {
    globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, (changedParts) => {
      try {
        if (!propagatingLocally) {
          if (typeof localStorage !== "undefined") {
            localStorage.setItem(STORAGE_MUTATED_DOM_EVENT_NAME, JSON.stringify({
              trig: Math.random(),
              changedParts
            }));
          }
          if (typeof self["clients"] === "object") {
            [...self["clients"].matchAll({ includeUncontrolled: true })].forEach((client) => client.postMessage({
              type: STORAGE_MUTATED_DOM_EVENT_NAME,
              changedParts
            }));
          }
        }
      } catch (_a) {
      }
    });
    if (typeof addEventListener !== "undefined") {
      addEventListener("storage", (ev) => {
        if (ev.key === STORAGE_MUTATED_DOM_EVENT_NAME) {
          const data = JSON.parse(ev.newValue);
          if (data)
            propagateLocally(data.changedParts);
        }
      });
    }
    const swContainer = self.document && navigator.serviceWorker;
    if (swContainer) {
      swContainer.addEventListener("message", propagateMessageLocally);
    }
  }
  function propagateMessageLocally({ data }) {
    if (data && data.type === STORAGE_MUTATED_DOM_EVENT_NAME) {
      propagateLocally(data.changedParts);
    }
  }
  DexiePromise.rejectionMapper = mapError;
  setDebug(debug, dexieStackFrameFilter);
  function shareSameDomainSuffix(hostname, vhost) {
    if (hostname.endsWith(vhost)) {
      return hostname.length === vhost.length || hostname[hostname.length - vhost.length - 1] === ".";
    }
    return false;
  }
  function extractDomainWithSuffix(hostname, publicSuffix) {
    const publicSuffixIndex = hostname.length - publicSuffix.length - 2;
    const lastDotBeforeSuffixIndex = hostname.lastIndexOf(".", publicSuffixIndex);
    if (lastDotBeforeSuffixIndex === -1) {
      return hostname;
    }
    return hostname.slice(lastDotBeforeSuffixIndex + 1);
  }
  function getDomain(suffix, hostname, options) {
    if (options.validHosts !== null) {
      const validHosts = options.validHosts;
      for (const vhost of validHosts) {
        if (shareSameDomainSuffix(hostname, vhost)) {
          return vhost;
        }
      }
    }
    let numberOfLeadingDots = 0;
    if (hostname.startsWith(".")) {
      while (numberOfLeadingDots < hostname.length && hostname[numberOfLeadingDots] === ".") {
        numberOfLeadingDots += 1;
      }
    }
    if (suffix.length === hostname.length - numberOfLeadingDots) {
      return null;
    }
    return extractDomainWithSuffix(hostname, suffix);
  }
  function getDomainWithoutSuffix(domain, suffix) {
    return domain.slice(0, -suffix.length - 1);
  }
  function extractHostname(url, urlIsValidHostname) {
    let start = 0;
    let end = url.length;
    let hasUpper = false;
    if (!urlIsValidHostname) {
      if (url.startsWith("data:")) {
        return null;
      }
      while (start < url.length && url.charCodeAt(start) <= 32) {
        start += 1;
      }
      while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {
        end -= 1;
      }
      if (url.charCodeAt(start) === 47 && url.charCodeAt(start + 1) === 47) {
        start += 2;
      } else {
        const indexOfProtocol = url.indexOf(":/", start);
        if (indexOfProtocol !== -1) {
          const protocolSize = indexOfProtocol - start;
          const c0 = url.charCodeAt(start);
          const c1 = url.charCodeAt(start + 1);
          const c2 = url.charCodeAt(start + 2);
          const c3 = url.charCodeAt(start + 3);
          const c4 = url.charCodeAt(start + 4);
          if (protocolSize === 5 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112 && c4 === 115) {
          } else if (protocolSize === 4 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112) {
          } else if (protocolSize === 3 && c0 === 119 && c1 === 115 && c2 === 115) {
          } else if (protocolSize === 2 && c0 === 119 && c1 === 115) {
          } else {
            for (let i = start; i < indexOfProtocol; i += 1) {
              const lowerCaseCode = url.charCodeAt(i) | 32;
              if (!(lowerCaseCode >= 97 && lowerCaseCode <= 122 || lowerCaseCode >= 48 && lowerCaseCode <= 57 || lowerCaseCode === 46 || lowerCaseCode === 45 || lowerCaseCode === 43)) {
                return null;
              }
            }
          }
          start = indexOfProtocol + 2;
          while (url.charCodeAt(start) === 47) {
            start += 1;
          }
        }
      }
      let indexOfIdentifier = -1;
      let indexOfClosingBracket = -1;
      let indexOfPort = -1;
      for (let i = start; i < end; i += 1) {
        const code = url.charCodeAt(i);
        if (code === 35 || code === 47 || code === 63) {
          end = i;
          break;
        } else if (code === 64) {
          indexOfIdentifier = i;
        } else if (code === 93) {
          indexOfClosingBracket = i;
        } else if (code === 58) {
          indexOfPort = i;
        } else if (code >= 65 && code <= 90) {
          hasUpper = true;
        }
      }
      if (indexOfIdentifier !== -1 && indexOfIdentifier > start && indexOfIdentifier < end) {
        start = indexOfIdentifier + 1;
      }
      if (url.charCodeAt(start) === 91) {
        if (indexOfClosingBracket !== -1) {
          return url.slice(start + 1, indexOfClosingBracket).toLowerCase();
        }
        return null;
      } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) {
        end = indexOfPort;
      }
    }
    while (end > start + 1 && url.charCodeAt(end - 1) === 46) {
      end -= 1;
    }
    const hostname = start !== 0 || end !== url.length ? url.slice(start, end) : url;
    if (hasUpper) {
      return hostname.toLowerCase();
    }
    return hostname;
  }
  function isProbablyIpv4(hostname) {
    if (hostname.length < 7) {
      return false;
    }
    if (hostname.length > 15) {
      return false;
    }
    let numberOfDots = 0;
    for (let i = 0; i < hostname.length; i += 1) {
      const code = hostname.charCodeAt(i);
      if (code === 46) {
        numberOfDots += 1;
      } else if (code < 48 || code > 57) {
        return false;
      }
    }
    return numberOfDots === 3 && hostname.charCodeAt(0) !== 46 && hostname.charCodeAt(hostname.length - 1) !== 46;
  }
  function isProbablyIpv6(hostname) {
    if (hostname.length < 3) {
      return false;
    }
    let start = hostname.startsWith("[") ? 1 : 0;
    let end = hostname.length;
    if (hostname[end - 1] === "]") {
      end -= 1;
    }
    if (end - start > 39) {
      return false;
    }
    let hasColon = false;
    for (; start < end; start += 1) {
      const code = hostname.charCodeAt(start);
      if (code === 58) {
        hasColon = true;
      } else if (!(code >= 48 && code <= 57 || code >= 97 && code <= 102 || code >= 65 && code <= 90)) {
        return false;
      }
    }
    return hasColon;
  }
  function isIp(hostname) {
    return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);
  }
  function isValidAscii(code) {
    return code >= 97 && code <= 122 || code >= 48 && code <= 57 || code > 127;
  }
  function is_valid_default(hostname) {
    if (hostname.length > 255) {
      return false;
    }
    if (hostname.length === 0) {
      return false;
    }
    if (!isValidAscii(hostname.charCodeAt(0)) && hostname.charCodeAt(0) !== 46 && hostname.charCodeAt(0) !== 95) {
      return false;
    }
    let lastDotIndex = -1;
    let lastCharCode = -1;
    const len = hostname.length;
    for (let i = 0; i < len; i += 1) {
      const code = hostname.charCodeAt(i);
      if (code === 46) {
        if (i - lastDotIndex > 64 || lastCharCode === 46 || lastCharCode === 45 || lastCharCode === 95) {
          return false;
        }
        lastDotIndex = i;
      } else if (!(isValidAscii(code) || code === 45 || code === 95)) {
        return false;
      }
      lastCharCode = code;
    }
    return len - lastDotIndex - 1 <= 63 && lastCharCode !== 45;
  }
  function setDefaultsImpl({
    allowIcannDomains = true,
    allowPrivateDomains = false,
    detectIp = true,
    extractHostname: extractHostname2 = true,
    mixedInputs = true,
    validHosts = null,
    validateHostname = true
  }) {
    return {
      allowIcannDomains,
      allowPrivateDomains,
      detectIp,
      extractHostname: extractHostname2,
      mixedInputs,
      validHosts,
      validateHostname
    };
  }
  var DEFAULT_OPTIONS = setDefaultsImpl({});
  function setDefaults(options) {
    if (options === void 0) {
      return DEFAULT_OPTIONS;
    }
    return setDefaultsImpl(options);
  }
  function getSubdomain(hostname, domain) {
    if (domain.length === hostname.length) {
      return "";
    }
    return hostname.slice(0, -domain.length - 1);
  }
  function getEmptyResult() {
    return {
      domain: null,
      domainWithoutSuffix: null,
      hostname: null,
      isIcann: null,
      isIp: null,
      isPrivate: null,
      publicSuffix: null,
      subdomain: null
    };
  }
  function resetResult(result) {
    result.domain = null;
    result.domainWithoutSuffix = null;
    result.hostname = null;
    result.isIcann = null;
    result.isIp = null;
    result.isPrivate = null;
    result.publicSuffix = null;
    result.subdomain = null;
  }
  function parseImpl(url, step, suffixLookup2, partialOptions, result) {
    const options = setDefaults(partialOptions);
    if (typeof url !== "string") {
      return result;
    }
    if (!options.extractHostname) {
      result.hostname = url;
    } else if (options.mixedInputs) {
      result.hostname = extractHostname(url, is_valid_default(url));
    } else {
      result.hostname = extractHostname(url, false);
    }
    if (options.detectIp && result.hostname !== null) {
      result.isIp = isIp(result.hostname);
      if (result.isIp) {
        return result;
      }
    }
    if (options.validateHostname && options.extractHostname && result.hostname !== null && !is_valid_default(result.hostname)) {
      result.hostname = null;
      return result;
    }
    if (step === 0 || result.hostname === null) {
      return result;
    }
    suffixLookup2(result.hostname, options, result);
    if (step === 2 || result.publicSuffix === null) {
      return result;
    }
    result.domain = getDomain(result.publicSuffix, result.hostname, options);
    if (step === 3 || result.domain === null) {
      return result;
    }
    result.subdomain = getSubdomain(result.hostname, result.domain);
    if (step === 4) {
      return result;
    }
    result.domainWithoutSuffix = getDomainWithoutSuffix(result.domain, result.publicSuffix);
    return result;
  }
  function fast_path_default(hostname, options, out) {
    if (!options.allowPrivateDomains && hostname.length > 3) {
      const last = hostname.length - 1;
      const c3 = hostname.charCodeAt(last);
      const c2 = hostname.charCodeAt(last - 1);
      const c1 = hostname.charCodeAt(last - 2);
      const c0 = hostname.charCodeAt(last - 3);
      if (c3 === 109 && c2 === 111 && c1 === 99 && c0 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "com";
        return true;
      } else if (c3 === 103 && c2 === 114 && c1 === 111 && c0 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "org";
        return true;
      } else if (c3 === 117 && c2 === 100 && c1 === 101 && c0 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "edu";
        return true;
      } else if (c3 === 118 && c2 === 111 && c1 === 103 && c0 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "gov";
        return true;
      } else if (c3 === 116 && c2 === 101 && c1 === 110 && c0 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "net";
        return true;
      } else if (c3 === 101 && c2 === 100 && c1 === 46) {
        out.isIcann = true;
        out.isPrivate = false;
        out.publicSuffix = "de";
        return true;
      }
    }
    return false;
  }
  var exceptions2 =  (function() {
    const _0 = [1, {}], _1 = [0, {
      "city": _0
    }];
    const exceptions3 = [0, {
      "ck": [0, {
        "www": _0
      }],
      "jp": [0, {
        "kawasaki": _1,
        "kitakyushu": _1,
        "kobe": _1,
        "nagoya": _1,
        "sapporo": _1,
        "sendai": _1,
        "yokohama": _1
      }]
    }];
    return exceptions3;
  })();
  var rules =  (function() {
    const _2 = [1, {}], _3 = [2, {}], _4 = [1, {
      "com": _2,
      "edu": _2,
      "gov": _2,
      "net": _2,
      "org": _2
    }], _5 = [1, {
      "com": _2,
      "edu": _2,
      "gov": _2,
      "mil": _2,
      "net": _2,
      "org": _2
    }], _6 = [0, {
      "*": _3
    }], _7 = [2, {
      "s": _6
    }], _8 = [0, {
      "relay": _3
    }], _9 = [2, {
      "id": _3
    }], _10 = [1, {
      "gov": _2
    }], _11 = [0, {
      "airflow": _6,
      "transfer-webapp": _3
    }], _12 = [0, {
      "transfer-webapp": _3,
      "transfer-webapp-fips": _3
    }], _13 = [0, {
      "notebook": _3,
      "studio": _3
    }], _14 = [0, {
      "labeling": _3,
      "notebook": _3,
      "studio": _3
    }], _15 = [0, {
      "notebook": _3
    }], _16 = [0, {
      "labeling": _3,
      "notebook": _3,
      "notebook-fips": _3,
      "studio": _3
    }], _17 = [0, {
      "notebook": _3,
      "notebook-fips": _3,
      "studio": _3,
      "studio-fips": _3
    }], _18 = [0, {
      "*": _2
    }], _19 = [1, {
      "co": _3
    }], _20 = [0, {
      "objects": _3
    }], _21 = [2, {
      "nodes": _3
    }], _22 = [0, {
      "my": _3
    }], _23 = [0, {
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-website": _3
    }], _24 = [0, {
      "s3": _3,
      "s3-accesspoint": _3
    }], _25 = [0, {
      "direct": _3
    }], _26 = [0, {
      "webview-assets": _3
    }], _27 = [0, {
      "vfs": _3,
      "webview-assets": _3
    }], _28 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _23,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-object-lambda": _3,
      "s3-website": _3,
      "aws-cloud9": _26,
      "cloud9": _27
    }], _29 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _24,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-object-lambda": _3,
      "s3-website": _3,
      "aws-cloud9": _26,
      "cloud9": _27
    }], _30 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _23,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-object-lambda": _3,
      "s3-website": _3,
      "analytics-gateway": _3,
      "aws-cloud9": _26,
      "cloud9": _27
    }], _31 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _23,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-object-lambda": _3,
      "s3-website": _3
    }], _32 = [0, {
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-accesspoint-fips": _3,
      "s3-fips": _3,
      "s3-website": _3
    }], _33 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _32,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-accesspoint-fips": _3,
      "s3-fips": _3,
      "s3-object-lambda": _3,
      "s3-website": _3,
      "aws-cloud9": _26,
      "cloud9": _27
    }], _34 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _32,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-accesspoint-fips": _3,
      "s3-deprecated": _3,
      "s3-fips": _3,
      "s3-object-lambda": _3,
      "s3-website": _3,
      "analytics-gateway": _3,
      "aws-cloud9": _26,
      "cloud9": _27
    }], _35 = [0, {
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-accesspoint-fips": _3,
      "s3-fips": _3
    }], _36 = [0, {
      "execute-api": _3,
      "emrappui-prod": _3,
      "emrnotebooks-prod": _3,
      "emrstudio-prod": _3,
      "dualstack": _35,
      "s3": _3,
      "s3-accesspoint": _3,
      "s3-accesspoint-fips": _3,
      "s3-fips": _3,
      "s3-object-lambda": _3,
      "s3-website": _3
    }], _37 = [0, {
      "auth": _3
    }], _38 = [0, {
      "auth": _3,
      "auth-fips": _3
    }], _39 = [0, {
      "auth-fips": _3
    }], _40 = [0, {
      "apps": _3
    }], _41 = [0, {
      "paas": _3
    }], _42 = [2, {
      "eu": _3
    }], _43 = [0, {
      "app": _3
    }], _44 = [0, {
      "site": _3
    }], _45 = [1, {
      "com": _2,
      "edu": _2,
      "net": _2,
      "org": _2
    }], _46 = [0, {
      "j": _3
    }], _47 = [0, {
      "dyn": _3
    }], _48 = [2, {
      "web": _3
    }], _49 = [1, {
      "co": _2,
      "com": _2,
      "edu": _2,
      "gov": _2,
      "net": _2,
      "org": _2
    }], _50 = [0, {
      "p": _3
    }], _51 = [0, {
      "user": _3
    }], _52 = [0, {
      "shop": _3
    }], _53 = [0, {
      "cdn": _3
    }], _54 = [2, {
      "raw": _6
    }], _55 = [0, {
      "cust": _3,
      "reservd": _3
    }], _56 = [0, {
      "cust": _3
    }], _57 = [0, {
      "s3": _3
    }], _58 = [1, {
      "biz": _2,
      "com": _2,
      "edu": _2,
      "gov": _2,
      "info": _2,
      "net": _2,
      "org": _2
    }], _59 = [0, {
      "ipfs": _3
    }], _60 = [1, {
      "framer": _3
    }], _61 = [0, {
      "forgot": _3
    }], _62 = [1, {
      "gs": _2
    }], _63 = [0, {
      "nes": _2
    }], _64 = [1, {
      "k12": _2,
      "cc": _2,
      "lib": _2
    }], _65 = [1, {
      "cc": _2,
      "lib": _2
    }];
    const rules2 = [0, {
      "ac": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "drr": _3,
        "feedback": _3,
        "forms": _3
      }],
      "ad": _2,
      "ae": [1, {
        "ac": _2,
        "co": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "sch": _2
      }],
      "aero": [1, {
        "airline": _2,
        "airport": _2,
        "accident-investigation": _2,
        "accident-prevention": _2,
        "aerobatic": _2,
        "aeroclub": _2,
        "aerodrome": _2,
        "agents": _2,
        "air-surveillance": _2,
        "air-traffic-control": _2,
        "aircraft": _2,
        "airtraffic": _2,
        "ambulance": _2,
        "association": _2,
        "author": _2,
        "ballooning": _2,
        "broker": _2,
        "caa": _2,
        "cargo": _2,
        "catering": _2,
        "certification": _2,
        "championship": _2,
        "charter": _2,
        "civilaviation": _2,
        "club": _2,
        "conference": _2,
        "consultant": _2,
        "consulting": _2,
        "control": _2,
        "council": _2,
        "crew": _2,
        "design": _2,
        "dgca": _2,
        "educator": _2,
        "emergency": _2,
        "engine": _2,
        "engineer": _2,
        "entertainment": _2,
        "equipment": _2,
        "exchange": _2,
        "express": _2,
        "federation": _2,
        "flight": _2,
        "freight": _2,
        "fuel": _2,
        "gliding": _2,
        "government": _2,
        "groundhandling": _2,
        "group": _2,
        "hanggliding": _2,
        "homebuilt": _2,
        "insurance": _2,
        "journal": _2,
        "journalist": _2,
        "leasing": _2,
        "logistics": _2,
        "magazine": _2,
        "maintenance": _2,
        "marketplace": _2,
        "media": _2,
        "microlight": _2,
        "modelling": _2,
        "navigation": _2,
        "parachuting": _2,
        "paragliding": _2,
        "passenger-association": _2,
        "pilot": _2,
        "press": _2,
        "production": _2,
        "recreation": _2,
        "repbody": _2,
        "res": _2,
        "research": _2,
        "rotorcraft": _2,
        "safety": _2,
        "scientist": _2,
        "services": _2,
        "show": _2,
        "skydiving": _2,
        "software": _2,
        "student": _2,
        "taxi": _2,
        "trader": _2,
        "trading": _2,
        "trainer": _2,
        "union": _2,
        "workinggroup": _2,
        "works": _2
      }],
      "af": _4,
      "ag": [1, {
        "co": _2,
        "com": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "obj": _3
      }],
      "ai": [1, {
        "com": _2,
        "net": _2,
        "off": _2,
        "org": _2,
        "uwu": _3,
        "framer": _3
      }],
      "al": _5,
      "am": [1, {
        "co": _2,
        "com": _2,
        "commune": _2,
        "net": _2,
        "org": _2,
        "radio": _3
      }],
      "ao": [1, {
        "co": _2,
        "ed": _2,
        "edu": _2,
        "gov": _2,
        "gv": _2,
        "it": _2,
        "og": _2,
        "org": _2,
        "pb": _2
      }],
      "aq": _2,
      "ar": [1, {
        "bet": _2,
        "com": _2,
        "coop": _2,
        "edu": _2,
        "gob": _2,
        "gov": _2,
        "int": _2,
        "mil": _2,
        "musica": _2,
        "mutual": _2,
        "net": _2,
        "org": _2,
        "seg": _2,
        "senasa": _2,
        "tur": _2
      }],
      "arpa": [1, {
        "e164": _2,
        "home": _2,
        "in-addr": _2,
        "ip6": _2,
        "iris": _2,
        "uri": _2,
        "urn": _2
      }],
      "as": _10,
      "asia": [1, {
        "cloudns": _3,
        "daemon": _3,
        "dix": _3
      }],
      "at": [1, {
        "4": _3,
        "ac": [1, {
          "sth": _2
        }],
        "co": _2,
        "gv": _2,
        "or": _2,
        "funkfeuer": [0, {
          "wien": _3
        }],
        "futurecms": [0, {
          "*": _3,
          "ex": _6,
          "in": _6
        }],
        "futurehosting": _3,
        "futuremailing": _3,
        "ortsinfo": [0, {
          "ex": _6,
          "kunden": _6
        }],
        "biz": _3,
        "info": _3,
        "123webseite": _3,
        "priv": _3,
        "my": _3,
        "myspreadshop": _3,
        "12hp": _3,
        "2ix": _3,
        "4lima": _3,
        "lima-city": _3
      }],
      "au": [1, {
        "asn": _2,
        "com": [1, {
          "cloudlets": [0, {
            "mel": _3
          }],
          "myspreadshop": _3
        }],
        "edu": [1, {
          "act": _2,
          "catholic": _2,
          "nsw": [1, {
            "schools": _2
          }],
          "nt": _2,
          "qld": _2,
          "sa": _2,
          "tas": _2,
          "vic": _2,
          "wa": _2
        }],
        "gov": [1, {
          "qld": _2,
          "sa": _2,
          "tas": _2,
          "vic": _2,
          "wa": _2
        }],
        "id": _2,
        "net": _2,
        "org": _2,
        "conf": _2,
        "oz": _2,
        "act": _2,
        "nsw": _2,
        "nt": _2,
        "qld": _2,
        "sa": _2,
        "tas": _2,
        "vic": _2,
        "wa": _2
      }],
      "aw": [1, {
        "com": _2
      }],
      "ax": _2,
      "az": [1, {
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "int": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pp": _2,
        "pro": _2
      }],
      "ba": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "rs": _3
      }],
      "bb": [1, {
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "net": _2,
        "org": _2,
        "store": _2,
        "tv": _2
      }],
      "bd": _18,
      "be": [1, {
        "ac": _2,
        "cloudns": _3,
        "webhosting": _3,
        "interhostsolutions": [0, {
          "cloud": _3
        }],
        "kuleuven": [0, {
          "ezproxy": _3
        }],
        "123website": _3,
        "myspreadshop": _3,
        "transurl": _6
      }],
      "bf": _10,
      "bg": [1, {
        "0": _2,
        "1": _2,
        "2": _2,
        "3": _2,
        "4": _2,
        "5": _2,
        "6": _2,
        "7": _2,
        "8": _2,
        "9": _2,
        "a": _2,
        "b": _2,
        "c": _2,
        "d": _2,
        "e": _2,
        "f": _2,
        "g": _2,
        "h": _2,
        "i": _2,
        "j": _2,
        "k": _2,
        "l": _2,
        "m": _2,
        "n": _2,
        "o": _2,
        "p": _2,
        "q": _2,
        "r": _2,
        "s": _2,
        "t": _2,
        "u": _2,
        "v": _2,
        "w": _2,
        "x": _2,
        "y": _2,
        "z": _2,
        "barsy": _3
      }],
      "bh": _4,
      "bi": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "or": _2,
        "org": _2
      }],
      "biz": [1, {
        "activetrail": _3,
        "cloud-ip": _3,
        "cloudns": _3,
        "jozi": _3,
        "dyndns": _3,
        "for-better": _3,
        "for-more": _3,
        "for-some": _3,
        "for-the": _3,
        "selfip": _3,
        "webhop": _3,
        "orx": _3,
        "mmafan": _3,
        "myftp": _3,
        "no-ip": _3,
        "dscloud": _3
      }],
      "bj": [1, {
        "africa": _2,
        "agro": _2,
        "architectes": _2,
        "assur": _2,
        "avocats": _2,
        "co": _2,
        "com": _2,
        "eco": _2,
        "econo": _2,
        "edu": _2,
        "info": _2,
        "loisirs": _2,
        "money": _2,
        "net": _2,
        "org": _2,
        "ote": _2,
        "restaurant": _2,
        "resto": _2,
        "tourism": _2,
        "univ": _2
      }],
      "bm": _4,
      "bn": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "co": _3
      }],
      "bo": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "int": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "tv": _2,
        "web": _2,
        "academia": _2,
        "agro": _2,
        "arte": _2,
        "blog": _2,
        "bolivia": _2,
        "ciencia": _2,
        "cooperativa": _2,
        "democracia": _2,
        "deporte": _2,
        "ecologia": _2,
        "economia": _2,
        "empresa": _2,
        "indigena": _2,
        "industria": _2,
        "info": _2,
        "medicina": _2,
        "movimiento": _2,
        "musica": _2,
        "natural": _2,
        "nombre": _2,
        "noticias": _2,
        "patria": _2,
        "plurinacional": _2,
        "politica": _2,
        "profesional": _2,
        "pueblo": _2,
        "revista": _2,
        "salud": _2,
        "tecnologia": _2,
        "tksat": _2,
        "transporte": _2,
        "wiki": _2
      }],
      "br": [1, {
        "9guacu": _2,
        "abc": _2,
        "adm": _2,
        "adv": _2,
        "agr": _2,
        "aju": _2,
        "am": _2,
        "anani": _2,
        "aparecida": _2,
        "app": _2,
        "arq": _2,
        "art": _2,
        "ato": _2,
        "b": _2,
        "barueri": _2,
        "belem": _2,
        "bet": _2,
        "bhz": _2,
        "bib": _2,
        "bio": _2,
        "blog": _2,
        "bmd": _2,
        "boavista": _2,
        "bsb": _2,
        "campinagrande": _2,
        "campinas": _2,
        "caxias": _2,
        "cim": _2,
        "cng": _2,
        "cnt": _2,
        "com": [1, {
          "simplesite": _3
        }],
        "contagem": _2,
        "coop": _2,
        "coz": _2,
        "cri": _2,
        "cuiaba": _2,
        "curitiba": _2,
        "def": _2,
        "des": _2,
        "det": _2,
        "dev": _2,
        "ecn": _2,
        "eco": _2,
        "edu": _2,
        "emp": _2,
        "enf": _2,
        "eng": _2,
        "esp": _2,
        "etc": _2,
        "eti": _2,
        "far": _2,
        "feira": _2,
        "flog": _2,
        "floripa": _2,
        "fm": _2,
        "fnd": _2,
        "fortal": _2,
        "fot": _2,
        "foz": _2,
        "fst": _2,
        "g12": _2,
        "geo": _2,
        "ggf": _2,
        "goiania": _2,
        "gov": [1, {
          "ac": _2,
          "al": _2,
          "am": _2,
          "ap": _2,
          "ba": _2,
          "ce": _2,
          "df": _2,
          "es": _2,
          "go": _2,
          "ma": _2,
          "mg": _2,
          "ms": _2,
          "mt": _2,
          "pa": _2,
          "pb": _2,
          "pe": _2,
          "pi": _2,
          "pr": _2,
          "rj": _2,
          "rn": _2,
          "ro": _2,
          "rr": _2,
          "rs": _2,
          "sc": _2,
          "se": _2,
          "sp": _2,
          "to": _2
        }],
        "gru": _2,
        "imb": _2,
        "ind": _2,
        "inf": _2,
        "jab": _2,
        "jampa": _2,
        "jdf": _2,
        "joinville": _2,
        "jor": _2,
        "jus": _2,
        "leg": [1, {
          "ac": _3,
          "al": _3,
          "am": _3,
          "ap": _3,
          "ba": _3,
          "ce": _3,
          "df": _3,
          "es": _3,
          "go": _3,
          "ma": _3,
          "mg": _3,
          "ms": _3,
          "mt": _3,
          "pa": _3,
          "pb": _3,
          "pe": _3,
          "pi": _3,
          "pr": _3,
          "rj": _3,
          "rn": _3,
          "ro": _3,
          "rr": _3,
          "rs": _3,
          "sc": _3,
          "se": _3,
          "sp": _3,
          "to": _3
        }],
        "leilao": _2,
        "lel": _2,
        "log": _2,
        "londrina": _2,
        "macapa": _2,
        "maceio": _2,
        "manaus": _2,
        "maringa": _2,
        "mat": _2,
        "med": _2,
        "mil": _2,
        "morena": _2,
        "mp": _2,
        "mus": _2,
        "natal": _2,
        "net": _2,
        "niteroi": _2,
        "nom": _18,
        "not": _2,
        "ntr": _2,
        "odo": _2,
        "ong": _2,
        "org": _2,
        "osasco": _2,
        "palmas": _2,
        "poa": _2,
        "ppg": _2,
        "pro": _2,
        "psc": _2,
        "psi": _2,
        "pvh": _2,
        "qsl": _2,
        "radio": _2,
        "rec": _2,
        "recife": _2,
        "rep": _2,
        "ribeirao": _2,
        "rio": _2,
        "riobranco": _2,
        "riopreto": _2,
        "salvador": _2,
        "sampa": _2,
        "santamaria": _2,
        "santoandre": _2,
        "saobernardo": _2,
        "saogonca": _2,
        "seg": _2,
        "sjc": _2,
        "slg": _2,
        "slz": _2,
        "sorocaba": _2,
        "srv": _2,
        "taxi": _2,
        "tc": _2,
        "tec": _2,
        "teo": _2,
        "the": _2,
        "tmp": _2,
        "trd": _2,
        "tur": _2,
        "tv": _2,
        "udi": _2,
        "vet": _2,
        "vix": _2,
        "vlog": _2,
        "wiki": _2,
        "zlg": _2,
        "tche": _3
      }],
      "bs": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "we": _3
      }],
      "bt": _4,
      "bv": _2,
      "bw": [1, {
        "ac": _2,
        "co": _2,
        "gov": _2,
        "net": _2,
        "org": _2
      }],
      "by": [1, {
        "gov": _2,
        "mil": _2,
        "com": _2,
        "of": _2,
        "mediatech": _3
      }],
      "bz": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "za": _3,
        "mydns": _3,
        "gsj": _3
      }],
      "ca": [1, {
        "ab": _2,
        "bc": _2,
        "mb": _2,
        "nb": _2,
        "nf": _2,
        "nl": _2,
        "ns": _2,
        "nt": _2,
        "nu": _2,
        "on": _2,
        "pe": _2,
        "qc": _2,
        "sk": _2,
        "yk": _2,
        "gc": _2,
        "barsy": _3,
        "awdev": _6,
        "co": _3,
        "no-ip": _3,
        "onid": _3,
        "myspreadshop": _3,
        "box": _3
      }],
      "cat": _2,
      "cc": [1, {
        "cleverapps": _3,
        "cloudns": _3,
        "ftpaccess": _3,
        "game-server": _3,
        "myphotos": _3,
        "scrapping": _3,
        "twmail": _3,
        "csx": _3,
        "fantasyleague": _3,
        "spawn": [0, {
          "instances": _3
        }]
      }],
      "cd": _10,
      "cf": _2,
      "cg": _2,
      "ch": [1, {
        "square7": _3,
        "cloudns": _3,
        "cloudscale": [0, {
          "cust": _3,
          "lpg": _20,
          "rma": _20
        }],
        "objectstorage": [0, {
          "lpg": _3,
          "rma": _3
        }],
        "flow": [0, {
          "ae": [0, {
            "alp1": _3
          }],
          "appengine": _3
        }],
        "linkyard-cloud": _3,
        "gotdns": _3,
        "dnsking": _3,
        "123website": _3,
        "myspreadshop": _3,
        "firenet": [0, {
          "*": _3,
          "svc": _6
        }],
        "12hp": _3,
        "2ix": _3,
        "4lima": _3,
        "lima-city": _3
      }],
      "ci": [1, {
        "ac": _2,
        "xn--aroport-bya": _2,
        "aéroport": _2,
        "asso": _2,
        "co": _2,
        "com": _2,
        "ed": _2,
        "edu": _2,
        "go": _2,
        "gouv": _2,
        "int": _2,
        "net": _2,
        "or": _2,
        "org": _2
      }],
      "ck": _18,
      "cl": [1, {
        "co": _2,
        "gob": _2,
        "gov": _2,
        "mil": _2,
        "cloudns": _3
      }],
      "cm": [1, {
        "co": _2,
        "com": _2,
        "gov": _2,
        "net": _2
      }],
      "cn": [1, {
        "ac": _2,
        "com": [1, {
          "amazonaws": [0, {
            "cn-north-1": [0, {
              "execute-api": _3,
              "emrappui-prod": _3,
              "emrnotebooks-prod": _3,
              "emrstudio-prod": _3,
              "dualstack": _23,
              "s3": _3,
              "s3-accesspoint": _3,
              "s3-deprecated": _3,
              "s3-object-lambda": _3,
              "s3-website": _3
            }],
            "cn-northwest-1": [0, {
              "execute-api": _3,
              "emrappui-prod": _3,
              "emrnotebooks-prod": _3,
              "emrstudio-prod": _3,
              "dualstack": _24,
              "s3": _3,
              "s3-accesspoint": _3,
              "s3-object-lambda": _3,
              "s3-website": _3
            }],
            "compute": _6,
            "airflow": [0, {
              "cn-north-1": _6,
              "cn-northwest-1": _6
            }],
            "eb": [0, {
              "cn-north-1": _3,
              "cn-northwest-1": _3
            }],
            "elb": _6
          }],
          "amazonwebservices": [0, {
            "on": [0, {
              "cn-north-1": _11,
              "cn-northwest-1": _11
            }]
          }],
          "sagemaker": [0, {
            "cn-north-1": _13,
            "cn-northwest-1": _13
          }]
        }],
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "xn--55qx5d": _2,
        "公司": _2,
        "xn--od0alg": _2,
        "網絡": _2,
        "xn--io0a7i": _2,
        "网络": _2,
        "ah": _2,
        "bj": _2,
        "cq": _2,
        "fj": _2,
        "gd": _2,
        "gs": _2,
        "gx": _2,
        "gz": _2,
        "ha": _2,
        "hb": _2,
        "he": _2,
        "hi": _2,
        "hk": _2,
        "hl": _2,
        "hn": _2,
        "jl": _2,
        "js": _2,
        "jx": _2,
        "ln": _2,
        "mo": _2,
        "nm": _2,
        "nx": _2,
        "qh": _2,
        "sc": _2,
        "sd": _2,
        "sh": [1, {
          "as": _3
        }],
        "sn": _2,
        "sx": _2,
        "tj": _2,
        "tw": _2,
        "xj": _2,
        "xz": _2,
        "yn": _2,
        "zj": _2,
        "canva-apps": _3,
        "canvasite": _22,
        "myqnapcloud": _3,
        "quickconnect": _25
      }],
      "co": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "carrd": _3,
        "crd": _3,
        "otap": _6,
        "hidns": _3,
        "leadpages": _3,
        "lpages": _3,
        "mypi": _3,
        "xmit": _6,
        "firewalledreplit": _9,
        "repl": _9,
        "supabase": _3
      }],
      "com": [1, {
        "a2hosted": _3,
        "cpserver": _3,
        "adobeaemcloud": [2, {
          "dev": _6
        }],
        "africa": _3,
        "airkitapps": _3,
        "airkitapps-au": _3,
        "aivencloud": _3,
        "alibabacloudcs": _3,
        "kasserver": _3,
        "amazonaws": [0, {
          "af-south-1": _28,
          "ap-east-1": _29,
          "ap-northeast-1": _30,
          "ap-northeast-2": _30,
          "ap-northeast-3": _28,
          "ap-south-1": _30,
          "ap-south-2": _31,
          "ap-southeast-1": _30,
          "ap-southeast-2": _30,
          "ap-southeast-3": _31,
          "ap-southeast-4": _31,
          "ap-southeast-5": [0, {
            "execute-api": _3,
            "dualstack": _23,
            "s3": _3,
            "s3-accesspoint": _3,
            "s3-deprecated": _3,
            "s3-object-lambda": _3,
            "s3-website": _3
          }],
          "ca-central-1": _33,
          "ca-west-1": [0, {
            "execute-api": _3,
            "emrappui-prod": _3,
            "emrnotebooks-prod": _3,
            "emrstudio-prod": _3,
            "dualstack": _32,
            "s3": _3,
            "s3-accesspoint": _3,
            "s3-accesspoint-fips": _3,
            "s3-fips": _3,
            "s3-object-lambda": _3,
            "s3-website": _3
          }],
          "eu-central-1": _30,
          "eu-central-2": _31,
          "eu-north-1": _29,
          "eu-south-1": _28,
          "eu-south-2": _31,
          "eu-west-1": [0, {
            "execute-api": _3,
            "emrappui-prod": _3,
            "emrnotebooks-prod": _3,
            "emrstudio-prod": _3,
            "dualstack": _23,
            "s3": _3,
            "s3-accesspoint": _3,
            "s3-deprecated": _3,
            "s3-object-lambda": _3,
            "s3-website": _3,
            "analytics-gateway": _3,
            "aws-cloud9": _26,
            "cloud9": _27
          }],
          "eu-west-2": _29,
          "eu-west-3": _28,
          "il-central-1": [0, {
            "execute-api": _3,
            "emrappui-prod": _3,
            "emrnotebooks-prod": _3,
            "emrstudio-prod": _3,
            "dualstack": _23,
            "s3": _3,
            "s3-accesspoint": _3,
            "s3-object-lambda": _3,
            "s3-website": _3,
            "aws-cloud9": _26,
            "cloud9": [0, {
              "vfs": _3
            }]
          }],
          "me-central-1": _31,
          "me-south-1": _29,
          "sa-east-1": _28,
          "us-east-1": [2, {
            "execute-api": _3,
            "emrappui-prod": _3,
            "emrnotebooks-prod": _3,
            "emrstudio-prod": _3,
            "dualstack": _32,
            "s3": _3,
            "s3-accesspoint": _3,
            "s3-accesspoint-fips": _3,
            "s3-deprecated": _3,
            "s3-fips": _3,
            "s3-object-lambda": _3,
            "s3-website": _3,
            "analytics-gateway": _3,
            "aws-cloud9": _26,
            "cloud9": _27
          }],
          "us-east-2": _34,
          "us-gov-east-1": _36,
          "us-gov-west-1": _36,
          "us-west-1": _33,
          "us-west-2": _34,
          "compute": _6,
          "compute-1": _6,
          "airflow": [0, {
            "af-south-1": _6,
            "ap-east-1": _6,
            "ap-northeast-1": _6,
            "ap-northeast-2": _6,
            "ap-northeast-3": _6,
            "ap-south-1": _6,
            "ap-south-2": _6,
            "ap-southeast-1": _6,
            "ap-southeast-2": _6,
            "ap-southeast-3": _6,
            "ap-southeast-4": _6,
            "ap-southeast-5": _6,
            "ca-central-1": _6,
            "ca-west-1": _6,
            "eu-central-1": _6,
            "eu-central-2": _6,
            "eu-north-1": _6,
            "eu-south-1": _6,
            "eu-south-2": _6,
            "eu-west-1": _6,
            "eu-west-2": _6,
            "eu-west-3": _6,
            "il-central-1": _6,
            "me-central-1": _6,
            "me-south-1": _6,
            "sa-east-1": _6,
            "us-east-1": _6,
            "us-east-2": _6,
            "us-west-1": _6,
            "us-west-2": _6
          }],
          "s3": _3,
          "s3-1": _3,
          "s3-ap-east-1": _3,
          "s3-ap-northeast-1": _3,
          "s3-ap-northeast-2": _3,
          "s3-ap-northeast-3": _3,
          "s3-ap-south-1": _3,
          "s3-ap-southeast-1": _3,
          "s3-ap-southeast-2": _3,
          "s3-ca-central-1": _3,
          "s3-eu-central-1": _3,
          "s3-eu-north-1": _3,
          "s3-eu-west-1": _3,
          "s3-eu-west-2": _3,
          "s3-eu-west-3": _3,
          "s3-external-1": _3,
          "s3-fips-us-gov-east-1": _3,
          "s3-fips-us-gov-west-1": _3,
          "s3-global": [0, {
            "accesspoint": [0, {
              "mrap": _3
            }]
          }],
          "s3-me-south-1": _3,
          "s3-sa-east-1": _3,
          "s3-us-east-2": _3,
          "s3-us-gov-east-1": _3,
          "s3-us-gov-west-1": _3,
          "s3-us-west-1": _3,
          "s3-us-west-2": _3,
          "s3-website-ap-northeast-1": _3,
          "s3-website-ap-southeast-1": _3,
          "s3-website-ap-southeast-2": _3,
          "s3-website-eu-west-1": _3,
          "s3-website-sa-east-1": _3,
          "s3-website-us-east-1": _3,
          "s3-website-us-gov-west-1": _3,
          "s3-website-us-west-1": _3,
          "s3-website-us-west-2": _3,
          "elb": _6
        }],
        "amazoncognito": [0, {
          "af-south-1": _37,
          "ap-east-1": _37,
          "ap-northeast-1": _37,
          "ap-northeast-2": _37,
          "ap-northeast-3": _37,
          "ap-south-1": _37,
          "ap-south-2": _37,
          "ap-southeast-1": _37,
          "ap-southeast-2": _37,
          "ap-southeast-3": _37,
          "ap-southeast-4": _37,
          "ap-southeast-5": _37,
          "ap-southeast-7": _37,
          "ca-central-1": _37,
          "ca-west-1": _37,
          "eu-central-1": _37,
          "eu-central-2": _37,
          "eu-north-1": _37,
          "eu-south-1": _37,
          "eu-south-2": _37,
          "eu-west-1": _37,
          "eu-west-2": _37,
          "eu-west-3": _37,
          "il-central-1": _37,
          "me-central-1": _37,
          "me-south-1": _37,
          "mx-central-1": _37,
          "sa-east-1": _37,
          "us-east-1": _38,
          "us-east-2": _38,
          "us-gov-east-1": _39,
          "us-gov-west-1": _39,
          "us-west-1": _38,
          "us-west-2": _38
        }],
        "amplifyapp": _3,
        "awsapprunner": _6,
        "awsapps": _3,
        "elasticbeanstalk": [2, {
          "af-south-1": _3,
          "ap-east-1": _3,
          "ap-northeast-1": _3,
          "ap-northeast-2": _3,
          "ap-northeast-3": _3,
          "ap-south-1": _3,
          "ap-southeast-1": _3,
          "ap-southeast-2": _3,
          "ap-southeast-3": _3,
          "ca-central-1": _3,
          "eu-central-1": _3,
          "eu-north-1": _3,
          "eu-south-1": _3,
          "eu-west-1": _3,
          "eu-west-2": _3,
          "eu-west-3": _3,
          "il-central-1": _3,
          "me-south-1": _3,
          "sa-east-1": _3,
          "us-east-1": _3,
          "us-east-2": _3,
          "us-gov-east-1": _3,
          "us-gov-west-1": _3,
          "us-west-1": _3,
          "us-west-2": _3
        }],
        "awsglobalaccelerator": _3,
        "siiites": _3,
        "appspacehosted": _3,
        "appspaceusercontent": _3,
        "on-aptible": _3,
        "myasustor": _3,
        "balena-devices": _3,
        "boutir": _3,
        "bplaced": _3,
        "cafjs": _3,
        "canva-apps": _3,
        "cdn77-storage": _3,
        "br": _3,
        "cn": _3,
        "de": _3,
        "eu": _3,
        "jpn": _3,
        "mex": _3,
        "ru": _3,
        "sa": _3,
        "uk": _3,
        "us": _3,
        "za": _3,
        "clever-cloud": [0, {
          "services": _6
        }],
        "dnsabr": _3,
        "ip-ddns": _3,
        "jdevcloud": _3,
        "wpdevcloud": _3,
        "cf-ipfs": _3,
        "cloudflare-ipfs": _3,
        "trycloudflare": _3,
        "co": _3,
        "devinapps": _6,
        "builtwithdark": _3,
        "datadetect": [0, {
          "demo": _3,
          "instance": _3
        }],
        "dattolocal": _3,
        "dattorelay": _3,
        "dattoweb": _3,
        "mydatto": _3,
        "digitaloceanspaces": _6,
        "discordsays": _3,
        "discordsez": _3,
        "drayddns": _3,
        "dreamhosters": _3,
        "durumis": _3,
        "mydrobo": _3,
        "blogdns": _3,
        "cechire": _3,
        "dnsalias": _3,
        "dnsdojo": _3,
        "doesntexist": _3,
        "dontexist": _3,
        "doomdns": _3,
        "dyn-o-saur": _3,
        "dynalias": _3,
        "dyndns-at-home": _3,
        "dyndns-at-work": _3,
        "dyndns-blog": _3,
        "dyndns-free": _3,
        "dyndns-home": _3,
        "dyndns-ip": _3,
        "dyndns-mail": _3,
        "dyndns-office": _3,
        "dyndns-pics": _3,
        "dyndns-remote": _3,
        "dyndns-server": _3,
        "dyndns-web": _3,
        "dyndns-wiki": _3,
        "dyndns-work": _3,
        "est-a-la-maison": _3,
        "est-a-la-masion": _3,
        "est-le-patron": _3,
        "est-mon-blogueur": _3,
        "from-ak": _3,
        "from-al": _3,
        "from-ar": _3,
        "from-ca": _3,
        "from-ct": _3,
        "from-dc": _3,
        "from-de": _3,
        "from-fl": _3,
        "from-ga": _3,
        "from-hi": _3,
        "from-ia": _3,
        "from-id": _3,
        "from-il": _3,
        "from-in": _3,
        "from-ks": _3,
        "from-ky": _3,
        "from-ma": _3,
        "from-md": _3,
        "from-mi": _3,
        "from-mn": _3,
        "from-mo": _3,
        "from-ms": _3,
        "from-mt": _3,
        "from-nc": _3,
        "from-nd": _3,
        "from-ne": _3,
        "from-nh": _3,
        "from-nj": _3,
        "from-nm": _3,
        "from-nv": _3,
        "from-oh": _3,
        "from-ok": _3,
        "from-or": _3,
        "from-pa": _3,
        "from-pr": _3,
        "from-ri": _3,
        "from-sc": _3,
        "from-sd": _3,
        "from-tn": _3,
        "from-tx": _3,
        "from-ut": _3,
        "from-va": _3,
        "from-vt": _3,
        "from-wa": _3,
        "from-wi": _3,
        "from-wv": _3,
        "from-wy": _3,
        "getmyip": _3,
        "gotdns": _3,
        "hobby-site": _3,
        "homelinux": _3,
        "homeunix": _3,
        "iamallama": _3,
        "is-a-anarchist": _3,
        "is-a-blogger": _3,
        "is-a-bookkeeper": _3,
        "is-a-bulls-fan": _3,
        "is-a-caterer": _3,
        "is-a-chef": _3,
        "is-a-conservative": _3,
        "is-a-cpa": _3,
        "is-a-cubicle-slave": _3,
        "is-a-democrat": _3,
        "is-a-designer": _3,
        "is-a-doctor": _3,
        "is-a-financialadvisor": _3,
        "is-a-geek": _3,
        "is-a-green": _3,
        "is-a-guru": _3,
        "is-a-hard-worker": _3,
        "is-a-hunter": _3,
        "is-a-landscaper": _3,
        "is-a-lawyer": _3,
        "is-a-liberal": _3,
        "is-a-libertarian": _3,
        "is-a-llama": _3,
        "is-a-musician": _3,
        "is-a-nascarfan": _3,
        "is-a-nurse": _3,
        "is-a-painter": _3,
        "is-a-personaltrainer": _3,
        "is-a-photographer": _3,
        "is-a-player": _3,
        "is-a-republican": _3,
        "is-a-rockstar": _3,
        "is-a-socialist": _3,
        "is-a-student": _3,
        "is-a-teacher": _3,
        "is-a-techie": _3,
        "is-a-therapist": _3,
        "is-an-accountant": _3,
        "is-an-actor": _3,
        "is-an-actress": _3,
        "is-an-anarchist": _3,
        "is-an-artist": _3,
        "is-an-engineer": _3,
        "is-an-entertainer": _3,
        "is-certified": _3,
        "is-gone": _3,
        "is-into-anime": _3,
        "is-into-cars": _3,
        "is-into-cartoons": _3,
        "is-into-games": _3,
        "is-leet": _3,
        "is-not-certified": _3,
        "is-slick": _3,
        "is-uberleet": _3,
        "is-with-theband": _3,
        "isa-geek": _3,
        "isa-hockeynut": _3,
        "issmarterthanyou": _3,
        "likes-pie": _3,
        "likescandy": _3,
        "neat-url": _3,
        "saves-the-whales": _3,
        "selfip": _3,
        "sells-for-less": _3,
        "sells-for-u": _3,
        "servebbs": _3,
        "simple-url": _3,
        "space-to-rent": _3,
        "teaches-yoga": _3,
        "writesthisblog": _3,
        "ddnsfree": _3,
        "ddnsgeek": _3,
        "giize": _3,
        "gleeze": _3,
        "kozow": _3,
        "loseyourip": _3,
        "ooguy": _3,
        "theworkpc": _3,
        "mytuleap": _3,
        "tuleap-partners": _3,
        "encoreapi": _3,
        "evennode": [0, {
          "eu-1": _3,
          "eu-2": _3,
          "eu-3": _3,
          "eu-4": _3,
          "us-1": _3,
          "us-2": _3,
          "us-3": _3,
          "us-4": _3
        }],
        "onfabrica": _3,
        "fastly-edge": _3,
        "fastly-terrarium": _3,
        "fastvps-server": _3,
        "mydobiss": _3,
        "firebaseapp": _3,
        "fldrv": _3,
        "forgeblocks": _3,
        "framercanvas": _3,
        "freebox-os": _3,
        "freeboxos": _3,
        "freemyip": _3,
        "aliases121": _3,
        "gentapps": _3,
        "gentlentapis": _3,
        "githubusercontent": _3,
        "0emm": _6,
        "appspot": [2, {
          "r": _6
        }],
        "blogspot": _3,
        "codespot": _3,
        "googleapis": _3,
        "googlecode": _3,
        "pagespeedmobilizer": _3,
        "withgoogle": _3,
        "withyoutube": _3,
        "grayjayleagues": _3,
        "hatenablog": _3,
        "hatenadiary": _3,
        "herokuapp": _3,
        "gr": _3,
        "smushcdn": _3,
        "wphostedmail": _3,
        "wpmucdn": _3,
        "pixolino": _3,
        "apps-1and1": _3,
        "live-website": _3,
        "webspace-host": _3,
        "dopaas": _3,
        "hosted-by-previder": _41,
        "hosteur": [0, {
          "rag-cloud": _3,
          "rag-cloud-ch": _3
        }],
        "ik-server": [0, {
          "jcloud": _3,
          "jcloud-ver-jpc": _3
        }],
        "jelastic": [0, {
          "demo": _3
        }],
        "massivegrid": _41,
        "wafaicloud": [0, {
          "jed": _3,
          "ryd": _3
        }],
        "webadorsite": _3,
        "joyent": [0, {
          "cns": _6
        }],
        "on-forge": _3,
        "on-vapor": _3,
        "lpusercontent": _3,
        "linode": [0, {
          "members": _3,
          "nodebalancer": _6
        }],
        "linodeobjects": _6,
        "linodeusercontent": [0, {
          "ip": _3
        }],
        "localtonet": _3,
        "lovableproject": _3,
        "barsycenter": _3,
        "barsyonline": _3,
        "lutrausercontent": _6,
        "modelscape": _3,
        "mwcloudnonprod": _3,
        "polyspace": _3,
        "mazeplay": _3,
        "miniserver": _3,
        "atmeta": _3,
        "fbsbx": _40,
        "meteorapp": _42,
        "routingthecloud": _3,
        "same-app": _3,
        "same-preview": _3,
        "mydbserver": _3,
        "hostedpi": _3,
        "mythic-beasts": [0, {
          "caracal": _3,
          "customer": _3,
          "fentiger": _3,
          "lynx": _3,
          "ocelot": _3,
          "oncilla": _3,
          "onza": _3,
          "sphinx": _3,
          "vs": _3,
          "x": _3,
          "yali": _3
        }],
        "nospamproxy": [0, {
          "cloud": [2, {
            "o365": _3
          }]
        }],
        "4u": _3,
        "nfshost": _3,
        "3utilities": _3,
        "blogsyte": _3,
        "ciscofreak": _3,
        "damnserver": _3,
        "ddnsking": _3,
        "ditchyourip": _3,
        "dnsiskinky": _3,
        "dynns": _3,
        "geekgalaxy": _3,
        "health-carereform": _3,
        "homesecuritymac": _3,
        "homesecuritypc": _3,
        "myactivedirectory": _3,
        "mysecuritycamera": _3,
        "myvnc": _3,
        "net-freaks": _3,
        "onthewifi": _3,
        "point2this": _3,
        "quicksytes": _3,
        "securitytactics": _3,
        "servebeer": _3,
        "servecounterstrike": _3,
        "serveexchange": _3,
        "serveftp": _3,
        "servegame": _3,
        "servehalflife": _3,
        "servehttp": _3,
        "servehumour": _3,
        "serveirc": _3,
        "servemp3": _3,
        "servep2p": _3,
        "servepics": _3,
        "servequake": _3,
        "servesarcasm": _3,
        "stufftoread": _3,
        "unusualperson": _3,
        "workisboring": _3,
        "myiphost": _3,
        "observableusercontent": [0, {
          "static": _3
        }],
        "simplesite": _3,
        "oaiusercontent": _6,
        "orsites": _3,
        "operaunite": _3,
        "customer-oci": [0, {
          "*": _3,
          "oci": _6,
          "ocp": _6,
          "ocs": _6
        }],
        "oraclecloudapps": _6,
        "oraclegovcloudapps": _6,
        "authgear-staging": _3,
        "authgearapps": _3,
        "skygearapp": _3,
        "outsystemscloud": _3,
        "ownprovider": _3,
        "pgfog": _3,
        "pagexl": _3,
        "gotpantheon": _3,
        "paywhirl": _6,
        "upsunapp": _3,
        "postman-echo": _3,
        "prgmr": [0, {
          "xen": _3
        }],
        "project-study": [0, {
          "dev": _3
        }],
        "pythonanywhere": _42,
        "qa2": _3,
        "alpha-myqnapcloud": _3,
        "dev-myqnapcloud": _3,
        "mycloudnas": _3,
        "mynascloud": _3,
        "myqnapcloud": _3,
        "qualifioapp": _3,
        "ladesk": _3,
        "qualyhqpartner": _6,
        "qualyhqportal": _6,
        "qbuser": _3,
        "quipelements": _6,
        "rackmaze": _3,
        "readthedocs-hosted": _3,
        "rhcloud": _3,
        "onrender": _3,
        "render": _43,
        "subsc-pay": _3,
        "180r": _3,
        "dojin": _3,
        "sakuratan": _3,
        "sakuraweb": _3,
        "x0": _3,
        "code": [0, {
          "builder": _6,
          "dev-builder": _6,
          "stg-builder": _6
        }],
        "salesforce": [0, {
          "platform": [0, {
            "code-builder-stg": [0, {
              "test": [0, {
                "001": _6
              }]
            }]
          }]
        }],
        "logoip": _3,
        "scrysec": _3,
        "firewall-gateway": _3,
        "myshopblocks": _3,
        "myshopify": _3,
        "shopitsite": _3,
        "1kapp": _3,
        "appchizi": _3,
        "applinzi": _3,
        "sinaapp": _3,
        "vipsinaapp": _3,
        "streamlitapp": _3,
        "try-snowplow": _3,
        "playstation-cloud": _3,
        "myspreadshop": _3,
        "w-corp-staticblitz": _3,
        "w-credentialless-staticblitz": _3,
        "w-staticblitz": _3,
        "stackhero-network": _3,
        "stdlib": [0, {
          "api": _3
        }],
        "strapiapp": [2, {
          "media": _3
        }],
        "streak-link": _3,
        "streaklinks": _3,
        "streakusercontent": _3,
        "temp-dns": _3,
        "dsmynas": _3,
        "familyds": _3,
        "mytabit": _3,
        "taveusercontent": _3,
        "tb-hosting": _44,
        "reservd": _3,
        "thingdustdata": _3,
        "townnews-staging": _3,
        "typeform": [0, {
          "pro": _3
        }],
        "hk": _3,
        "it": _3,
        "deus-canvas": _3,
        "vultrobjects": _6,
        "wafflecell": _3,
        "hotelwithflight": _3,
        "reserve-online": _3,
        "cprapid": _3,
        "pleskns": _3,
        "remotewd": _3,
        "wiardweb": [0, {
          "pages": _3
        }],
        "wixsite": _3,
        "wixstudio": _3,
        "messwithdns": _3,
        "woltlab-demo": _3,
        "wpenginepowered": [2, {
          "js": _3
        }],
        "xnbay": [2, {
          "u2": _3,
          "u2-local": _3
        }],
        "yolasite": _3
      }],
      "coop": _2,
      "cr": [1, {
        "ac": _2,
        "co": _2,
        "ed": _2,
        "fi": _2,
        "go": _2,
        "or": _2,
        "sa": _2
      }],
      "cu": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "inf": _2,
        "nat": _2,
        "net": _2,
        "org": _2
      }],
      "cv": [1, {
        "com": _2,
        "edu": _2,
        "id": _2,
        "int": _2,
        "net": _2,
        "nome": _2,
        "org": _2,
        "publ": _2
      }],
      "cw": _45,
      "cx": [1, {
        "gov": _2,
        "cloudns": _3,
        "ath": _3,
        "info": _3,
        "assessments": _3,
        "calculators": _3,
        "funnels": _3,
        "paynow": _3,
        "quizzes": _3,
        "researched": _3,
        "tests": _3
      }],
      "cy": [1, {
        "ac": _2,
        "biz": _2,
        "com": [1, {
          "scaleforce": _46
        }],
        "ekloges": _2,
        "gov": _2,
        "ltd": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "press": _2,
        "pro": _2,
        "tm": _2
      }],
      "cz": [1, {
        "gov": _2,
        "contentproxy9": [0, {
          "rsc": _3
        }],
        "realm": _3,
        "e4": _3,
        "co": _3,
        "metacentrum": [0, {
          "cloud": _6,
          "custom": _3
        }],
        "muni": [0, {
          "cloud": [0, {
            "flt": _3,
            "usr": _3
          }]
        }]
      }],
      "de": [1, {
        "bplaced": _3,
        "square7": _3,
        "com": _3,
        "cosidns": _47,
        "dnsupdater": _3,
        "dynamisches-dns": _3,
        "internet-dns": _3,
        "l-o-g-i-n": _3,
        "ddnss": [2, {
          "dyn": _3,
          "dyndns": _3
        }],
        "dyn-ip24": _3,
        "dyndns1": _3,
        "home-webserver": [2, {
          "dyn": _3
        }],
        "myhome-server": _3,
        "dnshome": _3,
        "fuettertdasnetz": _3,
        "isteingeek": _3,
        "istmein": _3,
        "lebtimnetz": _3,
        "leitungsen": _3,
        "traeumtgerade": _3,
        "frusky": _6,
        "goip": _3,
        "xn--gnstigbestellen-zvb": _3,
        "günstigbestellen": _3,
        "xn--gnstigliefern-wob": _3,
        "günstigliefern": _3,
        "hs-heilbronn": [0, {
          "it": [0, {
            "pages": _3,
            "pages-research": _3
          }]
        }],
        "dyn-berlin": _3,
        "in-berlin": _3,
        "in-brb": _3,
        "in-butter": _3,
        "in-dsl": _3,
        "in-vpn": _3,
        "iservschule": _3,
        "mein-iserv": _3,
        "schuldock": _3,
        "schulplattform": _3,
        "schulserver": _3,
        "test-iserv": _3,
        "keymachine": _3,
        "co": _3,
        "git-repos": _3,
        "lcube-server": _3,
        "svn-repos": _3,
        "barsy": _3,
        "webspaceconfig": _3,
        "123webseite": _3,
        "rub": _3,
        "ruhr-uni-bochum": [2, {
          "noc": [0, {
            "io": _3
          }]
        }],
        "logoip": _3,
        "firewall-gateway": _3,
        "my-gateway": _3,
        "my-router": _3,
        "spdns": _3,
        "my": _3,
        "speedpartner": [0, {
          "customer": _3
        }],
        "myspreadshop": _3,
        "taifun-dns": _3,
        "12hp": _3,
        "2ix": _3,
        "4lima": _3,
        "lima-city": _3,
        "dd-dns": _3,
        "dray-dns": _3,
        "draydns": _3,
        "dyn-vpn": _3,
        "dynvpn": _3,
        "mein-vigor": _3,
        "my-vigor": _3,
        "my-wan": _3,
        "syno-ds": _3,
        "synology-diskstation": _3,
        "synology-ds": _3,
        "virtual-user": _3,
        "virtualuser": _3,
        "community-pro": _3,
        "diskussionsbereich": _3
      }],
      "dj": _2,
      "dk": [1, {
        "biz": _3,
        "co": _3,
        "firm": _3,
        "reg": _3,
        "store": _3,
        "123hjemmeside": _3,
        "myspreadshop": _3
      }],
      "dm": _49,
      "do": [1, {
        "art": _2,
        "com": _2,
        "edu": _2,
        "gob": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "sld": _2,
        "web": _2
      }],
      "dz": [1, {
        "art": _2,
        "asso": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "pol": _2,
        "soc": _2,
        "tm": _2
      }],
      "ec": [1, {
        "abg": _2,
        "adm": _2,
        "agron": _2,
        "arqt": _2,
        "art": _2,
        "bar": _2,
        "chef": _2,
        "com": _2,
        "cont": _2,
        "cpa": _2,
        "cue": _2,
        "dent": _2,
        "dgn": _2,
        "disco": _2,
        "doc": _2,
        "edu": _2,
        "eng": _2,
        "esm": _2,
        "fin": _2,
        "fot": _2,
        "gal": _2,
        "gob": _2,
        "gov": _2,
        "gye": _2,
        "ibr": _2,
        "info": _2,
        "k12": _2,
        "lat": _2,
        "loj": _2,
        "med": _2,
        "mil": _2,
        "mktg": _2,
        "mon": _2,
        "net": _2,
        "ntr": _2,
        "odont": _2,
        "org": _2,
        "pro": _2,
        "prof": _2,
        "psic": _2,
        "psiq": _2,
        "pub": _2,
        "rio": _2,
        "rrpp": _2,
        "sal": _2,
        "tech": _2,
        "tul": _2,
        "tur": _2,
        "uio": _2,
        "vet": _2,
        "xxx": _2,
        "base": _3,
        "official": _3
      }],
      "edu": [1, {
        "rit": [0, {
          "git-pages": _3
        }]
      }],
      "ee": [1, {
        "aip": _2,
        "com": _2,
        "edu": _2,
        "fie": _2,
        "gov": _2,
        "lib": _2,
        "med": _2,
        "org": _2,
        "pri": _2,
        "riik": _2
      }],
      "eg": [1, {
        "ac": _2,
        "com": _2,
        "edu": _2,
        "eun": _2,
        "gov": _2,
        "info": _2,
        "me": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "sci": _2,
        "sport": _2,
        "tv": _2
      }],
      "er": _18,
      "es": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "nom": _2,
        "org": _2,
        "123miweb": _3,
        "myspreadshop": _3
      }],
      "et": [1, {
        "biz": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "name": _2,
        "net": _2,
        "org": _2
      }],
      "eu": [1, {
        "airkitapps": _3,
        "cloudns": _3,
        "dogado": [0, {
          "jelastic": _3
        }],
        "barsy": _3,
        "spdns": _3,
        "nxa": _6,
        "transurl": _6,
        "diskstation": _3
      }],
      "fi": [1, {
        "aland": _2,
        "dy": _3,
        "xn--hkkinen-5wa": _3,
        "häkkinen": _3,
        "iki": _3,
        "cloudplatform": [0, {
          "fi": _3
        }],
        "datacenter": [0, {
          "demo": _3,
          "paas": _3
        }],
        "kapsi": _3,
        "123kotisivu": _3,
        "myspreadshop": _3
      }],
      "fj": [1, {
        "ac": _2,
        "biz": _2,
        "com": _2,
        "gov": _2,
        "info": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pro": _2
      }],
      "fk": _18,
      "fm": [1, {
        "com": _2,
        "edu": _2,
        "net": _2,
        "org": _2,
        "radio": _3,
        "user": _6
      }],
      "fo": _2,
      "fr": [1, {
        "asso": _2,
        "com": _2,
        "gouv": _2,
        "nom": _2,
        "prd": _2,
        "tm": _2,
        "avoues": _2,
        "cci": _2,
        "greta": _2,
        "huissier-justice": _2,
        "en-root": _3,
        "fbx-os": _3,
        "fbxos": _3,
        "freebox-os": _3,
        "freeboxos": _3,
        "goupile": _3,
        "123siteweb": _3,
        "on-web": _3,
        "chirurgiens-dentistes-en-france": _3,
        "dedibox": _3,
        "aeroport": _3,
        "avocat": _3,
        "chambagri": _3,
        "chirurgiens-dentistes": _3,
        "experts-comptables": _3,
        "medecin": _3,
        "notaires": _3,
        "pharmacien": _3,
        "port": _3,
        "veterinaire": _3,
        "myspreadshop": _3,
        "ynh": _3
      }],
      "ga": _2,
      "gb": _2,
      "gd": [1, {
        "edu": _2,
        "gov": _2
      }],
      "ge": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "pvt": _2,
        "school": _2
      }],
      "gf": _2,
      "gg": [1, {
        "co": _2,
        "net": _2,
        "org": _2,
        "botdash": _3,
        "kaas": _3,
        "stackit": _3,
        "panel": [2, {
          "daemon": _3
        }]
      }],
      "gh": [1, {
        "biz": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "gi": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "ltd": _2,
        "mod": _2,
        "org": _2
      }],
      "gl": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "net": _2,
        "org": _2
      }],
      "gm": _2,
      "gn": [1, {
        "ac": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2
      }],
      "gov": _2,
      "gp": [1, {
        "asso": _2,
        "com": _2,
        "edu": _2,
        "mobi": _2,
        "net": _2,
        "org": _2
      }],
      "gq": _2,
      "gr": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "barsy": _3,
        "simplesite": _3
      }],
      "gs": _2,
      "gt": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "ind": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "gu": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "guam": _2,
        "info": _2,
        "net": _2,
        "org": _2,
        "web": _2
      }],
      "gw": [1, {
        "nx": _3
      }],
      "gy": _49,
      "hk": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "idv": _2,
        "net": _2,
        "org": _2,
        "xn--ciqpn": _2,
        "个人": _2,
        "xn--gmqw5a": _2,
        "個人": _2,
        "xn--55qx5d": _2,
        "公司": _2,
        "xn--mxtq1m": _2,
        "政府": _2,
        "xn--lcvr32d": _2,
        "敎育": _2,
        "xn--wcvs22d": _2,
        "教育": _2,
        "xn--gmq050i": _2,
        "箇人": _2,
        "xn--uc0atv": _2,
        "組織": _2,
        "xn--uc0ay4a": _2,
        "組织": _2,
        "xn--od0alg": _2,
        "網絡": _2,
        "xn--zf0avx": _2,
        "網络": _2,
        "xn--mk0axi": _2,
        "组織": _2,
        "xn--tn0ag": _2,
        "组织": _2,
        "xn--od0aq3b": _2,
        "网絡": _2,
        "xn--io0a7i": _2,
        "网络": _2,
        "inc": _3,
        "ltd": _3
      }],
      "hm": _2,
      "hn": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "hr": [1, {
        "com": _2,
        "from": _2,
        "iz": _2,
        "name": _2,
        "brendly": _52
      }],
      "ht": [1, {
        "adult": _2,
        "art": _2,
        "asso": _2,
        "com": _2,
        "coop": _2,
        "edu": _2,
        "firm": _2,
        "gouv": _2,
        "info": _2,
        "med": _2,
        "net": _2,
        "org": _2,
        "perso": _2,
        "pol": _2,
        "pro": _2,
        "rel": _2,
        "shop": _2,
        "rt": _3
      }],
      "hu": [1, {
        "2000": _2,
        "agrar": _2,
        "bolt": _2,
        "casino": _2,
        "city": _2,
        "co": _2,
        "erotica": _2,
        "erotika": _2,
        "film": _2,
        "forum": _2,
        "games": _2,
        "hotel": _2,
        "info": _2,
        "ingatlan": _2,
        "jogasz": _2,
        "konyvelo": _2,
        "lakas": _2,
        "media": _2,
        "news": _2,
        "org": _2,
        "priv": _2,
        "reklam": _2,
        "sex": _2,
        "shop": _2,
        "sport": _2,
        "suli": _2,
        "szex": _2,
        "tm": _2,
        "tozsde": _2,
        "utazas": _2,
        "video": _2
      }],
      "id": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "desa": _2,
        "go": _2,
        "kop": _2,
        "mil": _2,
        "my": _2,
        "net": _2,
        "or": _2,
        "ponpes": _2,
        "sch": _2,
        "web": _2,
        "zone": _3
      }],
      "ie": [1, {
        "gov": _2,
        "myspreadshop": _3
      }],
      "il": [1, {
        "ac": _2,
        "co": [1, {
          "ravpage": _3,
          "mytabit": _3,
          "tabitorder": _3
        }],
        "gov": _2,
        "idf": _2,
        "k12": _2,
        "muni": _2,
        "net": _2,
        "org": _2
      }],
      "xn--4dbrk0ce": [1, {
        "xn--4dbgdty6c": _2,
        "xn--5dbhl8d": _2,
        "xn--8dbq2a": _2,
        "xn--hebda8b": _2
      }],
      "ישראל": [1, {
        "אקדמיה": _2,
        "ישוב": _2,
        "צהל": _2,
        "ממשל": _2
      }],
      "im": [1, {
        "ac": _2,
        "co": [1, {
          "ltd": _2,
          "plc": _2
        }],
        "com": _2,
        "net": _2,
        "org": _2,
        "tt": _2,
        "tv": _2
      }],
      "in": [1, {
        "5g": _2,
        "6g": _2,
        "ac": _2,
        "ai": _2,
        "am": _2,
        "bihar": _2,
        "biz": _2,
        "business": _2,
        "ca": _2,
        "cn": _2,
        "co": _2,
        "com": _2,
        "coop": _2,
        "cs": _2,
        "delhi": _2,
        "dr": _2,
        "edu": _2,
        "er": _2,
        "firm": _2,
        "gen": _2,
        "gov": _2,
        "gujarat": _2,
        "ind": _2,
        "info": _2,
        "int": _2,
        "internet": _2,
        "io": _2,
        "me": _2,
        "mil": _2,
        "net": _2,
        "nic": _2,
        "org": _2,
        "pg": _2,
        "post": _2,
        "pro": _2,
        "res": _2,
        "travel": _2,
        "tv": _2,
        "uk": _2,
        "up": _2,
        "us": _2,
        "cloudns": _3,
        "barsy": _3,
        "web": _3,
        "supabase": _3
      }],
      "info": [1, {
        "cloudns": _3,
        "dynamic-dns": _3,
        "barrel-of-knowledge": _3,
        "barrell-of-knowledge": _3,
        "dyndns": _3,
        "for-our": _3,
        "groks-the": _3,
        "groks-this": _3,
        "here-for-more": _3,
        "knowsitall": _3,
        "selfip": _3,
        "webhop": _3,
        "barsy": _3,
        "mayfirst": _3,
        "mittwald": _3,
        "mittwaldserver": _3,
        "typo3server": _3,
        "dvrcam": _3,
        "ilovecollege": _3,
        "no-ip": _3,
        "forumz": _3,
        "nsupdate": _3,
        "dnsupdate": _3,
        "v-info": _3
      }],
      "int": [1, {
        "eu": _2
      }],
      "io": [1, {
        "2038": _3,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "on-acorn": _6,
        "myaddr": _3,
        "apigee": _3,
        "b-data": _3,
        "beagleboard": _3,
        "bitbucket": _3,
        "bluebite": _3,
        "boxfuse": _3,
        "brave": _7,
        "browsersafetymark": _3,
        "bubble": _53,
        "bubbleapps": _3,
        "bigv": [0, {
          "uk0": _3
        }],
        "cleverapps": _3,
        "cloudbeesusercontent": _3,
        "dappnode": [0, {
          "dyndns": _3
        }],
        "darklang": _3,
        "definima": _3,
        "dedyn": _3,
        "icp0": _54,
        "icp1": _54,
        "qzz": _3,
        "fh-muenster": _3,
        "shw": _3,
        "forgerock": [0, {
          "id": _3
        }],
        "github": _3,
        "gitlab": _3,
        "lolipop": _3,
        "hasura-app": _3,
        "hostyhosting": _3,
        "hypernode": _3,
        "moonscale": _6,
        "beebyte": _41,
        "beebyteapp": [0, {
          "sekd1": _3
        }],
        "jele": _3,
        "webthings": _3,
        "loginline": _3,
        "barsy": _3,
        "azurecontainer": _6,
        "ngrok": [2, {
          "ap": _3,
          "au": _3,
          "eu": _3,
          "in": _3,
          "jp": _3,
          "sa": _3,
          "us": _3
        }],
        "nodeart": [0, {
          "stage": _3
        }],
        "pantheonsite": _3,
        "pstmn": [2, {
          "mock": _3
        }],
        "protonet": _3,
        "qcx": [2, {
          "sys": _6
        }],
        "qoto": _3,
        "vaporcloud": _3,
        "myrdbx": _3,
        "rb-hosting": _44,
        "on-k3s": _6,
        "on-rio": _6,
        "readthedocs": _3,
        "resindevice": _3,
        "resinstaging": [0, {
          "devices": _3
        }],
        "hzc": _3,
        "sandcats": _3,
        "scrypted": [0, {
          "client": _3
        }],
        "mo-siemens": _3,
        "lair": _40,
        "stolos": _6,
        "musician": _3,
        "utwente": _3,
        "edugit": _3,
        "telebit": _3,
        "thingdust": [0, {
          "dev": _55,
          "disrec": _55,
          "prod": _56,
          "testing": _55
        }],
        "tickets": _3,
        "webflow": _3,
        "webflowtest": _3,
        "editorx": _3,
        "wixstudio": _3,
        "basicserver": _3,
        "virtualserver": _3
      }],
      "iq": _5,
      "ir": [1, {
        "ac": _2,
        "co": _2,
        "gov": _2,
        "id": _2,
        "net": _2,
        "org": _2,
        "sch": _2,
        "xn--mgba3a4f16a": _2,
        "ایران": _2,
        "xn--mgba3a4fra": _2,
        "ايران": _2,
        "arvanedge": _3,
        "vistablog": _3
      }],
      "is": _2,
      "it": [1, {
        "edu": _2,
        "gov": _2,
        "abr": _2,
        "abruzzo": _2,
        "aosta-valley": _2,
        "aostavalley": _2,
        "bas": _2,
        "basilicata": _2,
        "cal": _2,
        "calabria": _2,
        "cam": _2,
        "campania": _2,
        "emilia-romagna": _2,
        "emiliaromagna": _2,
        "emr": _2,
        "friuli-v-giulia": _2,
        "friuli-ve-giulia": _2,
        "friuli-vegiulia": _2,
        "friuli-venezia-giulia": _2,
        "friuli-veneziagiulia": _2,
        "friuli-vgiulia": _2,
        "friuliv-giulia": _2,
        "friulive-giulia": _2,
        "friulivegiulia": _2,
        "friulivenezia-giulia": _2,
        "friuliveneziagiulia": _2,
        "friulivgiulia": _2,
        "fvg": _2,
        "laz": _2,
        "lazio": _2,
        "lig": _2,
        "liguria": _2,
        "lom": _2,
        "lombardia": _2,
        "lombardy": _2,
        "lucania": _2,
        "mar": _2,
        "marche": _2,
        "mol": _2,
        "molise": _2,
        "piedmont": _2,
        "piemonte": _2,
        "pmn": _2,
        "pug": _2,
        "puglia": _2,
        "sar": _2,
        "sardegna": _2,
        "sardinia": _2,
        "sic": _2,
        "sicilia": _2,
        "sicily": _2,
        "taa": _2,
        "tos": _2,
        "toscana": _2,
        "trentin-sud-tirol": _2,
        "xn--trentin-sd-tirol-rzb": _2,
        "trentin-süd-tirol": _2,
        "trentin-sudtirol": _2,
        "xn--trentin-sdtirol-7vb": _2,
        "trentin-südtirol": _2,
        "trentin-sued-tirol": _2,
        "trentin-suedtirol": _2,
        "trentino": _2,
        "trentino-a-adige": _2,
        "trentino-aadige": _2,
        "trentino-alto-adige": _2,
        "trentino-altoadige": _2,
        "trentino-s-tirol": _2,
        "trentino-stirol": _2,
        "trentino-sud-tirol": _2,
        "xn--trentino-sd-tirol-c3b": _2,
        "trentino-süd-tirol": _2,
        "trentino-sudtirol": _2,
        "xn--trentino-sdtirol-szb": _2,
        "trentino-südtirol": _2,
        "trentino-sued-tirol": _2,
        "trentino-suedtirol": _2,
        "trentinoa-adige": _2,
        "trentinoaadige": _2,
        "trentinoalto-adige": _2,
        "trentinoaltoadige": _2,
        "trentinos-tirol": _2,
        "trentinostirol": _2,
        "trentinosud-tirol": _2,
        "xn--trentinosd-tirol-rzb": _2,
        "trentinosüd-tirol": _2,
        "trentinosudtirol": _2,
        "xn--trentinosdtirol-7vb": _2,
        "trentinosüdtirol": _2,
        "trentinosued-tirol": _2,
        "trentinosuedtirol": _2,
        "trentinsud-tirol": _2,
        "xn--trentinsd-tirol-6vb": _2,
        "trentinsüd-tirol": _2,
        "trentinsudtirol": _2,
        "xn--trentinsdtirol-nsb": _2,
        "trentinsüdtirol": _2,
        "trentinsued-tirol": _2,
        "trentinsuedtirol": _2,
        "tuscany": _2,
        "umb": _2,
        "umbria": _2,
        "val-d-aosta": _2,
        "val-daosta": _2,
        "vald-aosta": _2,
        "valdaosta": _2,
        "valle-aosta": _2,
        "valle-d-aosta": _2,
        "valle-daosta": _2,
        "valleaosta": _2,
        "valled-aosta": _2,
        "valledaosta": _2,
        "vallee-aoste": _2,
        "xn--valle-aoste-ebb": _2,
        "vallée-aoste": _2,
        "vallee-d-aoste": _2,
        "xn--valle-d-aoste-ehb": _2,
        "vallée-d-aoste": _2,
        "valleeaoste": _2,
        "xn--valleaoste-e7a": _2,
        "valléeaoste": _2,
        "valleedaoste": _2,
        "xn--valledaoste-ebb": _2,
        "valléedaoste": _2,
        "vao": _2,
        "vda": _2,
        "ven": _2,
        "veneto": _2,
        "ag": _2,
        "agrigento": _2,
        "al": _2,
        "alessandria": _2,
        "alto-adige": _2,
        "altoadige": _2,
        "an": _2,
        "ancona": _2,
        "andria-barletta-trani": _2,
        "andria-trani-barletta": _2,
        "andriabarlettatrani": _2,
        "andriatranibarletta": _2,
        "ao": _2,
        "aosta": _2,
        "aoste": _2,
        "ap": _2,
        "aq": _2,
        "aquila": _2,
        "ar": _2,
        "arezzo": _2,
        "ascoli-piceno": _2,
        "ascolipiceno": _2,
        "asti": _2,
        "at": _2,
        "av": _2,
        "avellino": _2,
        "ba": _2,
        "balsan": _2,
        "balsan-sudtirol": _2,
        "xn--balsan-sdtirol-nsb": _2,
        "balsan-südtirol": _2,
        "balsan-suedtirol": _2,
        "bari": _2,
        "barletta-trani-andria": _2,
        "barlettatraniandria": _2,
        "belluno": _2,
        "benevento": _2,
        "bergamo": _2,
        "bg": _2,
        "bi": _2,
        "biella": _2,
        "bl": _2,
        "bn": _2,
        "bo": _2,
        "bologna": _2,
        "bolzano": _2,
        "bolzano-altoadige": _2,
        "bozen": _2,
        "bozen-sudtirol": _2,
        "xn--bozen-sdtirol-2ob": _2,
        "bozen-südtirol": _2,
        "bozen-suedtirol": _2,
        "br": _2,
        "brescia": _2,
        "brindisi": _2,
        "bs": _2,
        "bt": _2,
        "bulsan": _2,
        "bulsan-sudtirol": _2,
        "xn--bulsan-sdtirol-nsb": _2,
        "bulsan-südtirol": _2,
        "bulsan-suedtirol": _2,
        "bz": _2,
        "ca": _2,
        "cagliari": _2,
        "caltanissetta": _2,
        "campidano-medio": _2,
        "campidanomedio": _2,
        "campobasso": _2,
        "carbonia-iglesias": _2,
        "carboniaiglesias": _2,
        "carrara-massa": _2,
        "carraramassa": _2,
        "caserta": _2,
        "catania": _2,
        "catanzaro": _2,
        "cb": _2,
        "ce": _2,
        "cesena-forli": _2,
        "xn--cesena-forl-mcb": _2,
        "cesena-forlì": _2,
        "cesenaforli": _2,
        "xn--cesenaforl-i8a": _2,
        "cesenaforlì": _2,
        "ch": _2,
        "chieti": _2,
        "ci": _2,
        "cl": _2,
        "cn": _2,
        "co": _2,
        "como": _2,
        "cosenza": _2,
        "cr": _2,
        "cremona": _2,
        "crotone": _2,
        "cs": _2,
        "ct": _2,
        "cuneo": _2,
        "cz": _2,
        "dell-ogliastra": _2,
        "dellogliastra": _2,
        "en": _2,
        "enna": _2,
        "fc": _2,
        "fe": _2,
        "fermo": _2,
        "ferrara": _2,
        "fg": _2,
        "fi": _2,
        "firenze": _2,
        "florence": _2,
        "fm": _2,
        "foggia": _2,
        "forli-cesena": _2,
        "xn--forl-cesena-fcb": _2,
        "forlì-cesena": _2,
        "forlicesena": _2,
        "xn--forlcesena-c8a": _2,
        "forlìcesena": _2,
        "fr": _2,
        "frosinone": _2,
        "ge": _2,
        "genoa": _2,
        "genova": _2,
        "go": _2,
        "gorizia": _2,
        "gr": _2,
        "grosseto": _2,
        "iglesias-carbonia": _2,
        "iglesiascarbonia": _2,
        "im": _2,
        "imperia": _2,
        "is": _2,
        "isernia": _2,
        "kr": _2,
        "la-spezia": _2,
        "laquila": _2,
        "laspezia": _2,
        "latina": _2,
        "lc": _2,
        "le": _2,
        "lecce": _2,
        "lecco": _2,
        "li": _2,
        "livorno": _2,
        "lo": _2,
        "lodi": _2,
        "lt": _2,
        "lu": _2,
        "lucca": _2,
        "macerata": _2,
        "mantova": _2,
        "massa-carrara": _2,
        "massacarrara": _2,
        "matera": _2,
        "mb": _2,
        "mc": _2,
        "me": _2,
        "medio-campidano": _2,
        "mediocampidano": _2,
        "messina": _2,
        "mi": _2,
        "milan": _2,
        "milano": _2,
        "mn": _2,
        "mo": _2,
        "modena": _2,
        "monza": _2,
        "monza-brianza": _2,
        "monza-e-della-brianza": _2,
        "monzabrianza": _2,
        "monzaebrianza": _2,
        "monzaedellabrianza": _2,
        "ms": _2,
        "mt": _2,
        "na": _2,
        "naples": _2,
        "napoli": _2,
        "no": _2,
        "novara": _2,
        "nu": _2,
        "nuoro": _2,
        "og": _2,
        "ogliastra": _2,
        "olbia-tempio": _2,
        "olbiatempio": _2,
        "or": _2,
        "oristano": _2,
        "ot": _2,
        "pa": _2,
        "padova": _2,
        "padua": _2,
        "palermo": _2,
        "parma": _2,
        "pavia": _2,
        "pc": _2,
        "pd": _2,
        "pe": _2,
        "perugia": _2,
        "pesaro-urbino": _2,
        "pesarourbino": _2,
        "pescara": _2,
        "pg": _2,
        "pi": _2,
        "piacenza": _2,
        "pisa": _2,
        "pistoia": _2,
        "pn": _2,
        "po": _2,
        "pordenone": _2,
        "potenza": _2,
        "pr": _2,
        "prato": _2,
        "pt": _2,
        "pu": _2,
        "pv": _2,
        "pz": _2,
        "ra": _2,
        "ragusa": _2,
        "ravenna": _2,
        "rc": _2,
        "re": _2,
        "reggio-calabria": _2,
        "reggio-emilia": _2,
        "reggiocalabria": _2,
        "reggioemilia": _2,
        "rg": _2,
        "ri": _2,
        "rieti": _2,
        "rimini": _2,
        "rm": _2,
        "rn": _2,
        "ro": _2,
        "roma": _2,
        "rome": _2,
        "rovigo": _2,
        "sa": _2,
        "salerno": _2,
        "sassari": _2,
        "savona": _2,
        "si": _2,
        "siena": _2,
        "siracusa": _2,
        "so": _2,
        "sondrio": _2,
        "sp": _2,
        "sr": _2,
        "ss": _2,
        "xn--sdtirol-n2a": _2,
        "südtirol": _2,
        "suedtirol": _2,
        "sv": _2,
        "ta": _2,
        "taranto": _2,
        "te": _2,
        "tempio-olbia": _2,
        "tempioolbia": _2,
        "teramo": _2,
        "terni": _2,
        "tn": _2,
        "to": _2,
        "torino": _2,
        "tp": _2,
        "tr": _2,
        "trani-andria-barletta": _2,
        "trani-barletta-andria": _2,
        "traniandriabarletta": _2,
        "tranibarlettaandria": _2,
        "trapani": _2,
        "trento": _2,
        "treviso": _2,
        "trieste": _2,
        "ts": _2,
        "turin": _2,
        "tv": _2,
        "ud": _2,
        "udine": _2,
        "urbino-pesaro": _2,
        "urbinopesaro": _2,
        "va": _2,
        "varese": _2,
        "vb": _2,
        "vc": _2,
        "ve": _2,
        "venezia": _2,
        "venice": _2,
        "verbania": _2,
        "vercelli": _2,
        "verona": _2,
        "vi": _2,
        "vibo-valentia": _2,
        "vibovalentia": _2,
        "vicenza": _2,
        "viterbo": _2,
        "vr": _2,
        "vs": _2,
        "vt": _2,
        "vv": _2,
        "12chars": _3,
        "ibxos": _3,
        "iliadboxos": _3,
        "neen": [0, {
          "jc": _3
        }],
        "123homepage": _3,
        "16-b": _3,
        "32-b": _3,
        "64-b": _3,
        "myspreadshop": _3,
        "syncloud": _3
      }],
      "je": [1, {
        "co": _2,
        "net": _2,
        "org": _2,
        "of": _3
      }],
      "jm": _18,
      "jo": [1, {
        "agri": _2,
        "ai": _2,
        "com": _2,
        "edu": _2,
        "eng": _2,
        "fm": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "per": _2,
        "phd": _2,
        "sch": _2,
        "tv": _2
      }],
      "jobs": _2,
      "jp": [1, {
        "ac": _2,
        "ad": _2,
        "co": _2,
        "ed": _2,
        "go": _2,
        "gr": _2,
        "lg": _2,
        "ne": [1, {
          "aseinet": _51,
          "gehirn": _3,
          "ivory": _3,
          "mail-box": _3,
          "mints": _3,
          "mokuren": _3,
          "opal": _3,
          "sakura": _3,
          "sumomo": _3,
          "topaz": _3
        }],
        "or": _2,
        "aichi": [1, {
          "aisai": _2,
          "ama": _2,
          "anjo": _2,
          "asuke": _2,
          "chiryu": _2,
          "chita": _2,
          "fuso": _2,
          "gamagori": _2,
          "handa": _2,
          "hazu": _2,
          "hekinan": _2,
          "higashiura": _2,
          "ichinomiya": _2,
          "inazawa": _2,
          "inuyama": _2,
          "isshiki": _2,
          "iwakura": _2,
          "kanie": _2,
          "kariya": _2,
          "kasugai": _2,
          "kira": _2,
          "kiyosu": _2,
          "komaki": _2,
          "konan": _2,
          "kota": _2,
          "mihama": _2,
          "miyoshi": _2,
          "nishio": _2,
          "nisshin": _2,
          "obu": _2,
          "oguchi": _2,
          "oharu": _2,
          "okazaki": _2,
          "owariasahi": _2,
          "seto": _2,
          "shikatsu": _2,
          "shinshiro": _2,
          "shitara": _2,
          "tahara": _2,
          "takahama": _2,
          "tobishima": _2,
          "toei": _2,
          "togo": _2,
          "tokai": _2,
          "tokoname": _2,
          "toyoake": _2,
          "toyohashi": _2,
          "toyokawa": _2,
          "toyone": _2,
          "toyota": _2,
          "tsushima": _2,
          "yatomi": _2
        }],
        "akita": [1, {
          "akita": _2,
          "daisen": _2,
          "fujisato": _2,
          "gojome": _2,
          "hachirogata": _2,
          "happou": _2,
          "higashinaruse": _2,
          "honjo": _2,
          "honjyo": _2,
          "ikawa": _2,
          "kamikoani": _2,
          "kamioka": _2,
          "katagami": _2,
          "kazuno": _2,
          "kitaakita": _2,
          "kosaka": _2,
          "kyowa": _2,
          "misato": _2,
          "mitane": _2,
          "moriyoshi": _2,
          "nikaho": _2,
          "noshiro": _2,
          "odate": _2,
          "oga": _2,
          "ogata": _2,
          "semboku": _2,
          "yokote": _2,
          "yurihonjo": _2
        }],
        "aomori": [1, {
          "aomori": _2,
          "gonohe": _2,
          "hachinohe": _2,
          "hashikami": _2,
          "hiranai": _2,
          "hirosaki": _2,
          "itayanagi": _2,
          "kuroishi": _2,
          "misawa": _2,
          "mutsu": _2,
          "nakadomari": _2,
          "noheji": _2,
          "oirase": _2,
          "owani": _2,
          "rokunohe": _2,
          "sannohe": _2,
          "shichinohe": _2,
          "shingo": _2,
          "takko": _2,
          "towada": _2,
          "tsugaru": _2,
          "tsuruta": _2
        }],
        "chiba": [1, {
          "abiko": _2,
          "asahi": _2,
          "chonan": _2,
          "chosei": _2,
          "choshi": _2,
          "chuo": _2,
          "funabashi": _2,
          "futtsu": _2,
          "hanamigawa": _2,
          "ichihara": _2,
          "ichikawa": _2,
          "ichinomiya": _2,
          "inzai": _2,
          "isumi": _2,
          "kamagaya": _2,
          "kamogawa": _2,
          "kashiwa": _2,
          "katori": _2,
          "katsuura": _2,
          "kimitsu": _2,
          "kisarazu": _2,
          "kozaki": _2,
          "kujukuri": _2,
          "kyonan": _2,
          "matsudo": _2,
          "midori": _2,
          "mihama": _2,
          "minamiboso": _2,
          "mobara": _2,
          "mutsuzawa": _2,
          "nagara": _2,
          "nagareyama": _2,
          "narashino": _2,
          "narita": _2,
          "noda": _2,
          "oamishirasato": _2,
          "omigawa": _2,
          "onjuku": _2,
          "otaki": _2,
          "sakae": _2,
          "sakura": _2,
          "shimofusa": _2,
          "shirako": _2,
          "shiroi": _2,
          "shisui": _2,
          "sodegaura": _2,
          "sosa": _2,
          "tako": _2,
          "tateyama": _2,
          "togane": _2,
          "tohnosho": _2,
          "tomisato": _2,
          "urayasu": _2,
          "yachimata": _2,
          "yachiyo": _2,
          "yokaichiba": _2,
          "yokoshibahikari": _2,
          "yotsukaido": _2
        }],
        "ehime": [1, {
          "ainan": _2,
          "honai": _2,
          "ikata": _2,
          "imabari": _2,
          "iyo": _2,
          "kamijima": _2,
          "kihoku": _2,
          "kumakogen": _2,
          "masaki": _2,
          "matsuno": _2,
          "matsuyama": _2,
          "namikata": _2,
          "niihama": _2,
          "ozu": _2,
          "saijo": _2,
          "seiyo": _2,
          "shikokuchuo": _2,
          "tobe": _2,
          "toon": _2,
          "uchiko": _2,
          "uwajima": _2,
          "yawatahama": _2
        }],
        "fukui": [1, {
          "echizen": _2,
          "eiheiji": _2,
          "fukui": _2,
          "ikeda": _2,
          "katsuyama": _2,
          "mihama": _2,
          "minamiechizen": _2,
          "obama": _2,
          "ohi": _2,
          "ono": _2,
          "sabae": _2,
          "sakai": _2,
          "takahama": _2,
          "tsuruga": _2,
          "wakasa": _2
        }],
        "fukuoka": [1, {
          "ashiya": _2,
          "buzen": _2,
          "chikugo": _2,
          "chikuho": _2,
          "chikujo": _2,
          "chikushino": _2,
          "chikuzen": _2,
          "chuo": _2,
          "dazaifu": _2,
          "fukuchi": _2,
          "hakata": _2,
          "higashi": _2,
          "hirokawa": _2,
          "hisayama": _2,
          "iizuka": _2,
          "inatsuki": _2,
          "kaho": _2,
          "kasuga": _2,
          "kasuya": _2,
          "kawara": _2,
          "keisen": _2,
          "koga": _2,
          "kurate": _2,
          "kurogi": _2,
          "kurume": _2,
          "minami": _2,
          "miyako": _2,
          "miyama": _2,
          "miyawaka": _2,
          "mizumaki": _2,
          "munakata": _2,
          "nakagawa": _2,
          "nakama": _2,
          "nishi": _2,
          "nogata": _2,
          "ogori": _2,
          "okagaki": _2,
          "okawa": _2,
          "oki": _2,
          "omuta": _2,
          "onga": _2,
          "onojo": _2,
          "oto": _2,
          "saigawa": _2,
          "sasaguri": _2,
          "shingu": _2,
          "shinyoshitomi": _2,
          "shonai": _2,
          "soeda": _2,
          "sue": _2,
          "tachiarai": _2,
          "tagawa": _2,
          "takata": _2,
          "toho": _2,
          "toyotsu": _2,
          "tsuiki": _2,
          "ukiha": _2,
          "umi": _2,
          "usui": _2,
          "yamada": _2,
          "yame": _2,
          "yanagawa": _2,
          "yukuhashi": _2
        }],
        "fukushima": [1, {
          "aizubange": _2,
          "aizumisato": _2,
          "aizuwakamatsu": _2,
          "asakawa": _2,
          "bandai": _2,
          "date": _2,
          "fukushima": _2,
          "furudono": _2,
          "futaba": _2,
          "hanawa": _2,
          "higashi": _2,
          "hirata": _2,
          "hirono": _2,
          "iitate": _2,
          "inawashiro": _2,
          "ishikawa": _2,
          "iwaki": _2,
          "izumizaki": _2,
          "kagamiishi": _2,
          "kaneyama": _2,
          "kawamata": _2,
          "kitakata": _2,
          "kitashiobara": _2,
          "koori": _2,
          "koriyama": _2,
          "kunimi": _2,
          "miharu": _2,
          "mishima": _2,
          "namie": _2,
          "nango": _2,
          "nishiaizu": _2,
          "nishigo": _2,
          "okuma": _2,
          "omotego": _2,
          "ono": _2,
          "otama": _2,
          "samegawa": _2,
          "shimogo": _2,
          "shirakawa": _2,
          "showa": _2,
          "soma": _2,
          "sukagawa": _2,
          "taishin": _2,
          "tamakawa": _2,
          "tanagura": _2,
          "tenei": _2,
          "yabuki": _2,
          "yamato": _2,
          "yamatsuri": _2,
          "yanaizu": _2,
          "yugawa": _2
        }],
        "gifu": [1, {
          "anpachi": _2,
          "ena": _2,
          "gifu": _2,
          "ginan": _2,
          "godo": _2,
          "gujo": _2,
          "hashima": _2,
          "hichiso": _2,
          "hida": _2,
          "higashishirakawa": _2,
          "ibigawa": _2,
          "ikeda": _2,
          "kakamigahara": _2,
          "kani": _2,
          "kasahara": _2,
          "kasamatsu": _2,
          "kawaue": _2,
          "kitagata": _2,
          "mino": _2,
          "minokamo": _2,
          "mitake": _2,
          "mizunami": _2,
          "motosu": _2,
          "nakatsugawa": _2,
          "ogaki": _2,
          "sakahogi": _2,
          "seki": _2,
          "sekigahara": _2,
          "shirakawa": _2,
          "tajimi": _2,
          "takayama": _2,
          "tarui": _2,
          "toki": _2,
          "tomika": _2,
          "wanouchi": _2,
          "yamagata": _2,
          "yaotsu": _2,
          "yoro": _2
        }],
        "gunma": [1, {
          "annaka": _2,
          "chiyoda": _2,
          "fujioka": _2,
          "higashiagatsuma": _2,
          "isesaki": _2,
          "itakura": _2,
          "kanna": _2,
          "kanra": _2,
          "katashina": _2,
          "kawaba": _2,
          "kiryu": _2,
          "kusatsu": _2,
          "maebashi": _2,
          "meiwa": _2,
          "midori": _2,
          "minakami": _2,
          "naganohara": _2,
          "nakanojo": _2,
          "nanmoku": _2,
          "numata": _2,
          "oizumi": _2,
          "ora": _2,
          "ota": _2,
          "shibukawa": _2,
          "shimonita": _2,
          "shinto": _2,
          "showa": _2,
          "takasaki": _2,
          "takayama": _2,
          "tamamura": _2,
          "tatebayashi": _2,
          "tomioka": _2,
          "tsukiyono": _2,
          "tsumagoi": _2,
          "ueno": _2,
          "yoshioka": _2
        }],
        "hiroshima": [1, {
          "asaminami": _2,
          "daiwa": _2,
          "etajima": _2,
          "fuchu": _2,
          "fukuyama": _2,
          "hatsukaichi": _2,
          "higashihiroshima": _2,
          "hongo": _2,
          "jinsekikogen": _2,
          "kaita": _2,
          "kui": _2,
          "kumano": _2,
          "kure": _2,
          "mihara": _2,
          "miyoshi": _2,
          "naka": _2,
          "onomichi": _2,
          "osakikamijima": _2,
          "otake": _2,
          "saka": _2,
          "sera": _2,
          "seranishi": _2,
          "shinichi": _2,
          "shobara": _2,
          "takehara": _2
        }],
        "hokkaido": [1, {
          "abashiri": _2,
          "abira": _2,
          "aibetsu": _2,
          "akabira": _2,
          "akkeshi": _2,
          "asahikawa": _2,
          "ashibetsu": _2,
          "ashoro": _2,
          "assabu": _2,
          "atsuma": _2,
          "bibai": _2,
          "biei": _2,
          "bifuka": _2,
          "bihoro": _2,
          "biratori": _2,
          "chippubetsu": _2,
          "chitose": _2,
          "date": _2,
          "ebetsu": _2,
          "embetsu": _2,
          "eniwa": _2,
          "erimo": _2,
          "esan": _2,
          "esashi": _2,
          "fukagawa": _2,
          "fukushima": _2,
          "furano": _2,
          "furubira": _2,
          "haboro": _2,
          "hakodate": _2,
          "hamatonbetsu": _2,
          "hidaka": _2,
          "higashikagura": _2,
          "higashikawa": _2,
          "hiroo": _2,
          "hokuryu": _2,
          "hokuto": _2,
          "honbetsu": _2,
          "horokanai": _2,
          "horonobe": _2,
          "ikeda": _2,
          "imakane": _2,
          "ishikari": _2,
          "iwamizawa": _2,
          "iwanai": _2,
          "kamifurano": _2,
          "kamikawa": _2,
          "kamishihoro": _2,
          "kamisunagawa": _2,
          "kamoenai": _2,
          "kayabe": _2,
          "kembuchi": _2,
          "kikonai": _2,
          "kimobetsu": _2,
          "kitahiroshima": _2,
          "kitami": _2,
          "kiyosato": _2,
          "koshimizu": _2,
          "kunneppu": _2,
          "kuriyama": _2,
          "kuromatsunai": _2,
          "kushiro": _2,
          "kutchan": _2,
          "kyowa": _2,
          "mashike": _2,
          "matsumae": _2,
          "mikasa": _2,
          "minamifurano": _2,
          "mombetsu": _2,
          "moseushi": _2,
          "mukawa": _2,
          "muroran": _2,
          "naie": _2,
          "nakagawa": _2,
          "nakasatsunai": _2,
          "nakatombetsu": _2,
          "nanae": _2,
          "nanporo": _2,
          "nayoro": _2,
          "nemuro": _2,
          "niikappu": _2,
          "niki": _2,
          "nishiokoppe": _2,
          "noboribetsu": _2,
          "numata": _2,
          "obihiro": _2,
          "obira": _2,
          "oketo": _2,
          "okoppe": _2,
          "otaru": _2,
          "otobe": _2,
          "otofuke": _2,
          "otoineppu": _2,
          "oumu": _2,
          "ozora": _2,
          "pippu": _2,
          "rankoshi": _2,
          "rebun": _2,
          "rikubetsu": _2,
          "rishiri": _2,
          "rishirifuji": _2,
          "saroma": _2,
          "sarufutsu": _2,
          "shakotan": _2,
          "shari": _2,
          "shibecha": _2,
          "shibetsu": _2,
          "shikabe": _2,
          "shikaoi": _2,
          "shimamaki": _2,
          "shimizu": _2,
          "shimokawa": _2,
          "shinshinotsu": _2,
          "shintoku": _2,
          "shiranuka": _2,
          "shiraoi": _2,
          "shiriuchi": _2,
          "sobetsu": _2,
          "sunagawa": _2,
          "taiki": _2,
          "takasu": _2,
          "takikawa": _2,
          "takinoue": _2,
          "teshikaga": _2,
          "tobetsu": _2,
          "tohma": _2,
          "tomakomai": _2,
          "tomari": _2,
          "toya": _2,
          "toyako": _2,
          "toyotomi": _2,
          "toyoura": _2,
          "tsubetsu": _2,
          "tsukigata": _2,
          "urakawa": _2,
          "urausu": _2,
          "uryu": _2,
          "utashinai": _2,
          "wakkanai": _2,
          "wassamu": _2,
          "yakumo": _2,
          "yoichi": _2
        }],
        "hyogo": [1, {
          "aioi": _2,
          "akashi": _2,
          "ako": _2,
          "amagasaki": _2,
          "aogaki": _2,
          "asago": _2,
          "ashiya": _2,
          "awaji": _2,
          "fukusaki": _2,
          "goshiki": _2,
          "harima": _2,
          "himeji": _2,
          "ichikawa": _2,
          "inagawa": _2,
          "itami": _2,
          "kakogawa": _2,
          "kamigori": _2,
          "kamikawa": _2,
          "kasai": _2,
          "kasuga": _2,
          "kawanishi": _2,
          "miki": _2,
          "minamiawaji": _2,
          "nishinomiya": _2,
          "nishiwaki": _2,
          "ono": _2,
          "sanda": _2,
          "sannan": _2,
          "sasayama": _2,
          "sayo": _2,
          "shingu": _2,
          "shinonsen": _2,
          "shiso": _2,
          "sumoto": _2,
          "taishi": _2,
          "taka": _2,
          "takarazuka": _2,
          "takasago": _2,
          "takino": _2,
          "tamba": _2,
          "tatsuno": _2,
          "toyooka": _2,
          "yabu": _2,
          "yashiro": _2,
          "yoka": _2,
          "yokawa": _2
        }],
        "ibaraki": [1, {
          "ami": _2,
          "asahi": _2,
          "bando": _2,
          "chikusei": _2,
          "daigo": _2,
          "fujishiro": _2,
          "hitachi": _2,
          "hitachinaka": _2,
          "hitachiomiya": _2,
          "hitachiota": _2,
          "ibaraki": _2,
          "ina": _2,
          "inashiki": _2,
          "itako": _2,
          "iwama": _2,
          "joso": _2,
          "kamisu": _2,
          "kasama": _2,
          "kashima": _2,
          "kasumigaura": _2,
          "koga": _2,
          "miho": _2,
          "mito": _2,
          "moriya": _2,
          "naka": _2,
          "namegata": _2,
          "oarai": _2,
          "ogawa": _2,
          "omitama": _2,
          "ryugasaki": _2,
          "sakai": _2,
          "sakuragawa": _2,
          "shimodate": _2,
          "shimotsuma": _2,
          "shirosato": _2,
          "sowa": _2,
          "suifu": _2,
          "takahagi": _2,
          "tamatsukuri": _2,
          "tokai": _2,
          "tomobe": _2,
          "tone": _2,
          "toride": _2,
          "tsuchiura": _2,
          "tsukuba": _2,
          "uchihara": _2,
          "ushiku": _2,
          "yachiyo": _2,
          "yamagata": _2,
          "yawara": _2,
          "yuki": _2
        }],
        "ishikawa": [1, {
          "anamizu": _2,
          "hakui": _2,
          "hakusan": _2,
          "kaga": _2,
          "kahoku": _2,
          "kanazawa": _2,
          "kawakita": _2,
          "komatsu": _2,
          "nakanoto": _2,
          "nanao": _2,
          "nomi": _2,
          "nonoichi": _2,
          "noto": _2,
          "shika": _2,
          "suzu": _2,
          "tsubata": _2,
          "tsurugi": _2,
          "uchinada": _2,
          "wajima": _2
        }],
        "iwate": [1, {
          "fudai": _2,
          "fujisawa": _2,
          "hanamaki": _2,
          "hiraizumi": _2,
          "hirono": _2,
          "ichinohe": _2,
          "ichinoseki": _2,
          "iwaizumi": _2,
          "iwate": _2,
          "joboji": _2,
          "kamaishi": _2,
          "kanegasaki": _2,
          "karumai": _2,
          "kawai": _2,
          "kitakami": _2,
          "kuji": _2,
          "kunohe": _2,
          "kuzumaki": _2,
          "miyako": _2,
          "mizusawa": _2,
          "morioka": _2,
          "ninohe": _2,
          "noda": _2,
          "ofunato": _2,
          "oshu": _2,
          "otsuchi": _2,
          "rikuzentakata": _2,
          "shiwa": _2,
          "shizukuishi": _2,
          "sumita": _2,
          "tanohata": _2,
          "tono": _2,
          "yahaba": _2,
          "yamada": _2
        }],
        "kagawa": [1, {
          "ayagawa": _2,
          "higashikagawa": _2,
          "kanonji": _2,
          "kotohira": _2,
          "manno": _2,
          "marugame": _2,
          "mitoyo": _2,
          "naoshima": _2,
          "sanuki": _2,
          "tadotsu": _2,
          "takamatsu": _2,
          "tonosho": _2,
          "uchinomi": _2,
          "utazu": _2,
          "zentsuji": _2
        }],
        "kagoshima": [1, {
          "akune": _2,
          "amami": _2,
          "hioki": _2,
          "isa": _2,
          "isen": _2,
          "izumi": _2,
          "kagoshima": _2,
          "kanoya": _2,
          "kawanabe": _2,
          "kinko": _2,
          "kouyama": _2,
          "makurazaki": _2,
          "matsumoto": _2,
          "minamitane": _2,
          "nakatane": _2,
          "nishinoomote": _2,
          "satsumasendai": _2,
          "soo": _2,
          "tarumizu": _2,
          "yusui": _2
        }],
        "kanagawa": [1, {
          "aikawa": _2,
          "atsugi": _2,
          "ayase": _2,
          "chigasaki": _2,
          "ebina": _2,
          "fujisawa": _2,
          "hadano": _2,
          "hakone": _2,
          "hiratsuka": _2,
          "isehara": _2,
          "kaisei": _2,
          "kamakura": _2,
          "kiyokawa": _2,
          "matsuda": _2,
          "minamiashigara": _2,
          "miura": _2,
          "nakai": _2,
          "ninomiya": _2,
          "odawara": _2,
          "oi": _2,
          "oiso": _2,
          "sagamihara": _2,
          "samukawa": _2,
          "tsukui": _2,
          "yamakita": _2,
          "yamato": _2,
          "yokosuka": _2,
          "yugawara": _2,
          "zama": _2,
          "zushi": _2
        }],
        "kochi": [1, {
          "aki": _2,
          "geisei": _2,
          "hidaka": _2,
          "higashitsuno": _2,
          "ino": _2,
          "kagami": _2,
          "kami": _2,
          "kitagawa": _2,
          "kochi": _2,
          "mihara": _2,
          "motoyama": _2,
          "muroto": _2,
          "nahari": _2,
          "nakamura": _2,
          "nankoku": _2,
          "nishitosa": _2,
          "niyodogawa": _2,
          "ochi": _2,
          "okawa": _2,
          "otoyo": _2,
          "otsuki": _2,
          "sakawa": _2,
          "sukumo": _2,
          "susaki": _2,
          "tosa": _2,
          "tosashimizu": _2,
          "toyo": _2,
          "tsuno": _2,
          "umaji": _2,
          "yasuda": _2,
          "yusuhara": _2
        }],
        "kumamoto": [1, {
          "amakusa": _2,
          "arao": _2,
          "aso": _2,
          "choyo": _2,
          "gyokuto": _2,
          "kamiamakusa": _2,
          "kikuchi": _2,
          "kumamoto": _2,
          "mashiki": _2,
          "mifune": _2,
          "minamata": _2,
          "minamioguni": _2,
          "nagasu": _2,
          "nishihara": _2,
          "oguni": _2,
          "ozu": _2,
          "sumoto": _2,
          "takamori": _2,
          "uki": _2,
          "uto": _2,
          "yamaga": _2,
          "yamato": _2,
          "yatsushiro": _2
        }],
        "kyoto": [1, {
          "ayabe": _2,
          "fukuchiyama": _2,
          "higashiyama": _2,
          "ide": _2,
          "ine": _2,
          "joyo": _2,
          "kameoka": _2,
          "kamo": _2,
          "kita": _2,
          "kizu": _2,
          "kumiyama": _2,
          "kyotamba": _2,
          "kyotanabe": _2,
          "kyotango": _2,
          "maizuru": _2,
          "minami": _2,
          "minamiyamashiro": _2,
          "miyazu": _2,
          "muko": _2,
          "nagaokakyo": _2,
          "nakagyo": _2,
          "nantan": _2,
          "oyamazaki": _2,
          "sakyo": _2,
          "seika": _2,
          "tanabe": _2,
          "uji": _2,
          "ujitawara": _2,
          "wazuka": _2,
          "yamashina": _2,
          "yawata": _2
        }],
        "mie": [1, {
          "asahi": _2,
          "inabe": _2,
          "ise": _2,
          "kameyama": _2,
          "kawagoe": _2,
          "kiho": _2,
          "kisosaki": _2,
          "kiwa": _2,
          "komono": _2,
          "kumano": _2,
          "kuwana": _2,
          "matsusaka": _2,
          "meiwa": _2,
          "mihama": _2,
          "minamiise": _2,
          "misugi": _2,
          "miyama": _2,
          "nabari": _2,
          "shima": _2,
          "suzuka": _2,
          "tado": _2,
          "taiki": _2,
          "taki": _2,
          "tamaki": _2,
          "toba": _2,
          "tsu": _2,
          "udono": _2,
          "ureshino": _2,
          "watarai": _2,
          "yokkaichi": _2
        }],
        "miyagi": [1, {
          "furukawa": _2,
          "higashimatsushima": _2,
          "ishinomaki": _2,
          "iwanuma": _2,
          "kakuda": _2,
          "kami": _2,
          "kawasaki": _2,
          "marumori": _2,
          "matsushima": _2,
          "minamisanriku": _2,
          "misato": _2,
          "murata": _2,
          "natori": _2,
          "ogawara": _2,
          "ohira": _2,
          "onagawa": _2,
          "osaki": _2,
          "rifu": _2,
          "semine": _2,
          "shibata": _2,
          "shichikashuku": _2,
          "shikama": _2,
          "shiogama": _2,
          "shiroishi": _2,
          "tagajo": _2,
          "taiwa": _2,
          "tome": _2,
          "tomiya": _2,
          "wakuya": _2,
          "watari": _2,
          "yamamoto": _2,
          "zao": _2
        }],
        "miyazaki": [1, {
          "aya": _2,
          "ebino": _2,
          "gokase": _2,
          "hyuga": _2,
          "kadogawa": _2,
          "kawaminami": _2,
          "kijo": _2,
          "kitagawa": _2,
          "kitakata": _2,
          "kitaura": _2,
          "kobayashi": _2,
          "kunitomi": _2,
          "kushima": _2,
          "mimata": _2,
          "miyakonojo": _2,
          "miyazaki": _2,
          "morotsuka": _2,
          "nichinan": _2,
          "nishimera": _2,
          "nobeoka": _2,
          "saito": _2,
          "shiiba": _2,
          "shintomi": _2,
          "takaharu": _2,
          "takanabe": _2,
          "takazaki": _2,
          "tsuno": _2
        }],
        "nagano": [1, {
          "achi": _2,
          "agematsu": _2,
          "anan": _2,
          "aoki": _2,
          "asahi": _2,
          "azumino": _2,
          "chikuhoku": _2,
          "chikuma": _2,
          "chino": _2,
          "fujimi": _2,
          "hakuba": _2,
          "hara": _2,
          "hiraya": _2,
          "iida": _2,
          "iijima": _2,
          "iiyama": _2,
          "iizuna": _2,
          "ikeda": _2,
          "ikusaka": _2,
          "ina": _2,
          "karuizawa": _2,
          "kawakami": _2,
          "kiso": _2,
          "kisofukushima": _2,
          "kitaaiki": _2,
          "komagane": _2,
          "komoro": _2,
          "matsukawa": _2,
          "matsumoto": _2,
          "miasa": _2,
          "minamiaiki": _2,
          "minamimaki": _2,
          "minamiminowa": _2,
          "minowa": _2,
          "miyada": _2,
          "miyota": _2,
          "mochizuki": _2,
          "nagano": _2,
          "nagawa": _2,
          "nagiso": _2,
          "nakagawa": _2,
          "nakano": _2,
          "nozawaonsen": _2,
          "obuse": _2,
          "ogawa": _2,
          "okaya": _2,
          "omachi": _2,
          "omi": _2,
          "ookuwa": _2,
          "ooshika": _2,
          "otaki": _2,
          "otari": _2,
          "sakae": _2,
          "sakaki": _2,
          "saku": _2,
          "sakuho": _2,
          "shimosuwa": _2,
          "shinanomachi": _2,
          "shiojiri": _2,
          "suwa": _2,
          "suzaka": _2,
          "takagi": _2,
          "takamori": _2,
          "takayama": _2,
          "tateshina": _2,
          "tatsuno": _2,
          "togakushi": _2,
          "togura": _2,
          "tomi": _2,
          "ueda": _2,
          "wada": _2,
          "yamagata": _2,
          "yamanouchi": _2,
          "yasaka": _2,
          "yasuoka": _2
        }],
        "nagasaki": [1, {
          "chijiwa": _2,
          "futsu": _2,
          "goto": _2,
          "hasami": _2,
          "hirado": _2,
          "iki": _2,
          "isahaya": _2,
          "kawatana": _2,
          "kuchinotsu": _2,
          "matsuura": _2,
          "nagasaki": _2,
          "obama": _2,
          "omura": _2,
          "oseto": _2,
          "saikai": _2,
          "sasebo": _2,
          "seihi": _2,
          "shimabara": _2,
          "shinkamigoto": _2,
          "togitsu": _2,
          "tsushima": _2,
          "unzen": _2
        }],
        "nara": [1, {
          "ando": _2,
          "gose": _2,
          "heguri": _2,
          "higashiyoshino": _2,
          "ikaruga": _2,
          "ikoma": _2,
          "kamikitayama": _2,
          "kanmaki": _2,
          "kashiba": _2,
          "kashihara": _2,
          "katsuragi": _2,
          "kawai": _2,
          "kawakami": _2,
          "kawanishi": _2,
          "koryo": _2,
          "kurotaki": _2,
          "mitsue": _2,
          "miyake": _2,
          "nara": _2,
          "nosegawa": _2,
          "oji": _2,
          "ouda": _2,
          "oyodo": _2,
          "sakurai": _2,
          "sango": _2,
          "shimoichi": _2,
          "shimokitayama": _2,
          "shinjo": _2,
          "soni": _2,
          "takatori": _2,
          "tawaramoto": _2,
          "tenkawa": _2,
          "tenri": _2,
          "uda": _2,
          "yamatokoriyama": _2,
          "yamatotakada": _2,
          "yamazoe": _2,
          "yoshino": _2
        }],
        "niigata": [1, {
          "aga": _2,
          "agano": _2,
          "gosen": _2,
          "itoigawa": _2,
          "izumozaki": _2,
          "joetsu": _2,
          "kamo": _2,
          "kariwa": _2,
          "kashiwazaki": _2,
          "minamiuonuma": _2,
          "mitsuke": _2,
          "muika": _2,
          "murakami": _2,
          "myoko": _2,
          "nagaoka": _2,
          "niigata": _2,
          "ojiya": _2,
          "omi": _2,
          "sado": _2,
          "sanjo": _2,
          "seiro": _2,
          "seirou": _2,
          "sekikawa": _2,
          "shibata": _2,
          "tagami": _2,
          "tainai": _2,
          "tochio": _2,
          "tokamachi": _2,
          "tsubame": _2,
          "tsunan": _2,
          "uonuma": _2,
          "yahiko": _2,
          "yoita": _2,
          "yuzawa": _2
        }],
        "oita": [1, {
          "beppu": _2,
          "bungoono": _2,
          "bungotakada": _2,
          "hasama": _2,
          "hiji": _2,
          "himeshima": _2,
          "hita": _2,
          "kamitsue": _2,
          "kokonoe": _2,
          "kuju": _2,
          "kunisaki": _2,
          "kusu": _2,
          "oita": _2,
          "saiki": _2,
          "taketa": _2,
          "tsukumi": _2,
          "usa": _2,
          "usuki": _2,
          "yufu": _2
        }],
        "okayama": [1, {
          "akaiwa": _2,
          "asakuchi": _2,
          "bizen": _2,
          "hayashima": _2,
          "ibara": _2,
          "kagamino": _2,
          "kasaoka": _2,
          "kibichuo": _2,
          "kumenan": _2,
          "kurashiki": _2,
          "maniwa": _2,
          "misaki": _2,
          "nagi": _2,
          "niimi": _2,
          "nishiawakura": _2,
          "okayama": _2,
          "satosho": _2,
          "setouchi": _2,
          "shinjo": _2,
          "shoo": _2,
          "soja": _2,
          "takahashi": _2,
          "tamano": _2,
          "tsuyama": _2,
          "wake": _2,
          "yakage": _2
        }],
        "okinawa": [1, {
          "aguni": _2,
          "ginowan": _2,
          "ginoza": _2,
          "gushikami": _2,
          "haebaru": _2,
          "higashi": _2,
          "hirara": _2,
          "iheya": _2,
          "ishigaki": _2,
          "ishikawa": _2,
          "itoman": _2,
          "izena": _2,
          "kadena": _2,
          "kin": _2,
          "kitadaito": _2,
          "kitanakagusuku": _2,
          "kumejima": _2,
          "kunigami": _2,
          "minamidaito": _2,
          "motobu": _2,
          "nago": _2,
          "naha": _2,
          "nakagusuku": _2,
          "nakijin": _2,
          "nanjo": _2,
          "nishihara": _2,
          "ogimi": _2,
          "okinawa": _2,
          "onna": _2,
          "shimoji": _2,
          "taketomi": _2,
          "tarama": _2,
          "tokashiki": _2,
          "tomigusuku": _2,
          "tonaki": _2,
          "urasoe": _2,
          "uruma": _2,
          "yaese": _2,
          "yomitan": _2,
          "yonabaru": _2,
          "yonaguni": _2,
          "zamami": _2
        }],
        "osaka": [1, {
          "abeno": _2,
          "chihayaakasaka": _2,
          "chuo": _2,
          "daito": _2,
          "fujiidera": _2,
          "habikino": _2,
          "hannan": _2,
          "higashiosaka": _2,
          "higashisumiyoshi": _2,
          "higashiyodogawa": _2,
          "hirakata": _2,
          "ibaraki": _2,
          "ikeda": _2,
          "izumi": _2,
          "izumiotsu": _2,
          "izumisano": _2,
          "kadoma": _2,
          "kaizuka": _2,
          "kanan": _2,
          "kashiwara": _2,
          "katano": _2,
          "kawachinagano": _2,
          "kishiwada": _2,
          "kita": _2,
          "kumatori": _2,
          "matsubara": _2,
          "minato": _2,
          "minoh": _2,
          "misaki": _2,
          "moriguchi": _2,
          "neyagawa": _2,
          "nishi": _2,
          "nose": _2,
          "osakasayama": _2,
          "sakai": _2,
          "sayama": _2,
          "sennan": _2,
          "settsu": _2,
          "shijonawate": _2,
          "shimamoto": _2,
          "suita": _2,
          "tadaoka": _2,
          "taishi": _2,
          "tajiri": _2,
          "takaishi": _2,
          "takatsuki": _2,
          "tondabayashi": _2,
          "toyonaka": _2,
          "toyono": _2,
          "yao": _2
        }],
        "saga": [1, {
          "ariake": _2,
          "arita": _2,
          "fukudomi": _2,
          "genkai": _2,
          "hamatama": _2,
          "hizen": _2,
          "imari": _2,
          "kamimine": _2,
          "kanzaki": _2,
          "karatsu": _2,
          "kashima": _2,
          "kitagata": _2,
          "kitahata": _2,
          "kiyama": _2,
          "kouhoku": _2,
          "kyuragi": _2,
          "nishiarita": _2,
          "ogi": _2,
          "omachi": _2,
          "ouchi": _2,
          "saga": _2,
          "shiroishi": _2,
          "taku": _2,
          "tara": _2,
          "tosu": _2,
          "yoshinogari": _2
        }],
        "saitama": [1, {
          "arakawa": _2,
          "asaka": _2,
          "chichibu": _2,
          "fujimi": _2,
          "fujimino": _2,
          "fukaya": _2,
          "hanno": _2,
          "hanyu": _2,
          "hasuda": _2,
          "hatogaya": _2,
          "hatoyama": _2,
          "hidaka": _2,
          "higashichichibu": _2,
          "higashimatsuyama": _2,
          "honjo": _2,
          "ina": _2,
          "iruma": _2,
          "iwatsuki": _2,
          "kamiizumi": _2,
          "kamikawa": _2,
          "kamisato": _2,
          "kasukabe": _2,
          "kawagoe": _2,
          "kawaguchi": _2,
          "kawajima": _2,
          "kazo": _2,
          "kitamoto": _2,
          "koshigaya": _2,
          "kounosu": _2,
          "kuki": _2,
          "kumagaya": _2,
          "matsubushi": _2,
          "minano": _2,
          "misato": _2,
          "miyashiro": _2,
          "miyoshi": _2,
          "moroyama": _2,
          "nagatoro": _2,
          "namegawa": _2,
          "niiza": _2,
          "ogano": _2,
          "ogawa": _2,
          "ogose": _2,
          "okegawa": _2,
          "omiya": _2,
          "otaki": _2,
          "ranzan": _2,
          "ryokami": _2,
          "saitama": _2,
          "sakado": _2,
          "satte": _2,
          "sayama": _2,
          "shiki": _2,
          "shiraoka": _2,
          "soka": _2,
          "sugito": _2,
          "toda": _2,
          "tokigawa": _2,
          "tokorozawa": _2,
          "tsurugashima": _2,
          "urawa": _2,
          "warabi": _2,
          "yashio": _2,
          "yokoze": _2,
          "yono": _2,
          "yorii": _2,
          "yoshida": _2,
          "yoshikawa": _2,
          "yoshimi": _2
        }],
        "shiga": [1, {
          "aisho": _2,
          "gamo": _2,
          "higashiomi": _2,
          "hikone": _2,
          "koka": _2,
          "konan": _2,
          "kosei": _2,
          "koto": _2,
          "kusatsu": _2,
          "maibara": _2,
          "moriyama": _2,
          "nagahama": _2,
          "nishiazai": _2,
          "notogawa": _2,
          "omihachiman": _2,
          "otsu": _2,
          "ritto": _2,
          "ryuoh": _2,
          "takashima": _2,
          "takatsuki": _2,
          "torahime": _2,
          "toyosato": _2,
          "yasu": _2
        }],
        "shimane": [1, {
          "akagi": _2,
          "ama": _2,
          "gotsu": _2,
          "hamada": _2,
          "higashiizumo": _2,
          "hikawa": _2,
          "hikimi": _2,
          "izumo": _2,
          "kakinoki": _2,
          "masuda": _2,
          "matsue": _2,
          "misato": _2,
          "nishinoshima": _2,
          "ohda": _2,
          "okinoshima": _2,
          "okuizumo": _2,
          "shimane": _2,
          "tamayu": _2,
          "tsuwano": _2,
          "unnan": _2,
          "yakumo": _2,
          "yasugi": _2,
          "yatsuka": _2
        }],
        "shizuoka": [1, {
          "arai": _2,
          "atami": _2,
          "fuji": _2,
          "fujieda": _2,
          "fujikawa": _2,
          "fujinomiya": _2,
          "fukuroi": _2,
          "gotemba": _2,
          "haibara": _2,
          "hamamatsu": _2,
          "higashiizu": _2,
          "ito": _2,
          "iwata": _2,
          "izu": _2,
          "izunokuni": _2,
          "kakegawa": _2,
          "kannami": _2,
          "kawanehon": _2,
          "kawazu": _2,
          "kikugawa": _2,
          "kosai": _2,
          "makinohara": _2,
          "matsuzaki": _2,
          "minamiizu": _2,
          "mishima": _2,
          "morimachi": _2,
          "nishiizu": _2,
          "numazu": _2,
          "omaezaki": _2,
          "shimada": _2,
          "shimizu": _2,
          "shimoda": _2,
          "shizuoka": _2,
          "susono": _2,
          "yaizu": _2,
          "yoshida": _2
        }],
        "tochigi": [1, {
          "ashikaga": _2,
          "bato": _2,
          "haga": _2,
          "ichikai": _2,
          "iwafune": _2,
          "kaminokawa": _2,
          "kanuma": _2,
          "karasuyama": _2,
          "kuroiso": _2,
          "mashiko": _2,
          "mibu": _2,
          "moka": _2,
          "motegi": _2,
          "nasu": _2,
          "nasushiobara": _2,
          "nikko": _2,
          "nishikata": _2,
          "nogi": _2,
          "ohira": _2,
          "ohtawara": _2,
          "oyama": _2,
          "sakura": _2,
          "sano": _2,
          "shimotsuke": _2,
          "shioya": _2,
          "takanezawa": _2,
          "tochigi": _2,
          "tsuga": _2,
          "ujiie": _2,
          "utsunomiya": _2,
          "yaita": _2
        }],
        "tokushima": [1, {
          "aizumi": _2,
          "anan": _2,
          "ichiba": _2,
          "itano": _2,
          "kainan": _2,
          "komatsushima": _2,
          "matsushige": _2,
          "mima": _2,
          "minami": _2,
          "miyoshi": _2,
          "mugi": _2,
          "nakagawa": _2,
          "naruto": _2,
          "sanagochi": _2,
          "shishikui": _2,
          "tokushima": _2,
          "wajiki": _2
        }],
        "tokyo": [1, {
          "adachi": _2,
          "akiruno": _2,
          "akishima": _2,
          "aogashima": _2,
          "arakawa": _2,
          "bunkyo": _2,
          "chiyoda": _2,
          "chofu": _2,
          "chuo": _2,
          "edogawa": _2,
          "fuchu": _2,
          "fussa": _2,
          "hachijo": _2,
          "hachioji": _2,
          "hamura": _2,
          "higashikurume": _2,
          "higashimurayama": _2,
          "higashiyamato": _2,
          "hino": _2,
          "hinode": _2,
          "hinohara": _2,
          "inagi": _2,
          "itabashi": _2,
          "katsushika": _2,
          "kita": _2,
          "kiyose": _2,
          "kodaira": _2,
          "koganei": _2,
          "kokubunji": _2,
          "komae": _2,
          "koto": _2,
          "kouzushima": _2,
          "kunitachi": _2,
          "machida": _2,
          "meguro": _2,
          "minato": _2,
          "mitaka": _2,
          "mizuho": _2,
          "musashimurayama": _2,
          "musashino": _2,
          "nakano": _2,
          "nerima": _2,
          "ogasawara": _2,
          "okutama": _2,
          "ome": _2,
          "oshima": _2,
          "ota": _2,
          "setagaya": _2,
          "shibuya": _2,
          "shinagawa": _2,
          "shinjuku": _2,
          "suginami": _2,
          "sumida": _2,
          "tachikawa": _2,
          "taito": _2,
          "tama": _2,
          "toshima": _2
        }],
        "tottori": [1, {
          "chizu": _2,
          "hino": _2,
          "kawahara": _2,
          "koge": _2,
          "kotoura": _2,
          "misasa": _2,
          "nanbu": _2,
          "nichinan": _2,
          "sakaiminato": _2,
          "tottori": _2,
          "wakasa": _2,
          "yazu": _2,
          "yonago": _2
        }],
        "toyama": [1, {
          "asahi": _2,
          "fuchu": _2,
          "fukumitsu": _2,
          "funahashi": _2,
          "himi": _2,
          "imizu": _2,
          "inami": _2,
          "johana": _2,
          "kamiichi": _2,
          "kurobe": _2,
          "nakaniikawa": _2,
          "namerikawa": _2,
          "nanto": _2,
          "nyuzen": _2,
          "oyabe": _2,
          "taira": _2,
          "takaoka": _2,
          "tateyama": _2,
          "toga": _2,
          "tonami": _2,
          "toyama": _2,
          "unazuki": _2,
          "uozu": _2,
          "yamada": _2
        }],
        "wakayama": [1, {
          "arida": _2,
          "aridagawa": _2,
          "gobo": _2,
          "hashimoto": _2,
          "hidaka": _2,
          "hirogawa": _2,
          "inami": _2,
          "iwade": _2,
          "kainan": _2,
          "kamitonda": _2,
          "katsuragi": _2,
          "kimino": _2,
          "kinokawa": _2,
          "kitayama": _2,
          "koya": _2,
          "koza": _2,
          "kozagawa": _2,
          "kudoyama": _2,
          "kushimoto": _2,
          "mihama": _2,
          "misato": _2,
          "nachikatsuura": _2,
          "shingu": _2,
          "shirahama": _2,
          "taiji": _2,
          "tanabe": _2,
          "wakayama": _2,
          "yuasa": _2,
          "yura": _2
        }],
        "yamagata": [1, {
          "asahi": _2,
          "funagata": _2,
          "higashine": _2,
          "iide": _2,
          "kahoku": _2,
          "kaminoyama": _2,
          "kaneyama": _2,
          "kawanishi": _2,
          "mamurogawa": _2,
          "mikawa": _2,
          "murayama": _2,
          "nagai": _2,
          "nakayama": _2,
          "nanyo": _2,
          "nishikawa": _2,
          "obanazawa": _2,
          "oe": _2,
          "oguni": _2,
          "ohkura": _2,
          "oishida": _2,
          "sagae": _2,
          "sakata": _2,
          "sakegawa": _2,
          "shinjo": _2,
          "shirataka": _2,
          "shonai": _2,
          "takahata": _2,
          "tendo": _2,
          "tozawa": _2,
          "tsuruoka": _2,
          "yamagata": _2,
          "yamanobe": _2,
          "yonezawa": _2,
          "yuza": _2
        }],
        "yamaguchi": [1, {
          "abu": _2,
          "hagi": _2,
          "hikari": _2,
          "hofu": _2,
          "iwakuni": _2,
          "kudamatsu": _2,
          "mitou": _2,
          "nagato": _2,
          "oshima": _2,
          "shimonoseki": _2,
          "shunan": _2,
          "tabuse": _2,
          "tokuyama": _2,
          "toyota": _2,
          "ube": _2,
          "yuu": _2
        }],
        "yamanashi": [1, {
          "chuo": _2,
          "doshi": _2,
          "fuefuki": _2,
          "fujikawa": _2,
          "fujikawaguchiko": _2,
          "fujiyoshida": _2,
          "hayakawa": _2,
          "hokuto": _2,
          "ichikawamisato": _2,
          "kai": _2,
          "kofu": _2,
          "koshu": _2,
          "kosuge": _2,
          "minami-alps": _2,
          "minobu": _2,
          "nakamichi": _2,
          "nanbu": _2,
          "narusawa": _2,
          "nirasaki": _2,
          "nishikatsura": _2,
          "oshino": _2,
          "otsuki": _2,
          "showa": _2,
          "tabayama": _2,
          "tsuru": _2,
          "uenohara": _2,
          "yamanakako": _2,
          "yamanashi": _2
        }],
        "xn--ehqz56n": _2,
        "三重": _2,
        "xn--1lqs03n": _2,
        "京都": _2,
        "xn--qqqt11m": _2,
        "佐賀": _2,
        "xn--f6qx53a": _2,
        "兵庫": _2,
        "xn--djrs72d6uy": _2,
        "北海道": _2,
        "xn--mkru45i": _2,
        "千葉": _2,
        "xn--0trq7p7nn": _2,
        "和歌山": _2,
        "xn--5js045d": _2,
        "埼玉": _2,
        "xn--kbrq7o": _2,
        "大分": _2,
        "xn--pssu33l": _2,
        "大阪": _2,
        "xn--ntsq17g": _2,
        "奈良": _2,
        "xn--uisz3g": _2,
        "宮城": _2,
        "xn--6btw5a": _2,
        "宮崎": _2,
        "xn--1ctwo": _2,
        "富山": _2,
        "xn--6orx2r": _2,
        "山口": _2,
        "xn--rht61e": _2,
        "山形": _2,
        "xn--rht27z": _2,
        "山梨": _2,
        "xn--nit225k": _2,
        "岐阜": _2,
        "xn--rht3d": _2,
        "岡山": _2,
        "xn--djty4k": _2,
        "岩手": _2,
        "xn--klty5x": _2,
        "島根": _2,
        "xn--kltx9a": _2,
        "広島": _2,
        "xn--kltp7d": _2,
        "徳島": _2,
        "xn--c3s14m": _2,
        "愛媛": _2,
        "xn--vgu402c": _2,
        "愛知": _2,
        "xn--efvn9s": _2,
        "新潟": _2,
        "xn--1lqs71d": _2,
        "東京": _2,
        "xn--4pvxs": _2,
        "栃木": _2,
        "xn--uuwu58a": _2,
        "沖縄": _2,
        "xn--zbx025d": _2,
        "滋賀": _2,
        "xn--8pvr4u": _2,
        "熊本": _2,
        "xn--5rtp49c": _2,
        "石川": _2,
        "xn--ntso0iqx3a": _2,
        "神奈川": _2,
        "xn--elqq16h": _2,
        "福井": _2,
        "xn--4it168d": _2,
        "福岡": _2,
        "xn--klt787d": _2,
        "福島": _2,
        "xn--rny31h": _2,
        "秋田": _2,
        "xn--7t0a264c": _2,
        "群馬": _2,
        "xn--uist22h": _2,
        "茨城": _2,
        "xn--8ltr62k": _2,
        "長崎": _2,
        "xn--2m4a15e": _2,
        "長野": _2,
        "xn--32vp30h": _2,
        "青森": _2,
        "xn--4it797k": _2,
        "静岡": _2,
        "xn--5rtq34k": _2,
        "香川": _2,
        "xn--k7yn95e": _2,
        "高知": _2,
        "xn--tor131o": _2,
        "鳥取": _2,
        "xn--d5qv7z876c": _2,
        "鹿児島": _2,
        "kawasaki": _18,
        "kitakyushu": _18,
        "kobe": _18,
        "nagoya": _18,
        "sapporo": _18,
        "sendai": _18,
        "yokohama": _18,
        "buyshop": _3,
        "fashionstore": _3,
        "handcrafted": _3,
        "kawaiishop": _3,
        "supersale": _3,
        "theshop": _3,
        "0am": _3,
        "0g0": _3,
        "0j0": _3,
        "0t0": _3,
        "mydns": _3,
        "pgw": _3,
        "wjg": _3,
        "usercontent": _3,
        "angry": _3,
        "babyblue": _3,
        "babymilk": _3,
        "backdrop": _3,
        "bambina": _3,
        "bitter": _3,
        "blush": _3,
        "boo": _3,
        "boy": _3,
        "boyfriend": _3,
        "but": _3,
        "candypop": _3,
        "capoo": _3,
        "catfood": _3,
        "cheap": _3,
        "chicappa": _3,
        "chillout": _3,
        "chips": _3,
        "chowder": _3,
        "chu": _3,
        "ciao": _3,
        "cocotte": _3,
        "coolblog": _3,
        "cranky": _3,
        "cutegirl": _3,
        "daa": _3,
        "deca": _3,
        "deci": _3,
        "digick": _3,
        "egoism": _3,
        "fakefur": _3,
        "fem": _3,
        "flier": _3,
        "floppy": _3,
        "fool": _3,
        "frenchkiss": _3,
        "girlfriend": _3,
        "girly": _3,
        "gloomy": _3,
        "gonna": _3,
        "greater": _3,
        "hacca": _3,
        "heavy": _3,
        "her": _3,
        "hiho": _3,
        "hippy": _3,
        "holy": _3,
        "hungry": _3,
        "icurus": _3,
        "itigo": _3,
        "jellybean": _3,
        "kikirara": _3,
        "kill": _3,
        "kilo": _3,
        "kuron": _3,
        "littlestar": _3,
        "lolipopmc": _3,
        "lolitapunk": _3,
        "lomo": _3,
        "lovepop": _3,
        "lovesick": _3,
        "main": _3,
        "mods": _3,
        "mond": _3,
        "mongolian": _3,
        "moo": _3,
        "namaste": _3,
        "nikita": _3,
        "nobushi": _3,
        "noor": _3,
        "oops": _3,
        "parallel": _3,
        "parasite": _3,
        "pecori": _3,
        "peewee": _3,
        "penne": _3,
        "pepper": _3,
        "perma": _3,
        "pigboat": _3,
        "pinoko": _3,
        "punyu": _3,
        "pupu": _3,
        "pussycat": _3,
        "pya": _3,
        "raindrop": _3,
        "readymade": _3,
        "sadist": _3,
        "schoolbus": _3,
        "secret": _3,
        "staba": _3,
        "stripper": _3,
        "sub": _3,
        "sunnyday": _3,
        "thick": _3,
        "tonkotsu": _3,
        "under": _3,
        "upper": _3,
        "velvet": _3,
        "verse": _3,
        "versus": _3,
        "vivian": _3,
        "watson": _3,
        "weblike": _3,
        "whitesnow": _3,
        "zombie": _3,
        "hateblo": _3,
        "hatenablog": _3,
        "hatenadiary": _3,
        "2-d": _3,
        "bona": _3,
        "crap": _3,
        "daynight": _3,
        "eek": _3,
        "flop": _3,
        "halfmoon": _3,
        "jeez": _3,
        "matrix": _3,
        "mimoza": _3,
        "netgamers": _3,
        "nyanta": _3,
        "o0o0": _3,
        "rdy": _3,
        "rgr": _3,
        "rulez": _3,
        "sakurastorage": [0, {
          "isk01": _57,
          "isk02": _57
        }],
        "saloon": _3,
        "sblo": _3,
        "skr": _3,
        "tank": _3,
        "uh-oh": _3,
        "undo": _3,
        "webaccel": [0, {
          "rs": _3,
          "user": _3
        }],
        "websozai": _3,
        "xii": _3
      }],
      "ke": [1, {
        "ac": _2,
        "co": _2,
        "go": _2,
        "info": _2,
        "me": _2,
        "mobi": _2,
        "ne": _2,
        "or": _2,
        "sc": _2
      }],
      "kg": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "us": _3,
        "xx": _3
      }],
      "kh": _18,
      "ki": _58,
      "km": [1, {
        "ass": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "nom": _2,
        "org": _2,
        "prd": _2,
        "tm": _2,
        "asso": _2,
        "coop": _2,
        "gouv": _2,
        "medecin": _2,
        "notaires": _2,
        "pharmaciens": _2,
        "presse": _2,
        "veterinaire": _2
      }],
      "kn": [1, {
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2
      }],
      "kp": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "org": _2,
        "rep": _2,
        "tra": _2
      }],
      "kr": [1, {
        "ac": _2,
        "ai": _2,
        "co": _2,
        "es": _2,
        "go": _2,
        "hs": _2,
        "io": _2,
        "it": _2,
        "kg": _2,
        "me": _2,
        "mil": _2,
        "ms": _2,
        "ne": _2,
        "or": _2,
        "pe": _2,
        "re": _2,
        "sc": _2,
        "busan": _2,
        "chungbuk": _2,
        "chungnam": _2,
        "daegu": _2,
        "daejeon": _2,
        "gangwon": _2,
        "gwangju": _2,
        "gyeongbuk": _2,
        "gyeonggi": _2,
        "gyeongnam": _2,
        "incheon": _2,
        "jeju": _2,
        "jeonbuk": _2,
        "jeonnam": _2,
        "seoul": _2,
        "ulsan": _2,
        "c01": _3,
        "eliv-cdn": _3,
        "eliv-dns": _3,
        "mmv": _3,
        "vki": _3
      }],
      "kw": [1, {
        "com": _2,
        "edu": _2,
        "emb": _2,
        "gov": _2,
        "ind": _2,
        "net": _2,
        "org": _2
      }],
      "ky": _45,
      "kz": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "jcloud": _3
      }],
      "la": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "int": _2,
        "net": _2,
        "org": _2,
        "per": _2,
        "bnr": _3
      }],
      "lb": _4,
      "lc": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "oy": _3
      }],
      "li": _2,
      "lk": [1, {
        "ac": _2,
        "assn": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "grp": _2,
        "hotel": _2,
        "int": _2,
        "ltd": _2,
        "net": _2,
        "ngo": _2,
        "org": _2,
        "sch": _2,
        "soc": _2,
        "web": _2
      }],
      "lr": _4,
      "ls": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "net": _2,
        "org": _2,
        "sc": _2
      }],
      "lt": _10,
      "lu": [1, {
        "123website": _3
      }],
      "lv": [1, {
        "asn": _2,
        "com": _2,
        "conf": _2,
        "edu": _2,
        "gov": _2,
        "id": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "ly": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "id": _2,
        "med": _2,
        "net": _2,
        "org": _2,
        "plc": _2,
        "sch": _2
      }],
      "ma": [1, {
        "ac": _2,
        "co": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "press": _2
      }],
      "mc": [1, {
        "asso": _2,
        "tm": _2
      }],
      "md": [1, {
        "ir": _3
      }],
      "me": [1, {
        "ac": _2,
        "co": _2,
        "edu": _2,
        "gov": _2,
        "its": _2,
        "net": _2,
        "org": _2,
        "priv": _2,
        "c66": _3,
        "craft": _3,
        "edgestack": _3,
        "filegear": _3,
        "filegear-sg": _3,
        "lohmus": _3,
        "barsy": _3,
        "mcdir": _3,
        "brasilia": _3,
        "ddns": _3,
        "dnsfor": _3,
        "hopto": _3,
        "loginto": _3,
        "noip": _3,
        "webhop": _3,
        "soundcast": _3,
        "tcp4": _3,
        "vp4": _3,
        "diskstation": _3,
        "dscloud": _3,
        "i234": _3,
        "myds": _3,
        "synology": _3,
        "transip": _44,
        "nohost": _3
      }],
      "mg": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "nom": _2,
        "org": _2,
        "prd": _2
      }],
      "mh": _2,
      "mil": _2,
      "mk": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "inf": _2,
        "name": _2,
        "net": _2,
        "org": _2
      }],
      "ml": [1, {
        "ac": _2,
        "art": _2,
        "asso": _2,
        "com": _2,
        "edu": _2,
        "gouv": _2,
        "gov": _2,
        "info": _2,
        "inst": _2,
        "net": _2,
        "org": _2,
        "pr": _2,
        "presse": _2
      }],
      "mm": _18,
      "mn": [1, {
        "edu": _2,
        "gov": _2,
        "org": _2,
        "nyc": _3
      }],
      "mo": _4,
      "mobi": [1, {
        "barsy": _3,
        "dscloud": _3
      }],
      "mp": [1, {
        "ju": _3
      }],
      "mq": _2,
      "mr": _10,
      "ms": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "minisite": _3
      }],
      "mt": _45,
      "mu": [1, {
        "ac": _2,
        "co": _2,
        "com": _2,
        "gov": _2,
        "net": _2,
        "or": _2,
        "org": _2
      }],
      "museum": _2,
      "mv": [1, {
        "aero": _2,
        "biz": _2,
        "com": _2,
        "coop": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "int": _2,
        "mil": _2,
        "museum": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pro": _2
      }],
      "mw": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "com": _2,
        "coop": _2,
        "edu": _2,
        "gov": _2,
        "int": _2,
        "net": _2,
        "org": _2
      }],
      "mx": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "net": _2,
        "org": _2
      }],
      "my": [1, {
        "biz": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2
      }],
      "mz": [1, {
        "ac": _2,
        "adv": _2,
        "co": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "na": [1, {
        "alt": _2,
        "co": _2,
        "com": _2,
        "gov": _2,
        "net": _2,
        "org": _2
      }],
      "name": [1, {
        "her": _61,
        "his": _61
      }],
      "nc": [1, {
        "asso": _2,
        "nom": _2
      }],
      "ne": _2,
      "net": [1, {
        "adobeaemcloud": _3,
        "adobeio-static": _3,
        "adobeioruntime": _3,
        "akadns": _3,
        "akamai": _3,
        "akamai-staging": _3,
        "akamaiedge": _3,
        "akamaiedge-staging": _3,
        "akamaihd": _3,
        "akamaihd-staging": _3,
        "akamaiorigin": _3,
        "akamaiorigin-staging": _3,
        "akamaized": _3,
        "akamaized-staging": _3,
        "edgekey": _3,
        "edgekey-staging": _3,
        "edgesuite": _3,
        "edgesuite-staging": _3,
        "alwaysdata": _3,
        "myamaze": _3,
        "cloudfront": _3,
        "appudo": _3,
        "atlassian-dev": [0, {
          "prod": _53
        }],
        "myfritz": _3,
        "onavstack": _3,
        "shopselect": _3,
        "blackbaudcdn": _3,
        "boomla": _3,
        "bplaced": _3,
        "square7": _3,
        "cdn77": [0, {
          "r": _3
        }],
        "cdn77-ssl": _3,
        "gb": _3,
        "hu": _3,
        "jp": _3,
        "se": _3,
        "uk": _3,
        "clickrising": _3,
        "ddns-ip": _3,
        "dns-cloud": _3,
        "dns-dynamic": _3,
        "cloudaccess": _3,
        "cloudflare": [2, {
          "cdn": _3
        }],
        "cloudflareanycast": _53,
        "cloudflarecn": _53,
        "cloudflareglobal": _53,
        "ctfcloud": _3,
        "feste-ip": _3,
        "knx-server": _3,
        "static-access": _3,
        "cryptonomic": _6,
        "dattolocal": _3,
        "mydatto": _3,
        "debian": _3,
        "definima": _3,
        "deno": _3,
        "icp": _6,
        "at-band-camp": _3,
        "blogdns": _3,
        "broke-it": _3,
        "buyshouses": _3,
        "dnsalias": _3,
        "dnsdojo": _3,
        "does-it": _3,
        "dontexist": _3,
        "dynalias": _3,
        "dynathome": _3,
        "endofinternet": _3,
        "from-az": _3,
        "from-co": _3,
        "from-la": _3,
        "from-ny": _3,
        "gets-it": _3,
        "ham-radio-op": _3,
        "homeftp": _3,
        "homeip": _3,
        "homelinux": _3,
        "homeunix": _3,
        "in-the-band": _3,
        "is-a-chef": _3,
        "is-a-geek": _3,
        "isa-geek": _3,
        "kicks-ass": _3,
        "office-on-the": _3,
        "podzone": _3,
        "scrapper-site": _3,
        "selfip": _3,
        "sells-it": _3,
        "servebbs": _3,
        "serveftp": _3,
        "thruhere": _3,
        "webhop": _3,
        "casacam": _3,
        "dynu": _3,
        "dynv6": _3,
        "twmail": _3,
        "ru": _3,
        "channelsdvr": [2, {
          "u": _3
        }],
        "fastly": [0, {
          "freetls": _3,
          "map": _3,
          "prod": [0, {
            "a": _3,
            "global": _3
          }],
          "ssl": [0, {
            "a": _3,
            "b": _3,
            "global": _3
          }]
        }],
        "fastlylb": [2, {
          "map": _3
        }],
        "edgeapp": _3,
        "keyword-on": _3,
        "live-on": _3,
        "server-on": _3,
        "cdn-edges": _3,
        "heteml": _3,
        "cloudfunctions": _3,
        "grafana-dev": _3,
        "iobb": _3,
        "moonscale": _3,
        "in-dsl": _3,
        "in-vpn": _3,
        "oninferno": _3,
        "botdash": _3,
        "apps-1and1": _3,
        "ipifony": _3,
        "cloudjiffy": [2, {
          "fra1-de": _3,
          "west1-us": _3
        }],
        "elastx": [0, {
          "jls-sto1": _3,
          "jls-sto2": _3,
          "jls-sto3": _3
        }],
        "massivegrid": [0, {
          "paas": [0, {
            "fr-1": _3,
            "lon-1": _3,
            "lon-2": _3,
            "ny-1": _3,
            "ny-2": _3,
            "sg-1": _3
          }]
        }],
        "saveincloud": [0, {
          "jelastic": _3,
          "nordeste-idc": _3
        }],
        "scaleforce": _46,
        "kinghost": _3,
        "uni5": _3,
        "krellian": _3,
        "ggff": _3,
        "localcert": _3,
        "localto": _6,
        "barsy": _3,
        "luyani": _3,
        "memset": _3,
        "azure-api": _3,
        "azure-mobile": _3,
        "azureedge": _3,
        "azurefd": _3,
        "azurestaticapps": [2, {
          "1": _3,
          "2": _3,
          "3": _3,
          "4": _3,
          "5": _3,
          "6": _3,
          "7": _3,
          "centralus": _3,
          "eastasia": _3,
          "eastus2": _3,
          "westeurope": _3,
          "westus2": _3
        }],
        "azurewebsites": _3,
        "cloudapp": _3,
        "trafficmanager": _3,
        "windows": [0, {
          "core": [0, {
            "blob": _3
          }],
          "servicebus": _3
        }],
        "mynetname": [0, {
          "sn": _3
        }],
        "routingthecloud": _3,
        "bounceme": _3,
        "ddns": _3,
        "eating-organic": _3,
        "mydissent": _3,
        "myeffect": _3,
        "mymediapc": _3,
        "mypsx": _3,
        "mysecuritycamera": _3,
        "nhlfan": _3,
        "no-ip": _3,
        "pgafan": _3,
        "privatizehealthinsurance": _3,
        "redirectme": _3,
        "serveblog": _3,
        "serveminecraft": _3,
        "sytes": _3,
        "dnsup": _3,
        "hicam": _3,
        "now-dns": _3,
        "ownip": _3,
        "vpndns": _3,
        "cloudycluster": _3,
        "ovh": [0, {
          "hosting": _6,
          "webpaas": _6
        }],
        "rackmaze": _3,
        "myradweb": _3,
        "in": _3,
        "subsc-pay": _3,
        "squares": _3,
        "schokokeks": _3,
        "firewall-gateway": _3,
        "seidat": _3,
        "senseering": _3,
        "siteleaf": _3,
        "mafelo": _3,
        "myspreadshop": _3,
        "vps-host": [2, {
          "jelastic": [0, {
            "atl": _3,
            "njs": _3,
            "ric": _3
          }]
        }],
        "srcf": [0, {
          "soc": _3,
          "user": _3
        }],
        "supabase": _3,
        "dsmynas": _3,
        "familyds": _3,
        "ts": [2, {
          "c": _6
        }],
        "torproject": [2, {
          "pages": _3
        }],
        "vusercontent": _3,
        "reserve-online": _3,
        "community-pro": _3,
        "meinforum": _3,
        "yandexcloud": [2, {
          "storage": _3,
          "website": _3
        }],
        "za": _3,
        "zabc": _3
      }],
      "nf": [1, {
        "arts": _2,
        "com": _2,
        "firm": _2,
        "info": _2,
        "net": _2,
        "other": _2,
        "per": _2,
        "rec": _2,
        "store": _2,
        "web": _2
      }],
      "ng": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "i": _2,
        "mil": _2,
        "mobi": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "sch": _2,
        "biz": [2, {
          "co": _3,
          "dl": _3,
          "go": _3,
          "lg": _3,
          "on": _3
        }],
        "col": _3,
        "firm": _3,
        "gen": _3,
        "ltd": _3,
        "ngo": _3,
        "plc": _3
      }],
      "ni": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gob": _2,
        "in": _2,
        "info": _2,
        "int": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "web": _2
      }],
      "nl": [1, {
        "co": _3,
        "hosting-cluster": _3,
        "gov": _3,
        "khplay": _3,
        "123website": _3,
        "myspreadshop": _3,
        "transurl": _6,
        "cistron": _3,
        "demon": _3
      }],
      "no": [1, {
        "fhs": _2,
        "folkebibl": _2,
        "fylkesbibl": _2,
        "idrett": _2,
        "museum": _2,
        "priv": _2,
        "vgs": _2,
        "dep": _2,
        "herad": _2,
        "kommune": _2,
        "mil": _2,
        "stat": _2,
        "aa": _62,
        "ah": _62,
        "bu": _62,
        "fm": _62,
        "hl": _62,
        "hm": _62,
        "jan-mayen": _62,
        "mr": _62,
        "nl": _62,
        "nt": _62,
        "of": _62,
        "ol": _62,
        "oslo": _62,
        "rl": _62,
        "sf": _62,
        "st": _62,
        "svalbard": _62,
        "tm": _62,
        "tr": _62,
        "va": _62,
        "vf": _62,
        "akrehamn": _2,
        "xn--krehamn-dxa": _2,
        "åkrehamn": _2,
        "algard": _2,
        "xn--lgrd-poac": _2,
        "ålgård": _2,
        "arna": _2,
        "bronnoysund": _2,
        "xn--brnnysund-m8ac": _2,
        "brønnøysund": _2,
        "brumunddal": _2,
        "bryne": _2,
        "drobak": _2,
        "xn--drbak-wua": _2,
        "drøbak": _2,
        "egersund": _2,
        "fetsund": _2,
        "floro": _2,
        "xn--flor-jra": _2,
        "florø": _2,
        "fredrikstad": _2,
        "hokksund": _2,
        "honefoss": _2,
        "xn--hnefoss-q1a": _2,
        "hønefoss": _2,
        "jessheim": _2,
        "jorpeland": _2,
        "xn--jrpeland-54a": _2,
        "jørpeland": _2,
        "kirkenes": _2,
        "kopervik": _2,
        "krokstadelva": _2,
        "langevag": _2,
        "xn--langevg-jxa": _2,
        "langevåg": _2,
        "leirvik": _2,
        "mjondalen": _2,
        "xn--mjndalen-64a": _2,
        "mjøndalen": _2,
        "mo-i-rana": _2,
        "mosjoen": _2,
        "xn--mosjen-eya": _2,
        "mosjøen": _2,
        "nesoddtangen": _2,
        "orkanger": _2,
        "osoyro": _2,
        "xn--osyro-wua": _2,
        "osøyro": _2,
        "raholt": _2,
        "xn--rholt-mra": _2,
        "råholt": _2,
        "sandnessjoen": _2,
        "xn--sandnessjen-ogb": _2,
        "sandnessjøen": _2,
        "skedsmokorset": _2,
        "slattum": _2,
        "spjelkavik": _2,
        "stathelle": _2,
        "stavern": _2,
        "stjordalshalsen": _2,
        "xn--stjrdalshalsen-sqb": _2,
        "stjørdalshalsen": _2,
        "tananger": _2,
        "tranby": _2,
        "vossevangen": _2,
        "aarborte": _2,
        "aejrie": _2,
        "afjord": _2,
        "xn--fjord-lra": _2,
        "åfjord": _2,
        "agdenes": _2,
        "akershus": _63,
        "aknoluokta": _2,
        "xn--koluokta-7ya57h": _2,
        "ákŋoluokta": _2,
        "al": _2,
        "xn--l-1fa": _2,
        "ål": _2,
        "alaheadju": _2,
        "xn--laheadju-7ya": _2,
        "álaheadju": _2,
        "alesund": _2,
        "xn--lesund-hua": _2,
        "ålesund": _2,
        "alstahaug": _2,
        "alta": _2,
        "xn--lt-liac": _2,
        "áltá": _2,
        "alvdal": _2,
        "amli": _2,
        "xn--mli-tla": _2,
        "åmli": _2,
        "amot": _2,
        "xn--mot-tla": _2,
        "åmot": _2,
        "andasuolo": _2,
        "andebu": _2,
        "andoy": _2,
        "xn--andy-ira": _2,
        "andøy": _2,
        "ardal": _2,
        "xn--rdal-poa": _2,
        "årdal": _2,
        "aremark": _2,
        "arendal": _2,
        "xn--s-1fa": _2,
        "ås": _2,
        "aseral": _2,
        "xn--seral-lra": _2,
        "åseral": _2,
        "asker": _2,
        "askim": _2,
        "askoy": _2,
        "xn--asky-ira": _2,
        "askøy": _2,
        "askvoll": _2,
        "asnes": _2,
        "xn--snes-poa": _2,
        "åsnes": _2,
        "audnedaln": _2,
        "aukra": _2,
        "aure": _2,
        "aurland": _2,
        "aurskog-holand": _2,
        "xn--aurskog-hland-jnb": _2,
        "aurskog-høland": _2,
        "austevoll": _2,
        "austrheim": _2,
        "averoy": _2,
        "xn--avery-yua": _2,
        "averøy": _2,
        "badaddja": _2,
        "xn--bdddj-mrabd": _2,
        "bådåddjå": _2,
        "xn--brum-voa": _2,
        "bærum": _2,
        "bahcavuotna": _2,
        "xn--bhcavuotna-s4a": _2,
        "báhcavuotna": _2,
        "bahccavuotna": _2,
        "xn--bhccavuotna-k7a": _2,
        "báhccavuotna": _2,
        "baidar": _2,
        "xn--bidr-5nac": _2,
        "báidár": _2,
        "bajddar": _2,
        "xn--bjddar-pta": _2,
        "bájddar": _2,
        "balat": _2,
        "xn--blt-elab": _2,
        "bálát": _2,
        "balestrand": _2,
        "ballangen": _2,
        "balsfjord": _2,
        "bamble": _2,
        "bardu": _2,
        "barum": _2,
        "batsfjord": _2,
        "xn--btsfjord-9za": _2,
        "båtsfjord": _2,
        "bearalvahki": _2,
        "xn--bearalvhki-y4a": _2,
        "bearalváhki": _2,
        "beardu": _2,
        "beiarn": _2,
        "berg": _2,
        "bergen": _2,
        "berlevag": _2,
        "xn--berlevg-jxa": _2,
        "berlevåg": _2,
        "bievat": _2,
        "xn--bievt-0qa": _2,
        "bievát": _2,
        "bindal": _2,
        "birkenes": _2,
        "bjarkoy": _2,
        "xn--bjarky-fya": _2,
        "bjarkøy": _2,
        "bjerkreim": _2,
        "bjugn": _2,
        "bodo": _2,
        "xn--bod-2na": _2,
        "bodø": _2,
        "bokn": _2,
        "bomlo": _2,
        "xn--bmlo-gra": _2,
        "bømlo": _2,
        "bremanger": _2,
        "bronnoy": _2,
        "xn--brnny-wuac": _2,
        "brønnøy": _2,
        "budejju": _2,
        "buskerud": _63,
        "bygland": _2,
        "bykle": _2,
        "cahcesuolo": _2,
        "xn--hcesuolo-7ya35b": _2,
        "čáhcesuolo": _2,
        "davvenjarga": _2,
        "xn--davvenjrga-y4a": _2,
        "davvenjárga": _2,
        "davvesiida": _2,
        "deatnu": _2,
        "dielddanuorri": _2,
        "divtasvuodna": _2,
        "divttasvuotna": _2,
        "donna": _2,
        "xn--dnna-gra": _2,
        "dønna": _2,
        "dovre": _2,
        "drammen": _2,
        "drangedal": _2,
        "dyroy": _2,
        "xn--dyry-ira": _2,
        "dyrøy": _2,
        "eid": _2,
        "eidfjord": _2,
        "eidsberg": _2,
        "eidskog": _2,
        "eidsvoll": _2,
        "eigersund": _2,
        "elverum": _2,
        "enebakk": _2,
        "engerdal": _2,
        "etne": _2,
        "etnedal": _2,
        "evenassi": _2,
        "xn--eveni-0qa01ga": _2,
        "evenášši": _2,
        "evenes": _2,
        "evje-og-hornnes": _2,
        "farsund": _2,
        "fauske": _2,
        "fedje": _2,
        "fet": _2,
        "finnoy": _2,
        "xn--finny-yua": _2,
        "finnøy": _2,
        "fitjar": _2,
        "fjaler": _2,
        "fjell": _2,
        "fla": _2,
        "xn--fl-zia": _2,
        "flå": _2,
        "flakstad": _2,
        "flatanger": _2,
        "flekkefjord": _2,
        "flesberg": _2,
        "flora": _2,
        "folldal": _2,
        "forde": _2,
        "xn--frde-gra": _2,
        "førde": _2,
        "forsand": _2,
        "fosnes": _2,
        "xn--frna-woa": _2,
        "fræna": _2,
        "frana": _2,
        "frei": _2,
        "frogn": _2,
        "froland": _2,
        "frosta": _2,
        "froya": _2,
        "xn--frya-hra": _2,
        "frøya": _2,
        "fuoisku": _2,
        "fuossko": _2,
        "fusa": _2,
        "fyresdal": _2,
        "gaivuotna": _2,
        "xn--givuotna-8ya": _2,
        "gáivuotna": _2,
        "galsa": _2,
        "xn--gls-elac": _2,
        "gálsá": _2,
        "gamvik": _2,
        "gangaviika": _2,
        "xn--ggaviika-8ya47h": _2,
        "gáŋgaviika": _2,
        "gaular": _2,
        "gausdal": _2,
        "giehtavuoatna": _2,
        "gildeskal": _2,
        "xn--gildeskl-g0a": _2,
        "gildeskål": _2,
        "giske": _2,
        "gjemnes": _2,
        "gjerdrum": _2,
        "gjerstad": _2,
        "gjesdal": _2,
        "gjovik": _2,
        "xn--gjvik-wua": _2,
        "gjøvik": _2,
        "gloppen": _2,
        "gol": _2,
        "gran": _2,
        "grane": _2,
        "granvin": _2,
        "gratangen": _2,
        "grimstad": _2,
        "grong": _2,
        "grue": _2,
        "gulen": _2,
        "guovdageaidnu": _2,
        "ha": _2,
        "xn--h-2fa": _2,
        "hå": _2,
        "habmer": _2,
        "xn--hbmer-xqa": _2,
        "hábmer": _2,
        "hadsel": _2,
        "xn--hgebostad-g3a": _2,
        "hægebostad": _2,
        "hagebostad": _2,
        "halden": _2,
        "halsa": _2,
        "hamar": _2,
        "hamaroy": _2,
        "hammarfeasta": _2,
        "xn--hmmrfeasta-s4ac": _2,
        "hámmárfeasta": _2,
        "hammerfest": _2,
        "hapmir": _2,
        "xn--hpmir-xqa": _2,
        "hápmir": _2,
        "haram": _2,
        "hareid": _2,
        "harstad": _2,
        "hasvik": _2,
        "hattfjelldal": _2,
        "haugesund": _2,
        "hedmark": [0, {
          "os": _2,
          "valer": _2,
          "xn--vler-qoa": _2,
          "våler": _2
        }],
        "hemne": _2,
        "hemnes": _2,
        "hemsedal": _2,
        "hitra": _2,
        "hjartdal": _2,
        "hjelmeland": _2,
        "hobol": _2,
        "xn--hobl-ira": _2,
        "hobøl": _2,
        "hof": _2,
        "hol": _2,
        "hole": _2,
        "holmestrand": _2,
        "holtalen": _2,
        "xn--holtlen-hxa": _2,
        "holtålen": _2,
        "hordaland": [0, {
          "os": _2
        }],
        "hornindal": _2,
        "horten": _2,
        "hoyanger": _2,
        "xn--hyanger-q1a": _2,
        "høyanger": _2,
        "hoylandet": _2,
        "xn--hylandet-54a": _2,
        "høylandet": _2,
        "hurdal": _2,
        "hurum": _2,
        "hvaler": _2,
        "hyllestad": _2,
        "ibestad": _2,
        "inderoy": _2,
        "xn--indery-fya": _2,
        "inderøy": _2,
        "iveland": _2,
        "ivgu": _2,
        "jevnaker": _2,
        "jolster": _2,
        "xn--jlster-bya": _2,
        "jølster": _2,
        "jondal": _2,
        "kafjord": _2,
        "xn--kfjord-iua": _2,
        "kåfjord": _2,
        "karasjohka": _2,
        "xn--krjohka-hwab49j": _2,
        "kárášjohka": _2,
        "karasjok": _2,
        "karlsoy": _2,
        "karmoy": _2,
        "xn--karmy-yua": _2,
        "karmøy": _2,
        "kautokeino": _2,
        "klabu": _2,
        "xn--klbu-woa": _2,
        "klæbu": _2,
        "klepp": _2,
        "kongsberg": _2,
        "kongsvinger": _2,
        "kraanghke": _2,
        "xn--kranghke-b0a": _2,
        "kråanghke": _2,
        "kragero": _2,
        "xn--krager-gya": _2,
        "kragerø": _2,
        "kristiansand": _2,
        "kristiansund": _2,
        "krodsherad": _2,
        "xn--krdsherad-m8a": _2,
        "krødsherad": _2,
        "xn--kvfjord-nxa": _2,
        "kvæfjord": _2,
        "xn--kvnangen-k0a": _2,
        "kvænangen": _2,
        "kvafjord": _2,
        "kvalsund": _2,
        "kvam": _2,
        "kvanangen": _2,
        "kvinesdal": _2,
        "kvinnherad": _2,
        "kviteseid": _2,
        "kvitsoy": _2,
        "xn--kvitsy-fya": _2,
        "kvitsøy": _2,
        "laakesvuemie": _2,
        "xn--lrdal-sra": _2,
        "lærdal": _2,
        "lahppi": _2,
        "xn--lhppi-xqa": _2,
        "láhppi": _2,
        "lardal": _2,
        "larvik": _2,
        "lavagis": _2,
        "lavangen": _2,
        "leangaviika": _2,
        "xn--leagaviika-52b": _2,
        "leaŋgaviika": _2,
        "lebesby": _2,
        "leikanger": _2,
        "leirfjord": _2,
        "leka": _2,
        "leksvik": _2,
        "lenvik": _2,
        "lerdal": _2,
        "lesja": _2,
        "levanger": _2,
        "lier": _2,
        "lierne": _2,
        "lillehammer": _2,
        "lillesand": _2,
        "lindas": _2,
        "xn--linds-pra": _2,
        "lindås": _2,
        "lindesnes": _2,
        "loabat": _2,
        "xn--loabt-0qa": _2,
        "loabát": _2,
        "lodingen": _2,
        "xn--ldingen-q1a": _2,
        "lødingen": _2,
        "lom": _2,
        "loppa": _2,
        "lorenskog": _2,
        "xn--lrenskog-54a": _2,
        "lørenskog": _2,
        "loten": _2,
        "xn--lten-gra": _2,
        "løten": _2,
        "lund": _2,
        "lunner": _2,
        "luroy": _2,
        "xn--lury-ira": _2,
        "lurøy": _2,
        "luster": _2,
        "lyngdal": _2,
        "lyngen": _2,
        "malatvuopmi": _2,
        "xn--mlatvuopmi-s4a": _2,
        "málatvuopmi": _2,
        "malselv": _2,
        "xn--mlselv-iua": _2,
        "målselv": _2,
        "malvik": _2,
        "mandal": _2,
        "marker": _2,
        "marnardal": _2,
        "masfjorden": _2,
        "masoy": _2,
        "xn--msy-ula0h": _2,
        "måsøy": _2,
        "matta-varjjat": _2,
        "xn--mtta-vrjjat-k7af": _2,
        "mátta-várjjat": _2,
        "meland": _2,
        "meldal": _2,
        "melhus": _2,
        "meloy": _2,
        "xn--mely-ira": _2,
        "meløy": _2,
        "meraker": _2,
        "xn--merker-kua": _2,
        "meråker": _2,
        "midsund": _2,
        "midtre-gauldal": _2,
        "moareke": _2,
        "xn--moreke-jua": _2,
        "moåreke": _2,
        "modalen": _2,
        "modum": _2,
        "molde": _2,
        "more-og-romsdal": [0, {
          "heroy": _2,
          "sande": _2
        }],
        "xn--mre-og-romsdal-qqb": [0, {
          "xn--hery-ira": _2,
          "sande": _2
        }],
        "møre-og-romsdal": [0, {
          "herøy": _2,
          "sande": _2
        }],
        "moskenes": _2,
        "moss": _2,
        "mosvik": _2,
        "muosat": _2,
        "xn--muost-0qa": _2,
        "muosát": _2,
        "naamesjevuemie": _2,
        "xn--nmesjevuemie-tcba": _2,
        "nååmesjevuemie": _2,
        "xn--nry-yla5g": _2,
        "nærøy": _2,
        "namdalseid": _2,
        "namsos": _2,
        "namsskogan": _2,
        "nannestad": _2,
        "naroy": _2,
        "narviika": _2,
        "narvik": _2,
        "naustdal": _2,
        "navuotna": _2,
        "xn--nvuotna-hwa": _2,
        "návuotna": _2,
        "nedre-eiker": _2,
        "nesna": _2,
        "nesodden": _2,
        "nesseby": _2,
        "nesset": _2,
        "nissedal": _2,
        "nittedal": _2,
        "nord-aurdal": _2,
        "nord-fron": _2,
        "nord-odal": _2,
        "norddal": _2,
        "nordkapp": _2,
        "nordland": [0, {
          "bo": _2,
          "xn--b-5ga": _2,
          "bø": _2,
          "heroy": _2,
          "xn--hery-ira": _2,
          "herøy": _2
        }],
        "nordre-land": _2,
        "nordreisa": _2,
        "nore-og-uvdal": _2,
        "notodden": _2,
        "notteroy": _2,
        "xn--nttery-byae": _2,
        "nøtterøy": _2,
        "odda": _2,
        "oksnes": _2,
        "xn--ksnes-uua": _2,
        "øksnes": _2,
        "omasvuotna": _2,
        "oppdal": _2,
        "oppegard": _2,
        "xn--oppegrd-ixa": _2,
        "oppegård": _2,
        "orkdal": _2,
        "orland": _2,
        "xn--rland-uua": _2,
        "ørland": _2,
        "orskog": _2,
        "xn--rskog-uua": _2,
        "ørskog": _2,
        "orsta": _2,
        "xn--rsta-fra": _2,
        "ørsta": _2,
        "osen": _2,
        "osteroy": _2,
        "xn--ostery-fya": _2,
        "osterøy": _2,
        "ostfold": [0, {
          "valer": _2
        }],
        "xn--stfold-9xa": [0, {
          "xn--vler-qoa": _2
        }],
        "østfold": [0, {
          "våler": _2
        }],
        "ostre-toten": _2,
        "xn--stre-toten-zcb": _2,
        "østre-toten": _2,
        "overhalla": _2,
        "ovre-eiker": _2,
        "xn--vre-eiker-k8a": _2,
        "øvre-eiker": _2,
        "oyer": _2,
        "xn--yer-zna": _2,
        "øyer": _2,
        "oygarden": _2,
        "xn--ygarden-p1a": _2,
        "øygarden": _2,
        "oystre-slidre": _2,
        "xn--ystre-slidre-ujb": _2,
        "øystre-slidre": _2,
        "porsanger": _2,
        "porsangu": _2,
        "xn--porsgu-sta26f": _2,
        "porsáŋgu": _2,
        "porsgrunn": _2,
        "rade": _2,
        "xn--rde-ula": _2,
        "råde": _2,
        "radoy": _2,
        "xn--rady-ira": _2,
        "radøy": _2,
        "xn--rlingen-mxa": _2,
        "rælingen": _2,
        "rahkkeravju": _2,
        "xn--rhkkervju-01af": _2,
        "ráhkkerávju": _2,
        "raisa": _2,
        "xn--risa-5na": _2,
        "ráisa": _2,
        "rakkestad": _2,
        "ralingen": _2,
        "rana": _2,
        "randaberg": _2,
        "rauma": _2,
        "rendalen": _2,
        "rennebu": _2,
        "rennesoy": _2,
        "xn--rennesy-v1a": _2,
        "rennesøy": _2,
        "rindal": _2,
        "ringebu": _2,
        "ringerike": _2,
        "ringsaker": _2,
        "risor": _2,
        "xn--risr-ira": _2,
        "risør": _2,
        "rissa": _2,
        "roan": _2,
        "rodoy": _2,
        "xn--rdy-0nab": _2,
        "rødøy": _2,
        "rollag": _2,
        "romsa": _2,
        "romskog": _2,
        "xn--rmskog-bya": _2,
        "rømskog": _2,
        "roros": _2,
        "xn--rros-gra": _2,
        "røros": _2,
        "rost": _2,
        "xn--rst-0na": _2,
        "røst": _2,
        "royken": _2,
        "xn--ryken-vua": _2,
        "røyken": _2,
        "royrvik": _2,
        "xn--ryrvik-bya": _2,
        "røyrvik": _2,
        "ruovat": _2,
        "rygge": _2,
        "salangen": _2,
        "salat": _2,
        "xn--slat-5na": _2,
        "sálat": _2,
        "xn--slt-elab": _2,
        "sálát": _2,
        "saltdal": _2,
        "samnanger": _2,
        "sandefjord": _2,
        "sandnes": _2,
        "sandoy": _2,
        "xn--sandy-yua": _2,
        "sandøy": _2,
        "sarpsborg": _2,
        "sauda": _2,
        "sauherad": _2,
        "sel": _2,
        "selbu": _2,
        "selje": _2,
        "seljord": _2,
        "siellak": _2,
        "sigdal": _2,
        "siljan": _2,
        "sirdal": _2,
        "skanit": _2,
        "xn--sknit-yqa": _2,
        "skánit": _2,
        "skanland": _2,
        "xn--sknland-fxa": _2,
        "skånland": _2,
        "skaun": _2,
        "skedsmo": _2,
        "ski": _2,
        "skien": _2,
        "skierva": _2,
        "xn--skierv-uta": _2,
        "skiervá": _2,
        "skiptvet": _2,
        "skjak": _2,
        "xn--skjk-soa": _2,
        "skjåk": _2,
        "skjervoy": _2,
        "xn--skjervy-v1a": _2,
        "skjervøy": _2,
        "skodje": _2,
        "smola": _2,
        "xn--smla-hra": _2,
        "smøla": _2,
        "snaase": _2,
        "xn--snase-nra": _2,
        "snåase": _2,
        "snasa": _2,
        "xn--snsa-roa": _2,
        "snåsa": _2,
        "snillfjord": _2,
        "snoasa": _2,
        "sogndal": _2,
        "sogne": _2,
        "xn--sgne-gra": _2,
        "søgne": _2,
        "sokndal": _2,
        "sola": _2,
        "solund": _2,
        "somna": _2,
        "xn--smna-gra": _2,
        "sømna": _2,
        "sondre-land": _2,
        "xn--sndre-land-0cb": _2,
        "søndre-land": _2,
        "songdalen": _2,
        "sor-aurdal": _2,
        "xn--sr-aurdal-l8a": _2,
        "sør-aurdal": _2,
        "sor-fron": _2,
        "xn--sr-fron-q1a": _2,
        "sør-fron": _2,
        "sor-odal": _2,
        "xn--sr-odal-q1a": _2,
        "sør-odal": _2,
        "sor-varanger": _2,
        "xn--sr-varanger-ggb": _2,
        "sør-varanger": _2,
        "sorfold": _2,
        "xn--srfold-bya": _2,
        "sørfold": _2,
        "sorreisa": _2,
        "xn--srreisa-q1a": _2,
        "sørreisa": _2,
        "sortland": _2,
        "sorum": _2,
        "xn--srum-gra": _2,
        "sørum": _2,
        "spydeberg": _2,
        "stange": _2,
        "stavanger": _2,
        "steigen": _2,
        "steinkjer": _2,
        "stjordal": _2,
        "xn--stjrdal-s1a": _2,
        "stjørdal": _2,
        "stokke": _2,
        "stor-elvdal": _2,
        "stord": _2,
        "stordal": _2,
        "storfjord": _2,
        "strand": _2,
        "stranda": _2,
        "stryn": _2,
        "sula": _2,
        "suldal": _2,
        "sund": _2,
        "sunndal": _2,
        "surnadal": _2,
        "sveio": _2,
        "svelvik": _2,
        "sykkylven": _2,
        "tana": _2,
        "telemark": [0, {
          "bo": _2,
          "xn--b-5ga": _2,
          "bø": _2
        }],
        "time": _2,
        "tingvoll": _2,
        "tinn": _2,
        "tjeldsund": _2,
        "tjome": _2,
        "xn--tjme-hra": _2,
        "tjøme": _2,
        "tokke": _2,
        "tolga": _2,
        "tonsberg": _2,
        "xn--tnsberg-q1a": _2,
        "tønsberg": _2,
        "torsken": _2,
        "xn--trna-woa": _2,
        "træna": _2,
        "trana": _2,
        "tranoy": _2,
        "xn--trany-yua": _2,
        "tranøy": _2,
        "troandin": _2,
        "trogstad": _2,
        "xn--trgstad-r1a": _2,
        "trøgstad": _2,
        "tromsa": _2,
        "tromso": _2,
        "xn--troms-zua": _2,
        "tromsø": _2,
        "trondheim": _2,
        "trysil": _2,
        "tvedestrand": _2,
        "tydal": _2,
        "tynset": _2,
        "tysfjord": _2,
        "tysnes": _2,
        "xn--tysvr-vra": _2,
        "tysvær": _2,
        "tysvar": _2,
        "ullensaker": _2,
        "ullensvang": _2,
        "ulvik": _2,
        "unjarga": _2,
        "xn--unjrga-rta": _2,
        "unjárga": _2,
        "utsira": _2,
        "vaapste": _2,
        "vadso": _2,
        "xn--vads-jra": _2,
        "vadsø": _2,
        "xn--vry-yla5g": _2,
        "værøy": _2,
        "vaga": _2,
        "xn--vg-yiab": _2,
        "vågå": _2,
        "vagan": _2,
        "xn--vgan-qoa": _2,
        "vågan": _2,
        "vagsoy": _2,
        "xn--vgsy-qoa0j": _2,
        "vågsøy": _2,
        "vaksdal": _2,
        "valle": _2,
        "vang": _2,
        "vanylven": _2,
        "vardo": _2,
        "xn--vard-jra": _2,
        "vardø": _2,
        "varggat": _2,
        "xn--vrggt-xqad": _2,
        "várggát": _2,
        "varoy": _2,
        "vefsn": _2,
        "vega": _2,
        "vegarshei": _2,
        "xn--vegrshei-c0a": _2,
        "vegårshei": _2,
        "vennesla": _2,
        "verdal": _2,
        "verran": _2,
        "vestby": _2,
        "vestfold": [0, {
          "sande": _2
        }],
        "vestnes": _2,
        "vestre-slidre": _2,
        "vestre-toten": _2,
        "vestvagoy": _2,
        "xn--vestvgy-ixa6o": _2,
        "vestvågøy": _2,
        "vevelstad": _2,
        "vik": _2,
        "vikna": _2,
        "vindafjord": _2,
        "voagat": _2,
        "volda": _2,
        "voss": _2,
        "co": _3,
        "123hjemmeside": _3,
        "myspreadshop": _3
      }],
      "np": _18,
      "nr": _58,
      "nu": [1, {
        "merseine": _3,
        "mine": _3,
        "shacknet": _3,
        "enterprisecloud": _3
      }],
      "nz": [1, {
        "ac": _2,
        "co": _2,
        "cri": _2,
        "geek": _2,
        "gen": _2,
        "govt": _2,
        "health": _2,
        "iwi": _2,
        "kiwi": _2,
        "maori": _2,
        "xn--mori-qsa": _2,
        "māori": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "parliament": _2,
        "school": _2,
        "cloudns": _3
      }],
      "om": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "med": _2,
        "museum": _2,
        "net": _2,
        "org": _2,
        "pro": _2
      }],
      "onion": _2,
      "org": [1, {
        "altervista": _3,
        "pimienta": _3,
        "poivron": _3,
        "potager": _3,
        "sweetpepper": _3,
        "cdn77": [0, {
          "c": _3,
          "rsc": _3
        }],
        "cdn77-secure": [0, {
          "origin": [0, {
            "ssl": _3
          }]
        }],
        "ae": _3,
        "cloudns": _3,
        "ip-dynamic": _3,
        "ddnss": _3,
        "dpdns": _3,
        "duckdns": _3,
        "tunk": _3,
        "blogdns": _3,
        "blogsite": _3,
        "boldlygoingnowhere": _3,
        "dnsalias": _3,
        "dnsdojo": _3,
        "doesntexist": _3,
        "dontexist": _3,
        "doomdns": _3,
        "dvrdns": _3,
        "dynalias": _3,
        "dyndns": [2, {
          "go": _3,
          "home": _3
        }],
        "endofinternet": _3,
        "endoftheinternet": _3,
        "from-me": _3,
        "game-host": _3,
        "gotdns": _3,
        "hobby-site": _3,
        "homedns": _3,
        "homeftp": _3,
        "homelinux": _3,
        "homeunix": _3,
        "is-a-bruinsfan": _3,
        "is-a-candidate": _3,
        "is-a-celticsfan": _3,
        "is-a-chef": _3,
        "is-a-geek": _3,
        "is-a-knight": _3,
        "is-a-linux-user": _3,
        "is-a-patsfan": _3,
        "is-a-soxfan": _3,
        "is-found": _3,
        "is-lost": _3,
        "is-saved": _3,
        "is-very-bad": _3,
        "is-very-evil": _3,
        "is-very-good": _3,
        "is-very-nice": _3,
        "is-very-sweet": _3,
        "isa-geek": _3,
        "kicks-ass": _3,
        "misconfused": _3,
        "podzone": _3,
        "readmyblog": _3,
        "selfip": _3,
        "sellsyourhome": _3,
        "servebbs": _3,
        "serveftp": _3,
        "servegame": _3,
        "stuff-4-sale": _3,
        "webhop": _3,
        "accesscam": _3,
        "camdvr": _3,
        "freeddns": _3,
        "mywire": _3,
        "webredirect": _3,
        "twmail": _3,
        "eu": [2, {
          "al": _3,
          "asso": _3,
          "at": _3,
          "au": _3,
          "be": _3,
          "bg": _3,
          "ca": _3,
          "cd": _3,
          "ch": _3,
          "cn": _3,
          "cy": _3,
          "cz": _3,
          "de": _3,
          "dk": _3,
          "edu": _3,
          "ee": _3,
          "es": _3,
          "fi": _3,
          "fr": _3,
          "gr": _3,
          "hr": _3,
          "hu": _3,
          "ie": _3,
          "il": _3,
          "in": _3,
          "int": _3,
          "is": _3,
          "it": _3,
          "jp": _3,
          "kr": _3,
          "lt": _3,
          "lu": _3,
          "lv": _3,
          "me": _3,
          "mk": _3,
          "mt": _3,
          "my": _3,
          "net": _3,
          "ng": _3,
          "nl": _3,
          "no": _3,
          "nz": _3,
          "pl": _3,
          "pt": _3,
          "ro": _3,
          "ru": _3,
          "se": _3,
          "si": _3,
          "sk": _3,
          "tr": _3,
          "uk": _3,
          "us": _3
        }],
        "fedorainfracloud": _3,
        "fedorapeople": _3,
        "fedoraproject": [0, {
          "cloud": _3,
          "os": _43,
          "stg": [0, {
            "os": _43
          }]
        }],
        "freedesktop": _3,
        "hatenadiary": _3,
        "hepforge": _3,
        "in-dsl": _3,
        "in-vpn": _3,
        "js": _3,
        "barsy": _3,
        "mayfirst": _3,
        "routingthecloud": _3,
        "bmoattachments": _3,
        "cable-modem": _3,
        "collegefan": _3,
        "couchpotatofries": _3,
        "hopto": _3,
        "mlbfan": _3,
        "myftp": _3,
        "mysecuritycamera": _3,
        "nflfan": _3,
        "no-ip": _3,
        "read-books": _3,
        "ufcfan": _3,
        "zapto": _3,
        "dynserv": _3,
        "now-dns": _3,
        "is-local": _3,
        "httpbin": _3,
        "pubtls": _3,
        "jpn": _3,
        "my-firewall": _3,
        "myfirewall": _3,
        "spdns": _3,
        "small-web": _3,
        "dsmynas": _3,
        "familyds": _3,
        "teckids": _57,
        "tuxfamily": _3,
        "diskstation": _3,
        "hk": _3,
        "us": _3,
        "toolforge": _3,
        "wmcloud": [2, {
          "beta": _3
        }],
        "wmflabs": _3,
        "za": _3
      }],
      "pa": [1, {
        "abo": _2,
        "ac": _2,
        "com": _2,
        "edu": _2,
        "gob": _2,
        "ing": _2,
        "med": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "sld": _2
      }],
      "pe": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2
      }],
      "pf": [1, {
        "com": _2,
        "edu": _2,
        "org": _2
      }],
      "pg": _18,
      "ph": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "i": _2,
        "mil": _2,
        "net": _2,
        "ngo": _2,
        "org": _2,
        "cloudns": _3
      }],
      "pk": [1, {
        "ac": _2,
        "biz": _2,
        "com": _2,
        "edu": _2,
        "fam": _2,
        "gkp": _2,
        "gob": _2,
        "gog": _2,
        "gok": _2,
        "gop": _2,
        "gos": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "web": _2
      }],
      "pl": [1, {
        "com": _2,
        "net": _2,
        "org": _2,
        "agro": _2,
        "aid": _2,
        "atm": _2,
        "auto": _2,
        "biz": _2,
        "edu": _2,
        "gmina": _2,
        "gsm": _2,
        "info": _2,
        "mail": _2,
        "media": _2,
        "miasta": _2,
        "mil": _2,
        "nieruchomosci": _2,
        "nom": _2,
        "pc": _2,
        "powiat": _2,
        "priv": _2,
        "realestate": _2,
        "rel": _2,
        "sex": _2,
        "shop": _2,
        "sklep": _2,
        "sos": _2,
        "szkola": _2,
        "targi": _2,
        "tm": _2,
        "tourism": _2,
        "travel": _2,
        "turystyka": _2,
        "gov": [1, {
          "ap": _2,
          "griw": _2,
          "ic": _2,
          "is": _2,
          "kmpsp": _2,
          "konsulat": _2,
          "kppsp": _2,
          "kwp": _2,
          "kwpsp": _2,
          "mup": _2,
          "mw": _2,
          "oia": _2,
          "oirm": _2,
          "oke": _2,
          "oow": _2,
          "oschr": _2,
          "oum": _2,
          "pa": _2,
          "pinb": _2,
          "piw": _2,
          "po": _2,
          "pr": _2,
          "psp": _2,
          "psse": _2,
          "pup": _2,
          "rzgw": _2,
          "sa": _2,
          "sdn": _2,
          "sko": _2,
          "so": _2,
          "sr": _2,
          "starostwo": _2,
          "ug": _2,
          "ugim": _2,
          "um": _2,
          "umig": _2,
          "upow": _2,
          "uppo": _2,
          "us": _2,
          "uw": _2,
          "uzs": _2,
          "wif": _2,
          "wiih": _2,
          "winb": _2,
          "wios": _2,
          "witd": _2,
          "wiw": _2,
          "wkz": _2,
          "wsa": _2,
          "wskr": _2,
          "wsse": _2,
          "wuoz": _2,
          "wzmiuw": _2,
          "zp": _2,
          "zpisdn": _2
        }],
        "augustow": _2,
        "babia-gora": _2,
        "bedzin": _2,
        "beskidy": _2,
        "bialowieza": _2,
        "bialystok": _2,
        "bielawa": _2,
        "bieszczady": _2,
        "boleslawiec": _2,
        "bydgoszcz": _2,
        "bytom": _2,
        "cieszyn": _2,
        "czeladz": _2,
        "czest": _2,
        "dlugoleka": _2,
        "elblag": _2,
        "elk": _2,
        "glogow": _2,
        "gniezno": _2,
        "gorlice": _2,
        "grajewo": _2,
        "ilawa": _2,
        "jaworzno": _2,
        "jelenia-gora": _2,
        "jgora": _2,
        "kalisz": _2,
        "karpacz": _2,
        "kartuzy": _2,
        "kaszuby": _2,
        "katowice": _2,
        "kazimierz-dolny": _2,
        "kepno": _2,
        "ketrzyn": _2,
        "klodzko": _2,
        "kobierzyce": _2,
        "kolobrzeg": _2,
        "konin": _2,
        "konskowola": _2,
        "kutno": _2,
        "lapy": _2,
        "lebork": _2,
        "legnica": _2,
        "lezajsk": _2,
        "limanowa": _2,
        "lomza": _2,
        "lowicz": _2,
        "lubin": _2,
        "lukow": _2,
        "malbork": _2,
        "malopolska": _2,
        "mazowsze": _2,
        "mazury": _2,
        "mielec": _2,
        "mielno": _2,
        "mragowo": _2,
        "naklo": _2,
        "nowaruda": _2,
        "nysa": _2,
        "olawa": _2,
        "olecko": _2,
        "olkusz": _2,
        "olsztyn": _2,
        "opoczno": _2,
        "opole": _2,
        "ostroda": _2,
        "ostroleka": _2,
        "ostrowiec": _2,
        "ostrowwlkp": _2,
        "pila": _2,
        "pisz": _2,
        "podhale": _2,
        "podlasie": _2,
        "polkowice": _2,
        "pomorskie": _2,
        "pomorze": _2,
        "prochowice": _2,
        "pruszkow": _2,
        "przeworsk": _2,
        "pulawy": _2,
        "radom": _2,
        "rawa-maz": _2,
        "rybnik": _2,
        "rzeszow": _2,
        "sanok": _2,
        "sejny": _2,
        "skoczow": _2,
        "slask": _2,
        "slupsk": _2,
        "sosnowiec": _2,
        "stalowa-wola": _2,
        "starachowice": _2,
        "stargard": _2,
        "suwalki": _2,
        "swidnica": _2,
        "swiebodzin": _2,
        "swinoujscie": _2,
        "szczecin": _2,
        "szczytno": _2,
        "tarnobrzeg": _2,
        "tgory": _2,
        "turek": _2,
        "tychy": _2,
        "ustka": _2,
        "walbrzych": _2,
        "warmia": _2,
        "warszawa": _2,
        "waw": _2,
        "wegrow": _2,
        "wielun": _2,
        "wlocl": _2,
        "wloclawek": _2,
        "wodzislaw": _2,
        "wolomin": _2,
        "wroclaw": _2,
        "zachpomor": _2,
        "zagan": _2,
        "zarow": _2,
        "zgora": _2,
        "zgorzelec": _2,
        "art": _3,
        "gliwice": _3,
        "krakow": _3,
        "poznan": _3,
        "wroc": _3,
        "zakopane": _3,
        "beep": _3,
        "ecommerce-shop": _3,
        "cfolks": _3,
        "dfirma": _3,
        "dkonto": _3,
        "you2": _3,
        "shoparena": _3,
        "homesklep": _3,
        "sdscloud": _3,
        "unicloud": _3,
        "lodz": _3,
        "pabianice": _3,
        "plock": _3,
        "sieradz": _3,
        "skierniewice": _3,
        "zgierz": _3,
        "krasnik": _3,
        "leczna": _3,
        "lubartow": _3,
        "lublin": _3,
        "poniatowa": _3,
        "swidnik": _3,
        "co": _3,
        "torun": _3,
        "simplesite": _3,
        "myspreadshop": _3,
        "gda": _3,
        "gdansk": _3,
        "gdynia": _3,
        "med": _3,
        "sopot": _3,
        "bielsko": _3
      }],
      "pm": [1, {
        "own": _3,
        "name": _3
      }],
      "pn": [1, {
        "co": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2
      }],
      "post": _2,
      "pr": [1, {
        "biz": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "isla": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pro": _2,
        "ac": _2,
        "est": _2,
        "prof": _2
      }],
      "pro": [1, {
        "aaa": _2,
        "aca": _2,
        "acct": _2,
        "avocat": _2,
        "bar": _2,
        "cpa": _2,
        "eng": _2,
        "jur": _2,
        "law": _2,
        "med": _2,
        "recht": _2,
        "12chars": _3,
        "cloudns": _3,
        "barsy": _3,
        "ngrok": _3
      }],
      "ps": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "plo": _2,
        "sec": _2
      }],
      "pt": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "int": _2,
        "net": _2,
        "nome": _2,
        "org": _2,
        "publ": _2,
        "123paginaweb": _3
      }],
      "pw": [1, {
        "gov": _2,
        "cloudns": _3,
        "x443": _3
      }],
      "py": [1, {
        "com": _2,
        "coop": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "qa": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "sch": _2
      }],
      "re": [1, {
        "asso": _2,
        "com": _2,
        "netlib": _3,
        "can": _3
      }],
      "ro": [1, {
        "arts": _2,
        "com": _2,
        "firm": _2,
        "info": _2,
        "nom": _2,
        "nt": _2,
        "org": _2,
        "rec": _2,
        "store": _2,
        "tm": _2,
        "www": _2,
        "co": _3,
        "shop": _3,
        "barsy": _3
      }],
      "rs": [1, {
        "ac": _2,
        "co": _2,
        "edu": _2,
        "gov": _2,
        "in": _2,
        "org": _2,
        "brendly": _52,
        "barsy": _3,
        "ox": _3
      }],
      "ru": [1, {
        "ac": _3,
        "edu": _3,
        "gov": _3,
        "int": _3,
        "mil": _3,
        "eurodir": _3,
        "adygeya": _3,
        "bashkiria": _3,
        "bir": _3,
        "cbg": _3,
        "com": _3,
        "dagestan": _3,
        "grozny": _3,
        "kalmykia": _3,
        "kustanai": _3,
        "marine": _3,
        "mordovia": _3,
        "msk": _3,
        "mytis": _3,
        "nalchik": _3,
        "nov": _3,
        "pyatigorsk": _3,
        "spb": _3,
        "vladikavkaz": _3,
        "vladimir": _3,
        "na4u": _3,
        "mircloud": _3,
        "myjino": [2, {
          "hosting": _6,
          "landing": _6,
          "spectrum": _6,
          "vps": _6
        }],
        "cldmail": [0, {
          "hb": _3
        }],
        "mcdir": [2, {
          "vps": _3
        }],
        "mcpre": _3,
        "net": _3,
        "org": _3,
        "pp": _3,
        "lk3": _3,
        "ras": _3
      }],
      "rw": [1, {
        "ac": _2,
        "co": _2,
        "coop": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "sa": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "med": _2,
        "net": _2,
        "org": _2,
        "pub": _2,
        "sch": _2
      }],
      "sb": _4,
      "sc": _4,
      "sd": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "med": _2,
        "net": _2,
        "org": _2,
        "tv": _2
      }],
      "se": [1, {
        "a": _2,
        "ac": _2,
        "b": _2,
        "bd": _2,
        "brand": _2,
        "c": _2,
        "d": _2,
        "e": _2,
        "f": _2,
        "fh": _2,
        "fhsk": _2,
        "fhv": _2,
        "g": _2,
        "h": _2,
        "i": _2,
        "k": _2,
        "komforb": _2,
        "kommunalforbund": _2,
        "komvux": _2,
        "l": _2,
        "lanbib": _2,
        "m": _2,
        "n": _2,
        "naturbruksgymn": _2,
        "o": _2,
        "org": _2,
        "p": _2,
        "parti": _2,
        "pp": _2,
        "press": _2,
        "r": _2,
        "s": _2,
        "t": _2,
        "tm": _2,
        "u": _2,
        "w": _2,
        "x": _2,
        "y": _2,
        "z": _2,
        "com": _3,
        "iopsys": _3,
        "123minsida": _3,
        "itcouldbewor": _3,
        "myspreadshop": _3
      }],
      "sg": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "enscaled": _3
      }],
      "sh": [1, {
        "com": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "hashbang": _3,
        "botda": _3,
        "lovable": _3,
        "platform": [0, {
          "ent": _3,
          "eu": _3,
          "us": _3
        }],
        "now": _3
      }],
      "si": [1, {
        "f5": _3,
        "gitapp": _3,
        "gitpage": _3
      }],
      "sj": _2,
      "sk": _2,
      "sl": _4,
      "sm": _2,
      "sn": [1, {
        "art": _2,
        "com": _2,
        "edu": _2,
        "gouv": _2,
        "org": _2,
        "perso": _2,
        "univ": _2
      }],
      "so": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "me": _2,
        "net": _2,
        "org": _2,
        "surveys": _3
      }],
      "sr": _2,
      "ss": [1, {
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "me": _2,
        "net": _2,
        "org": _2,
        "sch": _2
      }],
      "st": [1, {
        "co": _2,
        "com": _2,
        "consulado": _2,
        "edu": _2,
        "embaixada": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "principe": _2,
        "saotome": _2,
        "store": _2,
        "helioho": _3,
        "kirara": _3,
        "noho": _3
      }],
      "su": [1, {
        "abkhazia": _3,
        "adygeya": _3,
        "aktyubinsk": _3,
        "arkhangelsk": _3,
        "armenia": _3,
        "ashgabad": _3,
        "azerbaijan": _3,
        "balashov": _3,
        "bashkiria": _3,
        "bryansk": _3,
        "bukhara": _3,
        "chimkent": _3,
        "dagestan": _3,
        "east-kazakhstan": _3,
        "exnet": _3,
        "georgia": _3,
        "grozny": _3,
        "ivanovo": _3,
        "jambyl": _3,
        "kalmykia": _3,
        "kaluga": _3,
        "karacol": _3,
        "karaganda": _3,
        "karelia": _3,
        "khakassia": _3,
        "krasnodar": _3,
        "kurgan": _3,
        "kustanai": _3,
        "lenug": _3,
        "mangyshlak": _3,
        "mordovia": _3,
        "msk": _3,
        "murmansk": _3,
        "nalchik": _3,
        "navoi": _3,
        "north-kazakhstan": _3,
        "nov": _3,
        "obninsk": _3,
        "penza": _3,
        "pokrovsk": _3,
        "sochi": _3,
        "spb": _3,
        "tashkent": _3,
        "termez": _3,
        "togliatti": _3,
        "troitsk": _3,
        "tselinograd": _3,
        "tula": _3,
        "tuva": _3,
        "vladikavkaz": _3,
        "vladimir": _3,
        "vologda": _3
      }],
      "sv": [1, {
        "com": _2,
        "edu": _2,
        "gob": _2,
        "org": _2,
        "red": _2
      }],
      "sx": _10,
      "sy": _5,
      "sz": [1, {
        "ac": _2,
        "co": _2,
        "org": _2
      }],
      "tc": _2,
      "td": _2,
      "tel": _2,
      "tf": [1, {
        "sch": _3
      }],
      "tg": _2,
      "th": [1, {
        "ac": _2,
        "co": _2,
        "go": _2,
        "in": _2,
        "mi": _2,
        "net": _2,
        "or": _2,
        "online": _3,
        "shop": _3
      }],
      "tj": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "go": _2,
        "gov": _2,
        "int": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "nic": _2,
        "org": _2,
        "test": _2,
        "web": _2
      }],
      "tk": _2,
      "tl": _10,
      "tm": [1, {
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2
      }],
      "tn": [1, {
        "com": _2,
        "ens": _2,
        "fin": _2,
        "gov": _2,
        "ind": _2,
        "info": _2,
        "intl": _2,
        "mincom": _2,
        "nat": _2,
        "net": _2,
        "org": _2,
        "perso": _2,
        "tourism": _2,
        "orangecloud": _3
      }],
      "to": [1, {
        "611": _3,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "oya": _3,
        "x0": _3,
        "quickconnect": _25,
        "vpnplus": _3
      }],
      "tr": [1, {
        "av": _2,
        "bbs": _2,
        "bel": _2,
        "biz": _2,
        "com": _2,
        "dr": _2,
        "edu": _2,
        "gen": _2,
        "gov": _2,
        "info": _2,
        "k12": _2,
        "kep": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pol": _2,
        "tel": _2,
        "tsk": _2,
        "tv": _2,
        "web": _2,
        "nc": _10
      }],
      "tt": [1, {
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "mil": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pro": _2
      }],
      "tv": [1, {
        "better-than": _3,
        "dyndns": _3,
        "on-the-web": _3,
        "worse-than": _3,
        "from": _3,
        "sakura": _3
      }],
      "tw": [1, {
        "club": _2,
        "com": [1, {
          "mymailer": _3
        }],
        "ebiz": _2,
        "edu": _2,
        "game": _2,
        "gov": _2,
        "idv": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "url": _3,
        "mydns": _3
      }],
      "tz": [1, {
        "ac": _2,
        "co": _2,
        "go": _2,
        "hotel": _2,
        "info": _2,
        "me": _2,
        "mil": _2,
        "mobi": _2,
        "ne": _2,
        "or": _2,
        "sc": _2,
        "tv": _2
      }],
      "ua": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "in": _2,
        "net": _2,
        "org": _2,
        "cherkassy": _2,
        "cherkasy": _2,
        "chernigov": _2,
        "chernihiv": _2,
        "chernivtsi": _2,
        "chernovtsy": _2,
        "ck": _2,
        "cn": _2,
        "cr": _2,
        "crimea": _2,
        "cv": _2,
        "dn": _2,
        "dnepropetrovsk": _2,
        "dnipropetrovsk": _2,
        "donetsk": _2,
        "dp": _2,
        "if": _2,
        "ivano-frankivsk": _2,
        "kh": _2,
        "kharkiv": _2,
        "kharkov": _2,
        "kherson": _2,
        "khmelnitskiy": _2,
        "khmelnytskyi": _2,
        "kiev": _2,
        "kirovograd": _2,
        "km": _2,
        "kr": _2,
        "kropyvnytskyi": _2,
        "krym": _2,
        "ks": _2,
        "kv": _2,
        "kyiv": _2,
        "lg": _2,
        "lt": _2,
        "lugansk": _2,
        "luhansk": _2,
        "lutsk": _2,
        "lv": _2,
        "lviv": _2,
        "mk": _2,
        "mykolaiv": _2,
        "nikolaev": _2,
        "od": _2,
        "odesa": _2,
        "odessa": _2,
        "pl": _2,
        "poltava": _2,
        "rivne": _2,
        "rovno": _2,
        "rv": _2,
        "sb": _2,
        "sebastopol": _2,
        "sevastopol": _2,
        "sm": _2,
        "sumy": _2,
        "te": _2,
        "ternopil": _2,
        "uz": _2,
        "uzhgorod": _2,
        "uzhhorod": _2,
        "vinnica": _2,
        "vinnytsia": _2,
        "vn": _2,
        "volyn": _2,
        "yalta": _2,
        "zakarpattia": _2,
        "zaporizhzhe": _2,
        "zaporizhzhia": _2,
        "zhitomir": _2,
        "zhytomyr": _2,
        "zp": _2,
        "zt": _2,
        "cc": _3,
        "inf": _3,
        "ltd": _3,
        "cx": _3,
        "biz": _3,
        "co": _3,
        "pp": _3,
        "v": _3
      }],
      "ug": [1, {
        "ac": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "go": _2,
        "gov": _2,
        "mil": _2,
        "ne": _2,
        "or": _2,
        "org": _2,
        "sc": _2,
        "us": _2
      }],
      "uk": [1, {
        "ac": _2,
        "co": [1, {
          "bytemark": [0, {
            "dh": _3,
            "vm": _3
          }],
          "layershift": _46,
          "barsy": _3,
          "barsyonline": _3,
          "retrosnub": _56,
          "nh-serv": _3,
          "no-ip": _3,
          "adimo": _3,
          "myspreadshop": _3
        }],
        "gov": [1, {
          "api": _3,
          "campaign": _3,
          "service": _3
        }],
        "ltd": _2,
        "me": _2,
        "net": _2,
        "nhs": _2,
        "org": [1, {
          "glug": _3,
          "lug": _3,
          "lugs": _3,
          "affinitylottery": _3,
          "raffleentry": _3,
          "weeklylottery": _3
        }],
        "plc": _2,
        "police": _2,
        "sch": _18,
        "conn": _3,
        "copro": _3,
        "hosp": _3,
        "independent-commission": _3,
        "independent-inquest": _3,
        "independent-inquiry": _3,
        "independent-panel": _3,
        "independent-review": _3,
        "public-inquiry": _3,
        "royal-commission": _3,
        "pymnt": _3,
        "barsy": _3,
        "nimsite": _3,
        "oraclegovcloudapps": _6
      }],
      "us": [1, {
        "dni": _2,
        "isa": _2,
        "nsn": _2,
        "ak": _64,
        "al": _64,
        "ar": _64,
        "as": _64,
        "az": _64,
        "ca": _64,
        "co": _64,
        "ct": _64,
        "dc": _64,
        "de": [1, {
          "cc": _2,
          "lib": _3
        }],
        "fl": _64,
        "ga": _64,
        "gu": _64,
        "hi": _65,
        "ia": _64,
        "id": _64,
        "il": _64,
        "in": _64,
        "ks": _64,
        "ky": _64,
        "la": _64,
        "ma": [1, {
          "k12": [1, {
            "chtr": _2,
            "paroch": _2,
            "pvt": _2
          }],
          "cc": _2,
          "lib": _2
        }],
        "md": _64,
        "me": _64,
        "mi": [1, {
          "k12": _2,
          "cc": _2,
          "lib": _2,
          "ann-arbor": _2,
          "cog": _2,
          "dst": _2,
          "eaton": _2,
          "gen": _2,
          "mus": _2,
          "tec": _2,
          "washtenaw": _2
        }],
        "mn": _64,
        "mo": _64,
        "ms": _64,
        "mt": _64,
        "nc": _64,
        "nd": _65,
        "ne": _64,
        "nh": _64,
        "nj": _64,
        "nm": _64,
        "nv": _64,
        "ny": _64,
        "oh": _64,
        "ok": _64,
        "or": _64,
        "pa": _64,
        "pr": _64,
        "ri": _65,
        "sc": _64,
        "sd": _65,
        "tn": _64,
        "tx": _64,
        "ut": _64,
        "va": _64,
        "vi": _64,
        "vt": _64,
        "wa": _64,
        "wi": _64,
        "wv": [1, {
          "cc": _2
        }],
        "wy": _64,
        "cloudns": _3,
        "is-by": _3,
        "land-4-sale": _3,
        "stuff-4-sale": _3,
        "heliohost": _3,
        "enscaled": [0, {
          "phx": _3
        }],
        "mircloud": _3,
        "ngo": _3,
        "golffan": _3,
        "noip": _3,
        "pointto": _3,
        "freeddns": _3,
        "srv": [2, {
          "gh": _3,
          "gl": _3
        }],
        "platterp": _3,
        "servername": _3
      }],
      "uy": [1, {
        "com": _2,
        "edu": _2,
        "gub": _2,
        "mil": _2,
        "net": _2,
        "org": _2
      }],
      "uz": [1, {
        "co": _2,
        "com": _2,
        "net": _2,
        "org": _2
      }],
      "va": _2,
      "vc": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "gv": [2, {
          "d": _3
        }],
        "0e": _6,
        "mydns": _3
      }],
      "ve": [1, {
        "arts": _2,
        "bib": _2,
        "co": _2,
        "com": _2,
        "e12": _2,
        "edu": _2,
        "emprende": _2,
        "firm": _2,
        "gob": _2,
        "gov": _2,
        "info": _2,
        "int": _2,
        "mil": _2,
        "net": _2,
        "nom": _2,
        "org": _2,
        "rar": _2,
        "rec": _2,
        "store": _2,
        "tec": _2,
        "web": _2
      }],
      "vg": [1, {
        "edu": _2
      }],
      "vi": [1, {
        "co": _2,
        "com": _2,
        "k12": _2,
        "net": _2,
        "org": _2
      }],
      "vn": [1, {
        "ac": _2,
        "ai": _2,
        "biz": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "health": _2,
        "id": _2,
        "info": _2,
        "int": _2,
        "io": _2,
        "name": _2,
        "net": _2,
        "org": _2,
        "pro": _2,
        "angiang": _2,
        "bacgiang": _2,
        "backan": _2,
        "baclieu": _2,
        "bacninh": _2,
        "baria-vungtau": _2,
        "bentre": _2,
        "binhdinh": _2,
        "binhduong": _2,
        "binhphuoc": _2,
        "binhthuan": _2,
        "camau": _2,
        "cantho": _2,
        "caobang": _2,
        "daklak": _2,
        "daknong": _2,
        "danang": _2,
        "dienbien": _2,
        "dongnai": _2,
        "dongthap": _2,
        "gialai": _2,
        "hagiang": _2,
        "haiduong": _2,
        "haiphong": _2,
        "hanam": _2,
        "hanoi": _2,
        "hatinh": _2,
        "haugiang": _2,
        "hoabinh": _2,
        "hungyen": _2,
        "khanhhoa": _2,
        "kiengiang": _2,
        "kontum": _2,
        "laichau": _2,
        "lamdong": _2,
        "langson": _2,
        "laocai": _2,
        "longan": _2,
        "namdinh": _2,
        "nghean": _2,
        "ninhbinh": _2,
        "ninhthuan": _2,
        "phutho": _2,
        "phuyen": _2,
        "quangbinh": _2,
        "quangnam": _2,
        "quangngai": _2,
        "quangninh": _2,
        "quangtri": _2,
        "soctrang": _2,
        "sonla": _2,
        "tayninh": _2,
        "thaibinh": _2,
        "thainguyen": _2,
        "thanhhoa": _2,
        "thanhphohochiminh": _2,
        "thuathienhue": _2,
        "tiengiang": _2,
        "travinh": _2,
        "tuyenquang": _2,
        "vinhlong": _2,
        "vinhphuc": _2,
        "yenbai": _2
      }],
      "vu": _45,
      "wf": [1, {
        "biz": _3,
        "sch": _3
      }],
      "ws": [1, {
        "com": _2,
        "edu": _2,
        "gov": _2,
        "net": _2,
        "org": _2,
        "advisor": _6,
        "cloud66": _3,
        "dyndns": _3,
        "mypets": _3
      }],
      "yt": [1, {
        "org": _3
      }],
      "xn--mgbaam7a8h": _2,
      "امارات": _2,
      "xn--y9a3aq": _2,
      "հայ": _2,
      "xn--54b7fta0cc": _2,
      "বাংলা": _2,
      "xn--90ae": _2,
      "бг": _2,
      "xn--mgbcpq6gpa1a": _2,
      "البحرين": _2,
      "xn--90ais": _2,
      "бел": _2,
      "xn--fiqs8s": _2,
      "中国": _2,
      "xn--fiqz9s": _2,
      "中國": _2,
      "xn--lgbbat1ad8j": _2,
      "الجزائر": _2,
      "xn--wgbh1c": _2,
      "مصر": _2,
      "xn--e1a4c": _2,
      "ею": _2,
      "xn--qxa6a": _2,
      "ευ": _2,
      "xn--mgbah1a3hjkrd": _2,
      "موريتانيا": _2,
      "xn--node": _2,
      "გე": _2,
      "xn--qxam": _2,
      "ελ": _2,
      "xn--j6w193g": [1, {
        "xn--gmqw5a": _2,
        "xn--55qx5d": _2,
        "xn--mxtq1m": _2,
        "xn--wcvs22d": _2,
        "xn--uc0atv": _2,
        "xn--od0alg": _2
      }],
      "香港": [1, {
        "個人": _2,
        "公司": _2,
        "政府": _2,
        "教育": _2,
        "組織": _2,
        "網絡": _2
      }],
      "xn--2scrj9c": _2,
      "ಭಾರತ": _2,
      "xn--3hcrj9c": _2,
      "ଭାରତ": _2,
      "xn--45br5cyl": _2,
      "ভাৰত": _2,
      "xn--h2breg3eve": _2,
      "भारतम्": _2,
      "xn--h2brj9c8c": _2,
      "भारोत": _2,
      "xn--mgbgu82a": _2,
      "ڀارت": _2,
      "xn--rvc1e0am3e": _2,
      "ഭാരതം": _2,
      "xn--h2brj9c": _2,
      "भारत": _2,
      "xn--mgbbh1a": _2,
      "بارت": _2,
      "xn--mgbbh1a71e": _2,
      "بھارت": _2,
      "xn--fpcrj9c3d": _2,
      "భారత్": _2,
      "xn--gecrj9c": _2,
      "ભારત": _2,
      "xn--s9brj9c": _2,
      "ਭਾਰਤ": _2,
      "xn--45brj9c": _2,
      "ভারত": _2,
      "xn--xkc2dl3a5ee0h": _2,
      "இந்தியா": _2,
      "xn--mgba3a4f16a": _2,
      "ایران": _2,
      "xn--mgba3a4fra": _2,
      "ايران": _2,
      "xn--mgbtx2b": _2,
      "عراق": _2,
      "xn--mgbayh7gpa": _2,
      "الاردن": _2,
      "xn--3e0b707e": _2,
      "한국": _2,
      "xn--80ao21a": _2,
      "қаз": _2,
      "xn--q7ce6a": _2,
      "ລາວ": _2,
      "xn--fzc2c9e2c": _2,
      "ලංකා": _2,
      "xn--xkc2al3hye2a": _2,
      "இலங்கை": _2,
      "xn--mgbc0a9azcg": _2,
      "المغرب": _2,
      "xn--d1alf": _2,
      "мкд": _2,
      "xn--l1acc": _2,
      "мон": _2,
      "xn--mix891f": _2,
      "澳門": _2,
      "xn--mix082f": _2,
      "澳门": _2,
      "xn--mgbx4cd0ab": _2,
      "مليسيا": _2,
      "xn--mgb9awbf": _2,
      "عمان": _2,
      "xn--mgbai9azgqp6j": _2,
      "پاکستان": _2,
      "xn--mgbai9a5eva00b": _2,
      "پاكستان": _2,
      "xn--ygbi2ammx": _2,
      "فلسطين": _2,
      "xn--90a3ac": [1, {
        "xn--80au": _2,
        "xn--90azh": _2,
        "xn--d1at": _2,
        "xn--c1avg": _2,
        "xn--o1ac": _2,
        "xn--o1ach": _2
      }],
      "срб": [1, {
        "ак": _2,
        "обр": _2,
        "од": _2,
        "орг": _2,
        "пр": _2,
        "упр": _2
      }],
      "xn--p1ai": _2,
      "рф": _2,
      "xn--wgbl6a": _2,
      "قطر": _2,
      "xn--mgberp4a5d4ar": _2,
      "السعودية": _2,
      "xn--mgberp4a5d4a87g": _2,
      "السعودیة": _2,
      "xn--mgbqly7c0a67fbc": _2,
      "السعودیۃ": _2,
      "xn--mgbqly7cvafr": _2,
      "السعوديه": _2,
      "xn--mgbpl2fh": _2,
      "سودان": _2,
      "xn--yfro4i67o": _2,
      "新加坡": _2,
      "xn--clchc0ea0b2g2a9gcd": _2,
      "சிங்கப்பூர்": _2,
      "xn--ogbpf8fl": _2,
      "سورية": _2,
      "xn--mgbtf8fl": _2,
      "سوريا": _2,
      "xn--o3cw4h": [1, {
        "xn--o3cyx2a": _2,
        "xn--12co0c3b4eva": _2,
        "xn--m3ch0j3a": _2,
        "xn--h3cuzk1di": _2,
        "xn--12c1fe0br": _2,
        "xn--12cfi8ixb8l": _2
      }],
      "ไทย": [1, {
        "ทหาร": _2,
        "ธุรกิจ": _2,
        "เน็ต": _2,
        "รัฐบาล": _2,
        "ศึกษา": _2,
        "องค์กร": _2
      }],
      "xn--pgbs0dh": _2,
      "تونس": _2,
      "xn--kpry57d": _2,
      "台灣": _2,
      "xn--kprw13d": _2,
      "台湾": _2,
      "xn--nnx388a": _2,
      "臺灣": _2,
      "xn--j1amh": _2,
      "укр": _2,
      "xn--mgb2ddes": _2,
      "اليمن": _2,
      "xxx": _2,
      "ye": _5,
      "za": [0, {
        "ac": _2,
        "agric": _2,
        "alt": _2,
        "co": _2,
        "edu": _2,
        "gov": _2,
        "grondar": _2,
        "law": _2,
        "mil": _2,
        "net": _2,
        "ngo": _2,
        "nic": _2,
        "nis": _2,
        "nom": _2,
        "org": _2,
        "school": _2,
        "tm": _2,
        "web": _2
      }],
      "zm": [1, {
        "ac": _2,
        "biz": _2,
        "co": _2,
        "com": _2,
        "edu": _2,
        "gov": _2,
        "info": _2,
        "mil": _2,
        "net": _2,
        "org": _2,
        "sch": _2
      }],
      "zw": [1, {
        "ac": _2,
        "co": _2,
        "gov": _2,
        "mil": _2,
        "org": _2
      }],
      "aaa": _2,
      "aarp": _2,
      "abb": _2,
      "abbott": _2,
      "abbvie": _2,
      "abc": _2,
      "able": _2,
      "abogado": _2,
      "abudhabi": _2,
      "academy": [1, {
        "official": _3
      }],
      "accenture": _2,
      "accountant": _2,
      "accountants": _2,
      "aco": _2,
      "actor": _2,
      "ads": _2,
      "adult": _2,
      "aeg": _2,
      "aetna": _2,
      "afl": _2,
      "africa": _2,
      "agakhan": _2,
      "agency": _2,
      "aig": _2,
      "airbus": _2,
      "airforce": _2,
      "airtel": _2,
      "akdn": _2,
      "alibaba": _2,
      "alipay": _2,
      "allfinanz": _2,
      "allstate": _2,
      "ally": _2,
      "alsace": _2,
      "alstom": _2,
      "amazon": _2,
      "americanexpress": _2,
      "americanfamily": _2,
      "amex": _2,
      "amfam": _2,
      "amica": _2,
      "amsterdam": _2,
      "analytics": _2,
      "android": _2,
      "anquan": _2,
      "anz": _2,
      "aol": _2,
      "apartments": _2,
      "app": [1, {
        "adaptable": _3,
        "aiven": _3,
        "beget": _6,
        "brave": _7,
        "clerk": _3,
        "clerkstage": _3,
        "wnext": _3,
        "csb": [2, {
          "preview": _3
        }],
        "convex": _3,
        "deta": _3,
        "ondigitalocean": _3,
        "easypanel": _3,
        "encr": [2, {
          "frontend": _3
        }],
        "evervault": _8,
        "expo": [2, {
          "staging": _3
        }],
        "edgecompute": _3,
        "on-fleek": _3,
        "flutterflow": _3,
        "e2b": _3,
        "framer": _3,
        "github": _3,
        "hosted": _6,
        "run": [0, {
          "*": _3,
          "mtls": _6
        }],
        "web": _3,
        "hasura": _3,
        "botdash": _3,
        "loginline": _3,
        "lovable": _3,
        "luyani": _3,
        "medusajs": _3,
        "messerli": _3,
        "netfy": _3,
        "netlify": _3,
        "ngrok": _3,
        "ngrok-free": _3,
        "developer": _6,
        "noop": _3,
        "northflank": _6,
        "upsun": _6,
        "railway": [0, {
          "up": _3
        }],
        "replit": _9,
        "nyat": _3,
        "snowflake": [0, {
          "*": _3,
          "privatelink": _6
        }],
        "streamlit": _3,
        "storipress": _3,
        "telebit": _3,
        "typedream": _3,
        "vercel": _3,
        "bookonline": _3,
        "wdh": _3,
        "windsurf": _3,
        "zeabur": _3,
        "zerops": _6
      }],
      "apple": _2,
      "aquarelle": _2,
      "arab": _2,
      "aramco": _2,
      "archi": _2,
      "army": _2,
      "art": _2,
      "arte": _2,
      "asda": _2,
      "associates": _2,
      "athleta": _2,
      "attorney": _2,
      "auction": _2,
      "audi": _2,
      "audible": _2,
      "audio": _2,
      "auspost": _2,
      "author": _2,
      "auto": _2,
      "autos": _2,
      "aws": [1, {
        "on": [0, {
          "af-south-1": _11,
          "ap-east-1": _11,
          "ap-northeast-1": _11,
          "ap-northeast-2": _11,
          "ap-northeast-3": _11,
          "ap-south-1": _11,
          "ap-south-2": _11,
          "ap-southeast-1": _11,
          "ap-southeast-2": _11,
          "ap-southeast-3": _11,
          "ap-southeast-4": _11,
          "ap-southeast-5": _11,
          "ca-central-1": _11,
          "ca-west-1": _11,
          "eu-central-1": _11,
          "eu-central-2": _11,
          "eu-north-1": _11,
          "eu-south-1": _11,
          "eu-south-2": _11,
          "eu-west-1": _11,
          "eu-west-2": _11,
          "eu-west-3": _11,
          "il-central-1": _11,
          "me-central-1": _11,
          "me-south-1": _11,
          "sa-east-1": _11,
          "us-east-1": _11,
          "us-east-2": _11,
          "us-west-1": _11,
          "us-west-2": _11,
          "us-gov-east-1": _12,
          "us-gov-west-1": _12
        }],
        "sagemaker": [0, {
          "ap-northeast-1": _14,
          "ap-northeast-2": _14,
          "ap-south-1": _14,
          "ap-southeast-1": _14,
          "ap-southeast-2": _14,
          "ca-central-1": _16,
          "eu-central-1": _14,
          "eu-west-1": _14,
          "eu-west-2": _14,
          "us-east-1": _16,
          "us-east-2": _16,
          "us-west-2": _16,
          "af-south-1": _13,
          "ap-east-1": _13,
          "ap-northeast-3": _13,
          "ap-south-2": _15,
          "ap-southeast-3": _13,
          "ap-southeast-4": _15,
          "ca-west-1": [0, {
            "notebook": _3,
            "notebook-fips": _3
          }],
          "eu-central-2": _13,
          "eu-north-1": _13,
          "eu-south-1": _13,
          "eu-south-2": _13,
          "eu-west-3": _13,
          "il-central-1": _13,
          "me-central-1": _13,
          "me-south-1": _13,
          "sa-east-1": _13,
          "us-gov-east-1": _17,
          "us-gov-west-1": _17,
          "us-west-1": [0, {
            "notebook": _3,
            "notebook-fips": _3,
            "studio": _3
          }],
          "experiments": _6
        }],
        "repost": [0, {
          "private": _6
        }]
      }],
      "axa": _2,
      "azure": _2,
      "baby": _2,
      "baidu": _2,
      "banamex": _2,
      "band": _2,
      "bank": _2,
      "bar": _2,
      "barcelona": _2,
      "barclaycard": _2,
      "barclays": _2,
      "barefoot": _2,
      "bargains": _2,
      "baseball": _2,
      "basketball": [1, {
        "aus": _3,
        "nz": _3
      }],
      "bauhaus": _2,
      "bayern": _2,
      "bbc": _2,
      "bbt": _2,
      "bbva": _2,
      "bcg": _2,
      "bcn": _2,
      "beats": _2,
      "beauty": _2,
      "beer": _2,
      "berlin": _2,
      "best": _2,
      "bestbuy": _2,
      "bet": _2,
      "bharti": _2,
      "bible": _2,
      "bid": _2,
      "bike": _2,
      "bing": _2,
      "bingo": _2,
      "bio": _2,
      "black": _2,
      "blackfriday": _2,
      "blockbuster": _2,
      "blog": _2,
      "bloomberg": _2,
      "blue": _2,
      "bms": _2,
      "bmw": _2,
      "bnpparibas": _2,
      "boats": _2,
      "boehringer": _2,
      "bofa": _2,
      "bom": _2,
      "bond": _2,
      "boo": _2,
      "book": _2,
      "booking": _2,
      "bosch": _2,
      "bostik": _2,
      "boston": _2,
      "bot": _2,
      "boutique": _2,
      "box": _2,
      "bradesco": _2,
      "bridgestone": _2,
      "broadway": _2,
      "broker": _2,
      "brother": _2,
      "brussels": _2,
      "build": [1, {
        "v0": _3,
        "windsurf": _3
      }],
      "builders": [1, {
        "cloudsite": _3
      }],
      "business": _19,
      "buy": _2,
      "buzz": _2,
      "bzh": _2,
      "cab": _2,
      "cafe": _2,
      "cal": _2,
      "call": _2,
      "calvinklein": _2,
      "cam": _2,
      "camera": _2,
      "camp": [1, {
        "emf": [0, {
          "at": _3
        }]
      }],
      "canon": _2,
      "capetown": _2,
      "capital": _2,
      "capitalone": _2,
      "car": _2,
      "caravan": _2,
      "cards": _2,
      "care": _2,
      "career": _2,
      "careers": _2,
      "cars": _2,
      "casa": [1, {
        "nabu": [0, {
          "ui": _3
        }]
      }],
      "case": _2,
      "cash": _2,
      "casino": _2,
      "catering": _2,
      "catholic": _2,
      "cba": _2,
      "cbn": _2,
      "cbre": _2,
      "center": _2,
      "ceo": _2,
      "cern": _2,
      "cfa": _2,
      "cfd": _2,
      "chanel": _2,
      "channel": _2,
      "charity": _2,
      "chase": _2,
      "chat": _2,
      "cheap": _2,
      "chintai": _2,
      "christmas": _2,
      "chrome": _2,
      "church": _2,
      "cipriani": _2,
      "circle": _2,
      "cisco": _2,
      "citadel": _2,
      "citi": _2,
      "citic": _2,
      "city": _2,
      "claims": _2,
      "cleaning": _2,
      "click": _2,
      "clinic": _2,
      "clinique": _2,
      "clothing": _2,
      "cloud": [1, {
        "convex": _3,
        "elementor": _3,
        "encoway": [0, {
          "eu": _3
        }],
        "statics": _6,
        "ravendb": _3,
        "axarnet": [0, {
          "es-1": _3
        }],
        "diadem": _3,
        "jelastic": [0, {
          "vip": _3
        }],
        "jele": _3,
        "jenv-aruba": [0, {
          "aruba": [0, {
            "eur": [0, {
              "it1": _3
            }]
          }],
          "it1": _3
        }],
        "keliweb": [2, {
          "cs": _3
        }],
        "oxa": [2, {
          "tn": _3,
          "uk": _3
        }],
        "primetel": [2, {
          "uk": _3
        }],
        "reclaim": [0, {
          "ca": _3,
          "uk": _3,
          "us": _3
        }],
        "trendhosting": [0, {
          "ch": _3,
          "de": _3
        }],
        "jotelulu": _3,
        "kuleuven": _3,
        "laravel": _3,
        "linkyard": _3,
        "magentosite": _6,
        "matlab": _3,
        "observablehq": _3,
        "perspecta": _3,
        "vapor": _3,
        "on-rancher": _6,
        "scw": [0, {
          "baremetal": [0, {
            "fr-par-1": _3,
            "fr-par-2": _3,
            "nl-ams-1": _3
          }],
          "fr-par": [0, {
            "cockpit": _3,
            "ddl": _3,
            "dtwh": _3,
            "fnc": [2, {
              "functions": _3
            }],
            "ifr": _3,
            "k8s": _21,
            "kafk": _3,
            "mgdb": _3,
            "rdb": _3,
            "s3": _3,
            "s3-website": _3,
            "scbl": _3,
            "whm": _3
          }],
          "instances": [0, {
            "priv": _3,
            "pub": _3
          }],
          "k8s": _3,
          "nl-ams": [0, {
            "cockpit": _3,
            "ddl": _3,
            "dtwh": _3,
            "ifr": _3,
            "k8s": _21,
            "kafk": _3,
            "mgdb": _3,
            "rdb": _3,
            "s3": _3,
            "s3-website": _3,
            "scbl": _3,
            "whm": _3
          }],
          "pl-waw": [0, {
            "cockpit": _3,
            "ddl": _3,
            "dtwh": _3,
            "ifr": _3,
            "k8s": _21,
            "kafk": _3,
            "mgdb": _3,
            "rdb": _3,
            "s3": _3,
            "s3-website": _3,
            "scbl": _3
          }],
          "scalebook": _3,
          "smartlabeling": _3
        }],
        "servebolt": _3,
        "onstackit": [0, {
          "runs": _3
        }],
        "trafficplex": _3,
        "unison-services": _3,
        "urown": _3,
        "voorloper": _3,
        "zap": _3
      }],
      "club": [1, {
        "cloudns": _3,
        "jele": _3,
        "barsy": _3
      }],
      "clubmed": _2,
      "coach": _2,
      "codes": [1, {
        "owo": _6
      }],
      "coffee": _2,
      "college": _2,
      "cologne": _2,
      "commbank": _2,
      "community": [1, {
        "nog": _3,
        "ravendb": _3,
        "myforum": _3
      }],
      "company": _2,
      "compare": _2,
      "computer": _2,
      "comsec": _2,
      "condos": _2,
      "construction": _2,
      "consulting": _2,
      "contact": _2,
      "contractors": _2,
      "cooking": _2,
      "cool": [1, {
        "elementor": _3,
        "de": _3
      }],
      "corsica": _2,
      "country": _2,
      "coupon": _2,
      "coupons": _2,
      "courses": _2,
      "cpa": _2,
      "credit": _2,
      "creditcard": _2,
      "creditunion": _2,
      "cricket": _2,
      "crown": _2,
      "crs": _2,
      "cruise": _2,
      "cruises": _2,
      "cuisinella": _2,
      "cymru": _2,
      "cyou": _2,
      "dad": _2,
      "dance": _2,
      "data": _2,
      "date": _2,
      "dating": _2,
      "datsun": _2,
      "day": _2,
      "dclk": _2,
      "dds": _2,
      "deal": _2,
      "dealer": _2,
      "deals": _2,
      "degree": _2,
      "delivery": _2,
      "dell": _2,
      "deloitte": _2,
      "delta": _2,
      "democrat": _2,
      "dental": _2,
      "dentist": _2,
      "desi": _2,
      "design": [1, {
        "graphic": _3,
        "bss": _3
      }],
      "dev": [1, {
        "12chars": _3,
        "myaddr": _3,
        "panel": _3,
        "lcl": _6,
        "lclstage": _6,
        "stg": _6,
        "stgstage": _6,
        "pages": _3,
        "r2": _3,
        "workers": _3,
        "deno": _3,
        "deno-staging": _3,
        "deta": _3,
        "lp": [2, {
          "api": _3,
          "objects": _3
        }],
        "evervault": _8,
        "fly": _3,
        "githubpreview": _3,
        "gateway": _6,
        "botdash": _3,
        "inbrowser": _6,
        "is-a-good": _3,
        "is-a": _3,
        "iserv": _3,
        "runcontainers": _3,
        "localcert": [0, {
          "user": _6
        }],
        "loginline": _3,
        "barsy": _3,
        "mediatech": _3,
        "modx": _3,
        "ngrok": _3,
        "ngrok-free": _3,
        "is-a-fullstack": _3,
        "is-cool": _3,
        "is-not-a": _3,
        "localplayer": _3,
        "xmit": _3,
        "platter-app": _3,
        "replit": [2, {
          "archer": _3,
          "bones": _3,
          "canary": _3,
          "global": _3,
          "hacker": _3,
          "id": _3,
          "janeway": _3,
          "kim": _3,
          "kira": _3,
          "kirk": _3,
          "odo": _3,
          "paris": _3,
          "picard": _3,
          "pike": _3,
          "prerelease": _3,
          "reed": _3,
          "riker": _3,
          "sisko": _3,
          "spock": _3,
          "staging": _3,
          "sulu": _3,
          "tarpit": _3,
          "teams": _3,
          "tucker": _3,
          "wesley": _3,
          "worf": _3
        }],
        "crm": [0, {
          "d": _6,
          "w": _6,
          "wa": _6,
          "wb": _6,
          "wc": _6,
          "wd": _6,
          "we": _6,
          "wf": _6
        }],
        "erp": _48,
        "vercel": _3,
        "webhare": _6,
        "hrsn": _3
      }],
      "dhl": _2,
      "diamonds": _2,
      "diet": _2,
      "digital": [1, {
        "cloudapps": [2, {
          "london": _3
        }]
      }],
      "direct": [1, {
        "libp2p": _3
      }],
      "directory": _2,
      "discount": _2,
      "discover": _2,
      "dish": _2,
      "diy": _2,
      "dnp": _2,
      "docs": _2,
      "doctor": _2,
      "dog": _2,
      "domains": _2,
      "dot": _2,
      "download": _2,
      "drive": _2,
      "dtv": _2,
      "dubai": _2,
      "dunlop": _2,
      "dupont": _2,
      "durban": _2,
      "dvag": _2,
      "dvr": _2,
      "earth": _2,
      "eat": _2,
      "eco": _2,
      "edeka": _2,
      "education": _19,
      "email": [1, {
        "crisp": [0, {
          "on": _3
        }],
        "tawk": _50,
        "tawkto": _50
      }],
      "emerck": _2,
      "energy": _2,
      "engineer": _2,
      "engineering": _2,
      "enterprises": _2,
      "epson": _2,
      "equipment": _2,
      "ericsson": _2,
      "erni": _2,
      "esq": _2,
      "estate": [1, {
        "compute": _6
      }],
      "eurovision": _2,
      "eus": [1, {
        "party": _51
      }],
      "events": [1, {
        "koobin": _3,
        "co": _3
      }],
      "exchange": _2,
      "expert": _2,
      "exposed": _2,
      "express": _2,
      "extraspace": _2,
      "fage": _2,
      "fail": _2,
      "fairwinds": _2,
      "faith": _2,
      "family": _2,
      "fan": _2,
      "fans": _2,
      "farm": [1, {
        "storj": _3
      }],
      "farmers": _2,
      "fashion": _2,
      "fast": _2,
      "fedex": _2,
      "feedback": _2,
      "ferrari": _2,
      "ferrero": _2,
      "fidelity": _2,
      "fido": _2,
      "film": _2,
      "final": _2,
      "finance": _2,
      "financial": _19,
      "fire": _2,
      "firestone": _2,
      "firmdale": _2,
      "fish": _2,
      "fishing": _2,
      "fit": _2,
      "fitness": _2,
      "flickr": _2,
      "flights": _2,
      "flir": _2,
      "florist": _2,
      "flowers": _2,
      "fly": _2,
      "foo": _2,
      "food": _2,
      "football": _2,
      "ford": _2,
      "forex": _2,
      "forsale": _2,
      "forum": _2,
      "foundation": _2,
      "fox": _2,
      "free": _2,
      "fresenius": _2,
      "frl": _2,
      "frogans": _2,
      "frontier": _2,
      "ftr": _2,
      "fujitsu": _2,
      "fun": _2,
      "fund": _2,
      "furniture": _2,
      "futbol": _2,
      "fyi": _2,
      "gal": _2,
      "gallery": _2,
      "gallo": _2,
      "gallup": _2,
      "game": _2,
      "games": [1, {
        "pley": _3,
        "sheezy": _3
      }],
      "gap": _2,
      "garden": _2,
      "gay": [1, {
        "pages": _3
      }],
      "gbiz": _2,
      "gdn": [1, {
        "cnpy": _3
      }],
      "gea": _2,
      "gent": _2,
      "genting": _2,
      "george": _2,
      "ggee": _2,
      "gift": _2,
      "gifts": _2,
      "gives": _2,
      "giving": _2,
      "glass": _2,
      "gle": _2,
      "global": [1, {
        "appwrite": _3
      }],
      "globo": _2,
      "gmail": _2,
      "gmbh": _2,
      "gmo": _2,
      "gmx": _2,
      "godaddy": _2,
      "gold": _2,
      "goldpoint": _2,
      "golf": _2,
      "goo": _2,
      "goodyear": _2,
      "goog": [1, {
        "cloud": _3,
        "translate": _3,
        "usercontent": _6
      }],
      "google": _2,
      "gop": _2,
      "got": _2,
      "grainger": _2,
      "graphics": _2,
      "gratis": _2,
      "green": _2,
      "gripe": _2,
      "grocery": _2,
      "group": [1, {
        "discourse": _3
      }],
      "gucci": _2,
      "guge": _2,
      "guide": _2,
      "guitars": _2,
      "guru": _2,
      "hair": _2,
      "hamburg": _2,
      "hangout": _2,
      "haus": _2,
      "hbo": _2,
      "hdfc": _2,
      "hdfcbank": _2,
      "health": [1, {
        "hra": _3
      }],
      "healthcare": _2,
      "help": _2,
      "helsinki": _2,
      "here": _2,
      "hermes": _2,
      "hiphop": _2,
      "hisamitsu": _2,
      "hitachi": _2,
      "hiv": _2,
      "hkt": _2,
      "hockey": _2,
      "holdings": _2,
      "holiday": _2,
      "homedepot": _2,
      "homegoods": _2,
      "homes": _2,
      "homesense": _2,
      "honda": _2,
      "horse": _2,
      "hospital": _2,
      "host": [1, {
        "cloudaccess": _3,
        "freesite": _3,
        "easypanel": _3,
        "fastvps": _3,
        "myfast": _3,
        "tempurl": _3,
        "wpmudev": _3,
        "iserv": _3,
        "jele": _3,
        "mircloud": _3,
        "wp2": _3,
        "half": _3
      }],
      "hosting": [1, {
        "opencraft": _3
      }],
      "hot": _2,
      "hotel": _2,
      "hotels": _2,
      "hotmail": _2,
      "house": _2,
      "how": _2,
      "hsbc": _2,
      "hughes": _2,
      "hyatt": _2,
      "hyundai": _2,
      "ibm": _2,
      "icbc": _2,
      "ice": _2,
      "icu": _2,
      "ieee": _2,
      "ifm": _2,
      "ikano": _2,
      "imamat": _2,
      "imdb": _2,
      "immo": _2,
      "immobilien": _2,
      "inc": _2,
      "industries": _2,
      "infiniti": _2,
      "ing": _2,
      "ink": _2,
      "institute": _2,
      "insurance": _2,
      "insure": _2,
      "international": _2,
      "intuit": _2,
      "investments": _2,
      "ipiranga": _2,
      "irish": _2,
      "ismaili": _2,
      "ist": _2,
      "istanbul": _2,
      "itau": _2,
      "itv": _2,
      "jaguar": _2,
      "java": _2,
      "jcb": _2,
      "jeep": _2,
      "jetzt": _2,
      "jewelry": _2,
      "jio": _2,
      "jll": _2,
      "jmp": _2,
      "jnj": _2,
      "joburg": _2,
      "jot": _2,
      "joy": _2,
      "jpmorgan": _2,
      "jprs": _2,
      "juegos": _2,
      "juniper": _2,
      "kaufen": _2,
      "kddi": _2,
      "kerryhotels": _2,
      "kerryproperties": _2,
      "kfh": _2,
      "kia": _2,
      "kids": _2,
      "kim": _2,
      "kindle": _2,
      "kitchen": _2,
      "kiwi": _2,
      "koeln": _2,
      "komatsu": _2,
      "kosher": _2,
      "kpmg": _2,
      "kpn": _2,
      "krd": [1, {
        "co": _3,
        "edu": _3
      }],
      "kred": _2,
      "kuokgroup": _2,
      "kyoto": _2,
      "lacaixa": _2,
      "lamborghini": _2,
      "lamer": _2,
      "land": _2,
      "landrover": _2,
      "lanxess": _2,
      "lasalle": _2,
      "lat": _2,
      "latino": _2,
      "latrobe": _2,
      "law": _2,
      "lawyer": _2,
      "lds": _2,
      "lease": _2,
      "leclerc": _2,
      "lefrak": _2,
      "legal": _2,
      "lego": _2,
      "lexus": _2,
      "lgbt": _2,
      "lidl": _2,
      "life": _2,
      "lifeinsurance": _2,
      "lifestyle": _2,
      "lighting": _2,
      "like": _2,
      "lilly": _2,
      "limited": _2,
      "limo": _2,
      "lincoln": _2,
      "link": [1, {
        "myfritz": _3,
        "cyon": _3,
        "dweb": _6,
        "inbrowser": _6,
        "nftstorage": _59,
        "mypep": _3,
        "storacha": _59,
        "w3s": _59
      }],
      "live": [1, {
        "aem": _3,
        "hlx": _3,
        "ewp": _6
      }],
      "living": _2,
      "llc": _2,
      "llp": _2,
      "loan": _2,
      "loans": _2,
      "locker": _2,
      "locus": _2,
      "lol": [1, {
        "omg": _3
      }],
      "london": _2,
      "lotte": _2,
      "lotto": _2,
      "love": _2,
      "lpl": _2,
      "lplfinancial": _2,
      "ltd": _2,
      "ltda": _2,
      "lundbeck": _2,
      "luxe": _2,
      "luxury": _2,
      "madrid": _2,
      "maif": _2,
      "maison": _2,
      "makeup": _2,
      "man": _2,
      "management": _2,
      "mango": _2,
      "map": _2,
      "market": _2,
      "marketing": _2,
      "markets": _2,
      "marriott": _2,
      "marshalls": _2,
      "mattel": _2,
      "mba": _2,
      "mckinsey": _2,
      "med": _2,
      "media": _60,
      "meet": _2,
      "melbourne": _2,
      "meme": _2,
      "memorial": _2,
      "men": _2,
      "menu": [1, {
        "barsy": _3,
        "barsyonline": _3
      }],
      "merck": _2,
      "merckmsd": _2,
      "miami": _2,
      "microsoft": _2,
      "mini": _2,
      "mint": _2,
      "mit": _2,
      "mitsubishi": _2,
      "mlb": _2,
      "mls": _2,
      "mma": _2,
      "mobile": _2,
      "moda": _2,
      "moe": _2,
      "moi": _2,
      "mom": _2,
      "monash": _2,
      "money": _2,
      "monster": _2,
      "mormon": _2,
      "mortgage": _2,
      "moscow": _2,
      "moto": _2,
      "motorcycles": _2,
      "mov": _2,
      "movie": _2,
      "msd": _2,
      "mtn": _2,
      "mtr": _2,
      "music": _2,
      "nab": _2,
      "nagoya": _2,
      "navy": _2,
      "nba": _2,
      "nec": _2,
      "netbank": _2,
      "netflix": _2,
      "network": [1, {
        "aem": _3,
        "alces": _6,
        "co": _3,
        "arvo": _3,
        "azimuth": _3,
        "tlon": _3
      }],
      "neustar": _2,
      "new": _2,
      "news": [1, {
        "noticeable": _3
      }],
      "next": _2,
      "nextdirect": _2,
      "nexus": _2,
      "nfl": _2,
      "ngo": _2,
      "nhk": _2,
      "nico": _2,
      "nike": _2,
      "nikon": _2,
      "ninja": _2,
      "nissan": _2,
      "nissay": _2,
      "nokia": _2,
      "norton": _2,
      "now": _2,
      "nowruz": _2,
      "nowtv": _2,
      "nra": _2,
      "nrw": _2,
      "ntt": _2,
      "nyc": _2,
      "obi": _2,
      "observer": _2,
      "office": _2,
      "okinawa": _2,
      "olayan": _2,
      "olayangroup": _2,
      "ollo": _2,
      "omega": _2,
      "one": [1, {
        "kin": _6,
        "service": _3
      }],
      "ong": [1, {
        "obl": _3
      }],
      "onl": _2,
      "online": [1, {
        "eero": _3,
        "eero-stage": _3,
        "websitebuilder": _3,
        "barsy": _3
      }],
      "ooo": _2,
      "open": _2,
      "oracle": _2,
      "orange": [1, {
        "tech": _3
      }],
      "organic": _2,
      "origins": _2,
      "osaka": _2,
      "otsuka": _2,
      "ott": _2,
      "ovh": [1, {
        "nerdpol": _3
      }],
      "page": [1, {
        "aem": _3,
        "hlx": _3,
        "translated": _3,
        "codeberg": _3,
        "heyflow": _3,
        "prvcy": _3,
        "rocky": _3,
        "pdns": _3,
        "plesk": _3
      }],
      "panasonic": _2,
      "paris": _2,
      "pars": _2,
      "partners": _2,
      "parts": _2,
      "party": _2,
      "pay": _2,
      "pccw": _2,
      "pet": _2,
      "pfizer": _2,
      "pharmacy": _2,
      "phd": _2,
      "philips": _2,
      "phone": _2,
      "photo": _2,
      "photography": _2,
      "photos": _60,
      "physio": _2,
      "pics": _2,
      "pictet": _2,
      "pictures": [1, {
        "1337": _3
      }],
      "pid": _2,
      "pin": _2,
      "ping": _2,
      "pink": _2,
      "pioneer": _2,
      "pizza": [1, {
        "ngrok": _3
      }],
      "place": _19,
      "play": _2,
      "playstation": _2,
      "plumbing": _2,
      "plus": _2,
      "pnc": _2,
      "pohl": _2,
      "poker": _2,
      "politie": _2,
      "porn": _2,
      "praxi": _2,
      "press": _2,
      "prime": _2,
      "prod": _2,
      "productions": _2,
      "prof": _2,
      "progressive": _2,
      "promo": _2,
      "properties": _2,
      "property": _2,
      "protection": _2,
      "pru": _2,
      "prudential": _2,
      "pub": [1, {
        "id": _6,
        "kin": _6,
        "barsy": _3
      }],
      "pwc": _2,
      "qpon": _2,
      "quebec": _2,
      "quest": _2,
      "racing": _2,
      "radio": _2,
      "read": _2,
      "realestate": _2,
      "realtor": _2,
      "realty": _2,
      "recipes": _2,
      "red": _2,
      "redstone": _2,
      "redumbrella": _2,
      "rehab": _2,
      "reise": _2,
      "reisen": _2,
      "reit": _2,
      "reliance": _2,
      "ren": _2,
      "rent": _2,
      "rentals": _2,
      "repair": _2,
      "report": _2,
      "republican": _2,
      "rest": _2,
      "restaurant": _2,
      "review": _2,
      "reviews": [1, {
        "aem": _3
      }],
      "rexroth": _2,
      "rich": _2,
      "richardli": _2,
      "ricoh": _2,
      "ril": _2,
      "rio": _2,
      "rip": [1, {
        "clan": _3
      }],
      "rocks": [1, {
        "myddns": _3,
        "stackit": _3,
        "lima-city": _3,
        "webspace": _3
      }],
      "rodeo": _2,
      "rogers": _2,
      "room": _2,
      "rsvp": _2,
      "rugby": _2,
      "ruhr": _2,
      "run": [1, {
        "appwrite": _6,
        "development": _3,
        "ravendb": _3,
        "liara": [2, {
          "iran": _3
        }],
        "servers": _3,
        "lovable": _3,
        "build": _6,
        "code": _6,
        "database": _6,
        "migration": _6,
        "onporter": _3,
        "repl": _3,
        "stackit": _3,
        "val": _48,
        "vercel": _3,
        "wix": _3
      }],
      "rwe": _2,
      "ryukyu": _2,
      "saarland": _2,
      "safe": _2,
      "safety": _2,
      "sakura": _2,
      "sale": _2,
      "salon": _2,
      "samsclub": _2,
      "samsung": _2,
      "sandvik": _2,
      "sandvikcoromant": _2,
      "sanofi": _2,
      "sap": _2,
      "sarl": _2,
      "sas": _2,
      "save": _2,
      "saxo": _2,
      "sbi": _2,
      "sbs": _2,
      "scb": _2,
      "schaeffler": _2,
      "schmidt": _2,
      "scholarships": _2,
      "school": _2,
      "schule": _2,
      "schwarz": _2,
      "science": _2,
      "scot": [1, {
        "gov": [2, {
          "service": _3
        }]
      }],
      "search": _2,
      "seat": _2,
      "secure": _2,
      "security": _2,
      "seek": _2,
      "select": _2,
      "sener": _2,
      "services": [1, {
        "loginline": _3
      }],
      "seven": _2,
      "sew": _2,
      "sex": _2,
      "sexy": _2,
      "sfr": _2,
      "shangrila": _2,
      "sharp": _2,
      "shell": _2,
      "shia": _2,
      "shiksha": _2,
      "shoes": _2,
      "shop": [1, {
        "base": _3,
        "hoplix": _3,
        "barsy": _3,
        "barsyonline": _3,
        "shopware": _3
      }],
      "shopping": _2,
      "shouji": _2,
      "show": _2,
      "silk": _2,
      "sina": _2,
      "singles": _2,
      "site": [1, {
        "square": _3,
        "canva": _22,
        "cloudera": _6,
        "convex": _3,
        "cyon": _3,
        "caffeine": _3,
        "fastvps": _3,
        "figma": _3,
        "preview": _3,
        "heyflow": _3,
        "jele": _3,
        "jouwweb": _3,
        "loginline": _3,
        "barsy": _3,
        "notion": _3,
        "omniwe": _3,
        "opensocial": _3,
        "madethis": _3,
        "platformsh": _6,
        "tst": _6,
        "byen": _3,
        "srht": _3,
        "novecore": _3,
        "cpanel": _3,
        "wpsquared": _3
      }],
      "ski": _2,
      "skin": _2,
      "sky": _2,
      "skype": _2,
      "sling": _2,
      "smart": _2,
      "smile": _2,
      "sncf": _2,
      "soccer": _2,
      "social": _2,
      "softbank": _2,
      "software": _2,
      "sohu": _2,
      "solar": _2,
      "solutions": _2,
      "song": _2,
      "sony": _2,
      "soy": _2,
      "spa": _2,
      "space": [1, {
        "myfast": _3,
        "heiyu": _3,
        "hf": [2, {
          "static": _3
        }],
        "app-ionos": _3,
        "project": _3,
        "uber": _3,
        "xs4all": _3
      }],
      "sport": _2,
      "spot": _2,
      "srl": _2,
      "stada": _2,
      "staples": _2,
      "star": _2,
      "statebank": _2,
      "statefarm": _2,
      "stc": _2,
      "stcgroup": _2,
      "stockholm": _2,
      "storage": _2,
      "store": [1, {
        "barsy": _3,
        "sellfy": _3,
        "shopware": _3,
        "storebase": _3
      }],
      "stream": _2,
      "studio": _2,
      "study": _2,
      "style": _2,
      "sucks": _2,
      "supplies": _2,
      "supply": _2,
      "support": [1, {
        "barsy": _3
      }],
      "surf": _2,
      "surgery": _2,
      "suzuki": _2,
      "swatch": _2,
      "swiss": _2,
      "sydney": _2,
      "systems": [1, {
        "knightpoint": _3
      }],
      "tab": _2,
      "taipei": _2,
      "talk": _2,
      "taobao": _2,
      "target": _2,
      "tatamotors": _2,
      "tatar": _2,
      "tattoo": _2,
      "tax": _2,
      "taxi": _2,
      "tci": _2,
      "tdk": _2,
      "team": [1, {
        "discourse": _3,
        "jelastic": _3
      }],
      "tech": [1, {
        "cleverapps": _3
      }],
      "technology": _19,
      "temasek": _2,
      "tennis": _2,
      "teva": _2,
      "thd": _2,
      "theater": _2,
      "theatre": _2,
      "tiaa": _2,
      "tickets": _2,
      "tienda": _2,
      "tips": _2,
      "tires": _2,
      "tirol": _2,
      "tjmaxx": _2,
      "tjx": _2,
      "tkmaxx": _2,
      "tmall": _2,
      "today": [1, {
        "prequalifyme": _3
      }],
      "tokyo": _2,
      "tools": [1, {
        "addr": _47,
        "myaddr": _3
      }],
      "top": [1, {
        "ntdll": _3,
        "wadl": _6
      }],
      "toray": _2,
      "toshiba": _2,
      "total": _2,
      "tours": _2,
      "town": _2,
      "toyota": _2,
      "toys": _2,
      "trade": _2,
      "trading": _2,
      "training": _2,
      "travel": _2,
      "travelers": _2,
      "travelersinsurance": _2,
      "trust": _2,
      "trv": _2,
      "tube": _2,
      "tui": _2,
      "tunes": _2,
      "tushu": _2,
      "tvs": _2,
      "ubank": _2,
      "ubs": _2,
      "unicom": _2,
      "university": _2,
      "uno": _2,
      "uol": _2,
      "ups": _2,
      "vacations": _2,
      "vana": _2,
      "vanguard": _2,
      "vegas": _2,
      "ventures": _2,
      "verisign": _2,
      "versicherung": _2,
      "vet": _2,
      "viajes": _2,
      "video": _2,
      "vig": _2,
      "viking": _2,
      "villas": _2,
      "vin": _2,
      "vip": [1, {
        "hidns": _3
      }],
      "virgin": _2,
      "visa": _2,
      "vision": _2,
      "viva": _2,
      "vivo": _2,
      "vlaanderen": _2,
      "vodka": _2,
      "volvo": _2,
      "vote": _2,
      "voting": _2,
      "voto": _2,
      "voyage": _2,
      "wales": _2,
      "walmart": _2,
      "walter": _2,
      "wang": _2,
      "wanggou": _2,
      "watch": _2,
      "watches": _2,
      "weather": _2,
      "weatherchannel": _2,
      "webcam": _2,
      "weber": _2,
      "website": _60,
      "wed": _2,
      "wedding": _2,
      "weibo": _2,
      "weir": _2,
      "whoswho": _2,
      "wien": _2,
      "wiki": _60,
      "williamhill": _2,
      "win": _2,
      "windows": _2,
      "wine": _2,
      "winners": _2,
      "wme": _2,
      "wolterskluwer": _2,
      "woodside": _2,
      "work": _2,
      "works": _2,
      "world": _2,
      "wow": _2,
      "wtc": _2,
      "wtf": _2,
      "xbox": _2,
      "xerox": _2,
      "xihuan": _2,
      "xin": _2,
      "xn--11b4c3d": _2,
      "कॉम": _2,
      "xn--1ck2e1b": _2,
      "セール": _2,
      "xn--1qqw23a": _2,
      "佛山": _2,
      "xn--30rr7y": _2,
      "慈善": _2,
      "xn--3bst00m": _2,
      "集团": _2,
      "xn--3ds443g": _2,
      "在线": _2,
      "xn--3pxu8k": _2,
      "点看": _2,
      "xn--42c2d9a": _2,
      "คอม": _2,
      "xn--45q11c": _2,
      "八卦": _2,
      "xn--4gbrim": _2,
      "موقع": _2,
      "xn--55qw42g": _2,
      "公益": _2,
      "xn--55qx5d": _2,
      "公司": _2,
      "xn--5su34j936bgsg": _2,
      "香格里拉": _2,
      "xn--5tzm5g": _2,
      "网站": _2,
      "xn--6frz82g": _2,
      "移动": _2,
      "xn--6qq986b3xl": _2,
      "我爱你": _2,
      "xn--80adxhks": _2,
      "москва": _2,
      "xn--80aqecdr1a": _2,
      "католик": _2,
      "xn--80asehdb": _2,
      "онлайн": _2,
      "xn--80aswg": _2,
      "сайт": _2,
      "xn--8y0a063a": _2,
      "联通": _2,
      "xn--9dbq2a": _2,
      "קום": _2,
      "xn--9et52u": _2,
      "时尚": _2,
      "xn--9krt00a": _2,
      "微博": _2,
      "xn--b4w605ferd": _2,
      "淡马锡": _2,
      "xn--bck1b9a5dre4c": _2,
      "ファッション": _2,
      "xn--c1avg": _2,
      "орг": _2,
      "xn--c2br7g": _2,
      "नेट": _2,
      "xn--cck2b3b": _2,
      "ストア": _2,
      "xn--cckwcxetd": _2,
      "アマゾン": _2,
      "xn--cg4bki": _2,
      "삼성": _2,
      "xn--czr694b": _2,
      "商标": _2,
      "xn--czrs0t": _2,
      "商店": _2,
      "xn--czru2d": _2,
      "商城": _2,
      "xn--d1acj3b": _2,
      "дети": _2,
      "xn--eckvdtc9d": _2,
      "ポイント": _2,
      "xn--efvy88h": _2,
      "新闻": _2,
      "xn--fct429k": _2,
      "家電": _2,
      "xn--fhbei": _2,
      "كوم": _2,
      "xn--fiq228c5hs": _2,
      "中文网": _2,
      "xn--fiq64b": _2,
      "中信": _2,
      "xn--fjq720a": _2,
      "娱乐": _2,
      "xn--flw351e": _2,
      "谷歌": _2,
      "xn--fzys8d69uvgm": _2,
      "電訊盈科": _2,
      "xn--g2xx48c": _2,
      "购物": _2,
      "xn--gckr3f0f": _2,
      "クラウド": _2,
      "xn--gk3at1e": _2,
      "通販": _2,
      "xn--hxt814e": _2,
      "网店": _2,
      "xn--i1b6b1a6a2e": _2,
      "संगठन": _2,
      "xn--imr513n": _2,
      "餐厅": _2,
      "xn--io0a7i": _2,
      "网络": _2,
      "xn--j1aef": _2,
      "ком": _2,
      "xn--jlq480n2rg": _2,
      "亚马逊": _2,
      "xn--jvr189m": _2,
      "食品": _2,
      "xn--kcrx77d1x4a": _2,
      "飞利浦": _2,
      "xn--kput3i": _2,
      "手机": _2,
      "xn--mgba3a3ejt": _2,
      "ارامكو": _2,
      "xn--mgba7c0bbn0a": _2,
      "العليان": _2,
      "xn--mgbab2bd": _2,
      "بازار": _2,
      "xn--mgbca7dzdo": _2,
      "ابوظبي": _2,
      "xn--mgbi4ecexp": _2,
      "كاثوليك": _2,
      "xn--mgbt3dhd": _2,
      "همراه": _2,
      "xn--mk1bu44c": _2,
      "닷컴": _2,
      "xn--mxtq1m": _2,
      "政府": _2,
      "xn--ngbc5azd": _2,
      "شبكة": _2,
      "xn--ngbe9e0a": _2,
      "بيتك": _2,
      "xn--ngbrx": _2,
      "عرب": _2,
      "xn--nqv7f": _2,
      "机构": _2,
      "xn--nqv7fs00ema": _2,
      "组织机构": _2,
      "xn--nyqy26a": _2,
      "健康": _2,
      "xn--otu796d": _2,
      "招聘": _2,
      "xn--p1acf": [1, {
        "xn--90amc": _3,
        "xn--j1aef": _3,
        "xn--j1ael8b": _3,
        "xn--h1ahn": _3,
        "xn--j1adp": _3,
        "xn--c1avg": _3,
        "xn--80aaa0cvac": _3,
        "xn--h1aliz": _3,
        "xn--90a1af": _3,
        "xn--41a": _3
      }],
      "рус": [1, {
        "биз": _3,
        "ком": _3,
        "крым": _3,
        "мир": _3,
        "мск": _3,
        "орг": _3,
        "самара": _3,
        "сочи": _3,
        "спб": _3,
        "я": _3
      }],
      "xn--pssy2u": _2,
      "大拿": _2,
      "xn--q9jyb4c": _2,
      "みんな": _2,
      "xn--qcka1pmc": _2,
      "グーグル": _2,
      "xn--rhqv96g": _2,
      "世界": _2,
      "xn--rovu88b": _2,
      "書籍": _2,
      "xn--ses554g": _2,
      "网址": _2,
      "xn--t60b56a": _2,
      "닷넷": _2,
      "xn--tckwe": _2,
      "コム": _2,
      "xn--tiq49xqyj": _2,
      "天主教": _2,
      "xn--unup4y": _2,
      "游戏": _2,
      "xn--vermgensberater-ctb": _2,
      "vermögensberater": _2,
      "xn--vermgensberatung-pwb": _2,
      "vermögensberatung": _2,
      "xn--vhquv": _2,
      "企业": _2,
      "xn--vuq861b": _2,
      "信息": _2,
      "xn--w4r85el8fhu5dnra": _2,
      "嘉里大酒店": _2,
      "xn--w4rs40l": _2,
      "嘉里": _2,
      "xn--xhq521b": _2,
      "广东": _2,
      "xn--zfr164b": _2,
      "政务": _2,
      "xyz": [1, {
        "botdash": _3,
        "telebit": _6
      }],
      "yachts": _2,
      "yahoo": _2,
      "yamaxun": _2,
      "yandex": _2,
      "yodobashi": _2,
      "yoga": _2,
      "yokohama": _2,
      "you": _2,
      "youtube": _2,
      "yun": _2,
      "zappos": _2,
      "zara": _2,
      "zero": _2,
      "zip": _2,
      "zone": [1, {
        "triton": _6,
        "stackit": _3,
        "lima": _3
      }],
      "zuerich": _2
    }];
    return rules2;
  })();
  function lookupInTrie(parts, trie, index, allowedMask) {
    let result = null;
    let node = trie;
    while (node !== void 0) {
      if ((node[0] & allowedMask) !== 0) {
        result = {
          index: index + 1,
          isIcann: node[0] === 1,
          isPrivate: node[0] === 2
        };
      }
      if (index === -1) {
        break;
      }
      const succ = node[1];
      node = Object.prototype.hasOwnProperty.call(succ, parts[index]) ? succ[parts[index]] : succ["*"];
      index -= 1;
    }
    return result;
  }
  function suffixLookup(hostname, options, out) {
    var _a;
    if (fast_path_default(hostname, options, out)) {
      return;
    }
    const hostnameParts = hostname.split(".");
    const allowedMask = (options.allowPrivateDomains ? 2 : 0) | (options.allowIcannDomains ? 1 : 0);
    const exceptionMatch = lookupInTrie(hostnameParts, exceptions2, hostnameParts.length - 1, allowedMask);
    if (exceptionMatch !== null) {
      out.isIcann = exceptionMatch.isIcann;
      out.isPrivate = exceptionMatch.isPrivate;
      out.publicSuffix = hostnameParts.slice(exceptionMatch.index + 1).join(".");
      return;
    }
    const rulesMatch = lookupInTrie(hostnameParts, rules, hostnameParts.length - 1, allowedMask);
    if (rulesMatch !== null) {
      out.isIcann = rulesMatch.isIcann;
      out.isPrivate = rulesMatch.isPrivate;
      out.publicSuffix = hostnameParts.slice(rulesMatch.index).join(".");
      return;
    }
    out.isIcann = false;
    out.isPrivate = false;
    out.publicSuffix = (_a = hostnameParts[hostnameParts.length - 1]) !== null && _a !== void 0 ? _a : null;
  }
  var RESULT = getEmptyResult();
  function parse(url, options = {}) {
    return parseImpl(url, 5, suffixLookup, options, getEmptyResult());
  }
  function getHostname(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 0, suffixLookup, options, RESULT).hostname;
  }
  function getPublicSuffix(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 2, suffixLookup, options, RESULT).publicSuffix;
  }
  function getDomain2(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 3, suffixLookup, options, RESULT).domain;
  }
  function getSubdomain2(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 4, suffixLookup, options, RESULT).subdomain;
  }
  function getDomainWithoutSuffix2(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 5, suffixLookup, options, RESULT).domainWithoutSuffix;
  }
  var import_moment = __toESM(require_moment(), 1);
  var Database = class _Database extends Dexie$1 {
    constructor() {
      super("IwaraDownloadTool");
      this.version(2).stores({
        follows: "id, username, name, friend, following, followedBy",
        friends: "id, username, name, friend, following, followedBy",
        videos: "ID, Type, UploadTime, Private, Unlisted",
        caches: "ID"
      });
      this.follows = this.table("follows");
      this.friends = this.table("friends");
      this.videos = this.table("videos");
      this.caches = this.table("caches");
    }
    async getFilteredVideos(startTime, endTime) {
      if (isNullOrUndefined(startTime) || isNullOrUndefined(endTime)) return [];
      return this.videos.where("UploadTime").between(startTime, endTime, true, true).and((video) => (video.Type === "partial" || video.Type === "full") && (video.Private || video.Unlisted)).and((video) => !isNullOrUndefined(video.RAW)).toArray();
    }
    static getInstance() {
      if (isNullOrUndefined(_Database.instance)) _Database.instance = new _Database();
      return _Database.instance;
    }
    static destroyInstance() {
      _Database.instance = void 0;
    }
  };
  var db = Database.getInstance();
  Date.prototype.format = function(format) {
    return (0, import_moment.default)(this).format(format);
  };
  var unlimitedFetch = async (input, init = {}, options) => {
    const {
      force = false,
      retry = false,
      maxRetries = 3,
      retryDelay = 3e3,
      successStatus = [200, 201],
      failStatuses = [403, 404],
      onFail,
      onRetry
    } = options || {};
    const successStatuses = Array.isArray(successStatus) ? successStatus : [successStatus];
    const failStatusList = Array.isArray(failStatuses) ? failStatuses : [failStatuses];
    const url = typeof input === "string" ? input : input.url;
    const isCrossOrigin = force || new URL(url).hostname !== unsafeWindow.location.hostname;
    const doFetch = async () => {
      if (isCrossOrigin) {
        return new Promise((resolve, reject) => {
          GM_xmlhttpRequest({
            method: init.method,
            url,
            headers: init.headers || {},
            data: init.body || void 0,
            onload: (response) => {
              resolve(new Response(response.responseText, {
                status: response.status,
                statusText: response.statusText
              }));
            },
            onerror: reject
          });
        });
      } else {
        return originalFetch(input, init);
      }
    };
    if (!retry) return doFetch();
    let lastResponse = await doFetch();
    let attempts = 1;
    while (attempts < maxRetries) {
      if (successStatuses.includes(lastResponse.status)) return lastResponse;
      if (failStatusList.includes(lastResponse.status)) break;
      attempts++;
      if (onRetry) await onRetry(lastResponse);
      await delay(retryDelay);
      lastResponse = await doFetch();
    }
    if (onFail) await onFail(lastResponse);
    return lastResponse;
  };
  var findElement = (element, condition) => {
    while (!isNullOrUndefined(element) && !element.matches(condition)) {
      if (isNullOrUndefined(element.parentElement)) return void 0;
      element = element.parentElement;
    }
    return element.querySelectorAll(condition).length > 1 ? void 0 : element;
  };
  var renderNode = (renderCode) => {
    let code = prune(renderCode);
    if (isNullOrUndefined(code)) throw new Error("RenderCode null");
    if (typeof code === "string") {
      return document.createTextNode(code.replaceVariable(i18nList[config.language]));
    }
    if (code instanceof Node) {
      return code;
    }
    if (typeof renderCode !== "object" || !renderCode.nodeType) {
      throw new Error("Invalid arguments");
    }
    const {
      nodeType,
      attributes,
      events,
      className,
      childs
    } = renderCode;
    const node = document.createElement(nodeType);
    if (!isNullOrUndefined(events) && Object.keys(events).length > 0) {
      Object.entries(events).forEach(([eventName, eventHandler]) => originalAddEventListener.call(node, eventName, eventHandler));
    }
    if (!isNullOrUndefined(className) && className.length > 0) {
      node.classList.add(...typeof className === "string" ? [className] : className);
    }
    if (!isNullOrUndefined(childs)) {
      node.append(...(isArray(childs) ? childs : [childs]).filter((child) => !isNullOrUndefined(child)).map(renderNode));
    }
    if (!isNullOrUndefined(attributes) && Object.keys(attributes).length > 0) {
      Object.entries(attributes).forEach(([key, value]) => {
        node[key] = value;
        node.setAttribute(key, value);
      });
    }
    return node;
  };
  var activeToasts = new Dictionary();
  var toastTimeouts =  new Map();
  var toastIntervals =  new Map();
  var toastContainers =  new Map();
  var offscreenContainer = document.createElement("div");
  offscreenContainer.classList.add("offscreen-container");
  var getContainer = (gravity, position) => {
    const containerId = `toast-container-${gravity}-${position}`;
    if (!toastContainers.has(containerId)) {
      const container = document.createElement("div");
      container.id = containerId;
      container.classList.add("toast-container", `toast-${gravity}`, `toast-${position}`);
      document.body.appendChild(container);
      toastContainers.set(containerId, container);
    }
    return toastContainers.get(containerId);
  };
  var addTimeout = (toast, callback) => {
    if (isNullOrUndefined(toast.options.duration)) return;
    delTimeout(toast);
    const duration = toast.options.duration;
    const timeoutId = window.setTimeout(() => {
      callback();
      delTimeout(toast);
    }, duration);
    toastTimeouts.set(toast, timeoutId);
    if (!toast.showProgress) return;
    if (isNullOrUndefined(toast.progress)) return;
    const startTime = Date.now();
    const updateRemainingTime = () => {
      if (isNullOrUndefined(toast.progress)) return;
      const elapsed = Date.now() - startTime;
      const remaining = Math.max(0, duration - elapsed);
      toast.progress.style.setProperty("--toast-progress", `${remaining / duration}`);
    };
    toast.progress.style.setProperty("--toast-progress", `1`);
    const intervalId = window.setInterval(updateRemainingTime, 20);
    toastIntervals.set(toast, intervalId);
  };
  var delTimeout = (toast) => {
    const timeoutId = toastTimeouts.get(toast);
    if (!isNullOrUndefined(timeoutId)) {
      clearTimeout(timeoutId);
      toastTimeouts.delete(toast);
    }
    if (!toast.showProgress) return;
    const intervalId = toastIntervals.get(toast);
    if (!isNullOrUndefined(intervalId)) {
      clearInterval(intervalId);
      toastIntervals.delete(toast);
    }
    if (!isNullOrUndefined(toast.progress)) {
      toast.progress.style.removeProperty("--toast-progress");
    }
  };
  var Toast = class _Toast {
    static defaults = {
      id: UUID(),
      gravity: "top",
      position: "left",
      stopOnFocus: true,
      oldestFirst: true,
      showProgress: false
    };
    constructor(options) {
      this.options = {
        ..._Toast.defaults,
        ...options
      };
      this.id = this.options.id;
      this.root = getContainer(this.options.gravity, this.options.position);
      this.gravity = this.options.gravity;
      this.position = this.options.position;
      this.stopOnFocus = this.options.stopOnFocus;
      this.oldestFirst = this.options.oldestFirst;
      this.showProgress = this.options.showProgress;
      this.element = document.createElement("div");
      this.applyBaseStyles().addCloseButton().createContent().ensureCloseMethod().bindEvents();
      activeToasts.set(this.id, this);
    }
    applyBaseStyles() {
      this.element.classList.add("toast");
      if (this.options.className) {
        const classes = Array.isArray(this.options.className) ? this.options.className : [this.options.className];
        classes.forEach((cls) => this.element.classList.add(cls));
      }
      return this;
    }
    createContent() {
      this.content = document.createElement("div");
      this.content.classList.add("toast-content");
      if (this.options.text) {
        this.content.textContent = this.options.text;
      }
      if (this.options.node) {
        this.content.appendChild(this.options.node);
      }
      if (this.options.style) {
        this.applyStyles(this.content, this.options.style);
      }
      if (this.options.showProgress) {
        this.progress = document.createElement("div");
        this.progress.classList.add("toast-progress");
        this.content.appendChild(this.progress);
      }
      this.element.appendChild(this.content);
      return this;
    }
    addCloseButton() {
      if (this.options.close) {
        this.closeButton = document.createElement("span");
        this.closeButton.className = "toast-close";
        this.closeButton.textContent = "🗙";
        this.closeButtonHandler = () => this.hide("close-button");
        this.closeButton.addEventListener("click", this.closeButtonHandler);
        this.element.appendChild(this.closeButton);
      }
      return this;
    }
    setToastRect() {
      if (!this.element.classList.contains("show")) offscreenContainer.appendChild(this.element);
      this.element.style.removeProperty("--toast-height");
      this.element.style.removeProperty("--toast-width");
      this.element.style.setProperty("max-height", "none", "important");
      this.element.style.setProperty("max-width", `${this.root.getBoundingClientRect().width}px`, "important");
      const {
        height,
        width
      } = this.element.getBoundingClientRect();
      this.element.style.setProperty("--toast-height", `${height}px`);
      this.element.style.setProperty("--toast-width", `${width}px`);
      this.element.style.removeProperty("max-height");
      this.element.style.removeProperty("max-width");
      if (!this.element.classList.contains("show")) offscreenContainer.removeChild(this.element);
      return this;
    }
    ensureCloseMethod() {
      if (isNullOrUndefined(this.options.duration) && isNullOrUndefined(this.options.close) && isNullOrUndefined(this.options.onClick)) {
        this.options.onClick = () => this.hide("other");
      }
      return this;
    }
    bindEvents() {
      if (this.stopOnFocus && !isNullOrUndefined(this.options.duration) && this.options.duration > 0) {
        this.mouseOverHandler = () => delTimeout(this);
        this.mouseLeaveHandler = () => addTimeout(this, () => this.hide("timeout"));
        this.element.addEventListener("mouseover", this.mouseOverHandler);
        this.element.addEventListener("mouseleave", this.mouseLeaveHandler);
      }
      if (!isNullOrUndefined(this.options.onClick)) {
        this.clickHandler = this.options.onClick.bind(this);
        this.element.addEventListener("click", this.clickHandler);
      }
      return this;
    }
    applyStyles(element, styles) {
      function camelToKebab(str) {
        return str.replace(/([A-Z])/g, "-$1").toLowerCase();
      }
      for (const key in styles) {
        const value = styles[key];
        const property = camelToKebab(key);
        if (isNullOrUndefined(value)) {
          element.style.removeProperty(property);
          continue;
        }
        const important = value.includes("!important");
        const cleanValue = value.replace(/\s*!important\s*/, "").trim();
        element.style.setProperty(property, cleanValue, important ? "important" : "");
      }
    }
    toggleAnimationState(animation) {
      if (!this.element.classList.replace(animation ? "hide" : "show", animation ? "show" : "hide")) {
        this.element.classList.add(animation ? "show" : "hide");
      }
      return this;
    }
    insertToastElement() {
      if (this.oldestFirst) {
        this.root.insertBefore(this.element, this.root.firstChild);
      } else {
        if (this.root.lastChild) {
          this.root.insertBefore(this.element, this.root.lastChild.nextSibling);
        } else {
          this.root.appendChild(this.element);
        }
      }
      return this;
    }
    setupAutoHide() {
      if (!isNullOrUndefined(this.options.duration) && this.options.duration > 0) {
        addTimeout(this, () => this.hide("timeout"));
      }
      return this;
    }
    show() {
      this.setToastRect().insertToastElement().toggleAnimationState(true).setupAutoHide();
      return this;
    }
    showToast() {
      return this.show();
    }
    removeEventListeners() {
      if (this.mouseOverHandler) {
        this.element.removeEventListener("mouseover", this.mouseOverHandler);
      }
      if (this.mouseLeaveHandler) {
        this.element.removeEventListener("mouseleave", this.mouseLeaveHandler);
      }
      if (this.clickHandler) {
        this.element.removeEventListener("click", this.clickHandler);
      }
      if (this.options.close && this.closeButton && this.closeButtonHandler) {
        this.closeButton.removeEventListener("click", this.closeButtonHandler);
      }
      return this;
    }
    hide(reason = "other") {
      if (!this.element) return;
      delTimeout(this);
      activeToasts.delete(this.id);
      this.animationEndHandler = (e) => {
        if (e.animationName.startsWith("toast-out")) {
          this.element.removeEventListener("animationend", this.animationEndHandler);
          this.element.remove();
          this.options.onClose?.call(this, new CustomEvent("toast-close", {
            detail: {
              reason
            }
          }));
        }
      };
      this.element.addEventListener("animationend", this.animationEndHandler);
      this.removeEventListeners().toggleAnimationState(false);
    }
    hideToast() {
      this.hide("other");
    }
  };
  function createToast(options) {
    return new Toast(options);
  }
  globalThis.Toast = createToast;
  globalThis.Toastify = createToast;
  (document.body ?? document.documentElement).appendChild(offscreenContainer);
  window.addEventListener("resize", debounce(() => {
    for (const [_, toast] of activeToasts) {
      toast.setToastRect();
    }
  }, 100));
  async function refreshToken() {
    const {
      authorization
    } = config;
    if (!isLoggedIn()) throw new Error(`Refresh token failed: Not logged in`);
    const refreshToken2 = localStorage.getItem("token") ?? authorization;
    if (isNullOrUndefined(refreshToken2) || refreshToken2.isEmpty()) {
      throw new Error(`Refresh token failed: no refresh token`);
    }
    const oldAccessToken = localStorage.getItem("accessToken");
    try {
      const res = await unlimitedFetch("https://api.iwara.tv/user/token", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${refreshToken2}`
        }
      });
      if (!res.ok) {
        throw new Error(`Refresh token failed with status: ${res.status}`);
      }
      const {
        accessToken
      } = await res.json();
      if (!accessToken) {
        throw new Error(`No access token in response`);
      }
      if (!oldAccessToken || oldAccessToken !== accessToken) {
        localStorage.setItem("accessToken", accessToken);
      }
      return accessToken;
    } catch (error) {
      originalConsole.warn("Failed to refresh token:", error);
      if (!oldAccessToken?.trim()) {
        throw new Error(`Refresh token failed and no valid access token available`);
      }
      return oldAccessToken;
    }
  }
  async function getAuth(url) {
    return prune({
      "Accept": "application/json",
      "Cooike": unsafeWindow.document.cookie,
      "Authorization": isLoggedIn() ? `Bearer ${localStorage.getItem("accessToken") ?? await refreshToken()}` : void 0,
      "X-Version": !isNullOrUndefined(url) && !url.isEmpty() ? await getXVersion(url) : void 0
    });
  }
  function checkIsHaveDownloadLink(comment) {
    if (!config.checkDownloadLink || isNullOrUndefined(comment) || comment.isEmpty()) {
      return false;
    }
    return ["iwara.zip", "pan.baidu", "/s/", "mega.nz", "drive.google.com", "aliyundrive", "uploadgig", "katfile", "storex", "subyshare", "rapidgator", "filebe", "filespace", "mexa.sh", "mexashare", "mx-sh.net", "icerbox", "alfafile", "1drv.ms", "onedrive.", "gofile.io", "workupload.com", "pixeldrain.", "dailyuploads.net", "katfile.com", "fikper.com", "frdl.io", "rg.to", "gigafile.nu"].filter((i) => comment.toLowerCase().includes(i)).any();
  }
  function toastNode(body, title) {
    return renderNode({
      nodeType: "div",
      childs: [!isNullOrUndefined(title) && !title.isEmpty() ? {
        nodeType: "h3",
        childs: `%#appName#% - ${title}`
      } : {
        nodeType: "h3",
        childs: "%#appName#%"
      }, {
        nodeType: "p",
        childs: body
      }]
    });
  }
  function getTextNode(node) {
    return node.nodeType === Node.TEXT_NODE ? node.textContent || "" : node.nodeType === Node.ELEMENT_NODE ? Array.from(node.childNodes).map(getTextNode).join("") : "";
  }
  function newToast(type2, params) {
    const logFunc = {
      [ToastType.Warn]: originalConsole.warn,
      [ToastType.Error]: originalConsole.error,
      [ToastType.Log]: originalConsole.log,
      [ToastType.Info]: originalConsole.info
    }[type2] || originalConsole.log;
    if (isNullOrUndefined(params)) params = {};
    if (!isNullOrUndefined(params.id) && activeToasts.has(params.id)) activeToasts.get(params.id)?.hide();
    switch (type2) {
      case ToastType.Info:
        params = Object.assign({
          duration: 2e3,
          style: {
            background: "linear-gradient(-30deg, rgb(0, 108, 215), rgb(0, 180, 255))"
          }
        }, params);
      case ToastType.Warn:
        params = Object.assign({
          duration: -1,
          style: {
            background: "linear-gradient(-30deg, rgb(119, 76, 0), rgb(255, 165, 0))"
          }
        }, params);
        break;
      case ToastType.Error:
        params = Object.assign({
          duration: -1,
          style: {
            background: "linear-gradient(-30deg, rgb(108, 0, 0), rgb(215, 0, 0))"
          }
        }, params);
      default:
        break;
    }
    if (!isNullOrUndefined(params.text)) {
      params.text = params.text.replaceVariable(i18nList[config.language]).toString();
    }
    logFunc((!isNullOrUndefined(params.text) ? params.text : !isNullOrUndefined(params.node) ? getTextNode(params.node) : "undefined").replaceVariable(i18nList[config.language]));
    return new Toast(params);
  }
  function getDownloadPath(videoInfo) {
    return analyzeLocalPath(config.downloadPath.trim().replaceVariable({
      NowTime:  new Date(),
      UploadTime: new Date(videoInfo.UploadTime),
      AUTHOR: videoInfo.Author,
      ID: videoInfo.ID,
      TITLE: videoInfo.Title.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(72),
      ALIAS: videoInfo.Alias.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(64),
      QUALITY: videoInfo.DownloadQuality
    }));
  }
  function analyzeLocalPath(path) {
    try {
      return new Path(path);
    } catch (error) {
      let toast = newToast(ToastType.Error, {
        node: toastNode([`%#downloadPathError#%`, {
          nodeType: "br"
        }, stringify(error)], "%#settingsCheck#%"),
        position: "center",
        onClick() {
          toast.hide();
        }
      });
      toast.show();
      throw new Error(`%#downloadPathError#% ["${path}"]`);
    }
  }
  async function EnvCheck() {
    try {
      if (GM_info.scriptHandler !== "ScriptCat" && GM_info.downloadMode !== "browser") {
        GM_getValue("isDebug") && originalConsole.debug("[Debug]", GM_info);
        throw new Error("%#browserDownloadModeError#%");
      }
    } catch (error) {
      let toast = newToast(ToastType.Error, {
        node: toastNode([`%#configError#%`, {
          nodeType: "br"
        }, stringify(error)], "%#settingsCheck#%"),
        position: "center",
        onClick() {
          toast.hide();
        }
      });
      toast.show();
      return false;
    }
    return true;
  }
  async function localPathCheck() {
    try {
      let pathTest = analyzeLocalPath(config.downloadPath.replaceVariable({
        NowTime:  new Date(),
        UploadTime:  new Date(),
        AUTHOR: "test",
        ID: "test",
        TITLE: "test",
        ALIAS: "test",
        QUALITY: "test"
      }));
      if (isNullOrUndefined(pathTest)) throw "analyzeLocalPath error";
      if (pathTest.fullPath.isEmpty()) throw "analyzeLocalPath isEmpty";
    } catch (error) {
      let toast = newToast(ToastType.Error, {
        node: toastNode([`%#downloadPathError#%`, {
          nodeType: "br"
        }, stringify(error)], "%#settingsCheck#%"),
        position: "center",
        onClick() {
          toast.hide();
        }
      });
      toast.show();
      return false;
    }
    return true;
  }
  async function aria2Check() {
    try {
      let res = await (await unlimitedFetch(config.aria2Path, {
        method: "POST",
        headers: {
          "accept": "application/json",
          "content-type": "application/json"
        },
        body: JSON.stringify({
          "jsonrpc": "2.0",
          "method": "aria2.tellActive",
          "id": UUID(),
          "params": ["token:" + config.aria2Token]
        })
      })).json();
      if (res.error) {
        throw new Error(res.error.message);
      }
    } catch (error) {
      let toast = newToast(ToastType.Error, {
        node: toastNode([`Aria2 RPC %#connectionTest#%`, {
          nodeType: "br"
        }, stringify(error)], "%#settingsCheck#%"),
        position: "center",
        onClick() {
          toast.hide();
        }
      });
      toast.show();
      return false;
    }
    return true;
  }
  async function iwaraDownloaderCheck() {
    try {
      let res = await (await unlimitedFetch(config.iwaraDownloaderPath, {
        method: "POST",
        headers: {
          "accept": "application/json",
          "content-type": "application/json"
        },
        body: JSON.stringify(prune({
          "ver": GM_getValue("version", "0.0.0").split(".").map((i) => Number(i)),
          "code": "State",
          "token": config.iwaraDownloaderToken
        }))
      })).json();
      if (res.code !== 0) {
        throw new Error(res.msg);
      }
    } catch (error) {
      let toast = newToast(ToastType.Error, {
        node: toastNode([`IwaraDownloader RPC %#connectionTest#%`, {
          nodeType: "br"
        }, stringify(error)], "%#settingsCheck#%"),
        position: "center",
        onClick() {
          toast.hide();
        }
      });
      toast.show();
      return false;
    }
    return true;
  }
  function aria2Download(videoInfo) {
    (async function(id, author, title, uploadTime, info, tag, quality, alias, downloadUrl) {
      let localPath = analyzeLocalPath(config.downloadPath.replaceVariable({
        NowTime:  new Date(),
        UploadTime: new Date(uploadTime),
        AUTHOR: author,
        ID: id,
        TITLE: title.normalize("NFKC").replaceAll(new RegExp("(\\P{Mark})(\\p{Mark}+)", "gu"), "_").replaceEmojis("_").replace(/^\.|[\\\\/:*?\"<>|]/img, "_").truncate(72),
        ALIAS: alias,
        QUALITY: quality
      }).trim());
      downloadUrl.searchParams.set("videoid", id);
      downloadUrl.searchParams.set("download", localPath.fullName);
      let params = [[downloadUrl.href], prune({
        "all-proxy": config.downloadProxy,
        "all-proxy-passwd": !config.downloadProxy.isEmpty() ? config.downloadProxyPassword : void 0,
        "all-proxy-user": !config.downloadProxy.isEmpty() ? config.downloadProxyUsername : void 0,
        "out": localPath.fullName,
        "dir": localPath.directory,
        "referer": window.location.hostname,
        "header": ["Cookie:" + unsafeWindow.document.cookie]
      })];
      let res = await aria2API("aria2.addUri", params);
      originalConsole.log(`Aria2 ${title} ${JSON.stringify(res)}`);
      newToast(ToastType.Info, {
        gravity: "bottom",
        node: toastNode(`${videoInfo.Title}[${videoInfo.ID}] %#pushTaskSucceed#%`)
      }).show();
    })(videoInfo.ID, videoInfo.Author, videoInfo.Title, videoInfo.UploadTime, videoInfo.Comments, videoInfo.Tags, videoInfo.DownloadQuality, videoInfo.Alias, videoInfo.DownloadUrl.toURL());
  }
  function iwaraDownloaderDownload(videoInfo) {
    (async function(videoInfo2) {
      let r = await (await unlimitedFetch(config.iwaraDownloaderPath, {
        method: "POST",
        headers: {
          "accept": "application/json",
          "content-type": "application/json"
        },
        body: JSON.stringify(prune({
          "ver": GM_getValue("version", "0.0.0").split(".").map((i) => Number(i)),
          "code": "add",
          "token": config.iwaraDownloaderToken,
          "data": {
            "info": {
              "title": videoInfo2.Title,
              "url": videoInfo2.DownloadUrl,
              "size": videoInfo2.Size,
              "source": videoInfo2.ID,
              "alias": videoInfo2.Alias,
              "author": videoInfo2.Author,
              "uploadTime": videoInfo2.UploadTime,
              "comments": videoInfo2.Comments,
              "tags": videoInfo2.Tags,
              "path": config.downloadPath.replaceVariable({
                NowTime:  new Date(),
                UploadTime: videoInfo2.UploadTime,
                AUTHOR: videoInfo2.Author,
                ID: videoInfo2.ID,
                TITLE: videoInfo2.Title,
                ALIAS: videoInfo2.Alias,
                QUALITY: videoInfo2.DownloadQuality
              })
            },
            "option": {
              "proxy": config.downloadProxy,
              "cookies": unsafeWindow.document.cookie
            }
          }
        }))
      })).json();
      if (r.code === 0) {
        originalConsole.log(`${videoInfo2.Title} %#pushTaskSucceed#% ${r}`);
        newToast(ToastType.Info, {
          node: toastNode(`${videoInfo2.Title}[${videoInfo2.ID}] %#pushTaskSucceed#%`)
        }).show();
      } else {
        let toast = newToast(ToastType.Error, {
          node: toastNode([`${videoInfo2.Title}[${videoInfo2.ID}] %#pushTaskFailed#% `, {
            nodeType: "br"
          }, r.msg], "%#iwaraDownloaderDownload#%"),
          onClick() {
            toast.hide();
          }
        });
        toast.show();
      }
    })(videoInfo);
  }
  function othersDownload(videoInfo) {
    (async function(DownloadUrl) {
      DownloadUrl.searchParams.set("download", getDownloadPath(videoInfo).fullName);
      GM_openInTab(DownloadUrl.href, {
        active: false,
        insert: true,
        setParent: true
      });
    })(videoInfo.DownloadUrl.toURL());
  }
  function browserDownloadErrorParse(error) {
    let errorInfo = stringify(error);
    if (!(error instanceof Error)) {
      errorInfo = {
        "not_enabled": `%#browserDownloadNotEnabled#%`,
        "not_whitelisted": `%#browserDownloadNotWhitelisted#%`,
        "not_permitted": `%#browserDownloadNotPermitted#%`,
        "not_supported": `%#browserDownloadNotSupported#%`,
        "not_succeeded": `%#browserDownloadNotSucceeded#% ${isNullOrUndefined(error.details) ? "UnknownError" : error.details}`
      }[error.error] || `%#browserDownloadUnknownError#%`;
    }
    return errorInfo;
  }
  function browserDownload(videoInfo) {
    (async function(ID, Author, Title, UploadTime, Info, Tag, DownloadQuality, Alias, DownloadUrl) {
      function toastError(error) {
        let toast = newToast(ToastType.Error, {
          node: toastNode([`${Title}[${ID}] %#downloadFailed#%`, {
            nodeType: "br"
          }, browserDownloadErrorParse(error), {
            nodeType: "br"
          }, `%#tryRestartingDownload#%`], "%#browserDownload#%"),
          async onClick() {
            toast.hide();
            await pushDownloadTask(videoInfo);
          }
        });
        toast.show();
      }
      GM_download({
        url: DownloadUrl,
        saveAs: false,
        name: getDownloadPath(videoInfo).fullPath,
        onerror: (err) => toastError(err),
        ontimeout: () => toastError(new Error("%#browserDownloadTimeout#%"))
      });
    })(videoInfo.ID, videoInfo.Author, videoInfo.Title, videoInfo.UploadTime, videoInfo.Comments, videoInfo.Tags, videoInfo.DownloadQuality, videoInfo.Alias, videoInfo.DownloadUrl);
  }
  async function aria2API(method, params) {
    return await (await unlimitedFetch(config.aria2Path, {
      headers: {
        "accept": "application/json",
        "content-type": "application/json"
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        method,
        id: UUID(),
        params: [`token:${config.aria2Token}`, ...params]
      }),
      method: "POST"
    })).json();
  }
  function aria2TaskExtractVideoID(task2) {
    try {
      if (isNullOrUndefined(task2.files) || task2.files.length !== 1) return;
      const file = task2.files[0];
      if (isNullOrUndefined(file)) return;
      if (file.uris.length < 1) return;
      let downloadUrl = file.uris[0].uri.toURL();
      if (isNullOrUndefined(downloadUrl)) return;
      let videoID;
      if (downloadUrl.searchParams.has("videoid")) videoID = downloadUrl.searchParams.get("videoid");
      if (!isNullOrUndefined(videoID) && !videoID.isEmpty()) return videoID;
      if (isNullOrUndefined(file.path) || file.path.isEmpty()) return;
      let path = analyzeLocalPath(file.path);
      if (isNullOrUndefined(path.fullName) || path.fullName.isEmpty()) return;
      videoID = path.fullName.toLowerCase().among("[", "].mp4", false, true);
      if (videoID.isEmpty()) return;
      return videoID;
    } catch (error) {
      GM_getValue("isDebug") && originalConsole.debug(`[Debug] check aria2 task file fail! ${stringify(task2)}`);
      return;
    }
  }
  async function aria2TaskCheckAndRestart() {
    let stoped = prune((await aria2API("aria2.tellStopped", [0, 4096, ["gid", "status", "files", "errorCode", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => {
      let ID = aria2TaskExtractVideoID(task2);
      if (!isNullOrUndefined(ID) && !ID.isEmpty()) {
        return {
          id: ID,
          data: task2
        };
      }
    }));
    let active = prune((await aria2API("aria2.tellActive", [["gid", "status", "files", "downloadSpeed", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => {
      let ID = aria2TaskExtractVideoID(task2);
      if (!isNullOrUndefined(ID) && !ID.isEmpty()) {
        return {
          id: ID,
          data: task2
        };
      }
    }));
    let downloadNormalTasks = active.filter((task2) => isConvertibleToNumber(task2.data.downloadSpeed) && Number(task2.data.downloadSpeed) >= 512).unique("id");
    let downloadCompleted = stoped.filter((task2) => task2.data.status === "complete").unique("id");
    let downloadUncompleted = stoped.difference(downloadCompleted, "id").difference(downloadNormalTasks, "id");
    let downloadToSlowTasks = active.filter((task2) => isConvertibleToNumber(task2.data.downloadSpeed) && Number(task2.data.downloadSpeed) <= 512).unique("id");
    let needRestart = downloadUncompleted.union(downloadToSlowTasks, "id");
    if (needRestart.length !== 0) {
      newToast(ToastType.Warn, {
        id: "aria2TaskCheckAndRestart",
        node: toastNode([`发现 ${needRestart.length} 个需要重启的下载任务!`, {
          nodeType: "br"
        }, "%#tryRestartingDownload#%"], "%#aria2TaskCheck#%"),
        async onClick() {
          this.hide();
          for (let i = 0; i < needRestart.length; i++) {
            const task2 = needRestart[i];
            await pushDownloadTask(await parseVideoInfo({
              Type: "init",
              ID: task2.id
            }), true);
            let activeTasks = active.filter((activeTask) => activeTask.id === task2.id);
            for (let t = 0; t < activeTasks.length; t++) {
              const element = activeTasks[t];
              await aria2API("aria2.forceRemove", [element.data.gid]);
            }
          }
        }
      }).show();
    } else {
      newToast(ToastType.Info, {
        id: "aria2TaskCheckAndRestart",
        duration: 1e4,
        node: toastNode(`未发现需要重启的下载任务!`)
      }).show();
    }
  }
  function getPlayload(authorization) {
    return JSON.parse(decodeURIComponent(encodeURIComponent(window.atob(authorization.split(" ").pop().split(".")[1]))));
  }
  async function check() {
    if (await localPathCheck()) {
      switch (config.downloadType) {
        case DownloadType.Aria2:
          return await aria2Check();
        case DownloadType.IwaraDownloader:
          return await iwaraDownloaderCheck();
        case DownloadType.Browser:
          return await EnvCheck();
        default:
          break;
      }
      return true;
    } else {
      return false;
    }
  }
  async function getXVersion(urlString) {
    let url = urlString.toURL();
    const data = new TextEncoder().encode([url.pathname.split("/").pop(), url.searchParams.get("expires"), "5nFp9kmbNnHdAFhaqMvt"].join("_"));
    const hashBuffer = await crypto.subtle.digest("SHA-1", data);
    return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
  }
  var main_default = '@keyframes rainbow-horizontal{0%{background-position:0% 0%}to{background-position:200% 0%}}@keyframes rainbow-vertical{0%{background-position:0% 0%}to{background-position:0% 200%}}.rainbow-text{background-image:linear-gradient(to right,#ff4040,#ffff40,#40ff40,#40ffff,#4040ff,#ff40ff,#ff4040);background-size:200% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:rainbow-horizontal .8s infinite linear;font-weight:700}#pluginMenu{z-index:2147483644;position:fixed;top:50%;right:0;padding:10px 26px;background-color:var(--body-dark);border:1px solid var(--text);border-radius:5px;box-shadow:0 0 10px var(--text);transform:translate(calc(100% - 26px)) translateY(-50%);transition:transform .3s ease-in-out}#pluginMenu:not(.expanded){overflow:visible}#pluginMenu:not(.expanded):before{content:"";mask:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIj48cGF0aCBkPSJNNTYwLTI0MCAzMjAtNDgwbDI0MC0yNDAgNTYgNTYtMTg0IDE4NCAxODQgMTg0LTU2IDU2WiIvPjwvc3ZnPg==) no-repeat center;background-color:var(--text);width:24px;height:24px;position:absolute;left:0;top:50%;line-height:0;transform:translateY(-50%)}#pluginMenu.expanded{transform:translate(0) translateY(-50%)}#pluginMenu ul{list-style:none;margin:0;padding:0}#pluginMenu li{padding:5px 10px;cursor:pointer;text-align:center;user-select:none;color:var(--text)}#pluginMenu li:hover{background-color:var(--primary-dark);border-radius:3px}#pluginConfig{color:var(--text);position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000000bf;z-index:2147483646;display:flex;flex-direction:column;align-items:center;justify-content:center}#pluginConfig .main{background-color:var(--body);padding:24px;margin:10px;overflow-y:auto;width:480px}#pluginConfig .buttonList{display:flex;flex-direction:row;justify-content:center}@media (max-width: 640px){#pluginConfig .main{width:100%}}#pluginConfig button{background-color:var(--primary);margin:0 20px;padding:10px 20px;color:var(--primary-text);font-size:18px;border:none;border-radius:4px;cursor:pointer}#pluginConfig button{background-color:var(--primary)}#pluginConfig button[disabled]{background-color:var(--muted);cursor:not-allowed}#pluginConfig p{display:flex;flex-direction:column;margin-top:10px;margin-bottom:0}#pluginConfig fieldset{border:none;margin:10px 0 0;padding:0;display:flex;justify-content:space-between;flex-wrap:nowrap}#pluginConfig fieldset>legend{margin:0 0 5px;padding:0}#pluginConfig fieldset>label{text-align:center}#pluginConfig p label{display:flex;flex-direction:column;margin:5px 0 0}#pluginConfig .inputRadioLine{display:flex;align-items:center;flex-direction:row;justify-content:space-between}#pluginConfig input[type=text],#pluginConfig input[type=password]{outline:none;border-top:none;border-right:none;border-left:none;border-image:initial;border-bottom:1px solid var(--muted);line-height:1;height:30px;box-sizing:border-box;width:100%;background-color:var(--body);color:var(--text)}#pluginConfig input[type=checkbox].switch{outline:none;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;width:40px;height:20px;background:var(--muted);border-radius:10px;transition:border-color .2s,background-color .2s}#pluginConfig input[type=checkbox].switch:after{content:"";display:inline-block;width:40%;height:80%;border-radius:50%;background:var(--white);box-shadow:0,0,2px,var(--muted);transition:.2s;top:2px;position:absolute;right:55%}#pluginConfig input[type=checkbox].switch:checked{background:var(--success)}#pluginConfig input[type=checkbox].switch:checked:after{content:"";position:absolute;right:2px;top:2px}#pluginOverlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000000bf;z-index:2147483645;display:flex;flex-direction:column;align-items:center;justify-content:center}#pluginOverlay .main{color:var(--text);font-size:24px;width:60%;background-color:#404040bf;padding:24px;margin:10px;overflow-y:auto}@media (max-width: 640px){#pluginOverlay .main{width:100%}}#pluginOverlay button{padding:10px 20px;color:var(--primary-text);font-size:18px;border:none;border-radius:4px;cursor:pointer}#pluginOverlay button{background-color:var(--primary)}#pluginOverlay button[disabled]{background-color:var(--muted);cursor:not-allowed}#pluginOverlay .checkbox{width:32px;height:32px;margin:0 4px 0 0;padding:0}#pluginOverlay .checkbox-container{display:flex;align-items:center;margin:0 0 10px}#pluginOverlay .checkbox-label{color:var(--text);font-size:32px;font-weight:700;margin-left:10px;display:flex;align-items:center}.fixed-bottom-right{position:fixed;bottom:0;right:0;background-color:var(--body);color:var(--text);border-top:1px solid var(--primary);border-left:1px solid var(--primary);border-top-left-radius:6px;padding:2px 5px;margin:0;user-select:none;z-index:102}.follow{bottom:24px;right:2px;border-radius:2px;position:absolute;padding:3px 5px;background-color:#000c;pointer-events:none}.selectButton{accent-color:var(--primary);position:absolute;width:38px;height:38px;right:0;cursor:pointer;z-index:102;top:22px}.deleteButton{accent-color:var(--danger);position:absolute;width:38px;height:38px;left:0;cursor:pointer;z-index:101;border:none;padding:0;margin:3px;top:22px}.toast h3{margin:0 0 10px}.toast p{margin:0}.offscreen-container{position:absolute;visibility:hidden;pointer-events:none;max-width:480px}.toast-container{isolation:isolate;position:fixed;z-index:2147483647;display:flex;flex-direction:column;box-sizing:border-box;transition:transform calc(.6 * var(--toast-rate) * 1s) ease,opacity calc(.6 * var(--toast-rate) * 1s) ease}.toast-container.toast-top{top:0}.toast-container.toast-bottom{bottom:0}.toast-container.toast-left{left:0;align-items:flex-start}.toast-container.toast-center{left:50%;transform:translate(-50%);align-items:center}.toast-container.toast-right{right:0;align-items:flex-end}#toast-container-top-left .toast{margin:10px 0 0 10px;transform-origin:left center}#toast-container-top-center .toast{margin:10px 0 0;transform-origin:top}#toast-container-top-right .toast{margin:10px 10px 0 0;transform-origin:right center}#toast-container-bottom-left .toast{margin:0 0 10px 10px;transform-origin:left center}#toast-container-bottom-center .toast{margin:0 0 10px;transform-origin:bottom}#toast-container-bottom-right .toast{margin:0 10px 10px 0;transform-origin:right center}.toast{--toast-rate: 1;--toast-translate: 0;--toast-scale: 1;position:relative;transition:transform calc(.4s * var(--toast-rate)) cubic-bezier(.34,1.56,.64,1),opacity calc(.3s * var(--toast-rate)) ease;transform:translate3d(0,var(--toast-translate),0) scale(var(--toast-scale));max-width:480px;max-height:0px;will-change:transform,opacity;backface-visibility:hidden;contain:content;border-radius:6px;box-shadow:0 4px 8px #00000040}.toast-close{position:absolute;color:var(--text);top:5px;right:5px;cursor:pointer;font-size:12px;line-height:12px;z-index:2147483648;transform-origin:center center}.toast-content{border-radius:6px;padding:14px 18px;max-width:100%;box-sizing:border-box;background:var(--primary);color:var(--primary-text);cursor:pointer;white-space:normal;word-break:break-all;overflow:hidden;position:relative}.toast-progress{position:absolute;bottom:0;left:0;right:0;height:4px;background:#fffc;transform:scaleX(var(--toast-progress, 0));transition:transform calc(.05s * var(--toast-rate)) linear;will-change:transform;backface-visibility:hidden}.toast:hover{z-index:2147483648;--toast-scale: 1.15}.toast-container.toast-left .toast .toast-content .toast-progress{transform-origin:left}.toast-container.toast-center .toast .toast-content .toast-progress{transform-origin:center}.toast-container.toast-right .toast .toast-content .toast-progress{transform-origin:right}.toast-container.toast-top .toast.show{animation:toast-in-top calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-bottom .toast.show{animation:toast-in-bottom calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-top .toast.hide{animation:toast-out-top calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}.toast-container.toast-bottom .toast.hide{animation:toast-out-bottom calc(.3 * var(--toast-rate) * 1s) ease-in-out forwards}@keyframes toast-in-top{0%{opacity:0;max-height:0px}to{max-height:var(--toast-height)}}@keyframes toast-in-bottom{0%{opacity:0;max-height:0px}to{max-height:var(--toast-height)}}@keyframes toast-out-top{0%{max-height:var(--toast-height)}to{opacity:0;max-height:0px}}@keyframes toast-out-bottom{0%{max-height:var(--toast-height)}to{opacity:0;max-height:0px}}\n';
  if (getDomain2(unsafeWindow.location.href) !== "iwara.tv" && getDomain2(unsafeWindow.location.href) !== "iwara.zip" && unsafeWindow.location.hostname.includes("iwara")) {
    XMLHttpRequest.prototype.open = void 0;
    unsafeWindow.fetch = void 0;
    unsafeWindow.WebSocket = void 0;
    if (!confirm(stringify(i18nList[config.language].notOfficialWarning))) {
      unsafeWindow.location.href = "about:blank";
      unsafeWindow.close();
    } else {
      throw "Not official";
    }
  }
  if (getDomain2(unsafeWindow.location.href) !== "iwara.tv") {
    throw "Not target";
  }
  var isPageType = (type2) => new Set(Object.values(PageType)).has(type2);
  var isLoggedIn = () => !(unsafeWindow.localStorage.getItem("token") ?? "").isEmpty();
  var rating = () => localStorage.getItem("rating") ?? "all";
  var mouseTarget = null;
  async function getCommentData(id, commentID, page = 0) {
    return await (await unlimitedFetch(`https://api.iwara.tv/video/${id}/comments?page=${page}${!isNullOrUndefined(commentID) && !commentID.isEmpty() ? "&parent=" + commentID : ""}`, {
      headers: await getAuth()
    })).json();
  }
  async function getCommentDatas(id, commentID) {
    let comments = [];
    let base = await getCommentData(id, commentID);
    comments.push(...base.results);
    for (let page = 1; page < Math.ceil(base.count / base.limit); page++) {
      comments.push(...(await getCommentData(id, commentID, page)).results);
    }
    let replies = [];
    for (let index = 0; index < comments.length; index++) {
      const comment = comments[index];
      if (comment.numReplies > 0) {
        replies.push(...await getCommentDatas(id, comment.id));
      }
    }
    comments.push(...replies);
    return comments;
  }
  async function getCDNCache(id, info) {
    let cache = (await db.videos.where("ID").equals(id).toArray()).pop() ?? info;
    let cdnCache = await db.caches.where("ID").equals(id).toArray();
    if (!cdnCache.any() && (cache?.Type === "partial" || cache?.Type === "full")) {
      let query = prune({
        author: cache.Alias ?? cache.Author,
        title: cache.Title
      });
      for (const key in query) {
        let dom = new DOMParser().parseFromString(await (await unlimitedFetch(`https://mmdfans.net/?query=${encodeURIComponent(`${key}:${query[key]}`)}`)).text(), "text/html");
        for (let i of [...dom.querySelectorAll(".mdui-col > a")]) {
          let ID = i.querySelector(".mdui-grid-tile > img")?.src?.toURL()?.pathname?.split("/")?.pop()?.trimTail(".jpg");
          if (isNullOrUndefined(ID)) continue;
          await db.caches.put({
            ID,
            href: `https://mmdfans.net${i.getAttribute("href")}`
          });
        }
      }
    }
    cdnCache = await db.caches.where("ID").equals(id).toArray();
    if (cdnCache.any()) {
      newToast(ToastType.Warn, {
        node: toastNode([`${cache?.RAW?.title}[${id}] %#parsingFailed#%`, {
          nodeType: "br"
        }, `%#cdnCacheFinded#%`], "%#createTask#%"),
        onClick() {
          GM_openInTab(cdnCache[0].href, {
            active: false,
            insert: true,
            setParent: true
          });
          this.hide();
        }
      }).show();
      return;
    }
    newToast(ToastType.Error, {
      node: toastNode([`${cache?.RAW?.title}[${id}] %#parsingFailed#%`], "%#createTask#%"),
      onClick() {
        this.hide();
      }
    }).show();
  }
  async function parseVideoInfo(info) {
    let ID = info.ID;
    let Type = info.Type;
    let RAW = info.RAW;
    try {
      switch (info.Type) {
        case "cache":
          RAW = info.RAW;
          ID = RAW.id;
          Type = "partial";
          break;
        case "init":
        case "fail":
        case "partial":
        case "full":
          let sourceResult = await (await unlimitedFetch(`https://api.iwara.tv/video/${info.ID}`, {
            headers: await getAuth()
          }, {
            retry: true,
            maxRetries: 3,
            failStatuses: [403, 404],
            retryDelay: 1e3,
            onRetry: async () => {
              await refreshToken();
            }
          })).json();
          if (isNullOrUndefined(sourceResult.id)) {
            Type = "fail";
            return {
              ID,
              Type,
              RAW,
              Msg: sourceResult.message ?? stringify(sourceResult)
            };
          }
          RAW = sourceResult;
          ID = RAW.id;
          Type = "full";
          break;
        default:
          Type = "fail";
          return {
            ID,
            Type,
            RAW,
            Msg: "Unknown type"
          };
      }
    } catch (error) {
      newToast(ToastType.Error, {
        node: toastNode([`${info.RAW?.title}[${ID}] %#parsingFailed#%`], "%#createTask#%"),
        async onClick() {
          await parseVideoInfo({
            Type: "init",
            ID,
            RAW,
            UploadTime: 0
          });
          this.hide();
        }
      }).show();
      Type = "fail";
      return {
        ID,
        Type,
        RAW,
        Msg: stringify(error)
      };
    }
    let FileName;
    let Size;
    let External;
    let ExternalUrl;
    let Description;
    let DownloadQuality;
    let DownloadUrl;
    let Comments;
    let UploadTime;
    let Title;
    let Tags;
    let Liked;
    let Alias;
    let Author;
    let AuthorID;
    let Private;
    let Unlisted;
    let Following;
    let Friend;
    UploadTime = new Date(RAW.createdAt ?? 0).getTime();
    Title = RAW.title;
    Tags = RAW.tags;
    Liked = RAW.liked;
    Alias = RAW.user.name;
    Author = RAW.user.username;
    AuthorID = RAW.user.id;
    Private = RAW.private;
    Unlisted = RAW.unlisted;
    External = !isNullOrUndefined(RAW.embedUrl) && !RAW.embedUrl.isEmpty();
    ExternalUrl = RAW.embedUrl;
    if (External) {
      Type = "fail";
      return {
        Type,
        RAW,
        ID,
        Alias,
        Author,
        AuthorID,
        Private,
        UploadTime,
        Title,
        Tags,
        Liked,
        External,
        ExternalUrl,
        Description,
        Unlisted,
        Msg: "external Video"
      };
    }
    try {
      switch (Type) {
        case "full":
          Following = RAW.user.following;
          Friend = RAW.user.friend;
          if (Following) {
            db.follows.put(RAW.user, AuthorID);
          } else {
            db.follows.delete(AuthorID);
          }
          if (Friend) {
            db.friends.put(RAW.user, AuthorID);
          } else {
            db.friends.delete(AuthorID);
          }
          Description = RAW.body;
          FileName = RAW.file.name;
          Size = RAW.file.size;
          let VideoFileSource = (await (await unlimitedFetch(RAW.fileUrl, {
            headers: await getAuth(RAW.fileUrl)
          })).json()).sort((a, b) => (!isNullOrUndefined(config.priority[b.name]) ? config.priority[b.name] : 0) - (!isNullOrUndefined(config.priority[a.name]) ? config.priority[a.name] : 0));
          if (isNullOrUndefined(VideoFileSource) || !(VideoFileSource instanceof Array) || VideoFileSource.length < 1) throw new Error(i18nList[config.language].getVideoSourceFailed.toString());
          DownloadQuality = config.checkPriority ? config.downloadPriority : VideoFileSource[0].name;
          let fileList = VideoFileSource.filter((x) => x.name === DownloadQuality);
          if (!fileList.any()) throw new Error(i18nList[config.language].noAvailableVideoSource.toString());
          let Source = fileList[Math.floor(Math.random() * fileList.length)].src.download;
          if (isNullOrUndefined(Source) || Source.isEmpty()) throw new Error(i18nList[config.language].videoSourceNotAvailable.toString());
          DownloadUrl = decodeURIComponent(`https:${Source}`);
          Comments = `${(await getCommentDatas(ID)).map((i) => i.body).join("\n")}`.normalize("NFKC");
          return {
            Type,
            RAW,
            ID,
            Alias,
            Author,
            AuthorID,
            Private,
            UploadTime,
            Title,
            Tags,
            Liked,
            External,
            FileName,
            DownloadQuality,
            ExternalUrl,
            Description,
            Comments,
            DownloadUrl,
            Size,
            Following,
            Unlisted,
            Friend
          };
        case "partial":
          return {
            Type,
            RAW,
            ID,
            Alias,
            Author,
            AuthorID,
            UploadTime,
            Title,
            Tags,
            Liked,
            External,
            ExternalUrl,
            Unlisted,
            Private
          };
        default:
          Type = "fail";
          return {
            Type,
            RAW,
            ID,
            Alias,
            Author,
            AuthorID,
            Private,
            UploadTime,
            Title,
            Tags,
            Liked,
            External,
            ExternalUrl,
            Description,
            Unlisted,
            Msg: "Unknown type"
          };
      }
    } catch (error) {
      Type = "fail";
      return {
        Type,
        RAW,
        ID,
        Alias,
        Author,
        AuthorID,
        Private,
        UploadTime,
        Title,
        Tags,
        Liked,
        External,
        ExternalUrl,
        Description,
        Unlisted,
        Msg: stringify(error)
      };
    }
  }
  var configEdit = class {
    constructor(config2) {
      this.target = config2;
      this.target.configChange = (item) => {
        this.configChange.call(this, item);
      };
      this.interfacePage = renderNode({
        nodeType: "p"
      });
      let save = renderNode({
        nodeType: "button",
        childs: "%#save#%",
        attributes: {
          title: i18nList[config2.language].save
        },
        events: {
          click: async () => {
            save.disabled = !save.disabled;
            if (await check()) {
              unsafeWindow.location.reload();
            }
            save.disabled = !save.disabled;
          }
        }
      });
      let reset = renderNode({
        nodeType: "button",
        childs: "%#reset#%",
        attributes: {
          title: i18nList[config2.language].reset
        },
        events: {
          click: () => {
            GM_setValue("isFirstRun", true);
            unsafeWindow.location.reload();
          }
        }
      });
      this.interface = renderNode({
        nodeType: "div",
        attributes: {
          id: "pluginConfig"
        },
        childs: [{
          nodeType: "div",
          className: "main",
          childs: [{
            nodeType: "h2",
            childs: "%#appName#%"
          }, {
            nodeType: "label",
            childs: ["%#language#% ", {
              nodeType: "input",
              className: "inputRadioLine",
              attributes: {
                name: "language",
                type: "text",
                value: this.target.language
              },
              events: {
                change: (event) => {
                  this.target.language = event.target.value;
                }
              }
            }]
          }, this.downloadTypeSelect(), this.interfacePage, this.switchButton("checkPriority"), this.switchButton("checkDownloadLink"), this.switchButton("autoFollow"), this.switchButton("autoLike"), this.switchButton("autoInjectCheckbox"), this.switchButton("autoDownloadMetadata"), this.switchButton("autoCopySaveFileName"), this.switchButton("addUnlistedAndPrivate"), this.switchButton("experimentalFeatures"), this.switchButton("enableUnsafeMode"), this.switchButton("isDebug", GM_getValue, (name, e) => {
            GM_setValue(name, e.target.checked);
            unsafeWindow.location.reload();
          }, false)]
        }, {
          nodeType: "p",
          className: "buttonList",
          childs: [reset, save]
        }]
      });
    }
    switchButton(name, get, set, defaultValue) {
      return renderNode({
        nodeType: "p",
        className: "inputRadioLine",
        childs: [{
          nodeType: "label",
          childs: `%#${name}#%`,
          attributes: {
            for: name
          }
        }, {
          nodeType: "input",
          className: "switch",
          attributes: {
            type: "checkbox",
            name,
            checked: get !== void 0 ? get(name, defaultValue) : this.target[name] ?? defaultValue ?? false
          },
          events: {
            change: (e) => {
              if (set !== void 0) {
                set(name, e);
                return;
              } else {
                this.target[name] = e.target.checked;
              }
            }
          }
        }]
      });
    }
    inputComponent(name, type2, help, get, set) {
      return renderNode({
        nodeType: "label",
        childs: [{
          nodeType: "span",
          childs: [`%#${name}#%`, help]
        }, {
          nodeType: "input",
          attributes: {
            name,
            type: type2 ?? "text",
            value: get !== void 0 ? get(name) : this.target[name]
          },
          events: {
            change: (e) => {
              if (set !== void 0) {
                set(name, e);
                return;
              } else {
                this.target[name] = e.target.value;
              }
            }
          }
        }]
      });
    }
    downloadTypeSelect() {
      return renderNode({
        nodeType: "fieldset",
        childs: [{
          nodeType: "legend",
          childs: "%#downloadType#%"
        }, ...Object.keys(DownloadType).filter((i) => isNaN(Number(i))).map((type2, index) => renderNode({
          nodeType: "label",
          childs: [{
            nodeType: "input",
            attributes: {
              type: "radio",
              name: "downloadType",
              value: index,
              checked: index === Number(this.target.downloadType)
            },
            events: {
              change: (e) => {
                this.target.downloadType = Number(e.target.value);
              }
            }
          }, type2]
        }))]
      });
    }
    configChange(item) {
      switch (item) {
        case "downloadType":
          const radios = this.interface.querySelectorAll(`[name=${item}]`);
          radios.forEach((radio) => {
            radio.checked = Number(radio.value) === Number(this.target.downloadType);
          });
          this.pageChange();
          break;
        case "checkPriority":
          this.pageChange();
          break;
        default:
          let element = this.interface.querySelector(`[name=${item}]`);
          if (element) {
            switch (element.type) {
              case "radio":
                element.value = this.target[item];
                break;
              case "checkbox":
                element.checked = this.target[item];
                break;
              case "text":
              case "password":
                element.value = this.target[item];
                break;
              default:
                break;
            }
          }
          break;
      }
    }
    pageChange() {
      while (this.interfacePage.hasChildNodes()) {
        this.interfacePage.removeChild(this.interfacePage.firstChild);
      }
      let downloadConfigInput = [this.inputComponent("downloadPath", "text", renderNode({
        nodeType: "a",
        childs: "%#variable#%",
        className: "rainbow-text",
        attributes: {
          style: "float: inline-end;",
          href: "https://github.com/dawn-lc/IwaraDownloadTool/wiki/路径可用变量"
        }
      }))];
      let proxyConfigInput = [this.inputComponent("downloadProxy"), this.inputComponent("downloadProxyUsername"), this.inputComponent("downloadProxyPassword", "password")];
      let aria2ConfigInput = [this.inputComponent("aria2Path"), this.inputComponent("aria2Token", "password"), ...proxyConfigInput];
      let iwaraDownloaderConfigInput = [this.inputComponent("iwaraDownloaderPath"), this.inputComponent("iwaraDownloaderToken", "password"), ...proxyConfigInput];
      switch (this.target.downloadType) {
        case DownloadType.Aria2:
          downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          aria2ConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
        case DownloadType.IwaraDownloader:
          downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          iwaraDownloaderConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
        default:
          downloadConfigInput.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
      }
      if (this.target.checkPriority) {
        originalNodeAppendChild.call(this.interfacePage, this.inputComponent("downloadPriority"));
      }
    }
    inject() {
      if (!unsafeWindow.document.querySelector("#pluginConfig")) {
        originalNodeAppendChild.call(unsafeWindow.document.body, this.interface);
        this.configChange("downloadType");
      }
    }
  };
  var menu = class {
    constructor() {
      let body = new Proxy(this, {
        set: (target, prop, value) => {
          if (prop === "pageType") {
            if (isNullOrUndefined(value) || this.pageType === value) return true;
            target[prop] = value;
            this.pageChange();
            GM_getValue("isDebug") && originalConsole.debug(`[Debug] Page change to ${this.pageType}`);
            return true;
          }
          return target[prop] = value;
        }
      });
      body.interfacePage = renderNode({
        nodeType: "ul"
      });
      body.interface = renderNode({
        nodeType: "div",
        attributes: {
          id: "pluginMenu"
        },
        childs: body.interfacePage
      });
      let mouseoutTimer = null;
      originalAddEventListener.call(body.interface, "mouseover", (event) => {
        if (mouseoutTimer !== null) {
          clearTimeout(mouseoutTimer);
          mouseoutTimer = null;
        }
        body.interface.classList.add("expanded");
      });
      originalAddEventListener.call(body.interface, "mouseout", (event) => {
        const e = event;
        const relatedTarget = e.relatedTarget;
        if (relatedTarget && body.interface.contains(relatedTarget)) {
          return;
        }
        mouseoutTimer = setTimeout(() => {
          body.interface.classList.remove("expanded");
          mouseoutTimer = null;
        }, 300);
      });
      originalAddEventListener.call(body.interface, "click", (event) => {
        if (event.target === body.interface) {
          body.interface.classList.toggle("expanded");
        }
      });
      body.observer = new MutationObserver((mutationsList) => body.pageType = getPageType(mutationsList) ?? body.pageType);
      body.pageType = PageType.Page;
      return body;
    }
    button(name, click) {
      return renderNode({
        nodeType: "li",
        childs: `%#${name}#%`,
        events: {
          click: (event) => {
            !isNullOrUndefined(click) && click(name, event);
            event.stopPropagation();
            return false;
          }
        }
      });
    }
    async parseUnlistedAndPrivate() {
      if (!isLoggedIn()) return;
      const lastMonthTimestamp = Date.now() - 30 * 24 * 60 * 60 * 1e3;
      const thisMonthUnlistedAndPrivateVideos = await db.videos.where("UploadTime").between(lastMonthTimestamp, Infinity).and((i) => !isInitVideoInfo(i) && !isFailVideoInfo(i) && !isCacheVideoInfo(i) && (i.Private || i.Unlisted)).toArray();
      let parseUnlistedAndPrivateVideos = [];
      let pageCount = 0;
      const MAX_FIND_PAGES = 64;
      GM_getValue("isDebug") && originalConsole.debug(`[Debug] Starting fetch loop. MAX_PAGES=${MAX_FIND_PAGES}`);
      while (pageCount < MAX_FIND_PAGES) {
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Fetching page ${pageCount}.`);
        const response = await unlimitedFetch(`https://api.iwara.tv/videos?subscribed=true&limit=50&rating=${rating()}&page=${pageCount}`, {
          method: "GET",
          headers: await getAuth()
        }, {
          retry: true,
          retryDelay: 1e3,
          onRetry: async () => {
            await refreshToken();
          }
        });
        GM_getValue("isDebug") && originalConsole.debug("[Debug] Received response, parsing JSON.");
        const data = (await response.json()).results;
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Page ${pageCount} returned ${data.length} videos.`);
        data.forEach((info) => info.user.following = true);
        const videoPromises = data.map((info) => parseVideoInfo({
          Type: "cache",
          ID: info.id,
          RAW: info
        }));
        GM_getValue("isDebug") && originalConsole.debug("[Debug] Initializing VideoInfo promises.");
        const videoInfos = await Promise.all(videoPromises);
        parseUnlistedAndPrivateVideos.push(...videoInfos);
        let test = videoInfos.filter((i) => i.Type === "partial" && (i.Private || i.Unlisted)).any();
        GM_getValue("isDebug") && originalConsole.debug("[Debug] All VideoInfo objects initialized.");
        if (test && thisMonthUnlistedAndPrivateVideos.intersect(videoInfos, "ID").any()) {
          GM_getValue("isDebug") && originalConsole.debug(`[Debug] Found private video on page ${pageCount}.`);
          break;
        }
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Latest private video not found on page ${pageCount}, continuing.`);
        pageCount++;
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Incremented page to ${pageCount}, delaying next fetch.`);
        await delay(100);
      }
      GM_getValue("isDebug") && originalConsole.debug("[Debug] Fetch loop ended. Start updating the database");
      const toUpdate = parseUnlistedAndPrivateVideos.difference((await db.videos.where("ID").anyOf(parseUnlistedAndPrivateVideos.map((v) => v.ID)).toArray()).filter((v) => v.Type === "full"), "ID");
      if (toUpdate.any()) {
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Need to update ${toUpdate.length} pieces of data.`);
        await db.videos.bulkPut(toUpdate);
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] Update Completed.`);
      } else {
        GM_getValue("isDebug") && originalConsole.debug(`[Debug] No need to update data.`);
      }
    }
    async pageChange() {
      while (this.interfacePage.hasChildNodes()) {
        this.interfacePage.removeChild(this.interfacePage.firstChild);
      }
      let manualDownloadButton = this.button("manualDownload", (name, event) => {
        addDownloadTask();
      });
      let settingsButton = this.button("settings", (name, event) => {
        editConfig.inject();
      });
      let exportConfigButton = this.button("exportConfig", (name, event) => {
        GM_setClipboard(stringify(config));
        newToast(ToastType.Info, {
          node: toastNode(i18nList[config.language].exportConfigSucceed),
          duration: 3e3,
          gravity: "bottom",
          position: "center",
          onClick() {
            this.hide();
          }
        }).show();
      });
      let baseButtons = [manualDownloadButton, exportConfigButton, settingsButton];
      let injectCheckboxButton = this.button("injectCheckbox", (name, event) => {
        if (unsafeWindow.document.querySelector(".selectButton")) {
          unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => {
            element.remove();
          });
        } else {
          unsafeWindow.document.querySelectorAll(`.videoTeaser`).forEach((element) => {
            injectCheckbox(element);
          });
        }
      });
      let deselectAllButton = this.button("deselectAll", (name, event) => {
        for (const id of selectList.keys()) {
          selectList.delete(id);
        }
      });
      let reverseSelectButton = this.button("reverseSelect", (name, event) => {
        unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => {
          element.click();
        });
      });
      let selectThisButton = this.button("selectThis", (name, event) => {
        unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => {
          let button = element;
          !button.checked && button.click();
        });
      });
      let deselectThisButton = this.button("deselectThis", (name, event) => {
        unsafeWindow.document.querySelectorAll(".selectButton").forEach((element) => {
          let button = element;
          button.checked && button.click();
        });
      });
      let downloadSelectedButton = this.button("downloadSelected", (name, event) => {
        analyzeDownloadTask();
        newToast(ToastType.Info, {
          text: `%#${name}#%`,
          close: true
        }).show();
      });
      let selectButtons = [injectCheckboxButton, deselectAllButton, reverseSelectButton, selectThisButton, deselectThisButton, downloadSelectedButton];
      let downloadThisButton = this.button("downloadThis", async (name, event) => {
        let ID = unsafeWindow.location.href.toURL().pathname.split("/")[2];
        await pushDownloadTask(await parseVideoInfo({
          Type: "init",
          ID
        }), true);
      });
      let aria2TaskCheckButton = this.button("aria2TaskCheck", (name, event) => {
        aria2TaskCheckAndRestart();
      });
      config.experimentalFeatures && originalNodeAppendChild.call(this.interfacePage, aria2TaskCheckButton);
      switch (this.pageType) {
        case PageType.Video:
          originalNodeAppendChild.call(this.interfacePage, downloadThisButton);
          selectButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
        case PageType.Search:
        case PageType.Profile:
        case PageType.Home:
        case PageType.VideoList:
        case PageType.Subscriptions:
        case PageType.Playlist:
        case PageType.Favorites:
        case PageType.Account:
          selectButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
        case PageType.Page:
        case PageType.Forum:
        case PageType.Image:
        case PageType.ImageList:
        case PageType.ForumSection:
        case PageType.ForumThread:
        default:
          baseButtons.map((i) => originalNodeAppendChild.call(this.interfacePage, i));
          break;
      }
      if (config.addUnlistedAndPrivate && this.pageType === PageType.VideoList) {
        this.parseUnlistedAndPrivate();
      } else {
        GM_getValue("isDebug") && originalConsole.debug("[Debug] Conditions not met: addUnlistedAndPrivate or pageType mismatch.");
      }
    }
    inject() {
      this.observer.observe(unsafeWindow.document.getElementById("app"), {
        childList: true,
        subtree: true
      });
      if (!unsafeWindow.document.querySelector("#pluginMenu")) {
        originalNodeAppendChild.call(unsafeWindow.document.body, this.interface);
        this.pageType = getPageType() ?? this.pageType;
      }
    }
  };
  var pluginMenu = new menu();
  var editConfig = new configEdit(config);
  var selectList = new VCSyncDictionary("selectList");
  var pageStatus = new MultiPage();
  var pageSelectButtons = new Dictionary();
  var selected = renderNode({
    nodeType: "span",
    childs: ` %#selected#% ${selectList.size} `
  });
  var watermark = renderNode({
    nodeType: "p",
    className: "fixed-bottom-right",
    childs: [`%#appName#% ${GM_getValue("version")} `, selected, GM_getValue("isDebug") ? `%#isDebug#%` : ""]
  });
  function getSelectButton(id) {
    return pageSelectButtons.has(id) ? pageSelectButtons.get(id) : unsafeWindow.document.querySelector(`input.selectButton[videoid="${id}"]`);
  }
  function saveSelectList() {
    GM_getTabs((tabs) => {
      if (Object.keys(tabs).length > 1) return;
      selectList.save();
    });
  }
  function updateSelected() {
    selected.textContent = ` ${i18nList[config.language].selected} ${selectList.size} `;
  }
  function updateButtonState(videoID) {
    const selectButton = getSelectButton(videoID);
    if (selectButton) selectButton.checked = selectList.has(videoID);
  }
  originalAddEventListener.call(unsafeWindow.document, "visibilitychange", saveSelectList);
  pageStatus.onPageLeave = () => {
    saveSelectList();
  };
  selectList.onSet = (key) => {
    updateButtonState(key);
    saveSelectList();
    updateSelected();
  };
  selectList.onDel = (key) => {
    updateButtonState(key);
    saveSelectList();
    updateSelected();
  };
  selectList.onSync = () => {
    pageSelectButtons.forEach((value, key) => {
      updateButtonState(key);
    });
    saveSelectList();
    updateSelected();
  };
  function generateMatadataURL(videoInfo) {
    const metadataContent = generateMetadataContent(videoInfo);
    const blob = new Blob([metadataContent], {
      type: "text/plain"
    });
    return URL.createObjectURL(blob);
  }
  function getMatadataPath(videoInfo) {
    const videoPath = getDownloadPath(videoInfo);
    return `${videoPath.directory}/${videoPath.baseName}.json`;
  }
  function generateMetadataContent(videoInfo) {
    const metadata = Object.assign(videoInfo, {
      DownloadPath: getDownloadPath(videoInfo).fullPath,
      MetaDataVersion: GM_info.script.version
    });
    return JSON.stringify(metadata, (key, value) => {
      if (value instanceof Date) {
        return value.toISOString();
      }
      return value;
    }, 2);
  }
  function browserDownloadMetadata(videoInfo) {
    const url = generateMatadataURL(videoInfo);
    function toastError(error) {
      newToast(ToastType.Error, {
        node: toastNode([`${videoInfo.Title}[${videoInfo.ID}] %#videoMetadata#% %#downloadFailed#%`, {
          nodeType: "br"
        }, browserDownloadErrorParse(error)], "%#browserDownload#%"),
        close: true
      }).show();
    }
    GM_download({
      url,
      saveAs: false,
      name: getMatadataPath(videoInfo),
      onerror: (err) => toastError(err),
      ontimeout: () => toastError(new Error("%#browserDownloadTimeout#%")),
      onload: () => URL.revokeObjectURL(url)
    });
  }
  function othersDownloadMetadata(videoInfo) {
    const url = generateMatadataURL(videoInfo);
    const metadataFile = analyzeLocalPath(getMatadataPath(videoInfo)).fullName;
    const downloadHandle = renderNode({
      nodeType: "a",
      attributes: {
        href: url,
        download: metadataFile
      }
    });
    downloadHandle.click();
    downloadHandle.remove();
    URL.revokeObjectURL(url);
  }
  async function addDownloadTask() {
    let textArea = renderNode({
      nodeType: "textarea",
      attributes: {
        placeholder: i18nList[config.language].manualDownloadTips,
        style: "margin-bottom: 10px;",
        rows: "16",
        cols: "96"
      }
    });
    let body = renderNode({
      nodeType: "div",
      attributes: {
        id: "pluginOverlay"
      },
      childs: [textArea, {
        nodeType: "button",
        events: {
          click: (e) => {
            if (!isNullOrUndefined(textArea.value) && !textArea.value.isEmpty()) {
              let list = [];
              try {
                const parsed = JSON.parse(textArea.value);
                if (Array.isArray(parsed)) {
                  list = parsed.map((item) => {
                    if (Array.isArray(item) && isString(item[0]) && !item[0].isEmpty()) {
                      if (!isVideoInfo(item[1])) {
                        item[1].Type = "init";
                        item[1].ID = item[1].ID ?? item[0];
                        item[1].UpdateTime = item[1].UpdateTime ?? Date.now();
                      }
                    }
                    return [...item];
                  });
                } else {
                  throw new Error("解析结果不是符合预期的列表");
                }
              } catch (error) {
                list = textArea.value.split("|").map((ID) => [ID.trim(), {
                  Type: "init",
                  ID: ID.trim(),
                  UpdateTime: Date.now()
                }]);
              }
              if (list.length > 0) {
                analyzeDownloadTask(new Dictionary(list));
              }
            }
            body.remove();
          }
        },
        childs: i18nList[config.language].ok
      }]
    });
    unsafeWindow.document.body.appendChild(body);
  }
  async function downloadTaskUnique(taskList) {
    let stoped = prune((await aria2API("aria2.tellStopped", [0, 4096, ["gid", "status", "files", "errorCode", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => {
      let ID = aria2TaskExtractVideoID(task2);
      if (!isNullOrUndefined(ID) && !ID.isEmpty()) {
        return {
          id: ID,
          data: task2
        };
      }
    }));
    let active = prune((await aria2API("aria2.tellActive", [["gid", "status", "files", "downloadSpeed", "bittorrent"]])).result.filter((task2) => isNullOrUndefined(task2.bittorrent)).map((task2) => {
      let ID = aria2TaskExtractVideoID(task2);
      if (!isNullOrUndefined(ID) && !ID.isEmpty()) {
        return {
          id: ID,
          data: task2
        };
      }
    }));
    let downloadCompleted = stoped.filter((task2) => task2.data.status === "complete").unique("id");
    let startedAndCompleted = [...active, ...downloadCompleted].map((i) => i.id);
    for (let key of taskList.keysArray().intersect(startedAndCompleted)) {
      taskList.delete(key);
    }
  }
  async function analyzeDownloadTask(taskList = selectList) {
    let size = taskList.size;
    let node = renderNode({
      nodeType: "p",
      childs: `${i18nList[config.language].parsingProgress}[${taskList.size}/${size}]`
    });
    let parsingProgressToast = newToast(ToastType.Info, {
      node,
      duration: -1
    });
    function updateParsingProgress() {
      node.firstChild.textContent = `${i18nList[config.language].parsingProgress}[${taskList.size}/${size}]`;
    }
    parsingProgressToast.show();
    if (config.experimentalFeatures && config.downloadType === DownloadType.Aria2) {
      await downloadTaskUnique(taskList);
      updateParsingProgress();
    }
    for (let [id, info] of taskList) {
      await pushDownloadTask(await parseVideoInfo(info));
      taskList.delete(id);
      updateParsingProgress();
      !config.enableUnsafeMode && await delay(3e3);
    }
    parsingProgressToast.hide();
    newToast(ToastType.Info, {
      text: `%#allCompleted#%`,
      duration: -1,
      close: true,
      onClick() {
        this.hide();
      }
    }).show();
  }
  async function pushDownloadTask(videoInfo, bypass = false) {
    switch (videoInfo.Type) {
      case "full":
        await db.videos.put(videoInfo, videoInfo.ID);
        if (!bypass) {
          const authorInfo = await db.follows.get(videoInfo.AuthorID);
          if (config.autoFollow && (!authorInfo?.following || !videoInfo.Following)) {
            await unlimitedFetch(`https://api.iwara.tv/user/${videoInfo.AuthorID}/followers`, {
              method: "POST",
              headers: await getAuth()
            }, {
              retry: true,
              successStatus: 201,
              failStatuses: [404],
              onFail: async (res) => {
                newToast(ToastType.Warn, {
                  text: `${videoInfo.Alias} %#autoFollowFailed#% ${res.status}`,
                  close: true,
                  onClick() {
                    this.hide();
                  }
                }).show();
              },
              onRetry: async () => {
                await refreshToken();
              }
            });
          }
          if (config.autoLike && !videoInfo.Liked) {
            await unlimitedFetch(`https://api.iwara.tv/video/${videoInfo.ID}/like`, {
              method: "POST",
              headers: await getAuth()
            }, {
              retry: true,
              successStatus: 201,
              failStatuses: [404],
              onFail: async (res) => {
                newToast(ToastType.Warn, {
                  text: `${videoInfo.Alias} %#autoLikeFailed#% ${res.status}`,
                  close: true,
                  onClick() {
                    this.hide();
                  }
                }).show();
              },
              onRetry: async () => {
                await refreshToken();
              }
            });
          }
          if (config.checkDownloadLink && checkIsHaveDownloadLink(`${videoInfo.Description} ${videoInfo.Comments}`)) {
            let toastBody = toastNode([`${videoInfo.Title}[${videoInfo.ID}] %#findedDownloadLink#%`, {
              nodeType: "br"
            }, `%#openVideoLink#%`], "%#createTask#%");
            newToast(ToastType.Warn, {
              node: toastBody,
              close: config.autoCopySaveFileName,
              onClick() {
                GM_openInTab(`https://www.iwara.tv/video/${videoInfo.ID}`, {
                  active: false,
                  insert: true,
                  setParent: true
                });
                if (config.autoCopySaveFileName) {
                  GM_setClipboard(getDownloadPath(videoInfo).fullName, "text");
                  toastBody.appendChild(renderNode({
                    nodeType: "p",
                    childs: "%#copySucceed#%"
                  }));
                } else {
                  this.hide();
                }
              }
            }).show();
            return;
          }
        }
        if (config.checkPriority && videoInfo.DownloadQuality !== config.downloadPriority) {
          newToast(ToastType.Warn, {
            node: toastNode([`${videoInfo.Title.truncate(64)}[${videoInfo.ID}] %#downloadQualityError#%`, {
              nodeType: "br"
            }, `%#tryReparseDownload#%`], "%#createTask#%"),
            async onClick() {
              this.hide();
              await pushDownloadTask(await parseVideoInfo(videoInfo));
            }
          }).show();
          return;
        }
        switch (config.downloadType) {
          case DownloadType.Aria2:
            aria2Download(videoInfo);
            break;
          case DownloadType.IwaraDownloader:
            iwaraDownloaderDownload(videoInfo);
            break;
          case DownloadType.Browser:
            browserDownload(videoInfo);
            break;
          default:
            othersDownload(videoInfo);
            break;
        }
        if (config.autoDownloadMetadata) {
          switch (config.downloadType) {
            case DownloadType.Others:
              othersDownloadMetadata(videoInfo);
              break;
            case DownloadType.Browser:
              browserDownloadMetadata(videoInfo);
              break;
            default:
              break;
          }
          GM_getValue("isDebug") && originalConsole.debug("[Debug] Download task pushed:", videoInfo);
        }
        selectList.delete(videoInfo.ID);
        break;
      case "partial":
        const partialCache = await db.videos.get(videoInfo.ID);
        if (!isNullOrUndefined(partialCache) && partialCache.Type !== "full") await db.videos.put(videoInfo, videoInfo.ID);
      case "cache":
      case "init":
        return await pushDownloadTask(await parseVideoInfo(videoInfo));
      case "fail":
        const cache = await db.videos.get(videoInfo.ID);
        newToast(ToastType.Error, {
          close: true,
          node: toastNode([`${videoInfo.Title ?? videoInfo.RAW?.title ?? cache?.RAW?.title}[${videoInfo.ID}] %#parsingFailed#%`, {
            nodeType: "br"
          }, videoInfo.Msg, {
            nodeType: "br"
          }, videoInfo.External ? `%#openVideoLink#%` : `%#tryReparseDownload#%`], "%#createTask#%"),
          async onClick() {
            this.hide();
            if (videoInfo.External && !isNullOrUndefined(videoInfo.ExternalUrl) && !videoInfo.ExternalUrl.isEmpty()) {
              GM_openInTab(videoInfo.ExternalUrl, {
                active: false,
                insert: true,
                setParent: true
              });
            } else {
              await pushDownloadTask(await parseVideoInfo({
                Type: "init",
                ID: videoInfo.ID,
                RAW: videoInfo.RAW ?? cache?.RAW
              }));
            }
          }
        }).show();
        break;
      default:
        GM_getValue("isDebug") && originalConsole.debug("[Debug] Unknown type:", videoInfo);
        break;
    }
  }
  function uninjectCheckbox(element) {
    if (element instanceof HTMLElement) {
      if (element instanceof HTMLInputElement && element.classList.contains("selectButton")) {
        element.hasAttribute("videoID") && pageSelectButtons.delete(element.getAttribute("videoID"));
      }
      if (element.querySelector("input.selectButton")) {
        element.querySelectorAll(".selectButton").forEach((i) => i.hasAttribute("videoID") && pageSelectButtons.delete(i.getAttribute("videoID")));
      }
    }
  }
  async function injectCheckbox(element) {
    let ID = element.querySelector("a.videoTeaser__thumbnail").href.toURL().pathname.split("/")[2];
    if (isNullOrUndefined(ID)) return;
    let info = await db.videos.get(ID);
    let Title = info?.Type === "full" || info?.Type === "partial" ? info?.Title : info?.RAW?.title ?? element.querySelector(".videoTeaser__title")?.getAttribute("title") ?? void 0;
    let Alias = info?.Type === "full" || info?.Type === "partial" ? info?.Alias : info?.RAW?.user.name ?? element.querySelector("a.username")?.getAttribute("title") ?? void 0;
    let Author = info?.Type === "full" || info?.Type === "partial" ? info?.Author : info?.RAW?.user.username ?? element.querySelector("a.username")?.href.toURL().pathname.split("/").pop();
    let UploadTime = info?.Type === "full" || info?.Type === "partial" ? info?.UploadTime : new Date(info?.RAW?.updatedAt ?? 0).getTime();
    let button = renderNode({
      nodeType: "input",
      attributes: {
        type: "checkbox",
        videoID: ID,
        checked: selectList.has(ID) ? true : void 0,
        videoName: Title,
        videoAlias: Alias,
        videoAuthor: Author,
        videoUploadTime: UploadTime
      },
      className: "selectButton",
      events: {
        click: (event) => {
          event.target.checked ? selectList.set(ID, {
            Type: "init",
            ID,
            Title,
            Alias,
            Author,
            UploadTime
          }) : selectList.delete(ID);
          event.stopPropagation();
          event.stopImmediatePropagation();
          return false;
        }
      }
    });
    let item = element.querySelector(".videoTeaser__thumbnail")?.parentElement;
    item?.style.setProperty("position", "relative");
    pageSelectButtons.set(ID, button);
    originalNodeAppendChild.call(item, button);
    if (!isNullOrUndefined(Author)) {
      const AuthorInfo = await db.follows.where("username").equals(Author).first();
      if (AuthorInfo?.following && element.querySelector(".videoTeaser__thumbnail")?.querySelector(".follow") === null) {
        originalNodeAppendChild.call(element.querySelector(".videoTeaser__thumbnail"), renderNode({
          nodeType: "div",
          className: "follow",
          childs: {
            nodeType: "div",
            className: ["text", "text--white", "text--tiny", "text--bold"],
            childs: "%#following#%"
          }
        }));
      }
    }
    if (pluginMenu.pageType === PageType.Playlist) {
      let deletePlaylistItme = renderNode({
        nodeType: "button",
        attributes: {
          videoID: ID
        },
        childs: "%#delete#%",
        className: "deleteButton",
        events: {
          click: async (event) => {
            if ((await unlimitedFetch(`https://api.iwara.tv/playlist/${unsafeWindow.location.pathname.split("/")[2]}/${ID}`, {
              method: "DELETE",
              headers: await getAuth()
            })).ok) {
              newToast(ToastType.Info, {
                text: `${Title} %#deleteSucceed#%`,
                close: true
              }).show();
              deletePlaylistItme.remove();
            }
            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();
            return false;
          }
        }
      });
      originalNodeAppendChild.call(item, deletePlaylistItme);
    }
  }
  function getPageType(mutationsList) {
    if (unsafeWindow.location.pathname.toLowerCase().endsWith("/search")) {
      return PageType.Search;
    }
    const extractPageType = (page) => {
      if (isNullOrUndefined(page)) return void 0;
      if (page.classList.length < 2) return PageType.Page;
      const pageClass = page.classList[1]?.split("-").pop();
      return !isNullOrUndefined(pageClass) && isPageType(pageClass) ? pageClass : PageType.Page;
    };
    if (isNullOrUndefined(mutationsList)) {
      return extractPageType(unsafeWindow.document.querySelector(".page"));
    }
    for (const mutation of mutationsList) {
      if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
        return extractPageType(Array.from(mutation.addedNodes).find((node) => node instanceof Element && node.classList.contains("page")));
      }
    }
  }
  function pageChange() {
    pluginMenu.pageType = getPageType() ?? pluginMenu.pageType;
    GM_getValue("isDebug") && originalConsole.debug("[Debug]", pageSelectButtons);
  }
  function hijackAddEventListener() {
    unsafeWindow.EventTarget.prototype.addEventListener = function(type2, listener, options) {
      originalAddEventListener.call(this, type2, listener, options);
    };
  }
  function hijackNodeAppendChild() {
    Node.prototype.appendChild = function(node) {
      if (node instanceof HTMLElement && node.classList.contains("videoTeaser")) {
        injectCheckbox(node);
      }
      return originalNodeAppendChild.call(this, node);
    };
  }
  function hijackNodeRemoveChild() {
    Node.prototype.removeChild = function(child) {
      uninjectCheckbox(child);
      return originalNodeRemoveChild.apply(this, [child]);
    };
  }
  function hijackElementRemove() {
    Element.prototype.remove = function() {
      uninjectCheckbox(this);
      return originalElementRemove.apply(this);
    };
  }
  function hijackHistoryPushState() {
    unsafeWindow.history.pushState = function(...args) {
      originalHistoryPushState.apply(this, args);
      pageChange();
    };
  }
  function hijackHistoryReplaceState() {
    unsafeWindow.history.replaceState = function(...args) {
      originalHistoryReplaceState.apply(this, args);
      pageChange();
    };
  }
  function hijackStorage() {
    unsafeWindow.Storage.prototype.setItem = function(key, value) {
      originalStorageSetItem.call(this, key, value);
      if (key === "token") pluginMenu.pageChange();
    };
    unsafeWindow.Storage.prototype.removeItem = function(key) {
      originalStorageRemoveItem.call(this, key);
      if (key === "token") pluginMenu.pageChange();
    };
    unsafeWindow.Storage.prototype.clear = function() {
      originalStorageClear.call(this);
      pluginMenu.pageChange();
    };
  }
  function firstRun() {
    originalConsole.log("First run config reset!");
    GM_listValues().forEach((i) => GM_deleteValue(i));
    Config.destroyInstance();
    editConfig = new configEdit(config);
    let confirmButton = renderNode({
      nodeType: "button",
      attributes: {
        disabled: true,
        title: i18nList[config.language].ok
      },
      childs: "%#ok#%",
      events: {
        click: () => {
          GM_setValue("isFirstRun", false);
          GM_setValue("version", GM_info.script.version);
          unsafeWindow.document.querySelector("#pluginOverlay")?.remove();
          editConfig.inject();
        }
      }
    });
    originalNodeAppendChild.call(unsafeWindow.document.body, renderNode({
      nodeType: "div",
      attributes: {
        id: "pluginOverlay"
      },
      childs: [{
        nodeType: "div",
        className: "main",
        childs: [{
          nodeType: "p",
          childs: i18nList[config.language].useHelpForBase
        }, {
          nodeType: "p",
          childs: "%#useHelpForInjectCheckbox#%"
        }, {
          nodeType: "p",
          childs: "%#useHelpForCheckDownloadLink#%"
        }, {
          nodeType: "p",
          childs: i18nList[config.language].useHelpForManualDownload
        }, {
          nodeType: "p",
          childs: i18nList[config.language].useHelpForBugreport
        }]
      }, {
        nodeType: "div",
        className: "checkbox-container",
        childs: {
          nodeType: "label",
          className: ["checkbox-label", "rainbow-text"],
          childs: [{
            nodeType: "input",
            className: "checkbox",
            attributes: {
              type: "checkbox",
              name: "agree-checkbox"
            },
            events: {
              change: (event) => {
                confirmButton.disabled = !event.target.checked;
              }
            }
          }, "%#alreadyKnowHowToUse#%"]
        }
      }, confirmButton]
    }));
  }
  async function main() {
    if (new Version(GM_getValue("version", "0.0.0")).compare(new Version("3.3.0")) === VersionState.Low) {
      GM_setValue("isFirstRun", true);
      alert(i18nList[config.language].configurationIncompatible);
    }
    if (GM_getValue("isFirstRun", true)) {
      firstRun();
      return;
    }
    if (new Version(GM_getValue("version", "0.0.0")).compare(new Version("3.3.22")) === VersionState.Low) {
      alert(i18nList[config.language].configurationIncompatible);
      try {
        pageStatus.suicide();
        selectList.clear();
        GM_deleteValue("selectList");
        await db.delete();
        GM_setValue("version", GM_info.script.version);
        unsafeWindow.location.reload();
      } catch (error) {
        originalConsole.error(error);
      }
      return;
    }
    if (!await check()) {
      newToast(ToastType.Info, {
        text: `%#configError#%`,
        duration: 60 * 1e3
      }).show();
      editConfig.inject();
      return;
    }
    GM_setValue("version", GM_info.script.version);
    hijackAddEventListener();
    if (config.autoInjectCheckbox) hijackNodeAppendChild();
    hijackNodeRemoveChild();
    hijackElementRemove();
    hijackStorage();
    hijackHistoryPushState();
    hijackHistoryReplaceState();
    originalAddEventListener("mouseover", (event) => {
      mouseTarget = event.target instanceof Element ? event.target : null;
    });
    originalAddEventListener("keydown", (event) => {
      const keyboardEvent = event;
      if (keyboardEvent.code === "Space" && !isNullOrUndefined(mouseTarget)) {
        let element = findElement(mouseTarget, ".videoTeaser");
        let button = element && (element.matches(".selectButton") ? element : element.querySelector(".selectButton"));
        button && button.click();
        button && keyboardEvent.preventDefault();
      }
    });
    new MutationObserver(async (m, o) => {
      if (m.some((m2) => m2.type === "childList" && unsafeWindow.document.getElementById("app"))) {
        pluginMenu.inject();
        o.disconnect();
      }
    }).observe(unsafeWindow.document.body, {
      childList: true,
      subtree: true
    });
    originalNodeAppendChild.call(unsafeWindow.document.body, watermark);
    if (isLoggedIn()) {
      let user = await (await unlimitedFetch("https://api.iwara.tv/user", {
        method: "GET",
        headers: await getAuth()
      })).json();
      let authorProfile = await db.follows.where("username").equals("dawn").first();
      if (isNullOrUndefined(authorProfile)) {
        authorProfile = (await (await unlimitedFetch("https://api.iwara.tv/profile/dawn", {
          method: "GET",
          headers: await getAuth()
        })).json()).user;
        if (user.user.id !== authorProfile.id) {
          if (!authorProfile.following) {
            unlimitedFetch(`https://api.iwara.tv/user/${authorProfile.id}/followers`, {
              method: "POST",
              headers: await getAuth()
            });
          }
          if (!authorProfile.friend) {
            unlimitedFetch(`https://api.iwara.tv/user/${authorProfile.id}/friends`, {
              method: "POST",
              headers: await getAuth()
            });
          }
        }
      }
    }
    newToast(ToastType.Info, {
      node: toastNode(i18nList[config.language].notice),
      duration: 1e4,
      gravity: "bottom",
      position: "center",
      onClick() {
        this.hide();
      }
    }).show();
  }
  if (!unsafeWindow.IwaraDownloadTool) {
    unsafeWindow.IwaraDownloadTool = true;
    if (GM_getValue("isDebug")) {
      debugger;
      unsafeWindow.pageStatus = pageStatus;
      originalConsole.debug(stringify(GM_info));
    }
    unsafeWindow.fetch = async (input, init) => {
      GM_getValue("isDebug") && originalConsole.debug(`[Debug] Fetch ${input}`);
      let url = (input instanceof Request ? input.url : input instanceof URL ? input.href : input).toURL();
      if (!isNullOrUndefined(init) && !isNullOrUndefined(init.headers)) {
        let authorization = null;
        if (init.headers instanceof Headers) {
          authorization = init.headers.has("Authorization") ? init.headers.get("Authorization") : null;
        } else {
          if (Array.isArray(init.headers)) {
            let index = init.headers.findIndex(([key, value]) => key.toLowerCase() !== "authorization");
            if (!(index < 0)) authorization = init.headers[index][1];
          } else {
            for (const key in init.headers) {
              if (key.toLowerCase() !== "authorization") continue;
              authorization = init.headers[key];
              break;
            }
          }
        }
        if (!isNullOrUndefined(authorization)) {
          let playload = getPlayload(authorization);
          let token = authorization.split(" ").pop() ?? "";
          if (playload["type"] === "refresh_token" && !token.isEmpty()) {
            localStorage.setItem("token", token);
            config.authorization = token;
            GM_getValue("isDebug") && originalConsole.debug(`[Debug] refresh_token: 凭证已隐藏`);
          }
        }
      }
      return new Promise((resolve, reject) => originalFetch(input, init).then(async (response) => {
        if (url.hostname !== "api.iwara.tv" || url.pathname.isEmpty()) return resolve(response);
        let path = url.pathname.toLowerCase().split("/").slice(1);
        switch (path[0]) {
          case "user":
            if (path[1] === "token") {
              const cloneResponse2 = response.clone();
              if (!cloneResponse2.ok) break;
              const {
                accessToken
              } = await cloneResponse2.json();
              let token = localStorage.getItem("accessToken");
              if (isNullOrUndefined(token) || token !== accessToken) localStorage.setItem("accessToken", accessToken);
            }
            break;
          case "videos":
            const cloneResponse = response.clone();
            if (!cloneResponse.ok) break;
            const cloneBody = await cloneResponse.json();
            const list = (await Promise.allSettled(cloneBody.results.map((info) => parseVideoInfo({
              Type: "cache",
              ID: info.id,
              RAW: info
            })))).filter((i) => i.status === "fulfilled").map((i) => i.value).filter((i) => i.Type === "partial" || i.Type === "full");
            const toUpdate = list.difference((await db.videos.where("ID").anyOf(list.map((v) => v.ID)).toArray()).filter((v) => v.Type === "full"), "ID");
            if (toUpdate.any()) {
              await db.videos.bulkPut(toUpdate);
            }
            if (!config.addUnlistedAndPrivate) break;
            GM_getValue("isDebug") && originalConsole.debug("[Debug]", url.searchParams);
            if (url.searchParams.has("user")) break;
            if (url.searchParams.has("subscribed")) break;
            if (url.searchParams.has("sort") ? url.searchParams.get("sort") !== "date" : false) break;
            const sortedList = list.sort((a, b) => a.UploadTime - b.UploadTime);
            const minTime = sortedList.at(0).UploadTime;
            const maxTime = sortedList.at(-1).UploadTime;
            const startTime = new Date(minTime).sub({
              hours: 4
            }).getTime();
            const endTime = new Date(maxTime).add({
              hours: 4
            }).getTime();
            const cache = (await db.getFilteredVideos(startTime, endTime)).filter((i) => i.Type === "partial" || i.Type === "full").sort((a, b) => a.UploadTime - b.UploadTime).map((i) => i.RAW);
            if (!cache.any()) break;
            cloneBody.count += cache.length;
            cloneBody.limit += cache.length;
            cloneBody.results.push(...cache);
            return resolve(new Response(JSON.stringify(cloneBody), {
              status: cloneResponse.status,
              statusText: cloneResponse.statusText,
              headers: Object.fromEntries(cloneResponse.headers.entries())
            }));
          default:
            break;
        }
        return resolve(response);
      }).catch((err) => reject(err)));
    };
    GM_getTabs((tabs) => {
      if (Object.keys(tabs).length != 1) return;
      try {
        selectList = VCSyncDictionary.load("selectList") ?? new VCSyncDictionary("selectList");
      } catch (error) {
        GM_deleteValue("selectList");
        selectList = new VCSyncDictionary("selectList");
      }
    });
    GM_addStyle(main_default);
    (unsafeWindow.document.body ? Promise.resolve() : new Promise((resolve) => originalAddEventListener.call(unsafeWindow.document, "DOMContentLoaded", resolve))).then(main);
  }
})();