FZ Tracker

Track game versions you finished playing on F95Zone.

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         FZ Tracker
// @namespace    https://f95zone.to/threads/186670/
// @version      1.2.0
// @author       feeling_blue
// @description  Track game versions you finished playing on F95Zone.
// @license      MIT
// @icon         https://external-content.duckduckgo.com/ip3/f95zone.to.ico
// @supportURL   https://f95zone.to/threads/186670/
// @match        https://f95zone.to/threads/*
// @match        https://f95zone.to/sam/latest_alpha/*
// @require      https://unpkg.com/vue@3.3.13/dist/vue.global.prod.js
// @require      https://unpkg.com/@vueuse/shared@10.7.0/index.iife.min.js
// @require      data:application/javascript,%3Bwindow.Vue%3DVue%3B
// @require      https://unpkg.com/@vueuse/core@10.7.0/index.iife.min.js
// @require      https://unpkg.com/element-plus@2.4.4/dist/index.full.min.js
// @require      https://unpkg.com/@element-plus/icons-vue@2.3.1/dist/index.iife.min.js
// @resource     element-plus/dist/index.css  https://unpkg.com/element-plus@2.4.4/dist/index.css
// @grant        GM_addStyle
// @grant        GM_getResourceText
// ==/UserScript==

(r=>{if(typeof GM_addStyle=="function"){GM_addStyle(r);return}const o=document.createElement("style");o.textContent=r,document.head.append(o)})(' html.dark{color-scheme:dark;--el-color-primary:#409eff;--el-color-primary-light-3:#3375b9;--el-color-primary-light-5:#2a598a;--el-color-primary-light-7:#213d5b;--el-color-primary-light-8:#1d3043;--el-color-primary-light-9:#18222c;--el-color-primary-dark-2:#66b1ff;--el-color-success:#67c23a;--el-color-success-light-3:#4e8e2f;--el-color-success-light-5:#3e6b27;--el-color-success-light-7:#2d481f;--el-color-success-light-8:#25371c;--el-color-success-light-9:#1c2518;--el-color-success-dark-2:#85ce61;--el-color-warning:#e6a23c;--el-color-warning-light-3:#a77730;--el-color-warning-light-5:#7d5b28;--el-color-warning-light-7:#533f20;--el-color-warning-light-8:#3e301c;--el-color-warning-light-9:#292218;--el-color-warning-dark-2:#ebb563;--el-color-danger:#f56c6c;--el-color-danger-light-3:#b25252;--el-color-danger-light-5:#854040;--el-color-danger-light-7:#582e2e;--el-color-danger-light-8:#412626;--el-color-danger-light-9:#2b1d1d;--el-color-danger-dark-2:#f78989;--el-color-error:#f56c6c;--el-color-error-light-3:#b25252;--el-color-error-light-5:#854040;--el-color-error-light-7:#582e2e;--el-color-error-light-8:#412626;--el-color-error-light-9:#2b1d1d;--el-color-error-dark-2:#f78989;--el-color-info:#909399;--el-color-info-light-3:#6b6d71;--el-color-info-light-5:#525457;--el-color-info-light-7:#393a3c;--el-color-info-light-8:#2d2d2f;--el-color-info-light-9:#202121;--el-color-info-dark-2:#a6a9ad;--el-box-shadow:0px 12px 32px 4px rgba(0, 0, 0, .36),0px 8px 20px rgba(0, 0, 0, .72);--el-box-shadow-light:0px 0px 12px rgba(0, 0, 0, .72);--el-box-shadow-lighter:0px 0px 6px rgba(0, 0, 0, .72);--el-box-shadow-dark:0px 16px 48px 16px rgba(0, 0, 0, .72),0px 12px 32px #000000,0px 8px 16px -8px #000000;--el-bg-color-page:#0a0a0a;--el-bg-color:#141414;--el-bg-color-overlay:#1d1e1f;--el-text-color-primary:#E5EAF3;--el-text-color-regular:#CFD3DC;--el-text-color-secondary:#A3A6AD;--el-text-color-placeholder:#8D9095;--el-text-color-disabled:#6C6E72;--el-border-color-darker:#636466;--el-border-color-dark:#58585B;--el-border-color:#4C4D4F;--el-border-color-light:#414243;--el-border-color-lighter:#363637;--el-border-color-extra-light:#2B2B2C;--el-fill-color-darker:#424243;--el-fill-color-dark:#39393A;--el-fill-color:#303030;--el-fill-color-light:#262727;--el-fill-color-lighter:#1D1D1D;--el-fill-color-extra-light:#191919;--el-fill-color-blank:transparent;--el-mask-color:rgba(0, 0, 0, .8);--el-mask-color-extra-light:rgba(0, 0, 0, .3)}html.dark .el-button{--el-button-disabled-text-color:rgba(255, 255, 255, .5)}html.dark .el-card{--el-card-bg-color:var(--el-bg-color-overlay)}html.dark .el-empty{--el-empty-fill-color-0:var(--el-color-black);--el-empty-fill-color-1:#4b4b52;--el-empty-fill-color-2:#36383d;--el-empty-fill-color-3:#1e1e20;--el-empty-fill-color-4:#262629;--el-empty-fill-color-5:#202124;--el-empty-fill-color-6:#212224;--el-empty-fill-color-7:#1b1c1f;--el-empty-fill-color-8:#1c1d1f;--el-empty-fill-color-9:#18181a}#--unocss--{layer:__ALL__}.el-form-item.button-group[data-v-9a23e112] .el-form-item__content{justify-content:flex-end}.fz-tracker .p-body-header{z-index:5}.fz-tracker .p-body{z-index:4}.fz-tracker .el-icon svg path{fill:currentColor}#--unocss-layer-start--__ALL__--{start:__ALL__}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.m-l-\\[10px\\]{margin-left:10px}.m-t-\\[5px\\]{margin-top:5px}.ml-4{margin-left:1rem}.inline-block{display:inline-block}[size~="20"]{width:5rem;height:5rem}[size~="35"]{width:8.75rem;height:8.75rem}.cursor-pointer{cursor:pointer}.border-rd-\\[3px\\]{border-radius:3px}.p-\\[5px\\]{padding:5px}.p-1{padding:.25rem}.p-l-\\[5px\\]{padding-left:5px}.v-middle{vertical-align:middle}.v-sub{vertical-align:sub}.text-\\[0\\.75em\\]{font-size:.75em}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\\[rgb\\(147\\,152\\,160\\)\\]{--un-text-opacity:1;color:rgb(147 152 160 / var(--un-text-opacity))}.text-\\#ec5555{--un-text-opacity:1;color:rgb(236 85 85 / var(--un-text-opacity))}.text-white{--un-text-opacity:1;color:rgb(255 255 255 / var(--un-text-opacity))}.opacity-70{opacity:.7}.hover\\:opacity-100:hover{opacity:1}.backdrop-blur-5{--un-backdrop-blur:blur(5px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}.blur{--un-blur:blur(8px);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}#--unocss-layer-end--__ALL__--{end:__ALL__} ');

