text: /*
   * Copyright (c) 2019. The copyright is reserved by Ghode of Harbin Institute
   * of Technology. Users are free to copy, change or remove. Because no one
   * will read this. Only I know is that Repeaters are the best of the world.
   * Only I know is that Repeaters are the best of the world. Only I know is
   * that Repeaters are the best of the world. Maybe a long copyright text
   * seems professional. Therefore this text will be a bit lengthy. However,
   * the author seems to be afraid that one day, this text may be uploaded to
   * business projects. That is the time you can contact with author via email
   * ghode@cirnocraft.im or directly ignore this, which will be interesting.
   */
  
  (function () {
      var $D = Date;
      var lang = Date.CultureStrings ? Date.CultureStrings.lang : null;
      var loggedKeys = {}; // for debug purposes.
      var getText = {
          getFromKey: function (key, countryCode) {
              var output;
              if (Date.CultureStrings && Date.CultureStrings[countryCode] && Date.CultureStrings[countryCode][key]) {
                  output = Date.CultureStrings[countryCode][key];
              } else {
                  output = getText.buildFromDefault(key);
              }
              if (key.charAt(0) === "/") { // Assume it's a regex
                  output = getText.buildFromRegex(key, countryCode);
              }
              return output;
          },
          getFromObjectValues: function (obj, countryCode) {
              var key, output = {};
              for (key in obj) {
                  if (obj.hasOwnProperty(key)) {
                      output[key] = getText.getFromKey(obj[key], countryCode);
                  }
              }
              return output;
          },
          getFromObjectKeys: function (obj, countryCode) {
              var key, output = {};
              for (key in obj) {
                  if (obj.hasOwnProperty(key)) {
                      output[getText.getFromKey(key, countryCode)] = obj[key];
                  }
              }
              return output;
          },
          getFromArray: function (arr, countryCode) {
              var output = [];
              for (var i = 0; i < arr.length; i++) {
                  if (i in arr) {
                      output[i] = getText.getFromKey(arr[i], countryCode);
                  }
              }
              return output;
          },
          buildFromDefault: function (key) {
              var output, length, split, last;
              switch (key) {
                  case "name":
                      output = "en-US";
                      break;
                  case "englishName":
                      output = "English (United States)";
                      break;
                  case "nativeName":
                      output = "English (United States)";
                      break;
                  case "twoDigitYearMax":
                      output = 2049;
                      break;
                  case "firstDayOfWeek":
                      output = 0;
                      break;
                  default:
                      output = key;
                      split = key.split("_");
                      length = split.length;
                      if (length > 1 && key.charAt(0) !== "/") {
                          // if the key isn't a regex and it has a split.
                          last = split[(length - 1)].toLowerCase();
                          if (last === "initial" || last === "abbr") {
                              output = split[0];
                          }
                      }
                      break;
              }
              return output;
          },
          buildFromRegex: function (key, countryCode) {
              var output;
              if (Date.CultureStrings && Date.CultureStrings[countryCode] && Date.CultureStrings[countryCode][key]) {
                  output = new RegExp(Date.CultureStrings[countryCode][key], "i");
              } else {
                  output = new RegExp(key.replace(new RegExp("/", "g"), ""), "i");
              }
              return output;
          }
      };
  
      var shallowMerge = function (obj1, obj2) {
          for (var attrname in obj2) {
              if (obj2.hasOwnProperty(attrname)) {
                  obj1[attrname] = obj2[attrname];
              }
          }
      };
  
      var __ = function (key, language) {
          var countryCode = (language) ? language : lang;
          loggedKeys[key] = key;
          if (typeof key === "object") {
              if (key instanceof Array) {
                  return getText.getFromArray(key, countryCode);
              } else {
                  return getText.getFromObjectKeys(key, countryCode);
              }
          } else {
              return getText.getFromKey(key, countryCode);
          }
      };
  
      var loadI18nScript = function (code) {
          // paatterned after jQuery's getScript.
          var url = Date.Config.i18n + code + ".js";
          var head = document.getElementsByTagName("head")[0] || document.documentElement;
          var script = document.createElement("script");
          script.src = url;
  
          var completed = false;
          var events = {
              done: function () {
              } // placeholder function
          };
          // Attach handlers for all browsers
          script.onload = script.onreadystatechange = function () {
              if (!completed && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
                  events.done();
                  head.removeChild(script);
              }
          };
  
          setTimeout(function () {
              head.insertBefore(script, head.firstChild);
          }, 0); // allows return to execute first
  
          return {
              done: function (cb) {
                  events.done = function () {
                      if (cb) {
                          setTimeout(cb, 0);
                      }
                  };
              }
          };
      };
  
      var buildInfo = {
          buildFromMethodHash: function (obj) {
              var key;
              for (key in obj) {
                  if (obj.hasOwnProperty(key)) {
                      obj[key] = buildInfo[obj[key]]();
                  }
              }
              return obj;
          },
          timeZoneDST: function () {
              var DST = {
                  "CHADT": "+1345",
                  "NZDT": "+1300",
                  "AEDT": "+1100",
                  "ACDT": "+1030",
                  "AZST": "+0500",
                  "IRDT": "+0430",
                  "EEST": "+0300",
                  "CEST": "+0200",
                  "BST": "+0100",
                  "PMDT": "-0200",
                  "ADT": "-0300",
                  "NDT": "-0230",
                  "EDT": "-0400",
                  "CDT": "-0500",
                  "MDT": "-0600",
                  "PDT": "-0700",
                  "AKDT": "-0800",
                  "HADT": "-0900"
              };
              return __(DST);
          },
          timeZoneStandard: function () {
              var standard = {
                  "LINT": "+1400",
                  "TOT": "+1300",
                  "CHAST": "+1245",
                  "NZST": "+1200",
                  "NFT": "+1130",
                  "SBT": "+1100",
                  "AEST": "+1000",
                  "ACST": "+0930",
                  "JST": "+0900",
                  "CWST": "+0845",
                  "CT": "+0800",
                  "ICT": "+0700",
                  "MMT": "+0630",
                  "BST": "+0600",
                  "NPT": "+0545",
                  "IST": "+0530",
                  "PKT": "+0500",
                  "AFT": "+0430",
                  "MSK": "+0400",
                  "IRST": "+0330",
                  "FET": "+0300",
                  "EET": "+0200",
                  "CET": "+0100",
                  "GMT": "+0000",
                  "UTC": "+0000",
                  "CVT": "-0100",
                  "GST": "-0200",
                  "BRT": "-0300",
                  "NST": "-0330",
                  "AST": "-0400",
                  "EST": "-0500",
                  "CST": "-0600",
                  "MST": "-0700",
                  "PST": "-0800",
                  "AKST": "-0900",
                  "MIT": "-0930",
                  "HST": "-1000",
                  "SST": "-1100",
                  "BIT": "-1200"
              };
              return __(standard);
          },
          timeZones: function (data) {
              var zone;
              data.timezones = [];
              for (zone in data.abbreviatedTimeZoneStandard) {
                  if (data.abbreviatedTimeZoneStandard.hasOwnProperty(zone)) {
                      data.timezones.push({
                          name: zone,
                          offset: data.abbreviatedTimeZoneStandard[zone]
                      });
                  }
              }
              for (zone in data.abbreviatedTimeZoneDST) {
                  if (data.abbreviatedTimeZoneDST.hasOwnProperty(zone)) {
                      data.timezones.push({
                          name: zone,
                          offset: data.abbreviatedTimeZoneDST[zone],
                          dst: true
                      });
                  }
              }
              return data.timezones;
          },
          days: function () {
              return __(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]);
          },
          dayAbbr: function () {
              return __(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]);
          },
          dayShortNames: function () {
              return __(["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]);
          },
          dayFirstLetters: function () {
              return __(["S_Sun_Initial", "M_Mon_Initial", "T_Tues_Initial", "W_Wed_Initial", "T_Thu_Initial", "F_Fri_Initial", "S_Sat_Initial"]);
          },
          months: function () {
              return __(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]);
          },
          monthAbbr: function () {
              return __(["Jan_Abbr", "Feb_Abbr", "Mar_Abbr", "Apr_Abbr", "May_Abbr", "Jun_Abbr", "Jul_Abbr", "Aug_Abbr", "Sep_Abbr", "Oct_Abbr", "Nov_Abbr", "Dec_Abbr"]);
          },
          formatPatterns: function () {
              return getText.getFromObjectValues({
                  shortDate: "M/d/yyyy",
                  longDate: "dddd, MMMM dd, yyyy",
                  shortTime: "h:mm tt",
                  longTime: "h:mm:ss tt",
                  fullDateTime: "dddd, MMMM dd, yyyy h:mm:ss tt",
                  sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
                  universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
                  rfc1123: "ddd, dd MMM yyyy HH:mm:ss",
                  monthDay: "MMMM dd",
                  yearMonth: "MMMM, yyyy"
              }, Date.i18n.currentLanguage());
          },
          regex: function () {
              return getText.getFromObjectValues({
                  inTheMorning: "/( in the )(morn(ing)?)\\b/",
                  thisMorning: "/(this )(morn(ing)?)\\b/",
                  amThisMorning: "/(\b\\d(am)? )(this )(morn(ing)?)/",
                  inTheEvening: "/( in the )(even(ing)?)\\b/",
                  thisEvening: "/(this )(even(ing)?)\\b/",
                  pmThisEvening: "/(\b\\d(pm)? )(this )(even(ing)?)/",
                  jan: "/jan(uary)?/",
                  feb: "/feb(ruary)?/",
                  mar: "/mar(ch)?/",
                  apr: "/apr(il)?/",
                  may: "/may/",
                  jun: "/jun(e)?/",
                  jul: "/jul(y)?/",
                  aug: "/aug(ust)?/",
                  sep: "/sep(t(ember)?)?/",
                  oct: "/oct(ober)?/",
                  nov: "/nov(ember)?/",
                  dec: "/dec(ember)?/",
                  sun: "/^su(n(day)?)?/",
                  mon: "/^mo(n(day)?)?/",
                  tue: "/^tu(e(s(day)?)?)?/",
                  wed: "/^we(d(nesday)?)?/",
                  thu: "/^th(u(r(s(day)?)?)?)?/",
                  fri: "/fr(i(day)?)?/",
                  sat: "/^sa(t(urday)?)?/",
                  future: "/^next/",
                  past: "/^last|past|prev(ious)?/",
                  add: "/^(\\+|aft(er)?|from|hence)/",
                  subtract: "/^(\\-|bef(ore)?|ago)/",
                  yesterday: "/^yes(terday)?/",
                  today: "/^t(od(ay)?)?/",
                  tomorrow: "/^tom(orrow)?/",
                  now: "/^n(ow)?/",
                  millisecond: "/^ms|milli(second)?s?/",
                  second: "/^sec(ond)?s?/",
                  minute: "/^mn|min(ute)?s?/",
                  hour: "/^h(our)?s?/",
                  week: "/^w(eek)?s?/",
                  month: "/^m(onth)?s?/",
                  day: "/^d(ay)?s?/",
                  year: "/^y(ear)?s?/",
                  shortMeridian: "/^(a|p)/",
                  longMeridian: "/^(a\\.?m?\\.?|p\\.?m?\\.?)/",
                  timezone: "/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\\s*(\\+|\\-)\\s*\\d\\d\\d\\d?)|gmt|utc)/",
                  ordinalSuffix: "/^\\s*(st|nd|rd|th)/",
                  timeContext: "/^\\s*(\\:|a(?!u|p)|p)/"
              }, Date.i18n.currentLanguage());
          }
      };
  
      var CultureInfo = function () {
          var info = getText.getFromObjectValues({
              name: "name",
              englishName: "englishName",
              nativeName: "nativeName",
              amDesignator: "AM",
              pmDesignator: "PM",
              firstDayOfWeek: "firstDayOfWeek",
              twoDigitYearMax: "twoDigitYearMax",
              dateElementOrder: "mdy"
          }, Date.i18n.currentLanguage());
  
          var constructedInfo = buildInfo.buildFromMethodHash({
              dayNames: "days",
              abbreviatedDayNames: "dayAbbr",
              shortestDayNames: "dayShortNames",
              firstLetterDayNames: "dayFirstLetters",
              monthNames: "months",
              abbreviatedMonthNames: "monthAbbr",
              formatPatterns: "formatPatterns",
              regexPatterns: "regex",
              abbreviatedTimeZoneDST: "timeZoneDST",
              abbreviatedTimeZoneStandard: "timeZoneStandard"
          });
  
          shallowMerge(info, constructedInfo);
          buildInfo.timeZones(info);
          return info;
      };
  
      $D.i18n = {
          __: function (key, lang) {
              return __(key, lang);
          },
          currentLanguage: function () {
              return lang || "en-US";
          },
          setLanguage: function (code, force, cb) {
              var async = false;
              if (force || code === "en-US" || (!!Date.CultureStrings && !!Date.CultureStrings[code])) {
                  lang = code;
                  Date.CultureStrings = Date.CultureStrings || {};
                  Date.CultureStrings.lang = code;
                  Date.CultureInfo = new CultureInfo();
              } else {
                  if (!(!!Date.CultureStrings && !!Date.CultureStrings[code])) {
                      if (typeof exports !== "undefined" && this.exports !== exports) {
                          // we're in a Node enviroment, load it using require
                          try {
                              require("../i18n/" + code + ".js");
                              lang = code;
                              Date.CultureStrings.lang = code;
                              Date.CultureInfo = new CultureInfo();
                          } catch (e) {
                              // var str = "The language for '" + code + "' could not be loaded by Node. It likely does not exist.";
                              throw new Error("The DateJS IETF language tag '" + code + "' could not be loaded by Node. It likely does not exist.");
                          }
                      } else if (Date.Config && Date.Config.i18n) {
                          // we know the location of the files, so lets load them
                          async = true;
                          loadI18nScript(code).done(function () {
                              lang = code;
                              Date.CultureStrings = Date.CultureStrings || {};
                              Date.CultureStrings.lang = code;
                              Date.CultureInfo = new CultureInfo();
                              $D.Parsing.Normalizer.buildReplaceData(); // because this is async
                              if ($D.Grammar) {
                                  $D.Grammar.buildGrammarFormats(); // so we can parse those strings...
                              }
                              if (cb) {
                                  setTimeout(cb, 0);
                              }
                          });
                      } else {
                          Date.console.error("The DateJS IETF language tag '" + code + "' is not available and has not been loaded.");
                          return false;
                      }
                  }
              }
              $D.Parsing.Normalizer.buildReplaceData(); // rebuild normalizer strings
              if ($D.Grammar) {
                  $D.Grammar.buildGrammarFormats(); // so we can parse those strings...
              }
              if (!async && cb) {
                  setTimeout(cb, 0);
              }
          },
          getLoggedKeys: function () {
              return loggedKeys;
          },
          updateCultureInfo: function () {
              Date.CultureInfo = new CultureInfo();
          }
      };
      $D.i18n.updateCultureInfo(); // run automatically
  }());