deepseek-helper-userscript

this is userscript's description

  1. // ==UserScript==
  2. // @name deepseek-helper-userscript
  3. // @namespace https://github.com/llm-sec/deepseek-helper-userscript
  4. // @version 0.0.1
  5. // @description this is userscript's description
  6. // @document https://github.com/llm-sec/deepseek-helper-userscript
  7. // @author CC11001100 <CC11001100@qq.com>
  8. // @match https://chat.deepseek.com/*
  9. // @run-at document-start
  10. // ==/UserScript==
  11.  
  12.  
  13. // 8888888b. .d8888b. 888
  14. // 888 "Y88b d88P Y88b 888
  15. // 888 888 Y88b. 888
  16. // 888 888 .d88b. .d88b. 88888b. "Y888b. .d88b. .d88b. 888 888
  17. // 888 888 d8P Y8b d8P Y8b 888 "88b "Y88b. d8P Y8b d8P Y8b 888 .88P
  18. // 888 888 88888888 88888888 888 888 "888 88888888 88888888 888888K
  19. // 888 .d88P Y8b. Y8b. 888 d88P Y88b d88P Y8b. Y8b. 888 "88b
  20. // 8888888P" "Y8888 "Y8888 88888P" "Y8888P" "Y8888 "Y8888 888 888
  21. // 888
  22. // 888
  23. // 888
  24. //
  25.  
  26. /******/ (() => { // webpackBootstrap
  27. /******/ "use strict";
  28. /******/ var __webpack_modules__ = ([
  29. /* 0 */,
  30. /* 1 */
  31. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  32.  
  33. __webpack_require__.r(__webpack_exports__);
  34. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  35. /* harmony export */ "default": () => (/* binding */ init)
  36. /* harmony export */ });
  37. /* harmony import */ var _crazy_retry_crazy_retry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
  38. /* harmony import */ var _logger_Logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
  39. /**
  40. * 应用初始化模块
  41. *
  42. * 此模块负责整合并执行应用启动时所需的各项初始化任务
  43. * 通过统一入口管理初始化流程,确保启动顺序和依赖关系
  44. */
  45. var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
  46. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  47. return new (P || (P = Promise))(function (resolve, reject) {
  48. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  49. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  50. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  51. step((generator = generator.apply(thisArg, _arguments || [])).next());
  52. });
  53. };
  54.  
  55.  
  56. /**
  57. * 应用主初始化函数
  58. *
  59. * @async
  60. * @function
  61. * @description 执行核心初始化流程,当前包含:
  62. * - 异常重试机制初始化
  63. *
  64. * @example
  65. * // 在应用启动入口调用
  66. * import init from './init/init';
  67. * await init();
  68. *
  69. * @returns {Promise<void>} 初始化完成Promise
  70. */
  71. function init() {
  72. return __awaiter(this, void 0, void 0, function* () {
  73. _logger_Logger__WEBPACK_IMPORTED_MODULE_1__["default"].configure({
  74. level: _logger_Logger__WEBPACK_IMPORTED_MODULE_1__.LogLevel.DEBUG,
  75. enableColors: false
  76. });
  77. // 初始化异常重试机制
  78. // 配置全局请求失败时的重试策略
  79. yield (0,_crazy_retry_crazy_retry__WEBPACK_IMPORTED_MODULE_0__["default"])();
  80. // 可在此处添加其他初始化任务
  81. // 例如:await initLogger();
  82. // await initAnalytics();
  83. });
  84. }
  85.  
  86.  
  87. /***/ }),
  88. /* 2 */
  89. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  90.  
  91. __webpack_require__.r(__webpack_exports__);
  92. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  93. /* harmony export */ "default": () => (/* binding */ runCrazyRetry)
  94. /* harmony export */ });
  95. /* harmony import */ var _selector_SessionElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
  96. /* harmony import */ var _utils_sleep_util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
  97. /* harmony import */ var _ui_component_Toast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
  98. /* harmony import */ var _selector_DeepSeekToastElement__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
  99. /* harmony import */ var _logger_Logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8);
  100. /* harmony import */ var _utils_element_fingerprint__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9);
  101. var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
  102. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  103. return new (P || (P = Promise))(function (resolve, reject) {
  104. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  105. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  106. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  107. step((generator = generator.apply(thisArg, _arguments || [])).next());
  108. });
  109. };
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. // 指数退避配置参数
  117. const RETRY_CONFIG = {
  118. BASE_DELAY: 1000,
  119. MAX_DELAY: 64 * 1000,
  120. BACKOFF_FACTOR: 2
  121. };
  122. // 新增元素级重试限制配置
  123. const ELEMENT_RETRY_LIMIT = 128; // 每个元素最大重试次数
  124. const elementRetryMap = new Map(); // 存储元素哈希和重试次数的映射
  125. function runCrazyRetry() {
  126. return __awaiter(this, void 0, void 0, function* () {
  127. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].info("启动智能重试功能(元素级指数退避重试限制)");
  128. let currentDelay = RETRY_CONFIG.BASE_DELAY;
  129. let lastContentHash = null;
  130. while (true) {
  131. try {
  132. yield (0,_utils_sleep_util__WEBPACK_IMPORTED_MODULE_1__["default"])(currentDelay);
  133. const session = new _selector_SessionElement__WEBPACK_IMPORTED_MODULE_0__["default"]();
  134. const lastAnswerElement = session.findLastAnswerElement();
  135. if (!lastAnswerElement) {
  136. handleNoElementCase();
  137. continue;
  138. }
  139. const currentHash = yield getContentHash(lastAnswerElement);
  140. // 检测到新内容时清理旧记录的计数器
  141. if (currentHash && currentHash !== lastContentHash) {
  142. cleanupOldHashRecord(lastContentHash);
  143. lastContentHash = currentHash;
  144. }
  145. // 检查元素重试次数
  146. if (currentHash && isElementOverRetryLimit(currentHash)) {
  147. handleRetryLimit(currentHash);
  148. continue;
  149. }
  150. if (!lastAnswerElement.isServerBusy()) {
  151. handleUnchangedContent();
  152. continue;
  153. }
  154. yield performRetry(lastAnswerElement);
  155. resetBackoff();
  156. }
  157. catch (error) {
  158. yield handleRetryError(error, lastContentHash);
  159. updateBackoff();
  160. }
  161. }
  162. // 内部工具函数
  163. function getContentHash(element) {
  164. return __awaiter(this, void 0, void 0, function* () {
  165. try {
  166. return (0,_utils_element_fingerprint__WEBPACK_IMPORTED_MODULE_5__["default"])(element.answerElement);
  167. }
  168. catch (_a) {
  169. return null;
  170. }
  171. });
  172. }
  173. function isElementOverRetryLimit(hash) {
  174. const count = elementRetryMap.get(hash) || 0;
  175. return count >= ELEMENT_RETRY_LIMIT;
  176. }
  177. function cleanupOldHashRecord(oldHash) {
  178. if (oldHash && elementRetryMap.has(oldHash)) {
  179. elementRetryMap.delete(oldHash);
  180. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug(`清理旧元素记录: ${oldHash}`);
  181. }
  182. }
  183. function handleNoElementCase() {
  184. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug("未检测到回答元素,保持退避策略");
  185. }
  186. function handleRetryLimit(hash) {
  187. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].warn(`元素 ${hash.slice(0, 6)}... 已达重试上限(${ELEMENT_RETRY_LIMIT}次)`);
  188. _ui_component_Toast__WEBPACK_IMPORTED_MODULE_2__["default"].show("当前内容已达重试上限,请手动刷新", 5000);
  189. currentDelay = RETRY_CONFIG.MAX_DELAY; // 进入最大等待状态
  190. }
  191. function handleUnchangedContent() {
  192. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug("内容未更新,维持退避策略");
  193. }
  194. function performRetry(element) {
  195. return __awaiter(this, void 0, void 0, function* () {
  196. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].info(`[重试 ${elementRetryMap.get(lastContentHash) || 0 + 1}/${ELEMENT_RETRY_LIMIT}] 服务器繁忙`);
  197. _ui_component_Toast__WEBPACK_IMPORTED_MODULE_2__["default"].show("检测到回答失败,尝试自动刷新响应...", 3000);
  198. element.clickRefreshBtn();
  199. const toastElement = yield _selector_DeepSeekToastElement__WEBPACK_IMPORTED_MODULE_3__["default"].captureDeepSeekToast(3000);
  200. if (toastElement === null || toastElement === void 0 ? void 0 : toastElement.isTooFast()) {
  201. throw new Error("CLICK_TOO_FAST");
  202. }
  203. });
  204. }
  205. function handleRetryError(error, hash) {
  206. return __awaiter(this, void 0, void 0, function* () {
  207. if (error.message === "CLICK_TOO_FAST") {
  208. yield handleTooFastError();
  209. }
  210. else {
  211. updateElementRetryCount(hash);
  212. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].error(`重试异常: ${error.message}`);
  213. }
  214. });
  215. }
  216. function updateElementRetryCount(hash) {
  217. if (hash) {
  218. const count = (elementRetryMap.get(hash) || 0) + 1;
  219. elementRetryMap.set(hash, count);
  220. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug(`元素 ${hash.slice(0, 6)}... 重试计数: ${count}/${ELEMENT_RETRY_LIMIT}`);
  221. }
  222. }
  223. function handleTooFastError() {
  224. return __awaiter(this, void 0, void 0, function* () {
  225. const waitMinutes = 30;
  226. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].warn(`操作频率限制,等待${waitMinutes}分钟`);
  227. _ui_component_Toast__WEBPACK_IMPORTED_MODULE_2__["default"].show(`操作过快,触发高等级封禁,功能临时不可用,${waitMinutes}分钟后再试`, 60 * 30 * 1000);
  228. yield (0,_utils_sleep_util__WEBPACK_IMPORTED_MODULE_1__["default"])(1000 * 60 * 30);
  229. resetBackoff();
  230. });
  231. }
  232. function updateBackoff() {
  233. currentDelay = Math.min(currentDelay * RETRY_CONFIG.BACKOFF_FACTOR, RETRY_CONFIG.MAX_DELAY);
  234. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug(`退避策略更新 等待时长:${currentDelay}ms`);
  235. }
  236. function resetBackoff() {
  237. currentDelay = RETRY_CONFIG.BASE_DELAY;
  238. _logger_Logger__WEBPACK_IMPORTED_MODULE_4__["default"].debug("重置基础等待时间");
  239. }
  240. });
  241. }
  242.  
  243.  
  244. /***/ }),
  245. /* 3 */
  246. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  247.  
  248. __webpack_require__.r(__webpack_exports__);
  249. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  250. /* harmony export */ "default": () => (/* binding */ SessionElement)
  251. /* harmony export */ });
  252. /* harmony import */ var _AnswertElement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
  253. // [file name]: Session.ts
  254.  
  255. /**
  256. * 会话元素管理类
  257. * 处理当前会话中回答元素的定位和操作
  258. */
  259. class SessionElement {
  260. /**
  261. * 查找最近生成的回答元素
  262. * @returns 最新回答元素的封装对象,找不到返回null
  263. */
  264. findLastAnswerElement() {
  265. var _a, _b;
  266. // 通过DOM层级关系定位回答元素(依赖当前DOM结构)
  267. const refreshBtn = this.findLastRefreshIcon();
  268. const answerElement = (_b = (_a = refreshBtn === null || refreshBtn === void 0 ? void 0 : refreshBtn.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.parentElement;
  269. return answerElement ? new _AnswertElement__WEBPACK_IMPORTED_MODULE_0__["default"](answerElement) : null;
  270. }
  271. /**
  272. * 查找最后一个刷新按钮元素
  273. * @private
  274. * @returns 包含#重新生成子元素的按钮,找不到返回null
  275. */
  276. findLastRefreshIcon() {
  277. // 获取所有候选按钮元素
  278. const elements = document.querySelectorAll('.ds-icon-button');
  279. // 逆向遍历查找最新元素(从最后元素开始)
  280. for (let i = elements.length - 1; i >= 0; i--) {
  281. const element = elements[i];
  282. // 通过ID选择器验证按钮功能
  283. if (element.querySelector('#重新生成')) {
  284. return element;
  285. }
  286. }
  287. return null;
  288. }
  289. }
  290.  
  291.  
  292. /***/ }),
  293. /* 4 */
  294. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  295.  
  296. __webpack_require__.r(__webpack_exports__);
  297. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  298. /* harmony export */ "default": () => (/* binding */ AnswertElement)
  299. /* harmony export */ });
  300. // [file name]: AnswertElement.ts
  301. /**
  302. * 回答元素封装类
  303. * 封装单个回答元素的DOM操作和状态判断
  304. */
  305. class AnswertElement {
  306. /**
  307. * 构造函数
  308. * @param answerElement - 需要封装的回答元素DOM节点
  309. */
  310. constructor(answerElement) {
  311. this.answerElement = answerElement;
  312. }
  313. /**
  314. * 判断当前回答是否显示服务器繁忙状态
  315. * @returns 当回答内容包含"服务器繁忙,请稍后再试。"时返回true
  316. */
  317. isServerBusy() {
  318. var _a;
  319. // 通过特定class选择器定位内容区域
  320. const content = this.answerElement.querySelector(".ds-markdown");
  321. return ((_a = content === null || content === void 0 ? void 0 : content.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === "服务器繁忙,请稍后再试。";
  322. }
  323. /**
  324. * 点击当前回答的刷新按钮
  325. * @returns 找到并点击按钮返回true,否则返回false
  326. */
  327. clickRefreshBtn() {
  328. // 在当前回答元素范围内搜索按钮(限定查找范围避免干扰其他会话)
  329. const buttons = this.answerElement.querySelectorAll('.ds-icon-button');
  330. // 逆向遍历查找最新按钮(从最后元素开始)
  331. for (let i = buttons.length - 1; i >= 0; i--) {
  332. const btn = buttons[i];
  333. if (btn.querySelector('#重新生成')) {
  334. // 执行点击操作
  335. btn.click();
  336. return true;
  337. }
  338. }
  339. return false;
  340. }
  341. }
  342.  
  343.  
  344. /***/ }),
  345. /* 5 */
  346. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  347.  
  348. __webpack_require__.r(__webpack_exports__);
  349. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  350. /* harmony export */ "default": () => (/* binding */ sleep)
  351. /* harmony export */ });
  352. var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
  353. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  354. return new (P || (P = Promise))(function (resolve, reject) {
  355. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  356. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  357. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  358. step((generator = generator.apply(thisArg, _arguments || [])).next());
  359. });
  360. };
  361. /**
  362. * 异步休眠函数
  363. * @param ms 休眠时间(毫秒)
  364. * @returns Promise<void>
  365. *
  366. * @example
  367. * // 在async函数中使用
  368. * async function demo() {
  369. * console.log('开始');
  370. * await sleep(2000); // 暂停2秒
  371. * console.log('2秒后执行');
  372. * }
  373. */
  374. function sleep(ms) {
  375. return __awaiter(this, void 0, void 0, function* () {
  376. return new Promise(resolve => setTimeout(resolve, ms));
  377. });
  378. }
  379.  
  380.  
  381. /***/ }),
  382. /* 6 */
  383. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  384.  
  385. __webpack_require__.r(__webpack_exports__);
  386. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  387. /* harmony export */ "default": () => (/* binding */ Toast)
  388. /* harmony export */ });
  389. /**
  390. * 提示框工具类
  391. * 提供静态方法调用的提示框功能
  392. */
  393. class Toast {
  394. /**
  395. * 初始化样式(惰性加载)
  396. */
  397. static ensureStylesInjected() {
  398. if (!Toast.styleElement) {
  399. const style = document.createElement('style');
  400. style.textContent = `
  401. .custom-tip {
  402. position: fixed;
  403. top: 100px;
  404. left: 50%;
  405. transform: translateX(-50%);
  406. background: #4CAF50;
  407. color: white;
  408. padding: 15px 25px;
  409. border-radius: 25px;
  410. box-shadow: 0 3px 6px rgba(0,0,0,0.16);
  411. opacity: 0;
  412. animation: fadeIn 0.3s forwards;
  413. z-index: 1000;
  414. }
  415.  
  416. @keyframes fadeIn {
  417. to { opacity: 1; }
  418. }
  419.  
  420. .fade-out {
  421. animation: fadeOut 0.3s forwards !important;
  422. }
  423.  
  424. @keyframes fadeOut {
  425. from { opacity: 1; }
  426. to { opacity: 0; }
  427. }
  428. `;
  429. document.head.appendChild(style);
  430. Toast.styleElement = style;
  431. }
  432. }
  433. /**
  434. * 显示提示框
  435. * @param text 提示文字
  436. * @param duration 显示持续时间(毫秒),默认3000
  437. */
  438. static show(text, duration = 3000) {
  439. Toast.ensureStylesInjected();
  440. const tip = Toast.createTipElement(text);
  441. Toast.setupAutoClose(tip, duration);
  442. }
  443. /**
  444. * 创建提示框元素
  445. */
  446. static createTipElement(text) {
  447. const tip = document.createElement('div');
  448. tip.className = 'custom-tip';
  449. tip.textContent = text;
  450. document.body.appendChild(tip);
  451. return tip;
  452. }
  453. /**
  454. * 设置自动关闭逻辑
  455. */
  456. static setupAutoClose(element, duration) {
  457. setTimeout(() => {
  458. element.classList.add('fade-out');
  459. element.addEventListener('animationend', () => {
  460. element.remove();
  461. }, { once: true });
  462. }, duration);
  463. }
  464. }
  465. // 使用示例:
  466. // Tips.show('操作成功!');
  467. // Tips.show('文件已上传', 5000);
  468.  
  469.  
  470. /***/ }),
  471. /* 7 */
  472. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  473.  
  474. __webpack_require__.r(__webpack_exports__);
  475. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  476. /* harmony export */ "default": () => (/* binding */ DeepSeekToastElement)
  477. /* harmony export */ });
  478. /* harmony import */ var _utils_sleep_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5);
  479. var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
  480. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  481. return new (P || (P = Promise))(function (resolve, reject) {
  482. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  483. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  484. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  485. step((generator = generator.apply(thisArg, _arguments || [])).next());
  486. });
  487. };
  488. // [file name]: DeepSeekToastElement.ts
  489.  
  490. /**
  491. * Toast提示元素封装类
  492. * 用于操作和管理DeepSeek系统中的Toast提示组件
  493. */
  494. class DeepSeekToastElement {
  495. /**
  496. * 构造函数
  497. * @param toastElement - 需要封装的Toast元素DOM节点
  498. */
  499. constructor(toastElement) {
  500. this.toastElement = toastElement;
  501. }
  502. /**
  503. * 捕获Toast元素(带超时的轮询方法)
  504. * @param timeoutMs - 最大等待时间(毫秒)
  505. * @returns Promise<DeepSeekToastElement | null> 成功捕获返回实例,超时返回null
  506. *
  507. * @example
  508. * // 等待最多3秒捕获Toast
  509. * const toast = await DeepSeekToastElement.captureDeepSeekToast(3000);
  510. * if(toast?.isTooFast()) {
  511. * // 处理频率过高情况
  512. * }
  513. */
  514. static captureDeepSeekToast(timeoutMs) {
  515. return __awaiter(this, void 0, void 0, function* () {
  516. const startTs = Date.now();
  517. while (Date.now() - startTs < timeoutMs) {
  518. // 通过复合选择器定位完整Toast容器
  519. const element = document.querySelector(".ds-toast__content");
  520. if (element === null || element === void 0 ? void 0 : element.parentElement) {
  521. return new DeepSeekToastElement(element.parentElement);
  522. }
  523. // 每100ms轮询一次以平衡性能与响应速度
  524. yield (0,_utils_sleep_util__WEBPACK_IMPORTED_MODULE_0__["default"])(100);
  525. }
  526. return null;
  527. });
  528. }
  529. /**
  530. * 获取弹窗内容
  531. */
  532. getContent() {
  533. var _a, _b;
  534. return ((_b = (_a = this.toastElement.querySelector(".ds-toast__content")) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || "";
  535. }
  536. /**
  537. * 判断是否为"发送频率过快"提示
  538. * @returns 当Toast内容匹配预设文案时返回true
  539. */
  540. isTooFast() {
  541. // 精确匹配系统预设提示文案
  542. return this.getContent() === "你发送消息的频率过快,请稍后再发";
  543. }
  544. }
  545.  
  546.  
  547. /***/ }),
  548. /* 8 */
  549. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  550.  
  551. __webpack_require__.r(__webpack_exports__);
  552. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  553. /* harmony export */ LogLevel: () => (/* binding */ LogLevel),
  554. /* harmony export */ Logger: () => (/* binding */ Logger),
  555. /* harmony export */ "default": () => (/* binding */ logger)
  556. /* harmony export */ });
  557. // Logger.ts
  558. /**
  559. * 日志级别枚举
  560. * DEBUG < INFO < WARN < ERROR < NONE
  561. */
  562. var LogLevel;
  563. (function (LogLevel) {
  564. LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
  565. LogLevel[LogLevel["INFO"] = 1] = "INFO";
  566. LogLevel[LogLevel["WARN"] = 2] = "WARN";
  567. LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
  568. LogLevel[LogLevel["NONE"] = 4] = "NONE"; // 关闭所有日志
  569. })(LogLevel || (LogLevel = {}));
  570. // 默认配置选项
  571. const DEFAULT_OPTIONS = {
  572. level: LogLevel.DEBUG,
  573. enableTimestamp: true,
  574. enableColors: true,
  575. };
  576. /**
  577. * 浏览器环境日志记录器
  578. * 功能特性:
  579. * - 分级日志输出
  580. * - 颜色区分级别
  581. * - 动态配置
  582. * - 保留原始调用堆栈
  583. */
  584. class Logger {
  585. constructor(options = {}) {
  586. // 各日志级别的CSS样式配置
  587. this.colorStyles = {
  588. [LogLevel.DEBUG]: 'color: #666; background-color: #f0f0f0',
  589. [LogLevel.INFO]: 'color: #1e88e5; background-color: #e3f2fd',
  590. [LogLevel.WARN]: 'color: #ffa000; background-color: #fff3e0',
  591. [LogLevel.ERROR]: 'color: #d32f2f; background-color: #ffebee',
  592. [LogLevel.NONE]: '' // NONE级别不需要样式
  593. };
  594. this.options = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
  595. }
  596. // 设置日志级别
  597. setLevel(level) {
  598. this.options.level = level;
  599. }
  600. // 动态更新配置
  601. configure(options) {
  602. this.options = Object.assign(Object.assign({}, this.options), options);
  603. }
  604. // 调试日志
  605. debug(...args) {
  606. this.log(LogLevel.DEBUG, args);
  607. }
  608. // 信息日志
  609. info(...args) {
  610. this.log(LogLevel.INFO, args);
  611. }
  612. // 警告日志
  613. warn(...args) {
  614. this.log(LogLevel.WARN, args);
  615. }
  616. // 错误日志
  617. error(...args) {
  618. this.log(LogLevel.ERROR, args);
  619. }
  620. // 获取ISO格式时间戳
  621. getTimestamp() {
  622. return new Date().toISOString();
  623. }
  624. // 获取日志级别标签
  625. getLabel(level) {
  626. const labels = {
  627. [LogLevel.DEBUG]: 'DEBUG',
  628. [LogLevel.INFO]: 'INFO',
  629. [LogLevel.WARN]: 'WARN',
  630. [LogLevel.ERROR]: 'ERROR',
  631. [LogLevel.NONE]: 'NONE'
  632. };
  633. return labels[level] || 'LOG';
  634. }
  635. /**
  636. * 核心日志方法
  637. * @param level 日志级别
  638. * @param args 日志参数
  639. */
  640. log(level, args) {
  641. // 过滤低于当前级别的日志
  642. if (level < this.options.level)
  643. return;
  644. const label = this.getLabel(level);
  645. const timestamp = this.options.enableTimestamp ? `${this.getTimestamp()} ` : '';
  646. const styles = this.options.enableColors
  647. ? this.colorStyles[level]
  648. : '';
  649. // 构造格式化参数,保留原始调用堆栈
  650. const formattedArgs = [
  651. `%c${timestamp}${label}:`, // 带样式的首参数
  652. styles, // CSS样式
  653. ...args // 原始日志内容
  654. ];
  655. // 根据级别调用对应的console方法
  656. switch (level) { // ✅ 正确变量名(小写level)
  657. case LogLevel.DEBUG:
  658. console.debug(...formattedArgs); // ✅ 正确方法名和变量名
  659. break;
  660. case LogLevel.INFO: // ✅ 正确枚举值
  661. console.info(...formattedArgs);
  662. break;
  663. case LogLevel.WARN:
  664. console.warn(...formattedArgs); // ✅ 正确方法名
  665. break;
  666. case LogLevel.ERROR:
  667. console.error(...formattedArgs);
  668. break;
  669. default:
  670. // 穷举检查确保处理所有枚举值
  671. console.info(...formattedArgs);
  672. break;
  673. }
  674. }
  675. }
  676. // 导出默认单例实例
  677. const logger = new Logger();
  678.  
  679. /* 使用示例:
  680. // 基础使用
  681. logger.debug('User login', { username: 'alice' });
  682. logger.info('API response', responseData);
  683. logger.warn('Deprecation warning');
  684. logger.error('Network error', error);
  685.  
  686. // 生产环境配置
  687. logger.configure({
  688. level: LogLevel.ERROR,
  689. enableColors: false
  690. });
  691.  
  692. // 自定义实例
  693. const customLogger = new Logger({
  694. enableTimestamp: false,
  695. level: LogLevel.WARN
  696. });
  697. */
  698.  
  699.  
  700. /***/ }),
  701. /* 9 */
  702. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  703.  
  704. __webpack_require__.r(__webpack_exports__);
  705. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  706. /* harmony export */ "default": () => (/* binding */ getElementFingerprint)
  707. /* harmony export */ });
  708. /**
  709. * 生成HTML元素的字符串指纹
  710. * @param element - 目标元素
  711. * @returns 元素的指纹哈希值
  712. */
  713. function getElementFingerprint(element) {
  714. var _a;
  715. // 1. 提取核心特征
  716. const features = {
  717. tag: element.tagName.toLowerCase(),
  718. id: element.id,
  719. classes: Array.from(element.classList).sort().join(' '),
  720. text: ((_a = element.textContent) === null || _a === void 0 ? void 0 : _a.trim().replace(/\s+/g, ' ')) || '',
  721. children: element.children.length,
  722. attributes: getKeyAttributes(element)
  723. };
  724. // 2. 生成特征字符串
  725. const featureString = JSON.stringify(features);
  726. // 3. 计算哈希值
  727. return simpleHash(featureString);
  728. }
  729. /**
  730. * 获取元素的关键自定义属性
  731. * @param element - 目标元素
  732. * @returns 包含data-*属性的对象
  733. */
  734. function getKeyAttributes(element) {
  735. const attrs = {};
  736. Array.from(element.attributes).forEach((attr) => {
  737. if (attr.name.startsWith('data-')) {
  738. attrs[attr.name] = attr.value;
  739. }
  740. });
  741. return attrs;
  742. }
  743. /**
  744. * 快速哈希函数(32位)
  745. * @param str - 输入字符串
  746. * @returns 十六进制哈希值
  747. */
  748. function simpleHash(str) {
  749. let hash = 5381;
  750. for (let i = 0; i < str.length; i++) {
  751. hash = (hash << 5) + hash + str.charCodeAt(i);
  752. }
  753. return (hash & 0x7fffffff).toString(16);
  754. }
  755. // // 使用示例
  756. // const element = document.getElementById('app') as HTMLElement;
  757. // if (element) {
  758. // console.log(getElementFingerprint(element));
  759. //
  760. // // 修改内容后重新生成
  761. // element.textContent = 'Updated Content';
  762. // console.log(getElementFingerprint(element));
  763. // }
  764.  
  765.  
  766. /***/ })
  767. /******/ ]);
  768. /************************************************************************/
  769. /******/ // The module cache
  770. /******/ var __webpack_module_cache__ = {};
  771. /******/
  772. /******/ // The require function
  773. /******/ function __webpack_require__(moduleId) {
  774. /******/ // Check if module is in cache
  775. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  776. /******/ if (cachedModule !== undefined) {
  777. /******/ return cachedModule.exports;
  778. /******/ }
  779. /******/ // Create a new module (and put it into the cache)
  780. /******/ var module = __webpack_module_cache__[moduleId] = {
  781. /******/ // no module.id needed
  782. /******/ // no module.loaded needed
  783. /******/ exports: {}
  784. /******/ };
  785. /******/
  786. /******/ // Execute the module function
  787. /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  788. /******/
  789. /******/ // Return the exports of the module
  790. /******/ return module.exports;
  791. /******/ }
  792. /******/
  793. /************************************************************************/
  794. /******/ /* webpack/runtime/define property getters */
  795. /******/ (() => {
  796. /******/ // define getter functions for harmony exports
  797. /******/ __webpack_require__.d = (exports, definition) => {
  798. /******/ for(var key in definition) {
  799. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  800. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  801. /******/ }
  802. /******/ }
  803. /******/ };
  804. /******/ })();
  805. /******/
  806. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  807. /******/ (() => {
  808. /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  809. /******/ })();
  810. /******/
  811. /******/ /* webpack/runtime/make namespace object */
  812. /******/ (() => {
  813. /******/ // define __esModule on exports
  814. /******/ __webpack_require__.r = (exports) => {
  815. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  816. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  817. /******/ }
  818. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  819. /******/ };
  820. /******/ })();
  821. /******/
  822. /************************************************************************/
  823. var __webpack_exports__ = {};
  824. // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
  825. (() => {
  826. __webpack_require__.r(__webpack_exports__);
  827. /* harmony import */ var _init_init__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
  828. /**
  829. * 应用主入口文件
  830. *
  831. * 该文件是应用的启动入口,负责调用初始化函数并启动应用。
  832. * 使用立即执行的异步函数来处理初始化过程中的异步操作。
  833. */
  834. var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
  835. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  836. return new (P || (P = Promise))(function (resolve, reject) {
  837. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  838. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  839. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  840. step((generator = generator.apply(thisArg, _arguments || [])).next());
  841. });
  842. };
  843. // 引入初始化模块,该模块负责应用启动前的配置、服务连接等初始化工作
  844.  
  845. /**
  846. * 异步立即执行函数
  847. *
  848. * 使用IIFE(立即调用函数表达式)包裹异步逻辑,便于使用await语法
  849. * 在初始化完成后可根据需要扩展其他启动逻辑
  850. */
  851. (() => __awaiter(void 0, void 0, void 0, function* () {
  852. try {
  853. // 执行初始化流程并等待完成
  854. yield (0,_init_init__WEBPACK_IMPORTED_MODULE_0__["default"])();
  855. // 初始化完成后可添加其他启动逻辑
  856. // 例如:启动HTTP服务、注册定时任务等
  857. }
  858. catch (error) {
  859. // 捕获并处理初始化过程中出现的错误
  860. console.error("DeepSeek助手初始化失败:", error);
  861. }
  862. }))();
  863.  
  864. })();
  865.  
  866. /******/ })()
  867. ;
  868. //# sourceMappingURL=index.js.map