Greasy Fork

来自缓存

Greasy Fork is available in English.

POE流放之路网页市集插件

市集一些优化

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         POE流放之路网页市集插件
// @namespace    http://tampermonkey.net/
// @version      2.0.1
// @author       rxdey
// @description  市集一些优化
// @license      MIT
// @icon         https://poe.game.qq.com/favicon.ico
// @match        https://poe.game.qq.com/trade/*
// @match        https://apps.game.qq.com/poe/a20160407LoginCheck/loginsuccess.html
// @require      https://unpkg.com/[email protected]/dist/db.global.js
// @require      data:application/javascript,window.CnPoeExportDb%3DCnPoeExportDb
// @require      https://unpkg.com/[email protected]/dist/vue.global.prod.js
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

(r=>{if(typeof GM_addStyle=="function"){GM_addStyle(r);return}const t=document.createElement("style");t.textContent=r,document.head.append(t)})(' .d-button[data-v-91a14c1a]{--b-color: rgba(var(--color-white));--b-size: 12px;border:1px solid var(--b-border);background-color:var(--b-type);color:var(--b-color);padding-bottom:var(--b-size);padding-top:var(--b-size)}.d-button[data-v-91a14c1a]:active,.d-button[data-v-91a14c1a]:hover{background-color:var(--b-active)}.d-button.disabled[data-v-91a14c1a]{opacity:.5;cursor:not-allowed}.d-button.disabled[data-v-91a14c1a]:active,.d-button.disabled[data-v-91a14c1a]:hover{background-color:var(--b-type)}*,: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: }.uno-6a64nq{position:fixed;bottom:5px;left:5px;z-index:2000;display:flex;flex-direction:row;gap:4px}.uno-cwirjq{position:absolute;left:50%;bottom:100%;display:none;flex-direction:column;--un-translate-x:-50%;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));align-items:center;justify-content:center;background-color:#000000e6}.uno-d54z7h{position:absolute;bottom:100%;left:0;z-index:1;margin-bottom:4px;width:100%;display:flex;flex-direction:column;gap:2px}.uno-hbwt5n{position:fixed;left:50%;top:30%;z-index:1000;z-index:2001;min-width:400px;transform-origin:left center;--un-translate-x:-50%;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));--un-translate-y:0;border-radius:12px;--un-bg-opacity:1;background-color:rgb(var(--color-white) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-dark) / var(--un-text-opacity))}.uno-j2fx0m{position:fixed;bottom:0;left:0;right:0;top:0;z-index:200;background-color:#0000004d}.uno-kdj5ae{position:relative;height:40px;display:flex;flex-direction:row;align-items:center;border-bottom-width:1px;border-left-width:0px;border-right-width:0px;border-top-width:0px;--un-border-opacity:1;border-color:rgb(229 229 229 / var(--un-border-opacity));border-style:solid;padding-left:8px;padding-right:0}.uno-l9jv7r{position:absolute;bottom:100%;left:0;z-index:1;margin-bottom:4px;max-height:600px;width:100%;display:flex;flex-direction:column;gap:4px;overflow-y:auto}.uno-n727xu{position:relative;display:flex;flex-direction:row;align-items:center;justify-content:center;border-style:none;padding-left:16px;padding-right:16px;font-size:14px;line-height:1;outline:2px solid transparent;outline-offset:2px;transition:all .3s linear}.uno-ni5pzh{position:fixed;left:50%;top:30%;z-index:101;z-index:3001;min-width:350px;transform-origin:left center;--un-translate-x:-50%;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));--un-translate-y:0;border-radius:12px;--un-bg-opacity:1;background-color:rgb(var(--color-white) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-dark) / var(--un-text-opacity))}.uno-pjhpbh{position:relative;margin-top:10px;display:inline-block;cursor:pointer;padding-top:10px;font-size:12px;line-height:1;--un-text-opacity:1;color:rgb(var(--foreground) / var(--un-text-opacity))}.uno-y292xp{position:relative}.uno-kdj5ae:after{position:absolute;bottom:-1px;left:0;height:2px;width:0;--un-bg-opacity:1;background-color:rgb(var(--color-primary) / var(--un-bg-opacity));content:"";transition:all .3s linear}.uno-8ut93f{z-index:2;width:120px}.uno-k9nrt0{z-index:2;width:150px}.uno-36f1r2{margin-bottom:20px;display:flex;flex-direction:row;gap:10px}.uno-5mgg2s{margin-left:10px;display:flex;flex-direction:row;align-items:center;justify-content:center;--un-text-opacity:1;color:rgb(var(--color-white) / var(--un-text-opacity))}.uno-kzvvcj{margin-bottom:20px}.uno-v15f5i{margin-right:12px;font-size:20px}.uno-xy2f5e{margin-bottom:20px;display:flex;flex-direction:row;justify-content:flex-end;gap:10px}.uno-0aac7g{width:100%;height:100%}.uno-4f0c85{width:100%;height:100%;border-style:none;background-color:transparent;color:inherit;outline:2px solid transparent;outline-offset:2px}.uno-bmns78{min-width:60px;--un-text-opacity:1;color:rgb(var(--color-primary) / var(--un-text-opacity))}.uno-je4uyi{min-width:0;flex:1 1 0%;padding-left:8px;padding-right:8px}.uno-lnbmsj{min-width:120px}.uno-suerow{width:100%;resize:none;border-style:none;background-color:transparent;--un-text-opacity:1;color:rgb(var(--foreground) / var(--un-text-opacity));outline:2px solid transparent;outline-offset:2px}.uno-9b57t1{display:flex;flex-direction:row;justify-content:space-between;padding:20px 20px 10px}.uno-weqgrm{display:flex;flex-direction:row;cursor:pointer;--un-bg-opacity:1;background-color:rgb(var(--background) / var(--un-bg-opacity));padding:6px 8px;--un-text-opacity:1;color:rgb(var(--foreground) / var(--un-text-opacity))}.uno-xzlctu{display:flex;flex-direction:row;justify-content:flex-end;gap:10px;padding:10px 20px 20px}.group:hover .uno-cwirjq{display:flex}.uno-2x98nu{flex:1 1 0%;word-break:break-all}.uno-yqud7r{flex:1 1 0%;--un-bg-opacity:1;background-color:rgb(var(--background) / var(--un-bg-opacity));padding:4px}.uno-5i3h1r{cursor:pointer}.uno-f70hor{cursor:pointer;--un-bg-opacity:1;background-color:rgb(var(--color-blue) / var(--un-bg-opacity));padding:4px 8px;--un-text-opacity:1;color:rgb(var(--foreground) / var(--un-text-opacity))}.uno-q3uz8k{padding:20px}.uno-j8124d{font-size:18px;line-height:1}.uno-m8p83r,.uno-m8p83r:visited{--un-text-opacity:1;color:rgb(56 189 248 / var(--un-text-opacity))}.uno-2x98nu:hover{--un-text-opacity:1;color:rgb(var(--color-white) / var(--un-text-opacity))}.uno-gd7xcy:hover{--un-text-opacity:1;color:rgb(var(--color-danger) / var(--un-text-opacity))}.uno-m8p83r:hover{--un-text-opacity:1;color:rgb(56 189 248 / var(--un-text-opacity))}.visible{visibility:visible}.block{display:block}.w-full{width:100%}.after\\:w-100\\%:after{width:100%}.border{border-width:1px}.rounded-full{border-radius:9999px}.ps{padding-inline-start:4px}.outline{outline-style:solid}:root{--color-primary: 155 86 252;--color-success: 48 150 48;--color-info: 28 177 249;--color-warning: 255 178 2;--color-danger: 217 83 79;--color-brown: 90 56 6;--color-blue: 15 48 77;--color-black: 0 0 0;--color-dark: 30 33 36;--color-white: 255 255 255;--color-gray: 153 153 153;--foreground: 226 226 226;--background: 30 33 36;--btn-blue-border: 76 76 125;--btn-brown-border: 138 86 9}.scale-up-enter-active,.scale-up-leave-active{transition:all .3s ease}.scale-up-enter-from,.scale-up-leave-to{scale:.5;opacity:0;transform:translateY(0) translate(-50%)}.slider-enter-active,.slider-leave-active{transition:all .3s linear}.slider-enter-from,.slider-leave-to{opacity:0;transform:translateY(100%)}.fade-enter-active,.fade-leave-active{transition:all .3s linear}.fade-enter-from,.fade-leave-to{opacity:0}.scroll-bar::-webkit-scrollbar{width:3px}.scroll-bar::-webkit-scrollbar-thumb{background:#555454;border-radius:3px} ');