(function (vue, ElementPlus, core, iconsVue) {
  'use strict';

  const cssLoader = (e) => {
    const t = GM_getResourceText(e);
    return GM_addStyle(t), t;
  };
  cssLoader("element-plus/dist/index.css");
  function gameStorageKey(gameID) {
    return `${gameID}-tracker`;
  }
  const _hoisted_1$1 = { class: "backdrop-blur-5 text-[0.75em] p-[5px] p-l-[5px] m-l-[10px] m-t-[5px] border-rd-[3px]" };
  const _sfc_main$2 = {
    __name: "LatestRecordTag",
    setup(__props) {
      const gameInfo = vue.inject("gameInfo");
      const gameData = JSON.parse(localStorage.getItem(gameStorageKey(gameInfo.ID)));
      const lastRecord = gameData.records[gameData.records.length - 1];
      const timeAgo = core.useTimeAgo(lastRecord ? lastRecord.time : null);
      let versionText = "";
      if (lastRecord && lastRecord.version !== gameInfo.version)
        versionText = `[${lastRecord.version}] `;
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, vue.toDisplayString(vue.unref(versionText)) + vue.toDisplayString(vue.unref(lastRecord) ? vue.unref(timeAgo) : ""), 1);
      };
    }
  };
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  function getDefaultExportFromCjs(x) {
    return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
  }
  var dayjs_min = { exports: {} };
  (function(module, exports) {
    !function(t, e) {
      module.exports = e();
    }(commonjsGlobal, function() {
      var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) {
        var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
        return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
      } }, m = function(t2, e2, n2) {
        var r2 = String(t2);
        return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
      }, v = { s: m, z: function(t2) {
        var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
        return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
      }, m: function t2(e2, n2) {
        if (e2.date() < n2.date())
          return -t2(n2, e2);
        var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c);
        return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
      }, a: function(t2) {
        return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
      }, p: function(t2) {
        return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
      }, u: function(t2) {
        return void 0 === t2;
      } }, g = "en", D = {};
      D[g] = M;
      var p = "$isDayjsObject", S = function(t2) {
        return t2 instanceof _ || !(!t2 || !t2[p]);
      }, w = function t2(e2, n2, r2) {
        var i2;
        if (!e2)
          return g;
        if ("string" == typeof e2) {
          var s2 = e2.toLowerCase();
          D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
          var u2 = e2.split("-");
          if (!i2 && u2.length > 1)
            return t2(u2[0]);
        } else {
          var a2 = e2.name;
          D[a2] = e2, i2 = a2;
        }
        return !r2 && i2 && (g = i2), i2 || !r2 && g;
      }, O = function(t2, e2) {
        if (S(t2))
          return t2.clone();
        var n2 = "object" == typeof e2 ? e2 : {};
        return n2.date = t2, n2.args = arguments, new _(n2);
      }, b = v;
      b.l = w, b.i = S, b.w = function(t2, e2) {
        return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
      };
      var _ = function() {
        function M2(t2) {
          this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
        }
        var m2 = M2.prototype;
        return m2.parse = function(t2) {
          this.$d = function(t3) {
            var e2 = t3.date, n2 = t3.utc;
            if (null === e2)
              return /* @__PURE__ */ new Date(NaN);
            if (b.u(e2))
              return /* @__PURE__ */ new Date();
            if (e2 instanceof Date)
              return new Date(e2);
            if ("string" == typeof e2 && !/Z$/i.test(e2)) {
              var r2 = e2.match($);
              if (r2) {
                var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
                return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
              }
            }
            return new Date(e2);
          }(t2), this.init();
        }, m2.init = function() {
          var t2 = this.$d;
          this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
        }, m2.$utils = function() {
          return b;
        }, m2.isValid = function() {
          return !(this.$d.toString() === l);
        }, m2.isSame = function(t2, e2) {
          var n2 = O(t2);
          return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
        }, m2.isAfter = function(t2, e2) {
          return O(t2) < this.startOf(e2);
        }, m2.isBefore = function(t2, e2) {
          return this.endOf(e2) < O(t2);
        }, m2.$g = function(t2, e2, n2) {
          return b.u(t2) ? this[e2] : this.set(n2, t2);
        }, m2.unix = function() {
          return Math.floor(this.valueOf() / 1e3);
        }, m2.valueOf = function() {
          return this.$d.getTime();
        }, m2.startOf = function(t2, e2) {
          var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
            var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
            return r2 ? i2 : i2.endOf(a);
          }, $2 = function(t3, e3) {
            return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
          }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
          switch (f2) {
            case h:
              return r2 ? l2(1, 0) : l2(31, 11);
            case c:
              return r2 ? l2(1, M3) : l2(0, M3 + 1);
            case o:
              var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
              return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
            case a:
            case d:
              return $2(v2 + "Hours", 0);
            case u:
              return $2(v2 + "Minutes", 1);
            case s:
              return $2(v2 + "Seconds", 2);
            case i:
              return $2(v2 + "Milliseconds", 3);
            default:
              return this.clone();
          }
        }, m2.endOf = function(t2) {
          return this.startOf(t2, false);
        }, m2.$set = function(t2, e2) {
          var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2;
          if (o2 === c || o2 === h) {
            var y2 = this.clone().set(d, 1);
            y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
          } else
            l2 && this.$d[l2]($2);
          return this.init(), this;
        }, m2.set = function(t2, e2) {
          return this.clone().$set(t2, e2);
        }, m2.get = function(t2) {
          return this[b.p(t2)]();
        }, m2.add = function(r2, f2) {
          var d2, l2 = this;
          r2 = Number(r2);
          var $2 = b.p(f2), y2 = function(t2) {
            var e2 = O(l2);
            return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
          };
          if ($2 === c)
            return this.set(c, this.$M + r2);
          if ($2 === h)
            return this.set(h, this.$y + r2);
          if ($2 === a)
            return y2(1);
          if ($2 === o)
            return y2(7);
          var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
          return b.w(m3, this);
        }, m2.subtract = function(t2, e2) {
          return this.add(-1 * t2, e2);
        }, m2.format = function(t2) {
          var e2 = this, n2 = this.$locale();
          if (!this.isValid())
            return n2.invalidDate || l;
          var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) {
            return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
          }, d2 = function(t3) {
            return b.s(s2 % 12 || 12, t3, "0");
          }, $2 = f2 || function(t3, e3, n3) {
            var r3 = t3 < 12 ? "AM" : "PM";
            return n3 ? r3.toLowerCase() : r3;
          };
          return r2.replace(y, function(t3, r3) {
            return r3 || function(t4) {
              switch (t4) {
                case "YY":
                  return String(e2.$y).slice(-2);
                case "YYYY":
                  return b.s(e2.$y, 4, "0");
                case "M":
                  return a2 + 1;
                case "MM":
                  return b.s(a2 + 1, 2, "0");
                case "MMM":
                  return h2(n2.monthsShort, a2, c2, 3);
                case "MMMM":
                  return h2(c2, a2);
                case "D":
                  return e2.$D;
                case "DD":
                  return b.s(e2.$D, 2, "0");
                case "d":
                  return String(e2.$W);
                case "dd":
                  return h2(n2.weekdaysMin, e2.$W, o2, 2);
                case "ddd":
                  return h2(n2.weekdaysShort, e2.$W, o2, 3);
                case "dddd":
                  return o2[e2.$W];
                case "H":
                  return String(s2);
                case "HH":
                  return b.s(s2, 2, "0");
                case "h":
                  return d2(1);
                case "hh":
                  return d2(2);
                case "a":
                  return $2(s2, u2, true);
                case "A":
                  return $2(s2, u2, false);
                case "m":
                  return String(u2);
                case "mm":
                  return b.s(u2, 2, "0");
                case "s":
                  return String(e2.$s);
                case "ss":
                  return b.s(e2.$s, 2, "0");
                case "SSS":
                  return b.s(e2.$ms, 3, "0");
                case "Z":
                  return i2;
              }
              return null;
            }(t3) || i2.replace(":", "");
          });
        }, m2.utcOffset = function() {
          return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
        }, m2.diff = function(r2, d2, l2) {
          var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
            return b.m(y2, m3);
          };
          switch (M3) {
            case h:
              $2 = D2() / 12;
              break;
            case c:
              $2 = D2();
              break;
            case f:
              $2 = D2() / 3;
              break;
            case o:
              $2 = (g2 - v2) / 6048e5;
              break;
            case a:
              $2 = (g2 - v2) / 864e5;
              break;
            case u:
              $2 = g2 / n;
              break;
            case s:
              $2 = g2 / e;
              break;
            case i:
              $2 = g2 / t;
              break;
            default:
              $2 = g2;
          }
          return l2 ? $2 : b.a($2);
        }, m2.daysInMonth = function() {
          return this.endOf(c).$D;
        }, m2.$locale = function() {
          return D[this.$L];
        }, m2.locale = function(t2, e2) {
          if (!t2)
            return this.$L;
          var n2 = this.clone(), r2 = w(t2, e2, true);
          return r2 && (n2.$L = r2), n2;
        }, m2.clone = function() {
          return b.w(this.$d, this);
        }, m2.toDate = function() {
          return new Date(this.valueOf());
        }, m2.toJSON = function() {
          return this.isValid() ? this.toISOString() : null;
        }, m2.toISOString = function() {
          return this.$d.toISOString();
        }, m2.toString = function() {
          return this.$d.toUTCString();
        }, M2;
      }(), k = _.prototype;
      return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
        k[t2[1]] = function(e2) {
          return this.$g(e2, t2[0], t2[1]);
        };
      }), O.extend = function(t2, e2) {
        return t2.$i || (t2(e2, _, O), t2.$i = true), O;
      }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
        return O(1e3 * t2);
      }, O.en = D[g], O.Ls = D, O.p = {}, O;
    });
  })(dayjs_min);
  var dayjs_minExports = dayjs_min.exports;
  const dayjs = /* @__PURE__ */ getDefaultExportFromCjs(dayjs_minExports);
  const trackerVersion = "1.2.0";
  const _export_sfc = (sfc, props) => {
    const target = sfc.__vccOpts || sfc;
    for (const [key, val] of props) {
      target[key] = val;
    }
    return target;
  };
  const _hoisted_1 = {
    key: 0,
    class: "text-2xl"
  };
  const _sfc_main$1 = {
    __name: "VersionTracker",
    setup(__props) {
      const gameInfo = vue.inject("gameInfo");
      const gameData = core.useLocalStorage(
        gameStorageKey(gameInfo.ID),
        {
          name: gameInfo.name,
          author: gameInfo.author,
          records: [],
          trackerVersion
        },
        {
          deep: true,
          listenToStorageChanges: true
        }
      );
      for (const prop of ["name", "author", "scriptVersion"]) {
        if (gameData.value[prop] !== gameInfo[prop]) {
          gameData.value[prop] = gameInfo[prop];
        }
      }
      const checked = vue.computed({
        get() {
          return gameData.value.records.some((record) => record.version === gameInfo.version);
        },
        set(newVal) {
          if (newVal)
            addRecord(gameInfo);
          else
            removeRecord(gameInfo);
        }
      });
      const lastRecord = vue.computed(() => {
        const records = gameData.value.records;
        if (records.length > 0) {
          return records[records.length - 1];
        }
        return null;
      });
      const lastRecordTime = vue.computed(() => {
        if (lastRecord.value) {
          return lastRecord.value.time;
        }
        return null;
      });
      const timeAgo = core.useTimeAgo(lastRecordTime);
      const lastPlayedText = vue.computed(() => {
        if (!lastRecord.value)
          return "";
        const lastRecordVersion = lastRecord.value.version;
        if (lastRecordVersion === gameInfo.version) {
          return "Finished ";
        } else {
          return `Finished [${lastRecordVersion}] `;
        }
      });
      const removeFlagConfirmVisible = vue.ref(false);
      function handleFlagClick() {
        if (checked.value) {
          removeFlagConfirmVisible.value = true;
        } else {
          checked.value = true;
        }
      }
      const form = vue.reactive({
        version: "",
        date: ""
      });
      const rules = vue.reactive({
        version: [
          {
            required: true,
            message: "Please input version",
            trigger: "blur"
          },
          {
            min: 1,
            max: 30,
            message: "Length should be 1 to 30",
            trigger: "blur"
          },
          {
            validator: (rule, value, callback) => {
              if (gameData.value.records.some((record) => record.version === value)) {
                callback(new Error(`[${value}] already recorded`));
              } else {
                callback();
              }
            },
            trigger: "blur"
          }
        ],
        date: [
          {
            type: "date",
            required: true,
            message: "Please pick a date",
            trigger: "change"
          }
        ]
      });
      const formRef = vue.ref(null);
      const popoverVisible = vue.ref(false);
      const onSubmit = () => {
        formRef.value.validate().then(() => {
          addRecord({
            version: form.version,
            time: form.date.getTime()
          });
          popoverVisible.value = false;
          form.version = "";
          form.date = "";
        }).catch(() => {
        });
      };
      const popoverCommonProps = {
        effect: "light",
        teleported: false,
        placement: "bottom"
      };
      function addRecord({ version, time }) {
        time = time || Date.now();
        gameData.value.records.push({
          version,
          time
        });
        gameData.value.records.sort((a, b) => a.time - b.time);
      }
      function removeRecord({ version }) {
        gameData.value.records = gameData.value.records.filter((record) => record.version !== version);
      }
      function formatTime(time) {
        if (dayjs(time).hour() === 0 && dayjs(time).minute() === 0 && dayjs(time).second() === 0) {
          return dayjs(time).format("YYYY-MM-DD");
        } else {
          return dayjs(time).format("YYYY-MM-DD HH:mm:ss");
        }
      }
      return (_ctx, _cache) => {
        const _component_el_icon = vue.resolveComponent("el-icon");
        const _component_el_popconfirm = vue.resolveComponent("el-popconfirm");
        const _component_el_tooltip = vue.resolveComponent("el-tooltip");
        const _component_el_input = vue.resolveComponent("el-input");
        const _component_el_form_item = vue.resolveComponent("el-form-item");
        const _component_el_date_picker = vue.resolveComponent("el-date-picker");
        const _component_el_button = vue.resolveComponent("el-button");
        const _component_el_form = vue.resolveComponent("el-form");
        const _component_el_popover = vue.resolveComponent("el-popover");
        const _component_el_table_column = vue.resolveComponent("el-table-column");
        const _component_el_table = vue.resolveComponent("el-table");
        return vue.openBlock(), vue.createElementBlock("span", null, [
          vue.createVNode(_component_el_popconfirm, vue.mergeProps({ visible: vue.unref(removeFlagConfirmVisible) }, popoverCommonProps, {
            width: "350",
            "confirm-button-text": "OK",
            "cancel-button-text": "Cancel",
            title: "Remove flag and delete corresponding record?",
            onConfirm: _cache[0] || (_cache[0] = ($event) => removeFlagConfirmVisible.value = checked.value = false),
            onCancel: _cache[1] || (_cache[1] = ($event) => removeFlagConfirmVisible.value = false)
          }), {
            reference: vue.withCtx(() => [
              vue.createElementVNode("span", {
                class: vue.normalizeClass(["p-1 inline-block cursor-pointer v-sub", vue.unref(checked) ? "text-#ec5555" : "text-[rgb(147,152,160)]"])
              }, [
                vue.createVNode(_component_el_icon, {
                  size: 35,
                  onClick: handleFlagClick
                }, {
                  default: vue.withCtx(() => [
                    vue.createVNode(vue.unref(iconsVue.Flag))
                  ]),
                  _: 1
                })
              ], 2)
            ]),
            _: 1
          }, 16, ["visible"]),
          vue.unref(lastPlayedText) ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1, [
            vue.createTextVNode(vue.toDisplayString(vue.unref(lastPlayedText)) + " ", 1),
            vue.createVNode(_component_el_tooltip, vue.mergeProps(popoverCommonProps, {
              content: formatTime(vue.unref(lastRecordTime))
            }), {
              default: vue.withCtx(() => [
                vue.createElementVNode("span", null, vue.toDisplayString(vue.unref(timeAgo)), 1)
              ]),
              _: 1
            }, 16, ["content"])
          ])) : vue.createCommentVNode("", true),
          vue.createVNode(_component_el_popover, vue.mergeProps(popoverCommonProps, {
            visible: vue.unref(popoverVisible),
            width: 350,
            trigger: "click"
          }), {
            reference: vue.withCtx(() => [
              vue.createVNode(_component_el_icon, {
                size: 20,
                class: "v-middle ml-4 cursor-pointer text-white opacity-70 hover:opacity-100"
              }, {
                default: vue.withCtx(() => [
                  vue.createVNode(vue.unref(iconsVue.CirclePlusFilled), {
                    onClick: _cache[2] || (_cache[2] = ($event) => popoverVisible.value = true)
                  })
                ]),
                _: 1
              })
            ]),
            default: vue.withCtx(() => [
              vue.createVNode(_component_el_form, {
                ref_key: "formRef",
                ref: formRef,
                "label-width": "130px",
                rules: vue.unref(rules),
                model: vue.unref(form)
              }, {
                default: vue.withCtx(() => [
                  vue.createVNode(_component_el_form_item, {
                    label: "Finished Version",
                    prop: "version"
                  }, {
                    default: vue.withCtx(() => [
                      vue.createVNode(_component_el_input, {
                        modelValue: vue.unref(form).version,
                        "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(form).version = $event)
                      }, null, 8, ["modelValue"])
                    ]),
                    _: 1
                  }),
                  vue.createVNode(_component_el_form_item, {
                    label: "Finished Time",
                    prop: "date"
                  }, {
                    default: vue.withCtx(() => [
                      vue.createVNode(_component_el_date_picker, {
                        modelValue: vue.unref(form).date,
                        "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(form).date = $event),
                        teleported: false,
                        "data-popper-placement": "bottom",
                        type: "date",
                        placeholder: "Pick a date",
                        style: { "width": "100%" }
                      }, null, 8, ["modelValue"])
                    ]),
                    _: 1
                  }),
                  vue.createVNode(_component_el_form_item, { class: "button-group" }, {
                    default: vue.withCtx(() => [
                      vue.createVNode(_component_el_button, {
                        size: "small",
                        onClick: _cache[5] || (_cache[5] = ($event) => popoverVisible.value = false)
                      }, {
                        default: vue.withCtx(() => [
                          vue.createTextVNode("Cancel")
                        ]),
                        _: 1
                      }),
                      vue.createVNode(_component_el_button, {
                        size: "small",
                        type: "primary",
                        onClick: onSubmit
                      }, {
                        default: vue.withCtx(() => [
                          vue.createTextVNode("Create")
                        ]),
                        _: 1
                      })
                    ]),
                    _: 1
                  })
                ]),
                _: 1
              }, 8, ["rules", "model"])
            ]),
            _: 1
          }, 16, ["visible"]),
          vue.createVNode(_component_el_popover, vue.mergeProps(popoverCommonProps, {
            width: 500,
            trigger: "click"
          }), {
            reference: vue.withCtx(() => [
              vue.createVNode(_component_el_icon, {
                size: 20,
                class: "v-middle ml-4 cursor-pointer text-white opacity-70 hover:opacity-100"
              }, {
                default: vue.withCtx(() => [
                  vue.createVNode(vue.unref(iconsVue.Document), {
                    onClick: ($event) => 1
                  })
                ]),
                _: 1
              })
            ]),
            default: vue.withCtx(() => [
              vue.createVNode(_component_el_table, {
                data: vue.unref(gameData).records,
                "default-sort": { prop: "time", order: "descending" }
              }, {
                default: vue.withCtx(() => [
                  vue.createVNode(_component_el_table_column, {
                    "min-width": "120",
                    property: "version",
                    label: "Version"
                  }),
                  vue.createVNode(_component_el_table_column, {
                    sortable: "",
                    "min-width": "150",
                    property: "time",
                    label: "Time"
                  }, {
                    default: vue.withCtx(({ row }) => [
                      vue.createTextVNode(vue.toDisplayString(formatTime(row.time)), 1)
                    ]),
                    _: 1
                  }),
                  vue.createVNode(_component_el_table_column, {
                    "min-width": "100",
                    label: "Operations"
                  }, {
                    default: vue.withCtx(({ row }) => [
                      vue.createVNode(_component_el_button, {
                        size: "small",
                        type: "danger",
                        onClick: ($event) => removeRecord(row)
                      }, {
                        default: vue.withCtx(() => [
                          vue.createTextVNode(" Delete ")
                        ]),
                        _: 2
                      }, 1032, ["onClick"])
                    ]),
                    _: 1
                  })
                ]),
                _: 1
              }, 8, ["data"])
            ]),
            _: 1
          }, 16)
        ]);
      };
    }
  };
  const VersionTracker = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-9a23e112"]]);
  const _sfc_main = {
    __name: "App",
    setup(__props) {
      const titleElement2 = vue.inject("titleElement");
      document.documentElement.classList.add("fz-tracker");
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Teleport, { to: vue.unref(titleElement2) }, [
          vue.createVNode(VersionTracker)
        ], 8, ["to"]);
      };
    }
  };
  document.documentElement.classList.add("dark");
  const titleElement = document.querySelector(".p-title-value");
  const isGamePage = (() => {
    const breadcrumbUl = document.querySelector("ul.p-breadcrumbs");
    if (breadcrumbUl) {
      const breadcrumbs = [...breadcrumbUl.querySelectorAll(":scope > li")];
      return breadcrumbs.length === 3 && breadcrumbs[2].innerText.trim().toLowerCase().includes("games");
    }
    return false;
  })();
  const isLatestUpdatesPage = window.location.pathname.startsWith("/sam/latest_alpha");
  if (isGamePage) {
    const gameInfo = titleElement ? (() => {
      const titleText = [...titleElement.childNodes].find((node) => node.nodeType === Node.TEXT_NODE).textContent.trim();
      const matches = titleText.match(/^(.*?)\s*\[(.*?)\]\s*\[(.*?)\]$/);
      if (matches && matches.length === 4) {
        const ID = window.location.pathname.split("/")[2].split(".")[1];
        return {
          ID,
          name: matches[1],
          version: matches[2],
          author: matches[3]
        };
      }
    })() : null;
    if (gameInfo) {
      const appEl = document.createElement("div");
      document.body.append(appEl);
      vue.createApp(_sfc_main).use(ElementPlus).provide("gameInfo", gameInfo).provide("titleElement", titleElement).mount(appEl);
    }
  } else if (isLatestUpdatesPage) {
    const gameCardListEl = document.querySelector("#latest-page_items-wrap_inner");
    if (gameCardListEl) {
      gameCardListEl.querySelectorAll("[data-thread-id]").forEach(mountTag);
      core.useMutationObserver(
        gameCardListEl,
        (mutations) => {
          mutations.filter((mutation) => mutation.type === "childList" && mutation.addedNodes.length > 0).map((mutation) => [...mutation.addedNodes]).flat().forEach(mountTag);
        },
        { childList: true }
      );
    }
  }
  function mountTag(gameInfoEl) {
    const gameInfo = {
      ID: parseInt(gameInfoEl.getAttribute("data-thread-id"), 10),
      name: gameInfoEl.querySelector(".resource-tile_info-header_title").textContent.trim(),
      version: gameInfoEl.querySelector(".resource-tile_label-version").textContent.trim(),
      author: gameInfoEl.querySelector(".resource-tile_dev").textContent.trim()
    };
    if (localStorage.getItem(gameStorageKey(gameInfo.ID))) {
      const tageContainer = document.createElement("div");
      Object.assign(tageContainer.style, {
        position: "absolute",
        left: 0,
        top: 0
      });
      gameInfoEl.append(tageContainer);
      vue.createApp(_sfc_main$2).provide("gameInfo", gameInfo).mount(tageContainer);
    }
  }

})(Vue, ElementPlus, VueUse, ElementPlusIconsVue);