'use strict';
var __createBinding = this && this["__createBinding"] || (Object["create"] ? function (_0x426d51, _0x1fa101, _0xd56cbf, _0x584cf0) {
  const _0x72e54d = {
    'uKmJw': function (_0xdd80ed, _0x4bf4c4) {
      return _0xdd80ed === _0x4bf4c4;
    },
    'TAoYL': function (_0x3d6ea4, _0x2c5cdc) {
      return _0x3d6ea4 in _0x2c5cdc;
    },
    'aPyeo': "get"
  };
  if (_0x72e54d["uKmJw"](_0x584cf0, undefined)) {
    _0x584cf0 = _0xd56cbf;
  }
  var _0x1907da = Object.getOwnPropertyDescriptor(_0x1fa101, _0xd56cbf);
  if (!_0x1907da || (_0x72e54d.aPyeo in _0x1907da ? !_0x1fa101.__esModule : _0x1907da["writable"] || _0x1907da.configurable)) {
    _0x1907da = {
      'enumerable': true,
      'get': function () {
        return _0x1fa101[_0xd56cbf];
      }
    };
  }
  Object["defineProperty"](_0x426d51, _0x584cf0, _0x1907da);
} : function (_0x5f91d1, _0x9a02cb, _0x4b8c9f, _0x19d088) {
  const _0x5f3f4d = {
    'SeNEr': function (_0x5d446f, _0x23305b) {
      return _0x5d446f === _0x23305b;
    }
  };
  if (_0x5f3f4d["SeNEr"](_0x19d088, undefined)) {
    _0x19d088 = _0x4b8c9f;
  }
  _0x5f91d1[_0x19d088] = _0x9a02cb[_0x4b8c9f];
});
var __setModuleDefault = this && this["__setModuleDefault"] || (Object["create"] ? function (_0x345a43, _0x11ae4c) {
  const _0x4f212a = {
    'FTXnn': "default"
  };
  Object["defineProperty"](_0x345a43, _0x4f212a.FTXnn, {
    'enumerable': true,
    'value': _0x11ae4c
  });
} : function (_0x1d7e4a, _0x48365a) {
  const _0x3780d5 = {
    'kZOut': "default"
  };
  _0x1d7e4a[_0x3780d5["kZOut"]] = _0x48365a;
});
var __importStar = this && this.__importStar || function () {
  const _0x4481b5 = {
    'fsNNJ': function (_0x24a54e, _0x1bdb80) {
      return _0x24a54e(_0x1bdb80);
    },
    'srHxh': '1|4|0|3|2',
    'MoXZb': function (_0x3f36e7, _0x3a1c53) {
      return _0x3f36e7 != _0x3a1c53;
    },
    'VqBsb': function (_0x32fe05, _0x1525ff) {
      return _0x32fe05 < _0x1525ff;
    },
    'mymIw': function (_0x4a533c, _0x29a9b2) {
      return _0x4a533c !== _0x29a9b2;
    },
    'zFOle': function (_0x3faee2, _0x31a6a7, _0x2bbca2, _0x53d668) {
      return _0x3faee2(_0x31a6a7, _0x2bbca2, _0x53d668);
    },
    'zPdmk': function (_0x326a22, _0x578e64, _0x1ca450) {
      return _0x326a22(_0x578e64, _0x1ca450);
    }
  };
  var _0xb2a35b = function (_0x4d1aec) {
    _0xb2a35b = Object["getOwnPropertyNames"] || function (_0x1a3c58) {
      var _0x5ea703 = [];
      for (var _0x185acc in _0x1a3c58) if (Object["prototype"]["hasOwnProperty"]["call"](_0x1a3c58, _0x185acc)) {
        _0x5ea703[_0x5ea703["length"]] = _0x185acc;
      }
      return _0x5ea703;
    };
    return _0x4481b5["fsNNJ"](_0xb2a35b, _0x4d1aec);
  };
  return function (_0x31ac5f) {
    const _0x3c765b = _0x4481b5["srHxh"]["split"]('|');
    let _0x2fee3c = 0x0;
    while (true) {
      switch (_0x3c765b[_0x2fee3c++]) {
        case '0':
          if (_0x4481b5["MoXZb"](_0x31ac5f, null)) {
            var _0x43241d = _0xb2a35b(_0x31ac5f);
            for (var _0x27b692 = 0x0; _0x4481b5["VqBsb"](_0x27b692, _0x43241d["length"]); _0x27b692++) {
              if (_0x4481b5["mymIw"](_0x43241d[_0x27b692], "default")) {
                _0x4481b5["zFOle"](__createBinding, _0x23061d, _0x31ac5f, _0x43241d[_0x27b692]);
              }
            }
          }
          continue;
        case '1':
          if (_0x31ac5f && _0x31ac5f["__esModule"]) {
            return _0x31ac5f;
          }
          continue;
        case '2':
          return _0x23061d;
        case '3':
          _0x4481b5["zPdmk"](__setModuleDefault, _0x23061d, _0x31ac5f);
          continue;
        case '4':
          var _0x23061d = {};
          continue;
      }
      break;
    }
  };
}();
Object["defineProperty"](exports, '__esModule', {
  'value': true
});
exports.CursorProViewProvider = undefined;
const vscode = __importStar(require("vscode"));
const client_1 = require("../api/client");
const extension_1 = require("../extension");
const account_1 = require('../utils/account');
const path = __importStar(require("path"));
const fs = __importStar(require('fs'));
const child_process_1 = require('child_process');
const util_1 = require("util");
const sqlite_1 = require('../utils/sqlite');
0x0;
const execAsync = util_1["promisify"](child_process_1["exec"]);
class CursorProViewProvider {
  constructor(_0x249e9c, _0x2abb89) {
    const _0x22d112 = {
      'dJwJk': "networkStatus",
      'NNvQE': "154.36.154.163",
      'HENcW': "api2.cursor.sh",
      'vVEYg': "api3.cursor.sh",
      'xOuBX': "# ===== CursorPro SNI Proxy Start =====",
      'gbbhA': "# ===== CursorPro SNI Proxy End ====="
    };
    this["_extensionUri"] = _0x249e9c;
    this["_context"] = _0x2abb89;
    this._hostsPermissionGranted = false;
    this.SNI_PROXY_IP = _0x22d112["NNvQE"];
    this["CURSOR_DOMAINS"] = [_0x22d112.HENcW, _0x22d112["vVEYg"]];
    this["HOSTS_MARKER_START"] = _0x22d112["xOuBX"];
    this["HOSTS_MARKER_END"] = _0x22d112["gbbhA"];
    this["_cachedCursorPath"] = null;
    0x0;
    this["_onlineStatusUnsubscribe"] = client_1["onOnlineStatusChange"](_0x11fa48 => {
      this["_postMessage"]({
        'type': _0x22d112["dJwJk"],
        'online': _0x11fa48
      });
    });
  }
  ["resolveWebviewView"](_0x3b70b5, _0x5282a8, _0x49a978) {
    const _0x5b922e = {
      'NRTxb': "没有写入权限",
      'MCtQT': "seamlessRestored",
      'RCwUS': "GfeNG",
      'gHWzN': "LNoTP",
      'HxMUq': 'switch',
      'mVWLv': "disableUpdate",
      'kIVSE': 'cleanEnv',
      'ayNzd': 'disable',
      'XJsJS': 'toggleProxy',
      'TwlLk': "getState",
      'Yecgn': "getSeamlessStatus",
      'ekYOQ': "injectSeamless",
      'sJjTI': 'toggleSeamless',
      'FtmLf': 'getUserSwitchStatus',
      'EflLA': "checkUsageBeforeSwitch",
      'rXOaA': "confirmSwitch",
      'OkEoz': "getCursorPath",
      'SLxXS': 'getAccountUsage',
      'ehEEN': 'checkVersion',
      'myCHL': "getCursorRunningPath",
      'KPDvL': "reloadWindow",
      'LHHus': "workbench.action.reloadWindow",
      'ozgjT': 'closeCursor'
    };
    this["_view"] = _0x3b70b5;
    _0x3b70b5["webview"].options = {
      'enableScripts': true,
      'localResourceRoots': [this["_extensionUri"]]
    };
    _0x3b70b5["webview"]["html"] = this["_getHtmlContent"](_0x3b70b5["webview"]);
    _0x3b70b5["webview"]["onDidReceiveMessage"](async _0x194d46 => {
      const _0x275d91 = {
        'WZyWQ': _0x5b922e["NRTxb"],
        'ZXhkG': _0x5b922e["MCtQT"]
      };
      if (_0x5b922e["RCwUS"] !== _0x5b922e["gHWzN"]) {
        switch (_0x194d46.type) {
          case "activate":
            await this._handleActivate(_0x194d46["key"]);
            break;
          case _0x5b922e["HxMUq"]:
            await this["_handleSwitch"]();
            break;
          case "resetMachineId":
            await this._handleResetMachineId();
            break;
          case _0x5b922e.mVWLv:
            await this["_handleDisableUpdate"]();
            break;
          case _0x5b922e["kIVSE"]:
            await this["_handleCleanEnv"]();
            break;
          case _0x5b922e["ayNzd"]:
            await this._handleDisable();
            break;
          case _0x5b922e["XJsJS"]:
            await this._handleToggleProxy(_0x194d46["enabled"], _0x194d46["url"]);
            break;
          case 'getProxyStatus':
            await this["_handleGetProxyStatus"]();
            break;
          case _0x5b922e["TwlLk"]:
            await this["_sendState"]();
            break;
          case "retryConnect":
            await this["_handleRetryConnect"]();
            break;
          case _0x5b922e["Yecgn"]:
            await this["_handleGetSeamlessStatus"]();
            break;
          case _0x5b922e.ekYOQ:
            await this["_handleInjectSeamless"]();
            break;
          case "restoreSeamless":
            await this._handleRestoreSeamless();
            break;
          case _0x5b922e["sJjTI"]:
            await this["_handleToggleSeamless"](_0x194d46.enabled);
            break;
          case _0x5b922e["FtmLf"]:
            await this["_handleGetUserSwitchStatus"]();
            break;
          case "manualSeamlessSwitch":
            await this._handleManualSeamlessSwitch();
            break;
          case _0x5b922e.EflLA:
            await this["_handleCheckUsageBeforeSwitch"](_0x194d46["email"]);
            break;
          case _0x5b922e["rXOaA"]:
            await this["_handleManualSeamlessSwitch"]();
            break;
          case _0x5b922e.OkEoz:
            await this._handleGetCursorPath();
            break;
          case 'getAccountUsage':
            await this["_handleGetAccountUsage"](_0x194d46["email"]);
            break;
          case "getAnnouncement":
            await this._handleGetAnnouncement();
            break;
          case _0x5b922e["ehEEN"]:
            await this._handleCheckVersion();
            break;
          case _0x5b922e["myCHL"]:
            await this["_handleGetCursorRunningPath"]();
            break;
          case _0x5b922e["KPDvL"]:
            vscode["commands"].executeCommand(_0x5b922e["LHHus"]);
            break;
          case 'closeCursor':
            0x0;
            await account_1.closeCursor();
            break;
        }
      } else {
        const _0x282668 = _0x275d91["WZyWQ"];
        this["_postMessage"]({
          'type': _0x275d91["ZXhkG"],
          'success': false,
          'error': _0x282668,
          'needAdmin': true
        });
        return;
      }
    });
    this["_sendState"]();
    this["_checkKeyStatus"]();
  }
  async ["_checkKeyStatus"]() {
    const _0x4da3ff = {
      'TLsxY': "utf-8",
      'KqsKI': "cursorpro.key",
      'OEKzo': function (_0x3f2189, _0x48838e) {
        return _0x3f2189 !== _0x48838e;
      },
      'krxOp': "FAZar",
      'lSeSm': "QlWcq",
      'ubmNf': function (_0x29914e, _0x4e5d68) {
        return _0x29914e === _0x4e5d68;
      },
      'yoPVW': 'EtMGw',
      'UGSnZ': 'DVTND',
      'jEejJ': 'cursorpro.expireDate',
      'lpyMQ': 'cursorpro.switchRemaining',
      'Auayd': "cursorpro.switchLimit",
      'sbaFL': "keyStatusChecked",
      'dyUVf': "激活码已过期或无效"
    };
    const _0x844666 = this["_context"]["globalState"].get(_0x4da3ff["KqsKI"]);
    if (!_0x844666) {
      if (_0x4da3ff["OEKzo"]('NCQkd', _0x4da3ff["krxOp"])) {
        return;
      } else {
        this["_postMessage"]({
          'type': "accountUsage",
          'success': false,
          'error': "未提供账号邮箱"
        });
        return;
      }
    }
    try {
      if (_0x4da3ff["lSeSm"] !== 'QlWcq') {
        _0x24f700["writeFileSync"](_0x5ce57d, _0x2697d5, _0x4da3ff["TLsxY"]);
      } else {
        0x0;
        const _0x439524 = await client_1.verifyKey(_0x844666);
        if (_0x439524["success"] && _0x439524.valid) {
          if (_0x4da3ff["ubmNf"](_0x4da3ff["yoPVW"], _0x4da3ff["UGSnZ"])) {
            const _0x3a2e35 = _0x45d671["readFileSync"](_0x1f88e9, _0x4da3ff["TLsxY"]);
            _0x2710ef = this["_checkInjected"](_0x3a2e35);
          } else {
            await this._context.globalState["update"](_0x4da3ff["jEejJ"], _0x439524["expire_date"]);
            await this._context["globalState"]["update"](_0x4da3ff["lpyMQ"], _0x439524["switch_remaining"]);
            await this._context["globalState"]["update"](_0x4da3ff["Auayd"], _0x439524["switch_limit"]);
            this["_postMessage"]({
              'type': _0x4da3ff["sbaFL"],
              'valid': true,
              'expireDate': _0x439524["expire_date"],
              'switchRemaining': _0x439524["switch_remaining"],
              'switchLimit': _0x439524["switch_limit"]
            });
          }
        } else {
          this._postMessage({
            'type': _0x4da3ff["sbaFL"],
            'valid': false,
            'expired': true,
            'error': _0x439524["error"] || _0x4da3ff["dyUVf"]
          });
        }
      }
    } catch (_0xe8e14c) {
      console.error("[CursorPro] 检查激活码状态失败:", _0xe8e14c);
    }
  }
  async ["_handleActivate"](_0x1c33b1) {
    const _0x83ba47 = {
      'cduDC': "utf-8",
      'dWzRy': function (_0x2eb04a, _0x1a63c1) {
        return _0x2eb04a(_0x1a63c1);
      },
      'yiKQp': "vscode",
      'loOtc': "[CursorPro] 使用 VS Code API 获取版本:",
      'fCoyb': function (_0x39f2f1, _0x5bc57a) {
        return _0x39f2f1 === _0x5bc57a;
      },
      'hneyF': "ZPKij",
      'MeNSD': "无感换号已启用，请先禁用后再更换授权码",
      'jfGyX': function (_0x341f1e, _0x13166d) {
        return _0x341f1e === _0x13166d;
      },
      'vAxgQ': 'ZyMNB',
      'IStwX': "activated",
      'RiXWk': "cursorpro.expireDate",
      'tkwFD': "cursorpro.key",
      'oRfTW': "cursorpro.switchLimit",
      'lnDvM': "aVnan",
      'bgJHu': "SOGed",
      'lRVPz': "授权码无效",
      'mbyBU': "连接服务器失败"
    };
    try {
      const _0x3b1ee2 = await this["_isSeamlessInjected"]();
      if (_0x3b1ee2) {
        if (_0x83ba47["fCoyb"](_0x83ba47["hneyF"], "ZPKij")) {
          this._postMessage({
            'type': "activated",
            'success': false,
            'error': _0x83ba47.MeNSD
          });
          return;
        } else {
          const _0x5234a5 = this._getHostsPath();
          if (_0x58e3ff["existsSync"](_0x5234a5)) {
            return _0x490712["readFileSync"](_0x5234a5, _0x83ba47["cduDC"]);
          }
        }
      }
      this._cleanProxySettings();
      0x0;
      const _0x48d007 = await client_1["verifyKey"](_0x1c33b1);
      if (_0x48d007["success"] && _0x48d007.valid) {
        if (_0x83ba47["jfGyX"]('ZyMNB', _0x83ba47["vAxgQ"])) {
          console.log("[CursorPro] 激活成功，后端返回:", {
            'expire_date': _0x48d007["expire_date"],
            'switch_remaining': _0x48d007["switch_remaining"],
            'switch_limit': _0x48d007["switch_limit"]
          });
          await this["_context"].globalState["update"](_0x83ba47.tkwFD, _0x1c33b1);
          await this._context["globalState"]["update"](_0x83ba47["RiXWk"], _0x48d007.expire_date);
          await this["_context"]["globalState"]["update"]("cursorpro.switchRemaining", _0x48d007.switch_remaining);
          await this._context["globalState"]["update"](_0x83ba47["oRfTW"], _0x48d007["switch_limit"]);
          this["_postMessage"]({
            'type': _0x83ba47["IStwX"],
            'success': true,
            'key': _0x1c33b1,
            'expireDate': _0x48d007.expire_date,
            'switchRemaining': _0x48d007["switch_remaining"],
            'switchLimit': _0x48d007["switch_limit"]
          });
          0x0;
          extension_1["showStatusBar"]();
          await this._handleGetUserSwitchStatus();
        } else {
          _0x287901["warn"]("[CursorPro] 清理失败: " + _0x532653, _0x1db3e3);
        }
      } else {
        if (_0x83ba47["lnDvM"] === _0x83ba47["bgJHu"]) {
          const _0x1cf00a = _0x83ba47["dWzRy"](_0x931219, _0x83ba47["yiKQp"]);
          if (_0x1cf00a["version"]) {
            _0x4e3d1c["log"](_0x83ba47["loOtc"], _0x1cf00a.version);
            return _0x1cf00a.version;
          }
        } else {
          this._postMessage({
            'type': _0x83ba47["IStwX"],
            'success': false,
            'error': _0x48d007["error"] || _0x83ba47["lRVPz"]
          });
        }
      }
    } catch (_0x40371b) {
      this._postMessage({
        'type': _0x83ba47["IStwX"],
        'success': false,
        'error': _0x83ba47["mbyBU"]
      });
    }
  }
  async ["_handleSwitch"]() {
    const _0x3e408e = {
      'QReae': "[CursorPro] WMIC 获取路径失败:",
      'OVooV': "cursorpro.key",
      'SpDeq': 'showToast',
      'PTQOe': "请先激活授权码",
      'YLEHJ': "cursorpro.switchRemaining",
      'eBTDM': 'switched',
      'kCeYh': "cursorpro.switchLimit",
      'omFtC': "userSwitchStatus",
      'XbTBi': function (_0x2bec63, _0x68602f) {
        return _0x2bec63 > _0x68602f;
      },
      'pyrHY': function (_0x56ae50, _0xd521fd) {
        return _0x56ae50 !== _0xd521fd;
      },
      'VqcBN': "kqrkg",
      'bfgAG': "QcuMv"
    };
    const _0x11c87a = this["_context"]["globalState"]["get"](_0x3e408e["OVooV"]);
    if (!_0x11c87a) {
      this._postMessage({
        'type': _0x3e408e["SpDeq"],
        'message': _0x3e408e["PTQOe"],
        'icon': '⚠️'
      });
      return;
    }
    try {
      0x0;
      const _0xbe1a2d = await client_1["switchSeamlessToken"](_0x11c87a);
      if (_0xbe1a2d["switched"]) {
        await this["_context"]["globalState"].update(_0x3e408e["YLEHJ"], _0xbe1a2d["switchRemaining"]);
        this._postMessage({
          'type': _0x3e408e["eBTDM"],
          'success': true,
          'email': _0xbe1a2d["email"],
          'switchRemaining': _0xbe1a2d["switchRemaining"],
          'switchLimit': this["_context"]["globalState"].get(_0x3e408e["kCeYh"]) || 0x64
        });
        const _0x4b2796 = _0xbe1a2d.switchRemaining ?? 0x0;
        this["_postMessage"]({
          'type': _0x3e408e["omFtC"],
          'switchRemaining': _0x4b2796,
          'canSwitch': _0x4b2796 > 0x0,
          'lockedAccount': _0xbe1a2d["email"] ? {
            'email': _0xbe1a2d["email"]
          } : null
        });
      } else if (_0x3e408e["pyrHY"]("yFoId", _0x3e408e.VqcBN)) {
        this["_postMessage"]({
          'type': _0x3e408e["eBTDM"],
          'success': false,
          'error': _0xbe1a2d["message"] || '换号失败'
        });
      } else {
        _0x5b771a = _0x1474f8[0x1];
      }
    } catch (_0x41fa19) {
      if (_0x3e408e["pyrHY"]("CyYkO", _0x3e408e["bfgAG"])) {
        this["_postMessage"]({
          'type': 'switched',
          'success': false,
          'error': "连接服务器失败"
        });
      } else {
        _0xb585cb["log"](_0x3e408e.QReae, _0x5d81f0);
      }
    }
  }
  async ["_writeAccountToLocal"](_0x51678f) {
    const _0x5df214 = {
      'jAygU': function (_0x1a9516, _0x14e09c) {
        return _0x1a9516 === _0x14e09c;
      },
      'lWsen': "Contents",
      'ujkvI': "app",
      'nHvFA': 'out',
      'WYIiR': "workbench",
      'HukDC': "workbench.desktop.main.js",
      'lAqMN': function (_0x4621bc, _0x5e828f) {
        return _0x4621bc === _0x5e828f;
      },
      'uJtvK': "darwin",
      'klERN': "没有写入权限，请在终端执行: sudo chmod -R 777 /Applications/Cursor.app",
      'qVIKa': "linux",
      'uJMyy': "没有写入权限，请使用 sudo 权限运行或修改文件权限",
      'oogyg': 'usageCheckResult',
      'UUaYi': "换号失败",
      'NEcQR': "manualSeamlessSwitched",
      'BPXIz': "proxyUpdated",
      'tWJGN': "修改 hosts 文件失败，请确保有管理员权限",
      'pgeAO': "showToast",
      'yjRVE': function (_0x2c52bd, _0x27885e) {
        return _0x2c52bd === _0x27885e;
      },
      'GXvhF': "hdUrt",
      'tFDff': "Cursor",
      'IFUbF': 'User',
      'RqMFq': "globalStorage",
      'tSjWJ': "state.vscdb",
      'WnTYM': "machineid",
      'ByhnO': "cursorAuth/accessToken",
      'MPCdN': "cursorAuth/refreshToken",
      'hrJHc': function (_0x223704, _0xb12866) {
        return _0x223704 === _0xb12866;
      },
      'atmmx': "rmAmZ",
      'qyuJo': "cursorAuth/cachedEmail",
      'iOndu': "pAlKG",
      'tfSWx': "cursorAuth/stripeMembershipType",
      'UnRdA': function (_0x17b49d, _0x28b8c0) {
        return _0x17b49d !== _0x28b8c0;
      },
      'FNcgD': "ptOKi",
      'JVIPE': 'yLQZc',
      'btARC': "cursorAuth/cachedSignUpType",
      'pTffC': "eNCnU",
      'taMeX': "storage.serviceMachineId",
      'QhViN': function (_0x3ede25, _0x102e15) {
        return _0x3ede25 === _0x102e15;
      },
      'IenCN': "xouQM",
      'ktByd': "telemetry.machineId",
      'ydHCU': 'telemetry.macMachineId',
      'hYviy': "eBQqu",
      'ltTAn': "hCBnO",
      'WtTZw': "[CursorPro] storage.json 已更新",
      'bohEI': "[CursorPro] machineid 文件已更新",
      'tqMKz': 'win32',
      'KhYFK': 'hhZyB',
      'TPjZV': function (_0x4acd6e, _0x4cbd0e) {
        return _0x4acd6e(_0x4cbd0e);
      },
      'dxmvV': "[CursorPro] 注册表写入失败（可能需要管理员权限）:"
    };
    try {
      if ("MClbP" === _0x5df214["GXvhF"]) {
        let _0x9583b2;
        if (_0x5df214["jAygU"](_0x48f1cd, "darwin")) {
          _0x9583b2 = _0x3e2a77.join(this["_cachedCursorPath"], _0x5df214["lWsen"], 'Resources', _0x5df214["ujkvI"], _0x5df214["nHvFA"], 'vs', _0x5df214["WYIiR"], _0x5df214["HukDC"]);
        } else {
          _0x9583b2 = _0x4e0cd1.join(this["_cachedCursorPath"], "resources", _0x5df214["ujkvI"], _0x5df214["nHvFA"], 'vs', _0x5df214["WYIiR"], _0x5df214["HukDC"]);
        }
        if (_0x240b48["existsSync"](_0x9583b2)) {
          return _0x9583b2;
        }
      } else {
        const _0x33651c = process["env"]["APPDATA"] || '';
        const _0x97018c = path["join"](_0x33651c, _0x5df214["tFDff"], _0x5df214["IFUbF"], _0x5df214.RqMFq, _0x5df214["tSjWJ"]);
        const _0x155e62 = path["join"](_0x33651c, "Cursor", _0x5df214["IFUbF"], _0x5df214.RqMFq, 'storage.json');
        const _0x392e23 = path["join"](_0x33651c, _0x5df214["tFDff"], _0x5df214.WnTYM);
        if (fs["existsSync"](_0x97018c)) {
          const _0x37f13d = [];
          if (_0x51678f["accessToken"]) {
            _0x37f13d["push"]([_0x5df214["ByhnO"], _0x51678f.accessToken]);
          }
          if (_0x51678f["refreshToken"]) {
            _0x37f13d["push"]([_0x5df214["MPCdN"], _0x51678f["refreshToken"]]);
          }
          if (_0x51678f.email) {
            if (_0x5df214["atmmx"] === 'mIiuu') {
              _0xfb725b = _0x1931cc["dirname"](_0x2dba3b["trim"]());
            } else {
              _0x37f13d["push"]([_0x5df214.qyuJo, _0x51678f["email"]]);
            }
          }
          if (_0x51678f["membership_type"]) {
            if ('vhcuB' === _0x5df214["iOndu"]) {
              const _0x637d29 = _0x1172a0["platform"];
              let _0x5a842b = '没有写入权限';
              if (_0x5df214["lAqMN"](_0x637d29, _0x5df214.uJtvK)) {
                _0x5a842b = _0x5df214.klERN;
              } else if (_0x5df214["lAqMN"](_0x637d29, _0x5df214["qVIKa"])) {
                _0x5a842b = _0x5df214["uJMyy"];
              }
              this._postMessage({
                'type': 'seamlessInjected',
                'success': false,
                'error': _0x5a842b,
                'needAdmin': true,
                'path': _0x24be1d
              });
              return;
            } else {
              _0x37f13d["push"]([_0x5df214.tfSWx, _0x51678f.membership_type]);
            }
          }
          if (_0x51678f["sign_up_type"]) {
            if (_0x5df214["UnRdA"](_0x5df214["FNcgD"], 'yLQZc')) {
              _0x37f13d["push"]([_0x5df214["btARC"], _0x51678f["sign_up_type"]]);
            } else {
              _0x433bcf = _0x2003b8.dirname(_0x43cf7e);
            }
          }
          if (_0x51678f["serviceMachineId"]) {
            if ('fYfXI' !== _0x5df214["pTffC"]) {
              _0x37f13d.push([_0x5df214["taMeX"], _0x51678f["serviceMachineId"]]);
            } else {
              this._postMessage({
                'type': _0x5df214["oogyg"],
                'success': true,
                'needConfirm': true,
                'costUSD': _0x2db93a["toFixed"](0x2),
                'email': _0x28077f
              });
            }
          }
          0x0;
          await sqlite_1["sqliteSetBatch"](_0x97018c, _0x37f13d);
          console["log"]("[CursorPro] SQLite 数据库已更新");
        }
        if (fs["existsSync"](_0x155e62)) {
          if (_0x5df214["QhViN"](_0x5df214["IenCN"], "nqqWG")) {
            const _0xc468de = _0x12337e.message || _0x352413["error"] || _0x5df214.UUaYi;
            this["_postMessage"]({
              'type': _0x5df214.NEcQR,
              'success': false,
              'error': _0xc468de
            });
          } else {
            const _0x589109 = JSON.parse(fs.readFileSync(_0x155e62, 'utf-8'));
            if (_0x51678f.machineId) {
              _0x589109[_0x5df214["ktByd"]] = _0x51678f["machineId"];
            }
            if (_0x51678f["macMachineId"]) {
              _0x589109['telemetry.macMachineId'] = _0x51678f["macMachineId"];
            }
            if (_0x51678f["devDeviceId"]) {
              _0x589109["telemetry.devDeviceId"] = _0x51678f.devDeviceId;
            }
            if (_0x51678f["sqmId"]) {
              if (_0x5df214.hYviy === _0x5df214["ltTAn"]) {
                this._postMessage({
                  'type': _0x5df214["BPXIz"],
                  'success': false,
                  'error': "修改 hosts 文件失败，请确保有管理员权限"
                });
                this["_postMessage"]({
                  'type': _0x5df214.pgeAO,
                  'message': "需要管理员权限修改 hosts 文件",
                  'icon': '⚠️'
                });
              } else {
                _0x589109["telemetry.sqmId"] = _0x51678f["sqmId"];
              }
            }
            fs["writeFileSync"](_0x155e62, JSON.stringify(_0x589109, null, 0x4));
            console["log"](_0x5df214["WtTZw"]);
          }
        }
        if (_0x51678f.machineId) {
          fs["writeFileSync"](_0x392e23, _0x51678f["machineId"]);
          console["log"](_0x5df214["bohEI"]);
        }
        if (_0x51678f["registryGuid"] && process.platform === _0x5df214["tqMKz"]) {
          if (_0x5df214["KhYFK"] === _0x5df214["KhYFK"]) {
            try {
              const _0x256ef2 = 'reg add "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid /t REG_SZ /d "' + _0x51678f.registryGuid + '" /f';
              await execAsync(_0x256ef2);
              console.log("[CursorPro] 注册表 MachineGuid 已更新");
            } catch (_0x5c0e6a) {
              console.warn(_0x5df214["dxmvV"], _0x5c0e6a);
            }
          } else {
            _0x1b21f9 = _0x5df214["uJMyy"];
          }
        }
        return true;
      }
    } catch (_0x4bd56d) {
      console.error("[CursorPro] 写入本地失败:", _0x4bd56d);
      vscode["window"].showErrorMessage("写入失败: " + _0x4bd56d);
      return false;
    }
  }
  async ["_handleReset"]() {
    const _0x178daf = {
      'SWWgG': '4|0|3|5|2|1',
      'uEcXh': 'reset',
      'eMKRt': 'cursorpro.switchRemaining',
      'FOwUP': "cursorpro.key"
    };
    const _0x46dec9 = '4|0|3|5|2|1'["split"]('|');
    let _0x51aa2c = 0x0;
    while (true) {
      switch (_0x46dec9[_0x51aa2c++]) {
        case '0':
          await this._context.globalState["update"]("cursorpro.expireDate", undefined);
          continue;
        case '1':
          vscode["window"]["showInformationMessage"]("插件已重置");
          continue;
        case '2':
          this["_postMessage"]({
            'type': 'reset',
            'success': true
          });
          continue;
        case '3':
          await this["_context"]["globalState"].update(_0x178daf["eMKRt"], undefined);
          continue;
        case '4':
          await this["_context"]["globalState"]["update"](_0x178daf["FOwUP"], undefined);
          continue;
        case '5':
          0x0;
          extension_1["hideStatusBar"]();
          continue;
      }
      break;
    }
  }
  async ._handleDisable() {
    await this._handleReset();
    vscode.window["showInformationMessage"]("插件已停用");
  }
  async ._checkAdminPrivilege() {
    const _0x53e404 = {
      'fAfUV': "Resources",
      'Llgfj': function (_0x2ea46e, _0x597079) {
        return _0x2ea46e !== _0x597079;
      },
      'pImJb': function (_0x3e6e32, _0x3b5f4c) {
        return _0x3e6e32(_0x3b5f4c);
      },
      'wncyL': "net session 2>nul"
    };
    if (process.platform !== "win32") {
      if ("FIUZS" === 'FIUZS') {
        return true;
      } else {
        _0x2739b0 = _0x1385f5["join"](_0x2a3737, 'Contents', _0x53e404["fAfUV"], 'app', "package.json");
      }
    }
    try {
      await _0x53e404["pImJb"](execAsync, 'reg query "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid 2>nul');
      const _0x41176e = await execAsync(_0x53e404["wncyL"])["catch"](() => ({
        'stdout': '',
        'stderr': 'error'
      }));
      return !_0x41176e.stderr;
    } catch (_0x6d5696) {
      return false;
    }
  }
  async ["_handleResetMachineId"]() {
    const _0x3dfa6c = {
      'lElIk': function (_0x3fa0c5, _0x578287) {
        return _0x3fa0c5 === _0x578287;
      },
      'yJQQD': "darwin",
      'oTJSZ': 'Contents',
      'sJMHZ': 'Resources',
      'tIdJk': "app",
      'rNqfB': "workbench",
      'PaBhO': "workbench.desktop.main.js",
      'cDXTK': "out",
      'mseLD': function (_0x1a7b0a, _0x4298ee) {
        return _0x1a7b0a(_0x4298ee);
      },
      'GpfdI': function (_0x561ce3, _0xd12af6) {
        return _0x561ce3 != _0xd12af6;
      },
      'jGfgE': function (_0x4a5a60, _0x3f3e51) {
        return _0x4a5a60 !== _0x3f3e51;
      },
      'SKKxx': "default",
      'WWGrA': "[CursorPro] Retry connect failed:",
      'zEnsI': 'networkStatus',
      'VmkCj': "seamlessInjected",
      'qukOr': "授权码无效",
      'nczgV': "[CursorPro] where 命令获取路径失败",
      'BmSwh': 'adminPermissionRequired',
      'DUzlm': "crypto",
      'iOJby': "hex",
      'SizrD': "EIFLO",
      'kVXre': "utf-8",
      'OoOvL': "telemetry.macMachineId",
      'NrAHw': "telemetry.devDeviceId",
      'DYlNA': "[CursorPro] storage.json 已更新",
      'oWHkO': function (_0xa487f2, _0x46d29e) {
        return _0xa487f2 === _0x46d29e;
      },
      'hazjj': "OKDBI",
      'sltuA': "[CursorPro] storage.json 更新失败:",
      'kdlCx': "storage.json",
      'yAadA': "AGUOM",
      'dVXng': function (_0x52e3f9, _0x1824a1) {
        return _0x52e3f9 > _0x1824a1;
      },
      'jVCTI': function (_0x36b294, _0x50a679) {
        return _0x36b294 !== _0x50a679;
      },
      'NgEqy': "XygLc",
      'JHBVl': "[CursorPro] machineid 文件已更新",
      'ihOph': "machineid",
      'CUSOw': function (_0x5dca29, _0x1c0e29) {
        return _0x5dca29 > _0x1c0e29;
      },
      'DXmLl': 'UbSjF',
      'XMamy': function (_0x56b6ca, _0x4d16fd) {
        return _0x56b6ca !== _0x4d16fd;
      },
      'TStTT': "SxHmQ",
      'xXEyx': function (_0x41e747, _0x456d1f) {
        return _0x41e747 !== _0x456d1f;
      },
      'iiJFH': 'edqsV',
      'dLXnX': function (_0x626dd4, _0x4c0c64) {
        return _0x626dd4 === _0x4c0c64;
      },
      'IMEYC': function (_0x2f404e, _0x1aec5f) {
        return _0x2f404e === _0x1aec5f;
      },
      'aYwpG': "EvLtz",
      'EdOfO': "[CursorPro] SQLite 更新失败:",
      'wSpvM': "win32",
      'hhSrG': function (_0x247938, _0x48462e) {
        return _0x247938 === _0x48462e;
      },
      'DAvAD': "uxdjv",
      'BkSzQ': "qWEGL",
      'WYomd': "[CursorPro] 注册表 MachineGuid 已更新",
      'ZaPkC': function (_0x59cb29, _0x513094) {
        return _0x59cb29 >= _0x513094;
      },
      'fVMJA': 'machineIdReset',
      'HiGXJ': "机器码重置成功",
      'SEsMN': function (_0x34e2fe, _0x135030) {
        return _0x34e2fe === _0x135030;
      },
      'dGXfv': "gGIGL",
      'pKuzu': function (_0x3f0c5f, _0xdc4a4f) {
        return _0x3f0c5f !== _0xdc4a4f;
      },
      'YfRLt': "KokEE"
    };
    try {
      const _0x5ca938 = process["platform"];
      if (_0x3dfa6c["lElIk"](_0x5ca938, 'win32')) {
        const _0x2196c3 = await this._checkAdminPrivilege();
        if (!_0x2196c3) {
          this["_postMessage"]({
            'type': _0x3dfa6c["BmSwh"]
          });
          return;
        }
      }
      0x0;
      const _0x5e7765 = account_1["getCursorPaths"]();
      const {
        dbPath: _0x4aa0cd,
        storagePath: _0x4a28ca,
        machineidPath: _0x2ec82c
      } = _0x5e7765;
      const _0x2aee57 = _0x3dfa6c["mseLD"](require, _0x3dfa6c["DUzlm"]);
      const _0x13d6be = _0x2aee57["randomBytes"](0x20).toString(_0x3dfa6c.iOJby);
      const _0x4520aa = _0x2aee57.randomBytes(0x20).toString(_0x3dfa6c["iOJby"]);
      const _0x5c9a5c = _0x2aee57["randomUUID"]();
      const _0x295e98 = '{' + _0x2aee57["randomUUID"]()["toUpperCase"]() + '}';
      let _0x42a386 = 0x0;
      let _0x410d72 = [];
      if (fs["existsSync"](_0x4a28ca)) {
        if (_0x3dfa6c["SizrD"] !== "EIFLO") {
          let _0x2d68ba;
          if (_0x3dfa6c["lElIk"](_0x1eaffe, _0x3dfa6c["yJQQD"])) {
            _0x2d68ba = _0x5e5bb2["join"](_0xae64c7, 'Contents', _0x3dfa6c["sJMHZ"], _0x3dfa6c["tIdJk"], "out", 'vs', _0x3dfa6c.rNqfB, _0x3dfa6c["PaBhO"]);
          } else {
            _0x2d68ba = _0x2996fd["join"](_0x5b8900, "resources", "app", _0x3dfa6c["cDXTK"], 'vs', _0x3dfa6c["rNqfB"], _0x3dfa6c.PaBhO);
          }
          if (_0xdd2a05.existsSync(_0x2d68ba)) {
            return _0x2d68ba;
          }
        } else {
          let _0x32a80e = 0x3;
          while (_0x32a80e > 0x0) {
            try {
              const _0x34dbe5 = JSON["parse"](fs.readFileSync(_0x4a28ca, _0x3dfa6c["kVXre"]));
              _0x34dbe5["telemetry.machineId"] = _0x13d6be;
              _0x34dbe5[_0x3dfa6c["OoOvL"]] = _0x4520aa;
              _0x34dbe5[_0x3dfa6c["NrAHw"]] = _0x5c9a5c;
              _0x34dbe5["telemetry.sqmId"] = _0x295e98;
              fs.writeFileSync(_0x4a28ca, JSON["stringify"](_0x34dbe5, null, 0x4));
              console["log"](_0x3dfa6c.DYlNA);
              _0x42a386++;
              break;
            } catch (_0x408e1a) {
              _0x32a80e--;
              if (_0x32a80e === 0x0) {
                if (_0x3dfa6c["oWHkO"]("VbcUu", _0x3dfa6c["hazjj"])) {
                  _0x5162ea.rmSync(_0x9608e0, {
                    'recursive': true,
                    'force': true
                  });
                  _0x12202b++;
                  _0x22902f.log("[CursorPro] 已清理: " + _0x566ae7);
                } else {
                  console["warn"](_0x3dfa6c["sltuA"], _0x408e1a["message"]);
                  _0x410d72["push"](_0x3dfa6c.kdlCx);
                }
              } else {
                await new Promise(_0x1fb805 => setTimeout(_0x1fb805, 0x64));
              }
            }
          }
        }
      }
      {
        if (_0x3dfa6c["oWHkO"](_0x3dfa6c.yAadA, "omtSK")) {
          var _0x2a4a6e = [];
          for (var _0x3716c4 in _0x3f83c7) if (_0x2daf25["prototype"]["hasOwnProperty"]["call"](_0x1170bb, _0x3716c4)) {
            _0x2a4a6e[_0x2a4a6e.length] = _0x3716c4;
          }
          return _0x2a4a6e;
        } else {
          let _0x3e6f5a = 0x3;
          while (_0x3e6f5a > 0x0) {
            try {
              const _0x91b94a = path.dirname(_0x2ec82c);
              if (!fs["existsSync"](_0x91b94a)) {
                if (_0x3dfa6c["jVCTI"]('UjEXX', _0x3dfa6c.NgEqy)) {
                  fs["mkdirSync"](_0x91b94a, {
                    'recursive': true
                  });
                } else {
                  return _0x5ad776;
                }
              }
              fs["writeFileSync"](_0x2ec82c, _0x13d6be);
              console["log"](_0x3dfa6c["JHBVl"]);
              _0x42a386++;
              break;
            } catch (_0x15034e) {
              _0x3e6f5a--;
              if (_0x3e6f5a === 0x0) {
                console["warn"]("[CursorPro] machineid 更新失败:", _0x15034e["message"]);
                _0x410d72.push(_0x3dfa6c["ihOph"]);
              } else {
                await new Promise(_0x128d98 => setTimeout(_0x128d98, 0x64));
              }
            }
          }
        }
      }
      if (fs["existsSync"](_0x4aa0cd)) {
        let _0x46b5f7 = 0x3;
        while (_0x3dfa6c["CUSOw"](_0x46b5f7, 0x0)) {
          if ("UbSjF" === _0x3dfa6c["DXmLl"]) {
            try {
              if ("EvWMl" !== _0x3dfa6c["TStTT"]) {
                const _0x49da25 = _0x2aee57.randomUUID();
                0x0;
                const _0x44bd41 = await sqlite_1.sqliteSetBatch(_0x4aa0cd, [['storage.serviceMachineId', _0x49da25]]);
                if (_0x44bd41) {
                  console["log"]("[CursorPro] SQLite 数据库已更新");
                  _0x42a386++;
                  break;
                } else {
                  if ('edqsV' !== "edqsV") {
                    const _0x480394 = {
                      'JDiGp': function (_0x296746, _0xe4a731) {
                        return _0x3dfa6c["GpfdI"](_0x296746, _0xe4a731);
                      },
                      'UJfLB': function (_0x5d0056, _0x5c568b) {
                        return _0x3dfa6c["jGfgE"](_0x5d0056, _0x5c568b);
                      },
                      'YIhbu': _0x3dfa6c["SKKxx"],
                      'hQSHL': function (_0x2ecb26, _0x249a15, _0x4919c7, _0x430d9c) {
                        return _0x2ecb26(_0x249a15, _0x4919c7, _0x430d9c);
                      },
                      'iFgQw': function (_0x3a1ffc, _0x7ebf92, _0x57e599) {
                        return _0x3a1ffc(_0x7ebf92, _0x57e599);
                      }
                    };
                    var _0x4b98ab = function (_0x111b39) {
                      _0x4b98ab = _0x2160f7.getOwnPropertyNames || function (_0x130daa) {
                        var _0x41f8fb = [];
                        for (var _0x670bc2 in _0x130daa) if (_0x75a24e.prototype["hasOwnProperty"]["call"](_0x130daa, _0x670bc2)) {
                          _0x41f8fb[_0x41f8fb["length"]] = _0x670bc2;
                        }
                        return _0x41f8fb;
                      };
                      return _0x3dfa6c["mseLD"](_0x4b98ab, _0x111b39);
                    };
                    return function (_0x20bb6b) {
                      if (_0x20bb6b && _0x20bb6b["__esModule"]) {
                        return _0x20bb6b;
                      }
                      var _0x2c00be = {};
                      if (_0x480394["JDiGp"](_0x20bb6b, null)) {
                        var _0x11069f = _0x4b98ab(_0x20bb6b);
                        for (var _0x2599df = 0x0; _0x2599df < _0x11069f["length"]; _0x2599df++) {
                          if (_0x3dfa6c["jGfgE"](_0x11069f[_0x2599df], _0x480394["YIhbu"])) {
                            _0x480394["hQSHL"](_0x674927, _0x2c00be, _0x20bb6b, _0x11069f[_0x2599df]);
                          }
                        }
                      }
                      _0x480394["iFgQw"](_0x240286, _0x2c00be, _0x20bb6b);
                      return _0x2c00be;
                    };
                  } else {
                    throw new Error("sqliteSetBatch 返回 false");
                  }
                }
              } else {
                throw new _0x1a22ee("sqliteSetBatch 返回 false");
              }
            } catch (_0xfa28ae) {
              _0x46b5f7--;
              if (_0x3dfa6c["dLXnX"](_0x46b5f7, 0x0)) {
                if (_0x3dfa6c["IMEYC"]('pUuQI', _0x3dfa6c["aYwpG"])) {
                  _0x964a59["error"](_0x3dfa6c["WWGrA"], _0x9baa98);
                  this["_postMessage"]({
                    'type': 'networkStatus',
                    'online': false
                  });
                } else {
                  console["warn"](_0x3dfa6c["EdOfO"], _0xfa28ae["message"]);
                  _0x410d72["push"]("SQLite");
                }
              } else {
                await new Promise(_0x1eb4ea => setTimeout(_0x1eb4ea, 0x1f4));
              }
            }
          } else {
            _0x38b61c = _0xf3fbd6["trim"]();
          }
        }
      }
      if (_0x5ca938 === _0x3dfa6c.wSpvM) {
        if (_0x3dfa6c["DAvAD"] === 'uxdjv') {
          const _0xc2bf8b = _0x2aee57["randomUUID"]();
          try {
            if (_0x3dfa6c["jVCTI"](_0x3dfa6c.BkSzQ, "lGcMr")) {
              await execAsync('reg add "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid /t REG_SZ /d "' + _0xc2bf8b + '" /f');
              console.log(_0x3dfa6c["WYomd"]);
              _0x42a386++;
            } else {
              this["_postMessage"]({
                'type': _0x3dfa6c["VmkCj"],
                'success': false,
                'error': _0x29f22d["error"] || _0x3dfa6c["qukOr"]
              });
              return;
            }
          } catch (_0x2a0e47) {
            console.warn("[CursorPro] 注册表更新失败（需要管理员权限），已跳过");
            _0x410d72["push"]("注册表");
          }
        } else {
          _0x45c2d2 = _0x2be321["getOwnPropertyNames"] || function (_0x5aff3b) {
            var _0x2ac6fe = [];
            for (var _0x56e238 in _0x5aff3b) if (_0x17dada["prototype"]["hasOwnProperty"]["call"](_0x5aff3b, _0x56e238)) {
              _0x2ac6fe[_0x2ac6fe.length] = _0x56e238;
            }
            return _0x2ac6fe;
          };
          return _0x6e782f(_0x5c5de0);
        }
      }
      if (_0x3dfa6c["ZaPkC"](_0x42a386, 0x2)) {
        this["_postMessage"]({
          'type': _0x3dfa6c["fVMJA"],
          'success': true,
          'needRestart': true,
          'message': _0x3dfa6c["dVXng"](_0x410d72["length"], 0x0) ? "机器码重置成功（" + _0x410d72["join"](", ") + " 更新失败，不影响使用）" : _0x3dfa6c["HiGXJ"]
        });
      } else if ("uIJXM" === _0x3dfa6c["dGXfv"]) {
        _0xb3a25e["log"]("[CursorPro] 尝试路径失败:", _0x35bfac, _0x26703c);
      } else {
        this._postMessage({
          'type': "showToast",
          'message': "重置部分失败: " + _0x410d72["join"](", ") + "。请先完全关闭 Cursor 再试",
          'icon': '⚠️'
        });
      }
    } catch (_0x2bd1a8) {
      if ("KokEE" !== _0x3dfa6c.YfRLt) {
        _0x2757ce["log"](_0x3dfa6c["nczgV"]);
      } else {
        this["_postMessage"]({
          'type': "showToast",
          'message': "重置机器码失败: " + _0x2bd1a8,
          'icon': '❌'
        });
      }
    }
  }
  ._generateRandomMAC() {
    const _0x351246 = {
      'gsyrk': function (_0x2456e7, _0x15dd24) {
        return _0x2456e7(_0x15dd24);
      },
      'lYDrY': 'crypto',
      'RmNIb': function (_0x562f1e, _0xc0a2a9) {
        return _0x562f1e & _0xc0a2a9;
      },
      'WCBzn': function (_0x233015, _0x3ca3bf) {
        return _0x233015 | _0x3ca3bf;
      }
    };
    const _0x539ee8 = _0x351246["gsyrk"](require, _0x351246["lYDrY"]);
    const _0x58dc79 = _0x539ee8["randomBytes"](0x6);
    _0x58dc79[0x0] = _0x351246["RmNIb"](_0x351246["WCBzn"](_0x58dc79[0x0], 0x2), 0xfe);
    return Array.from(_0x58dc79).map(_0x2d538f => _0x2d538f["toString"](0x10)["padStart"](0x2, '0'))["join"](':');
  }
  async ._handleDisableUpdate() {
    const _0xcdd27f = {
      'SlsxX': function (_0x2f9c04, _0x4c19d7) {
        return _0x2f9c04 + _0x4c19d7;
      },
      'obUIO': "cursor-updater",
      'MTNiO': function (_0x2e30f3, _0x4ab64b) {
        return _0x2e30f3 !== _0x4ab64b;
      },
      'Bhmmc': 'Fkark',
      'WHolg': "IvZQp",
      'vJjHJ': 'showToast',
      'KkOxm': "已禁用 Cursor 自动更新"
    };
    try {
      const _0x24fe79 = process["env"]["LOCALAPPDATA"] || '';
      const _0xac3e10 = path["join"](_0x24fe79, _0xcdd27f["obUIO"]);
      if (fs["existsSync"](_0xac3e10)) {
        if (_0xcdd27f["MTNiO"](_0xcdd27f["Bhmmc"], _0xcdd27f["Bhmmc"])) {
          return false;
        } else if (fs.statSync(_0xac3e10).isDirectory()) {
          if (_0xcdd27f["MTNiO"](_0xcdd27f.WHolg, "IvZQp")) {
            _0x5481a7 = _0x5e122b.substring(0x0, _0x4f63e3) + _0x214640["substring"](_0xcdd27f["SlsxX"](_0x5cc883, 0x7));
          } else {
            fs["rmSync"](_0xac3e10, {
              'recursive': true,
              'force': true
            });
          }
        } else {
          fs["unlinkSync"](_0xac3e10);
        }
      }
      fs["writeFileSync"](_0xac3e10, '');
      this["_postMessage"]({
        'type': 'showToast',
        'message': _0xcdd27f["KkOxm"],
        'icon': '✅'
      });
    } catch (_0x387797) {
      this._postMessage({
        'type': _0xcdd27f["vJjHJ"],
        'message': "禁用自动更新失败: " + _0x387797,
        'icon': '❌'
      });
    }
  }
  async ["_handleCleanEnv"]() {
    const _0x5d7007 = {
      'QgDaW': "networkStatus",
      'rCPOJ': "[CursorPro] WMIC 获取路径失败",
      'FZidX': "[CursorPro] 找到 Cursor 版本:",
      'nLBbF': "路径:",
      'tRjSQ': "announcement",
      'BlfQc': "获取公告失败",
      'JlTFY': 'activated',
      'cqICS': "授权码无效",
      'JPunF': "[CursorPro] 注入失败，未找到任何注入点",
      'KMKzx': "[CursorPro] 文件路径:",
      'xFYQT': "[CursorPro] 文件大小:",
      'hxRZC': "[CursorPro] 未找到的注入点:",
      'SPguA': '_showNotification',
      'IjZFI': "seamlessInjected",
      'JiWRI': "Cursor 版本不兼容，注入点未找到",
      'aPXBq': function (_0x449fed, _0x1e0222) {
        return _0x449fed === _0x1e0222;
      },
      'pYIFs': function (_0x3cef7a, _0x51f2f4) {
        return _0x3cef7a in _0x51f2f4;
      },
      'JBwTr': 'get',
      'koIoR': function (_0x43e103, _0x5178fd) {
        return _0x43e103 === _0x5178fd;
      },
      'PGlXD': "win32",
      'GTTuL': function (_0x5b1681, _0x264692) {
        return _0x5b1681 === _0x264692;
      },
      'Psmij': "rhIFB",
      'gYxAu': 'xYuSE',
      'MuQDV': function (_0x4cb02b, _0x14cda9) {
        return _0x4cb02b(_0x14cda9);
      },
      'IKcBt': "pkill -f Cursor",
      'RPLYj': function (_0x1c7600, _0xe03586) {
        return _0x1c7600 === _0xe03586;
      },
      'MGVKs': function (_0x4fe688, _0x467499) {
        return _0x4fe688 !== _0x467499;
      },
      'ryaos': 'uKgvW',
      'voPhc': "Cursor",
      'lXGbz': "cursor-updater",
      'xKriv': ".cursor",
      'ZoVAa': 'CTJTi',
      'MCBOh': "YZsoE",
      'pGLVT': "jAgIw",
      'OUBfk': "darwin",
      'FYnvF': 'Caches',
      'uIkRt': "Library",
      'tQzIF': "Logs",
      'HlGXa': "WKeGp",
      'EtSsM': "rxZvP",
      'FNyIR': "pLQpn",
      'WPZrs': 'udDhy',
      'jyFFs': '.cache',
      'hMrGj': ".local",
      'ISlsh': "share",
      'yteSk': 'lkchx',
      'Prgty': "SPIaC",
      'WVkud': "FbJEH",
      'okltc': "UEqoH"
    };
    try {
      if (process["platform"] === _0x5d7007.PGlXD) {
        await execAsync("taskkill /F /IM Cursor.exe")["catch"](() => {});
      } else if (_0x5d7007["Psmij"] === _0x5d7007["gYxAu"]) {
        this._postMessage({
          'type': "showToast",
          'message': "禁用自动更新失败: " + _0xaf40e5,
          'icon': '❌'
        });
      } else {
        await _0x5d7007["MuQDV"](execAsync, _0x5d7007["IKcBt"]).catch(() => {});
      }
      await new Promise(_0x30bca7 => setTimeout(_0x30bca7, 0x7d0));
      const _0x27dda7 = process.env["APPDATA"] || '';
      const _0x2dfaf0 = process["env"].LOCALAPPDATA || '';
      const _0x2bcaef = process["env"].HOME || process.env["USERPROFILE"] || '';
      let _0x1e982b = 0x0;
      if (process.platform === _0x5d7007["PGlXD"]) {
        if (_0x5d7007["MGVKs"]('OMLAe', _0x5d7007["ryaos"])) {
          const _0x680500 = [path.join(_0x27dda7, _0x5d7007["voPhc"]), path["join"](_0x2dfaf0, _0x5d7007["voPhc"]), path["join"](_0x2dfaf0, _0x5d7007.lXGbz), path["join"](_0x2bcaef, _0x5d7007["xKriv"])];
          for (const _0x395cca of _0x680500) {
            if (_0x5d7007["ZoVAa"] !== "CTJTi") {
              this._postMessage({
                'type': 'userSwitchStatus',
                'valid': false,
                'switchRemaining': 0x0,
                'canSwitch': false,
                'error': '获取状态失败'
              });
            } else {
              try {
                if (fs["existsSync"](_0x395cca)) {
                  if (_0x5d7007["aPXBq"](_0x5d7007["MCBOh"], _0x5d7007["pGLVT"])) {
                    this["_postMessage"]({
                      'type': _0x5d7007["QgDaW"],
                      'online': _0x1e9bca
                    });
                  } else {
                    fs["rmSync"](_0x395cca, {
                      'recursive': true,
                      'force': true
                    });
                    _0x1e982b++;
                    console["log"]("[CursorPro] 已清理: " + _0x395cca);
                  }
                }
              } catch (_0x47ea0c) {
                console["warn"]("[CursorPro] 清理失败: " + _0x395cca, _0x47ea0c);
              }
            }
          }
        } else {
          _0x305e73["log"](_0x5d7007["rCPOJ"]);
        }
      } else {
        if (process["platform"] === _0x5d7007["OUBfk"]) {
          const _0x173109 = [path["join"](_0x2bcaef, "Library", "Application Support", _0x5d7007["voPhc"]), path["join"](_0x2bcaef, "Library", _0x5d7007["FYnvF"], _0x5d7007["voPhc"]), path["join"](_0x2bcaef, _0x5d7007.uIkRt, _0x5d7007["tQzIF"], _0x5d7007.voPhc), path.join(_0x2bcaef, 'Library', "Application Support", 'Caches', _0x5d7007.lXGbz), path["join"](_0x2bcaef, _0x5d7007["xKriv"])];
          for (const _0x151011 of _0x173109) {
            if ("ZwnwK" === "juOiE") {
              const _0x4223b9 = _0x6afa13["readFileSync"](_0x263f1d, 'utf-8');
              const _0x4ffeb2 = _0x2673e3["parse"](_0x4223b9);
              if (_0x4ffeb2["version"]) {
                _0x4e128b["log"](_0x5d7007["FZidX"], _0x4ffeb2["version"], _0x5d7007["nLBbF"], _0x3afc55);
                return _0x4ffeb2["version"];
              }
            } else {
              try {
                if (fs["existsSync"](_0x151011)) {
                  if (_0x5d7007["HlGXa"] !== _0x5d7007["EtSsM"]) {
                    fs["rmSync"](_0x151011, {
                      'recursive': true,
                      'force': true
                    });
                    _0x1e982b++;
                  } else {
                    this["_postMessage"]({
                      'type': _0x5d7007["tRjSQ"],
                      'success': false,
                      'error': _0x1b6792.error || _0x5d7007["BlfQc"]
                    });
                  }
                }
              } catch (_0x52cb05) {
                if (_0x5d7007.FNyIR !== _0x5d7007["WPZrs"]) {
                  console["warn"]("[CursorPro] 清理失败: " + _0x151011, _0x52cb05);
                } else {
                  this["_postMessage"]({
                    'type': _0x5d7007["JlTFY"],
                    'success': false,
                    'error': _0xd37ccd["error"] || _0x5d7007["cqICS"]
                  });
                }
              }
            }
          }
        } else {
          const _0x305f11 = [path["join"](_0x2bcaef, ".config", _0x5d7007["voPhc"]), path.join(_0x2bcaef, _0x5d7007["jyFFs"], _0x5d7007["voPhc"]), path["join"](_0x2bcaef, _0x5d7007["hMrGj"], _0x5d7007.ISlsh, _0x5d7007.voPhc), path["join"](_0x2bcaef, _0x5d7007.xKriv)];
          for (const _0x5bbdfa of _0x305f11) {
            if ('lkchx' !== _0x5d7007["yteSk"]) {
              _0x17a266["error"](_0x5d7007["JPunF"]);
              _0xc8224e["error"](_0x5d7007["KMKzx"], _0x45b7c8);
              _0x557053["error"](_0x5d7007["xFYQT"], _0x27fd6a.length);
              _0x3c4a59["error"](_0x5d7007.hxRZC, _0x23fb79);
              const _0x1c19d0 = _0x54cc25["includes"]('_showNotification');
              const _0x605a0e = _0x4b5d6c["includes"]("getItems()");
              _0x24e1b7.error("[CursorPro] 包含 _showNotification:", _0x1c19d0);
              _0x16679d["error"]("[CursorPro] 包含 getItems():", _0x605a0e);
              this["_postMessage"]({
                'type': _0x5d7007["IjZFI"],
                'success': false,
                'error': _0x5d7007["JiWRI"],
                'details': "路径: " + _0x8d33d3
              });
              return;
            } else {
              try {
                if (fs.existsSync(_0x5bbdfa)) {
                  fs.rmSync(_0x5bbdfa, {
                    'recursive': true,
                    'force': true
                  });
                  _0x1e982b++;
                }
              } catch (_0x3fff64) {
                if ('SPIaC' === _0x5d7007["Prgty"]) {
                  console["warn"]("[CursorPro] 清理失败: " + _0x5bbdfa, _0x3fff64);
                } else {
                  if (_0x5a8ee0 === _0x67147f) {
                    _0x11f2b9 = _0x3ddb74;
                  }
                  var _0x5443a8 = _0x3e5510["getOwnPropertyDescriptor"](_0xf4f8d, _0x23f58b);
                  if (!_0x5443a8 || (_0x5d7007["pYIFs"]('get', _0x5443a8) ? !_0x30ad0e["__esModule"] : _0x5443a8["writable"] || _0x5443a8["configurable"])) {
                    _0x5443a8 = {
                      'enumerable': true,
                      'get': function () {
                        return _0x3769fc[_0x59f7bf];
                      }
                    };
                  }
                  _0xdc785.defineProperty(_0x25dfad, _0x4b142f, _0x5443a8);
                }
              }
            }
          }
        }
      }
      vscode["window"]["showInformationMessage"]("✅ Cursor 环境清理完成！已清理 " + _0x1e982b + " 个目录。请重新启动 Cursor。");
    } catch (_0x559de5) {
      if (_0x5d7007["WVkud"] !== _0x5d7007["okltc"]) {
        vscode["window"].showErrorMessage("清理失败: " + _0x559de5);
      } else {
        return;
      }
    }
  }
  ._cleanProxySettings() {
    const _0x476eaf = {
      'rbZoX': "/etc/hosts",
      'eHWqT': function (_0x4595b3, _0x51481f) {
        return _0x4595b3 > _0x51481f;
      },
      'UIOhf': 'versionCheck',
      'jYVrR': "app",
      'vgDUh': "package.json",
      'rqoZM': '连接服务器失败',
      'PbRuC': 'uJNLm',
      'ctBOw': function (_0x3ad726, _0x1a1bc9) {
        return _0x3ad726 === _0x1a1bc9;
      },
      'YNRuA': function (_0x374e35, _0x5f2806) {
        return _0x374e35 !== _0x5f2806;
      },
      'AcPSo': "Cursor",
      'XeYdv': 'User',
      'sRZng': "darwin",
      'EYltU': 'Library',
      'cngrf': "Application Support",
      'bQVqg': "settings.json",
      'lMMGf': "UAknb",
      'eEioj': ".config",
      'aTJcA': "TSToT",
      'YGjhE': function (_0xb1f254, _0x285077) {
        return _0xb1f254 in _0x285077;
      },
      'TTFqW': "tQfhG",
      'dtgRq': 'xvUoy',
      'KqxTd': "utf-8",
      'ANrMY': "[CursorPro] 清理 settings.json 代理配置失败:"
    };
    try {
      if (_0x476eaf["PbRuC"] === _0x476eaf["PbRuC"]) {
        const _0x232e3c = process["platform"];
        const _0x35e9f7 = process["env"]["HOME"] || process.env["USERPROFILE"] || '';
        let _0x50dd63;
        if (_0x476eaf["ctBOw"](_0x232e3c, "win32")) {
          if (_0x476eaf["YNRuA"]("xHyzt", "xHyzt")) {
            return _0x476eaf["rbZoX"];
          } else {
            const _0x3f558b = process.env["APPDATA"] || '';
            _0x50dd63 = path.join(_0x3f558b, _0x476eaf["AcPSo"], _0x476eaf["XeYdv"], "settings.json");
          }
        } else {
          if (_0x232e3c === _0x476eaf["sRZng"]) {
            _0x50dd63 = path["join"](_0x35e9f7, _0x476eaf["EYltU"], _0x476eaf["cngrf"], _0x476eaf["AcPSo"], 'User', _0x476eaf["bQVqg"]);
          } else {
            if (_0x476eaf["ctBOw"](_0x476eaf["lMMGf"], 'UAknb')) {
              _0x50dd63 = path["join"](_0x35e9f7, _0x476eaf["eEioj"], _0x476eaf["AcPSo"], _0x476eaf["XeYdv"], _0x476eaf["bQVqg"]);
            } else {
              const _0x13402f = _0xb498dc["version"];
              const _0x50bf1b = _0x227cb4.CURRENT_VERSION;
              const _0x310335 = _0x476eaf["eHWqT"](this["_compareVersions"](_0x13402f, _0x50bf1b), 0x0);
              this["_postMessage"]({
                'type': _0x476eaf["UIOhf"],
                'success': true,
                'currentVersion': _0x50bf1b,
                'latestVersion': _0x13402f,
                'hasUpdate': _0x310335
              });
            }
          }
        }
        if (!fs.existsSync(_0x50dd63)) {
          return;
        }
        const _0x3b1f5e = fs["readFileSync"](_0x50dd63, 'utf-8');
        let _0x2d1395;
        try {
          _0x2d1395 = JSON.parse(_0x3b1f5e);
        } catch {
          if (_0x476eaf.aTJcA === _0x476eaf.aTJcA) {
            return;
          } else {
            _0x374c70 = _0xf2eaf5.join(_0x313a74, "resources", _0x476eaf["jYVrR"], _0x476eaf.vgDUh);
          }
        }
        const _0x312520 = ["http.proxy", "http.proxyStrictSSL", "http.proxySupport", "cursor.general.disableHttp2", "http.noProxy"];
        let _0x163e93 = false;
        for (const _0x2ee1a1 of _0x312520) {
          if (_0x2ee1a1 in _0x2d1395) {
            _0x163e93 = true;
            delete _0x2d1395[_0x2ee1a1];
          }
        }
        if (_0x163e93) {
          if (_0x476eaf["TTFqW"] !== 'xvUoy') {
            fs["writeFileSync"](_0x50dd63, JSON["stringify"](_0x2d1395, null, 0x4), _0x476eaf["KqxTd"]);
            console["log"]("[CursorPro] 已清理 settings.json 中的旧代理配置");
          } else {
            _0x54658c = _0x115a6a[0x1]["trim"]();
          }
        }
      } else {
        const _0x75d65c = _0x5b4ad7?.["message"] || '连接服务器失败';
        this["_postMessage"]({
          'type': "manualSeamlessSwitched",
          'success': false,
          'error': _0x75d65c
        });
      }
    } catch (_0xaf9b9c) {
      console["warn"](_0x476eaf.ANrMY, _0xaf9b9c);
    }
  }
  ["_getHostsPath"]() {
    const _0x1afd5f = {
      'IIhaI': "win32",
      'rhwiN': "C:\\Windows\\System32\\drivers\\etc\\hosts",
      'WCHqe': '/etc/hosts'
    };
    return process.platform === _0x1afd5f["IIhaI"] ? _0x1afd5f["rhwiN"] : '/etc/hosts';
  }
  ._readHostsFile() {
    const _0x2eb328 = {
      'wAevF': "[CursorPro] 写入本地失败:",
      'sUhUV': function (_0x5ed9b2, _0x485978) {
        return _0x5ed9b2 !== _0x485978;
      },
      'hsoXL': 'SLTdx',
      'XvGHn': 'utf-8',
      'LHIiR': "[CursorPro] Read hosts error:"
    };
    try {
      if (_0x2eb328["sUhUV"]('SLTdx', _0x2eb328["hsoXL"])) {
        _0x154660["error"](_0x2eb328["wAevF"], _0x1f3d21);
        _0x12820c.window["showErrorMessage"]("写入失败: " + _0x430c52);
        return false;
      } else {
        const _0x49f82f = this["_getHostsPath"]();
        if (fs["existsSync"](_0x49f82f)) {
          return fs.readFileSync(_0x49f82f, _0x2eb328["XvGHn"]);
        }
      }
    } catch (_0x280006) {
      console["error"](_0x2eb328["LHIiR"], _0x280006);
    }
    return '';
  }
  ["_hasHostsConfig"]() {
    const _0x18cd4d = this["_readHostsFile"]();
    return _0x18cd4d["includes"](this["HOSTS_MARKER_START"]);
  }
  async ._grantHostsWritePermission() {
    const _0x32c62b = {
      'vkbEE': "seamlessStatus",
      'seTZS': '检测状态失败',
      'hKgsG': function (_0x4a5bc9, _0x2bfac2) {
        return _0x4a5bc9 !== _0x2bfac2;
      },
      'ScmlY': "win32",
      'HqZOI': "ffBKI",
      'Qwoeu': function (_0x36c14a, _0x3b36cd) {
        return _0x36c14a(_0x3b36cd);
      },
      'mzHlg': "[CursorPro] Hosts file permission granted to user:",
      'wVYbp': "[CursorPro] Grant hosts permission error:"
    };
    if (_0x32c62b["hKgsG"](process["platform"], _0x32c62b["ScmlY"])) {
      return false;
    }
    try {
      if (_0x32c62b["HqZOI"] === _0x32c62b["HqZOI"]) {
        const _0x4dd7b0 = this._getHostsPath();
        const _0x52e208 = process["env"].USERNAME || '';
        if (!_0x52e208) {
          return false;
        }
        const _0xb2d318 = _0x4dd7b0["replace"](/\\/g, "\\\\");
        const _0x1a66f9 = "powershell -WindowStyle Hidden -Command \"Start-Process powershell -ArgumentList '-WindowStyle Hidden -Command icacls \\\"" + _0xb2d318 + '\" /grant ' + _0x52e208 + ":M' -Verb RunAs -Wait\"";
        await _0x32c62b["Qwoeu"](execAsync, _0x1a66f9);
        this["_hostsPermissionGranted"] = true;
        console["log"](_0x32c62b["mzHlg"], _0x52e208);
        return true;
      } else {
        this["_postMessage"]({
          'type': _0x32c62b.vkbEE,
          'is_injected': false,
          'error': _0x32c62b["seTZS"]
        });
      }
    } catch (_0x32d96e) {
      console["error"](_0x32c62b["wVYbp"], _0x32d96e);
      return false;
    }
  }
  async ["_writeHostsFile"](_0x5922a3) {
    const _0x499688 = {
      'xBPFl': "usageCheckResult",
      'JhZQT': "未激活授权码",
      'iNsae': 'cursorAuth/cachedSignUpType',
      'AmHRk': "cursorAuth/stripeMembershipType",
      'FOcWe': function (_0x5324f3, _0x2a612f) {
        return _0x5324f3 === _0x2a612f;
      },
      'KudFK': "win32",
      'Vogwl': "qQhXV",
      'JcomX': 'utf-8',
      'ERSCs': "[CursorPro] Direct write failed, trying to grant permission",
      'oXrgE': 'gFBAJ',
      'YmFQv': 'UnshK',
      'CGqqu': "cursorpro_hosts_temp.txt",
      'vkEWS': function (_0x12ee8c, _0x39fa65) {
        return _0x12ee8c !== _0x39fa65;
      },
      'OaUGz': "XVhkW",
      'ofVDg': "kizvY",
      'NrWkg': function (_0x3a76ad, _0x4ab4f9) {
        return _0x3a76ad(_0x4ab4f9);
      },
      'sPvNi': "ipconfig /flushdns",
      'iDcQt': function (_0x54a20c, _0x2484fe) {
        return _0x54a20c === _0x2484fe;
      },
      'HLfqb': "darwin",
      'vgoUd': "/tmp/hosts_cursor_temp",
      'HGnBv': function (_0x134b08, _0x2d8a5b) {
        return _0x134b08(_0x2d8a5b);
      },
      'jDqga': 'BDewf',
      'txnlf': "[CursorPro] Write hosts error:"
    };
    const _0x2983c4 = this["_getHostsPath"]();
    try {
      if (_0x499688["FOcWe"](process.platform, _0x499688.KudFK)) {
        let _0x27620a = false;
        try {
          if (_0x499688["Vogwl"] !== _0x499688["Vogwl"]) {
            _0x3ec235 = _0x26751d["dirname"](_0x1b0534["trim"]());
          } else {
            fs["writeFileSync"](_0x2983c4, _0x5922a3, _0x499688["JcomX"]);
            _0x27620a = true;
          }
        } catch (_0x2a820d) {
          console["log"](_0x499688["ERSCs"]);
        }
        if (!_0x27620a) {
          if (!this._hostsPermissionGranted) {
            const _0x1cf639 = await this["_grantHostsWritePermission"]();
            if (_0x1cf639) {
              if (_0x499688["oXrgE"] === _0x499688["YmFQv"]) {
                this._postMessage({
                  'type': _0x499688.xBPFl,
                  'success': false,
                  'error': _0x499688["JhZQT"]
                });
                return;
              } else {
                try {
                  fs["writeFileSync"](_0x2983c4, _0x5922a3, _0x499688["JcomX"]);
                  _0x27620a = true;
                } catch (_0x22fb5c) {
                  console["log"]("[CursorPro] Write still failed after permission grant");
                }
              }
            }
          }
        }
        if (!_0x27620a) {
          const _0x1e3a86 = path["join"](process["env"]["TEMP"] || '', _0x499688.CGqqu);
          fs["writeFileSync"](_0x1e3a86, _0x5922a3, _0x499688["JcomX"]);
          const _0x2cf526 = _0x1e3a86["replace"](/\\/g, "\\\\");
          const _0x456ea4 = _0x2983c4["replace"](/\\/g, "\\\\");
          const _0x2a923f = "powershell -WindowStyle Hidden -Command \"Start-Process powershell -ArgumentList '-WindowStyle Hidden -Command Copy-Item -Path \\\"" + _0x2cf526 + '\" -Destination \"' + _0x456ea4 + "\\\" -Force' -Verb RunAs -Wait\"";
          await execAsync(_0x2a923f);
          try {
            if (_0x499688["OaUGz"] !== _0x499688["ofVDg"]) {
              fs["unlinkSync"](_0x1e3a86);
            } else {
              _0x23b2c1["push"]([_0x499688["iNsae"], _0x2e0cc7.sign_up_type]);
            }
          } catch {}
        }
        try {
          await _0x499688["NrWkg"](execAsync, _0x499688["sPvNi"]);
          console["log"]("[CursorPro] Windows DNS 缓存已刷新");
        } catch (_0x460c7f) {
          console.warn("[CursorPro] Windows DNS 刷新失败:", _0x460c7f);
        }
      } else {
        if (_0x499688["iDcQt"](process["platform"], _0x499688.HLfqb)) {
          const _0x24a472 = _0x499688["vgoUd"];
          fs["writeFileSync"](_0x24a472, _0x5922a3, _0x499688["JcomX"]);
          const _0x22f069 = "do shell script \"cp '" + _0x24a472 + "' '" + _0x2983c4 + "' && rm '" + _0x24a472 + "' && dscacheutil -flushcache && killall -HUP mDNSResponder\" with administrator privileges";
          await _0x499688["HGnBv"](execAsync, 'osascript -e "' + _0x22f069.replace(/"/g, "\\\"") + "\"");
        } else {
          fs["writeFileSync"](_0x2983c4, _0x5922a3, _0x499688["JcomX"]);
        }
      }
      return true;
    } catch (_0x4e285f) {
      console["error"](_0x499688["txnlf"], _0x4e285f);
      return false;
    }
  }
  async ["_handleToggleProxy"](_0x45fe86, _0x2bcba7) {
    const _0x55a623 = {
      'ejdVR': "[CursorPro] 检测无感换号状态失败:",
      'PEste': function (_0x53a002, _0x4c22fe) {
        return _0x53a002 === _0x4c22fe;
      },
      'hgedP': "win32",
      'qGQVl': "[CursorPro] macOS 获取进程路径失败:",
      'uJGtI': function (_0x48017f, _0x5c2c7c) {
        return _0x48017f !== _0x5c2c7c;
      },
      'JOyUC': "owyly",
      'abtRx': "JZnQC",
      'bPNQC': "cursorpro.key",
      'XKRmO': 'cursorpro.expireDate',
      'lrUSI': "proxyUpdated",
      'wngsU': '请先激活授权码',
      'bNcBC': 'showToast',
      'wbUaU': "nMubd",
      'qvcRi': function (_0x6220c6, _0x46b6bf) {
        return _0x6220c6 > _0x46b6bf;
      },
      'rBQDv': "授权码已过期，无法开启免魔法",
      'RrtRU': function (_0x572eb6, _0x46c0a4) {
        return _0x572eb6 !== _0x46c0a4;
      },
      'PoFgx': "BHFHl",
      'xXref': function (_0x1b909c, _0x5c9bad) {
        return _0x1b909c + _0x5c9bad;
      },
      'HwXSS': function (_0x576fb0, _0x41a4c1) {
        return _0x576fb0 !== _0x41a4c1;
      },
      'LwgUG': "ejFIc",
      'yTNgQ': "QrGmP",
      'rATBP': "免魔法已关闭",
      'jtzgG': "修改 hosts 文件失败，请确保有管理员权限",
      'SfnWE': '更新配置失败'
    };
    try {
      if ("JCMUi" === "JCMUi") {
        if (_0x45fe86) {
          if (_0x55a623["uJGtI"](_0x55a623.JOyUC, _0x55a623["abtRx"])) {
            const _0x2e87c9 = this["_context"]["globalState"]["get"](_0x55a623["bPNQC"]);
            const _0x4818f7 = this._context.globalState.get('cursorpro.expireDate');
            if (!_0x2e87c9) {
              this["_postMessage"]({
                'type': _0x55a623["lrUSI"],
                'success': false,
                'error': _0x55a623["wngsU"]
              });
              this["_postMessage"]({
                'type': _0x55a623["bNcBC"],
                'message': '请先激活授权码',
                'icon': '⚠️'
              });
              return;
            }
            if (_0x4818f7) {
              if (_0x55a623["wbUaU"] === _0x55a623.wbUaU) {
                const _0x13c1c7 = new Date(_0x4818f7)["getTime"]();
                if (_0x55a623["qvcRi"](Date["now"](), _0x13c1c7)) {
                  this._postMessage({
                    'type': _0x55a623["lrUSI"],
                    'success': false,
                    'error': _0x55a623.rBQDv
                  });
                  this["_postMessage"]({
                    'type': _0x55a623["bNcBC"],
                    'message': _0x55a623["rBQDv"],
                    'icon': '⚠️'
                  });
                  return;
                }
              } else {
                _0xdb849d["error"]("[CursorPro] 检测无感换号状态失败:", _0x27cca9);
                return false;
              }
            }
          } else {
            return true;
          }
        }
        this["_cleanProxySettings"]();
        let _0x41dcbc = this["_readHostsFile"]();
        const _0x8cbdf8 = _0x41dcbc["indexOf"](this["HOSTS_MARKER_START"]);
        const _0x5529db = _0x41dcbc["indexOf"](this.HOSTS_MARKER_END);
        if (_0x55a623["uJGtI"](_0x8cbdf8, -0x1) && _0x5529db !== -0x1) {
          if (_0x55a623["PoFgx"] !== 'jcvMA') {
            _0x41dcbc = _0x41dcbc.substring(0x0, _0x8cbdf8) + _0x41dcbc["substring"](_0x55a623["xXref"](_0x5529db, this.HOSTS_MARKER_END["length"]));
          } else {
            return _0x55a623["PEste"](_0x52d6bb["platform"], _0x55a623.hgedP) ? "C:\\Windows\\System32\\drivers\\etc\\hosts" : "/etc/hosts";
          }
        }
        _0x41dcbc = _0x41dcbc["replace"](/\n{3,}/g, "\n\n")["trim"]();
        if (_0x45fe86) {
          const _0x3c2da2 = this.CURSOR_DOMAINS.map(_0x2b32f6 => this.SNI_PROXY_IP + " " + _0x2b32f6)["join"]("\n");
          const _0x12c61b = "\n\n" + this.HOSTS_MARKER_START + "\n" + _0x3c2da2 + "\n" + this["HOSTS_MARKER_END"] + "\n";
          _0x41dcbc += _0x12c61b;
        }
        const _0x5b508c = await this._writeHostsFile(_0x41dcbc);
        if (_0x5b508c) {
          if (_0x55a623.LwgUG !== _0x55a623["yTNgQ"]) {
            0x0;
            await client_1["updateProxyConfig"](_0x45fe86, this["SNI_PROXY_IP"]);
            this["_postMessage"]({
              'type': _0x55a623["lrUSI"],
              'success': true,
              'enabled': _0x45fe86,
              'url': this.SNI_PROXY_IP
            });
            this["_postMessage"]({
              'type': _0x55a623["bNcBC"],
              'message': _0x45fe86 ? "免魔法已开启" : _0x55a623["rATBP"],
              'icon': '✅'
            });
          } else {
            _0x5dcacb.log("[CursorPro] 快捷方式解析获取路径失败");
          }
        } else {
          this["_postMessage"]({
            'type': "proxyUpdated",
            'success': false,
            'error': _0x55a623["jtzgG"]
          });
          this._postMessage({
            'type': "showToast",
            'message': "需要管理员权限修改 hosts 文件",
            'icon': '⚠️'
          });
        }
      } else {
        _0x2faaed["warn"](_0x55a623["qGQVl"], _0x591cf9);
      }
    } catch (_0x15bb87) {
      console["error"]("[CursorPro] Toggle proxy error:", _0x15bb87);
      this["_postMessage"]({
        'type': _0x55a623["lrUSI"],
        'success': false,
        'error': _0x55a623["SfnWE"]
      });
    }
  }
  async ["_handleGetProxyStatus"]() {
    const _0x2c5a98 = {
      'fZAIy': "[CursorPro] Get proxy status error:",
      'wipaS': "proxyStatus"
    };
    try {
      const _0x45986e = this["_hasHostsConfig"]();
      this._postMessage({
        'type': "proxyStatus",
        'enabled': _0x45986e,
        'url': _0x45986e ? this.SNI_PROXY_IP : ''
      });
    } catch (_0x590417) {
      console.error(_0x2c5a98["fZAIy"], _0x590417);
      this._postMessage({
        'type': _0x2c5a98["wipaS"],
        'enabled': false,
        'url': ''
      });
    }
  }
  async ["_handleGetSeamlessStatus"]() {
    const _0x5ae0f5 = {
      'KFUBS': 'seamlessStatus',
      'rCNDh': '未找到'
    };
    try {
      const _0x95ad53 = await this["_getWorkbenchPathAsync"]();
      let _0x571ba2 = false;
      if (_0x95ad53 && fs.existsSync(_0x95ad53)) {
        const _0x16bc8d = fs["readFileSync"](_0x95ad53, 'utf-8');
        _0x571ba2 = this["_checkInjected"](_0x16bc8d);
      }
      this["_postMessage"]({
        'type': _0x5ae0f5["KFUBS"],
        'is_injected': _0x571ba2,
        'workbench_path': _0x95ad53 || '未找到'
      });
    } catch (_0x4253d3) {
      this["_postMessage"]({
        'type': "seamlessStatus",
        'is_injected': false,
        'error': "检测状态失败"
      });
    }
  }
  async ._getCursorInstallPath() {
    const _0x56e2a7 = {
      'Dikkd': "showToast",
      'jsXpS': "请先激活授权码",
      'YOVDn': "更新配置失败",
      'iTlfT': "[CursorPro] 创建备份文件",
      'yLNTm': 'resources',
      'GeHhf': 'app',
      'CXUfC': "package.json",
      'UtnZu': "[CursorPro] 读取账号失败:",
      'gnUSM': "[CursorPro] 写入文件失败:",
      'bYxaW': function (_0x423a3a, _0x5db055) {
        return _0x423a3a === _0x5db055;
      },
      'EgKGn': "EPERM",
      'EAHLk': function (_0x337fa2, _0x2cea6d) {
        return _0x337fa2 === _0x2cea6d;
      },
      'WjWcW': "EACCES",
      'MQZgl': "EROFS",
      'oengj': function (_0x277036, _0x403852) {
        return _0x277036 === _0x403852;
      },
      'Aarxw': 'darwin',
      'DJbBl': "没有写入权限，请在终端执行: sudo chmod -R 777 /Applications/Cursor.app",
      'aREDm': "seamlessInjected",
      'iIXMD': "usageCheckResult",
      'BDJnl': function (_0x1e4a2f, _0x534c0a) {
        return _0x1e4a2f(_0x534c0a);
      },
      'DtDgA': function (_0x29bc62, _0x322a2b) {
        return _0x29bc62 < _0x322a2b;
      },
      'mmvWR': "[CursorPro] SQLite 更新失败:",
      'oaRrk': "SQLite",
      'CTVdA': function (_0x74a645, _0x1120bf) {
        return _0x74a645 * _0x1120bf;
      },
      'Uuffn': 'userSwitchStatus',
      'rBiqx': "未激活授权码",
      'rQFft': "cursorPath",
      'RnudW': "[CursorPro] 使用用户配置的 Cursor 路径:",
      'PVaIE': "win32",
      'XfqQZ': function (_0x9c7d0d, _0x5e3a66) {
        return _0x9c7d0d(_0x5e3a66);
      },
      'DeasY': function (_0x4abb75, _0x582177) {
        return _0x4abb75 !== _0x582177;
      },
      'AsIZj': "qoucU",
      'nqiCC': 'DFFnS',
      'QVuwP': "[CursorPro] WMIC 获取路径失败",
      'dRsNK': 'YbsJH',
      'jErMS': "KgPWK",
      'NyxMG': 'powershell -Command "Get-Process Cursor -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Path"',
      'wEuDv': function (_0x124977, _0x7c188e) {
        return _0x124977 !== _0x7c188e;
      },
      'XOHNV': "PCmsj",
      'TGItL': "[CursorPro] PowerShell Get-Process 获取路径失败",
      'thwli': 'reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s /f "Cursor" 2>nul | findstr "InstallLocation"',
      'VMcWU': 'xkLFN',
      'QxSsa': "VRqTq",
      'dCyzn': "qGOpJ",
      'fdUBf': "WEzFK",
      'PIiyE': "[CursorPro] 注册表方法1获取路径失败",
      'sbJjp': function (_0x20ef8a, _0x2ae693) {
        return _0x20ef8a(_0x2ae693);
      },
      'ZzzNm': "reg query \"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\" /s /f \"Cursor\" 2>nul | findstr \"InstallLocation\"",
      'nbZaF': function (_0x1cbd3c, _0x4a6cb7) {
        return _0x1cbd3c === _0x4a6cb7;
      },
      'wbtDv': "vnDbD",
      'cNdLq': 'xFoOA',
      'FZvwj': 'OHDPB',
      'UneuY': 'Microsoft',
      'qsIby': "Windows",
      'EHZof': 'Cursor.lnk',
      'jjkbK': "C:\\ProgramData",
      'BtFbH': "Start Menu",
      'JdBJc': function (_0x28f75d, _0x183780) {
        return _0x28f75d(_0x183780);
      },
      'jsxnQ': function (_0x136514, _0x280034) {
        return _0x136514 === _0x280034;
      },
      'qBUXV': "[CursorPro] 快捷方式解析获取路径失败",
      'exySU': "vhjCP",
      'TGkVo': function (_0x23968b, _0x7071) {
        return _0x23968b !== _0x7071;
      },
      'suGMP': "BQAEU",
      'UFTPT': "[CursorPro] where 命令获取路径失败",
      'DmbzX': "C:\\Program Files",
      'pezWM': "ProgramFiles(x86)",
      'siiYr': "Programs",
      'qYQbK': "Cursor",
      'IrvuT': 'cursor',
      'GSVlF': "AppData",
      'MCVpB': "Local",
      'PDSZm': "XrXcG",
      'EgLjx': function (_0x28fb08, _0xcbe128) {
        return _0x28fb08 !== _0xcbe128;
      },
      'HILVh': "iDOKM",
      'smRnq': "EZQju",
      'goLBO': function (_0x534585, _0x3cba48) {
        return _0x534585(_0x3cba48);
      },
      'PfsJK': function (_0x1edda8, _0x24c322) {
        return _0x1edda8 !== _0x24c322;
      },
      'SZhcT': "kFqGj",
      'NkvWo': "AvPWh",
      'fIoaQ': function (_0x241ec0, _0x2ed30c) {
        return _0x241ec0 === _0x2ed30c;
      },
      'AEQys': "DLzJi",
      'DMxiK': "fmKaB",
      'KCchE': "ps -eo comm,args | grep -i \"[C]ursor\" | grep -v \"grep\" | head -1",
      'oSNCM': "[CursorPro] macOS 获取进程路径失败:",
      'vFKuA': function (_0x3f2aba, _0x3b57d7) {
        return _0x3f2aba !== _0x3b57d7;
      },
      'BzqQS': "LPxcr",
      'Iiavz': function (_0x518563, _0x266c3c) {
        return _0x518563(_0x266c3c);
      },
      'DTxsT': "mdfind \"kMDItemCFBundleIdentifier == 'com.todesktop.*cursor*'\" 2>/dev/null | head -1",
      'Duhra': '/Applications/Cursor.app',
      'TWejg': function (_0x5bd29f, _0x55a6c4) {
        return _0x5bd29f(_0x55a6c4);
      },
      'hHnTm': function (_0x24d237, _0x40656e) {
        return _0x24d237(_0x40656e);
      },
      'ytsfa': '/bin',
      'fYZrC': 'BDrEe',
      'TLLsB': "which cursor 2>/dev/null",
      'IGQIN': "RTVew",
      'rbFqJ': "[CursorPro] Linux 获取进程路径失败:",
      'WgRyf': "/opt/Cursor",
      'XOLnJ': '/opt/cursor',
      'fxGJt': "/usr/share/cursor",
      'lzEMa': "/usr/lib/cursor",
      'gQXjY': "Applications/cursor",
      'EghBP': "[CursorPro] 获取 Cursor 安装路径失败:"
    };
    if (this["_cachedCursorPath"]) {
      return this["_cachedCursorPath"];
    }
    const _0x39cd5d = vscode["workspace"]["getConfiguration"]("cursorpro");
    const _0x3bf8b8 = _0x39cd5d["get"](_0x56e2a7.rQFft);
    if (_0x3bf8b8 && fs["existsSync"](_0x3bf8b8)) {
      console["log"](_0x56e2a7["RnudW"], _0x3bf8b8);
      this._cachedCursorPath = _0x3bf8b8;
      return _0x3bf8b8;
    }
    const _0x51335c = process["platform"];
    let _0x36d8e8 = null;
    try {
      if (_0x51335c === _0x56e2a7.PVaIE) {
        try {
          const {
            stdout: _0x446f65
          } = await execAsync("wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul");
          if (_0x446f65) {
            if (_0x56e2a7["DeasY"](_0x56e2a7["AsIZj"], _0x56e2a7["AsIZj"])) {
              this["_postMessage"]({
                'type': _0x56e2a7["Dikkd"],
                'message': _0x56e2a7.jsXpS,
                'icon': '⚠️'
              });
              return;
            } else {
              const _0x19ca83 = _0x446f65["match"](/ExecutablePath=(.+)/);
              if (_0x19ca83 && _0x19ca83[0x1]) {
                if (_0x56e2a7["nqiCC"] === "qzRkG") {
                  this._postMessage({
                    'type': "showToast",
                    'message': "重置机器码失败: " + _0x51bc1d,
                    'icon': '❌'
                  });
                } else {
                  const _0x27a427 = _0x19ca83[0x1]["trim"]();
                  _0x36d8e8 = path["dirname"](_0x27a427);
                }
              }
            }
          }
        } catch (_0x4c944d) {
          console["log"](_0x56e2a7.QVuwP);
        }
        if (!_0x36d8e8) {
          if ('YbsJH' !== _0x56e2a7["jErMS"]) {
            try {
              const {
                stdout: _0x2ac2d3
              } = await _0x56e2a7["BDJnl"](execAsync, _0x56e2a7.NyxMG);
              if (_0x2ac2d3 && _0x2ac2d3["trim"]()) {
                _0x36d8e8 = path["dirname"](_0x2ac2d3["trim"]());
              }
            } catch (_0x387539) {
              if (_0x56e2a7["wEuDv"](_0x56e2a7.XOHNV, "idSrD")) {
                console.log(_0x56e2a7["TGItL"]);
              } else if (_0x36e365["includes"](_0x216fbb.scode)) {
                _0x51a668 = _0x5d60b0["replace"](_0x562774["scode"], _0x1ac061["replacement"]);
                _0x15853d["push"](_0x1d4997["name"]);
              } else {
                _0x41fc0e["push"](_0x551686["name"]);
              }
            }
          } else {
            _0x86b57c = _0xcd7e5a["dirname"](_0x337963);
          }
        }
        if (!_0x36d8e8) {
          try {
            const {
              stdout: _0x1bbadc
            } = await execAsync(_0x56e2a7["thwli"]);
            if (_0x1bbadc && _0x1bbadc.trim()) {
              const _0x53b6fb = _0x1bbadc.match(/InstallLocation\s+REG_SZ\s+(.+)/);
              if (_0x53b6fb && _0x53b6fb[0x1] && fs["existsSync"](_0x53b6fb[0x1]["trim"]())) {
                if (_0x56e2a7["VMcWU"] !== _0x56e2a7.QxSsa) {
                  _0x36d8e8 = _0x53b6fb[0x1]["trim"]();
                } else {
                  this["_postMessage"]({
                    'type': "proxyUpdated",
                    'success': false,
                    'error': _0x56e2a7["jsXpS"]
                  });
                  this["_postMessage"]({
                    'type': _0x56e2a7["Dikkd"],
                    'message': _0x56e2a7["jsXpS"],
                    'icon': '⚠️'
                  });
                  return;
                }
              }
            }
          } catch (_0x4253cf) {
            if (_0x56e2a7["dCyzn"] !== _0x56e2a7["fdUBf"]) {
              console.log(_0x56e2a7.PIiyE);
            } else {
              this["_postMessage"]({
                'type': 'seamlessConfigUpdated',
                'success': false,
                'error': _0x56e2a7["YOVDn"]
              });
            }
          }
        }
        if (!_0x36d8e8) {
          try {
            const {
              stdout: _0xf5d246
            } = await execAsync(_0x56e2a7["ZzzNm"]);
            if (_0xf5d246 && _0xf5d246.trim()) {
              const _0x3c2cd7 = _0xf5d246["match"](/InstallLocation\s+REG_SZ\s+(.+)/);
              if (_0x3c2cd7 && _0x3c2cd7[0x1] && fs.existsSync(_0x3c2cd7[0x1].trim())) {
                if (_0x56e2a7["nbZaF"](_0x56e2a7["wbtDv"], _0x56e2a7["cNdLq"])) {
                  _0x371f53 = _0x3146b2["replace"](_0x262100["scode"], _0x35b030["replacement"]);
                  _0x2f13c6.push(_0x495b54.name);
                } else {
                  _0x36d8e8 = _0x3c2cd7[0x1]["trim"]();
                }
              }
            }
          } catch (_0x38448a) {
            console["log"]("[CursorPro] 注册表方法2获取路径失败");
          }
        }
        if (!_0x36d8e8) {
          if (_0x56e2a7["FZvwj"] !== 'ASYNt') {
            try {
              const _0x4a36af = path["join"](process["env"]["APPDATA"] || '', _0x56e2a7["UneuY"], _0x56e2a7.qsIby, "Start Menu", 'Programs', _0x56e2a7["EHZof"]);
              const _0x3876ac = path["join"](_0x56e2a7["jjkbK"], _0x56e2a7["UneuY"], 'Windows', _0x56e2a7["BtFbH"], "Programs", _0x56e2a7["EHZof"]);
              for (const _0x20745d of [_0x4a36af, _0x3876ac]) {
                if (fs["existsSync"](_0x20745d)) {
                  const {
                    stdout: _0x321537
                  } = await execAsync("powershell -Command \"(New-Object -ComObject WScript.Shell).CreateShortcut('" + _0x20745d["replace"](/'/g, "''") + "').TargetPath\"");
                  if (_0x321537 && _0x321537.trim() && fs.existsSync(_0x321537["trim"]())) {
                    if (_0x56e2a7["jsxnQ"]("EzvlI", "EzvlI")) {
                      _0x36d8e8 = path["dirname"](_0x321537["trim"]());
                      break;
                    } else {
                      _0x5839cf = ["/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js"];
                    }
                  }
                }
              }
            } catch (_0x628be0) {
              console["log"](_0x56e2a7["qBUXV"]);
            }
          } else {
            const _0x41d381 = _0x1d7b98.match(/ExecutablePath=(.+)/);
            if (_0x41d381 && _0x41d381[0x1]) {
              const _0x311d7f = _0x41d381[0x1]["trim"]();
              _0x7495 = _0x387799["dirname"](_0x311d7f);
            }
          }
        }
        if (!_0x36d8e8) {
          if (_0x56e2a7["exySU"] === _0x56e2a7["exySU"]) {
            try {
              const {
                stdout: _0x4d3618
              } = await _0x56e2a7["JdBJc"](execAsync, "where cursor 2>nul");
              if (_0x4d3618 && _0x4d3618["trim"]()) {
                const _0x1e390f = _0x4d3618.trim()["split"]("\n");
                for (const _0x4be01a of _0x1e390f) {
                  const _0x2817ed = _0x4be01a.trim();
                  if (_0x2817ed && fs.existsSync(_0x2817ed)) {
                    _0x36d8e8 = path["dirname"](_0x2817ed);
                    break;
                  }
                }
              }
            } catch (_0x2b8ad6) {
              if ("BQAEU" !== _0x56e2a7["suGMP"]) {
                _0x33db66["copyFileSync"](_0x51579c, _0x931655);
                _0x261bd5["log"](_0x56e2a7["iTlfT"]);
              } else {
                console["log"](_0x56e2a7["UFTPT"]);
              }
            }
          } else {
            const _0x4c6948 = _0x4dafc4[0x1].trim();
            _0x373919 = _0x57ec2c.dirname(_0x4c6948);
            _0x543724 = _0x3fcb44["join"](_0x2ba35f, _0x56e2a7["yLNTm"], _0x56e2a7["GeHhf"], _0x56e2a7["CXUfC"]);
          }
        }
        if (!_0x36d8e8) {
          const _0x526dcd = process["env"].LOCALAPPDATA || '';
          const _0x11abe2 = process["env"]["USERPROFILE"] || '';
          const _0x5a2b8c = process["env"]["ProgramFiles"] || _0x56e2a7["DmbzX"];
          const _0x53bae9 = process["env"][_0x56e2a7["pezWM"]] || "C:\\Program Files (x86)";
          const _0x7ed789 = [path["join"](_0x526dcd, _0x56e2a7.siiYr, _0x56e2a7.qYQbK), path.join(_0x526dcd, _0x56e2a7["siiYr"], _0x56e2a7["IrvuT"]), path["join"](_0x11abe2, _0x56e2a7["GSVlF"], _0x56e2a7.MCVpB, _0x56e2a7.siiYr, _0x56e2a7.qYQbK), path.join(_0x5a2b8c, _0x56e2a7.qYQbK), path["join"](_0x53bae9, "Cursor"), path.join(_0x526dcd, _0x56e2a7["qYQbK"]), path["join"](_0x526dcd, _0x56e2a7["IrvuT"])];
          for (const _0x5e748e of _0x7ed789) {
            if (_0x56e2a7["EAHLk"]("mDWBe", _0x56e2a7["PDSZm"])) {
              _0x4e428d.error(_0x56e2a7["UtnZu"], _0x4ee69e);
              return [];
            } else {
              if (_0x5e748e && fs["existsSync"](_0x5e748e)) {
                _0x36d8e8 = _0x5e748e;
                break;
              }
            }
          }
        }
      } else {
        if (_0x51335c === _0x56e2a7["Aarxw"]) {
          if (_0x56e2a7["EgLjx"](_0x56e2a7.HILVh, "mPbmb")) {
            try {
              if ("VYhDm" === _0x56e2a7["smRnq"]) {
                _0x3f27c6.error(_0x56e2a7["gnUSM"], _0x16e0a9);
                if (_0x56e2a7["bYxaW"](_0x3fa137["code"], _0x56e2a7["EgKGn"]) || _0x56e2a7["EAHLk"](_0x50c56a["code"], _0x56e2a7["WjWcW"]) || _0x2fdaaf.code === _0x56e2a7.MQZgl) {
                  const _0x2f5e07 = _0xf7d812["platform"];
                  let _0xee0d40 = "没有写入权限";
                  if (_0x56e2a7["oengj"](_0x2f5e07, 'darwin')) {
                    _0xee0d40 = _0x56e2a7["DJbBl"];
                  } else if (_0x2f5e07 === "linux") {
                    _0xee0d40 = "没有写入权限，请使用 sudo 权限运行或修改文件权限";
                  }
                  this["_postMessage"]({
                    'type': _0x56e2a7["aREDm"],
                    'success': false,
                    'error': _0xee0d40,
                    'needAdmin': true,
                    'path': _0x4f0e82
                  });
                  return;
                }
                throw _0x47d908;
              } else {
                const {
                  stdout: _0x369a56
                } = await _0x56e2a7["goLBO"](execAsync, "lsof -c Cursor 2>/dev/null | grep \"txt\" | grep -i \"Cursor.app\" | head -1 | awk '{print $9}'");
                if (_0x369a56 && _0x369a56.trim()) {
                  if (_0x56e2a7.SZhcT !== _0x56e2a7["SZhcT"]) {
                    this["_postMessage"]({
                      'type': "usageCheckResult",
                      'success': true,
                      'needConfirm': false
                    });
                  } else {
                    const _0x257e0d = _0x369a56.trim()["match"](/(.+\.app)/);
                    if (_0x257e0d) {
                      if (_0x56e2a7["bYxaW"](_0x56e2a7.NkvWo, 'hsffN')) {
                        this["_postMessage"]({
                          'type': _0x56e2a7["iIXMD"],
                          'success': true,
                          'needConfirm': false
                        });
                        return;
                      } else {
                        _0x36d8e8 = _0x257e0d[0x1];
                      }
                    }
                  }
                }
              }
            } catch (_0x1b82a1) {}
            if (!_0x36d8e8) {
              try {
                if (_0x56e2a7["fIoaQ"](_0x56e2a7.AEQys, _0x56e2a7["DMxiK"])) {
                  const _0x3b6ec9 = _0x4396d5.data["usage"] || {};
                  const _0x318ca7 = _0x56e2a7["BDJnl"](_0x5a3f82, _0x3b6ec9["totalCostUSD"] || 0x0);
                  if (_0x56e2a7["DtDgA"](_0x318ca7, 0xa)) {
                    this["_postMessage"]({
                      'type': _0x56e2a7.iIXMD,
                      'success': true,
                      'needConfirm': true,
                      'costUSD': _0x318ca7.toFixed(0x2),
                      'email': _0x430d08
                    });
                  } else {
                    this["_postMessage"]({
                      'type': _0x56e2a7["iIXMD"],
                      'success': true,
                      'needConfirm': false
                    });
                  }
                } else {
                  const {
                    stdout: _0x58b89f
                  } = await execAsync(_0x56e2a7["KCchE"]);
                  if (_0x58b89f && _0x58b89f.trim()) {
                    const _0x488389 = _0x58b89f["match"](/(\/.+\.app)/);
                    if (_0x488389) {
                      _0x36d8e8 = _0x488389[0x1];
                    }
                  }
                }
              } catch (_0x58c36b) {
                console.warn(_0x56e2a7["oSNCM"], _0x58c36b);
              }
            }
            if (!_0x36d8e8) {
              if (_0x56e2a7["vFKuA"]("LPxcr", _0x56e2a7["BzqQS"])) {
                _0x178033.error("[CursorPro] Write hosts error:", _0x1a091f);
                return false;
              } else {
                try {
                  const {
                    stdout: _0x45fa41
                  } = await execAsync(_0x56e2a7["DTxsT"]);
                  if (_0x45fa41 && _0x45fa41.trim() && fs.existsSync(_0x45fa41["trim"]())) {
                    _0x36d8e8 = _0x45fa41.trim();
                  }
                } catch (_0x141dcf) {}
              }
            }
            if (!_0x36d8e8 && fs["existsSync"]('/Applications/Cursor.app')) {
              _0x36d8e8 = _0x56e2a7["Duhra"];
            }
          } else {
            _0x221adf["warn"](_0x56e2a7["mmvWR"], _0x45ce1f.message);
            _0x2ae3cb["push"](_0x56e2a7["oaRrk"]);
          }
        } else {
          try {
            const {
              stdout: _0x11564d
            } = await execAsync('pgrep -f "[c]ursor" | head -1');
            const _0x5dd0f3 = _0x11564d && _0x11564d.trim();
            if (_0x5dd0f3) {
              const {
                stdout: _0x447245
              } = await _0x56e2a7["hHnTm"](execAsync, "readlink -f /proc/" + _0x5dd0f3 + "/exe 2>/dev/null");
              if (_0x447245 && _0x447245["trim"]()) {
                const _0x11b963 = _0x447245["trim"]();
                _0x36d8e8 = path.dirname(_0x11b963);
                if (_0x36d8e8["endsWith"](_0x56e2a7["ytsfa"])) {
                  _0x36d8e8 = path["dirname"](_0x36d8e8);
                }
              }
            }
          } catch (_0x27a28d) {}
          if (!_0x36d8e8) {
            if ("BDrEe" !== _0x56e2a7["fYZrC"]) {
              let _0x34acf5 = '';
              const _0x3634b6 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
              for (let _0x1963ff = 0x0; _0x1963ff < 0x20; _0x1963ff++) {
                _0x34acf5 += _0x3634b6.charAt(_0x5a7f9b["floor"](_0x142a7a["random"]() * _0x3634b6["length"]));
              }
              return _0x34acf5;
            } else {
              try {
                const {
                  stdout: _0x400a70
                } = await _0x56e2a7["BDJnl"](execAsync, _0x56e2a7["TLLsB"]);
                if (_0x400a70 && _0x400a70.trim()) {
                  const _0x44bb60 = await execAsync('readlink -f "' + _0x400a70.trim() + '" 2>/dev/null');
                  if (_0x44bb60.stdout && _0x44bb60["stdout"].trim()) {
                    _0x36d8e8 = path["dirname"](_0x44bb60["stdout"].trim());
                    if (_0x36d8e8["endsWith"]('/bin')) {
                      if (_0x56e2a7["oengj"](_0x56e2a7.IGQIN, "ZRSMl")) {
                        this["_postMessage"]({
                          'type': 'userSwitchStatus',
                          'valid': false,
                          'switchRemaining': 0x0,
                          'canSwitch': false,
                          'error': _0x56e2a7["rBiqx"]
                        });
                        return;
                      } else {
                        _0x36d8e8 = path["dirname"](_0x36d8e8);
                      }
                    }
                  }
                }
              } catch (_0x1d7835) {
                console["warn"](_0x56e2a7["rbFqJ"], _0x1d7835);
              }
            }
          }
          if (!_0x36d8e8) {
            const _0x38357a = [_0x56e2a7["WgRyf"], _0x56e2a7["XOLnJ"], _0x56e2a7["fxGJt"], _0x56e2a7["lzEMa"], path["join"](process["env"]["HOME"] || '', ".local/share/cursor"), path.join(process["env"]["HOME"] || '', _0x56e2a7["gQXjY"])];
            for (const _0x3a8856 of _0x38357a) {
              if (fs.existsSync(_0x3a8856)) {
                _0x36d8e8 = _0x3a8856;
                break;
              }
            }
          }
        }
      }
    } catch (_0x2440bb) {
      console["error"](_0x56e2a7["EghBP"], _0x2440bb);
    }
    if (_0x36d8e8) {
      this._cachedCursorPath = _0x36d8e8;
    }
    return _0x36d8e8;
  }
  ._getWorkbenchPath() {
    return this["_getWorkbenchPathSync"]();
  }
  ._getWorkbenchPathSync() {
    const _0x45dfd9 = {
      'UfpAf': "storage.serviceMachineId",
      'Anviz': "[CursorPro] machineid 更新失败:",
      'VVCFs': "machineid",
      'JyreV': function (_0x2669b9, _0x3af5b1) {
        return _0x2669b9(_0x3af5b1);
      },
      'LuKVI': 'crypto',
      'SWJRm': function (_0xc6cc6a, _0x1e79ba) {
        return _0xc6cc6a & _0x1e79ba;
      },
      'FQssd': function (_0x36d4a3, _0x3f9411) {
        return _0x36d4a3 !== _0x3f9411;
      },
      'eUATr': function (_0x5176f0, _0x2f72df) {
        return _0x5176f0 === _0x2f72df;
      },
      'jTUqv': "darwin",
      'VLslV': 'xuLZV',
      'UWqNM': "app",
      'sQFsh': "out",
      'eRJjA': "workbench",
      'gkqWe': "workbench.desktop.main.js",
      'ZSOkm': function (_0x45c79f, _0x381d17) {
        return _0x45c79f !== _0x381d17;
      },
      'SccyE': "kWVws",
      'dVhNW': "resources",
      'VfwmP': function (_0x239346, _0xe3f08f) {
        return _0x239346 === _0xe3f08f;
      },
      'NyLwi': "/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js",
      'aJjyB': 'qRWfN',
      'bWpPz': "/opt/Cursor/resources/app/out/vs/workbench/workbench.desktop.main.js"
    };
    const _0x476275 = process["platform"];
    if (this._cachedCursorPath) {
      if (_0x45dfd9["FQssd"]('zZyLK', "PQRiM")) {
        let _0x3205e4;
        if (_0x45dfd9["eUATr"](_0x476275, _0x45dfd9["jTUqv"])) {
          if (_0x45dfd9["eUATr"]("xuLZV", 'xuLZV')) {
            _0x3205e4 = path.join(this["_cachedCursorPath"], 'Contents', "Resources", _0x45dfd9["UWqNM"], _0x45dfd9["sQFsh"], 'vs', _0x45dfd9.eRJjA, _0x45dfd9["gkqWe"]);
          } else {
            _0x3e2976["push"]([_0x45dfd9["UfpAf"], _0x4568af["serviceMachineId"]]);
          }
        } else if (_0x45dfd9["ZSOkm"]("XbfIf", _0x45dfd9["SccyE"])) {
          _0x3205e4 = path["join"](this["_cachedCursorPath"], _0x45dfd9.dVhNW, "app", _0x45dfd9["sQFsh"], 'vs', _0x45dfd9["eRJjA"], "workbench.desktop.main.js");
        } else {
          _0x575999["warn"](_0x45dfd9["Anviz"], _0x58392c.message);
          _0x8af8ae["push"](_0x45dfd9["VVCFs"]);
        }
        if (fs.existsSync(_0x3205e4)) {
          return _0x3205e4;
        }
      } else {
        return [];
      }
    }
    if (_0x45dfd9["eUATr"](_0x476275, 'win32')) {
      return null;
    }
    let _0x5a8c19 = [];
    if (_0x45dfd9["VfwmP"](_0x476275, _0x45dfd9.jTUqv)) {
      _0x5a8c19 = [_0x45dfd9["NyLwi"]];
    } else {
      if ('DESET' !== _0x45dfd9["aJjyB"]) {
        _0x5a8c19 = [_0x45dfd9["bWpPz"], '/usr/share/cursor/resources/app/out/vs/workbench/workbench.desktop.main.js'];
      } else {
        const _0x495a3b = _0x45dfd9["JyreV"](_0x32b48c, 'crypto');
        const _0xfc487e = _0x495a3b["randomBytes"](0x6);
        _0xfc487e[0x0] = _0x45dfd9["SWJRm"](_0xfc487e[0x0] | 0x2, 0xfe);
        return _0x55363f["from"](_0xfc487e)["map"](_0x210fd8 => _0x210fd8.toString(0x10)["padStart"](0x2, '0'))["join"](':');
      }
    }
    for (const _0x3c46cb of _0x5a8c19) {
      if (fs["existsSync"](_0x3c46cb)) {
        return _0x3c46cb;
      }
    }
    return null;
  }
  async ["_getWorkbenchPathAsync"]() {
    const _0x333f76 = {
      'diJhY': "C:\\Program Files",
      'BHmwx': "ProgramFiles(x86)",
      'xDKiN': "C:\\Program Files (x86)",
      'aIUry': "Programs",
      'oemiO': "Cursor",
      'wNjLv': "resources",
      'BzPhh': "package.json",
      'dNHJx': "cursor",
      'JBwsK': "app",
      'NoEGQ': "AppData",
      'GOKzJ': "Local",
      'okosv': 'versionCheck',
      'ktVBs': function (_0x175f78, _0x5a924f) {
        return _0x175f78 === _0x5a924f;
      },
      'fYTsi': "EUUHA",
      'idevD': "eXeOK",
      'SJHtk': function (_0x48c702, _0x410996) {
        return _0x48c702 === _0x410996;
      },
      'AJPrD': "darwin",
      'qcilt': function (_0x48c64d, _0x367af2) {
        return _0x48c64d === _0x367af2;
      },
      'yQEWX': "vUlDT",
      'Knhyl': "Contents",
      'NPYXr': "Resources",
      'xDNVo': "out",
      'Lnhsa': "workbench",
      'ejmIv': "workbench.desktop.main.js",
      'yfprZ': "dtGAS"
    };
    const _0x4a5df6 = process.platform;
    const _0x1a6628 = await this["_getCursorInstallPath"]();
    if (_0x1a6628) {
      if (_0x333f76["ktVBs"](_0x333f76["fYTsi"], _0x333f76["idevD"])) {
        const _0x56cab4 = _0x12c65b[0x1]["trim"]();
        _0x13e8cf = _0x13c1c8["dirname"](_0x56cab4);
      } else {
        let _0x469a72;
        if (_0x4a5df6 === _0x333f76["AJPrD"]) {
          if (_0x333f76["qcilt"](_0x333f76["yQEWX"], _0x333f76.yQEWX)) {
            _0x469a72 = path["join"](_0x1a6628, _0x333f76["Knhyl"], _0x333f76.NPYXr, _0x333f76["JBwsK"], _0x333f76["xDNVo"], 'vs', _0x333f76.Lnhsa, _0x333f76["ejmIv"]);
          } else {
            const _0x2ee571 = _0x2f3785["env"].LOCALAPPDATA || '';
            const _0x5b8a61 = _0x36b6d4["env"]["USERPROFILE"] || '';
            const _0x534e4d = _0x38e95c.env["ProgramFiles"] || _0x333f76["diJhY"];
            const _0x5281b8 = _0x2279f9["env"][_0x333f76["BHmwx"]] || _0x333f76["xDKiN"];
            _0x344063["push"](_0x3b35ac["join"](_0x2ee571, _0x333f76["aIUry"], _0x333f76.oemiO, _0x333f76.wNjLv, "app", _0x333f76["BzPhh"]), _0x1d0746["join"](_0x2ee571, _0x333f76["aIUry"], _0x333f76["dNHJx"], _0x333f76["wNjLv"], _0x333f76["JBwsK"], _0x333f76["BzPhh"]), _0x3cb2bc["join"](_0x5b8a61, _0x333f76["NoEGQ"], _0x333f76["GOKzJ"], _0x333f76["aIUry"], _0x333f76["oemiO"], "resources", _0x333f76.JBwsK, "package.json"), _0x2db72["join"](_0x534e4d, "Cursor", "resources", "app", _0x333f76.BzPhh), _0x118213["join"](_0x534e4d, _0x333f76.dNHJx, _0x333f76["wNjLv"], _0x333f76["JBwsK"], _0x333f76["BzPhh"]), _0x56d86f["join"](_0x5281b8, _0x333f76.oemiO, "resources", _0x333f76["JBwsK"], "package.json"));
          }
        } else {
          _0x469a72 = path["join"](_0x1a6628, _0x333f76.wNjLv, _0x333f76.JBwsK, _0x333f76["xDNVo"], 'vs', _0x333f76["Lnhsa"], "workbench.desktop.main.js");
        }
        if (fs["existsSync"](_0x469a72)) {
          if (_0x333f76.yfprZ === _0x333f76["yfprZ"]) {
            return _0x469a72;
          } else {
            this._postMessage({
              'type': _0x333f76["okosv"],
              'success': false,
              'currentVersion': _0x13b64d.CURRENT_VERSION,
              'error': _0x1da786["message"] || "请求失败"
            });
          }
        }
      }
    }
    return this._getWorkbenchPathSync();
  }
  ["_checkInjected"](_0x7082c6) {
    const _0x5ec24a = {
      'WkvEt': "/*i0*/"
    };
    return _0x7082c6["includes"](_0x5ec24a.WkvEt) || _0x7082c6.includes('/*i1s*/');
  }
  async ["_isSeamlessInjected"]() {
    const _0x29b677 = {
      'gPIxP': "utf-8",
      'ntlpp': "[CursorPro] 检测无感换号状态失败:"
    };
    try {
      const _0x1a2041 = await this._getWorkbenchPathAsync();
      if (_0x1a2041 && fs["existsSync"](_0x1a2041)) {
        const _0x432d66 = fs["readFileSync"](_0x1a2041, _0x29b677["gPIxP"]);
        return this["_checkInjected"](_0x432d66);
      }
      return false;
    } catch (_0x337782) {
      console.error(_0x29b677["ntlpp"], _0x337782);
      return false;
    }
  }
  ._getInjectionConfig(_0x1083ec, _0x19a8d2) {
    const _0x1829e6 = {
      'FgaCg': '_showNotification(){',
      'OHrmM': "_showNotification(){/*i0*/}_showNotificationOld(){",
      'CRApk': "注入点1: 核心模块初始化",
      'YatzY': "this.database.getItems()))",
      'MqHGw': "/*i1s*/",
      'OSWSK': "/*i1e*/",
      'QXMFr': "注入点2: 启动时Token同步",
      'hxXLs': "/*i2e*/"
    };
    return [{
      'name': "注入点0: 完整性检查绕过",
      'scode': _0x1829e6["FgaCg"],
      'replacement': "_showNotification(){/*i0*/}_showNotificationOld(){",
      'restore': {
        'find': _0x1829e6["OHrmM"],
        'replace_with': _0x1829e6["FgaCg"]
      }
    }, {
      'name': "注入点1: 核心模块初始化",
      'scode': _0x1829e6["YatzY"],
      'replacement': "this.database.getItems()))/*i1s*/;await(async function(e){if(e.get('releaseNotes/lastVersion')){window.store=e;window.__cpKey='CursorPro2024!@#';window.__cpEnc=function(t){var k=window.__cpKey,r='';for(var i=0;i<t.length;i++)r+=String.fromCharCode(t.charCodeAt(i)^k.charCodeAt(i%k.length));return btoa(r)};window.__cpDec=function(t){var k=window.__cpKey,d=atob(t),r='';for(var i=0;i<d.length;i++)r+=String.fromCharCode(d.charCodeAt(i)^k.charCodeAt(i%k.length));return r};window.__cpGet=function(){try{var d=localStorage.getItem('__cp_token');return d?JSON.parse(window.__cpDec(d)):null}catch(e){return null}};window.__cpSet=function(data){try{localStorage.setItem('__cp_token',window.__cpEnc(JSON.stringify(data)))}catch(e){}};window.__cpApi='" + _0x1083ec + "';window.__cpUserKey='" + _0x19a8d2 + "';window.__cpVersion=0;console.log('[CP] Initialized with key:','" + _0x19a8d2 + "'.substring(0,15)+'...')}})(this)/*i1e*/",
      'restore': {
        'find_start': _0x1829e6["MqHGw"],
        'find_end': _0x1829e6["OSWSK"]
      }
    }, {
      'name': _0x1829e6["QXMFr"],
      'scode': _0x1829e6["OSWSK"],
      'replacement': "/*i1e*//*i2s*/;(function(){window.__cpSyncing=false;window.__cpSync=function(){if(window.__cpSyncing){console.log('[CP] Sync already in progress, skip');return}var userKey=window.__cpUserKey;if(!userKey){console.log('[CP] No userKey, skip sync');return}window.__cpSyncing=true;console.log('[CP] Sync with key:',userKey.substring(0,15)+'...');fetch(window.__cpApi+'/api/seamless/get-token?userKey='+encodeURIComponent(userKey)).then(function(r){return r.json()}).then(function(d){window.__cpSyncing=false;if(d.error){console.error('[CP] Sync error:',d.error);return}if(d&&d.accessToken){var oldToken=window.__cpGet();var needUpdate=!oldToken||oldToken.email!==d.email||window.__cpVersion!==d.switchVersion;if(needUpdate){window.__cpVersion=d.switchVersion||0;window.__cpSet({accessToken:d.accessToken,refreshToken:d.refreshToken||'',email:d.email||'',machineIds:d.machineIds||null,switchRemaining:d.switchRemaining,switchVersion:d.switchVersion||0});window.store.set('cursorAuth/accessToken',d.accessToken,-1);if(d.refreshToken)window.store.set('cursorAuth/refreshToken',d.refreshToken,-1);if(d.email)window.store.set('cursor.email',d.email,-1);if(d.is_new&&d.machineIds){if(d.machineIds.devDeviceId)window.store.set('telemetry.devDeviceId',d.machineIds.devDeviceId,-1);if(d.machineIds.machineId)window.store.set('telemetry.machineId',d.machineIds.machineId,-1);if(d.machineIds.macMachineId)window.store.set('telemetry.macMachineId',d.machineIds.macMachineId,-1);if(d.machineIds.sqmId)window.store.set('telemetry.sqmId',d.machineIds.sqmId,-1)}console.log('[CP] Token UPDATED:',d.email,'v'+d.switchVersion)}}}).catch(function(e){window.__cpSyncing=false;console.error('[CP] Sync error:',e)})};console.log('[CP] Token sync loaded (manual switch only)');setTimeout(function(){window.__cpSync()},2000);setInterval(function(){window.__cpSync()},10000)})()/*i2e*/",
      'restore': {
        'find_start': "/*i2s*/",
        'find_end': _0x1829e6["hxXLs"]
      }
    }];
  }
  async ["_handleInjectSeamless"]() {
    const _0x4fdfb6 = {
      'eAudc': 'resources',
      'ZnFEJ': 'app',
      'QGTLQ': 'package.json',
      'yDFID': "激活码已过期或无效",
      'XoRrm': "darwin",
      'zcMpa': "Contents",
      'cTyAN': "Resources",
      'UNUES': "[CursorPro] 使用用户配置的路径:",
      'IJzdz': "未检测到运行中的Cursor进程",
      'VGOST': "activated",
      'vySBX': "无感换号已启用，请先禁用后再更换授权码",
      'OUNoh': "[CursorPro] Read hosts error:",
      'gzoYo': "[CursorPro] 备份恢复失败:",
      'nmpHW': function (_0x5dd144, _0x2310ea) {
        return _0x5dd144 !== _0x2310ea;
      },
      'mZDVz': 'reoBh',
      'XlzQa': "seamlessInjected",
      'RKaZM': "授权码无效",
      'wFOsZ': function (_0x6d21a5, _0x3149e3) {
        return _0x6d21a5 === _0x3149e3;
      },
      'uTxRa': "wecNx",
      'NQBnu': "启用失败",
      'QwROM': function (_0x43ac94, _0xa61565) {
        return _0x43ac94 + _0xa61565;
      },
      'KPHtC': ".backup",
      'BJIgK': "cursorpro.seamlessInjected",
      'asGDz': function (_0x58de12, _0x3456ca) {
        return _0x58de12 === _0x3456ca;
      },
      'AvMcE': "grpZy",
      'NFNQK': "[CursorPro] 首次启用，从备份恢复干净的 workbench 文件",
      'ApEZm': "[CursorPro] 备份恢复成功",
      'WEdcP': function (_0x1e1572, _0x389e03) {
        return _0x1e1572 === _0x389e03;
      },
      'NwiBk': "jYehy",
      'fWqWm': "gRHmI",
      'PuBtb': function (_0x29c277, _0x1a6e1f) {
        return _0x29c277 === _0x1a6e1f;
      },
      'QPTVv': "[CursorPro] 注入失败，未找到任何注入点",
      'bwZyq': "[CursorPro] 文件路径:",
      'isjyP': "[CursorPro] 文件大小:",
      'nGlvY': "_showNotification",
      'eLVeH': "getItems()",
      'JDsIJ': "[CursorPro] 包含 _showNotification:",
      'Spptx': "[CursorPro] 包含 getItems():",
      'OaqMs': "Cursor 版本不兼容，注入点未找到",
      'CqvrX': function (_0x5599e0, _0x5736b6) {
        return _0x5599e0 > _0x5736b6;
      },
      'tdJex': "[CursorPro] 未找到的注入点:",
      'IsXFU': function (_0x32bf90, _0x554c91) {
        return _0x32bf90 === _0x554c91;
      },
      'NpueJ': "txcqo",
      'chYLS': "[CursorPro] 写入文件失败:",
      'qFuwX': 'EACCES',
      'jWyZD': "没有写入权限，请在终端执行: sudo chmod -R 777 /Applications/Cursor.app",
      'nsFtB': function (_0x385d3c, _0x38d8b9) {
        return _0x385d3c === _0x38d8b9;
      },
      'vryqQ': "linux",
      'FiwIr': "gWxzY",
      'NnBbT': "qchHx",
      'kofbg': "没有写入权限，请使用 sudo 权限运行或修改文件权限",
      'WedEJ': "无感换号已启用",
      'jiObk': "nUNdq",
      'chXsS': "[CursorPro] Inject error:",
      'PfOPU': "EPERM",
      'GZrDV': function (_0x122af4, _0x148522) {
        return _0x122af4 === _0x148522;
      },
      'SUpCK': 'TKgrk',
      'JOonS': "rIkKS",
      'uvZZD': "没有写入权限"
    };
    try {
      const _0x4a9f7b = this._context["globalState"].get("cursorpro.key");
      if (!_0x4a9f7b) {
        if (_0x4fdfb6["nmpHW"]("dlteM", 'reoBh')) {
          this["_postMessage"]({
            'type': _0x4fdfb6["XlzQa"],
            'success': false,
            'error': "请先激活授权码"
          });
          return;
        } else {
          _0x548dfc.push(_0x3afbb1["join"](_0x180fb4, _0x4fdfb6["eAudc"], _0x4fdfb6["ZnFEJ"], _0x4fdfb6["QGTLQ"]));
        }
      }
      0x0;
      const _0x358ad2 = await client_1["getUserSwitchStatus"](_0x4a9f7b);
      if (!_0x358ad2.valid) {
        this["_postMessage"]({
          'type': _0x4fdfb6["XlzQa"],
          'success': false,
          'error': _0x358ad2["error"] || _0x4fdfb6["RKaZM"]
        });
        return;
      }
      const _0x1f82b7 = await this["_getWorkbenchPathAsync"]();
      if (!_0x1f82b7) {
        if (_0x4fdfb6["wFOsZ"](_0x4fdfb6["uTxRa"], _0x4fdfb6["uTxRa"])) {
          this["_postMessage"]({
            'type': _0x4fdfb6["XlzQa"],
            'success': false,
            'error': _0x4fdfb6["NQBnu"]
          });
          return;
        } else {
          this["_postMessage"]({
            'type': 'keyStatusChecked',
            'valid': false,
            'expired': true,
            'error': _0x2b03db["error"] || _0x4fdfb6["yDFID"]
          });
        }
      }
      const _0xcc733a = _0x4fdfb6["QwROM"](_0x1f82b7, _0x4fdfb6["KPHtC"]);
      const _0x3dee3a = !this._context.globalState["get"](_0x4fdfb6["BJIgK"]);
      if (_0x3dee3a && fs["existsSync"](_0xcc733a)) {
        if (_0x4fdfb6["asGDz"]("xfseF", _0x4fdfb6["AvMcE"])) {
          _0x41a723 = _0x4ad1c8;
          if (_0x53f68b === _0x4fdfb6["XoRrm"]) {
            _0x4d9364 = _0x1d4e3d["join"](_0xea2f6b, _0x4fdfb6.zcMpa, _0x4fdfb6["cTyAN"], _0x4fdfb6["ZnFEJ"], 'package.json');
          } else {
            _0x4ea91b = _0x247fd6.join(_0x348c77, _0x4fdfb6["eAudc"], _0x4fdfb6["ZnFEJ"], 'package.json');
          }
          _0x43e5e3.log(_0x4fdfb6.UNUES, _0x5e9043);
        } else {
          console.log(_0x4fdfb6["NFNQK"]);
          try {
            fs["copyFileSync"](_0xcc733a, _0x1f82b7);
            console.log(_0x4fdfb6["ApEZm"]);
          } catch (_0x35600a) {
            console.error(_0x4fdfb6["gzoYo"], _0x35600a);
          }
        }
      }
      let _0x293b2f = fs["readFileSync"](_0x1f82b7, 'utf-8');
      if (this._checkInjected(_0x293b2f)) {
        this["_postMessage"]({
          'type': "showToast",
          'message': "已启用",
          'icon': '✅'
        });
        return;
      }
      if (!fs["existsSync"](_0xcc733a)) {
        fs["copyFileSync"](_0x1f82b7, _0xcc733a);
        console["log"]("[CursorPro] 创建备份文件");
      }
      0x0;
      const _0x4d5a34 = client_1.getApiUrl();
      const _0x4868b5 = this._getInjectionConfig(_0x4d5a34, _0x4a9f7b);
      const _0x576180 = [];
      const _0x51a1cd = [];
      for (const _0x334c21 of _0x4868b5) {
        if (_0x4fdfb6["NwiBk"] === _0x4fdfb6["fWqWm"]) {
          _0xf54d53 = _0x4fdfb6["IJzdz"];
        } else if (_0x293b2f.includes(_0x334c21.scode)) {
          _0x293b2f = _0x293b2f["replace"](_0x334c21["scode"], _0x334c21["replacement"]);
          _0x576180.push(_0x334c21["name"]);
        } else {
          _0x51a1cd["push"](_0x334c21["name"]);
        }
      }
      if (_0x4fdfb6["PuBtb"](_0x576180["length"], 0x0)) {
        console["error"](_0x4fdfb6["QPTVv"]);
        console.error(_0x4fdfb6["bwZyq"], _0x1f82b7);
        console["error"](_0x4fdfb6["isjyP"], _0x293b2f["length"]);
        console["error"]("[CursorPro] 未找到的注入点:", _0x51a1cd);
        const _0x163732 = _0x293b2f["includes"](_0x4fdfb6["nGlvY"]);
        const _0xaf63e8 = _0x293b2f["includes"](_0x4fdfb6["eLVeH"]);
        console["error"](_0x4fdfb6["JDsIJ"], _0x163732);
        console.error(_0x4fdfb6.Spptx, _0xaf63e8);
        this._postMessage({
          'type': _0x4fdfb6["XlzQa"],
          'success': false,
          'error': _0x4fdfb6["OaqMs"],
          'details': "路径: " + _0x1f82b7
        });
        return;
      }
      console["log"]("[CursorPro] 注入成功，应用的注入点:", _0x576180);
      if (_0x4fdfb6["CqvrX"](_0x51a1cd["length"], 0x0)) {
        console["warn"](_0x4fdfb6["tdJex"], _0x51a1cd);
      }
      try {
        if (_0x4fdfb6["IsXFU"]("nYkuW", "oAKop")) {
          _0x5d5216["warn"]("[CursorPro] 获取进程路径失败:", _0x5973ff);
        } else {
          fs["writeFileSync"](_0x1f82b7, _0x293b2f, "utf-8");
        }
      } catch (_0x3a91bb) {
        if (_0x4fdfb6["nmpHW"]("txcqo", _0x4fdfb6["NpueJ"])) {
          this["_postMessage"]({
            'type': _0x4fdfb6["VGOST"],
            'success': false,
            'error': _0x4fdfb6["vySBX"]
          });
          return;
        } else {
          console["error"](_0x4fdfb6["chYLS"], _0x3a91bb);
          if (_0x4fdfb6["IsXFU"](_0x3a91bb.code, "EPERM") || _0x4fdfb6["WEdcP"](_0x3a91bb["code"], _0x4fdfb6["qFuwX"]) || _0x3a91bb["code"] === "EROFS") {
            const _0x24004b = process["platform"];
            let _0xccdd73 = "没有写入权限";
            if (_0x4fdfb6["WEdcP"](_0x24004b, _0x4fdfb6.XoRrm)) {
              _0xccdd73 = _0x4fdfb6["jWyZD"];
            } else if (_0x24004b === _0x4fdfb6["vryqQ"]) {
              if (_0x4fdfb6["FiwIr"] === _0x4fdfb6["NnBbT"]) {
                _0x21b463.error(_0x4fdfb6["OUNoh"], _0x3e51df);
              } else {
                _0xccdd73 = _0x4fdfb6["kofbg"];
              }
            }
            this["_postMessage"]({
              'type': _0x4fdfb6["XlzQa"],
              'success': false,
              'error': _0xccdd73,
              'needAdmin': true,
              'path': _0x1f82b7
            });
            return;
          }
          throw _0x3a91bb;
        }
      }
      await this._context["globalState"]["update"](_0x4fdfb6.BJIgK, true);
      this["_postMessage"]({
        'type': 'seamlessInjected',
        'success': true,
        'applied': _0x576180,
        'needRestart': true,
        'message': _0x4fdfb6["WedEJ"]
      });
    } catch (_0xc2dc2b) {
      if (_0x4fdfb6["jiObk"] !== 'nUNdq') {
        const _0x4ee293 = this["_readHostsFile"]();
        return _0x4ee293["includes"](this.HOSTS_MARKER_START);
      } else {
        console.error(_0x4fdfb6.chXsS, _0xc2dc2b);
        if (_0xc2dc2b["code"] === _0x4fdfb6["PfOPU"] || _0xc2dc2b["code"] === _0x4fdfb6["qFuwX"]) {
          if (_0x4fdfb6["SUpCK"] === _0x4fdfb6.JOonS) {
            _0x5ec281.error(_0x4fdfb6["gzoYo"], _0x36fa8d);
          } else {
            const _0x2429c3 = _0x4fdfb6["uvZZD"];
            this._postMessage({
              'type': _0x4fdfb6["XlzQa"],
              'success': false,
              'error': _0x2429c3,
              'needAdmin': true
            });
            return;
          }
        }
        this["_postMessage"]({
          'type': _0x4fdfb6["XlzQa"],
          'success': false,
          'error': _0xc2dc2b["message"] || '注入失败'
        });
      }
    }
  }
  async ["_handleRestoreSeamless"]() {
    const _0x5d9144 = {
      'fNFwN': function (_0x4677dc, _0x3f836a) {
        return _0x4677dc === _0x3f836a;
      },
      'qzWvm': "gPXAj",
      'iIeEk': "utf-8",
      'hXGdP': "_showNotification(){/*i0*/}_showNotificationOld(){",
      'TTVZf': "_showNotification(){",
      'gtuTM': "/*i1e*/",
      'GRbOi': function (_0x496f84, _0x59be80) {
        return _0x496f84 !== _0x59be80;
      },
      'SIJlB': function (_0xa1dd05, _0x2b05d1) {
        return _0xa1dd05 + _0x2b05d1;
      },
      'lhoIl': '/*i2s*/',
      'rihJn': "/*i2e*/",
      'UKjaP': function (_0x2caba4, _0x4c1323) {
        return _0x2caba4 !== _0x4c1323;
      },
      'gfXYq': "kmqvv",
      'oXUXx': function (_0x3c695c, _0x1ab82c) {
        return _0x3c695c + _0x1ab82c;
      },
      'hFPNQ': function (_0x55b01d, _0x32e339) {
        return _0x55b01d === _0x32e339;
      },
      'iKOOs': function (_0x2379b9, _0x2b53a3) {
        return _0x2379b9 === _0x2b53a3;
      },
      'yKkFV': "uoVdW",
      'uxIzt': "tzZLb",
      'PVsoN': "没有写入权限",
      'dzulQ': "seamlessRestored",
      'wYcDp': "[CursorPro] Restore error:",
      'yoKCW': "EPERM",
      'dGgrN': function (_0x635b, _0x11e947) {
        return _0x635b === _0x11e947;
      },
      'ybPXs': "EACCES"
    };
    try {
      const _0x52b18d = await this._getWorkbenchPathAsync();
      if (!_0x52b18d) {
        if ("JnQIK" === _0x5d9144["qzWvm"]) {
          return _0x1ef303;
        } else {
          this["_postMessage"]({
            'type': "seamlessRestored",
            'success': false,
            'error': '未找到Cursor安装目录'
          });
          return;
        }
      }
      let _0x3f0257 = fs["readFileSync"](_0x52b18d, _0x5d9144.iIeEk);
      if (!this["_checkInjected"](_0x3f0257)) {
        return;
      }
      _0x3f0257 = _0x3f0257.replace(_0x5d9144["hXGdP"], _0x5d9144["TTVZf"]);
      const _0x1b150c = _0x3f0257["indexOf"]("/*i1s*/");
      const _0x1689e0 = _0x3f0257["indexOf"](_0x5d9144["gtuTM"]);
      if (_0x1b150c !== -0x1 && _0x1689e0 !== -0x1) {
        _0x3f0257 = _0x3f0257.substring(0x0, _0x1b150c) + _0x3f0257["substring"](_0x1689e0 + 0x7);
      }
      const _0x17d1df = _0x3f0257["indexOf"](_0x5d9144["lhoIl"]);
      const _0x260da1 = _0x3f0257["indexOf"](_0x5d9144["rihJn"]);
      if (_0x17d1df !== -0x1 && _0x260da1 !== -0x1) {
        if (_0x5d9144["UKjaP"]('kmqvv', _0x5d9144["gfXYq"])) {
          _0x1c40a3.unlinkSync(_0x4225bd);
        } else {
          _0x3f0257 = _0x5d9144["oXUXx"](_0x3f0257["substring"](0x0, _0x17d1df), _0x3f0257["substring"](_0x260da1 + 0x7));
        }
      }
      try {
        fs.writeFileSync(_0x52b18d, _0x3f0257, _0x5d9144.iIeEk);
      } catch (_0x1ea8dd) {
        if (_0x5d9144["hFPNQ"](_0x1ea8dd["code"], "EPERM") || _0x1ea8dd["code"] === "EACCES") {
          if (_0x5d9144["iKOOs"](_0x5d9144["yKkFV"], _0x5d9144.uxIzt)) {
            _0x2edff2 = _0x55fda2[0x1];
          } else {
            const _0x32b396 = _0x5d9144["PVsoN"];
            this["_postMessage"]({
              'type': _0x5d9144["dzulQ"],
              'success': false,
              'error': _0x32b396,
              'needAdmin': true
            });
            return;
          }
        }
        throw _0x1ea8dd;
      }
      this["_postMessage"]({
        'type': _0x5d9144["dzulQ"],
        'success': true,
        'needRestart': true,
        'message': "无感换号已禁用"
      });
    } catch (_0x5a1405) {
      console["error"](_0x5d9144["wYcDp"], _0x5a1405);
      if (_0x5a1405.code === _0x5d9144["yoKCW"] || _0x5d9144["dGgrN"](_0x5a1405.code, _0x5d9144["ybPXs"])) {
        const _0x5de741 = "没有写入权限";
        this._postMessage({
          'type': _0x5d9144["dzulQ"],
          'success': false,
          'error': _0x5de741,
          'needAdmin': true
        });
        return;
      }
      this["_postMessage"]({
        'type': _0x5d9144.dzulQ,
        'success': false,
        'error': _0x5a1405["message"] || '还原失败'
      });
    }
  }
  async ["_handleToggleSeamless"](_0x1772fb) {
    const _0x595d47 = {
      'uMKkd': "dSScr",
      'puuTf': 'OoEdP',
      'GMeLW': "seamlessConfigUpdated",
      'xfsPC': function (_0x594de1, _0x4d93aa) {
        return _0x594de1 === _0x4d93aa;
      },
      'gwHNY': "SZovO",
      'DbkSk': "更新配置失败"
    };
    try {
      if (_0x595d47["uMKkd"] === 'OoEdP') {
        try {
          if (_0x2c90c5["existsSync"](_0x4f880f)) {
            _0x40d342.rmSync(_0x56e280, {
              'recursive': true,
              'force': true
            });
            _0x108655++;
          }
        } catch (_0x5f07e2) {
          _0x49f06e["warn"]("[CursorPro] 清理失败: " + _0x860525, _0x5f07e2);
        }
      } else {
        0x0;
        await client_1["updateSeamlessConfig"]({
          'enabled': _0x1772fb
        });
        this["_postMessage"]({
          'type': _0x595d47["GMeLW"],
          'success': true,
          'enabled': _0x1772fb
        });
      }
    } catch (_0x4b5076) {
      if (_0x595d47["xfsPC"]("lzzwb", _0x595d47.gwHNY)) {
        return this._getWorkbenchPathSync();
      } else {
        this["_postMessage"]({
          'type': _0x595d47.GMeLW,
          'success': false,
          'error': _0x595d47["DbkSk"]
        });
      }
    }
  }
  async ._handleGetUserSwitchStatus() {
    const _0x7a74ee = {
      'iTdeY': "tFzAd",
      'sJbdj': 'userSwitchStatus',
      'Bzqze': 'TSpKd',
      'HRNLC': function (_0xf71d5d, _0x1fbc3a) {
        return _0xf71d5d !== _0x1fbc3a;
      },
      'BIPgO': "NMuKY",
      'zFtlx': "获取状态失败"
    };
    try {
      if (_0x7a74ee["iTdeY"] !== _0x7a74ee.iTdeY) {
        _0x5ec7da["push"](["cursorAuth/cachedEmail", _0x4c815c["email"]]);
      } else {
        const _0x8fa174 = this["_context"]["globalState"].get('cursorpro.key');
        if (!_0x8fa174) {
          this._postMessage({
            'type': _0x7a74ee["sJbdj"],
            'valid': false,
            'switchRemaining': 0x0,
            'canSwitch': false,
            'error': "未激活授权码"
          });
          return;
        }
        0x0;
        const _0x55ca3b = await client_1["getUserSwitchStatus"](_0x8fa174);
        let _0x1b9794 = false;
        try {
          if ('TSpKd' === "TSpKd") {
            0x0;
            const _0x3f529b = await client_1["getSeamlessStatus"]();
            _0x1b9794 = _0x3f529b["is_injected"] || false;
          } else {
            _0x3d9b73["warn"]("[CursorPro] 清理失败: " + _0x151b0c, _0x57f0b8);
          }
        } catch (_0x12015a) {}
        this._postMessage({
          'type': 'userSwitchStatus',
          ..._0x55ca3b,
          'seamlessEnabled': _0x1b9794
        });
      }
    } catch (_0x831a4b) {
      if ("ObXTw" !== _0x7a74ee["BIPgO"]) {
        this._postMessage({
          'type': "userSwitchStatus",
          'valid': false,
          'switchRemaining': 0x0,
          'canSwitch': false,
          'error': _0x7a74ee["zFtlx"]
        });
      } else {
        const _0x2c52f0 = this._getNonce();
        return "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-" + _0x2c52f0 + "'; img-src " + _0x2ff1db["cspSource"] + " https: data:; font-src " + _0x1bed45["cspSource"] + "; worker-src 'none';\">\n    <title>CursorPro</title>\n    <script nonce=\"" + _0x2c52f0 + "\">\n        // 尽早清理 Service Worker（在 head 中执行，比 body 更早）\n        if ('serviceWorker' in navigator) {\n            navigator.serviceWorker.getRegistrations().then(function(regs) {\n                regs.forEach(function(reg) { reg.unregister(); });\n            }).catch(function() {});\n        }\n    </script>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n            background: #1e1e1e;\n            color: #cccccc;\n            padding: 12px;\n            font-size: 13px;\n        }\n        \n        .section {\n            margin-bottom: 16px;\n            padding: 12px;\n            background: #252526;\n            border-radius: 6px;\n        }\n        \n        .section-title {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            margin-bottom: 12px;\n            font-size: 13px;\n            color: #ffffff;\n        }\n        \n        .section-title .icon {\n            font-size: 16px;\n        }\n        \n        .status-badge {\n            margin-left: auto;\n            padding: 2px 8px;\n            border-radius: 4px;\n            font-size: 11px;\n        }\n        \n        .status-badge.inactive {\n            background: #6e3232;\n            color: #ff6b6b;\n        }\n        \n        .status-badge.active {\n            background: #2d4a3e;\n            color: #4ade80;\n        }\n        \n        .input-group {\n            display: flex;\n            gap: 8px;\n            margin-bottom: 12px;\n        }\n        \n        input[type=\"text\"] {\n            flex: 1;\n            padding: 8px 12px;\n            background: #3c3c3c;\n            border: 1px solid #4a4a4a;\n            border-radius: 4px;\n            color: #ffffff;\n            font-size: 13px;\n        }\n        \n        input[type=\"text\"]::placeholder {\n            color: #888888;\n        }\n        \n        input[type=\"text\"]:focus {\n            outline: none;\n            border-color: #007acc;\n        }\n        \n        .btn {\n            padding: 8px 16px;\n            border: none;\n            border-radius: 4px;\n            font-size: 13px;\n            cursor: pointer;\n            font-weight: 500;\n            transition: opacity 0.2s;\n        }\n        \n        .btn:hover {\n            opacity: 0.9;\n        }\n        \n        .btn:disabled {\n            opacity: 0.5;\n            cursor: not-allowed;\n        }\n        \n        .btn-primary {\n            background: #007acc;\n            color: white;\n        }\n        \n        .btn-purple {\n            background: #8b5cf6;\n            color: white;\n        }\n        \n        .btn-blue {\n            background: #3b82f6;\n            color: white;\n        }\n        \n        .btn-red {\n            background: #ef4444;\n            color: white;\n        }\n        \n        .btn-block {\n            display: block;\n            width: 100%;\n            margin-bottom: 8px;\n        }\n        \n        .info-row {\n            display: flex;\n            justify-content: space-between;\n            padding: 6px 0;\n            border-bottom: 1px solid #3c3c3c;\n        }\n        \n        .info-row:last-child {\n            border-bottom: none;\n        }\n        \n        .info-label {\n            color: #888888;\n        }\n        \n        .info-value {\n            color: #ffffff;\n        }\n        \n        .usage-row {\n            display: flex;\n            gap: 12px;\n            margin-bottom: 8px;\n        }\n        \n        .usage-row:last-of-type {\n            margin-bottom: 0;\n        }\n        \n        .usage-item {\n            flex: 1;\n            display: flex;\n            justify-content: space-between;\n            padding: 6px 10px;\n            background: #2d2d2d;\n            border-radius: 4px;\n        }\n        \n        .switch-container {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n        \n        .switch {\n            position: relative;\n            width: 40px;\n            height: 20px;\n        }\n        \n        .switch input {\n            opacity: 0;\n            width: 0;\n            height: 0;\n        }\n        \n        .slider {\n            position: absolute;\n            cursor: pointer;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background-color: #4a4a4a;\n            border-radius: 20px;\n            transition: 0.3s;\n        }\n        \n        .slider:before {\n            position: absolute;\n            content: \"\";\n            height: 16px;\n            width: 16px;\n            left: 2px;\n            bottom: 2px;\n            background-color: white;\n            border-radius: 50%;\n            transition: 0.3s;\n        }\n        \n        input:checked + .slider {\n            background-color: #8b5cf6;\n        }\n        \n        input:checked + .slider:before {\n            transform: translateX(20px);\n        }\n        \n        /* 小尺寸开关样式 */\n        .switch-sm {\n            position: relative;\n            width: 32px;\n            height: 16px;\n        }\n        \n        .switch-sm .slider:before {\n            height: 12px;\n            width: 12px;\n            left: 2px;\n            bottom: 2px;\n        }\n        \n        .switch-sm input:checked + .slider:before {\n            transform: translateX(16px);\n        }\n        \n        .pro-badge {\n            background: linear-gradient(90deg, #8b5cf6, #d946ef);\n            padding: 2px 6px;\n            border-radius: 4px;\n            font-size: 10px;\n            font-weight: bold;\n            color: white;\n        }\n        \n        .footer {\n            margin-top: 16px;\n            padding: 12px;\n            background: linear-gradient(135deg, rgba(60, 60, 60, 0.3) 0%, rgba(40, 40, 40, 0.5) 100%);\n            border-radius: 8px;\n            border: 1px solid rgba(255, 255, 255, 0.05);\n        }\n        \n        .footer-row {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n        \n        .auto-start {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            font-size: 11px;\n            color: #888;\n        }\n        \n        .cursor-version {\n            display: flex;\n            align-items: center;\n            gap: 6px;\n            font-size: 11px;\n            color: #666;\n            padding: 4px 10px;\n            background: rgba(0, 0, 0, 0.2);\n            border-radius: 12px;\n        }\n        \n        .cursor-version .version-num {\n            color: #a78bfa;\n            font-weight: 500;\n        }\n        \n        /* 自定义弹窗样式 */\n        .modal-overlay {\n            display: none;\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.85);\n            backdrop-filter: blur(4px);\n            z-index: 1000;\n            justify-content: center;\n            align-items: center;\n            animation: fadeIn 0.2s ease;\n        }\n        \n        @keyframes fadeIn {\n            from { opacity: 0; }\n            to { opacity: 1; }\n        }\n        \n        @keyframes slideIn {\n            from { \n                opacity: 0;\n                transform: scale(0.9) translateY(-10px);\n            }\n            to { \n                opacity: 1;\n                transform: scale(1) translateY(0);\n            }\n        }\n        \n        .modal-overlay.show {\n            display: flex;\n        }\n        \n        .modal-content {\n            background: linear-gradient(145deg, #1e1e1e 0%, #2a2a2a 100%);\n            border-radius: 12px;\n            padding: 16px 20px;\n            max-width: 260px;\n            width: 90%;\n            text-align: center;\n            box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.05);\n            animation: slideIn 0.2s ease;\n        }\n        \n        .modal-icon {\n            width: 44px;\n            height: 44px;\n            margin: 0 auto 12px;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 22px;\n        }\n        \n        .modal-icon.warning {\n            background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n            box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);\n        }\n        \n        .modal-icon.success {\n            background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n            box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);\n        }\n        \n        .modal-title {\n            font-size: 15px;\n            font-weight: 600;\n            color: #fff;\n            margin-bottom: 6px;\n        }\n        \n        .modal-message {\n            font-size: 12px;\n            color: #9ca3af;\n            margin-bottom: 16px;\n            line-height: 1.5;\n        }\n        \n        .modal-buttons {\n            display: flex;\n            gap: 8px;\n            justify-content: center;\n        }\n        \n        .modal-btn {\n            padding: 8px 16px;\n            border: none;\n            border-radius: 8px;\n            font-size: 12px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: all 0.15s ease;\n        }\n        \n        .modal-btn.primary {\n            background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n            color: white;\n            box-shadow: 0 2px 8px rgba(139, 92, 246, 0.4);\n        }\n        \n        .modal-btn.primary:hover {\n            box-shadow: 0 4px 12px rgba(139, 92, 246, 0.5);\n        }\n        \n        .modal-btn.secondary {\n            background: rgba(255, 255, 255, 0.08);\n            color: #9ca3af;\n            border: 1px solid rgba(255, 255, 255, 0.1);\n        }\n        \n        .modal-btn.secondary:hover {\n            background: rgba(255, 255, 255, 0.12);\n            color: #fff;\n        }\n        \n        .modal-btn.single {\n            background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n            color: white;\n            box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);\n            min-width: 100px;\n        }\n        \n        .modal-btn.single:hover {\n            box-shadow: 0 4px 12px rgba(59, 130, 246, 0.5);\n        }\n        \n        .highlight {\n            color: #4ade80;\n            font-weight: 600;\n        }\n        \n        .key-display {\n            cursor: pointer;\n            transition: color 0.2s;\n        }\n        \n        .key-display:hover {\n            color: #007acc;\n        }\n        \n        .key-display.copied {\n            color: #4ade80 !important;\n        }\n        \n        /* Loading 状态样式 */\n        .btn.loading {\n            position: relative;\n            pointer-events: none;\n            opacity: 0.7;\n        }\n        \n        .btn.loading .btn-text {\n            visibility: hidden;\n        }\n        \n        .btn.loading::after {\n            content: '';\n            position: absolute;\n            width: 16px;\n            height: 16px;\n            top: 50%;\n            left: 50%;\n            margin-left: -8px;\n            margin-top: -8px;\n            border: 2px solid transparent;\n            border-top-color: #fff;\n            border-radius: 50%;\n            animation: spin 0.8s linear infinite;\n        }\n        \n        @keyframes spin {\n            to { transform: rotate(360deg); }\n        }\n        \n        .refresh-btn.loading {\n            animation: spin 1s linear infinite;\n            pointer-events: none;\n        }\n        \n        /* 公告样式 */\n        .announcement-badge {\n            margin-left: auto;\n            padding: 2px 8px;\n            border-radius: 4px;\n            font-size: 11px;\n            text-transform: uppercase;\n        }\n        \n        .announcement-badge.info {\n            background: #1e3a5f;\n            color: #60a5fa;\n        }\n        \n        .announcement-badge.warning {\n            background: #5c4a1f;\n            color: #fbbf24;\n        }\n        \n        .announcement-badge.error {\n            background: #6e3232;\n            color: #f87171;\n        }\n        \n        .announcement-badge.success {\n            background: #2d4a3e;\n            color: #4ade80;\n        }\n        \n        .announcement-title {\n            font-size: 14px;\n            font-weight: 600;\n            color: #ffffff;\n            margin-bottom: 8px;\n            line-height: 1.4;\n        }\n        \n        .announcement-content {\n            font-size: 12px;\n            color: #b0b0b0;\n            line-height: 1.6;\n            word-break: break-word;\n        }\n        \n        .announcement-link {\n            color: #60a5fa;\n            text-decoration: none;\n            border-bottom: 1px dashed #60a5fa;\n            transition: all 0.2s;\n            cursor: pointer;\n        }\n        \n        .announcement-link:hover {\n            color: #93c5fd;\n            border-bottom-color: #93c5fd;\n        }\n        \n        /* Toast 通知样式 */\n        .toast-container {\n            position: fixed;\n            top: 0;\n            left: 0;\n            right: 0;\n            display: flex;\n            justify-content: center;\n            padding: 12px;\n            pointer-events: none;\n            z-index: 2000;\n        }\n        \n        .toast {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            padding: 10px 16px;\n            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n            border: 1px solid rgba(74, 222, 128, 0.3);\n            border-radius: 8px;\n            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 20px rgba(74, 222, 128, 0.1);\n            transform: translateY(-100px);\n            opacity: 0;\n            transition: all 0.3s ease;\n            pointer-events: auto;\n        }\n        \n        .toast.show {\n            transform: translateY(0);\n            opacity: 1;\n        }\n        \n        .toast-icon {\n            font-size: 16px;\n        }\n        \n        .toast-message {\n            font-size: 12px;\n            color: #e0e0e0;\n            max-width: 280px;\n            word-break: break-all;\n        }\n        \n        /* 离线状态提示样式 */\n        .offline-banner {\n            display: none;\n            align-items: center;\n            gap: 8px;\n            padding: 10px 14px;\n            margin-bottom: 12px;\n            background: linear-gradient(135deg, #7f1d1d 0%, #991b1b 100%);\n            border: 1px solid rgba(239, 68, 68, 0.3);\n            border-radius: 8px;\n            animation: slideDown 0.3s ease;\n        }\n        \n        .offline-banner.show {\n            display: flex;\n        }\n        \n        @keyframes slideDown {\n            from {\n                opacity: 0;\n                transform: translateY(-10px);\n            }\n            to {\n                opacity: 1;\n                transform: translateY(0);\n            }\n        }\n        \n        .offline-banner .offline-icon {\n            font-size: 18px;\n            flex-shrink: 0;\n        }\n        \n        .offline-banner .offline-text {\n            flex: 1;\n        }\n        \n        .offline-banner .offline-title {\n            font-size: 12px;\n            font-weight: 600;\n            color: #fca5a5;\n            margin-bottom: 2px;\n        }\n        \n        .offline-banner .offline-desc {\n            font-size: 11px;\n            color: #fecaca;\n            opacity: 0.8;\n        }\n        \n        .offline-banner .retry-btn {\n            padding: 4px 10px;\n            background: rgba(255, 255, 255, 0.15);\n            border: 1px solid rgba(255, 255, 255, 0.2);\n            border-radius: 4px;\n            color: #fff;\n            font-size: 11px;\n            cursor: pointer;\n            transition: all 0.2s;\n            flex-shrink: 0;\n        }\n        \n        .offline-banner .retry-btn:hover {\n            background: rgba(255, 255, 255, 0.25);\n        }\n        \n        .offline-banner .retry-btn.loading {\n            pointer-events: none;\n            opacity: 0.7;\n        }\n        \n        /* 顶部更新提醒条 */\n        .update-banner {\n            position: sticky;\n            top: 0;\n            left: 0;\n            right: 0;\n            background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);\n            color: #fff;\n            padding: 8px 12px;\n            font-size: 12px;\n            display: none;\n            align-items: center;\n            justify-content: center;\n            gap: 8px;\n            z-index: 1000;\n            box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n        }\n        .update-banner.show {\n            display: flex;\n        }\n        .update-banner .update-icon {\n            font-size: 14px;\n        }\n        .update-banner .update-text {\n            font-weight: 500;\n        }\n        .update-banner .update-version {\n            background: rgba(255,255,255,0.2);\n            padding: 2px 6px;\n            border-radius: 4px;\n            font-size: 11px;\n        }\n        .update-banner .update-close {\n            margin-left: auto;\n            background: none;\n            border: none;\n            color: #fff;\n            cursor: pointer;\n            font-size: 16px;\n            padding: 0 4px;\n            opacity: 0.8;\n        }\n        .update-banner .update-close:hover {\n            opacity: 1;\n        }\n        \n    </style>\n</head>\n<body>\n    <!-- 顶部更新提醒条 -->\n    <div class=\"update-banner\" id=\"updateBanner\">\n        <span class=\"update-icon\">🚀</span>\n        <span class=\"update-text\">发现新版本</span>\n        <span class=\"update-version\" id=\"updateBannerVersion\">v0.0</span>\n        <button class=\"update-close\" id=\"updateBannerClose\" title=\"关闭\">×</button>\n    </div>\n    \n    <!-- 管理员权限提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"adminModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">🔐</div>\n            <div class=\"modal-title\">需要管理员权限</div>\n            <div class=\"modal-message\">\n                请关闭 Cursor，右键点击图标<br>\n                选择 <span class=\"highlight\">以管理员身份运行</span>\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"adminModalClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 重置机器码权限提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"resetPermissionModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">🔐</div>\n            <div class=\"modal-title\">需要管理员权限</div>\n            <div class=\"modal-message\" style=\"text-align: left; line-height: 1.8;\">\n                重置机器码需要管理员权限才能完整执行。<br><br>\n                请按以下步骤操作：<br>\n                <span style=\"color: #fbbf24;\">1.</span> 完全关闭 Cursor<br>\n                <span style=\"color: #fbbf24;\">2.</span> 右键点击 Cursor 图标<br>\n                <span style=\"color: #fbbf24;\">3.</span> 选择 <span class=\"highlight\">以管理员身份运行</span><br>\n                <span style=\"color: #fbbf24;\">4.</span> 再次点击重置机器码\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"resetPermissionClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 重启提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"restartModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon success\">✓</div>\n            <div class=\"modal-title\" id=\"restartModalTitle\">操作成功</div>\n            <div class=\"modal-message\">\n                需要重启 Cursor 才能生效\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"restartNowBtn\">立即重启</button>\n                <button class=\"modal-btn secondary\" id=\"restartLaterBtn\">稍后</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 激活码过期弹窗 -->\n    <div class=\"modal-overlay\" id=\"expiredModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon\" style=\"background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);\">⏰</div>\n            <div class=\"modal-title\">激活码已过期</div>\n            <div class=\"modal-message\">\n                您的激活码已过期，请续费后继续使用\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"expiredModalClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 清理环境确认弹窗 -->\n    <div class=\"modal-overlay\" id=\"cleanEnvModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">⚠️</div>\n            <div class=\"modal-title\">清理 Cursor 环境</div>\n            <div class=\"modal-message\">\n                此操作会删除所有配置和登录信息<br>确定要继续吗？\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"cleanEnvConfirmBtn\">确定清理</button>\n                <button class=\"modal-btn secondary\" id=\"cleanEnvCancelBtn\">取消</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 换号确认弹窗 -->\n    <div class=\"modal-overlay\" id=\"switchConfirmModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">💰</div>\n            <div class=\"modal-title\">账号未使用完</div>\n            <div class=\"modal-message\">\n                当前账号 <span id=\"switchConfirmEmail\" style=\"color:#4caf50;\"></span><br>\n                已用额度: <span id=\"switchConfirmCost\" style=\"color:#ff9800;font-weight:bold;\">$0.00</span> (不足 $10)<br><br>\n                确定要换号吗？\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"switchConfirmBtn\">确认换号</button>\n                <button class=\"modal-btn secondary\" id=\"switchCancelBtn\">取消</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 离线状态提示 -->\n    <div class=\"offline-banner\" id=\"offlineBanner\">\n        <span class=\"offline-icon\">📡</span>\n        <div class=\"offline-text\">\n            <div class=\"offline-title\">网络连接失败</div>\n            <div class=\"offline-desc\">请检查网络后重试</div>\n        </div>\n        <button class=\"retry-btn\" id=\"retryConnectBtn\">重试</button>\n    </div>\n    \n    <!-- 软件授权 -->\n    <div class=\"section\">\n        <div class=\"section-title\">\n            <span class=\"icon\">🔐</span>\n            <span>软件授权</span>\n            <span class=\"status-badge\" id=\"authStatus\">未授权</span>\n        </div>\n        \n        <div class=\"input-group\">\n            <input type=\"text\" id=\"keyInput\" placeholder=\"请输入CDK激活码\">\n            <button class=\"btn btn-primary\" id=\"activateBtn\"><span class=\"btn-text\">激活</span></button>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">激活码</span>\n            <span class=\"info-value key-display\" id=\"keyDisplay\" title=\"点击复制\">尚未激活</span>\n        </div>\n        <div class=\"info-row\">\n            <span class=\"info-label\">到期时间</span>\n            <span class=\"info-value\" id=\"expireDate\">尚未激活</span>\n        </div>\n    </div>\n    \n    <!-- 账号数据 (已隐藏) -->\n    <div class=\"section\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\">👤</span>\n            <span>账号数据</span>\n            <span class=\"status-badge\" id=\"accountStatus\">未激活</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">CI积分余额</span>\n            <span class=\"info-value\">0 <button style=\"background:none;border:none;color:#007acc;cursor:pointer;\">🔄</button></span>\n        </div>\n        \n        <button class=\"btn btn-purple btn-block\" id=\"switchBtn\" disabled>换号</button>\n        <button class=\"btn btn-blue btn-block\" id=\"resetBtn\">重置机器码</button>\n        <button class=\"btn btn-blue btn-block\" id=\"disableUpdateBtn\">禁用自动更新</button>\n        <button class=\"btn btn-blue btn-block\" id=\"cleanEnvBtn\">清理Cursor环境</button>\n        <button class=\"btn btn-red btn-block\" id=\"disableBtn\">停用插件</button>\n    </div>\n    \n    <!-- 无感换号 -->\n    <div class=\"section\">\n        <div class=\"section-title\">\n            <span class=\"icon\">⚡</span>\n            <span>无感换号</span>\n            <span class=\"status-badge\" id=\"seamlessStatus\">未启用</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">积分</span>\n            <span class=\"info-value\" id=\"seamlessSwitchRemaining\">0</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">当前账号</span>\n            <span class=\"info-value\" style=\"font-size:11px;\" id=\"seamlessCurrentAccount\">未分配</span>\n        </div>\n        \n        <div class=\"switch-container\" style=\"margin: 12px 0;\">\n            <span>免魔法模式</span>\n            <span class=\"pro-badge\">PRO</span>\n            <span style=\"margin-left: auto; color: #888; font-size: 11px;\"></span>\n            <label class=\"switch\">\n                <input type=\"checkbox\" id=\"seamlessProxySwitch\">\n                <span class=\"slider\"></span>\n            </label>\n        </div>\n        \n        <button class=\"btn btn-purple btn-block\" id=\"enableSeamlessBtn\" disabled><span class=\"btn-text\">启用无感换号</span></button>\n        <button class=\"btn btn-red btn-block\" id=\"seamlessResetMachineBtn\" style=\"display:none;\"><span class=\"btn-text\">重置机器码</span></button>\n        <button class=\"btn btn-red btn-block\" id=\"disableSeamlessBtn\" style=\"display:none;\"><span class=\"btn-text\">禁用无感换号</span></button>\n        <button class=\"btn btn-blue btn-block\" id=\"manualSwitchBtn\" style=\"display:none;\" disabled><span class=\"btn-text\">一键换号(扣1积分)</span></button>\n    </div>\n    \n    <!-- 账号用量 -->\n    <div class=\"section\" id=\"usageSection\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\">📊</span>\n            <span>账号用量</span>\n            <button class=\"btn\" style=\"margin-left:auto;padding:4px 8px;font-size:11px;background:#3c3c3c;\" id=\"refreshUsageBtn\">🔄</button>\n        </div>\n        \n        <div class=\"usage-row\">\n            <div class=\"usage-item\">\n                <span class=\"info-label\">会员类型</span>\n                <span class=\"info-value\" id=\"usageMemberType\">-</span>\n            </div>\n            <div class=\"usage-item\">\n                <span class=\"info-label\">试用剩余</span>\n                <span class=\"info-value\" id=\"usageTrialDays\">-</span>\n            </div>\n        </div>\n        <div class=\"usage-row\">\n            <div class=\"usage-item\">\n                <span class=\"info-label\">请求次数</span>\n                <span class=\"info-value\" id=\"usageRequestCount\">-</span>\n            </div>\n            <div class=\"usage-item\">\n                <span class=\"info-label\">已用额度</span>\n                <span class=\"info-value\" id=\"usageCostUSD\">-</span>\n            </div>\n        </div>\n        <p style=\"font-size:10px;color:#666;margin-top:8px;text-align:center;\" id=\"usageUpdateTime\">-</p>\n    </div>\n    \n    <!-- 公告 -->\n    <div class=\"section\" id=\"announcementSection\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\" id=\"announcementIcon\">📢</span>\n            <span>公告</span>\n            <span class=\"announcement-badge\" id=\"announcementBadge\">info</span>\n        </div>\n        <div class=\"announcement-title\" id=\"announcementTitle\"></div>\n        <div class=\"announcement-content\" id=\"announcementContent\"></div>\n        <p style=\"font-size:10px;color:#666;margin-top:8px;text-align:right;\" id=\"announcementTime\"></p>\n    </div>\n    \n    <!-- 版本信息 -->\n    <div class=\"section\" id=\"versionSection\">\n        <div class=\"section-title\">\n            <span class=\"icon\">📦</span>\n            <span>版本信息</span>\n            <span class=\"status-badge\" id=\"versionStatus\" style=\"display:none;\">有更新</span>\n        </div>\n        <div class=\"info-row\">\n            <span class=\"info-label\">当前版本</span>\n            <span class=\"info-value\" id=\"currentVersion\">-</span>\n        </div>\n        <div class=\"info-row\" id=\"latestVersionRow\" style=\"display:none;\">\n            <span class=\"info-label\">最新版本</span>\n            <span class=\"info-value\" id=\"latestVersion\" style=\"color:#4caf50;\">-</span>\n        </div>\n        <p id=\"updateHint\" style=\"font-size:11px;color:#ff9800;margin-top:8px;display:none;\">\n            ⚠️ 发现新版本，请更新插件以获取最新功能\n        </p>\n    </div>\n    \n    <!-- 页脚 -->\n    <div class=\"footer\">\n        <div class=\"footer-row\">\n            <div class=\"auto-start\">\n                <span>自动启动</span>\n                <label class=\"switch switch-sm\">\n                    <input type=\"checkbox\" id=\"autoStartSwitch\" checked>\n                    <span class=\"slider\"></span>\n                </label>\n            </div>\n            <div class=\"cursor-version\">\n                <span>Cursor</span>\n                <span class=\"version-num\" id=\"cursorVersion\">0.0.0</span>\n            </div>\n        </div>\n        <div class=\"footer-row\" style=\"margin-top: 8px;\">\n            <div style=\"font-size: 10px; color: #666; word-break: break-all;\">\n                <span>路径: </span>\n                <span id=\"cursorPath\" style=\"color: #888;\">获取中...</span>\n            </div>\n        </div>\n    </div>\n    \n    <!-- Toast 通知 -->\n    <div class=\"toast-container\" id=\"toastContainer\">\n        <div class=\"toast\" id=\"toast\">\n            <span class=\"toast-icon\" id=\"toastIcon\">✅</span>\n            <span class=\"toast-message\" id=\"toastMessage\"></span>\n        </div>\n    </div>\n    \n    <script nonce=\"" + _0x2c52f0 + "\">\n        const vscode = acquireVsCodeApi();\n        \n        // 元素引用\n        const keyInput = document.getElementById('keyInput');\n        const activateBtn = document.getElementById('activateBtn');\n        const switchBtn = document.getElementById('switchBtn');\n        const resetBtn = document.getElementById('resetBtn');\n        const disableUpdateBtn = document.getElementById('disableUpdateBtn');\n        const cleanEnvBtn = document.getElementById('cleanEnvBtn');\n        const disableBtn = document.getElementById('disableBtn');\n        const authStatus = document.getElementById('authStatus');\n        const accountStatus = document.getElementById('accountStatus');\n        const keyDisplay = document.getElementById('keyDisplay');\n        const switchCount = document.getElementById('switchCount');\n        const expireDate = document.getElementById('expireDate');\n        const cursorVersion = document.getElementById('cursorVersion');\n        const cursorPath = document.getElementById('cursorPath');\n        \n        // 离线状态元素\n        const offlineBanner = document.getElementById('offlineBanner');\n        const retryConnectBtn = document.getElementById('retryConnectBtn');\n        \n        // 无感换号元素\n        const seamlessStatus = document.getElementById('seamlessStatus');\n        const seamlessProxySwitch = document.getElementById('seamlessProxySwitch');\n        const enableSeamlessBtn = document.getElementById('enableSeamlessBtn');\n        const disableSeamlessBtn = document.getElementById('disableSeamlessBtn');\n        const manualSwitchBtn = document.getElementById('manualSwitchBtn');\n        const seamlessResetMachineBtn = document.getElementById('seamlessResetMachineBtn');\n        const seamlessSwitchRemaining = document.getElementById('seamlessSwitchRemaining');\n        const seamlessCurrentAccount = document.getElementById('seamlessCurrentAccount');\n        \n        // 用量显示元素\n        const usageSection = document.getElementById('usageSection');\n        const refreshUsageBtn = document.getElementById('refreshUsageBtn');\n        const usageMemberType = document.getElementById('usageMemberType');\n        const usageTrialDays = document.getElementById('usageTrialDays');\n        const usageRequestCount = document.getElementById('usageRequestCount');\n        const usageCostUSD = document.getElementById('usageCostUSD');\n        const usageUpdateTime = document.getElementById('usageUpdateTime');\n        \n        // 公告元素\n        const announcementSection = document.getElementById('announcementSection');\n        const announcementIcon = document.getElementById('announcementIcon');\n        const announcementBadge = document.getElementById('announcementBadge');\n        const announcementTitle = document.getElementById('announcementTitle');\n        const announcementContent = document.getElementById('announcementContent');\n        const announcementTime = document.getElementById('announcementTime');\n        \n        // 版本元素\n        const versionSection = document.getElementById('versionSection');\n        const versionStatus = document.getElementById('versionStatus');\n        const currentVersionEl = document.getElementById('currentVersion');\n        const latestVersionEl = document.getElementById('latestVersion');\n        const latestVersionRow = document.getElementById('latestVersionRow');\n        const updateHint = document.getElementById('updateHint');\n        \n        // 顶部更新提醒条\n        const updateBanner = document.getElementById('updateBanner');\n        const updateBannerVersion = document.getElementById('updateBannerVersion');\n        const updateBannerClose = document.getElementById('updateBannerClose');\n        \n        // Toast 元素\n        const toast = document.getElementById('toast');\n        const toastIcon = document.getElementById('toastIcon');\n        const toastMessage = document.getElementById('toastMessage');\n        let toastTimer = null;\n        \n        // 显示 Toast 通知\n        function showToast(message, icon = '✅', duration = 10000) {\n            // 清除之前的定时器\n            if (toastTimer) {\n                clearTimeout(toastTimer);\n            }\n            \n            toastIcon.textContent = icon;\n            toastMessage.textContent = message;\n            toast.classList.add('show');\n            \n            // 设置自动隐藏\n            toastTimer = setTimeout(() => {\n                toast.classList.remove('show');\n            }, duration);\n        }\n        \n        // 禁用换号按钮并显示倒计时\n        let switchBtnCountdownTimer = null;\n        const originalSwitchBtnText = '一键换号(扣1积分)';\n        \n        function disableSwitchBtnWithCountdown(seconds) {\n            // 清除之前的定时器\n            if (switchBtnCountdownTimer) {\n                clearInterval(switchBtnCountdownTimer);\n            }\n            \n            let remaining = seconds;\n            manualSwitchBtn.disabled = true;\n            manualSwitchBtn.querySelector('.btn-text').textContent = remaining + '秒后可用';\n            \n            switchBtnCountdownTimer = setInterval(() => {\n                remaining--;\n                if (remaining <= 0) {\n                    clearInterval(switchBtnCountdownTimer);\n                    switchBtnCountdownTimer = null;\n                    manualSwitchBtn.disabled = false;\n                    manualSwitchBtn.querySelector('.btn-text').textContent = originalSwitchBtnText;\n                } else {\n                    manualSwitchBtn.querySelector('.btn-text').textContent = remaining + '秒后可用';\n                }\n            }, 1000);\n        }\n        \n        // 弹窗元素\n        const adminModal = document.getElementById('adminModal');\n        const adminModalClose = document.getElementById('adminModalClose');\n        const resetPermissionModal = document.getElementById('resetPermissionModal');\n        const resetPermissionClose = document.getElementById('resetPermissionClose');\n        const restartModal = document.getElementById('restartModal');\n        const restartModalTitle = document.getElementById('restartModalTitle');\n        const restartNowBtn = document.getElementById('restartNowBtn');\n        const restartLaterBtn = document.getElementById('restartLaterBtn');\n        const expiredModal = document.getElementById('expiredModal');\n        const expiredModalClose = document.getElementById('expiredModalClose');\n        const cleanEnvModal = document.getElementById('cleanEnvModal');\n        const cleanEnvConfirmBtn = document.getElementById('cleanEnvConfirmBtn');\n        const cleanEnvCancelBtn = document.getElementById('cleanEnvCancelBtn');\n        \n        // 换号确认弹窗元素\n        const switchConfirmModal = document.getElementById('switchConfirmModal');\n        const switchConfirmEmail = document.getElementById('switchConfirmEmail');\n        const switchConfirmCost = document.getElementById('switchConfirmCost');\n        const switchConfirmBtn = document.getElementById('switchConfirmBtn');\n        const switchCancelBtn = document.getElementById('switchCancelBtn');\n        \n        // 显示管理员权限弹窗\n        function showAdminModal() {\n            adminModal.classList.add('show');\n        }\n        \n        // 显示重置机器码权限提示弹窗\n        function showAdminPermissionModal() {\n            resetPermissionModal.classList.add('show');\n        }\n        \n        // 重置机器码权限弹窗 - 关闭按钮\n        resetPermissionClose.addEventListener('click', () => {\n            resetPermissionModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭权限提示弹窗\n        resetPermissionModal.addEventListener('click', (e) => {\n            if (e.target === resetPermissionModal) {\n                resetPermissionModal.classList.remove('show');\n            }\n        });\n        \n        // 显示重启提示弹窗\n        let restartModalAction = 'reload'; // 'reload' 或 'close'\n        \n        function showRestartModal(title, action = 'reload') {\n            restartModalTitle.textContent = title || '操作成功';\n            restartModalAction = action;\n            // 根据操作类型更新按钮文字\n            restartNowBtn.textContent = action === 'close' ? '立即关闭 Cursor' : '立即重启';\n            restartModal.classList.add('show');\n        }\n        \n        // 显示过期弹窗\n        function showExpiredModal() {\n            expiredModal.classList.add('show');\n        }\n        \n        // 关闭管理员弹窗\n        adminModalClose.addEventListener('click', () => {\n            adminModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭管理员弹窗\n        adminModal.addEventListener('click', (e) => {\n            if (e.target === adminModal) {\n                adminModal.classList.remove('show');\n            }\n        });\n        \n        // 立即重启/关闭按钮\n        restartNowBtn.addEventListener('click', () => {\n            restartModal.classList.remove('show');\n            if (restartModalAction === 'close') {\n                // 完全关闭 Cursor\n                vscode.postMessage({ type: 'closeCursor' });\n            } else {\n                // 重新加载窗口\n            vscode.postMessage({ type: 'reloadWindow' });\n            }\n        });\n        \n        // 稍后手动按钮\n        restartLaterBtn.addEventListener('click', () => {\n            restartModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭重启弹窗\n        restartModal.addEventListener('click', (e) => {\n            if (e.target === restartModal) {\n                restartModal.classList.remove('show');\n            }\n        });\n        \n        // 关闭过期弹窗\n        expiredModalClose.addEventListener('click', () => {\n            expiredModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭过期弹窗\n        expiredModal.addEventListener('click', (e) => {\n            if (e.target === expiredModal) {\n                expiredModal.classList.remove('show');\n            }\n        });\n        \n        // 当前账号邮箱（用于查询用量）\n        let currentAccountEmail = '';\n        let usageRefreshInterval = null;\n        // 存储完整激活码（用于复制）\n        let fullActivationKey = '';\n        // 当前剩余换号次数\n        let currentSwitchRemaining = 0;\n        // 当前到期时间\n        let currentExpireDate = '';\n        \n        // 检查卡密是否已过期\n        function isKeyExpired() {\n            if (!currentExpireDate) return true;\n            try {\n                const expireTime = new Date(currentExpireDate).getTime();\n                return Date.now() > expireTime;\n            } catch {\n                return true;\n            }\n        }\n        \n        // 格式化到期时间为北京时间\n        function formatExpireDate(dateStr) {\n            if (!dateStr) return '';\n            try {\n                // 后端返回的时间没有时区标识，假设是 UTC 时间\n                // 将空格替换为T，并添加Z表示UTC\n                let utcStr = dateStr;\n                if (!dateStr.includes('T') && !dateStr.includes('Z') && !dateStr.includes('+')) {\n                    utcStr = dateStr.replace(' ', 'T') + 'Z';\n                }\n                const date = new Date(utcStr);\n                \n                // 使用中国时区格式化（UTC+8）\n                return date.toLocaleString('zh-CN', {\n                    timeZone: 'Asia/Shanghai',\n                    year: 'numeric',\n                    month: '2-digit',\n                    day: '2-digit',\n                    hour: '2-digit',\n                    minute: '2-digit',\n                    second: '2-digit',\n                    hour12: false\n                });\n            } catch {\n                return dateStr;  // 格式化失败返回原始值\n            }\n        }\n        \n        // 隐藏激活码后几位\n        function maskKey(key) {\n            if (!key || key.length <= 8) return key;\n            return key.substring(0, key.length - 4) + '****';\n        }\n        \n        // 点击激活码复制\n        keyDisplay.addEventListener('click', () => {\n            if (!fullActivationKey) return;\n            navigator.clipboard.writeText(fullActivationKey).then(() => {\n                keyDisplay.classList.add('copied');\n                const originalText = keyDisplay.textContent;\n                keyDisplay.textContent = '已复制!';\n                setTimeout(() => {\n                    keyDisplay.textContent = maskKey(fullActivationKey);\n                    keyDisplay.classList.remove('copied');\n                }, 1000);\n            }).catch(() => {\n                // 降级方案\n                const textarea = document.createElement('textarea');\n                textarea.value = fullActivationKey;\n                document.body.appendChild(textarea);\n                textarea.select();\n                document.execCommand('copy');\n                document.body.removeChild(textarea);\n                keyDisplay.classList.add('copied');\n                keyDisplay.textContent = '已复制!';\n                setTimeout(() => {\n                    keyDisplay.textContent = maskKey(fullActivationKey);\n                    keyDisplay.classList.remove('copied');\n                }, 1000);\n            });\n        });\n        \n        // Loading 状态控制\n        function setButtonLoading(btn, loading) {\n            if (loading) {\n                btn.classList.add('loading');\n                btn.disabled = true;\n            } else {\n                btn.classList.remove('loading');\n                // 注意：某些按钮可能需要保持禁用状态，由调用方控制\n            }\n        }\n        \n        function setRefreshLoading(btn, loading) {\n            if (loading) {\n                btn.classList.add('loading');\n            } else {\n                btn.classList.remove('loading');\n            }\n        }\n        \n        // 获取初始状态\n        vscode.postMessage({ type: 'getState' });\n        vscode.postMessage({ type: 'getSeamlessStatus' });\n        vscode.postMessage({ type: 'getUserSwitchStatus' });\n        vscode.postMessage({ type: 'getProxyStatus' });\n        vscode.postMessage({ type: 'getAnnouncement' });\n        vscode.postMessage({ type: 'checkVersion' });\n        vscode.postMessage({ type: 'getCursorRunningPath' });\n        \n        // 激活按钮\n        activateBtn.addEventListener('click', () => {\n            const key = keyInput.value.trim();\n            if (!key) {\n                return;\n            }\n            setButtonLoading(activateBtn, true);\n            vscode.postMessage({ type: 'activate', key });\n        });\n        \n        // 换号按钮\n        switchBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'switch' });\n        });\n        \n        // 重置机器码按钮\n        resetBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'resetMachineId' });\n        });\n        \n        // 禁用自动更新按钮\n        disableUpdateBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'disableUpdate' });\n        });\n        \n        // 清理Cursor环境按钮 - 显示确认弹窗\n        cleanEnvBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.add('show');\n        });\n        \n        // 确认清理\n        cleanEnvConfirmBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.remove('show');\n            vscode.postMessage({ type: 'cleanEnv' });\n        });\n        \n        // 取消清理\n        cleanEnvCancelBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭清理弹窗\n        cleanEnvModal.addEventListener('click', (e) => {\n            if (e.target === cleanEnvModal) {\n                cleanEnvModal.classList.remove('show');\n            }\n        });\n        \n        // 停用按钮\n        disableBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'disable' });\n        });\n        \n        // 关闭更新提醒条\n        updateBannerClose.addEventListener('click', () => {\n            updateBanner.classList.remove('show');\n        });\n        \n        // 免魔法开关\n        seamlessProxySwitch.addEventListener('change', (e) => {\n            const wantEnabled = e.target.checked;\n            \n            // 如果要开启免魔法，检查卡密是否过期（只要没过期就可以用，不管换号次数）\n            if (wantEnabled && isKeyExpired()) {\n                e.target.checked = false;\n                showToast('授权码已过期，无法开启免魔法', '⚠️', 3000);\n                return;\n            }\n            \n            vscode.postMessage({ \n                type: 'toggleProxy', \n                enabled: wantEnabled,\n                url: ''\n            });\n        });\n        \n        // 无感换号 - 启用按钮\n        enableSeamlessBtn.addEventListener('click', () => {\n            setButtonLoading(enableSeamlessBtn, true);\n            vscode.postMessage({ type: 'injectSeamless' });\n        });\n        \n        // 无感换号 - 禁用按钮\n        disableSeamlessBtn.addEventListener('click', () => {\n            setButtonLoading(disableSeamlessBtn, true);\n            vscode.postMessage({ type: 'restoreSeamless' });\n        });\n        \n        // 无感换号 - 手动换号按钮（先检查用量）\n        manualSwitchBtn.addEventListener('click', () => {\n            setButtonLoading(manualSwitchBtn, true);\n            // 传递当前显示的账号邮箱\n            vscode.postMessage({ type: 'checkUsageBeforeSwitch', email: currentAccountEmail });\n        });\n        \n        // 换号确认弹窗 - 确认按钮\n        switchConfirmBtn.addEventListener('click', () => {\n            switchConfirmModal.classList.remove('show');\n            setButtonLoading(manualSwitchBtn, true);\n            vscode.postMessage({ type: 'confirmSwitch' });\n        });\n        \n        // 换号确认弹窗 - 取消按钮\n        switchCancelBtn.addEventListener('click', () => {\n            switchConfirmModal.classList.remove('show');\n            setButtonLoading(manualSwitchBtn, false);\n            manualSwitchBtn.disabled = false;\n        });\n        \n        // 换号确认弹窗 - 点击遮罩关闭\n        switchConfirmModal.addEventListener('click', (e) => {\n            if (e.target === switchConfirmModal) {\n                switchConfirmModal.classList.remove('show');\n                setButtonLoading(manualSwitchBtn, false);\n                manualSwitchBtn.disabled = false;\n            }\n        });\n        \n        // 无感换号区域 - 重置机器码按钮\n        seamlessResetMachineBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'resetMachineId' });\n        });\n        \n        // 刷新用量按钮\n        refreshUsageBtn.addEventListener('click', () => {\n            if (currentAccountEmail) {\n                setRefreshLoading(refreshUsageBtn, true);\n                vscode.postMessage({ type: 'getAccountUsage', email: currentAccountEmail });\n            }\n        });\n        \n        // 刷新用量函数\n        function refreshUsage() {\n            if (currentAccountEmail) {\n                vscode.postMessage({ type: 'getAccountUsage', email: currentAccountEmail });\n            }\n        }\n        \n        // 启动用量定时刷新 (每分钟一次)\n        function startUsageRefresh() {\n            if (usageRefreshInterval) {\n                clearInterval(usageRefreshInterval);\n            }\n            // 立即刷新一次\n            refreshUsage();\n            // 每60秒刷新一次\n            usageRefreshInterval = setInterval(refreshUsage, 60000);\n        }\n        \n        // 停止用量刷新\n        function stopUsageRefresh() {\n            if (usageRefreshInterval) {\n                clearInterval(usageRefreshInterval);\n                usageRefreshInterval = null;\n            }\n        }\n        \n        // 更新用量显示\n        function updateUsageDisplay(data) {\n            if (!data) return;\n            \n            const subscription = data.subscription || {};\n            const usage = data.usage || {};\n            \n            // 会员类型\n            const memberTypeMap = {\n                'free_trial': '免费试用',\n                'pro': 'Pro会员',\n                'free': '免费版',\n                'business': '商业版'\n            };\n            usageMemberType.textContent = memberTypeMap[subscription.membershipType] || subscription.membershipType || '-';\n            \n            // 试用剩余天数\n            if (subscription.daysRemainingOnTrial !== undefined && subscription.daysRemainingOnTrial !== null) {\n                usageTrialDays.textContent = subscription.daysRemainingOnTrial + ' 天';\n                usageTrialDays.style.color = subscription.daysRemainingOnTrial <= 3 ? '#f87171' : '#4ade80';\n            } else {\n                usageTrialDays.textContent = '-';\n                usageTrialDays.style.color = '#fff';\n            }\n            \n            // 请求次数\n            usageRequestCount.textContent = (usage.totalUsageCount || 0) + ' 次';\n            \n            // 已用额度\n            const costUSD = usage.totalCostUSD || 0;\n            usageCostUSD.textContent = '$' + costUSD.toFixed(2);\n            usageCostUSD.style.color = costUSD > 5 ? '#f87171' : (costUSD > 2 ? '#fbbf24' : '#4ade80');\n            \n            // 更新时间\n            usageUpdateTime.textContent = '更新于 ' + new Date().toLocaleTimeString();\n        }\n        \n        // 解析公告内容中的链接 {文字URL}\n        function parseAnnouncementContent(content) {\n            if (!content) return '';\n            \n            // 转义 HTML 特殊字符\n            let escaped = content\n                .replace(/&/g, '&amp;')\n                .replace(/</g, '&lt;')\n                .replace(/>/g, '&gt;')\n                .replace(/\"/g, '&quot;');\n            \n            // 匹配 {文字https://...} 或 {文字http://...} 格式\n            const linkRegex = /\\{([^}]+?)(https?:\\/\\/[^}]+)\\}/g;\n            \n            escaped = escaped.replace(linkRegex, function(match, text, url) {\n                return '<a href=\"' + url + '\" class=\"announcement-link\" target=\"_blank\">' + text + '</a>';\n            });\n            \n            // 将换行符转换为 <br>\n            escaped = escaped.replace(/\\n/g, '<br>');\n            \n            return escaped;\n        }\n        \n        // 更新公告显示\n        function updateAnnouncementDisplay(data) {\n            if (!data || !data.is_active) {\n                announcementSection.style.display = 'none';\n                return;\n            }\n            \n            // 显示公告区域\n            announcementSection.style.display = 'block';\n            \n            // 设置图标和类型徽章\n            const typeConfig = {\n                'info': { icon: '📢', text: '通知', class: 'info' },\n                'warning': { icon: '⚠️', text: '警告', class: 'warning' },\n                'error': { icon: '🚨', text: '重要', class: 'error' },\n                'success': { icon: '✅', text: '好消息', class: 'success' }\n            };\n            \n            const config = typeConfig[data.type] || typeConfig.info;\n            announcementIcon.textContent = config.icon;\n            announcementBadge.textContent = config.text;\n            announcementBadge.className = 'announcement-badge ' + config.class;\n            \n            // 设置标题和内容（解析链接）\n            announcementTitle.textContent = data.title || '';\n            announcementContent.innerHTML = parseAnnouncementContent(data.content || '');\n            \n            // 设置时间\n            if (data.created_at) {\n                const date = new Date(data.created_at);\n                announcementTime.textContent = date.toLocaleDateString('zh-CN', {\n                    year: 'numeric',\n                    month: '2-digit',\n                    day: '2-digit',\n                    hour: '2-digit',\n                    minute: '2-digit'\n                });\n            } else {\n                announcementTime.textContent = '';\n            }\n        }\n        \n        // 处理来自扩展的消息\n        window.addEventListener('message', event => {\n            const message = event.data;\n            \n            switch (message.type) {\n                case 'state':\n                    updateUI(message);\n                    break;\n                case 'activated':\n                    setButtonLoading(activateBtn, false);\n                    activateBtn.disabled = false;\n                    if (message.success) {\n                        // 调试日志\n                        console.log('[CursorPro] 前端收到激活成功消息:', message);\n                        \n                        authStatus.textContent = '已授权';\n                        authStatus.className = 'status-badge active';\n                        accountStatus.textContent = '已激活';\n                        accountStatus.className = 'status-badge active';\n                        switchBtn.disabled = false;\n                        // 更新激活码显示（使用后端返回的 key）\n                        fullActivationKey = message.key || keyInput.value;\n                        keyDisplay.textContent = maskKey(fullActivationKey);\n                        // 更新到期时间\n                        console.log('[CursorPro] 更新到期时间:', message.expireDate);\n                        currentExpireDate = message.expireDate || '';\n                        expireDate.textContent = formatExpireDate(currentExpireDate) || '未知';\n                        // 更新换号次数\n                        if (message.switchRemaining !== undefined) {\n                            currentSwitchRemaining = message.switchRemaining;\n                            switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                        }\n                        // 清空输入框\n                        keyInput.value = '';\n                        showToast('授权码激活成功！', '✅', 10000);\n                    } else {\n                        showToast(message.error || '激活失败', '❌', 10000);\n                    }\n                    break;\n                case 'switched':\n                    if (message.success) {\n                        switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                        showToast('换号成功: ' + (message.email || ''), '✅', 10000);\n                    } else {\n                        showToast(message.error || '换号失败', '❌', 10000);\n                    }\n                    break;\n                case 'reset':\n                    authStatus.textContent = '未授权';\n                    authStatus.className = 'status-badge inactive';\n                    accountStatus.textContent = '未激活';\n                    accountStatus.className = 'status-badge inactive';\n                    switchBtn.disabled = true;\n                    keyInput.value = '';\n                    fullActivationKey = '';\n                    keyDisplay.textContent = '尚未激活';\n                    expireDate.textContent = '尚未激活';\n                    break;\n                \n                // 激活码状态检查结果\n                case 'keyStatusChecked':\n                    if (message.valid) {\n                        // 激活码有效，更新显示\n                        currentExpireDate = message.expireDate || '';\n                        currentSwitchRemaining = message.switchRemaining || 0;\n                        expireDate.textContent = formatExpireDate(currentExpireDate);\n                        switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                    } else if (message.expired) {\n                        // 激活码已过期，显示提示并重置状态\n                        currentExpireDate = '';\n                        currentSwitchRemaining = 0;\n                        authStatus.textContent = '已过期';\n                        authStatus.className = 'status-badge inactive';\n                        authStatus.style.background = '#6e3232';\n                        authStatus.style.color = '#ff6b6b';\n                        expireDate.textContent = '已过期';\n                        expireDate.style.color = '#f87171';\n                        switchBtn.disabled = true;\n                        enableSeamlessBtn.disabled = true;\n                        // 如果免魔法已开启，自动关闭\n                        if (seamlessProxySwitch.checked) {\n                            seamlessProxySwitch.checked = false;\n                            vscode.postMessage({ type: 'toggleProxy', enabled: false, url: '' });\n                        }\n                        // 显示过期弹窗\n                        showExpiredModal();\n                    }\n                    break;\n                \n                // 用户换号状态\n                case 'userSwitchStatus':\n                    const remaining = message.switchRemaining || 0;\n                    const canSwitch = remaining > 0;\n                    \n                    // 更新全局变量\n                    currentSwitchRemaining = remaining;\n                    \n                    seamlessSwitchRemaining.textContent = remaining.toString();\n                    seamlessSwitchRemaining.style.color = canSwitch ? '#4ade80' : '#f87171';\n                    \n                    if (message.lockedAccount) {\n                        seamlessCurrentAccount.textContent = message.lockedAccount.email;\n                        \n                        // 设置当前账号邮箱并启动用量刷新\n                        if (message.lockedAccount.email && message.lockedAccount.email !== currentAccountEmail) {\n                            currentAccountEmail = message.lockedAccount.email;\n                            usageSection.style.display = 'block';\n                            startUsageRefresh();\n                        }\n                    } else {\n                        seamlessCurrentAccount.textContent = '未分配';\n                        \n                        // 没有锁定账号时隐藏用量区域\n                        currentAccountEmail = '';\n                        usageSection.style.display = 'none';\n                        stopUsageRefresh();\n                    }\n                    \n                    // 根据剩余次数控制手动换号按钮状态\n                    if (!canSwitch) {\n                        manualSwitchBtn.disabled = true;\n                    }\n                    // 启用无感换号按钮不受积分限制，只有过期才禁用\n                    enableSeamlessBtn.disabled = isKeyExpired();\n                    \n                    // 如果无感换号已启用，显示手动换号按钮和重置机器码按钮\n                    if (message.seamlessEnabled && canSwitch) {\n                        manualSwitchBtn.style.display = 'block';\n                        manualSwitchBtn.disabled = false;\n                        setButtonLoading(manualSwitchBtn, false);\n                        seamlessResetMachineBtn.style.display = 'block';\n                    }\n                    break;\n                \n                // 账号用量\n                case 'accountUsage':\n                    setRefreshLoading(refreshUsageBtn, false);\n                    if (message.success && message.data) {\n                        updateUsageDisplay(message.data);\n                    } else {\n                        usageUpdateTime.textContent = '获取失败: ' + (message.error || '未知错误');\n                        usageUpdateTime.style.color = '#f87171';\n                    }\n                    break;\n                \n                // 无感换号状态\n                case 'seamlessStatus':\n                    if (message.is_injected) {\n                        seamlessStatus.textContent = '已启用';\n                        seamlessStatus.className = 'status-badge active';\n                        enableSeamlessBtn.style.display = 'none';\n                        disableSeamlessBtn.style.display = 'block';\n                        disableSeamlessBtn.disabled = false;\n                        setButtonLoading(disableSeamlessBtn, false);\n                        manualSwitchBtn.style.display = 'block';\n                        manualSwitchBtn.disabled = false;\n                        setButtonLoading(manualSwitchBtn, false);\n                        seamlessResetMachineBtn.style.display = 'block';\n                    } else {\n                        seamlessStatus.textContent = '未启用';\n                        seamlessStatus.className = 'status-badge inactive';\n                        enableSeamlessBtn.style.display = 'block';\n                        setButtonLoading(enableSeamlessBtn, false);\n                        // 启用按钮不受积分限制，只有过期才禁用\n                        enableSeamlessBtn.disabled = isKeyExpired();\n                        disableSeamlessBtn.style.display = 'none';\n                        manualSwitchBtn.style.display = 'none';\n                        seamlessResetMachineBtn.style.display = 'none';\n                    }\n                    break;\n                \n                case 'seamlessInjected':\n                    setButtonLoading(enableSeamlessBtn, false);\n                    enableSeamlessBtn.disabled = false;\n                    if (message.success) {\n                        seamlessStatus.textContent = '已启用';\n                        seamlessStatus.className = 'status-badge active';\n                        enableSeamlessBtn.style.display = 'none';\n                        disableSeamlessBtn.style.display = 'block';\n                        manualSwitchBtn.style.display = 'block';\n                        seamlessResetMachineBtn.style.display = 'block';\n                        // 刷新用户状态\n                        vscode.postMessage({ type: 'getUserSwitchStatus' });\n                        // 显示重启提示弹窗\n                        if (message.needRestart) {\n                            showRestartModal(message.message || '无感换号已启用');\n                        }\n                    } else {\n                        // 如果是权限错误，显示自定义弹窗\n                        if (message.needAdmin) {\n                            // Mac/Linux 权限问题，显示详细提示\n                            var errorMsg = message.error || '没有写入权限';\n                            if (message.path) {\n                                errorMsg += '\\n路径: ' + message.path;\n                            }\n                            showToast(errorMsg, '🔐', 15000);\n                        } else {\n                            // 显示详细错误\n                            var detailMsg = message.error || '启用失败';\n                            if (message.details) {\n                                detailMsg += '\\n' + message.details;\n                            }\n                            showToast(detailMsg, '❌', 15000);\n                        }\n                    }\n                    break;\n                \n                case 'seamlessRestored':\n                    setButtonLoading(disableSeamlessBtn, false);\n                    disableSeamlessBtn.disabled = false;\n                    if (message.success) {\n                        seamlessStatus.textContent = '未启用';\n                        seamlessStatus.className = 'status-badge inactive';\n                        enableSeamlessBtn.style.display = 'block';\n                        disableSeamlessBtn.style.display = 'none';\n                        manualSwitchBtn.style.display = 'none';\n                        seamlessResetMachineBtn.style.display = 'none';\n                        // 显示重启提示弹窗\n                        if (message.needRestart) {\n                            showRestartModal(message.message || '无感换号已禁用');\n                        }\n                    } else {\n                        // 如果是权限错误，显示自定义弹窗\n                        if (message.needAdmin) {\n                            showAdminModal();\n                        } else {\n                            showToast(message.error || '禁用失败', '❌', 10000);\n                        }\n                    }\n                    break;\n                \n                // 用量检查结果\n                case 'usageCheckResult':\n                    if (message.success) {\n                        if (message.needConfirm) {\n                            // 需要确认，显示弹窗（按钮保持可用状态，等用户选择）\n                            setButtonLoading(manualSwitchBtn, false);\n                            manualSwitchBtn.disabled = false;\n                            switchConfirmEmail.textContent = message.email || '';\n                            switchConfirmCost.textContent = '$' + (message.costUSD || '0.00');\n                            switchConfirmModal.classList.add('show');\n                        } else {\n                            // 不需要确认，直接换号\n                            vscode.postMessage({ type: 'confirmSwitch' });\n                        }\n                    } else {\n                        setButtonLoading(manualSwitchBtn, false);\n                        manualSwitchBtn.disabled = false;\n                        showToast(message.error || '检查失败', '❌', 5000);\n                    }\n                    break;\n                \n                case 'manualSeamlessSwitched':\n                    setButtonLoading(manualSwitchBtn, false);\n                    if (message.success) {\n                        seamlessSwitchRemaining.textContent = (message.switchRemaining || 0).toString();\n                        seamlessCurrentAccount.textContent = message.email || '未知';\n                        // 显示 Toast 通知，10秒后消失\n                        showToast('已切换到: ' + (message.email || '新账号') + '，约10秒内自动生效', '✅', 10000);\n                        // 刷新状态\n                        vscode.postMessage({ type: 'getUserSwitchStatus' });\n                        // 禁用按钮10秒，显示倒计时\n                        disableSwitchBtnWithCountdown(10);\n                    } else {\n                        manualSwitchBtn.disabled = false;\n                        showToast(message.error || '换号失败', '❌', 5000);\n                    }\n                    break;\n                \n                case 'proxyStatus':\n                    // 设置免魔法开关状态\n                    seamlessProxySwitch.checked = message.enabled;\n                    break;\n                \n                // 公告\n                case 'announcement':\n                    if (message.success && message.data) {\n                        updateAnnouncementDisplay(message.data);\n                    } else {\n                        announcementSection.style.display = 'none';\n                    }\n                    break;\n                \n                // 版本检查\n                case 'versionCheck':\n                    currentVersionEl.textContent = message.currentVersion || '-';\n                    if (message.success && message.hasUpdate) {\n                        // 有更新\n                        latestVersionEl.textContent = message.latestVersion;\n                        latestVersionRow.style.display = 'flex';\n                        versionStatus.style.display = 'inline-block';\n                        versionStatus.style.background = '#ff9800';\n                        updateHint.style.display = 'block';\n                        \n                        // 显示顶部更新提醒条\n                        updateBannerVersion.textContent = 'v' + message.latestVersion;\n                        updateBanner.classList.add('show');\n                    } else if (message.success) {\n                        // 已是最新版\n                        versionStatus.textContent = '最新';\n                        versionStatus.style.display = 'inline-block';\n                        versionStatus.style.background = '#4caf50';\n                        latestVersionRow.style.display = 'none';\n                        updateHint.style.display = 'none';\n                        updateBanner.classList.remove('show');\n                    }\n                    break;\n                \n                // Cursor 运行路径\n                case 'cursorRunningPath':\n                    if (message.path) {\n                        const pathText = message.path + (message.packageExists ? ' ✓' : ' ✗');\n                        cursorPath.textContent = pathText;\n                        cursorPath.style.color = message.packageExists ? '#4ade80' : '#f87171';\n                        // 同时更新版本号\n                        if (message.cursorVersion) {\n                            cursorVersion.textContent = message.cursorVersion;\n                        }\n                    } else {\n                        cursorPath.textContent = '未找到';\n                        cursorPath.style.color = '#f87171';\n                    }\n                    break;\n                \n                // 管理员权限不足提示\n                case 'adminPermissionRequired':\n                    showAdminPermissionModal();\n                    break;\n                \n                // 机器码重置\n                case 'machineIdReset':\n                    if (message.success && message.needRestart) {\n                        // 机器码重置需要完全关闭 Cursor，不是 reload\n                        showRestartModal(message.message || '机器码重置成功', 'close');\n                    }\n                    break;\n                \n                // 通用 Toast 消息\n                case 'showToast':\n                    showToast(message.message || '', message.icon || '📢', 10000);\n                    break;\n                \n                // 网络状态\n                case 'networkStatus':\n                    updateOfflineStatus(!message.online);\n                    break;\n            }\n        });\n        \n        // 离线状态显示/隐藏\n        let wasOffline = false; // 跟踪之前是否离线\n        function updateOfflineStatus(isOffline) {\n            if (isOffline) {\n                offlineBanner.classList.add('show');\n                wasOffline = true;\n            } else {\n                offlineBanner.classList.remove('show');\n                // 只有从离线恢复到在线时才刷新状态\n                if (wasOffline) {\n                    wasOffline = false;\n                    vscode.postMessage({ type: 'getState' });\n                    vscode.postMessage({ type: 'getUserSwitchStatus' });\n                }\n            }\n        }\n        \n        // 重试连接按钮\n        retryConnectBtn.addEventListener('click', async () => {\n            retryConnectBtn.classList.add('loading');\n            retryConnectBtn.textContent = '连接中...';\n            \n            // 发起真正的网络请求来测试网络\n            vscode.postMessage({ type: 'retryConnect' });\n            \n            // 5秒后恢复按钮状态（给网络请求足够时间）\n            setTimeout(() => {\n                retryConnectBtn.classList.remove('loading');\n                retryConnectBtn.textContent = '重试';\n            }, 5000);\n        });\n        \n        function updateUI(state) {\n            if (state.isActivated) {\n                authStatus.textContent = '已授权';\n                authStatus.className = 'status-badge active';\n                accountStatus.textContent = '已激活';\n                accountStatus.className = 'status-badge active';\n                switchBtn.disabled = false;\n                fullActivationKey = state.key;\n                keyDisplay.textContent = maskKey(fullActivationKey);\n                // 更新到期时间\n                currentExpireDate = state.expireDate || '';\n                expireDate.textContent = formatExpireDate(currentExpireDate);\n                // 更新换号次数\n                if (state.switchRemaining !== undefined) {\n                    currentSwitchRemaining = state.switchRemaining;\n                    switchCount.textContent = state.switchRemaining + '/' + (state.switchLimit || 100);\n                }\n                // 启用无感换号按钮（只有过期才禁用）\n                enableSeamlessBtn.disabled = isKeyExpired();\n            }\n            cursorVersion.textContent = state.cursorVersion || '0.0.0';\n            \n            // 根据网络状态显示/隐藏离线提示\n            if (state.isOnline === false) {\n                offlineBanner.classList.add('show');\n                wasOffline = true;\n            } else if (state.isOnline === true) {\n                // 网络恢复，隐藏离线提示\n                offlineBanner.classList.remove('show');\n                wasOffline = false;\n            }\n        }\n    </script>\n</body>\n</html>";
      }
    }
  }
  async ["_handleGetAccountUsage"](_0x1b796a) {
    const _0x312bb1 = {
      'kwSDs': "[CursorPro] Toggle proxy error:",
      'cuNHx': "proxyUpdated",
      'AlVbI': '更新配置失败',
      'cBprM': "accountUsage",
      'pLAQo': "未提供账号邮箱",
      'XCtgT': function (_0x51bb3f, _0x5ae513) {
        return _0x51bb3f(_0x5ae513);
      },
      'LcuLD': "获取用量失败",
      'JvSqa': "NYkng",
      'rptjh': "请求失败"
    };
    try {
      if (!_0x1b796a) {
        this._postMessage({
          'type': _0x312bb1.cBprM,
          'success': false,
          'error': _0x312bb1["pLAQo"]
        });
        return;
      }
      0x0;
      const _0x58b290 = client_1["getApiUrl"]() + "/api/cursor-accounts/query?email=" + _0x312bb1["XCtgT"](encodeURIComponent, _0x1b796a) + '&refresh=true';
      const _0x507bbc = await _0x312bb1["XCtgT"](fetch, _0x58b290);
      const _0x46ba2b = await _0x507bbc.json();
      if (_0x46ba2b["success"] && _0x46ba2b["data"]) {
        this["_postMessage"]({
          'type': _0x312bb1["cBprM"],
          'success': true,
          'data': _0x46ba2b["data"]
        });
        const _0x4cf6e5 = _0x46ba2b["data"]["usage"] || {};
        const _0x3d3ce3 = _0x4cf6e5["totalUsageCount"] || 0x0;
        const _0x1f779f = _0x312bb1["XCtgT"](parseFloat, _0x4cf6e5["totalCostUSD"] || 0x0);
        0x0;
        extension_1["updateUsageStatusBar"](_0x3d3ce3, _0x1f779f);
      } else {
        this["_postMessage"]({
          'type': _0x312bb1.cBprM,
          'success': false,
          'error': _0x46ba2b["error"] || _0x312bb1["LcuLD"]
        });
      }
    } catch (_0x3c8684) {
      if (_0x312bb1["JvSqa"] !== 'NYkng') {
        _0x496ef8["error"](_0x312bb1["kwSDs"], _0x4d4142);
        this["_postMessage"]({
          'type': _0x312bb1["cuNHx"],
          'success': false,
          'error': _0x312bb1["AlVbI"]
        });
      } else {
        this["_postMessage"]({
          'type': _0x312bb1["cBprM"],
          'success': false,
          'error': _0x3c8684.message || _0x312bb1["rptjh"]
        });
      }
    }
  }
  async ["_handleGetAnnouncement"]() {
    const _0x507cc2 = {
      'eXcSu': "cursorpro.key",
      'wCuhU': "cursorpro.expireDate",
      'tQyYP': '请先激活授权码',
      'fEjcy': function (_0x14a329, _0x3ca24d) {
        return _0x14a329 > _0x3ca24d;
      },
      'GLUmw': "proxyUpdated",
      'Bjkrw': '授权码已过期，无法开启免魔法',
      'trGXG': 'showToast',
      'aCZjy': function (_0x85327, _0x557946) {
        return _0x85327(_0x557946);
      },
      'aHNrz': 'announcement',
      'PynOc': function (_0x4e3da2, _0x27c602) {
        return _0x4e3da2 === _0x27c602;
      },
      'LjnPR': 'ysOwe',
      'RdeWm': "获取公告失败",
      'XcVTX': "请求失败"
    };
    try {
      0x0;
      const _0x2127d9 = client_1["getApiUrl"]() + "/api/announcements/latest";
      const _0x59851a = await _0x507cc2["aCZjy"](fetch, _0x2127d9);
      const _0x1529e0 = await _0x59851a.json();
      if (_0x1529e0["success"] && _0x1529e0["data"]) {
        this._postMessage({
          'type': _0x507cc2["aHNrz"],
          'success': true,
          'data': _0x1529e0["data"]
        });
      } else {
        if ('ysOwe' === _0x507cc2["LjnPR"]) {
          this._postMessage({
            'type': "announcement",
            'success': false,
            'error': _0x1529e0["error"] || _0x507cc2["RdeWm"]
          });
        } else {
          const _0x2213b8 = this["_context"].globalState.get(_0x507cc2["eXcSu"]);
          const _0x3fde55 = this["_context"]["globalState"]["get"](_0x507cc2["wCuhU"]);
          if (!_0x2213b8) {
            this["_postMessage"]({
              'type': 'proxyUpdated',
              'success': false,
              'error': '请先激活授权码'
            });
            this["_postMessage"]({
              'type': "showToast",
              'message': _0x507cc2["tQyYP"],
              'icon': '⚠️'
            });
            return;
          }
          if (_0x3fde55) {
            const _0x88cb25 = new _0x3cd6be(_0x3fde55)["getTime"]();
            if (_0x507cc2["fEjcy"](_0x4cae44["now"](), _0x88cb25)) {
              this._postMessage({
                'type': _0x507cc2.GLUmw,
                'success': false,
                'error': _0x507cc2["Bjkrw"]
              });
              this._postMessage({
                'type': _0x507cc2["trGXG"],
                'message': "授权码已过期，无法开启免魔法",
                'icon': '⚠️'
              });
              return;
            }
          }
        }
      }
    } catch (_0x2ebc04) {
      this["_postMessage"]({
        'type': _0x507cc2["aHNrz"],
        'success': false,
        'error': _0x2ebc04.message || _0x507cc2["XcVTX"]
      });
    }
  }
  async ["_handleCheckVersion"]() {
    const _0x250fa3 = {
      'HgWOc': "[CursorPro] 使用用户配置的 Cursor 路径:",
      'QXFeq': function (_0x28c00c, _0x55597c) {
        return _0x28c00c > _0x55597c;
      },
      'lYCxA': "versionCheck",
      'QtoxZ': function (_0x5cd3f7, _0x1bb416) {
        return _0x5cd3f7 === _0x1bb416;
      },
      'xqknY': "vUHCr",
      'GbNrd': "请求失败"
    };
    try {
      0x0;
      const _0xcbd93e = await client_1["getLatestVersion"]();
      if (_0xcbd93e.success && _0xcbd93e.version) {
        const _0x59dc2f = _0xcbd93e["version"];
        const _0x1a5d58 = CursorProViewProvider["CURRENT_VERSION"];
        const _0x4acb32 = _0x250fa3["QXFeq"](this["_compareVersions"](_0x59dc2f, _0x1a5d58), 0x0);
        this["_postMessage"]({
          'type': _0x250fa3["lYCxA"],
          'success': true,
          'currentVersion': _0x1a5d58,
          'latestVersion': _0x59dc2f,
          'hasUpdate': _0x4acb32
        });
      } else {
        this["_postMessage"]({
          'type': _0x250fa3["lYCxA"],
          'success': false,
          'currentVersion': CursorProViewProvider.CURRENT_VERSION,
          'error': _0xcbd93e["error"] || "获取版本失败"
        });
      }
    } catch (_0x5d97b6) {
      if (_0x250fa3["QtoxZ"](_0x250fa3["xqknY"], "LOWQh")) {
        _0x21c480["log"](_0x250fa3["HgWOc"], _0x41f567);
        this["_cachedCursorPath"] = _0x3c3681;
        return _0xb7920c;
      } else {
        this._postMessage({
          'type': "versionCheck",
          'success': false,
          'currentVersion': CursorProViewProvider.CURRENT_VERSION,
          'error': _0x5d97b6["message"] || _0x250fa3["GbNrd"]
        });
      }
    }
  }
  ["_compareVersions"](_0x2c35a0, _0x3e2c58) {
    const _0x576d14 = {
      'PMKNW': function (_0x2cee68, _0x17cabb) {
        return _0x2cee68 < _0x17cabb;
      },
      'qyNxu': function (_0xbd034d, _0x5b41) {
        return _0xbd034d > _0x5b41;
      },
      'HZvmu': function (_0x1f686e, _0x307d8c) {
        return _0x1f686e < _0x307d8c;
      }
    };
    const _0xbaec2f = _0x2c35a0["split"]('.')["map"](Number);
    const _0x52cf6d = _0x3e2c58["split"]('.')["map"](Number);
    const _0x23e911 = Math["max"](_0xbaec2f["length"], _0x52cf6d["length"]);
    for (let _0x2d8ca5 = 0x0; _0x2d8ca5 < _0x23e911; _0x2d8ca5++) {
      const _0x237a97 = _0xbaec2f[_0x2d8ca5] || 0x0;
      const _0x266b01 = _0x52cf6d[_0x2d8ca5] || 0x0;
      if (_0x576d14["qyNxu"](_0x237a97, _0x266b01)) {
        return 0x1;
      }
      if (_0x237a97 < _0x266b01) {
        return -0x1;
      }
    }
    return 0x0;
  }
  async ["_handleGetCursorRunningPath"]() {
    const _0x46ebbb = {
      'SsULC': "[CursorPro] 使用 VS Code API 获取版本:",
      'AwKfF': 'utf-8',
      'zAvXx': "UBmxB",
      'QhWXL': "未找到",
      'bZBTW': 'cursorpro',
      'vlHDb': 'cursorPath',
      'ONVXL': function (_0x45b9b2, _0x3d0419) {
        return _0x45b9b2 === _0x3d0419;
      },
      'JPYoo': "darwin",
      'nEYhA': 'Contents',
      'EbBLW': "Resources",
      'lMfdt': "app",
      'MFjtx': "package.json",
      'NjVqB': "[CursorPro] 使用用户配置的路径:",
      'Wxyfp': "win32",
      'JSWuW': "BbiYe",
      'ACRef': "wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul",
      'ydRHF': "resources",
      'ANYDK': function (_0x3ac49f, _0x3550a9) {
        return _0x3ac49f === _0x3550a9;
      },
      'rEwYQ': "snkgX",
      'YxYZp': "BoVlO",
      'Qvzam': function (_0x5c6915, _0xdddb6e) {
        return _0x5c6915 === _0xdddb6e;
      },
      'FyfZA': function (_0x35b4f7, _0x394159) {
        return _0x35b4f7 !== _0x394159;
      },
      'eCMQp': 'DZGqD',
      'QKwAH': 'Programs',
      'eEobw': "cursor",
      'aouCU': "ZhNbs",
      'XXRrw': "WrYgR",
      'biXGl': "/Applications/Cursor.app",
      'ErbAO': "/usr/share/cursor",
      'vvvXG': ".local",
      'kVBXU': "share",
      'sxYuF': "mnjXn",
      'sYfMC': "WRpnS",
      'UFfHe': "[CursorPro] 从路径获取 Cursor 版本:",
      'HLsOj': 'cursorRunningPath',
      'stZTh': "获取失败: "
    };
    try {
      if ("UBmxB" !== _0x46ebbb.zAvXx) {
        return [{
          'email': _0x7e9b73,
          'access_token': _0x4f7a33,
          'refresh_token': _0x32c653 || _0x23d4b2
        }];
      } else {
        const _0x1b946c = process["platform"];
        let _0x306e39 = _0x46ebbb.QhWXL;
        let _0x260237 = '';
        const _0x36a669 = vscode["workspace"]["getConfiguration"](_0x46ebbb["bZBTW"]);
        const _0x49eda3 = _0x36a669["get"](_0x46ebbb["vlHDb"]);
        if (_0x49eda3 && fs.existsSync(_0x49eda3)) {
          _0x306e39 = _0x49eda3;
          if (_0x1b946c === _0x46ebbb.JPYoo) {
            _0x260237 = path["join"](_0x49eda3, _0x46ebbb["nEYhA"], _0x46ebbb["EbBLW"], _0x46ebbb["lMfdt"], _0x46ebbb["MFjtx"]);
          } else {
            _0x260237 = path["join"](_0x49eda3, "resources", _0x46ebbb.lMfdt, _0x46ebbb["MFjtx"]);
          }
          console.log(_0x46ebbb["NjVqB"], _0x49eda3);
        } else {
          if (_0x1b946c === _0x46ebbb.Wxyfp) {
            try {
              if (_0x46ebbb["JSWuW"] === "eKgQY") {
                _0x2258e6 = true;
                delete _0x2dff6a[_0x1d391b];
              } else {
                const {
                  stdout: _0x1a7f66
                } = await execAsync(_0x46ebbb["ACRef"]);
                const _0xa3209b = _0x1a7f66["match"](/ExecutablePath=(.+)/);
                if (_0xa3209b && _0xa3209b[0x1]) {
                  const _0x5d0249 = _0xa3209b[0x1]["trim"]();
                  _0x306e39 = path.dirname(_0x5d0249);
                  _0x260237 = path["join"](_0x306e39, _0x46ebbb.ydRHF, _0x46ebbb.lMfdt, _0x46ebbb.MFjtx);
                }
              }
            } catch (_0x48a57c) {
              if (_0x46ebbb["rEwYQ"] === _0x46ebbb["YxYZp"]) {
                _0x15013a["log"](_0x46ebbb["SsULC"], _0x3e70a4.version);
                return _0x1800fc.version;
              } else {
                console.log("[CursorPro] WMIC 获取路径失败:", _0x48a57c);
              }
            }
            if (_0x306e39 === _0x46ebbb["QhWXL"]) {
              if (_0x46ebbb["FyfZA"]("DZGqD", _0x46ebbb["eCMQp"])) {
                try {
                  const _0x378439 = this["_getHostsPath"]();
                  if (_0x1530ba["existsSync"](_0x378439)) {
                    return _0x4386be["readFileSync"](_0x378439, _0x46ebbb["AwKfF"]);
                  }
                } catch (_0xba9c07) {
                  _0x79d384["error"]("[CursorPro] Read hosts error:", _0xba9c07);
                }
                return '';
              } else {
                const _0x17a391 = process["env"]["LOCALAPPDATA"] || '';
                const _0x6b3334 = [path["join"](_0x17a391, _0x46ebbb["QKwAH"], 'cursor'), path["join"](_0x17a391, _0x46ebbb["eEobw"])];
                for (const _0x516d23 of _0x6b3334) {
                  const _0x495418 = path["join"](_0x516d23, _0x46ebbb["ydRHF"], "app", _0x46ebbb["MFjtx"]);
                  if (fs.existsSync(_0x495418)) {
                    _0x306e39 = _0x516d23;
                    _0x260237 = _0x495418;
                    break;
                  }
                }
              }
            }
          } else {
            if (_0x1b946c === "darwin") {
              if (_0x46ebbb["Qvzam"](_0x46ebbb["aouCU"], _0x46ebbb["XXRrw"])) {
                return null;
              } else {
                _0x306e39 = (await this["_getCursorInstallPath"]()) || _0x46ebbb["biXGl"];
                _0x260237 = path["join"](_0x306e39, _0x46ebbb["nEYhA"], _0x46ebbb.EbBLW, 'app', _0x46ebbb.MFjtx);
              }
            } else {
              const _0x1071f5 = process.env["HOME"] || '';
              const _0x34c761 = [_0x46ebbb["ErbAO"], path.join(_0x1071f5, _0x46ebbb["vvvXG"], _0x46ebbb["kVBXU"], _0x46ebbb.eEobw)];
              for (const _0x1aac5b of _0x34c761) {
                if (fs.existsSync(_0x1aac5b)) {
                  _0x306e39 = _0x1aac5b;
                  _0x260237 = path["join"](_0x1aac5b, _0x46ebbb["ydRHF"], 'app', "package.json");
                  break;
                }
              }
            }
          }
        }
        const _0x3c9745 = _0x260237 && fs["existsSync"](_0x260237);
        let _0xd636a6 = '';
        if (_0x3c9745) {
          try {
            if (_0x46ebbb["sxYuF"] === _0x46ebbb["sYfMC"]) {
              if (_0x343ee2["existsSync"](_0x44179b)) {
                return _0x52b912;
              }
            } else {
              const _0x4c9fc9 = fs.readFileSync(_0x260237, _0x46ebbb["AwKfF"]);
              const _0x4056ed = JSON["parse"](_0x4c9fc9);
              _0xd636a6 = _0x4056ed.version || '';
              console["log"](_0x46ebbb["UFfHe"], _0xd636a6);
            }
          } catch (_0x15526b) {
            console.log("[CursorPro] 读取 package.json 失败:", _0x15526b);
          }
        }
        this._postMessage({
          'type': 'cursorRunningPath',
          'path': _0x306e39,
          'packageJsonPath': _0x260237,
          'packageExists': _0x3c9745,
          'cursorVersion': _0xd636a6
        });
      }
    } catch (_0x1da737) {
      this._postMessage({
        'type': _0x46ebbb["HLsOj"],
        'path': "获取失败: " + (_0x1da737["message"] || _0x1da737),
        'packageJsonPath': '',
        'packageExists': false,
        'cursorVersion': ''
      });
    }
  }
  async ["_handleCheckUsageBeforeSwitch"](_0x423ed0) {
    const _0x46be7a = {
      'sEVKj': "[CursorPro] PowerShell Get-Process 获取路径失败",
      'kcIfn': "[CursorPro] Direct write failed, trying to grant permission",
      'qVzhF': function (_0x1030be, _0x3ef0ad) {
        return _0x1030be === _0x3ef0ad;
      },
      'NTZfw': "klkmy",
      'LnwIK': 'usageCheckResult',
      'yCHku': "未激活授权码",
      'wnjiM': function (_0x5ba0af, _0x167687) {
        return _0x5ba0af === _0x167687;
      },
      'FHkCa': "taehn",
      'Elfrz': function (_0x4cea4c, _0x4a5432) {
        return _0x4cea4c(_0x4a5432);
      },
      'uXXMl': function (_0x4a7089, _0x1a8977) {
        return _0x4a7089(_0x1a8977);
      },
      'rMdug': "Drfmf",
      'KaGPw': "lZGGL",
      'DqgLz': function (_0x3614c7, _0x5a56ba) {
        return _0x3614c7 < _0x5a56ba;
      },
      'nMItX': "aCFwf",
      'YHdCp': 'MhURV',
      'zYseP': function (_0x315829, _0x209dfd) {
        return _0x315829 !== _0x209dfd;
      },
      'XaQBc': "PgKQl",
      'PYWHP': 'hlMgj',
      'EKVNJ': "zdYFk"
    };
    try {
      if ('pydTE' !== _0x46be7a["NTZfw"]) {
        const _0x265715 = this["_context"]["globalState"]["get"]("cursorpro.key");
        if (!_0x265715) {
          this["_postMessage"]({
            'type': _0x46be7a["LnwIK"],
            'success': false,
            'error': _0x46be7a.yCHku
          });
          return;
        }
        if (!_0x423ed0) {
          if (_0x46be7a["FHkCa"] === _0x46be7a["FHkCa"]) {
            this["_postMessage"]({
              'type': "usageCheckResult",
              'success': true,
              'needConfirm': false
            });
            return;
          } else {
            _0x4ade37["window"].showErrorMessage("清理失败: " + _0x39dd6b);
          }
        }
        0x0;
        const _0xe4de04 = client_1["getApiUrl"]() + '/api/cursor-accounts/query?email=' + encodeURIComponent(_0x423ed0) + "&refresh=false";
        const _0x4e6615 = await fetch(_0xe4de04);
        const _0xa38d3b = await _0x4e6615.json();
        if (_0xa38d3b["success"] && _0xa38d3b.data) {
          if (_0x46be7a.rMdug !== _0x46be7a["KaGPw"]) {
            const _0x1a9459 = _0xa38d3b["data"]["usage"] || {};
            const _0x54f98 = parseFloat(_0x1a9459["totalCostUSD"] || 0x0);
            if (_0x46be7a["DqgLz"](_0x54f98, 0xa)) {
              if (_0x46be7a["wnjiM"](_0x46be7a["nMItX"], _0x46be7a["YHdCp"])) {
                _0x36aa30["log"](_0x46be7a["sEVKj"]);
              } else {
                this["_postMessage"]({
                  'type': _0x46be7a["LnwIK"],
                  'success': true,
                  'needConfirm': true,
                  'costUSD': _0x54f98.toFixed(0x2),
                  'email': _0x423ed0
                });
              }
            } else {
              this._postMessage({
                'type': _0x46be7a["LnwIK"],
                'success': true,
                'needConfirm': false
              });
            }
          } else {
            _0x11939f["rmSync"](_0x5a5124, {
              'recursive': true,
              'force': true
            });
            _0x5829eb++;
          }
        } else if (_0x46be7a["zYseP"]('GbpRm', _0x46be7a.XaQBc)) {
          this["_postMessage"]({
            'type': _0x46be7a["LnwIK"],
            'success': true,
            'needConfirm': false
          });
        } else {
          _0x34b65e["log"](_0x46be7a["kcIfn"]);
        }
      } else {
        if (_0x46be7a["qVzhF"](_0x12d7bd, _0x4c400f)) {
          _0x2cc937 = _0x34b272;
        }
        _0x370969[_0x2f7e57] = _0x496a29[_0x21aa14];
      }
    } catch (_0xc3e637) {
      if (_0x46be7a["zYseP"](_0x46be7a["PYWHP"], _0x46be7a["EKVNJ"])) {
        this["_postMessage"]({
          'type': 'usageCheckResult',
          'success': true,
          'needConfirm': false
        });
      } else {
        _0xd7775["push"](_0x5f24a2.name);
      }
    }
  }
  async ._handleManualSeamlessSwitch() {
    const _0x239b7a = {
      'BIFqO': "utf-8",
      'BfPph': "[CursorPro] Linux 获取进程路径失败:",
      'loKNV': 'cursorRunningPath',
      'HrshN': function (_0x5b042b, _0x3fb2de) {
        return _0x5b042b + _0x3fb2de;
      },
      'ByJnO': "获取失败: ",
      'yJBIQ': 'exYVj',
      'KvCvh': 'manualSeamlessSwitched',
      'VLaZZ': "未激活授权码",
      'tbDpF': function (_0x5a9370, _0x36f88c) {
        return _0x5a9370 !== _0x36f88c;
      },
      'yPImL': 'ingEM',
      'mlftM': function (_0x148013, _0x58777f) {
        return _0x148013 !== _0x58777f;
      },
      'jnyry': "FYJZv",
      'HxZxj': "换号失败",
      'sLjSr': "连接服务器失败"
    };
    try {
      if (_0x239b7a["yJBIQ"] === 'exYVj') {
        const _0x204f37 = this["_context"]["globalState"]["get"]("cursorpro.key");
        if (!_0x204f37) {
          this["_postMessage"]({
            'type': _0x239b7a["KvCvh"],
            'success': false,
            'error': _0x239b7a["VLaZZ"]
          });
          return;
        }
        0x0;
        const _0x4d82f2 = await client_1["switchSeamlessToken"](_0x204f37);
        if (_0x4d82f2["switched"]) {
          if (_0x4d82f2["email"]) {
            await this["_context"].globalState["update"]("cursorpro.seamlessCurrentAccount", _0x4d82f2["email"]);
          }
          this["_postMessage"]({
            'type': _0x239b7a["KvCvh"],
            'success': true,
            'email': _0x4d82f2["email"],
            'switchRemaining': _0x4d82f2.switchRemaining
          });
        } else {
          if (_0x239b7a["mlftM"]("JYbEY", _0x239b7a["jnyry"])) {
            const _0x1d8cc3 = _0x4d82f2["message"] || _0x4d82f2["error"] || _0x239b7a["HxZxj"];
            this._postMessage({
              'type': _0x239b7a["KvCvh"],
              'success': false,
              'error': _0x1d8cc3
            });
          } else {
            _0x48d9fc.warn(_0x239b7a["BfPph"], _0x2600b5);
          }
        }
      } else {
        this["_postMessage"]({
          'type': 'cursorRunningPath',
          'path': _0x239b7a["HrshN"](_0x239b7a["ByJnO"], _0x2ae8a1["message"] || _0x13ffd1),
          'packageJsonPath': '',
          'packageExists': false,
          'cursorVersion': ''
        });
      }
    } catch (_0x56a0cb) {
      const _0x38f43a = _0x56a0cb?..message || _0x239b7a["sLjSr"];
      this._postMessage({
        'type': _0x239b7a["KvCvh"],
        'success': false,
        'error': _0x38f43a
      });
    }
  }
  async ["_handleGetCursorPath"]() {
    const _0x38acb3 = {
      'tbZpe': function (_0x46700e, _0x216ec6) {
        return _0x46700e === _0x216ec6;
      },
      'pcUwb': "EPERM",
      'WPzlq': "没有写入权限",
      'drojl': 'seamlessRestored',
      'fTNeN': "activated",
      'TbbUg': "没有写入权限，请在终端执行: sudo chmod -R 777 /Applications/Cursor.app",
      'NwHIv': "seamlessInjected",
      'jmXuW': "请先激活授权码",
      'rEDBm': 'utf-8',
      'bpeCI': "启用失败",
      'TFAWN': "win32",
      'VsfTO': function (_0x5469b9, _0x18421f) {
        return _0x5469b9(_0x18421f);
      },
      'LurDi': "wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul",
      'VtoJO': 'hKLIf',
      'KDsFj': function (_0x211f3c, _0x10fb3d) {
        return _0x211f3c === _0x10fb3d;
      },
      'rLwGW': "BKPzM",
      'ePJAJ': 'ATCVo',
      'WxyNi': "lshQE",
      'lqoLD': "[CursorPro] 获取进程路径失败:",
      'oVgdC': "Cursor",
      'USGWH': "ps aux | grep -i \"[C]ursor\" | head -1 | awk '{print $11}'",
      'gDuYC': "ps aux | grep -i \"[c]ursor\" | head -1 | awk '{print $11}'",
      'bwLpU': "TJpGd",
      'sWGNb': '.config',
      'KbfNq': "rnnax",
      'dALzw': '未检测到运行中的Cursor进程',
      'mOngd': "未检测",
      'GdGfE': function (_0x3b944e, _0x2c32f1) {
        return _0x3b944e !== _0x2c32f1;
      },
      'vdFYP': "app",
      'UmBJK': 'out',
      'NSGgG': 'workbench',
      'dEWjF': "workbench.desktop.main.js",
      'AVeQH': "RgvPD",
      'lEdrt': "Contents",
      'mlBaX': "fFSTL",
      'xjVUo': "resources",
      'NFQWc': "LwcoD",
      'IvxYw': "bwKxQ",
      'UFtEi': "未找到",
      'lWQvv': function (_0x273ac0, _0x5f39b) {
        return _0x273ac0 !== _0x5f39b;
      },
      'EYQCn': "EvRNl",
      'MiEkS': "cursorPath",
      'HiXkV': function (_0xd0ebf9, _0x4cfcad) {
        return _0xd0ebf9 || _0x4cfcad;
      },
      'hlIYy': 'ZzJmG',
      'GONGu': '获取失败'
    };
    try {
      const _0x2f8924 = process.platform;
      let _0x46d162 = '';
      let _0x3fe4eb = '';
      if (_0x38acb3["tbZpe"](_0x2f8924, _0x38acb3.TFAWN)) {
        try {
          const {
            stdout: _0x19a5fc
          } = await _0x38acb3["VsfTO"](execAsync, _0x38acb3["LurDi"]);
          const _0x1f42c2 = _0x19a5fc["match"](/ExecutablePath=(.+)/);
          if (_0x1f42c2 && _0x1f42c2[0x1]) {
            const _0x4dbd9f = _0x1f42c2[0x1]["trim"]();
            _0x46d162 = path.dirname(_0x4dbd9f);
          }
        } catch (_0x1aba5f) {
          if (_0x38acb3["VtoJO"] !== "hKLIf") {
            if (_0x38acb3["tbZpe"](_0x763182["code"], _0x38acb3["pcUwb"]) || _0x38acb3["tbZpe"](_0x1d6dfe["code"], "EACCES")) {
              const _0x5910ed = _0x38acb3["WPzlq"];
              this["_postMessage"]({
                'type': _0x38acb3["drojl"],
                'success': false,
                'error': _0x5910ed,
                'needAdmin': true
              });
              return;
            }
            throw _0x25718f;
          } else {
            try {
              if (_0x38acb3["KDsFj"](_0x38acb3["rLwGW"], _0x38acb3["rLwGW"])) {
                const {
                  stdout: _0x54d048
                } = await execAsync('powershell -Command "Get-Process Cursor -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Path"');
                if (_0x54d048["trim"]()) {
                  if (_0x38acb3["ePJAJ"] !== _0x38acb3.WxyNi) {
                    _0x46d162 = path["dirname"](_0x54d048["trim"]());
                  } else {
                    this._postMessage({
                      'type': _0x38acb3["fTNeN"],
                      'success': false,
                      'error': '连接服务器失败'
                    });
                  }
                }
              } else {
                _0x4bf468 = _0x1e8026["substring"](0x0, _0x40d01d) + _0x57a9ae["substring"](_0x17b950 + this.HOSTS_MARKER_END["length"]);
              }
            } catch (_0x215316) {
              console.warn(_0x38acb3["lqoLD"], _0x215316);
            }
          }
        }
        const _0x268111 = process["env"]["APPDATA"] || '';
        _0x3fe4eb = path["join"](_0x268111, _0x38acb3.oVgdC);
      } else {
        if (_0x2f8924 === "darwin") {
          try {
            const {
              stdout: _0x4f065d
            } = await _0x38acb3["VsfTO"](execAsync, _0x38acb3["USGWH"]);
            if (_0x4f065d.trim()) {
              const _0x5ebf8f = _0x4f065d["trim"]();
              const _0x228acb = _0x5ebf8f.match(/(.+\.app)/);
              if (_0x228acb) {
                _0x46d162 = _0x228acb[0x1];
              } else {
                _0x46d162 = path.dirname(_0x5ebf8f);
              }
            }
          } catch (_0x2b309c) {
            console["warn"]("[CursorPro] 获取进程路径失败:", _0x2b309c);
          }
          const _0x6ea467 = process["env"].HOME || '';
          _0x3fe4eb = path.join(_0x6ea467, 'Library', "Application Support", _0x38acb3.oVgdC);
        } else {
          try {
            const {
              stdout: _0x522bb9
            } = await execAsync(_0x38acb3["gDuYC"]);
            if (_0x522bb9["trim"]()) {
              if (_0x38acb3["tbZpe"](_0x38acb3["bwLpU"], _0x38acb3["bwLpU"])) {
                _0x46d162 = path.dirname(_0x522bb9["trim"]());
              } else {
                _0x3596e8 = _0x38acb3["TbbUg"];
              }
            }
          } catch (_0x22983f) {
            console["warn"](_0x38acb3["lqoLD"], _0x22983f);
          }
          const _0x456726 = process["env"].HOME || '';
          _0x3fe4eb = path["join"](_0x456726, _0x38acb3["sWGNb"], _0x38acb3["oVgdC"]);
        }
      }
      if (!_0x46d162) {
        if ("dWdoR" === _0x38acb3["KbfNq"]) {
          this["_postMessage"]({
            'type': _0x38acb3["NwHIv"],
            'success': false,
            'error': _0x38acb3.jmXuW
          });
          return;
        } else {
          _0x46d162 = _0x38acb3["dALzw"];
        }
      }
      let _0x121b7c = '';
      if (_0x46d162 && !_0x46d162.includes(_0x38acb3["mOngd"])) {
        if (_0x2f8924 === _0x38acb3["TFAWN"]) {
          if (_0x38acb3["GdGfE"]('lPhmJ', "lPhmJ")) {
            _0x1588d9["telemetry.devDeviceId"] = _0x11e099["devDeviceId"];
          } else {
            _0x121b7c = path["join"](_0x46d162, 'resources', _0x38acb3.vdFYP, 'out', 'vs', 'workbench', _0x38acb3["dEWjF"]);
          }
        } else {
          if (_0x2f8924 === "darwin") {
            if (_0x38acb3["KDsFj"]("RgvPD", _0x38acb3.AVeQH)) {
              _0x121b7c = path["join"](_0x46d162, _0x38acb3.lEdrt, "Resources", _0x38acb3.vdFYP, _0x38acb3["UmBJK"], 'vs', _0x38acb3["NSGgG"], 'workbench.desktop.main.js');
            } else {
              _0x37d2a5["writeFileSync"](_0x3c282c, _0x4bc83c, 'utf-8');
              _0x3e6238 = true;
            }
          } else {
            if ("PYNDj" === _0x38acb3["mlBaX"]) {
              this["_postMessage"]({
                'type': "seamlessInjected",
                'success': false,
                'error': _0x38acb3["bpeCI"]
              });
              return;
            } else {
              _0x121b7c = path["join"](_0x46d162, _0x38acb3["xjVUo"], _0x38acb3["vdFYP"], _0x38acb3["UmBJK"], 'vs', "workbench", _0x38acb3["dEWjF"]);
            }
          }
        }
        if (!fs["existsSync"](_0x121b7c)) {
          if (_0x38acb3["NFQWc"] !== _0x38acb3["IvxYw"]) {
            _0x121b7c = (await this["_getWorkbenchPathAsync"]()) || _0x38acb3["UFtEi"];
          } else {
            const _0x984d92 = _0x84f583["match"](/InstallLocation\s+REG_SZ\s+(.+)/);
            if (_0x984d92 && _0x984d92[0x1] && _0x529792["existsSync"](_0x984d92[0x1]["trim"]())) {
              _0x36e7db = _0x984d92[0x1]["trim"]();
            }
          }
        }
      } else {
        if (_0x38acb3["lWQvv"](_0x38acb3["EYQCn"], "npeOU")) {
          _0x121b7c = (await this["_getWorkbenchPathAsync"]()) || "未找到";
        } else {
          return;
        }
      }
      const _0xbd859c = _0x46d162 && !_0x46d162["includes"](_0x38acb3["mOngd"]) ? fs.existsSync(_0x46d162) : false;
      const _0x354cf1 = _0x3fe4eb ? fs["existsSync"](_0x3fe4eb) : false;
      this["_postMessage"]({
        'type': _0x38acb3["MiEkS"],
        'cursorPath': _0xbd859c ? _0x46d162 : _0x38acb3["HiXkV"](_0x46d162, "未找到"),
        'dataPath': _0x354cf1 ? _0x3fe4eb : _0x38acb3["UFtEi"],
        'workbenchPath': _0x121b7c,
        'platform': _0x2f8924
      });
    } catch (_0x5c0ff6) {
      if (_0x38acb3["GdGfE"](_0x38acb3["hlIYy"], "GnlEK")) {
        this["_postMessage"]({
          'type': _0x38acb3.MiEkS,
          'cursorPath': _0x38acb3["GONGu"],
          'dataPath': '获取失败',
          'workbenchPath': _0x38acb3["GONGu"],
          'error': _0x5c0ff6["message"]
        });
      } else {
        this["_view"]?..webview["postMessage"](_0x1b6a0f);
      }
    }
  }
  async ._loadAccountsFromDB() {
    const _0xefdab9 = {
      'oRodx': "[CursorPro] 找到 Cursor 版本:",
      'pvPNp': "路径:",
      'wjbSZ': "cursorAuth/accessToken",
      'YZqNp': "cursorAuth/refreshToken",
      'dbFLV': "cursorAuth/cachedEmail",
      'zHYNu': function (_0x3aff44, _0x103caf) {
        return _0x3aff44 && _0x103caf;
      },
      'rTrKG': function (_0x26321b, _0x5690c1) {
        return _0x26321b || _0x5690c1;
      }
    };
    try {
      0x0;
      const _0x3d6d98 = account_1["getCursorPaths"]();
      const {
        dbPath: _0x22a865
      } = _0x3d6d98;
      if (!fs["existsSync"](_0x22a865)) {
        return 'OIoiO' === "YEFIo" ? (_0x4484c3.log(_0xefdab9["oRodx"], _0xa4ee3f["version"], _0xefdab9["pvPNp"], _0x4c184d), _0x4e0899["version"]) : [];
      }
      0x0;
      const _0x483399 = await sqlite_1.sqliteGet(_0x22a865, _0xefdab9["wjbSZ"]);
      0x0;
      const _0x207002 = await sqlite_1["sqliteGet"](_0x22a865, _0xefdab9["YZqNp"]);
      0x0;
      const _0x1c5151 = await sqlite_1["sqliteGet"](_0x22a865, _0xefdab9["dbFLV"]);
      if (_0xefdab9["zHYNu"](_0x483399, _0x1c5151)) {
        return [{
          'email': _0x1c5151,
          'access_token': _0x483399,
          'refresh_token': _0xefdab9["rTrKG"](_0x207002, _0x483399)
        }];
      }
      return [];
    } catch (_0x7a83d1) {
      console.error("[CursorPro] 读取账号失败:", _0x7a83d1);
      return [];
    }
  }
  async ["_sendState"]() {
    const _0xd6358c = {
      'vIjoy': 'cursorpro.expireDate',
      'PnvAx': 'cursorpro.switchRemaining',
      'WEZcg': "cursorpro.switchLimit",
      'MBSJn': "state",
      'CNAgf': function (_0x34bf6b, _0x520b84) {
        return _0x34bf6b || _0x520b84;
      },
      'dNuxR': function (_0x289948, _0x9f1b8e) {
        return _0x289948 || _0x9f1b8e;
      },
      'tZHta': function (_0x216c5e, _0x1ac055) {
        return _0x216c5e ?? _0x1ac055;
      }
    };
    const _0x32793c = this["_context"]["globalState"]["get"]("cursorpro.key");
    const _0x59a0ae = this["_context"].globalState["get"]('cursorpro.expireDate');
    const _0x769674 = this["_context"]["globalState"]["get"](_0xd6358c["PnvAx"]);
    const _0x340d3f = this["_context"]["globalState"]["get"](_0xd6358c["WEZcg"]);
    const _0x440ba5 = await this["_getCursorVersion"]();
    0x0;
    const _0x5026a1 = client_1["getOnlineStatus"]();
    this["_postMessage"]({
      'type': _0xd6358c["MBSJn"],
      'isActivated': !!_0x32793c,
      'key': _0xd6358c["CNAgf"](_0x32793c, ''),
      'expireDate': _0xd6358c["dNuxR"](_0x59a0ae, ''),
      'switchRemaining': _0x769674 ?? 0x0,
      'switchLimit': _0xd6358c["tZHta"](_0x340d3f, 0x64),
      'cursorVersion': _0x440ba5,
      'isOnline': _0x5026a1
    });
  }
  async ["_handleRetryConnect"]() {
    const _0x229eab = {
      'rRAOR': function (_0x37df60, _0x561596) {
        return _0x37df60 < _0x561596;
      },
      'dLQJl': function (_0x4e9578, _0x5e18f6) {
        return _0x4e9578 < _0x5e18f6;
      },
      'vBOsW': 'cursorpro.key',
      'NhGlq': function (_0x10685c, _0x39a256) {
        return _0x10685c === _0x39a256;
      },
      'uUjDH': "NZAQL",
      'PglaH': function (_0x2bd5d8, _0x594963) {
        return _0x2bd5d8 !== _0x594963;
      },
      'zwtrx': "ANSiR",
      'vNOCd': "PPUYG",
      'vKktT': function (_0x1fc5b2, _0x4589aa, _0x33e731) {
        return _0x1fc5b2(_0x4589aa, _0x33e731);
      },
      'ZQDbk': "networkStatus",
      'FbRju': "[CursorPro] Retry connect failed:"
    };
    try {
      const _0x38b05a = this["_context"]["globalState"]["get"](_0x229eab["vBOsW"]);
      if (_0x38b05a) {
        if (_0x229eab["NhGlq"](_0x229eab["uUjDH"], _0x229eab["uUjDH"])) {
          0x0;
          await client_1.verifyKey(_0x38b05a);
        } else {
          const _0x32a796 = _0x54cc32.split('.')["map"](_0x4b9729);
          const _0x2142ee = _0x996c39["split"]('.')["map"](_0x1e92ec);
          const _0xa1e4e2 = _0x523189["max"](_0x32a796["length"], _0x2142ee["length"]);
          for (let _0x509f14 = 0x0; _0x229eab["rRAOR"](_0x509f14, _0xa1e4e2); _0x509f14++) {
            const _0x563ae1 = _0x32a796[_0x509f14] || 0x0;
            const _0x3a3596 = _0x2142ee[_0x509f14] || 0x0;
            if (_0x563ae1 > _0x3a3596) {
              return 0x1;
            }
            if (_0x229eab["dLQJl"](_0x563ae1, _0x3a3596)) {
              return -0x1;
            }
          }
          return 0x0;
        }
      } else {
        if (_0x229eab["PglaH"](_0x229eab.zwtrx, _0x229eab["vNOCd"])) {
          0x0;
          const _0x4f7f5e = client_1["getApiUrl"]() + '/api/announcements/latest';
          await _0x229eab["vKktT"](fetch, _0x4f7f5e, {
            'method': 'GET'
          });
        } else {
          _0x1df13e = _0x281b54[0x1].trim();
        }
      }
      await this["_sendState"]();
      this._postMessage({
        'type': _0x229eab.ZQDbk,
        'online': true
      });
    } catch (_0x46319e) {
      console["error"](_0x229eab["FbRju"], _0x46319e);
      this["_postMessage"]({
        'type': "networkStatus",
        'online': false
      });
    }
  }
  async ["_getCursorVersion"]() {
    const _0x4f58a2 = {
      'PTNWv': "[CursorPro] 首次启用，从备份恢复干净的 workbench 文件",
      'wswmm': "[CursorPro] 备份恢复成功",
      'QtJiM': "[CursorPro] 备份恢复失败:",
      'Xqkdy': "cursorPath",
      'ItKog': "获取失败",
      'YSmFZ': function (_0x4ecad8, _0x2cb4f2) {
        return _0x4ecad8 !== _0x2cb4f2;
      },
      'bglvq': 'LtYMm',
      'YXUju': "FXgaA",
      'vhvSM': function (_0xf9bd4a, _0x1405ae) {
        return _0xf9bd4a === _0x1405ae;
      },
      'bBFPC': "Contents",
      'gBPlE': "Resources",
      'bUMcY': 'app',
      'CaEkI': "package.json",
      'CfoeP': "Programs",
      'pwRyy': "Cursor",
      'TosHP': "resources",
      'LPmpS': "cursor",
      'RYOAX': "AppData",
      'qCStx': "Local",
      'DEXlW': "darwin",
      'VNwrn': '/Applications/Cursor.app/Contents/Resources/app/package.json',
      'fjFtX': "/usr/share/cursor/resources/app/package.json",
      'jHXyq': "/opt/Cursor/resources/app/package.json",
      'WWWWp': ".local",
      'dUUUB': "olTfK",
      'JVRzx': 'gPJxP',
      'uGyrr': "dqmkC",
      'RwEEN': "utf-8",
      'PKTCU': "Eoizq",
      'CRnub': "YcIFS",
      'ZQMXp': "路径:",
      'dEEFY': "[CursorPro] 尝试路径失败:",
      'opjtq': function (_0xd9c47c, _0x4fb652) {
        return _0xd9c47c(_0x4fb652);
      },
      'zEiiQ': "vscode",
      'GjUNd': "[CursorPro] 使用 VS Code API 获取版本:",
      'qlNII': "[CursorPro] 未找到 Cursor 版本，尝试的路径:",
      'GOgfB': "[CursorPro] 获取 Cursor 版本失败:"
    };
    try {
      const _0x574db7 = process["platform"];
      const _0x369839 = [];
      const _0x4065be = await this._getCursorInstallPath();
      if (_0x4065be) {
        if (_0x4f58a2["YSmFZ"](_0x4f58a2["bglvq"], _0x4f58a2.YXUju)) {
          if (_0x4f58a2["vhvSM"](_0x574db7, "darwin")) {
            _0x369839["push"](path.join(_0x4065be, _0x4f58a2.bBFPC, _0x4f58a2["gBPlE"], _0x4f58a2["bUMcY"], 'package.json'));
          } else {
            _0x369839["push"](path["join"](_0x4065be, "resources", 'app', _0x4f58a2.CaEkI));
          }
        } else {
          _0x219157["rmSync"](_0x1a5f35, {
            'recursive': true,
            'force': true
          });
        }
      }
      if (_0x4f58a2["vhvSM"](_0x574db7, "win32")) {
        const _0x2ff2ee = process["env"].LOCALAPPDATA || '';
        const _0x55e816 = process["env"]["USERPROFILE"] || '';
        const _0x1f7bd3 = process["env"].ProgramFiles || "C:\\Program Files";
        const _0x1defa4 = process["env"]['ProgramFiles(x86)'] || "C:\\Program Files (x86)";
        _0x369839["push"](path["join"](_0x2ff2ee, _0x4f58a2["CfoeP"], _0x4f58a2["pwRyy"], _0x4f58a2.TosHP, "app", "package.json"), path["join"](_0x2ff2ee, _0x4f58a2.CfoeP, _0x4f58a2["LPmpS"], _0x4f58a2.TosHP, 'app', _0x4f58a2.CaEkI), path["join"](_0x55e816, _0x4f58a2["RYOAX"], _0x4f58a2["qCStx"], _0x4f58a2["CfoeP"], _0x4f58a2["pwRyy"], _0x4f58a2["TosHP"], _0x4f58a2["bUMcY"], _0x4f58a2["CaEkI"]), path["join"](_0x1f7bd3, _0x4f58a2.pwRyy, _0x4f58a2.TosHP, 'app', "package.json"), path["join"](_0x1f7bd3, _0x4f58a2["LPmpS"], "resources", _0x4f58a2["bUMcY"], _0x4f58a2["CaEkI"]), path["join"](_0x1defa4, "Cursor", _0x4f58a2.TosHP, _0x4f58a2["bUMcY"], _0x4f58a2["CaEkI"]));
      } else {
        if (_0x574db7 === _0x4f58a2["DEXlW"]) {
          _0x369839.push(_0x4f58a2["VNwrn"]);
        } else {
          const _0x221758 = process.env.HOME || '';
          _0x369839["push"](_0x4f58a2["fjFtX"], _0x4f58a2["jHXyq"], "/opt/cursor/resources/app/package.json", path["join"](_0x221758, _0x4f58a2.WWWWp, 'share', "cursor", _0x4f58a2["TosHP"], 'app', _0x4f58a2.CaEkI));
        }
      }
      for (const _0x339dc7 of _0x369839) {
        if (_0x4f58a2["YSmFZ"]("olTfK", _0x4f58a2["dUUUB"])) {
          return;
        } else {
          try {
            if (_0x4f58a2["JVRzx"] !== "eTsxR") {
              if (fs.existsSync(_0x339dc7)) {
                if (_0x4f58a2["YSmFZ"](_0x4f58a2["uGyrr"], _0x4f58a2.uGyrr)) {
                  _0x14c38f["log"](_0x4f58a2.PTNWv);
                  try {
                    _0x4ace07["copyFileSync"](_0x1facd8, _0xbb494e);
                    _0x2425e0["log"](_0x4f58a2["wswmm"]);
                  } catch (_0x5ee7d8) {
                    _0x18ad92["error"](_0x4f58a2["QtJiM"], _0x5ee7d8);
                  }
                } else {
                  const _0x3621b8 = fs["readFileSync"](_0x339dc7, _0x4f58a2["RwEEN"]);
                  const _0x1f565f = JSON["parse"](_0x3621b8);
                  if (_0x1f565f["version"]) {
                    if (_0x4f58a2["YSmFZ"](_0x4f58a2["PKTCU"], _0x4f58a2["CRnub"])) {
                      console["log"]("[CursorPro] 找到 Cursor 版本:", _0x1f565f["version"], _0x4f58a2["ZQMXp"], _0x339dc7);
                      return _0x1f565f["version"];
                    } else {
                      this["_postMessage"]({
                        'type': _0x4f58a2["Xqkdy"],
                        'cursorPath': "获取失败",
                        'dataPath': _0x4f58a2["ItKog"],
                        'workbenchPath': _0x4f58a2["ItKog"],
                        'error': _0x130c99["message"]
                      });
                    }
                  }
                }
              }
            } else if (_0x1bada8.statSync(_0x1e9bf4)["isDirectory"]()) {
              _0x56260a["rmSync"](_0x74e730, {
                'recursive': true,
                'force': true
              });
            } else {
              _0x309108["unlinkSync"](_0x19d74d);
            }
          } catch (_0x2af808) {
            console["log"](_0x4f58a2["dEEFY"], _0x339dc7, _0x2af808);
          }
        }
      }
      try {
        const _0xe1f1d3 = _0x4f58a2["opjtq"](require, _0x4f58a2["zEiiQ"]);
        if (_0xe1f1d3.version) {
          console["log"]("[CursorPro] 使用 VS Code API 获取版本:", _0xe1f1d3["version"]);
          return _0xe1f1d3.version;
        }
      } catch (_0x35ddef) {}
      console["log"](_0x4f58a2["qlNII"], _0x369839);
      return '未知';
    } catch (_0x311666) {
      console.error(_0x4f58a2["GOgfB"], _0x311666);
      return '未知';
    }
  }
  ._postMessage(_0x571950) {
    this["_view"]?.["webview"]["postMessage"](_0x571950);
  }
  ["_getNonce"]() {
    const _0x323fa5 = {
      'YiwNs': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
      'FVmpm': function (_0x262e06, _0x566f52) {
        return _0x262e06 < _0x566f52;
      },
      'XVmEg': function (_0x892c66, _0x1cd020) {
        return _0x892c66 === _0x1cd020;
      },
      'gFjzo': 'UMZcN',
      'RjXnp': function (_0xd635ba, _0x484045) {
        return _0xd635ba * _0x484045;
      }
    };
    let _0x14dd44 = '';
    const _0x44199d = _0x323fa5["YiwNs"];
    for (let _0x5ece7c = 0x0; _0x323fa5["FVmpm"](_0x5ece7c, 0x20); _0x5ece7c++) {
      if (_0x323fa5["XVmEg"](_0x323fa5["gFjzo"], "UMZcN")) {
        _0x14dd44 += _0x44199d["charAt"](Math["floor"](Math["random"]() * _0x44199d["length"]));
      } else if (_0x56e4a8["existsSync"](_0x2ed688)) {
        _0x2ab3fb["rmSync"](_0x258880, {
          'recursive': true,
          'force': true
        });
        _0x3de72a++;
        _0x1d3455["log"]("[CursorPro] 已清理: " + _0x202472);
      }
    }
    return _0x14dd44;
  }
  ["_getHtmlContent"](_0x504c5f) {
    const _0x1d6267 = this["_getNonce"]();
    return "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-" + _0x1d6267 + "'; img-src " + _0x504c5f["cspSource"] + " https: data:; font-src " + _0x504c5f["cspSource"] + "; worker-src 'none';\">\n    <title>CursorPro</title>\n    <script nonce=\"" + _0x1d6267 + "\">\n        // 尽早清理 Service Worker（在 head 中执行，比 body 更早）\n        if ('serviceWorker' in navigator) {\n            navigator.serviceWorker.getRegistrations().then(function(regs) {\n                regs.forEach(function(reg) { reg.unregister(); });\n            }).catch(function() {});\n        }\n    </script>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n            background: #1e1e1e;\n            color: #cccccc;\n            padding: 12px;\n            font-size: 13px;\n        }\n        \n        .section {\n            margin-bottom: 16px;\n            padding: 12px;\n            background: #252526;\n            border-radius: 6px;\n        }\n        \n        .section-title {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            margin-bottom: 12px;\n            font-size: 13px;\n            color: #ffffff;\n        }\n        \n        .section-title .icon {\n            font-size: 16px;\n        }\n        \n        .status-badge {\n            margin-left: auto;\n            padding: 2px 8px;\n            border-radius: 4px;\n            font-size: 11px;\n        }\n        \n        .status-badge.inactive {\n            background: #6e3232;\n            color: #ff6b6b;\n        }\n        \n        .status-badge.active {\n            background: #2d4a3e;\n            color: #4ade80;\n        }\n        \n        .input-group {\n            display: flex;\n            gap: 8px;\n            margin-bottom: 12px;\n        }\n        \n        input[type=\"text\"] {\n            flex: 1;\n            padding: 8px 12px;\n            background: #3c3c3c;\n            border: 1px solid #4a4a4a;\n            border-radius: 4px;\n            color: #ffffff;\n            font-size: 13px;\n        }\n        \n        input[type=\"text\"]::placeholder {\n            color: #888888;\n        }\n        \n        input[type=\"text\"]:focus {\n            outline: none;\n            border-color: #007acc;\n        }\n        \n        .btn {\n            padding: 8px 16px;\n            border: none;\n            border-radius: 4px;\n            font-size: 13px;\n            cursor: pointer;\n            font-weight: 500;\n            transition: opacity 0.2s;\n        }\n        \n        .btn:hover {\n            opacity: 0.9;\n        }\n        \n        .btn:disabled {\n            opacity: 0.5;\n            cursor: not-allowed;\n        }\n        \n        .btn-primary {\n            background: #007acc;\n            color: white;\n        }\n        \n        .btn-purple {\n            background: #8b5cf6;\n            color: white;\n        }\n        \n        .btn-blue {\n            background: #3b82f6;\n            color: white;\n        }\n        \n        .btn-red {\n            background: #ef4444;\n            color: white;\n        }\n        \n        .btn-block {\n            display: block;\n            width: 100%;\n            margin-bottom: 8px;\n        }\n        \n        .info-row {\n            display: flex;\n            justify-content: space-between;\n            padding: 6px 0;\n            border-bottom: 1px solid #3c3c3c;\n        }\n        \n        .info-row:last-child {\n            border-bottom: none;\n        }\n        \n        .info-label {\n            color: #888888;\n        }\n        \n        .info-value {\n            color: #ffffff;\n        }\n        \n        .usage-row {\n            display: flex;\n            gap: 12px;\n            margin-bottom: 8px;\n        }\n        \n        .usage-row:last-of-type {\n            margin-bottom: 0;\n        }\n        \n        .usage-item {\n            flex: 1;\n            display: flex;\n            justify-content: space-between;\n            padding: 6px 10px;\n            background: #2d2d2d;\n            border-radius: 4px;\n        }\n        \n        .switch-container {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n        \n        .switch {\n            position: relative;\n            width: 40px;\n            height: 20px;\n        }\n        \n        .switch input {\n            opacity: 0;\n            width: 0;\n            height: 0;\n        }\n        \n        .slider {\n            position: absolute;\n            cursor: pointer;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background-color: #4a4a4a;\n            border-radius: 20px;\n            transition: 0.3s;\n        }\n        \n        .slider:before {\n            position: absolute;\n            content: \"\";\n            height: 16px;\n            width: 16px;\n            left: 2px;\n            bottom: 2px;\n            background-color: white;\n            border-radius: 50%;\n            transition: 0.3s;\n        }\n        \n        input:checked + .slider {\n            background-color: #8b5cf6;\n        }\n        \n        input:checked + .slider:before {\n            transform: translateX(20px);\n        }\n        \n        /* 小尺寸开关样式 */\n        .switch-sm {\n            position: relative;\n            width: 32px;\n            height: 16px;\n        }\n        \n        .switch-sm .slider:before {\n            height: 12px;\n            width: 12px;\n            left: 2px;\n            bottom: 2px;\n        }\n        \n        .switch-sm input:checked + .slider:before {\n            transform: translateX(16px);\n        }\n        \n        .pro-badge {\n            background: linear-gradient(90deg, #8b5cf6, #d946ef);\n            padding: 2px 6px;\n            border-radius: 4px;\n            font-size: 10px;\n            font-weight: bold;\n            color: white;\n        }\n        \n        .footer {\n            margin-top: 16px;\n            padding: 12px;\n            background: linear-gradient(135deg, rgba(60, 60, 60, 0.3) 0%, rgba(40, 40, 40, 0.5) 100%);\n            border-radius: 8px;\n            border: 1px solid rgba(255, 255, 255, 0.05);\n        }\n        \n        .footer-row {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n        \n        .auto-start {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            font-size: 11px;\n            color: #888;\n        }\n        \n        .cursor-version {\n            display: flex;\n            align-items: center;\n            gap: 6px;\n            font-size: 11px;\n            color: #666;\n            padding: 4px 10px;\n            background: rgba(0, 0, 0, 0.2);\n            border-radius: 12px;\n        }\n        \n        .cursor-version .version-num {\n            color: #a78bfa;\n            font-weight: 500;\n        }\n        \n        /* 自定义弹窗样式 */\n        .modal-overlay {\n            display: none;\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.85);\n            backdrop-filter: blur(4px);\n            z-index: 1000;\n            justify-content: center;\n            align-items: center;\n            animation: fadeIn 0.2s ease;\n        }\n        \n        @keyframes fadeIn {\n            from { opacity: 0; }\n            to { opacity: 1; }\n        }\n        \n        @keyframes slideIn {\n            from { \n                opacity: 0;\n                transform: scale(0.9) translateY(-10px);\n            }\n            to { \n                opacity: 1;\n                transform: scale(1) translateY(0);\n            }\n        }\n        \n        .modal-overlay.show {\n            display: flex;\n        }\n        \n        .modal-content {\n            background: linear-gradient(145deg, #1e1e1e 0%, #2a2a2a 100%);\n            border-radius: 12px;\n            padding: 16px 20px;\n            max-width: 260px;\n            width: 90%;\n            text-align: center;\n            box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.05);\n            animation: slideIn 0.2s ease;\n        }\n        \n        .modal-icon {\n            width: 44px;\n            height: 44px;\n            margin: 0 auto 12px;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 22px;\n        }\n        \n        .modal-icon.warning {\n            background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n            box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);\n        }\n        \n        .modal-icon.success {\n            background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n            box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);\n        }\n        \n        .modal-title {\n            font-size: 15px;\n            font-weight: 600;\n            color: #fff;\n            margin-bottom: 6px;\n        }\n        \n        .modal-message {\n            font-size: 12px;\n            color: #9ca3af;\n            margin-bottom: 16px;\n            line-height: 1.5;\n        }\n        \n        .modal-buttons {\n            display: flex;\n            gap: 8px;\n            justify-content: center;\n        }\n        \n        .modal-btn {\n            padding: 8px 16px;\n            border: none;\n            border-radius: 8px;\n            font-size: 12px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: all 0.15s ease;\n        }\n        \n        .modal-btn.primary {\n            background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n            color: white;\n            box-shadow: 0 2px 8px rgba(139, 92, 246, 0.4);\n        }\n        \n        .modal-btn.primary:hover {\n            box-shadow: 0 4px 12px rgba(139, 92, 246, 0.5);\n        }\n        \n        .modal-btn.secondary {\n            background: rgba(255, 255, 255, 0.08);\n            color: #9ca3af;\n            border: 1px solid rgba(255, 255, 255, 0.1);\n        }\n        \n        .modal-btn.secondary:hover {\n            background: rgba(255, 255, 255, 0.12);\n            color: #fff;\n        }\n        \n        .modal-btn.single {\n            background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n            color: white;\n            box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);\n            min-width: 100px;\n        }\n        \n        .modal-btn.single:hover {\n            box-shadow: 0 4px 12px rgba(59, 130, 246, 0.5);\n        }\n        \n        .highlight {\n            color: #4ade80;\n            font-weight: 600;\n        }\n        \n        .key-display {\n            cursor: pointer;\n            transition: color 0.2s;\n        }\n        \n        .key-display:hover {\n            color: #007acc;\n        }\n        \n        .key-display.copied {\n            color: #4ade80 !important;\n        }\n        \n        /* Loading 状态样式 */\n        .btn.loading {\n            position: relative;\n            pointer-events: none;\n            opacity: 0.7;\n        }\n        \n        .btn.loading .btn-text {\n            visibility: hidden;\n        }\n        \n        .btn.loading::after {\n            content: '';\n            position: absolute;\n            width: 16px;\n            height: 16px;\n            top: 50%;\n            left: 50%;\n            margin-left: -8px;\n            margin-top: -8px;\n            border: 2px solid transparent;\n            border-top-color: #fff;\n            border-radius: 50%;\n            animation: spin 0.8s linear infinite;\n        }\n        \n        @keyframes spin {\n            to { transform: rotate(360deg); }\n        }\n        \n        .refresh-btn.loading {\n            animation: spin 1s linear infinite;\n            pointer-events: none;\n        }\n        \n        /* 公告样式 */\n        .announcement-badge {\n            margin-left: auto;\n            padding: 2px 8px;\n            border-radius: 4px;\n            font-size: 11px;\n            text-transform: uppercase;\n        }\n        \n        .announcement-badge.info {\n            background: #1e3a5f;\n            color: #60a5fa;\n        }\n        \n        .announcement-badge.warning {\n            background: #5c4a1f;\n            color: #fbbf24;\n        }\n        \n        .announcement-badge.error {\n            background: #6e3232;\n            color: #f87171;\n        }\n        \n        .announcement-badge.success {\n            background: #2d4a3e;\n            color: #4ade80;\n        }\n        \n        .announcement-title {\n            font-size: 14px;\n            font-weight: 600;\n            color: #ffffff;\n            margin-bottom: 8px;\n            line-height: 1.4;\n        }\n        \n        .announcement-content {\n            font-size: 12px;\n            color: #b0b0b0;\n            line-height: 1.6;\n            word-break: break-word;\n        }\n        \n        .announcement-link {\n            color: #60a5fa;\n            text-decoration: none;\n            border-bottom: 1px dashed #60a5fa;\n            transition: all 0.2s;\n            cursor: pointer;\n        }\n        \n        .announcement-link:hover {\n            color: #93c5fd;\n            border-bottom-color: #93c5fd;\n        }\n        \n        /* Toast 通知样式 */\n        .toast-container {\n            position: fixed;\n            top: 0;\n            left: 0;\n            right: 0;\n            display: flex;\n            justify-content: center;\n            padding: 12px;\n            pointer-events: none;\n            z-index: 2000;\n        }\n        \n        .toast {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            padding: 10px 16px;\n            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n            border: 1px solid rgba(74, 222, 128, 0.3);\n            border-radius: 8px;\n            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 20px rgba(74, 222, 128, 0.1);\n            transform: translateY(-100px);\n            opacity: 0;\n            transition: all 0.3s ease;\n            pointer-events: auto;\n        }\n        \n        .toast.show {\n            transform: translateY(0);\n            opacity: 1;\n        }\n        \n        .toast-icon {\n            font-size: 16px;\n        }\n        \n        .toast-message {\n            font-size: 12px;\n            color: #e0e0e0;\n            max-width: 280px;\n            word-break: break-all;\n        }\n        \n        /* 离线状态提示样式 */\n        .offline-banner {\n            display: none;\n            align-items: center;\n            gap: 8px;\n            padding: 10px 14px;\n            margin-bottom: 12px;\n            background: linear-gradient(135deg, #7f1d1d 0%, #991b1b 100%);\n            border: 1px solid rgba(239, 68, 68, 0.3);\n            border-radius: 8px;\n            animation: slideDown 0.3s ease;\n        }\n        \n        .offline-banner.show {\n            display: flex;\n        }\n        \n        @keyframes slideDown {\n            from {\n                opacity: 0;\n                transform: translateY(-10px);\n            }\n            to {\n                opacity: 1;\n                transform: translateY(0);\n            }\n        }\n        \n        .offline-banner .offline-icon {\n            font-size: 18px;\n            flex-shrink: 0;\n        }\n        \n        .offline-banner .offline-text {\n            flex: 1;\n        }\n        \n        .offline-banner .offline-title {\n            font-size: 12px;\n            font-weight: 600;\n            color: #fca5a5;\n            margin-bottom: 2px;\n        }\n        \n        .offline-banner .offline-desc {\n            font-size: 11px;\n            color: #fecaca;\n            opacity: 0.8;\n        }\n        \n        .offline-banner .retry-btn {\n            padding: 4px 10px;\n            background: rgba(255, 255, 255, 0.15);\n            border: 1px solid rgba(255, 255, 255, 0.2);\n            border-radius: 4px;\n            color: #fff;\n            font-size: 11px;\n            cursor: pointer;\n            transition: all 0.2s;\n            flex-shrink: 0;\n        }\n        \n        .offline-banner .retry-btn:hover {\n            background: rgba(255, 255, 255, 0.25);\n        }\n        \n        .offline-banner .retry-btn.loading {\n            pointer-events: none;\n            opacity: 0.7;\n        }\n        \n        /* 顶部更新提醒条 */\n        .update-banner {\n            position: sticky;\n            top: 0;\n            left: 0;\n            right: 0;\n            background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);\n            color: #fff;\n            padding: 8px 12px;\n            font-size: 12px;\n            display: none;\n            align-items: center;\n            justify-content: center;\n            gap: 8px;\n            z-index: 1000;\n            box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n        }\n        .update-banner.show {\n            display: flex;\n        }\n        .update-banner .update-icon {\n            font-size: 14px;\n        }\n        .update-banner .update-text {\n            font-weight: 500;\n        }\n        .update-banner .update-version {\n            background: rgba(255,255,255,0.2);\n            padding: 2px 6px;\n            border-radius: 4px;\n            font-size: 11px;\n        }\n        .update-banner .update-close {\n            margin-left: auto;\n            background: none;\n            border: none;\n            color: #fff;\n            cursor: pointer;\n            font-size: 16px;\n            padding: 0 4px;\n            opacity: 0.8;\n        }\n        .update-banner .update-close:hover {\n            opacity: 1;\n        }\n        \n    </style>\n</head>\n<body>\n    <!-- 顶部更新提醒条 -->\n    <div class=\"update-banner\" id=\"updateBanner\">\n        <span class=\"update-icon\">🚀</span>\n        <span class=\"update-text\">发现新版本</span>\n        <span class=\"update-version\" id=\"updateBannerVersion\">v0.0</span>\n        <button class=\"update-close\" id=\"updateBannerClose\" title=\"关闭\">×</button>\n    </div>\n    \n    <!-- 管理员权限提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"adminModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">🔐</div>\n            <div class=\"modal-title\">需要管理员权限</div>\n            <div class=\"modal-message\">\n                请关闭 Cursor，右键点击图标<br>\n                选择 <span class=\"highlight\">以管理员身份运行</span>\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"adminModalClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 重置机器码权限提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"resetPermissionModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">🔐</div>\n            <div class=\"modal-title\">需要管理员权限</div>\n            <div class=\"modal-message\" style=\"text-align: left; line-height: 1.8;\">\n                重置机器码需要管理员权限才能完整执行。<br><br>\n                请按以下步骤操作：<br>\n                <span style=\"color: #fbbf24;\">1.</span> 完全关闭 Cursor<br>\n                <span style=\"color: #fbbf24;\">2.</span> 右键点击 Cursor 图标<br>\n                <span style=\"color: #fbbf24;\">3.</span> 选择 <span class=\"highlight\">以管理员身份运行</span><br>\n                <span style=\"color: #fbbf24;\">4.</span> 再次点击重置机器码\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"resetPermissionClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 重启提示弹窗 -->\n    <div class=\"modal-overlay\" id=\"restartModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon success\">✓</div>\n            <div class=\"modal-title\" id=\"restartModalTitle\">操作成功</div>\n            <div class=\"modal-message\">\n                需要重启 Cursor 才能生效\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"restartNowBtn\">立即重启</button>\n                <button class=\"modal-btn secondary\" id=\"restartLaterBtn\">稍后</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 激活码过期弹窗 -->\n    <div class=\"modal-overlay\" id=\"expiredModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon\" style=\"background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);\">⏰</div>\n            <div class=\"modal-title\">激活码已过期</div>\n            <div class=\"modal-message\">\n                您的激活码已过期，请续费后继续使用\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn single\" id=\"expiredModalClose\">我知道了</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 清理环境确认弹窗 -->\n    <div class=\"modal-overlay\" id=\"cleanEnvModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">⚠️</div>\n            <div class=\"modal-title\">清理 Cursor 环境</div>\n            <div class=\"modal-message\">\n                此操作会删除所有配置和登录信息<br>确定要继续吗？\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"cleanEnvConfirmBtn\">确定清理</button>\n                <button class=\"modal-btn secondary\" id=\"cleanEnvCancelBtn\">取消</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 换号确认弹窗 -->\n    <div class=\"modal-overlay\" id=\"switchConfirmModal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-icon warning\">💰</div>\n            <div class=\"modal-title\">账号未使用完</div>\n            <div class=\"modal-message\">\n                当前账号 <span id=\"switchConfirmEmail\" style=\"color:#4caf50;\"></span><br>\n                已用额度: <span id=\"switchConfirmCost\" style=\"color:#ff9800;font-weight:bold;\">$0.00</span> (不足 $10)<br><br>\n                确定要换号吗？\n            </div>\n            <div class=\"modal-buttons\">\n                <button class=\"modal-btn primary\" id=\"switchConfirmBtn\">确认换号</button>\n                <button class=\"modal-btn secondary\" id=\"switchCancelBtn\">取消</button>\n            </div>\n        </div>\n    </div>\n    \n    <!-- 离线状态提示 -->\n    <div class=\"offline-banner\" id=\"offlineBanner\">\n        <span class=\"offline-icon\">📡</span>\n        <div class=\"offline-text\">\n            <div class=\"offline-title\">网络连接失败</div>\n            <div class=\"offline-desc\">请检查网络后重试</div>\n        </div>\n        <button class=\"retry-btn\" id=\"retryConnectBtn\">重试</button>\n    </div>\n    \n    <!-- 软件授权 -->\n    <div class=\"section\">\n        <div class=\"section-title\">\n            <span class=\"icon\">🔐</span>\n            <span>软件授权</span>\n            <span class=\"status-badge\" id=\"authStatus\">未授权</span>\n        </div>\n        \n        <div class=\"input-group\">\n            <input type=\"text\" id=\"keyInput\" placeholder=\"请输入CDK激活码\">\n            <button class=\"btn btn-primary\" id=\"activateBtn\"><span class=\"btn-text\">激活</span></button>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">激活码</span>\n            <span class=\"info-value key-display\" id=\"keyDisplay\" title=\"点击复制\">尚未激活</span>\n        </div>\n        <div class=\"info-row\">\n            <span class=\"info-label\">到期时间</span>\n            <span class=\"info-value\" id=\"expireDate\">尚未激活</span>\n        </div>\n    </div>\n    \n    <!-- 账号数据 (已隐藏) -->\n    <div class=\"section\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\">👤</span>\n            <span>账号数据</span>\n            <span class=\"status-badge\" id=\"accountStatus\">未激活</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">CI积分余额</span>\n            <span class=\"info-value\">0 <button style=\"background:none;border:none;color:#007acc;cursor:pointer;\">🔄</button></span>\n        </div>\n        \n        <button class=\"btn btn-purple btn-block\" id=\"switchBtn\" disabled>换号</button>\n        <button class=\"btn btn-blue btn-block\" id=\"resetBtn\">重置机器码</button>\n        <button class=\"btn btn-blue btn-block\" id=\"disableUpdateBtn\">禁用自动更新</button>\n        <button class=\"btn btn-blue btn-block\" id=\"cleanEnvBtn\">清理Cursor环境</button>\n        <button class=\"btn btn-red btn-block\" id=\"disableBtn\">停用插件</button>\n    </div>\n    \n    <!-- 无感换号 -->\n    <div class=\"section\">\n        <div class=\"section-title\">\n            <span class=\"icon\">⚡</span>\n            <span>无感换号</span>\n            <span class=\"status-badge\" id=\"seamlessStatus\">未启用</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">积分</span>\n            <span class=\"info-value\" id=\"seamlessSwitchRemaining\">0</span>\n        </div>\n        \n        <div class=\"info-row\">\n            <span class=\"info-label\">当前账号</span>\n            <span class=\"info-value\" style=\"font-size:11px;\" id=\"seamlessCurrentAccount\">未分配</span>\n        </div>\n        \n        <div class=\"switch-container\" style=\"margin: 12px 0;\">\n            <span>免魔法模式</span>\n            <span class=\"pro-badge\">PRO</span>\n            <span style=\"margin-left: auto; color: #888; font-size: 11px;\"></span>\n            <label class=\"switch\">\n                <input type=\"checkbox\" id=\"seamlessProxySwitch\">\n                <span class=\"slider\"></span>\n            </label>\n        </div>\n        \n        <button class=\"btn btn-purple btn-block\" id=\"enableSeamlessBtn\" disabled><span class=\"btn-text\">启用无感换号</span></button>\n        <button class=\"btn btn-red btn-block\" id=\"seamlessResetMachineBtn\" style=\"display:none;\"><span class=\"btn-text\">重置机器码</span></button>\n        <button class=\"btn btn-red btn-block\" id=\"disableSeamlessBtn\" style=\"display:none;\"><span class=\"btn-text\">禁用无感换号</span></button>\n        <button class=\"btn btn-blue btn-block\" id=\"manualSwitchBtn\" style=\"display:none;\" disabled><span class=\"btn-text\">一键换号(扣1积分)</span></button>\n    </div>\n    \n    <!-- 账号用量 -->\n    <div class=\"section\" id=\"usageSection\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\">📊</span>\n            <span>账号用量</span>\n            <button class=\"btn\" style=\"margin-left:auto;padding:4px 8px;font-size:11px;background:#3c3c3c;\" id=\"refreshUsageBtn\">🔄</button>\n        </div>\n        \n        <div class=\"usage-row\">\n            <div class=\"usage-item\">\n                <span class=\"info-label\">会员类型</span>\n                <span class=\"info-value\" id=\"usageMemberType\">-</span>\n            </div>\n            <div class=\"usage-item\">\n                <span class=\"info-label\">试用剩余</span>\n                <span class=\"info-value\" id=\"usageTrialDays\">-</span>\n            </div>\n        </div>\n        <div class=\"usage-row\">\n            <div class=\"usage-item\">\n                <span class=\"info-label\">请求次数</span>\n                <span class=\"info-value\" id=\"usageRequestCount\">-</span>\n            </div>\n            <div class=\"usage-item\">\n                <span class=\"info-label\">已用额度</span>\n                <span class=\"info-value\" id=\"usageCostUSD\">-</span>\n            </div>\n        </div>\n        <p style=\"font-size:10px;color:#666;margin-top:8px;text-align:center;\" id=\"usageUpdateTime\">-</p>\n    </div>\n    \n    <!-- 公告 -->\n    <div class=\"section\" id=\"announcementSection\" style=\"display:none;\">\n        <div class=\"section-title\">\n            <span class=\"icon\" id=\"announcementIcon\">📢</span>\n            <span>公告</span>\n            <span class=\"announcement-badge\" id=\"announcementBadge\">info</span>\n        </div>\n        <div class=\"announcement-title\" id=\"announcementTitle\"></div>\n        <div class=\"announcement-content\" id=\"announcementContent\"></div>\n        <p style=\"font-size:10px;color:#666;margin-top:8px;text-align:right;\" id=\"announcementTime\"></p>\n    </div>\n    \n    <!-- 版本信息 -->\n    <div class=\"section\" id=\"versionSection\">\n        <div class=\"section-title\">\n            <span class=\"icon\">📦</span>\n            <span>版本信息</span>\n            <span class=\"status-badge\" id=\"versionStatus\" style=\"display:none;\">有更新</span>\n        </div>\n        <div class=\"info-row\">\n            <span class=\"info-label\">当前版本</span>\n            <span class=\"info-value\" id=\"currentVersion\">-</span>\n        </div>\n        <div class=\"info-row\" id=\"latestVersionRow\" style=\"display:none;\">\n            <span class=\"info-label\">最新版本</span>\n            <span class=\"info-value\" id=\"latestVersion\" style=\"color:#4caf50;\">-</span>\n        </div>\n        <p id=\"updateHint\" style=\"font-size:11px;color:#ff9800;margin-top:8px;display:none;\">\n            ⚠️ 发现新版本，请更新插件以获取最新功能\n        </p>\n    </div>\n    \n    <!-- 页脚 -->\n    <div class=\"footer\">\n        <div class=\"footer-row\">\n            <div class=\"auto-start\">\n                <span>自动启动</span>\n                <label class=\"switch switch-sm\">\n                    <input type=\"checkbox\" id=\"autoStartSwitch\" checked>\n                    <span class=\"slider\"></span>\n                </label>\n            </div>\n            <div class=\"cursor-version\">\n                <span>Cursor</span>\n                <span class=\"version-num\" id=\"cursorVersion\">0.0.0</span>\n            </div>\n        </div>\n        <div class=\"footer-row\" style=\"margin-top: 8px;\">\n            <div style=\"font-size: 10px; color: #666; word-break: break-all;\">\n                <span>路径: </span>\n                <span id=\"cursorPath\" style=\"color: #888;\">获取中...</span>\n            </div>\n        </div>\n    </div>\n    \n    <!-- Toast 通知 -->\n    <div class=\"toast-container\" id=\"toastContainer\">\n        <div class=\"toast\" id=\"toast\">\n            <span class=\"toast-icon\" id=\"toastIcon\">✅</span>\n            <span class=\"toast-message\" id=\"toastMessage\"></span>\n        </div>\n    </div>\n    \n    <script nonce=\"" + _0x1d6267 + "\">\n        const vscode = acquireVsCodeApi();\n        \n        // 元素引用\n        const keyInput = document.getElementById('keyInput');\n        const activateBtn = document.getElementById('activateBtn');\n        const switchBtn = document.getElementById('switchBtn');\n        const resetBtn = document.getElementById('resetBtn');\n        const disableUpdateBtn = document.getElementById('disableUpdateBtn');\n        const cleanEnvBtn = document.getElementById('cleanEnvBtn');\n        const disableBtn = document.getElementById('disableBtn');\n        const authStatus = document.getElementById('authStatus');\n        const accountStatus = document.getElementById('accountStatus');\n        const keyDisplay = document.getElementById('keyDisplay');\n        const switchCount = document.getElementById('switchCount');\n        const expireDate = document.getElementById('expireDate');\n        const cursorVersion = document.getElementById('cursorVersion');\n        const cursorPath = document.getElementById('cursorPath');\n        \n        // 离线状态元素\n        const offlineBanner = document.getElementById('offlineBanner');\n        const retryConnectBtn = document.getElementById('retryConnectBtn');\n        \n        // 无感换号元素\n        const seamlessStatus = document.getElementById('seamlessStatus');\n        const seamlessProxySwitch = document.getElementById('seamlessProxySwitch');\n        const enableSeamlessBtn = document.getElementById('enableSeamlessBtn');\n        const disableSeamlessBtn = document.getElementById('disableSeamlessBtn');\n        const manualSwitchBtn = document.getElementById('manualSwitchBtn');\n        const seamlessResetMachineBtn = document.getElementById('seamlessResetMachineBtn');\n        const seamlessSwitchRemaining = document.getElementById('seamlessSwitchRemaining');\n        const seamlessCurrentAccount = document.getElementById('seamlessCurrentAccount');\n        \n        // 用量显示元素\n        const usageSection = document.getElementById('usageSection');\n        const refreshUsageBtn = document.getElementById('refreshUsageBtn');\n        const usageMemberType = document.getElementById('usageMemberType');\n        const usageTrialDays = document.getElementById('usageTrialDays');\n        const usageRequestCount = document.getElementById('usageRequestCount');\n        const usageCostUSD = document.getElementById('usageCostUSD');\n        const usageUpdateTime = document.getElementById('usageUpdateTime');\n        \n        // 公告元素\n        const announcementSection = document.getElementById('announcementSection');\n        const announcementIcon = document.getElementById('announcementIcon');\n        const announcementBadge = document.getElementById('announcementBadge');\n        const announcementTitle = document.getElementById('announcementTitle');\n        const announcementContent = document.getElementById('announcementContent');\n        const announcementTime = document.getElementById('announcementTime');\n        \n        // 版本元素\n        const versionSection = document.getElementById('versionSection');\n        const versionStatus = document.getElementById('versionStatus');\n        const currentVersionEl = document.getElementById('currentVersion');\n        const latestVersionEl = document.getElementById('latestVersion');\n        const latestVersionRow = document.getElementById('latestVersionRow');\n        const updateHint = document.getElementById('updateHint');\n        \n        // 顶部更新提醒条\n        const updateBanner = document.getElementById('updateBanner');\n        const updateBannerVersion = document.getElementById('updateBannerVersion');\n        const updateBannerClose = document.getElementById('updateBannerClose');\n        \n        // Toast 元素\n        const toast = document.getElementById('toast');\n        const toastIcon = document.getElementById('toastIcon');\n        const toastMessage = document.getElementById('toastMessage');\n        let toastTimer = null;\n        \n        // 显示 Toast 通知\n        function showToast(message, icon = '✅', duration = 10000) {\n            // 清除之前的定时器\n            if (toastTimer) {\n                clearTimeout(toastTimer);\n            }\n            \n            toastIcon.textContent = icon;\n            toastMessage.textContent = message;\n            toast.classList.add('show');\n            \n            // 设置自动隐藏\n            toastTimer = setTimeout(() => {\n                toast.classList.remove('show');\n            }, duration);\n        }\n        \n        // 禁用换号按钮并显示倒计时\n        let switchBtnCountdownTimer = null;\n        const originalSwitchBtnText = '一键换号(扣1积分)';\n        \n        function disableSwitchBtnWithCountdown(seconds) {\n            // 清除之前的定时器\n            if (switchBtnCountdownTimer) {\n                clearInterval(switchBtnCountdownTimer);\n            }\n            \n            let remaining = seconds;\n            manualSwitchBtn.disabled = true;\n            manualSwitchBtn.querySelector('.btn-text').textContent = remaining + '秒后可用';\n            \n            switchBtnCountdownTimer = setInterval(() => {\n                remaining--;\n                if (remaining <= 0) {\n                    clearInterval(switchBtnCountdownTimer);\n                    switchBtnCountdownTimer = null;\n                    manualSwitchBtn.disabled = false;\n                    manualSwitchBtn.querySelector('.btn-text').textContent = originalSwitchBtnText;\n                } else {\n                    manualSwitchBtn.querySelector('.btn-text').textContent = remaining + '秒后可用';\n                }\n            }, 1000);\n        }\n        \n        // 弹窗元素\n        const adminModal = document.getElementById('adminModal');\n        const adminModalClose = document.getElementById('adminModalClose');\n        const resetPermissionModal = document.getElementById('resetPermissionModal');\n        const resetPermissionClose = document.getElementById('resetPermissionClose');\n        const restartModal = document.getElementById('restartModal');\n        const restartModalTitle = document.getElementById('restartModalTitle');\n        const restartNowBtn = document.getElementById('restartNowBtn');\n        const restartLaterBtn = document.getElementById('restartLaterBtn');\n        const expiredModal = document.getElementById('expiredModal');\n        const expiredModalClose = document.getElementById('expiredModalClose');\n        const cleanEnvModal = document.getElementById('cleanEnvModal');\n        const cleanEnvConfirmBtn = document.getElementById('cleanEnvConfirmBtn');\n        const cleanEnvCancelBtn = document.getElementById('cleanEnvCancelBtn');\n        \n        // 换号确认弹窗元素\n        const switchConfirmModal = document.getElementById('switchConfirmModal');\n        const switchConfirmEmail = document.getElementById('switchConfirmEmail');\n        const switchConfirmCost = document.getElementById('switchConfirmCost');\n        const switchConfirmBtn = document.getElementById('switchConfirmBtn');\n        const switchCancelBtn = document.getElementById('switchCancelBtn');\n        \n        // 显示管理员权限弹窗\n        function showAdminModal() {\n            adminModal.classList.add('show');\n        }\n        \n        // 显示重置机器码权限提示弹窗\n        function showAdminPermissionModal() {\n            resetPermissionModal.classList.add('show');\n        }\n        \n        // 重置机器码权限弹窗 - 关闭按钮\n        resetPermissionClose.addEventListener('click', () => {\n            resetPermissionModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭权限提示弹窗\n        resetPermissionModal.addEventListener('click', (e) => {\n            if (e.target === resetPermissionModal) {\n                resetPermissionModal.classList.remove('show');\n            }\n        });\n        \n        // 显示重启提示弹窗\n        let restartModalAction = 'reload'; // 'reload' 或 'close'\n        \n        function showRestartModal(title, action = 'reload') {\n            restartModalTitle.textContent = title || '操作成功';\n            restartModalAction = action;\n            // 根据操作类型更新按钮文字\n            restartNowBtn.textContent = action === 'close' ? '立即关闭 Cursor' : '立即重启';\n            restartModal.classList.add('show');\n        }\n        \n        // 显示过期弹窗\n        function showExpiredModal() {\n            expiredModal.classList.add('show');\n        }\n        \n        // 关闭管理员弹窗\n        adminModalClose.addEventListener('click', () => {\n            adminModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭管理员弹窗\n        adminModal.addEventListener('click', (e) => {\n            if (e.target === adminModal) {\n                adminModal.classList.remove('show');\n            }\n        });\n        \n        // 立即重启/关闭按钮\n        restartNowBtn.addEventListener('click', () => {\n            restartModal.classList.remove('show');\n            if (restartModalAction === 'close') {\n                // 完全关闭 Cursor\n                vscode.postMessage({ type: 'closeCursor' });\n            } else {\n                // 重新加载窗口\n            vscode.postMessage({ type: 'reloadWindow' });\n            }\n        });\n        \n        // 稍后手动按钮\n        restartLaterBtn.addEventListener('click', () => {\n            restartModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭重启弹窗\n        restartModal.addEventListener('click', (e) => {\n            if (e.target === restartModal) {\n                restartModal.classList.remove('show');\n            }\n        });\n        \n        // 关闭过期弹窗\n        expiredModalClose.addEventListener('click', () => {\n            expiredModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭过期弹窗\n        expiredModal.addEventListener('click', (e) => {\n            if (e.target === expiredModal) {\n                expiredModal.classList.remove('show');\n            }\n        });\n        \n        // 当前账号邮箱（用于查询用量）\n        let currentAccountEmail = '';\n        let usageRefreshInterval = null;\n        // 存储完整激活码（用于复制）\n        let fullActivationKey = '';\n        // 当前剩余换号次数\n        let currentSwitchRemaining = 0;\n        // 当前到期时间\n        let currentExpireDate = '';\n        \n        // 检查卡密是否已过期\n        function isKeyExpired() {\n            if (!currentExpireDate) return true;\n            try {\n                const expireTime = new Date(currentExpireDate).getTime();\n                return Date.now() > expireTime;\n            } catch {\n                return true;\n            }\n        }\n        \n        // 格式化到期时间为北京时间\n        function formatExpireDate(dateStr) {\n            if (!dateStr) return '';\n            try {\n                // 后端返回的时间没有时区标识，假设是 UTC 时间\n                // 将空格替换为T，并添加Z表示UTC\n                let utcStr = dateStr;\n                if (!dateStr.includes('T') && !dateStr.includes('Z') && !dateStr.includes('+')) {\n                    utcStr = dateStr.replace(' ', 'T') + 'Z';\n                }\n                const date = new Date(utcStr);\n                \n                // 使用中国时区格式化（UTC+8）\n                return date.toLocaleString('zh-CN', {\n                    timeZone: 'Asia/Shanghai',\n                    year: 'numeric',\n                    month: '2-digit',\n                    day: '2-digit',\n                    hour: '2-digit',\n                    minute: '2-digit',\n                    second: '2-digit',\n                    hour12: false\n                });\n            } catch {\n                return dateStr;  // 格式化失败返回原始值\n            }\n        }\n        \n        // 隐藏激活码后几位\n        function maskKey(key) {\n            if (!key || key.length <= 8) return key;\n            return key.substring(0, key.length - 4) + '****';\n        }\n        \n        // 点击激活码复制\n        keyDisplay.addEventListener('click', () => {\n            if (!fullActivationKey) return;\n            navigator.clipboard.writeText(fullActivationKey).then(() => {\n                keyDisplay.classList.add('copied');\n                const originalText = keyDisplay.textContent;\n                keyDisplay.textContent = '已复制!';\n                setTimeout(() => {\n                    keyDisplay.textContent = maskKey(fullActivationKey);\n                    keyDisplay.classList.remove('copied');\n                }, 1000);\n            }).catch(() => {\n                // 降级方案\n                const textarea = document.createElement('textarea');\n                textarea.value = fullActivationKey;\n                document.body.appendChild(textarea);\n                textarea.select();\n                document.execCommand('copy');\n                document.body.removeChild(textarea);\n                keyDisplay.classList.add('copied');\n                keyDisplay.textContent = '已复制!';\n                setTimeout(() => {\n                    keyDisplay.textContent = maskKey(fullActivationKey);\n                    keyDisplay.classList.remove('copied');\n                }, 1000);\n            });\n        });\n        \n        // Loading 状态控制\n        function setButtonLoading(btn, loading) {\n            if (loading) {\n                btn.classList.add('loading');\n                btn.disabled = true;\n            } else {\n                btn.classList.remove('loading');\n                // 注意：某些按钮可能需要保持禁用状态，由调用方控制\n            }\n        }\n        \n        function setRefreshLoading(btn, loading) {\n            if (loading) {\n                btn.classList.add('loading');\n            } else {\n                btn.classList.remove('loading');\n            }\n        }\n        \n        // 获取初始状态\n        vscode.postMessage({ type: 'getState' });\n        vscode.postMessage({ type: 'getSeamlessStatus' });\n        vscode.postMessage({ type: 'getUserSwitchStatus' });\n        vscode.postMessage({ type: 'getProxyStatus' });\n        vscode.postMessage({ type: 'getAnnouncement' });\n        vscode.postMessage({ type: 'checkVersion' });\n        vscode.postMessage({ type: 'getCursorRunningPath' });\n        \n        // 激活按钮\n        activateBtn.addEventListener('click', () => {\n            const key = keyInput.value.trim();\n            if (!key) {\n                return;\n            }\n            setButtonLoading(activateBtn, true);\n            vscode.postMessage({ type: 'activate', key });\n        });\n        \n        // 换号按钮\n        switchBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'switch' });\n        });\n        \n        // 重置机器码按钮\n        resetBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'resetMachineId' });\n        });\n        \n        // 禁用自动更新按钮\n        disableUpdateBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'disableUpdate' });\n        });\n        \n        // 清理Cursor环境按钮 - 显示确认弹窗\n        cleanEnvBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.add('show');\n        });\n        \n        // 确认清理\n        cleanEnvConfirmBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.remove('show');\n            vscode.postMessage({ type: 'cleanEnv' });\n        });\n        \n        // 取消清理\n        cleanEnvCancelBtn.addEventListener('click', () => {\n            cleanEnvModal.classList.remove('show');\n        });\n        \n        // 点击遮罩关闭清理弹窗\n        cleanEnvModal.addEventListener('click', (e) => {\n            if (e.target === cleanEnvModal) {\n                cleanEnvModal.classList.remove('show');\n            }\n        });\n        \n        // 停用按钮\n        disableBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'disable' });\n        });\n        \n        // 关闭更新提醒条\n        updateBannerClose.addEventListener('click', () => {\n            updateBanner.classList.remove('show');\n        });\n        \n        // 免魔法开关\n        seamlessProxySwitch.addEventListener('change', (e) => {\n            const wantEnabled = e.target.checked;\n            \n            // 如果要开启免魔法，检查卡密是否过期（只要没过期就可以用，不管换号次数）\n            if (wantEnabled && isKeyExpired()) {\n                e.target.checked = false;\n                showToast('授权码已过期，无法开启免魔法', '⚠️', 3000);\n                return;\n            }\n            \n            vscode.postMessage({ \n                type: 'toggleProxy', \n                enabled: wantEnabled,\n                url: ''\n            });\n        });\n        \n        // 无感换号 - 启用按钮\n        enableSeamlessBtn.addEventListener('click', () => {\n            setButtonLoading(enableSeamlessBtn, true);\n            vscode.postMessage({ type: 'injectSeamless' });\n        });\n        \n        // 无感换号 - 禁用按钮\n        disableSeamlessBtn.addEventListener('click', () => {\n            setButtonLoading(disableSeamlessBtn, true);\n            vscode.postMessage({ type: 'restoreSeamless' });\n        });\n        \n        // 无感换号 - 手动换号按钮（先检查用量）\n        manualSwitchBtn.addEventListener('click', () => {\n            setButtonLoading(manualSwitchBtn, true);\n            // 传递当前显示的账号邮箱\n            vscode.postMessage({ type: 'checkUsageBeforeSwitch', email: currentAccountEmail });\n        });\n        \n        // 换号确认弹窗 - 确认按钮\n        switchConfirmBtn.addEventListener('click', () => {\n            switchConfirmModal.classList.remove('show');\n            setButtonLoading(manualSwitchBtn, true);\n            vscode.postMessage({ type: 'confirmSwitch' });\n        });\n        \n        // 换号确认弹窗 - 取消按钮\n        switchCancelBtn.addEventListener('click', () => {\n            switchConfirmModal.classList.remove('show');\n            setButtonLoading(manualSwitchBtn, false);\n            manualSwitchBtn.disabled = false;\n        });\n        \n        // 换号确认弹窗 - 点击遮罩关闭\n        switchConfirmModal.addEventListener('click', (e) => {\n            if (e.target === switchConfirmModal) {\n                switchConfirmModal.classList.remove('show');\n                setButtonLoading(manualSwitchBtn, false);\n                manualSwitchBtn.disabled = false;\n            }\n        });\n        \n        // 无感换号区域 - 重置机器码按钮\n        seamlessResetMachineBtn.addEventListener('click', () => {\n            vscode.postMessage({ type: 'resetMachineId' });\n        });\n        \n        // 刷新用量按钮\n        refreshUsageBtn.addEventListener('click', () => {\n            if (currentAccountEmail) {\n                setRefreshLoading(refreshUsageBtn, true);\n                vscode.postMessage({ type: 'getAccountUsage', email: currentAccountEmail });\n            }\n        });\n        \n        // 刷新用量函数\n        function refreshUsage() {\n            if (currentAccountEmail) {\n                vscode.postMessage({ type: 'getAccountUsage', email: currentAccountEmail });\n            }\n        }\n        \n        // 启动用量定时刷新 (每分钟一次)\n        function startUsageRefresh() {\n            if (usageRefreshInterval) {\n                clearInterval(usageRefreshInterval);\n            }\n            // 立即刷新一次\n            refreshUsage();\n            // 每60秒刷新一次\n            usageRefreshInterval = setInterval(refreshUsage, 60000);\n        }\n        \n        // 停止用量刷新\n        function stopUsageRefresh() {\n            if (usageRefreshInterval) {\n                clearInterval(usageRefreshInterval);\n                usageRefreshInterval = null;\n            }\n        }\n        \n        // 更新用量显示\n        function updateUsageDisplay(data) {\n            if (!data) return;\n            \n            const subscription = data.subscription || {};\n            const usage = data.usage || {};\n            \n            // 会员类型\n            const memberTypeMap = {\n                'free_trial': '免费试用',\n                'pro': 'Pro会员',\n                'free': '免费版',\n                'business': '商业版'\n            };\n            usageMemberType.textContent = memberTypeMap[subscription.membershipType] || subscription.membershipType || '-';\n            \n            // 试用剩余天数\n            if (subscription.daysRemainingOnTrial !== undefined && subscription.daysRemainingOnTrial !== null) {\n                usageTrialDays.textContent = subscription.daysRemainingOnTrial + ' 天';\n                usageTrialDays.style.color = subscription.daysRemainingOnTrial <= 3 ? '#f87171' : '#4ade80';\n            } else {\n                usageTrialDays.textContent = '-';\n                usageTrialDays.style.color = '#fff';\n            }\n            \n            // 请求次数\n            usageRequestCount.textContent = (usage.totalUsageCount || 0) + ' 次';\n            \n            // 已用额度\n            const costUSD = usage.totalCostUSD || 0;\n            usageCostUSD.textContent = '$' + costUSD.toFixed(2);\n            usageCostUSD.style.color = costUSD > 5 ? '#f87171' : (costUSD > 2 ? '#fbbf24' : '#4ade80');\n            \n            // 更新时间\n            usageUpdateTime.textContent = '更新于 ' + new Date().toLocaleTimeString();\n        }\n        \n        // 解析公告内容中的链接 {文字URL}\n        function parseAnnouncementContent(content) {\n            if (!content) return '';\n            \n            // 转义 HTML 特殊字符\n            let escaped = content\n                .replace(/&/g, '&amp;')\n                .replace(/</g, '&lt;')\n                .replace(/>/g, '&gt;')\n                .replace(/\"/g, '&quot;');\n            \n            // 匹配 {文字https://...} 或 {文字http://...} 格式\n            const linkRegex = /\\{([^}]+?)(https?:\\/\\/[^}]+)\\}/g;\n            \n            escaped = escaped.replace(linkRegex, function(match, text, url) {\n                return '<a href=\"' + url + '\" class=\"announcement-link\" target=\"_blank\">' + text + '</a>';\n            });\n            \n            // 将换行符转换为 <br>\n            escaped = escaped.replace(/\\n/g, '<br>');\n            \n            return escaped;\n        }\n        \n        // 更新公告显示\n        function updateAnnouncementDisplay(data) {\n            if (!data || !data.is_active) {\n                announcementSection.style.display = 'none';\n                return;\n            }\n            \n            // 显示公告区域\n            announcementSection.style.display = 'block';\n            \n            // 设置图标和类型徽章\n            const typeConfig = {\n                'info': { icon: '📢', text: '通知', class: 'info' },\n                'warning': { icon: '⚠️', text: '警告', class: 'warning' },\n                'error': { icon: '🚨', text: '重要', class: 'error' },\n                'success': { icon: '✅', text: '好消息', class: 'success' }\n            };\n            \n            const config = typeConfig[data.type] || typeConfig.info;\n            announcementIcon.textContent = config.icon;\n            announcementBadge.textContent = config.text;\n            announcementBadge.className = 'announcement-badge ' + config.class;\n            \n            // 设置标题和内容（解析链接）\n            announcementTitle.textContent = data.title || '';\n            announcementContent.innerHTML = parseAnnouncementContent(data.content || '');\n            \n            // 设置时间\n            if (data.created_at) {\n                const date = new Date(data.created_at);\n                announcementTime.textContent = date.toLocaleDateString('zh-CN', {\n                    year: 'numeric',\n                    month: '2-digit',\n                    day: '2-digit',\n                    hour: '2-digit',\n                    minute: '2-digit'\n                });\n            } else {\n                announcementTime.textContent = '';\n            }\n        }\n        \n        // 处理来自扩展的消息\n        window.addEventListener('message', event => {\n            const message = event.data;\n            \n            switch (message.type) {\n                case 'state':\n                    updateUI(message);\n                    break;\n                case 'activated':\n                    setButtonLoading(activateBtn, false);\n                    activateBtn.disabled = false;\n                    if (message.success) {\n                        // 调试日志\n                        console.log('[CursorPro] 前端收到激活成功消息:', message);\n                        \n                        authStatus.textContent = '已授权';\n                        authStatus.className = 'status-badge active';\n                        accountStatus.textContent = '已激活';\n                        accountStatus.className = 'status-badge active';\n                        switchBtn.disabled = false;\n                        // 更新激活码显示（使用后端返回的 key）\n                        fullActivationKey = message.key || keyInput.value;\n                        keyDisplay.textContent = maskKey(fullActivationKey);\n                        // 更新到期时间\n                        console.log('[CursorPro] 更新到期时间:', message.expireDate);\n                        currentExpireDate = message.expireDate || '';\n                        expireDate.textContent = formatExpireDate(currentExpireDate) || '未知';\n                        // 更新换号次数\n                        if (message.switchRemaining !== undefined) {\n                            currentSwitchRemaining = message.switchRemaining;\n                            switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                        }\n                        // 清空输入框\n                        keyInput.value = '';\n                        showToast('授权码激活成功！', '✅', 10000);\n                    } else {\n                        showToast(message.error || '激活失败', '❌', 10000);\n                    }\n                    break;\n                case 'switched':\n                    if (message.success) {\n                        switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                        showToast('换号成功: ' + (message.email || ''), '✅', 10000);\n                    } else {\n                        showToast(message.error || '换号失败', '❌', 10000);\n                    }\n                    break;\n                case 'reset':\n                    authStatus.textContent = '未授权';\n                    authStatus.className = 'status-badge inactive';\n                    accountStatus.textContent = '未激活';\n                    accountStatus.className = 'status-badge inactive';\n                    switchBtn.disabled = true;\n                    keyInput.value = '';\n                    fullActivationKey = '';\n                    keyDisplay.textContent = '尚未激活';\n                    expireDate.textContent = '尚未激活';\n                    break;\n                \n                // 激活码状态检查结果\n                case 'keyStatusChecked':\n                    if (message.valid) {\n                        // 激活码有效，更新显示\n                        currentExpireDate = message.expireDate || '';\n                        currentSwitchRemaining = message.switchRemaining || 0;\n                        expireDate.textContent = formatExpireDate(currentExpireDate);\n                        switchCount.textContent = message.switchRemaining + '/' + (message.switchLimit || 100);\n                    } else if (message.expired) {\n                        // 激活码已过期，显示提示并重置状态\n                        currentExpireDate = '';\n                        currentSwitchRemaining = 0;\n                        authStatus.textContent = '已过期';\n                        authStatus.className = 'status-badge inactive';\n                        authStatus.style.background = '#6e3232';\n                        authStatus.style.color = '#ff6b6b';\n                        expireDate.textContent = '已过期';\n                        expireDate.style.color = '#f87171';\n                        switchBtn.disabled = true;\n                        enableSeamlessBtn.disabled = true;\n                        // 如果免魔法已开启，自动关闭\n                        if (seamlessProxySwitch.checked) {\n                            seamlessProxySwitch.checked = false;\n                            vscode.postMessage({ type: 'toggleProxy', enabled: false, url: '' });\n                        }\n                        // 显示过期弹窗\n                        showExpiredModal();\n                    }\n                    break;\n                \n                // 用户换号状态\n                case 'userSwitchStatus':\n                    const remaining = message.switchRemaining || 0;\n                    const canSwitch = remaining > 0;\n                    \n                    // 更新全局变量\n                    currentSwitchRemaining = remaining;\n                    \n                    seamlessSwitchRemaining.textContent = remaining.toString();\n                    seamlessSwitchRemaining.style.color = canSwitch ? '#4ade80' : '#f87171';\n                    \n                    if (message.lockedAccount) {\n                        seamlessCurrentAccount.textContent = message.lockedAccount.email;\n                        \n                        // 设置当前账号邮箱并启动用量刷新\n                        if (message.lockedAccount.email && message.lockedAccount.email !== currentAccountEmail) {\n                            currentAccountEmail = message.lockedAccount.email;\n                            usageSection.style.display = 'block';\n                            startUsageRefresh();\n                        }\n                    } else {\n                        seamlessCurrentAccount.textContent = '未分配';\n                        \n                        // 没有锁定账号时隐藏用量区域\n                        currentAccountEmail = '';\n                        usageSection.style.display = 'none';\n                        stopUsageRefresh();\n                    }\n                    \n                    // 根据剩余次数控制手动换号按钮状态\n                    if (!canSwitch) {\n                        manualSwitchBtn.disabled = true;\n                    }\n                    // 启用无感换号按钮不受积分限制，只有过期才禁用\n                    enableSeamlessBtn.disabled = isKeyExpired();\n                    \n                    // 如果无感换号已启用，显示手动换号按钮和重置机器码按钮\n                    if (message.seamlessEnabled && canSwitch) {\n                        manualSwitchBtn.style.display = 'block';\n                        manualSwitchBtn.disabled = false;\n                        setButtonLoading(manualSwitchBtn, false);\n                        seamlessResetMachineBtn.style.display = 'block';\n                    }\n                    break;\n                \n                // 账号用量\n                case 'accountUsage':\n                    setRefreshLoading(refreshUsageBtn, false);\n                    if (message.success && message.data) {\n                        updateUsageDisplay(message.data);\n                    } else {\n                        usageUpdateTime.textContent = '获取失败: ' + (message.error || '未知错误');\n                        usageUpdateTime.style.color = '#f87171';\n                    }\n                    break;\n                \n                // 无感换号状态\n                case 'seamlessStatus':\n                    if (message.is_injected) {\n                        seamlessStatus.textContent = '已启用';\n                        seamlessStatus.className = 'status-badge active';\n                        enableSeamlessBtn.style.display = 'none';\n                        disableSeamlessBtn.style.display = 'block';\n                        disableSeamlessBtn.disabled = false;\n                        setButtonLoading(disableSeamlessBtn, false);\n                        manualSwitchBtn.style.display = 'block';\n                        manualSwitchBtn.disabled = false;\n                        setButtonLoading(manualSwitchBtn, false);\n                        seamlessResetMachineBtn.style.display = 'block';\n                    } else {\n                        seamlessStatus.textContent = '未启用';\n                        seamlessStatus.className = 'status-badge inactive';\n                        enableSeamlessBtn.style.display = 'block';\n                        setButtonLoading(enableSeamlessBtn, false);\n                        // 启用按钮不受积分限制，只有过期才禁用\n                        enableSeamlessBtn.disabled = isKeyExpired();\n                        disableSeamlessBtn.style.display = 'none';\n                        manualSwitchBtn.style.display = 'none';\n                        seamlessResetMachineBtn.style.display = 'none';\n                    }\n                    break;\n                \n                case 'seamlessInjected':\n                    setButtonLoading(enableSeamlessBtn, false);\n                    enableSeamlessBtn.disabled = false;\n                    if (message.success) {\n                        seamlessStatus.textContent = '已启用';\n                        seamlessStatus.className = 'status-badge active';\n                        enableSeamlessBtn.style.display = 'none';\n                        disableSeamlessBtn.style.display = 'block';\n                        manualSwitchBtn.style.display = 'block';\n                        seamlessResetMachineBtn.style.display = 'block';\n                        // 刷新用户状态\n                        vscode.postMessage({ type: 'getUserSwitchStatus' });\n                        // 显示重启提示弹窗\n                        if (message.needRestart) {\n                            showRestartModal(message.message || '无感换号已启用');\n                        }\n                    } else {\n                        // 如果是权限错误，显示自定义弹窗\n                        if (message.needAdmin) {\n                            // Mac/Linux 权限问题，显示详细提示\n                            var errorMsg = message.error || '没有写入权限';\n                            if (message.path) {\n                                errorMsg += '\\n路径: ' + message.path;\n                            }\n                            showToast(errorMsg, '🔐', 15000);\n                        } else {\n                            // 显示详细错误\n                            var detailMsg = message.error || '启用失败';\n                            if (message.details) {\n                                detailMsg += '\\n' + message.details;\n                            }\n                            showToast(detailMsg, '❌', 15000);\n                        }\n                    }\n                    break;\n                \n                case 'seamlessRestored':\n                    setButtonLoading(disableSeamlessBtn, false);\n                    disableSeamlessBtn.disabled = false;\n                    if (message.success) {\n                        seamlessStatus.textContent = '未启用';\n                        seamlessStatus.className = 'status-badge inactive';\n                        enableSeamlessBtn.style.display = 'block';\n                        disableSeamlessBtn.style.display = 'none';\n                        manualSwitchBtn.style.display = 'none';\n                        seamlessResetMachineBtn.style.display = 'none';\n                        // 显示重启提示弹窗\n                        if (message.needRestart) {\n                            showRestartModal(message.message || '无感换号已禁用');\n                        }\n                    } else {\n                        // 如果是权限错误，显示自定义弹窗\n                        if (message.needAdmin) {\n                            showAdminModal();\n                        } else {\n                            showToast(message.error || '禁用失败', '❌', 10000);\n                        }\n                    }\n                    break;\n                \n                // 用量检查结果\n                case 'usageCheckResult':\n                    if (message.success) {\n                        if (message.needConfirm) {\n                            // 需要确认，显示弹窗（按钮保持可用状态，等用户选择）\n                            setButtonLoading(manualSwitchBtn, false);\n                            manualSwitchBtn.disabled = false;\n                            switchConfirmEmail.textContent = message.email || '';\n                            switchConfirmCost.textContent = '$' + (message.costUSD || '0.00');\n                            switchConfirmModal.classList.add('show');\n                        } else {\n                            // 不需要确认，直接换号\n                            vscode.postMessage({ type: 'confirmSwitch' });\n                        }\n                    } else {\n                        setButtonLoading(manualSwitchBtn, false);\n                        manualSwitchBtn.disabled = false;\n                        showToast(message.error || '检查失败', '❌', 5000);\n                    }\n                    break;\n                \n                case 'manualSeamlessSwitched':\n                    setButtonLoading(manualSwitchBtn, false);\n                    if (message.success) {\n                        seamlessSwitchRemaining.textContent = (message.switchRemaining || 0).toString();\n                        seamlessCurrentAccount.textContent = message.email || '未知';\n                        // 显示 Toast 通知，10秒后消失\n                        showToast('已切换到: ' + (message.email || '新账号') + '，约10秒内自动生效', '✅', 10000);\n                        // 刷新状态\n                        vscode.postMessage({ type: 'getUserSwitchStatus' });\n                        // 禁用按钮10秒，显示倒计时\n                        disableSwitchBtnWithCountdown(10);\n                    } else {\n                        manualSwitchBtn.disabled = false;\n                        showToast(message.error || '换号失败', '❌', 5000);\n                    }\n                    break;\n                \n                case 'proxyStatus':\n                    // 设置免魔法开关状态\n                    seamlessProxySwitch.checked = message.enabled;\n                    break;\n                \n                // 公告\n                case 'announcement':\n                    if (message.success && message.data) {\n                        updateAnnouncementDisplay(message.data);\n                    } else {\n                        announcementSection.style.display = 'none';\n                    }\n                    break;\n                \n                // 版本检查\n                case 'versionCheck':\n                    currentVersionEl.textContent = message.currentVersion || '-';\n                    if (message.success && message.hasUpdate) {\n                        // 有更新\n                        latestVersionEl.textContent = message.latestVersion;\n                        latestVersionRow.style.display = 'flex';\n                        versionStatus.style.display = 'inline-block';\n                        versionStatus.style.background = '#ff9800';\n                        updateHint.style.display = 'block';\n                        \n                        // 显示顶部更新提醒条\n                        updateBannerVersion.textContent = 'v' + message.latestVersion;\n                        updateBanner.classList.add('show');\n                    } else if (message.success) {\n                        // 已是最新版\n                        versionStatus.textContent = '最新';\n                        versionStatus.style.display = 'inline-block';\n                        versionStatus.style.background = '#4caf50';\n                        latestVersionRow.style.display = 'none';\n                        updateHint.style.display = 'none';\n                        updateBanner.classList.remove('show');\n                    }\n                    break;\n                \n                // Cursor 运行路径\n                case 'cursorRunningPath':\n                    if (message.path) {\n                        const pathText = message.path + (message.packageExists ? ' ✓' : ' ✗');\n                        cursorPath.textContent = pathText;\n                        cursorPath.style.color = message.packageExists ? '#4ade80' : '#f87171';\n                        // 同时更新版本号\n                        if (message.cursorVersion) {\n                            cursorVersion.textContent = message.cursorVersion;\n                        }\n                    } else {\n                        cursorPath.textContent = '未找到';\n                        cursorPath.style.color = '#f87171';\n                    }\n                    break;\n                \n                // 管理员权限不足提示\n                case 'adminPermissionRequired':\n                    showAdminPermissionModal();\n                    break;\n                \n                // 机器码重置\n                case 'machineIdReset':\n                    if (message.success && message.needRestart) {\n                        // 机器码重置需要完全关闭 Cursor，不是 reload\n                        showRestartModal(message.message || '机器码重置成功', 'close');\n                    }\n                    break;\n                \n                // 通用 Toast 消息\n                case 'showToast':\n                    showToast(message.message || '', message.icon || '📢', 10000);\n                    break;\n                \n                // 网络状态\n                case 'networkStatus':\n                    updateOfflineStatus(!message.online);\n                    break;\n            }\n        });\n        \n        // 离线状态显示/隐藏\n        let wasOffline = false; // 跟踪之前是否离线\n        function updateOfflineStatus(isOffline) {\n            if (isOffline) {\n                offlineBanner.classList.add('show');\n                wasOffline = true;\n            } else {\n                offlineBanner.classList.remove('show');\n                // 只有从离线恢复到在线时才刷新状态\n                if (wasOffline) {\n                    wasOffline = false;\n                    vscode.postMessage({ type: 'getState' });\n                    vscode.postMessage({ type: 'getUserSwitchStatus' });\n                }\n            }\n        }\n        \n        // 重试连接按钮\n        retryConnectBtn.addEventListener('click', async () => {\n            retryConnectBtn.classList.add('loading');\n            retryConnectBtn.textContent = '连接中...';\n            \n            // 发起真正的网络请求来测试网络\n            vscode.postMessage({ type: 'retryConnect' });\n            \n            // 5秒后恢复按钮状态（给网络请求足够时间）\n            setTimeout(() => {\n                retryConnectBtn.classList.remove('loading');\n                retryConnectBtn.textContent = '重试';\n            }, 5000);\n        });\n        \n        function updateUI(state) {\n            if (state.isActivated) {\n                authStatus.textContent = '已授权';\n                authStatus.className = 'status-badge active';\n                accountStatus.textContent = '已激活';\n                accountStatus.className = 'status-badge active';\n                switchBtn.disabled = false;\n                fullActivationKey = state.key;\n                keyDisplay.textContent = maskKey(fullActivationKey);\n                // 更新到期时间\n                currentExpireDate = state.expireDate || '';\n                expireDate.textContent = formatExpireDate(currentExpireDate);\n                // 更新换号次数\n                if (state.switchRemaining !== undefined) {\n                    currentSwitchRemaining = state.switchRemaining;\n                    switchCount.textContent = state.switchRemaining + '/' + (state.switchLimit || 100);\n                }\n                // 启用无感换号按钮（只有过期才禁用）\n                enableSeamlessBtn.disabled = isKeyExpired();\n            }\n            cursorVersion.textContent = state.cursorVersion || '0.0.0';\n            \n            // 根据网络状态显示/隐藏离线提示\n            if (state.isOnline === false) {\n                offlineBanner.classList.add('show');\n                wasOffline = true;\n            } else if (state.isOnline === true) {\n                // 网络恢复，隐藏离线提示\n                offlineBanner.classList.remove('show');\n                wasOffline = false;\n            }\n        }\n    </script>\n</body>\n</html>";
  }
}
exports["CursorProViewProvider"] = CursorProViewProvider;
CursorProViewProvider["CURRENT_VERSION"] = '0.4.5';