(function (vue) {
  'use strict';

  var _monkeyWindow = /* @__PURE__ */ (() => window)();
  class AttributeProvider {
    constructor(attrList) {
      this.attrIndexedByZhName = /* @__PURE__ */ new Map();
      for (const p of attrList) {
        const zh = p.zh;
        this.attrIndexedByZhName.set(zh, p);
      }
    }
    provideAttribute(zhName) {
      return this.attrIndexedByZhName.get(zhName);
    }
  }
  class BaseTypeProvider {
    constructor(baseTypesList) {
      var _a, _b;
      this.baseTypesIndexedByZh = /* @__PURE__ */ new Map();
      this.baseTypesIndexedByUniqueZh = /* @__PURE__ */ new Map();
      for (const baseTypeList of baseTypesList) {
        for (const baseType of baseTypeList) {
          const zh = baseType.zh;
          if (this.baseTypesIndexedByZh.has(zh)) {
            (_a = this.baseTypesIndexedByZh.get(zh)) === null || _a === void 0 ? void 0 : _a.push(baseType);
          } else {
            this.baseTypesIndexedByZh.set(zh, [baseType]);
          }
          const uniques = baseType.uniques;
          if (uniques !== void 0) {
            for (const unique of uniques) {
              const zh2 = unique.zh;
              if (zh2 in this.baseTypesIndexedByUniqueZh) {
                (_b = this.baseTypesIndexedByUniqueZh.get(zh2)) === null || _b === void 0 ? void 0 : _b.push(baseType);
              } else {
                this.baseTypesIndexedByUniqueZh.set(zh2, [baseType]);
              }
            }
          }
        }
      }
    }
    provideBaseTypesByZh(zh) {
      const entries = this.baseTypesIndexedByZh.get(zh);
      return entries;
    }
  }
  class GemProvider {
    constructor(gems, hybridSkills) {
      this.skillsIndexedByZh = /* @__PURE__ */ new Map();
      for (const gem of gems) {
        this.skillsIndexedByZh.set(gem.zh, gem);
      }
      for (const skill of hybridSkills) {
        this.skillsIndexedByZh.set(skill.zh, skill);
      }
    }
    provideSkill(zh) {
      return this.skillsIndexedByZh.get(zh);
    }
  }
  class PassiveSkillProvider {
    constructor(notables, keystones, ascendants) {
      this.notablesIndexedByZh = /* @__PURE__ */ new Map();
      this.keystonesIndexedByZh = /* @__PURE__ */ new Map();
      this.ascendantIndexedByZh = /* @__PURE__ */ new Map();
      for (const node of notables) {
        this.notablesIndexedByZh.set(node.zh, node);
      }
      for (const node of keystones) {
        this.keystonesIndexedByZh.set(node.zh, node);
      }
      for (const node of ascendants) {
        this.ascendantIndexedByZh.set(node.zh, node);
      }
    }
    provideNotableByZh(zhName) {
      return this.notablesIndexedByZh.get(zhName);
    }
    provideKeystoneByZh(zhName) {
      return this.keystonesIndexedByZh.get(zhName);
    }
    provideAscendantByZh(zhName) {
      return this.ascendantIndexedByZh.get(zhName);
    }
  }
  function escapeRegExp(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  }
  class StatUtil {
    static getBodyOfZhTemplate(template) {
      return this.getNonAsciiOrPer(template);
    }
    static getBodyOfZhModifier(mod) {
      return this.getNonAsciiOrPer(mod);
    }
    static getNonAsciiOrPer(str) {
      return str.replace(/[\u{0000}-\u{0024}\u{0026}-\u{007F}]/gu, "");
    }
    static render(enTemplate, zhTemplate, zhMod) {
      if (zhMod === zhTemplate) {
        return enTemplate;
      }
      const enTmpl = new Template(enTemplate);
      const zhTmpl = new Template(zhTemplate);
      const params = zhTmpl.parseParams(zhMod);
      if (params === void 0) {
        return void 0;
      }
      return enTmpl.render(params);
    }
  }
  class Template {
    constructor(text) {
      this.text = text;
      this.segments = [];
      this.paramNumbers = [];
      let j = 0;
      let k = 0;
      let onParam = false;
      for (let i = 0; i < text.length; i++) {
        const code = text.charCodeAt(i);
        if (code === 123) {
          k = i;
          onParam = true;
        } else if (code === 125) {
          if (onParam) {
            this.segments.push(text.slice(j, k));
            this.paramNumbers.push(Number.parseInt(text.slice(k + 1, i + 1)));
            j = i + 1;
            onParam = false;
          }
        } else {
          if (onParam) {
            if (code < 48 || code > 57) {
              onParam = false;
            }
          }
        }
      }
      this.segments.push(text.slice(j));
    }
    /**
     * parseParams parses the modifier and returns positional parameters.
     * @param modifier rendered template result with params
     * @returns map contains positions and parameters ; undefined if the modifier does not match the template.
     */
    parseParams(modifier) {
      const regStr = `^${this.segments.map((s) => escapeRegExp(s)).join("(\\S+)")}$`;
      const execResult = new RegExp(regStr).exec(modifier);
      if (!execResult) {
        return void 0;
      }
      const paramList = execResult.slice(1, this.paramNumbers.length + 1);
      const paramMap = /* @__PURE__ */ new Map();
      for (const [i, num] of this.paramNumbers.entries()) {
        paramMap.set(num, paramList[i]);
      }
      return paramMap;
    }
    /**
     * Render template by positional params.
     * @param params positional parameters
     */
    render(params) {
      const buf = new Array(this.segments.length + this.paramNumbers.length);
      let j = 0;
      for (let i = 0; i < this.paramNumbers.length; i++) {
        buf[j++] = this.segments[i];
        const paramValue = params.get(this.paramNumbers[i]);
        buf[j++] = paramValue ? paramValue : `{${i}}`;
      }
      buf[j] = this.segments[this.segments.length - 1];
      return buf.join("");
    }
  }
  const VARIABLE_MARK = "{0}";
  class PropertyProvider {
    constructor(propertyList) {
      this.propertyIndexedByZhName = /* @__PURE__ */ new Map();
      this.variablePropertyIndexedByZhBody = /* @__PURE__ */ new Map();
      for (const p of propertyList) {
        const zh = p.zh;
        this.propertyIndexedByZhName.set(zh, p);
        if (zh.includes(VARIABLE_MARK)) {
          this.variablePropertyIndexedByZhBody.set(StatUtil.getBodyOfZhTemplate(zh), p);
        }
      }
    }
    provideProperty(zhName) {
      return this.propertyIndexedByZhName.get(zhName);
    }
    provideVariablePropertyByZhBody(zhBody) {
      return this.variablePropertyIndexedByZhBody.get(zhBody);
    }
  }
  class RequirementProvider {
    constructor(requirementList, suffixList) {
      this.requirementsIndexedByZh = /* @__PURE__ */ new Map();
      this.suffixesIndexedByZh = /* @__PURE__ */ new Map();
      for (const r of requirementList) {
        const zh = r.zh;
        this.requirementsIndexedByZh.set(zh, r);
      }
      for (const s of suffixList) {
        const zh = s.zh;
        this.suffixesIndexedByZh.set(zh, s);
      }
    }
    provideRequirement(zh) {
      return this.requirementsIndexedByZh.get(zh);
    }
    provideSuffix(zh) {
      return this.suffixesIndexedByZh.get(zh);
    }
  }
  const COMPOUNDED_STAT_LINE_SEPARATOR = "\n";
  class StatProvider {
    constructor(statList) {
      this.statsIndexedByZhBody = /* @__PURE__ */ new Map();
      this.compoundedStatsIndexedByFirstLinesZhBody = /* @__PURE__ */ new Map();
      for (const stat of statList) {
        const zh = stat.zh;
        const body = StatUtil.getBodyOfZhTemplate(zh);
        if (this.statsIndexedByZhBody.has(body)) {
          const array = this.statsIndexedByZhBody.get(body);
          array.push(stat);
        } else {
          this.statsIndexedByZhBody.set(body, [stat]);
        }
        if (zh.includes(COMPOUNDED_STAT_LINE_SEPARATOR)) {
          const lines = zh.split(COMPOUNDED_STAT_LINE_SEPARATOR);
          const firstLine = lines[0];
          const firstLineBody = StatUtil.getBodyOfZhTemplate(firstLine);
          const value = this.compoundedStatsIndexedByFirstLinesZhBody.get(firstLineBody);
          const compoundedStat = { lineSize: lines.length, stat };
          if (value === void 0) {
            this.compoundedStatsIndexedByFirstLinesZhBody.set(firstLineBody, {
              maxLineSize: lines.length,
              stats: [compoundedStat]
            });
          } else {
            if (value.maxLineSize < lines.length) {
              value.maxLineSize = lines.length;
            }
            value.stats.push(compoundedStat);
          }
        }
      }
      for (const value of this.compoundedStatsIndexedByFirstLinesZhBody.values()) {
        if (value.stats.length > 1) {
          value.stats.sort((a, b) => b.lineSize - a.lineSize);
        }
      }
    }
    provideStatsByZhBody(zhBody) {
      return this.statsIndexedByZhBody.get(zhBody);
    }
    provideCompoundedStatsByFirstLinesZhBody(body) {
      return this.compoundedStatsIndexedByFirstLinesZhBody.get(body);
    }
  }
  class AttributeService {
    constructor(attrProvider) {
      this.attrProvider = attrProvider;
    }
    translatePair(zhName, zhValue) {
      return this.doTranslate(zhName, zhValue);
    }
    translateName(zhName) {
      const result = this.doTranslate(zhName, void 0);
      if (result !== void 0) {
        return result.name;
      }
    }
    doTranslate(zhName, zhValue) {
      const attr = this.attrProvider.provideAttribute(zhName);
      if (attr !== void 0) {
        const enName = attr.en;
        if (zhValue !== void 0 && attr.values !== void 0) {
          for (const v of attr.values) {
            if (zhValue === v.zh) {
              return {
                name: enName,
                value: v.en
              };
            }
          }
        }
        return {
          name: enName,
          value: void 0
        };
      }
    }
  }
  const ZH_SUPERIOR_PREFIX = "精良的 ";
  const SUPERIOR_PREFIX = "Superior ";
  const ZH_SYNTHESISED_PREFIX = "忆境 ";
  const SYNTHESISED_PREFIX = "Synthesised ";
  class BaseTypeService {
    constructor(baseTypeProvider) {
      this.baseTypeProvider = baseTypeProvider;
    }
    /**
     *
     * @param zhName item's zh name.
     * There may be duplicate zh baseTypes, uniques's zh name can help translating.
     */
    getBaseTypeByZh(zh, zhName) {
      const list = this.baseTypeProvider.provideBaseTypesByZh(zh);
      if (list === void 0) {
        return void 0;
      }
      if (list.length === 1 || zhName === void 0) {
        return list[0];
      }
      for (const b of list) {
        if (b.uniques !== void 0) {
          for (const unique of b.uniques) {
            if (unique.zh === zhName) {
              return b;
            }
          }
        }
      }
      return list[0];
    }
    /**
     * Infer the zh base type by zh base type line, and returns the matched BaseType.
     *
     * @param zhName item's zh name. There may be duplicate zh baseTypes, uniques's zh name can help translating.
     */
    getBaseTypeByZhTypeLine(zhTypeLine, zhName) {
      if (zhTypeLine.startsWith(ZH_SUPERIOR_PREFIX)) {
        zhTypeLine = zhTypeLine.substring(ZH_SUPERIOR_PREFIX.length);
      }
      if (zhTypeLine.startsWith(ZH_SYNTHESISED_PREFIX)) {
        zhTypeLine = zhTypeLine.substring(ZH_SYNTHESISED_PREFIX.length);
      }
      const b = this.getBaseTypeByZh(zhTypeLine, zhName);
      if (b !== void 0) {
        return { baseType: b, zhBaseType: zhTypeLine };
      }
      const pattern = /.+?[之的]/gu;
      if (pattern.test(zhTypeLine)) {
        pattern.lastIndex = 0;
        const len = zhTypeLine.length;
        let slices = [];
        let lastIndex = 0;
        while (lastIndex < len) {
          const matches = pattern.exec(zhTypeLine);
          if (matches) {
            const result = matches[0];
            slices.push(result);
            lastIndex = pattern.lastIndex;
          } else {
            if (lastIndex < len) {
              slices.push(zhTypeLine.substring(lastIndex));
            }
            break;
          }
        }
        for (let i = slices.length; i > 0; i--) {
          const possible = slices.join();
          const b2 = this.getBaseTypeByZh(possible, zhName);
          if (b2 !== void 0) {
            return { baseType: b2, zhBaseType: possible };
          }
          slices = slices.slice(1);
        }
      }
      return void 0;
    }
    translateBaseType(zhBaseType, zhName) {
      const b = this.getBaseTypeByZh(zhBaseType, zhName);
      if (b !== void 0) {
        return b.en;
      }
      return void 0;
    }
    /**
     * 一般情况下,物品的typeLine等价于baseType。魔法物品有所不同,其在baseType的基础上多了一堆修饰词前缀。
     *
     * 修饰词的翻译很麻烦,且用处不大,这里选择去掉修饰词,仅保留baseType。
     *
     * 推荐使用baseType替换typeLine,只有在翻译文本格式的物品时,因为缺乏baseType,需要调用该方法。
     * @param zhTypeLine
     * @param zhName
     */
    translateTypeLine(zhTypeLine, zhName) {
      if (zhTypeLine.startsWith(ZH_SUPERIOR_PREFIX)) {
        const t = this.translateTypeLine(zhTypeLine.substring(ZH_SUPERIOR_PREFIX.length), zhName);
        if (t !== void 0) {
          return SUPERIOR_PREFIX + t;
        }
        return void 0;
      }
      if (zhTypeLine.startsWith(ZH_SYNTHESISED_PREFIX)) {
        const t = this.translateTypeLine(zhTypeLine.substring(ZH_SYNTHESISED_PREFIX.length), zhName);
        if (t !== void 0) {
          return SYNTHESISED_PREFIX + t;
        }
        return void 0;
      }
      const b = this.getBaseTypeByZhTypeLine(zhTypeLine, zhName);
      if (b !== void 0) {
        return b.baseType.en;
      }
      return void 0;
    }
  }
  const PROPERTY_NAMES = /* @__PURE__ */ new Map([
    ["等级", "Level"],
    ["品质", "Quality"]
  ]);
  class GemService {
    constructor(gemProvider) {
      this.gemProvider = gemProvider;
    }
    formatGemZh(zh) {
      return zh.replace("(", "(").replace(")", ")");
    }
    translateBaseType(zhBaseType) {
      var _a;
      return (_a = this.gemProvider.provideSkill(this.formatGemZh(zhBaseType))) === null || _a === void 0 ? void 0 : _a.en;
    }
    translateTypeLine(zhTypeLine) {
      let zhSkill = zhTypeLine;
      const skill = this.translateBaseType(zhSkill);
      return skill !== void 0 ? `${skill}` : void 0;
    }
    translatePropertyName(zhName) {
      if (PROPERTY_NAMES.has(zhName)) {
        return PROPERTY_NAMES.get(zhName);
      }
      return void 0;
    }
  }
  const DEFAULT_NAME = "Item";
  class ItemService {
    constructor(baseTypeProvider) {
      this.baseTypeProvider = baseTypeProvider;
    }
    /**
     * Translate item name, but only unique name is supported.
     *
     * @returns DEFAULT_NAME if no unique with the zhName.
     */
    translateName(zhName, zhBaseType) {
      const baseTypes = this.baseTypeProvider.provideBaseTypesByZh(zhBaseType);
      if (baseTypes !== void 0) {
        for (const baseType of baseTypes) {
          const uniques = baseType.uniques;
          if (uniques !== void 0) {
            for (const unique of uniques) {
              if (unique.zh === zhName) {
                return unique.en;
              }
            }
          }
        }
      }
      return DEFAULT_NAME;
    }
  }
  class PassiveSkillService {
    constructor(passiveSkillProvider) {
      this.passiveSkillProvider = passiveSkillProvider;
    }
    translateNotable(zh) {
      const node = this.passiveSkillProvider.provideNotableByZh(zh);
      if (node !== void 0) {
        return node.en;
      }
      return void 0;
    }
    translateKeystone(zh) {
      const node = this.passiveSkillProvider.provideKeystoneByZh(zh);
      if (node !== void 0) {
        return node.en;
      }
      return void 0;
    }
    translateAscendant(zh) {
      const node = this.passiveSkillProvider.provideAscendantByZh(zh);
      if (node !== void 0) {
        return node.en;
      }
      return void 0;
    }
  }
  class PropertyService {
    constructor(propProvider) {
      this.propProvider = propProvider;
    }
    translate(zhName, zhValue) {
      const prop = this.propProvider.provideProperty(zhName);
      if (prop !== void 0) {
        if (prop.values !== void 0) {
          for (const v of prop.values) {
            if (zhValue === v.zh) {
              return {
                name: prop.en,
                value: v.en
              };
            }
          }
        }
        return {
          name: prop.en
        };
      }
      return void 0;
    }
    translateName(zhName) {
      let prop = this.propProvider.provideProperty(zhName);
      if (prop !== void 0) {
        return prop.en;
      }
      prop = this.propProvider.provideVariablePropertyByZhBody(StatUtil.getBodyOfZhModifier(zhName));
      if (prop !== void 0) {
        const zhTmpl = new Template(prop.zh);
        const posParams = zhTmpl.parseParams(zhName);
        if (posParams === void 0) {
          return void 0;
        }
        const enTmpl = new Template(prop.en);
        return enTmpl.render(posParams);
      }
      return void 0;
    }
  }
  class RequirementService {
    constructor(requirementProvider) {
      this.requirementProvider = requirementProvider;
    }
    translate(zhName, zhValue) {
      const r = this.requirementProvider.provideRequirement(zhName);
      if (r) {
        if (r.values) {
          for (const v of r.values) {
            if (v.zh === zhValue) {
              return { name: r.en, value: v.en };
            }
          }
        }
        return {
          name: r.en
        };
      }
    }
    translateName(zhName) {
      const r = this.requirementProvider.provideRequirement(zhName);
      if (r) {
        return r.en;
      }
    }
    translateSuffix(zhSuffix) {
      const suffix = this.requirementProvider.provideSuffix(zhSuffix);
      if (suffix) {
        return suffix.en;
      }
    }
  }
  const ZH_ANOINTED_MOD_REGEXP = /^配置 (.+)$/;
  const ZH_FORBIDDEN_FLESH_MOD_REGEXP = /^禁断之火上有匹配的词缀则配置 (.+)$/;
  const ZH_FORBIDDEN_FLAME_MOD_REGEXP = /^禁断之肉上有匹配的词缀则配置 (.+)$/;
  const ZH_UNIQUE_ENEMY_IN_YOUR_PRESENCE = "有一个传奇怪物出现在你面前:";
  const EN_UNIQUE_ENEMY_IN_YOUR_PRESENCE = "While a Unique Enemy is in your Presence, ";
  const ZH_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE = "有一个异界图鉴最终首领出现在你面前:";
  const EN_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE = "While a Pinnacle Atlas Boss is in your Presence, ";
  class StatService {
    constructor(passiveSkillService, statProvider) {
      this.passiveSkillService = passiveSkillService;
      this.statProvider = statProvider;
    }
    translateMod(zhMod) {
      if (this.isAnointedMod(zhMod)) {
        return this.translateAnointedMod(zhMod);
      }
      if (this.isForbiddenFlameMod(zhMod)) {
        return this.translateForbiddenFlameMod(zhMod);
      }
      if (this.isForbiddenFleshMod(zhMod)) {
        return this.translateForbiddenFleshMod(zhMod);
      }
      if (this.isEldritchImplicitMod(zhMod)) {
        return this.translateEldritchImplicitMod(zhMod);
      }
      return this.translateModInner(zhMod);
    }
    translateModInner(zhMod) {
      const body = StatUtil.getBodyOfZhModifier(zhMod);
      const stats = this.statProvider.provideStatsByZhBody(body);
      if (stats !== void 0) {
        for (const stat of stats) {
          const result = this.doTranslateMod(stat, zhMod);
          if (result !== void 0) {
            return result;
          }
        }
      }
      return void 0;
    }
    isAnointedMod(zhMod) {
      return ZH_ANOINTED_MOD_REGEXP.test(zhMod);
    }
    translateAnointedMod(zhMod) {
      const matches = ZH_ANOINTED_MOD_REGEXP.exec(zhMod);
      if (matches !== null) {
        const zhNotable = matches[1];
        const notable = this.passiveSkillService.translateNotable(zhNotable);
        if (notable !== void 0) {
          return `Allocates ${notable}`;
        }
      }
      return void 0;
    }
    isForbiddenFlameMod(zhMod) {
      return ZH_FORBIDDEN_FLAME_MOD_REGEXP.test(zhMod);
    }
    translateForbiddenFlameMod(zhMod) {
      const matches = ZH_FORBIDDEN_FLAME_MOD_REGEXP.exec(zhMod);
      if (matches !== null) {
        const zhAscendant = matches[1];
        const ascendant = this.passiveSkillService.translateAscendant(zhAscendant);
        if (ascendant !== void 0) {
          return `Allocates ${ascendant} if you have the matching modifier on Forbidden Flesh`;
        }
      }
      return void 0;
    }
    isForbiddenFleshMod(zhMod) {
      return ZH_FORBIDDEN_FLESH_MOD_REGEXP.test(zhMod);
    }
    translateForbiddenFleshMod(zhMod) {
      const matches = ZH_FORBIDDEN_FLESH_MOD_REGEXP.exec(zhMod);
      if (matches !== null) {
        const zhAscendant = matches[1];
        const ascendant = this.passiveSkillService.translateAscendant(zhAscendant);
        if (ascendant !== void 0) {
          return `Allocates ${ascendant} if you have the matching modifier on Forbidden Flame`;
        }
      }
      return void 0;
    }
    isEldritchImplicitMod(zhMod) {
      return zhMod.startsWith(ZH_UNIQUE_ENEMY_IN_YOUR_PRESENCE) || zhMod.startsWith(ZH_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE);
    }
    translateEldritchImplicitMod(zhMod) {
      if (zhMod.startsWith(ZH_UNIQUE_ENEMY_IN_YOUR_PRESENCE)) {
        const subMod = this.translateMod(zhMod.substring(ZH_UNIQUE_ENEMY_IN_YOUR_PRESENCE.length));
        if (subMod !== void 0) {
          return EN_UNIQUE_ENEMY_IN_YOUR_PRESENCE + subMod;
        }
      } else if (zhMod.startsWith(ZH_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE)) {
        const subMod = this.translateMod(zhMod.substring(ZH_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE.length));
        if (subMod !== void 0) {
          return EN_PINNACLE_ATLAS_BOSS_IN_YOUR_PRESENCE + subMod;
        }
      }
      return void 0;
    }
    doTranslateMod(stat, zhMod) {
      if (zhMod === stat.zh) {
        return stat.en;
      }
      const zhTmpl = new Template(stat.zh);
      const posParams = zhTmpl.parseParams(zhMod);
      if (posParams === void 0) {
        return void 0;
      }
      const enTmpl = new Template(stat.en);
      return enTmpl.render(posParams);
    }
    getMaxLineSizeOfCompoundedMod(firstLine) {
      const body = StatUtil.getBodyOfZhModifier(firstLine);
      const entry = this.statProvider.provideCompoundedStatsByFirstLinesZhBody(body);
      if (entry !== void 0) {
        return entry.maxLineSize;
      }
      return 0;
    }
    /**
     * Translate compounded mod for text item.
     *
     * Caller should use `getMaxLineSizeOfCompoundedMod` before to get the max lines of candidates which has the first line.
     *
     * The method uses the `lines` to infer a compounded mod, returns the translation.
     */
    translateCompoundedMod(lines) {
      const body = StatUtil.getBodyOfZhModifier(lines[0]);
      const entry = this.statProvider.provideCompoundedStatsByFirstLinesZhBody(body);
      if (entry === void 0) {
        return;
      }
      for (const compoundedStat of entry.stats) {
        const lineSize = compoundedStat.lineSize;
        if (compoundedStat.lineSize > lines.length) {
          continue;
        }
        const stat = compoundedStat.stat;
        const mod = lines.slice(0, lineSize).join(COMPOUNDED_STAT_LINE_SEPARATOR);
        if (StatUtil.getBodyOfZhTemplate(stat.zh) === StatUtil.getBodyOfZhModifier(mod)) {
          const result = this.doTranslateMod(stat, mod);
          if (result !== void 0) {
            return {
              result,
              lineSize
            };
          }
        }
      }
      return void 0;
    }
  }
  const ZH_PROPERTY_NAME_LIMITED_TO = "仅限";
  const ZH_PROPERTY_NAME_RADIUS = "范围";
  const ZH_REQUIREMENT_NAME_CLASS = "职业:";
  const ZH_THIEF_TRINKET = "赏金猎人饰品";
  const ZH_FORBIDDEN_FLESH = "禁断之肉";
  const ZH_FORBIDDEN_FLAME = "禁断之火";
  const ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN = "暗影";
  const ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN_FIXED = "暗影(贵族)";
  const ZH_CLASS_SCION = "贵族";
  class JsonTranslator {
    constructor(baseTypeService, itemService, requirementService, propertyService, gemService, statService, passiveSkillService) {
      this.baseTypeService = baseTypeService;
      this.itemService = itemService;
      this.requirementService = requirementService;
      this.propertyService = propertyService;
      this.gemService = gemService;
      this.statService = statService;
      this.passiveSkillService = passiveSkillService;
    }
    preHandleItem(item) {
      if (item.name && (item.name === ZH_FORBIDDEN_FLAME || item.name === ZH_FORBIDDEN_FLESH)) {
        if (item.requirements) {
          for (const requirement of item.requirements) {
            const name = requirement.name;
            if (name !== ZH_REQUIREMENT_NAME_CLASS) {
              continue;
            }
            const value = requirement.values[0][0];
            if (value === ZH_CLASS_SCION) {
              if (item.explicitMods) {
                for (let i = 0; i < item.explicitMods.length; i++) {
                  const zhStat = item.explicitMods[i];
                  if (zhStat.endsWith(ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN)) {
                    item.explicitMods[i] = zhStat.replace(ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN, ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN_FIXED);
                  }
                }
              }
            }
            break;
          }
        }
      }
    }
    translateItems(data) {
      const items = data.items;
      const translatedItems = [];
      for (const item of items) {
        if (this.isPobItem(item)) {
          this.translateItem(item);
          translatedItems.push(item);
        }
      }
      data.items = translatedItems;
      return data;
    }
    isPobItem(item) {
      if (item.inventoryId === "MainInventory" || item.inventoryId === "ExpandedMainInventory" || item.baseType === ZH_THIEF_TRINKET) {
        return false;
      }
      return true;
    }
    translateItem(item) {
      this.preHandleItem(item);
      const zhBaseType = item.baseType;
      const zhName = item.name;
      const zhTypeLine = item.typeLine;
      if (zhName) {
        const res = this.itemService.translateName(zhName, zhBaseType);
        if (res) {
          item.name = res;
        } else {
          console.log(`warning: should be translated: item name, ${zhName}`);
        }
      }
      if (zhBaseType) {
        const res = this.baseTypeService.translateBaseType(zhBaseType, zhName);
        if (res) {
          item.baseType = res;
        } else {
          console.log(`warning: should be translated: base type, ${zhBaseType}`);
        }
      }
      if (zhTypeLine) {
        item.typeLine = item.baseType;
      }
      if (item.requirements) {
        for (const r of item.requirements) {
          const zhName2 = r.name;
          const res = this.requirementService.translateName(zhName2);
          if (res) {
            r.name = res;
          } else {
            console.log(`warning: should be translated: requirement name, ${zhName2}`);
          }
          if (zhName2 === ZH_REQUIREMENT_NAME_CLASS) {
            if (r.values) {
              for (const v of r.values) {
                const zhValue = v[0];
                const result = this.requirementService.translate(zhName2, zhValue);
                if (result && result.value) {
                  v[0] = result.value;
                } else {
                  console.log(`warning: should be translated: requirement value, ${zhValue}`);
                }
              }
            }
          }
          if (r.suffix) {
            const zhSuffix = r.suffix;
            const res2 = this.requirementService.translateSuffix(zhSuffix);
            if (res2) {
              r.suffix = res2;
            } else {
              console.log(`warning: should be translated: requirement suffix, ${zhSuffix}`);
            }
          }
        }
      }
      if (item.properties) {
        for (const p of item.properties) {
          const zhName2 = p.name;
          const enName = this.propertyService.translateName(zhName2);
          if (enName) {
            p.name = enName;
          } else {
            console.log(`warning: should be translated: property name, ${zhName2}`);
          }
          if (zhName2 === ZH_PROPERTY_NAME_LIMITED_TO || zhName2 === ZH_PROPERTY_NAME_RADIUS) {
            if (p.values) {
              for (const v of p.values) {
                const zhValue = v[0];
                const res = this.propertyService.translate(zhName2, zhValue);
                if (res) {
                  v[0] = res.value;
                } else {
                  console.log(`warning: should be translated: property value, ${zhValue}`);
                }
              }
            }
          }
        }
      }
      if (item.socketedItems) {
        for (const si of item.socketedItems) {
          if (si.abyssJewel) {
            this.translateItem(si);
          } else {
            this.translateGem(si);
          }
        }
      }
      if (item.enchantMods) {
        for (let i = 0; i < item.enchantMods.length; i++) {
          const zhStat = item.enchantMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.enchantMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.explicitMods) {
        for (let i = 0; i < item.explicitMods.length; i++) {
          const zhStat = item.explicitMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.explicitMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.implicitMods) {
        for (let i = 0; i < item.implicitMods.length; i++) {
          const zhStat = item.implicitMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.implicitMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.craftedMods) {
        for (let i = 0; i < item.craftedMods.length; i++) {
          const zhStat = item.craftedMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.craftedMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.utilityMods) {
        for (let i = 0; i < item.utilityMods.length; i++) {
          const zhStat = item.utilityMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.utilityMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.fracturedMods) {
        for (let i = 0; i < item.fracturedMods.length; i++) {
          const zhStat = item.fracturedMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.fracturedMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.scourgeMods) {
        for (let i = 0; i < item.scourgeMods.length; i++) {
          const zhStat = item.scourgeMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.scourgeMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
      if (item.crucibleMods) {
        for (let i = 0; i < item.crucibleMods.length; i++) {
          const zhStat = item.crucibleMods[i];
          const res = this.statService.translateMod(zhStat);
          if (res) {
            item.crucibleMods[i] = res;
          } else {
            console.log(`warning: should be translated: stat: ${zhStat}`);
          }
        }
      }
    }
    translateGem(item) {
      const zhBaseType = item.baseType;
      const zhTypeLine = item.typeLine;
      if (zhBaseType) {
        const res = this.gemService.translateBaseType(zhBaseType);
        if (res) {
          item.baseType = res;
        } else {
          console.log(`warning: should be translated: gem base type: ${zhBaseType}`);
        }
      }
      if (zhTypeLine) {
        const res = this.gemService.translateTypeLine(zhTypeLine);
        if (res) {
          item.typeLine = res;
        } else {
          console.log(`warning: should be translated: gem type line: ${zhTypeLine}`);
        }
      }
      if (item.hybrid) {
        item.hybrid.baseTypeName = this.gemService.translateTypeLine(item.hybrid.baseTypeName);
      }
      if (item.properties) {
        for (const p of item.properties) {
          const res = this.gemService.translatePropertyName(p.name);
          if (res) {
            p.name = res;
          }
        }
      }
    }
    translatePassiveSkills(data) {
      if (data.items) {
        for (const item of data.items) {
          this.translateItem(item);
        }
      }
      if (data.skill_overrides) {
        for (const [key, value] of Object.entries(data.skill_overrides)) {
          if (value.name) {
            const name = value.name;
            if (value.isKeystone) {
              const result = this.passiveSkillService.translateKeystone(name);
              if (result !== void 0) {
                value.name = result;
              } else {
                console.log(`warning: should be translated: keystone, ${name}`);
              }
            } else {
              const result = this.baseTypeService.translateBaseType(name, void 0);
              if (result !== void 0) {
                value.name = result;
              } else {
                console.log(`warning: should be translated: base type, ${name}`);
              }
            }
          }
          if (value.stats) {
            const stats = value.stats;
            for (let i = 0; i < stats.length; i++) {
              const stat = stats[i];
              const result = this.statService.translateMod(stat);
              if (result !== void 0) {
                stats[i] = result;
              } else {
                console.log(`warning: should be translated: stat: ${stat}`);
              }
            }
          }
        }
      }
    }
  }
  class TextTranslator {
    constructor(baseTypeService, itemService, requirementService, propertyService, gemService, statService, attributeService) {
      this.baseTypeService = baseTypeService;
      this.itemService = itemService;
      this.requirementService = requirementService;
      this.propertyService = propertyService;
      this.gemService = gemService;
      this.statService = statService;
      this.attributeService = attributeService;
    }
    translate(content) {
      const item = new TextItem(this.fixChineseTextError(content));
      const ctx = new Context();
      ctx.translator = this;
      return item.getTranslation(ctx);
    }
    // Fix Chinese translation error
    fixChineseTextError(content) {
      if (content.includes(ZH_FORBIDDEN_FLESH) || content.includes(ZH_FORBIDDEN_FLAME)) {
        if (content.includes(ZH_CLASS_SCION)) {
          content = content.replace(ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN, ZH_PASSIVE_SKILL_ASCENDANT_ASSASSIN_FIXED);
        }
      }
      return content;
    }
  }
  class Context {
  }
  const PART_SEPARATOR = "\n--------\n";
  const LINE_SEPARATOR = "\n";
  const KEY_VALUE_SEPARATOR = ": ";
  const ZH_ITEM_CLASS = "物品类别";
  class TextItem {
    constructor(content) {
      const partsContents = content.split(PART_SEPARATOR);
      this.parts = partsContents.map((partContent) => {
        if (partContent.startsWith(ZH_ITEM_CLASS)) {
          return new MetaPart(partContent);
        }
        return new Part(partContent);
      });
    }
    getTranslation(ctx) {
      ctx.item = this;
      return this.parts.map((part) => part.getTranslation(ctx)).join(PART_SEPARATOR);
    }
  }
  class Part {
    constructor(content) {
      const linesContents = content.split(LINE_SEPARATOR);
      this.lines = linesContents.map((lineContent) => Line.NewLine(lineContent));
    }
    getTranslation(ctx) {
      ctx.part = this;
      const translator = ctx.translator;
      const buf = [];
      for (let i = 0; i < this.lines.length; ) {
        const line = this.lines[i];
        const maxSize = translator.statService.getMaxLineSizeOfCompoundedMod(line.content);
        if (maxSize > 0) {
          const mod = this.lines.slice(i, Math.min(i + maxSize, this.lines.length));
          const translation = translator.statService.translateCompoundedMod(mod.map((line2) => line2 instanceof ModifierLine ? line2.modifier : line2.content));
          if (translation !== void 0) {
            buf.push(this.fillSuffixesOfCompoundedModTranslation(mod, translation.result));
            i += translation.lineSize;
            continue;
          }
        }
        buf.push(line.getTranslation(ctx));
        i++;
      }
      return buf.join(LINE_SEPARATOR);
    }
    fillSuffixesOfCompoundedModTranslation(mod, translation) {
      const slices = translation.split(COMPOUNDED_STAT_LINE_SEPARATOR);
      const buf = [];
      for (const [i, slice] of slices.entries()) {
        const sub = mod[i];
        if (sub instanceof ModifierLine && sub.suffix) {
          buf.push(`${slice} ${sub.suffix}`);
        } else {
          buf.push(slice);
        }
      }
      return buf.join(COMPOUNDED_STAT_LINE_SEPARATOR);
    }
  }
  class MetaPart extends Part {
    getTranslation(ctx) {
      ctx.part = this;
      const translator = ctx.translator;
      const buf = [];
      for (let i = 0; i < this.lines.length; i++) {
        const line = this.lines[i];
        if (this.isNameLine(i)) {
          const zhName = line.content;
          const zhTypeLine = this.lines[this.lines.length - 1].content;
          const result = translator.baseTypeService.getBaseTypeByZhTypeLine(zhTypeLine, zhName);
          buf.push(translator.itemService.translateName(zhName, result !== void 0 ? result.zhBaseType : zhTypeLine));
        } else if (this.isTypeLine(i)) {
          const t = translator.baseTypeService.translateTypeLine(line.content);
          buf.push(t !== void 0 ? t : line.content);
        } else {
          buf.push(line.getTranslation(ctx));
        }
      }
      return buf.join(LINE_SEPARATOR);
    }
    isNameLine(lineNum) {
      return lineNum === this.lines.length - 2 && this.lines[lineNum] instanceof ModifierLine;
    }
    isTypeLine(lineNum) {
      return lineNum === this.lines.length - 1 && this.lines[lineNum] instanceof ModifierLine;
    }
  }
  class Line {
    constructor(content) {
      this.content = content;
    }
    static NewLine(content) {
      if (content.includes(KEY_VALUE_SEPARATOR)) {
        const pair = content.split(KEY_VALUE_SEPARATOR);
        if (pair.length !== 2) {
          return new ModifierLine(content);
        } else {
          return new KeyValueLine(content, pair[0], pair[1]);
        }
      } else if (content.endsWith(":")) {
        return new OnlyKeyLine(content);
      } else {
        return new ModifierLine(content);
      }
    }
    getTranslation(ctx) {
      return this.content;
    }
  }
  class KeyValueLine extends Line {
    constructor(content, key, value) {
      super(content);
      this.key = key;
      this.value = value;
    }
    getTranslation(ctx) {
      const translator = ctx.translator;
      let translation = translator.propertyService.translate(this.key, this.value);
      if (translation !== void 0) {
        let key = this.key;
        if (translation.name) {
          key = translation.name;
        }
        let value = this.value;
        if (translation.value) {
          value = translation.value;
        }
        return `${key}${KEY_VALUE_SEPARATOR}${value}`;
      }
      translation = translator.requirementService.translate(this.key, this.value);
      if (translation !== void 0) {
        const key = translation.name;
        const value = translation.value;
        return `${key ? key : this.key}${KEY_VALUE_SEPARATOR}${value ? value : this.value}`;
      }
      translation = translator.attributeService.translatePair(this.key, this.value);
      if (translation !== void 0) {
        if (translation.name) {
          this.key = translation.name;
        }
        if (translation.value) {
          this.value = translation.value;
        }
      }
      return `${this.key}${KEY_VALUE_SEPARATOR}${this.value}`;
    }
  }
  class OnlyKeyLine extends Line {
    constructor(content) {
      super(content);
      this.key = content.substring(0, content.length - 1);
    }
    getTranslation(ctx) {
      const translator = ctx.translator;
      let translation = translator.propertyService.translateName(this.key);
      if (translation !== void 0) {
        return `${translation}${KEY_VALUE_SEPARATOR}`;
      }
      translation = translator.attributeService.translateName(this.key);
      if (translation !== void 0) {
        return `${translation}${KEY_VALUE_SEPARATOR}`;
      }
      return `${this.key}${KEY_VALUE_SEPARATOR}`;
    }
  }
  class ModifierLine extends Line {
    constructor(content) {
      super(content);
      const pattern = new RegExp("(.+)\\s(\\(\\w+\\))$");
      const match = pattern.exec(content);
      if (match !== null) {
        this.modifier = match[1];
        this.suffix = match[2];
      } else {
        this.modifier = content;
      }
    }
    getTranslation(ctx) {
      const translator = ctx.translator;
      let translation = translator.statService.translateMod(this.modifier);
      if (translation !== void 0) {
        if (this.suffix) {
          return `${translation} ${this.suffix}`;
        }
        return translation;
      }
      translation = translator.propertyService.translateName(this.modifier);
      if (translation !== void 0) {
        return translation;
      }
      translation = translator.attributeService.translateName(this.modifier);
      if (translation !== void 0) {
        return translation;
      }
      return this.content;
    }
  }
  class TranslatorFactory {
  }
  class BasicTranslatorFactory extends TranslatorFactory {
    constructor(assets) {
      super();
      const baseTypesList = [
        assets.amulets,
        assets.belts,
        assets.rings,
        assets.bodyArmours,
        assets.boots,
        assets.gloves,
        assets.helmets,
        assets.quivers,
        assets.shields,
        assets.flasks,
        assets.jewels,
        assets.weapons,
        assets.tattoos
      ];
      const baseTypeProvider = new BaseTypeProvider(baseTypesList);
      this.baseTypeService = new BaseTypeService(baseTypeProvider);
      this.itemService = new ItemService(baseTypeProvider);
      const requirementProvider = new RequirementProvider(assets.requirements, assets.requirementSuffixes);
      this.requirementService = new RequirementService(requirementProvider);
      const propertyProvider = new PropertyProvider(assets.properties);
      this.propertyService = new PropertyService(propertyProvider);
      const gemProvider = new GemProvider(assets.gems, assets.hybridSkills);
      this.gemService = new GemService(gemProvider);
      const passiveSkillProvider = new PassiveSkillProvider(assets.notables, assets.keystones, assets.ascendant);
      this.passiveSkillService = new PassiveSkillService(passiveSkillProvider);
      const statProvider = new StatProvider(assets.stats);
      this.statService = new StatService(this.passiveSkillService, statProvider);
      const attributeProvider = new AttributeProvider(assets.attributes);
      this.attributeService = new AttributeService(attributeProvider);
      this.jsonTranslator = new JsonTranslator(this.baseTypeService, this.itemService, this.requirementService, this.propertyService, this.gemService, this.statService, this.passiveSkillService);
      this.textTranslator = new TextTranslator(this.baseTypeService, this.itemService, this.requirementService, this.propertyService, this.gemService, this.statService, this.attributeService);
    }
    getJsonTranslator() {
      return this.jsonTranslator;
    }
    getTextTranslator() {
      return this.textTranslator;
    }
    getBaseTypeService() {
      return this.baseTypeService;
    }
    getPassiveSkillService() {
      return this.passiveSkillService;
    }
    getAttributeService() {
      return this.attributeService;
    }
    getGemService() {
      return this.gemService;
    }
    getItemService() {
      return this.itemService;
    }
    getPropertiesService() {
      return this.propertyService;
    }
    getRequirementService() {
      return this.requirementService;
    }
    getStatService() {
      return this.statService;
    }
  }
  const copyToClipboard = (txt = "", cb = () => {
  }) => {
    const node = document.createElement("textarea");
    node.value = txt;
    document.body.appendChild(node);
    node.select();
    document.execCommand("Copy");
    document.body.removeChild(node);
    cb();
  };
  const translateItem = (text) => {
    if (!text)
      return;
    const factory = new BasicTranslatorFactory(_monkeyWindow.CnPoeExportDb);
    const textTranslator = factory.getTextTranslator();
    return textTranslator.translate(text);
  };
  const importFile = () => {
    const input = document.createElement("input");
    input.type = "file";
    input.accept = "text/plain";
    input.hidden = true;
    input.style.width = "0px";
    input.style.height = "0px";
    input.style.position = "absolute";
    document.body.appendChild(input);
    input.click();
    return new Promise((resolve, reject) => {
      input.onchange = (e) => {
        const files = e.target.files;
        resolve(files);
      };
    });
  };
  const readFile = (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (event) => {
        resolve(event.target.result);
      };
      reader.onerror = (error) => {
        reject(error);
      };
      reader.readAsText(file);
    });
  };
  const exportTxtFile = (filename, text) => {
    const blob = new Blob([text], { type: "text/plain" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(url);
  };
  const isValidConfig = (config) => {
    if (!Array.isArray(config))
      return false;
    for (const item of config) {
      if (typeof item !== "object" || typeof item.value !== "string")
        return false;
    }
    return true;
  };
  function mergeAndRemoveDuplicates(arr1, arr2) {
    const mergedArray = [...arr1, ...arr2];
    const map = /* @__PURE__ */ new Map();
    mergedArray.forEach((item) => {
      const key = item.label + item.value;
      if (!map.has(key)) {
        map.set(key, item);
      }
    });
    const uniqueArray = Array.from(map.values());
    return uniqueArray;
  }
  typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
  const isDef = (val) => typeof val !== "undefined";
  function cloneFnJSON(source) {
    return JSON.parse(JSON.stringify(source));
  }
  function useVModel(props, key, emit, options = {}) {
    var _a, _b, _c;
    const {
      clone = false,
      passive = false,
      eventName,
      deep = false,
      defaultValue,
      shouldEmit
    } = options;
    const vm = vue.getCurrentInstance();
    const _emit = emit || (vm == null ? void 0 : vm.emit) || ((_a = vm == null ? void 0 : vm.$emit) == null ? void 0 : _a.bind(vm)) || ((_c = (_b = vm == null ? void 0 : vm.proxy) == null ? void 0 : _b.$emit) == null ? void 0 : _c.bind(vm == null ? void 0 : vm.proxy));
    let event = eventName;
    if (!key) {
      {
        key = "modelValue";
      }
    }
    event = event || `update:${key.toString()}`;
    const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val);
    const getValue2 = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
    const triggerEmit = (value) => {
      if (shouldEmit) {
        if (shouldEmit(value))
          _emit(event, value);
      } else {
        _emit(event, value);
      }
    };
    if (passive) {
      const initialValue = getValue2();
      const proxy = vue.ref(initialValue);
      let isUpdating = false;
      vue.watch(
        () => props[key],
        (v) => {
          if (!isUpdating) {
            isUpdating = true;
            proxy.value = cloneFn(v);
            vue.nextTick(() => isUpdating = false);
          }
        }
      );
      vue.watch(
        proxy,
        (v) => {
          if (!isUpdating && (v !== props[key] || deep))
            triggerEmit(v);
        },
        { deep }
      );
      return proxy;
    } else {
      return vue.computed({
        get() {
          return getValue2();
        },
        set(value) {
          triggerEmit(value);
        }
      });
    }
  }
  const _hoisted_1$6 = { class: "DField" };
  const _hoisted_2$5 = { class: "uno-je4uyi" };
  const _hoisted_3$5 = ["type", "placeholder", "maxlength"];
  const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
    __name: "DField",
    props: {
      modelValue: { default: "" },
      label: { default: "" },
      placeholder: { default: "" },
      icon: { default: "" },
      type: { default: "text" },
      max: {},
      min: {}
    },
    emits: ["update:modelValue", "iconClick"],
    setup(__props, { emit: __emit }) {
      const emit = __emit;
      const props = __props;
      const value = useVModel(props, "modelValue", emit);
      const focus = vue.ref(false);
      const inputRef = vue.ref();
      const onFocus = () => {
        focus.value = true;
      };
      const onBlur = () => {
        setTimeout(() => {
          focus.value = false;
        }, 0);
      };
      const onLabelClick = () => {
        if (inputRef.value) {
          inputRef.value.focus();
        }
      };
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
          vue.createElementVNode("div", {
            class: vue.normalizeClass(["uno-kdj5ae", focus.value && "after:w-100%"])
          }, [
            _ctx.label ? (vue.openBlock(), vue.createElementBlock("div", {
              key: 0,
              class: "uno-bmns78",
              onClick: vue.withModifiers(onLabelClick, ["stop"])
            }, vue.toDisplayString(_ctx.label), 1)) : vue.createCommentVNode("", true),
            vue.createElementVNode("div", _hoisted_2$5, [
              vue.withDirectives(vue.createElementVNode("input", {
                type: _ctx.type,
                "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.isRef(value) ? value.value = $event : null),
                class: "uno-4f0c85",
                placeholder: _ctx.placeholder,
                ref_key: "inputRef",
                ref: inputRef,
                onFocus,
                onBlur,
                maxlength: _ctx.max
              }, null, 40, _hoisted_3$5), [
                [vue.vModelDynamic, vue.unref(value)]
              ])
            ])
          ], 2)
        ]);
      };
    }
  });
  const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
    __name: "DButton",
    props: {
      block: { type: Boolean, default: false },
      type: { default: "primary" },
      round: { type: Boolean, default: false },
      variant: { default: "default" },
      color: {},
      loading: { type: Boolean, default: false },
      disabled: { type: Boolean, default: false },
      icon: {},
      size: { default: "sm" }
    },
    emits: ["click"],
    setup(__props, { emit: __emit }) {
      const emit = __emit;
      const props = __props;
      const createStyle = () => {
        const actions = {
          default: {
            "--b-type-alpha": 1,
            "--b-active-alpha": 0.9,
            "--b-color": "white"
          },
          outline: {
            "--b-type-alpha": 0,
            "--b-border": `rgb(var(--color-${props.type}))`
          },
          light: {
            "--b-type-alpha": 0.2,
            "--b-active-alpha": 0.3
          },
          text: {
            "--b-type-alpha": 0
          }
        };
        const size = {
          sm: `6px`,
          md: `10px`,
          lg: `16px`
        };
        const style = {
          "--b-active-alpha": 0.2,
          "--b-type": `rgb(var(--color-${props.type}) / var(--b-type-alpha))`,
          "--b-active": `rgb(var(--color-${props.type}) / var(--b-active-alpha))`,
          "--b-color": `rgb(var(--color-${props.type}))`,
          "--b-border": "transparent",
          "--b-size": size[props.size],
          ...actions[props.variant]
        };
        return style;
      };
      const customStyle = vue.computed(() => {
        if (props.color)
          return `--b-type: ${props.color};`;
        return createStyle();
      });
      const onClick = () => {
        if (props.loading || props.disabled)
          return;
        emit("click");
      };
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("button", {
          class: vue.normalizeClass(["uno-n727xu d-button", [
            { "w-full": _ctx.block, disabled: _ctx.loading || _ctx.disabled, "rounded-full": _ctx.round }
          ]]),
          style: vue.normalizeStyle(customStyle.value),
          onClick: vue.withModifiers(onClick, ["stop"])
        }, [
          vue.createElementVNode("span", null, [
            vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
          ])
        ], 6);
      };
    }
  });
  const _export_sfc = (sfc, props) => {
    const target = sfc.__vccOpts || sfc;
    for (const [key, val] of props) {
      target[key] = val;
    }
    return target;
  };
  const DButton = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-91a14c1a"]]);
  const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
    __name: "DMask",
    props: {
      show: { type: Boolean },
      styles: {},
      zIndex: {}
    },
    emits: ["click"],
    setup(__props, { emit: __emit }) {
      const emit = __emit;
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Transition, { name: "fade" }, {
          default: vue.withCtx(() => [
            _ctx.show ? (vue.openBlock(), vue.createElementBlock("div", {
              key: 0,
              class: "uno-j2fx0m mask",
              onClick: _cache[0] || (_cache[0] = ($event) => emit("click")),
              style: vue.normalizeStyle({ "z-index": _ctx.zIndex, ..._ctx.styles || {} })
            }, null, 4)) : vue.createCommentVNode("", true)
          ]),
          _: 1
        });
      };
    }
  });
  const _hoisted_1$5 = { class: "uno-9b57t1" };
  const _hoisted_2$4 = { class: "uno-j8124d" };
  const _hoisted_3$4 = { class: "uno-q3uz8k" };
  const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
    __name: "DDialog",
    props: {
      modelValue: { type: Boolean, default: false },
      title: { default: "" },
      beforeClose: {}
    },
    emits: ["update:modelValue", "confirm"],
    setup(__props, { emit: __emit }) {
      const emit = __emit;
      const props = __props;
      const visible = useVModel(props, "modelValue", emit);
      const loading = vue.ref(false);
      const onClose = async (e) => {
        if (loading.value)
          return;
        if (props.beforeClose) {
          loading.value = true;
          const res = await props.beforeClose(e);
          loading.value = false;
          if (!res)
            return;
        }
        visible.value = false;
      };
      const onCancel = () => {
        onClose(false);
      };
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
          vue.createVNode(vue.Transition, { name: "scale-up" }, {
            default: vue.withCtx(() => [
              vue.unref(visible) ? (vue.openBlock(), vue.createElementBlock("div", {
                key: 0,
                class: "uno-hbwt5n",
                onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
                }, ["stop"]))
              }, [
                vue.createElementVNode("div", _hoisted_1$5, [
                  vue.renderSlot(_ctx.$slots, "title", {}, () => [
                    vue.createElementVNode("span", _hoisted_2$4, vue.toDisplayString(_ctx.title), 1)
                  ])
                ]),
                vue.createElementVNode("div", _hoisted_3$4, [
                  vue.renderSlot(_ctx.$slots, "default")
                ])
              ])) : vue.createCommentVNode("", true)
            ]),
            _: 3
          }),
          vue.createVNode(_sfc_main$6, {
            onClick: onCancel,
            show: vue.unref(visible),
            zIndex: "2000"
          }, null, 8, ["show"])
        ]);
      };
    }
  });
  const _hoisted_1$4 = { class: "uno-9b57t1" };
  const _hoisted_2$3 = { class: "uno-j8124d" };
  const _hoisted_3$3 = { class: "uno-q3uz8k" };
  const _hoisted_4$2 = ["innerHTML"];
  const _hoisted_5$1 = { class: "uno-xzlctu" };
  const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
    __name: "DMessageBox",
    props: {
      visible: { type: Boolean },
      close: { type: Function },
      confirm: { type: Function },
      title: {},
      message: {},
      showCancel: { type: Boolean },
      cancelText: {},
      confirmText: {}
    },
    emits: ["update:visible"],
    setup(__props, { emit: __emit }) {
      const props = __props;
      const loading = vue.ref(false);
      const show = vue.ref(false);
      const handleClose = () => {
        var _a;
        show.value = false;
        (_a = props.close) == null ? void 0 : _a.call(props);
      };
      const onMaskClick = () => {
        handleClose();
      };
      const onCancel = () => {
        handleClose();
      };
      const onConfirm = () => {
        var _a;
        (_a = props.confirm) == null ? void 0 : _a.call(props);
        show.value = false;
      };
      vue.watch(() => props.visible, (val) => {
        setTimeout(() => {
          show.value = val;
        }, 0);
      }, {
        immediate: true
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
          vue.createVNode(vue.unref(_sfc_main$6), {
            show: show.value,
            onClick: onMaskClick,
            "z-index": "3000"
          }, null, 8, ["show"]),
          vue.createVNode(vue.Transition, { name: "scale-up" }, {
            default: vue.withCtx(() => [
              show.value ? (vue.openBlock(), vue.createElementBlock("div", {
                key: 0,
                class: "uno-ni5pzh",
                onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
                }, ["stop"]))
              }, [
                vue.createElementVNode("div", _hoisted_1$4, [
                  vue.createElementVNode("span", _hoisted_2$3, vue.toDisplayString(_ctx.title), 1)
                ]),
                vue.createElementVNode("div", _hoisted_3$3, [
                  vue.createElementVNode("div", { innerHTML: _ctx.message }, null, 8, _hoisted_4$2)
                ]),
                vue.createElementVNode("div", _hoisted_5$1, [
                  _ctx.showCancel ? (vue.openBlock(), vue.createBlock(vue.unref(DButton), {
                    key: 0,
                    round: "",
                    type: "primary",
                    variant: "outline",
                    size: "md",
                    disabled: loading.value,
                    onClick: onCancel
                  }, {
                    default: vue.withCtx(() => [
                      vue.createTextVNode(vue.toDisplayString(_ctx.cancelText), 1)
                    ]),
                    _: 1
                  }, 8, ["disabled"])) : vue.createCommentVNode("", true),
                  vue.createVNode(vue.unref(DButton), {
                    round: "",
                    type: "primary",
                    variant: "default",
                    size: "md",
                    loading: loading.value,
                    onClick: onConfirm
                  }, {
                    default: vue.withCtx(() => [
                      vue.createTextVNode(vue.toDisplayString(_ctx.confirmText), 1)
                    ]),
                    _: 1
                  }, 8, ["loading"])
                ])
              ])) : vue.createCommentVNode("", true)
            ]),
            _: 1
          })
        ]);
      };
    }
  });
  const defaultConfig = {
    title: "注意",
    message: "",
    cancelText: "取消",
    confirmText: "确认",
    showCancel: true
  };
  function showMessageBox(options) {
    return new Promise((resolve, reject) => {
      const mountNode = document.createElement("div");
      const dialogApp = vue.createApp(_sfc_main$4, {
        visible: true,
        ...defaultConfig,
        ...options,
        close: () => {
          resolve(false);
          setTimeout(() => {
            dialogApp.unmount();
            document.body.removeChild(mountNode);
          }, 300);
        },
        confirm: () => {
          resolve(true);
          setTimeout(() => {
            dialogApp.unmount();
            document.body.removeChild(mountNode);
          }, 300);
        }
      });
      document.body.appendChild(mountNode);
      dialogApp.mount(mountNode);
    });
  }
  const _hoisted_1$3 = { class: "uno-y292xp" };
  const _hoisted_2$2 = { class: "uno-d54z7h" };
  const _hoisted_3$2 = { class: "uno-yqud7r" };
  const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
    __name: "Translate",
    setup(__props) {
      const show = vue.ref(false);
      const value = vue.ref("");
      const tip = vue.ref("");
      let st = null;
      const onTranslate = () => {
        const res = translateItem(value.value);
        if (!res) {
          tip.value = "转换异常,请重试";
          return;
        }
        value.value = res;
        copyToClipboard(value.value);
        tip.value = "已复制";
      };
      vue.watch(
        () => tip.value,
        (val) => {
          if (val) {
            if (st)
              clearTimeout(st);
            st = setTimeout(() => {
              tip.value = "";
            }, 3e3);
          }
        }
      );
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
          vue.createVNode(vue.Transition, { name: "slider" }, {
            default: vue.withCtx(() => [
              vue.withDirectives(vue.createElementVNode("div", _hoisted_2$2, [
                vue.createElementVNode("div", _hoisted_3$2, [
                  vue.withDirectives(vue.createElementVNode("textarea", {
                    class: "uno-suerow scroll-bar",
                    rows: "5",
                    "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => value.value = $event),
                    placeholder: "在这里粘贴"
                  }, null, 512), [
                    [vue.vModelText, value.value]
                  ])
                ]),
                vue.createVNode(vue.unref(DButton), {
                  type: "blue",
                  onClick: onTranslate
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode("翻译并复制")
                  ]),
                  _: 1
                })
              ], 512), [
                [vue.vShow, show.value]
              ])
            ]),
            _: 1
          }),
          vue.createVNode(vue.unref(DButton), {
            type: "brown",
            class: "uno-k9nrt0",
            onClick: _cache[1] || (_cache[1] = ($event) => show.value = !show.value)
          }, {
            default: vue.withCtx(() => [
              vue.createTextVNode(vue.toDisplayString(show.value ? "隐藏翻译界面" : "显示翻译界面"), 1)
            ]),
            _: 1
          })
        ]);
      };
    }
  });
  const SEARCH_PARAMS = [
    { label: "希望之线", value: "ajJPd8Te" },
    { label: "全抗装备", value: "Kl9qPYEc5" },
    { label: "爆伤珠宝", value: "lgPddkwhV" },
    { label: "21/20技能", value: "Nkz0F5" },
    { label: "8天赋星团", value: "nw0p9VS0" }
  ];
  const CLUSTER_LIST = [
    {
      attribute: "斧类攻击造成的击中和异常状态伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "鲜血之腥",
          ps: "前缀",
          order: 1
        },
        {
          name: "飘雪穿云",
          ps: "前缀",
          order: 2
        },
        {
          name: "恶化创伤",
          ps: "前缀",
          order: 3
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 4
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 5
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 6
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 7
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 8
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 9
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 10
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 11
        },
        {
          name: "以攻为守",
          ps: "前缀",
          order: 12
        }
      ]
    },
    {
      attribute: "长杖攻击造成的击中和异常状态伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "霸主",
          ps: "前缀",
          order: 1
        },
        {
          name: "万象之力",
          ps: "前缀",
          order: 2
        },
        {
          name: "千斤坠",
          ps: "前缀",
          order: 3
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 4
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 5
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 6
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 7
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 8
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 9
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 10
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 11
        },
        {
          name: "以攻为守",
          ps: "前缀",
          order: 12
        }
      ]
    },
    {
      attribute: "爪类攻击造成的击中和异常状态伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "螺旋之风",
          ps: "前缀",
          order: 1
        },
        {
          name: "回风之剑",
          ps: "前缀",
          order: 2
        },
        {
          name: "疫病弥漫",
          ps: "前缀",
          order: 3
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 4
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 5
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 6
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 7
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 8
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 9
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 10
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 11
        },
        {
          name: "以攻为守",
          ps: "前缀",
          order: 12
        }
      ]
    },
    {
      attribute: "弓类伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "弧光箭",
          ps: "前缀",
          order: 1
        },
        {
          name: "淬火箭头",
          ps: "前缀",
          order: 2
        },
        {
          name: "侧舷炮",
          ps: "前缀",
          order: 3
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 4
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 5
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 6
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 7
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 8
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 9
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 10
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 11
        }
      ]
    },
    {
      attribute: "法杖攻击造成的击中和异常状态伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "混元震天",
          ps: "前缀",
          order: 1
        },
        {
          name: "趁机发难",
          ps: "前缀",
          order: 2
        },
        {
          name: "风暴之手",
          ps: "前缀",
          order: 3
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 4
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 5
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 6
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 7
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 8
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 9
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 10
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 11
        }
      ]
    },
    {
      attribute: "双手武器的攻击伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "翻天横扫",
          ps: "前缀",
          order: 1
        },
        {
          name: "战场主宰",
          ps: "前缀",
          order: 2
        },
        {
          name: "武艺专精",
          ps: "前缀",
          order: 3
        },
        {
          name: "好整以暇",
          ps: "前缀",
          order: 4
        },
        {
          name: "优雅处刑",
          ps: "前缀",
          order: 5
        },
        {
          name: "恶名昭著",
          ps: "前缀",
          order: 6
        },
        {
          name: "凶骇武士",
          ps: "前缀",
          order: 7
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 8
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 9
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 10
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 11
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 12
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 13
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 14
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 15
        }
      ]
    },
    {
      attribute: "攻击伤害在双持武器时提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "韵律战法",
          ps: "前缀",
          order: 1
        },
        {
          name: "连打带跑",
          ps: "前缀",
          order: 2
        },
        {
          name: "无尽杀戮",
          ps: "前缀",
          order: 3
        },
        {
          name: "破法",
          ps: "前缀",
          order: 4
        },
        {
          name: "技如长虹",
          ps: "前缀",
          order: 5
        },
        {
          name: "疾雨摧花",
          ps: "前缀",
          order: 6
        },
        {
          name: "又快又狠",
          ps: "前缀",
          order: 7
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 8
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 9
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 10
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 11
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 12
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 13
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 14
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 15
        }
      ]
    },
    {
      attribute: "持盾牌时造成的攻击伤害提高",
      detail: [
        {
          name: "恢宏壁垒",
          ps: "前缀",
          order: 0
        },
        {
          name: "先遣卫士",
          ps: "前缀",
          order: 1
        },
        {
          name: "领军之将",
          ps: "前缀",
          order: 2
        },
        {
          name: "勇毅斗士",
          ps: "前缀",
          order: 3
        },
        {
          name: "睚眦必报",
          ps: "前缀",
          order: 4
        },
        {
          name: "防御老手",
          ps: "前缀",
          order: 5
        },
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 6
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 7
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 8
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 9
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 10
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 11
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 12
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 13
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 14
        },
        {
          name: "骚乱平息",
          ps: "前缀",
          order: 15
        }
      ]
    },
    {
      attribute: "攻击伤害提高",
      detail: [
        {
          name: "恶毒穿刺",
          ps: "前缀",
          order: 0
        },
        {
          name: "截心击",
          ps: "后缀",
          order: 1
        },
        {
          name: "金刚拳",
          ps: "后缀",
          order: 2
        },
        {
          name: "武艺精湛",
          ps: "后缀",
          order: 3
        },
        {
          name: "灾殃",
          ps: "前缀",
          order: 4
        },
        {
          name: "破坏者",
          ps: "前缀",
          order: 5
        },
        {
          name: "充能备战",
          ps: "前缀",
          order: 6
        },
        {
          name: "毁灭引擎",
          ps: "前缀",
          order: 7
        },
        {
          name: "怒火盛宴",
          ps: "前缀",
          order: 8
        }
      ]
    },
    {
      attribute: "法术伤害提高",
      detail: [
        {
          name: "先祖教化",
          ps: "前缀",
          order: 0
        },
        {
          name: "奥术专家",
          ps: "前缀",
          order: 1
        },
        {
          name: "弥补之印",
          ps: "前缀",
          order: 2
        },
        {
          name: "咒法之墙",
          ps: "前缀",
          order: 3
        },
        {
          name: "奥术英姿",
          ps: "前缀",
          order: 4
        },
        {
          name: "施法熟手",
          ps: "前缀",
          order: 5
        },
        {
          name: "掷象功",
          ps: "前缀",
          order: 6
        },
        {
          name: "奥法蠕虫",
          ps: "后缀",
          order: 7
        },
        {
          name: "精华疾攻",
          ps: "后缀",
          order: 8
        },
        {
          name: "心灵枯竭",
          ps: "后缀",
          order: 9
        },
        {
          name: "法师猎人",
          ps: "前缀",
          order: 10
        }
      ]
    },
    {
      attribute: "元素伤害提高",
      detail: [
        {
          name: "狂虐者",
          ps: "前缀",
          order: 0
        },
        {
          name: "腐蚀元素",
          ps: "前缀",
          order: 1
        },
        {
          name: "多利亚尼之训",
          ps: "后缀",
          order: 2
        },
        {
          name: "心神错乱",
          ps: "后缀",
          order: 3
        },
        {
          name: "棱光之心",
          ps: "前缀",
          order: 4
        },
        {
          name: "毁天灭地",
          ps: "后缀",
          order: 5
        },
        {
          name: "绝妙镇压",
          ps: "前缀",
          order: 6
        }
      ]
    },
    {
      attribute: "物理伤害提高",
      detail: [
        {
          name: "钢铁斗士",
          ps: "前缀",
          order: 0
        },
        {
          name: "规律主宰",
          ps: "前缀",
          order: 1
        },
        {
          name: "力量倍增",
          ps: "后缀",
          order: 2
        },
        {
          name: "狂风扫荡",
          ps: "后缀",
          order: 3
        },
        {
          name: "阴冷誓言",
          ps: "后缀",
          order: 4
        },
        {
          name: "坚守战场",
          ps: "前缀",
          order: 5
        }
      ]
    },
    {
      attribute: "火焰伤害提高",
      detail: [
        {
          name: "狂虐者",
          ps: "前缀",
          order: 0
        },
        {
          name: "腐蚀元素",
          ps: "前缀",
          order: 1
        },
        {
          name: "多利亚尼之训",
          ps: "后缀",
          order: 2
        },
        {
          name: "心神错乱",
          ps: "后缀",
          order: 3
        },
        {
          name: "棱光之心",
          ps: "前缀",
          order: 4
        },
        {
          name: "毁天灭地",
          ps: "后缀",
          order: 5
        },
        {
          name: "火焰之主",
          ps: "前缀",
          order: 6
        },
        {
          name: "燃烬之烟",
          ps: "前缀",
          order: 7
        },
        {
          name: "焚化炉",
          ps: "前缀",
          order: 8
        },
        {
          name: "熊熊燃烧",
          ps: "前缀",
          order: 9
        }
      ]
    },
    {
      attribute: "闪电伤害提高",
      detail: [
        {
          name: "狂虐者",
          ps: "前缀",
          order: 0
        },
        {
          name: "腐蚀元素",
          ps: "前缀",
          order: 1
        },
        {
          name: "多利亚尼之训",
          ps: "后缀",
          order: 2
        },
        {
          name: "心神错乱",
          ps: "后缀",
          order: 3
        },
        {
          name: "棱光之心",
          ps: "前缀",
          order: 4
        },
        {
          name: "毁天灭地",
          ps: "后缀",
          order: 5
        },
        {
          name: "暴风雪",
          ps: "前缀",
          order: 6
        },
        {
          name: "风暴痛饮",
          ps: "前缀",
          order: 7
        },
        {
          name: "瘫痪",
          ps: "前缀",
          order: 8
        },
        {
          name: "绝妙镇压",
          ps: "前缀",
          order: 9
        },
        {
          name: "天雷轰顶",
          ps: "前缀",
          order: 10
        },
        {
          name: "风暴骑手",
          ps: "前缀",
          order: 11
        },
        {
          name: "霹雳雷震",
          ps: "前缀",
          order: 12
        },
        {
          name: "闪光理念",
          ps: "前缀",
          order: 13
        }
      ]
    },
    {
      attribute: "冰霜伤害提高",
      detail: [
        {
          name: "狂虐者",
          ps: "前缀",
          order: 0
        },
        {
          name: "腐蚀元素",
          ps: "前缀",
          order: 1
        },
        {
          name: "多利亚尼之训",
          ps: "后缀",
          order: 2
        },
        {
          name: "心神错乱",
          ps: "后缀",
          order: 3
        },
        {
          name: "棱光之心",
          ps: "前缀",
          order: 4
        },
        {
          name: "毁天灭地",
          ps: "后缀",
          order: 5
        },
        {
          name: "暴风雪",
          ps: "前缀",
          order: 6
        },
        {
          name: "大雪漫天",
          ps: "前缀",
          order: 7
        },
        {
          name: "冻彻心扉",
          ps: "前缀",
          order: 8
        },
        {
          name: "冷血杀手",
          ps: "前缀",
          order: 9
        },
        {
          name: "绝妙镇压",
          ps: "前缀",
          order: 10
        },
        {
          name: "深寒",
          ps: "前缀",
          order: 11
        },
        {
          name: "千里冰封",
          ps: "前缀",
          order: 12
        },
        {
          name: "风暴骑手",
          ps: "前缀",
          order: 13
        }
      ]
    },
    {
      attribute: "混沌伤害提高",
      detail: [
        {
          name: "阴冷誓言",
          ps: "后缀",
          order: 0
        },
        {
          name: "罪恶滔天",
          ps: "前缀",
          order: 1
        },
        {
          name: "残酷之触",
          ps: "前缀",
          order: 2
        },
        {
          name: "不动之恶",
          ps: "前缀",
          order: 3
        },
        {
          name: "莫名之赐",
          ps: "后缀",
          order: 4
        },
        {
          name: "黑暗构想",
          ps: "前缀",
          order: 5
        },
        {
          name: "渎神雅量",
          ps: "后缀",
          order: 6
        },
        {
          name: "邪恶烟云",
          ps: "前缀",
          order: 7
        }
      ]
    },
    {
      attribute: "召唤生物的伤害提高",
      detail: [
        {
          name: "复兴",
          ps: "前缀",
          order: 0
        },
        {
          name: "寸草不生",
          ps: "前缀",
          order: 1
        },
        {
          name: "腐烂之爪",
          ps: "前缀",
          order: 2
        },
        {
          name: "屠夫呼唤",
          ps: "后缀",
          order: 3
        },
        {
          name: "恶毒撕咬",
          ps: "后缀",
          order: 4
        },
        {
          name: "原初之缚",
          ps: "后缀",
          order: 5
        },
        {
          name: "饕餮群魔",
          ps: "前缀",
          order: 6
        },
        {
          name: "魔侍凋零",
          ps: "前缀",
          order: 7
        }
      ]
    }
  ];
  const _hoisted_1$2 = { class: "uno-y292xp" };
  const _hoisted_2$1 = { class: "uno-l9jv7r scroll-bar" };
  const _hoisted_3$1 = { class: "uno-weqgrm" };
  const _hoisted_4$1 = ["onClick"];
  const _hoisted_5 = ["onClick"];
  const _hoisted_6 = /* @__PURE__ */ vue.createElementVNode("div", null, [
    /* @__PURE__ */ vue.createElementVNode("span", { class: "uno-v15f5i" }, "新增"),
    /* @__PURE__ */ vue.createElementVNode("a", {
      class: "uno-m8p83r",
      href: "",
      target: "_blank"
    }, "详见说明")
  ], -1);
  const _hoisted_7 = { class: "uno-0aac7g" };
  const _hoisted_8 = { class: "uno-36f1r2" };
  const _hoisted_9 = { class: "uno-xy2f5e" };
  const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
    __name: "Search",
    setup(__props) {
      const show = vue.ref(false);
      const showCustom = vue.ref(false);
      const searchKeys = vue.ref([]);
      const form = vue.ref({
        label: "",
        value: ""
      });
      const saveStore = (arr) => {
        localStorage.setItem("SEARCH_PARAMS", JSON.stringify(arr));
      };
      const onSearch = (data) => {
        let league = "";
        const localLeague = JSON.parse(localStorage.getItem("lscache-tradestate") || "{}");
        league = localLeague.league || window.location.href.match(/\/trade\/search\/([^/]+)/)[1];
        window.open(`https://poe.game.qq.com/trade/search/${league}/${data.value}`, "_blank");
      };
      const onDel = (i) => {
        searchKeys.value.splice(i, 1);
        saveStore(searchKeys.value);
      };
      const onSave = () => {
        if (!form.value.label || !form.value.value)
          return;
        searchKeys.value.push(vue.toRaw(form.value));
        vue.nextTick(() => {
          form.value = {
            value: "",
            label: ""
          };
          saveStore(searchKeys.value);
        });
      };
      const onReset = async () => {
        const res = await showMessageBox({
          title: "注意",
          message: "重置后将恢复预设选项,所有自定义的列表都将被删除。是否继续?"
        });
        if (!res)
          return;
        searchKeys.value = SEARCH_PARAMS;
        saveStore(SEARCH_PARAMS);
      };
      const onExport = async () => {
        const txt = JSON.stringify(searchKeys.value);
        exportTxtFile("trade_config.txt", txt);
      };
      const onImport = async () => {
        const files = await importFile();
        if (!files) {
          alert("获取文件失败");
          return;
        }
        const file = files[0];
        if (file.type !== "text/plain") {
          await showMessageBox({ title: "注意", message: "仅支持txt文本", showCancel: false });
          return;
        }
        try {
          const text = await readFile(file);
          const data = JSON.parse(text);
          if (!isValidConfig(data)) {
            throw new Error("格式错误");
          }
          searchKeys.value = mergeAndRemoveDuplicates(vue.toRaw(searchKeys.value), data);
          saveStore(searchKeys.value);
          showMessageBox({ title: "注意", message: "导入成功", showCancel: false });
        } catch (error) {
          console.error(error);
          await showMessageBox({ title: "注意", message: "文件读取异常,请确认格式正确", showCancel: false });
        }
      };
      vue.onMounted(() => {
        const searchkeyStr = localStorage.getItem("SEARCH_PARAMS");
        if (!searchkeyStr) {
          searchKeys.value = SEARCH_PARAMS;
        } else {
          searchKeys.value = JSON.parse(searchkeyStr);
        }
        saveStore(searchKeys.value);
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
          vue.createVNode(vue.Transition, { name: "slider" }, {
            default: vue.withCtx(() => [
              vue.withDirectives(vue.createElementVNode("div", _hoisted_2$1, [
                (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(searchKeys.value, (param, i) => {
                  return vue.openBlock(), vue.createElementBlock("div", _hoisted_3$1, [
                    vue.createElementVNode("span", {
                      class: "uno-2x98nu",
                      onClick: ($event) => onSearch(param)
                    }, vue.toDisplayString(param.label), 9, _hoisted_4$1),
                    vue.createElementVNode("span", {
                      class: "uno-gd7xcy",
                      onClick: ($event) => onDel(i)
                    }, "x", 8, _hoisted_5)
                  ]);
                }), 256)),
                vue.createElementVNode("div", {
                  class: "uno-f70hor",
                  onClick: _cache[0] || (_cache[0] = ($event) => showCustom.value = true)
                }, "+ 自定义")
              ], 512), [
                [vue.vShow, show.value]
              ])
            ]),
            _: 1
          }),
          vue.createVNode(vue.unref(DButton), {
            type: "brown",
            class: "uno-8ut93f",
            onClick: _cache[1] || (_cache[1] = ($event) => show.value = !show.value),
            title: "具体物品和数值需要点击跳转后手动输入,只是有的词缀选起来很烦"
          }, {
            default: vue.withCtx(() => [
              vue.createTextVNode("快捷搜索")
            ]),
            _: 1
          }),
          vue.createVNode(vue.unref(_sfc_main$5), {
            modelValue: showCustom.value,
            "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => showCustom.value = $event)
          }, {
            title: vue.withCtx(() => [
              _hoisted_6
            ]),
            default: vue.withCtx(() => [
              vue.createElementVNode("div", _hoisted_7, [
                vue.createElementVNode("div", _hoisted_8, [
                  vue.createVNode(vue.unref(DButton), {
                    type: "danger",
                    variant: "outline",
                    round: "",
                    onClick: onReset
                  }, {
                    default: vue.withCtx(() => [
                      vue.createTextVNode("重置为默认")
                    ]),
                    _: 1
                  }),
                  vue.createVNode(vue.unref(DButton), {
                    round: "",
                    onClick: onImport
                  }, {
                    default: vue.withCtx(() => [
                      vue.createTextVNode("批量导入")
                    ]),
                    _: 1
                  }),
                  vue.createVNode(vue.unref(DButton), {
                    round: "",
                    onClick: onExport
                  }, {
                    default: vue.withCtx(() => [
                      vue.createTextVNode("导出")
                    ]),
                    _: 1
                  })
                ]),
                vue.createElementVNode("div", null, [
                  vue.createVNode(vue.unref(_sfc_main$8), {
                    label: "名字",
                    modelValue: form.value.label,
                    "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => form.value.label = $event),
                    placeholder: "请输入名字",
                    class: "uno-kzvvcj",
                    max: 20
                  }, null, 8, ["modelValue"]),
                  vue.createVNode(vue.unref(_sfc_main$8), {
                    label: "查询字符串",
                    modelValue: form.value.value,
                    "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => form.value.value = $event),
                    placeholder: "地址里最后的字符串.如:nw0p9VS0",
                    class: "uno-kzvvcj"
                  }, null, 8, ["modelValue"]),
                  vue.createElementVNode("div", _hoisted_9, [
                    vue.createVNode(vue.unref(DButton), {
                      round: "",
                      variant: "outline",
                      size: "md",
                      class: "uno-lnbmsj",
                      onClick: _cache[4] || (_cache[4] = ($event) => showCustom.value = false)
                    }, {
                      default: vue.withCtx(() => [
                        vue.createTextVNode("取消")
                      ]),
                      _: 1
                    }),
                    vue.createVNode(vue.unref(DButton), {
                      round: "",
                      onClick: onSave,
                      size: "md",
                      class: "uno-lnbmsj"
                    }, {
                      default: vue.withCtx(() => [
                        vue.createTextVNode("保存")
                      ]),
                      _: 1
                    })
                  ])
                ])
              ])
            ]),
            _: 1
          }, 8, ["modelValue"])
        ]);
      };
    }
  });
  const _withScopeId = (n) => (vue.pushScopeId("data-v-e39b9b4e"), n = n(), vue.popScopeId(), n);
  const _hoisted_1$1 = { class: "uno-pjhpbh group" };
  const _hoisted_2 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("span", { title: "该功能尚在实验中, 不保证内容准确。如发现对不上的请前往插件页面反馈" }, "查看天赋位置", -1));
  const _hoisted_3 = { class: "uno-cwirjq" };
  const _hoisted_4 = ["width", "height"];
  const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
    __name: "Cluster",
    props: {
      data: {}
    },
    setup(__props) {
      const size = vue.ref(180);
      vue.ref(false);
      const canvas = vue.ref();
      const props = __props;
      const createCanvas = (num, types) => {
        if (!canvas.value)
          return;
        const ctx = canvas.value.getContext("2d");
        if (!ctx)
          return;
        const centerX = canvas.value.width / 2;
        const centerY = canvas.value.height / 2;
        const radius = 50;
        ctx.beginPath();
        ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
        ctx.strokeStyle = "gray";
        ctx.lineWidth = 2;
        ctx.stroke();
        const numDots = 12;
        const len = types.length;
        let count = 0;
        const angleStep = 2 * Math.PI / numDots;
        const startingAngle = -Math.PI;
        for (let i = 0; i < numDots; i++) {
          const angle = startingAngle + i * angleStep;
          let dotRadius = 4;
          ctx.fillStyle = "gray";
          if (i === 4 || i === 8)
            dotRadius = 6;
          const pointPosition = [];
          if (len >= 1)
            pointPosition.push(6);
          if (len >= 2)
            pointPosition.push(10);
          if (len >= 3)
            pointPosition.push(2);
          if (pointPosition.includes(i)) {
            dotRadius = 8;
            ctx.fillStyle = "#4dc64d";
          }
          const ignoreList = [];
          if (num <= 11)
            ignoreList.push(1);
          if (num <= 10)
            ignoreList.push(11);
          if (num <= 9)
            ignoreList.push(3);
          if (ignoreList.includes(i))
            continue;
          const x = centerX + Math.cos(angle) * radius;
          const y = centerY + Math.sin(angle) * radius;
          ctx.beginPath();
          ctx.arc(x, y, dotRadius, 0, 2 * Math.PI);
          ctx.fill();
          if (pointPosition.includes(i)) {
            ctx.fillStyle = "white";
            ctx.font = "12px Arial";
            ctx.fillText(types[count].name, x - 60, y + 5);
            count += 1;
          }
        }
      };
      vue.onMounted(() => {
        createCanvas(parseInt(props.data.num), props.data.types);
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
          _hoisted_2,
          vue.createElementVNode("div", _hoisted_3, [
            vue.createElementVNode("canvas", {
              ref_key: "canvas",
              ref: canvas,
              width: size.value,
              height: size.value
            }, null, 8, _hoisted_4)
          ])
        ]);
      };
    }
  });
  const Cluster = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e39b9b4e"]]);
  const injectButton = (cb) => {
    const targets = Array.from(document.querySelectorAll(".row[data-id]"));
    if (!targets || !targets.length)
      return;
    targets.forEach((target) => {
      if (target.querySelector(".copy-en"))
        return;
      const leftEl = target.querySelector(".left");
      if (!leftEl)
        return;
      const btn = document.createElement("div");
      btn.className = "copy-en";
      btn.title = "复制英文";
      btn.setAttribute(
        "style",
        `position: absolute;
            left: 84px;
            bottom: 10px;
            color: #fff;
            font-size: 14px;
            cursor: pointer;
            text-decoration: underline;`
      );
      btn.innerText = "复制英文";
      leftEl.appendChild(btn);
      btn.addEventListener("click", () => {
        const text = target.__vue__.itemText;
        let textarea = document.createElement("textarea");
        textarea.value = text;
        const res = translateItem(textarea.value);
        copyToClipboard(res);
        target.__vue__.itemTextCopied();
      });
      if (cb)
        cb(target);
    });
  };
  const initObserver = (cb) => {
    const observer = new MutationObserver((mutationsList, observer2) => {
      for (let mutation of mutationsList) {
        if (mutation.target.className !== "resultset")
          return;
        injectButton(cb);
      }
    });
    const targetNode = document.querySelector("body");
    const config = { childList: true, subtree: true };
    observer.observe(targetNode, config);
  };
  const _hoisted_1 = { class: "uno-6a64nq" };
  const _sfc_main = /* @__PURE__ */ vue.defineComponent({
    __name: "Trade",
    setup(__props) {
      const callBack = (e) => {
        var _a;
        const infoEl = e.querySelector(".middle");
        const name = (_a = infoEl.querySelector(".itemHeader")) == null ? void 0 : _a.innerText;
        if (!/大型星团珠宝/.test(name))
          return;
        const info = infoEl == null ? void 0 : infoEl.innerText;
        const num = info.match(/增加 (\d+) 个天赋技能/);
        const attribute = info.match(/增加的小天赋获得:(.*)/);
        if (!num || !attribute)
          return;
        const regex = /其中 1 个增加的天赋为(.*)/g;
        let matches = [];
        let match;
        while ((match = regex.exec(info)) !== null) {
          if (match[1].trim()) {
            matches.push(match[1].replace(/【|】/g, ""));
          }
        }
        if (!matches.length)
          return;
        const currentType = CLUSTER_LIST.find((e2) => new RegExp(`^${e2.attribute}`).test(attribute[1]));
        if (!currentType)
          return;
        const data = {
          num: num[1],
          attribute: attribute[1],
          types: currentType.detail.filter((e2) => matches.includes(e2.name))
        };
        const clusterCom = vue.createApp(Cluster, {
          data
        });
        const wrap = document.createElement("div");
        const taget = e.querySelector(".left");
        if (taget)
          taget.append(wrap);
        clusterCom.mount(wrap);
      };
      vue.onMounted(() => {
        initObserver(callBack);
      });
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
          vue.createVNode(_sfc_main$3),
          vue.createVNode(_sfc_main$2)
        ]);
      };
    }
  });
  if (/poe\.game\.qq\.com\/trade/.test(window.location.href)) {
    const app = vue.createApp(_sfc_main);
    app.mount(
      (() => {
        const app2 = document.createElement("div");
        app2.id = "poe-trade-plugin";
        document.body.append(app2);
        return app2;
      })()
    );
  }
  if (/apps\.game\.qq\.com/.test(window.location.href)) {
    setTimeout(() => {
      window.parent.location.replace("https://poe.game.qq.com/");
    }, 500);
  }

})(Vue);